diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index 4caf08bf26..2a2e546ce7 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -1070,6 +1070,14 @@ public String validate(CommandSourceStack source, CarpetRule currentRule ) public static boolean lightningKillsDropsFix = false; + //Todo figure out how to do death loot tables + @Rule( + desc = "Mob conversions keep NBT Tags", + extra = {"Setting to true will ensure NBT tags are kept when mobs convert (e.g Villager to Witch)", "Fixes [MC-88967](https://bugs.mojang.com/browse/MC-88967)."}, + category = BUGFIX + ) + public static boolean mobConvertKeepNBTTagsFix = false; + @Rule( desc = "Placing an activator rail on top of a barrier block will fill the neighbor updater stack when the rail turns off.", extra = {"The integer entered is the amount of updates that should be left in the stack", "-1 turns it off"}, diff --git a/src/main/java/carpet/mixins/AbstractPiglin_bugFixMixin.java b/src/main/java/carpet/mixins/AbstractPiglin_bugFixMixin.java new file mode 100644 index 0000000000..8cb78f56b5 --- /dev/null +++ b/src/main/java/carpet/mixins/AbstractPiglin_bugFixMixin.java @@ -0,0 +1,41 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.monster.ZombifiedPiglin; +import net.minecraft.world.entity.monster.piglin.AbstractPiglin; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(AbstractPiglin.class) +public abstract class AbstractPiglin_bugFixMixin extends Mob { + + protected AbstractPiglin_bugFixMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Inject(method = "finishConversion", at = @At(value = "TAIL"), locals = LocalCapture.CAPTURE_FAILSOFT) + private void mixin(ServerLevel serverLevel, CallbackInfo ci, ZombifiedPiglin zombifiedPiglin) { + if (CarpetSettings.mobConvertKeepNBTTagsFix) { + this.getActiveEffects().forEach(zombifiedPiglin::addEffect); + zombifiedPiglin.getAttributes().assignValues(this.getAttributes()); + zombifiedPiglin.setCanPickUpLoot(this.canPickUpLoot()); + zombifiedPiglin.setRemainingFireTicks(this.getRemainingFireTicks()); + zombifiedPiglin.setNoGravity(this.isNoGravity()); + zombifiedPiglin.setPortalCooldown(this.getPortalCooldown()); + zombifiedPiglin.setXRot(this.getXRot()); + zombifiedPiglin.setYRot(this.getYRot()); + zombifiedPiglin.setYBodyRot(this.getVisualRotationYInDegrees()); + zombifiedPiglin.setYHeadRot(this.getYHeadRot()); + zombifiedPiglin.setSilent(this.isSilent()); + this.getTags().forEach(zombifiedPiglin::addTag); + zombifiedPiglin.setUUID(this.getUUID()); + } + } +} diff --git a/src/main/java/carpet/mixins/MushroomCow_bugFixMixin.java b/src/main/java/carpet/mixins/MushroomCow_bugFixMixin.java new file mode 100644 index 0000000000..1cf895101c --- /dev/null +++ b/src/main/java/carpet/mixins/MushroomCow_bugFixMixin.java @@ -0,0 +1,42 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.animal.Cow; +import net.minecraft.world.entity.animal.MushroomCow; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(MushroomCow.class) +public abstract class MushroomCow_bugFixMixin extends Mob { + + protected MushroomCow_bugFixMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Inject(method = "shear", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/Cow;setInvulnerable(Z)V"), locals = LocalCapture.CAPTURE_FAILSOFT) + private void mixin(SoundSource soundSource, CallbackInfo ci, Cow cow) { + if (CarpetSettings.mobConvertKeepNBTTagsFix) { + this.getActiveEffects().forEach(cow::addEffect); + cow.getAttributes().assignValues(this.getAttributes()); + cow.setDeltaMovement(this.getDeltaMovement()); + cow.setRemainingFireTicks(this.getRemainingFireTicks()); + cow.setNoAi(this.isNoAi()); + cow.setNoGravity(this.isNoGravity()); + cow.setPortalCooldown(this.getPortalCooldown()); + cow.setXRot(this.getXRot()); + cow.setYRot(this.getYRot()); + cow.setYBodyRot(this.getVisualRotationYInDegrees()); + cow.setYHeadRot(this.getYHeadRot()); + cow.setSilent(this.isSilent()); + this.getTags().forEach(cow::addTag); + cow.setUUID(this.getUUID()); + } + } +} diff --git a/src/main/java/carpet/mixins/Slime_bugFixMixin.java b/src/main/java/carpet/mixins/Slime_bugFixMixin.java new file mode 100644 index 0000000000..94a8f15c72 --- /dev/null +++ b/src/main/java/carpet/mixins/Slime_bugFixMixin.java @@ -0,0 +1,34 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.monster.Slime; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(Slime.class) +public abstract class Slime_bugFixMixin extends Mob { + protected Slime_bugFixMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Inject(method = "remove", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"), locals = LocalCapture.CAPTURE_FAILSOFT) + private void mixin(RemovalReason removalReason, CallbackInfo ci, int i, Component component, boolean bl, float f, int j, int k, int l, float g, float h, Slime slime) { + if (CarpetSettings.mobConvertKeepNBTTagsFix) { + this.getActiveEffects().forEach(slime::addEffect); + slime.getAttributes().assignValues(this.getAttributes()); + slime.setDeltaMovement(this.getDeltaMovement()); + // slime.setRemainingFireTicks(this.getRemainingFireTicks()); technically a newly spawned entity, not the same one converted + slime.setNoGravity(this.isNoGravity()); + // slime.setPortalCooldown(this.getPortalCooldown()); same here + slime.setSilent(this.isSilent()); + this.getTags().forEach(slime::addTag); + } + } +} diff --git a/src/main/java/carpet/mixins/Tadpole_bugFixMixin.java b/src/main/java/carpet/mixins/Tadpole_bugFixMixin.java new file mode 100644 index 0000000000..6d9d875a34 --- /dev/null +++ b/src/main/java/carpet/mixins/Tadpole_bugFixMixin.java @@ -0,0 +1,32 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.animal.frog.Frog; +import net.minecraft.world.entity.animal.frog.Tadpole; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(Tadpole.class) +public abstract class Tadpole_bugFixMixin extends Mob { + protected Tadpole_bugFixMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Inject(method = "ageUp()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"), locals = LocalCapture.CAPTURE_FAILSOFT) + private void mixin(CallbackInfo ci, ServerLevel serverLevel, Frog frog) { + if (CarpetSettings.mobConvertKeepNBTTagsFix) { + frog.setXRot(this.getXRot()); + frog.setYRot(this.getYRot()); + frog.setYBodyRot(this.getVisualRotationYInDegrees()); + frog.setYHeadRot(this.getYHeadRot()); + frog.setUUID(this.getUUID()); + } + } +} diff --git a/src/main/java/carpet/mixins/Villager_bugFixMixin.java b/src/main/java/carpet/mixins/Villager_bugFixMixin.java new file mode 100644 index 0000000000..66cffadae3 --- /dev/null +++ b/src/main/java/carpet/mixins/Villager_bugFixMixin.java @@ -0,0 +1,42 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LightningBolt; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.monster.Witch; +import net.minecraft.world.entity.npc.Villager; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(Villager.class) +public abstract class Villager_bugFixMixin extends Mob { + + + protected Villager_bugFixMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Inject(method = "thunderHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/Witch;setPersistenceRequired()V"), locals = LocalCapture.CAPTURE_FAILSOFT) + private void mixin(ServerLevel serverLevel, LightningBolt lightningBolt, CallbackInfo ci, Witch witch) { + if (CarpetSettings.mobConvertKeepNBTTagsFix) { + this.getActiveEffects().forEach(witch::addEffect); + witch.getAttributes().assignValues(this.getAttributes()); + witch.setCanPickUpLoot(this.canPickUpLoot()); + witch.setInvulnerable(this.isInvulnerable()); + witch.setLeftHanded(this.isLeftHanded()); + witch.setNoGravity(this.isNoGravity()); + witch.setXRot(this.getXRot()); + witch.setYRot(this.getYRot()); + witch.setYBodyRot(this.getVisualRotationYInDegrees()); + witch.setYHeadRot(this.getYHeadRot()); + witch.setSilent(this.isSilent()); + this.getTags().forEach(witch::addTag); + } + } +} diff --git a/src/main/java/carpet/mixins/ZombieVillager_bugFixMixin.java b/src/main/java/carpet/mixins/ZombieVillager_bugFixMixin.java new file mode 100644 index 0000000000..8b26568cf7 --- /dev/null +++ b/src/main/java/carpet/mixins/ZombieVillager_bugFixMixin.java @@ -0,0 +1,38 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.monster.ZombieVillager; +import net.minecraft.world.entity.npc.Villager; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(ZombieVillager.class) +public abstract class ZombieVillager_bugFixMixin extends Mob { + + protected ZombieVillager_bugFixMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + + @Inject(method = "finishConversion", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EquipmentSlot;values()[Lnet/minecraft/world/entity/EquipmentSlot;"), locals = LocalCapture.CAPTURE_FAILSOFT) + private void mixin(ServerLevel serverLevel, CallbackInfo ci, Villager villager) { + if (CarpetSettings.mobConvertKeepNBTTagsFix) { + this.getActiveEffects().forEach(villager::addEffect); + villager.setCanPickUpLoot(this.canPickUpLoot()); + villager.setRemainingFireTicks(this.getRemainingFireTicks()); + villager.setLeftHanded(this.isLeftHanded()); + villager.setNoGravity(this.isNoGravity()); + villager.setPortalCooldown(this.getPortalCooldown()); + villager.setSilent(this.isSilent()); + this.getTags().forEach(villager::addTag); + villager.setUUID(this.getUUID()); + } + } +} diff --git a/src/main/java/carpet/mixins/Zombie_bugFixMixin.java b/src/main/java/carpet/mixins/Zombie_bugFixMixin.java new file mode 100644 index 0000000000..c32aaac38a --- /dev/null +++ b/src/main/java/carpet/mixins/Zombie_bugFixMixin.java @@ -0,0 +1,37 @@ +package carpet.mixins; + +import carpet.CarpetSettings; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.monster.Zombie; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(Zombie.class) +public abstract class Zombie_bugFixMixin extends Mob { + protected Zombie_bugFixMixin(EntityType entityType, Level level) { + super(entityType, level); + } + + @Inject(method = "convertToZombieType", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/Zombie;supportsBreakDoorGoal()Z"), locals = LocalCapture.CAPTURE_FAILSOFT) + private void mixin(EntityType entityType, CallbackInfo ci, Zombie zombie) { + if (CarpetSettings.mobConvertKeepNBTTagsFix) { + this.getActiveEffects().forEach(zombie::addEffect); + zombie.setRemainingFireTicks(this.getRemainingFireTicks()); + zombie.setLeftHanded(this.isLeftHanded()); + zombie.setNoGravity(this.isNoGravity()); + zombie.setPortalCooldown(this.getPortalCooldown()); + zombie.setXRot(this.getXRot()); + zombie.setYRot(this.getYRot()); + zombie.setYBodyRot(this.getVisualRotationYInDegrees()); + zombie.setYHeadRot(this.getYHeadRot()); + zombie.setSilent(this.isSilent()); + this.getTags().forEach(zombie::addTag); + zombie.setUUID(this.getUUID()); + } + } +} diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index c6af4fd698..a9ee273d69 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -26,6 +26,13 @@ "ServerStatus_motdMixin", "MinecraftServer_pingPlayerSampleLimit", "HugeFungusFeatureMixin", + "Villager_bugFixMixin", + "MushroomCow_bugFixMixin", + "ZombieVillager_bugFixMixin", + "AbstractPiglin_bugFixMixin", + "Tadpole_bugFixMixin", + "Slime_bugFixMixin", + "Zombie_bugFixMixin", "MinecraftServer_coreMixin",