Damage from disguises is now passed through to their hosts

This commit is contained in:
Sollace 2024-02-13 18:47:01 +00:00
parent e1d4b229ff
commit 91b8b827a6
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
6 changed files with 73 additions and 3 deletions

View file

@ -18,6 +18,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.Situation;
import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.advancement.UCriteria;
import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate;
import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
import com.minelittlepony.unicopia.entity.behaviour.Guest;
import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity; import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity;
import com.minelittlepony.unicopia.entity.damage.MagicalDamageSource; import com.minelittlepony.unicopia.entity.damage.MagicalDamageSource;
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
@ -36,6 +37,7 @@ import com.minelittlepony.unicopia.server.world.DragonBreathStore;
import com.minelittlepony.unicopia.util.*; import com.minelittlepony.unicopia.util.*;
import it.unimi.dsi.fastutil.floats.Float2ObjectFunction; import it.unimi.dsi.fastutil.floats.Float2ObjectFunction;
import net.fabricmc.fabric.api.util.TriState;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
@ -44,6 +46,7 @@ import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageTypes;
import net.minecraft.entity.data.*; import net.minecraft.entity.data.*;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.projectile.ProjectileEntity;
@ -92,6 +95,8 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
@Nullable @Nullable
private Caster<?> attacker; private Caster<?> attacker;
@Nullable
private transient Caster<?> host;
private Optional<Living<?>> target = Optional.empty(); private Optional<Living<?>> target = Optional.empty();
@ -478,6 +483,19 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
public Optional<Boolean> onDamage(DamageSource source, float amount) { public Optional<Boolean> onDamage(DamageSource source, float amount) {
if ((source.getAttacker() instanceof Guest guest && guest.getHost() instanceof Living l && l == this)
|| (source.getSource() instanceof Guest guest && guest.getHost() instanceof Living l && l == this)) {
var type = source.getTypeRegistryEntry();
return Optional.of(entity.damage(
type.matchesKey(DamageTypes.FIREBALL) ? entity.getDamageSources().create(DamageTypes.UNATTRIBUTED_FIREBALL) :
type.matchesKey(DamageTypes.PLAYER_EXPLOSION) ? entity.getDamageSources().create(DamageTypes.EXPLOSION) :
new DamageSource(type, entity, entity), amount));
}
if (entity instanceof Guest guest && guest.getHost() instanceof Living l) {
l.asEntity().damage(source, amount);
}
if (source.isIn(DamageTypeTags.IS_LIGHTNING) && (invinsibilityTicks > 0 || tryCaptureLightning())) { if (source.isIn(DamageTypeTags.IS_LIGHTNING) && (invinsibilityTicks > 0 || tryCaptureLightning())) {
return Optional.of(false); return Optional.of(false);
} }
@ -502,6 +520,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
return Optional.empty(); return Optional.empty();
} }
public TriState canBeHurtByWater() {
return TriState.DEFAULT;
}
public Optional<BlockPos> chooseClimbingPos() { public Optional<BlockPos> chooseClimbingPos() {
return getSpellSlot().get(SpellPredicate.IS_DISGUISE, false) return getSpellSlot().get(SpellPredicate.IS_DISGUISE, false)
.map(AbstractDisguiseSpell::getDisguise) .map(AbstractDisguiseSpell::getDisguise)

View file

@ -5,11 +5,13 @@ import com.minelittlepony.unicopia.entity.Living;
import net.minecraft.entity.mob.EndermanEntity; import net.minecraft.entity.mob.EndermanEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
public class EndermanBehaviour extends EntityBehaviour<EndermanEntity> { public class EndermanBehaviour extends EntityBehaviour<EndermanEntity> {
@Override @Override
public void update(Living<?> source, EndermanEntity entity, Disguise spell) { public void update(Living<?> source, EndermanEntity entity, Disguise spell) {
entity.setInvulnerable(!EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.test(source.asEntity()));
if (source.asEntity().isSneaking() || source.asEntity().isSprinting()) { if (source.asEntity().isSneaking() || source.asEntity().isSprinting()) {
entity.setTarget(entity); entity.setTarget(entity);
} else { } else {
@ -22,5 +24,13 @@ public class EndermanBehaviour extends EntityBehaviour<EndermanEntity> {
} else { } else {
entity.setCarriedBlock(null); entity.setCarriedBlock(null);
} }
//if (entity.hurtTime > 0) {
/* Vec3d teleportedPos = entity.getPos();
if (!teleportedPos.equals(source.asEntity().getPos())) {
source.asEntity().refreshPositionAfterTeleport(teleportedPos.x, teleportedPos.y, teleportedPos.z);
}*/
//}
} }
} }

View file

@ -205,8 +205,12 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
return; return;
} }
if (entity instanceof LivingEntity) { if (entity instanceof LivingEntity l) {
((LivingEntity) entity).getAttributeInstance(UEntityAttributes.ENTITY_GRAVITY_MODIFIER).clearModifiers(); l.getAttributeInstance(UEntityAttributes.ENTITY_GRAVITY_MODIFIER).clearModifiers();
}
if (entity instanceof Guest guest) {
guest.setHost(source);
} }
if (source.isClient()) { if (source.isClient()) {

View file

@ -0,0 +1,9 @@
package com.minelittlepony.unicopia.entity.behaviour;
import com.minelittlepony.unicopia.ability.magic.Caster;
public interface Guest {
void setHost(Caster<?> host);
Caster<?> getHost();
}

View file

@ -1,11 +1,13 @@
package com.minelittlepony.unicopia.entity.duck; package com.minelittlepony.unicopia.entity.duck;
import com.minelittlepony.unicopia.entity.behaviour.Guest;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public interface LivingEntityDuck { public interface LivingEntityDuck extends Guest {
void updateItemUsage(Hand hand, ItemStack stack, int time); void updateItemUsage(Hand hand, ItemStack stack, int time);
boolean isJumping(); boolean isJumping();

View file

@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.mixin;
import java.util.Optional; import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -18,6 +19,7 @@ import com.minelittlepony.unicopia.entity.*;
import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
import com.minelittlepony.unicopia.entity.duck.*; import com.minelittlepony.unicopia.entity.duck.*;
import net.fabricmc.fabric.api.util.TriState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.DefaultAttributeContainer;
@ -39,6 +41,8 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ
private Optional<BlockPos> climbingPos; private Optional<BlockPos> climbingPos;
private Equine<?> caster; private Equine<?> caster;
@Nullable
private transient Caster<?> host;
private MixinLivingEntity() { super(null, null); } private MixinLivingEntity() { super(null, null); }
@ -58,6 +62,17 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ
return (Living<?>)caster; return (Living<?>)caster;
} }
@Override
@Nullable
public Caster<?> getHost() {
return host;
}
@Override
public void setHost(Caster<?> host) {
this.host = host;
}
@Override @Override
@Accessor("jumping") @Accessor("jumping")
public abstract boolean isJumping(); public abstract boolean isJumping();
@ -157,6 +172,14 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ
get().onDamage(source, amount).ifPresent(info::setReturnValue); get().onDamage(source, amount).ifPresent(info::setReturnValue);
} }
@Inject(method = "hurtByWater()Z", at = @At("HEAD"), cancellable = true)
private void onCanBeHurtByWater(CallbackInfoReturnable<Boolean> info) {
TriState hurtByWater = get().canBeHurtByWater();
if (hurtByWater != TriState.DEFAULT) {
info.setReturnValue(hurtByWater.get());
}
}
@Inject(method = "writeCustomDataToNbt(Lnet/minecraft/nbt/NbtCompound;)V", at = @At("HEAD")) @Inject(method = "writeCustomDataToNbt(Lnet/minecraft/nbt/NbtCompound;)V", at = @At("HEAD"))
private void onWriteCustomDataToTag(NbtCompound tag, CallbackInfo info) { private void onWriteCustomDataToTag(NbtCompound tag, CallbackInfo info) {
tag.put("unicopia_caster", get().toNBT()); tag.put("unicopia_caster", get().toNBT());