Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix MC-88967: Mobs when converting don't keep NBT tags #1753

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
8 changes: 8 additions & 0 deletions src/main/java/carpet/CarpetSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,14 @@ public String validate(CommandSourceStack source, CarpetRule<String> 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"},
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/carpet/mixins/AbstractPiglin_bugFixMixin.java
Original file line number Diff line number Diff line change
@@ -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<? extends Mob> 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());
}
}
}
42 changes: 42 additions & 0 deletions src/main/java/carpet/mixins/MushroomCow_bugFixMixin.java
Original file line number Diff line number Diff line change
@@ -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<? extends Mob> 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());
}
}
}
34 changes: 34 additions & 0 deletions src/main/java/carpet/mixins/Slime_bugFixMixin.java
Original file line number Diff line number Diff line change
@@ -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<? extends Mob> 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);
}
}
}
32 changes: 32 additions & 0 deletions src/main/java/carpet/mixins/Tadpole_bugFixMixin.java
Original file line number Diff line number Diff line change
@@ -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<? extends Mob> 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());
}
}
}
42 changes: 42 additions & 0 deletions src/main/java/carpet/mixins/Villager_bugFixMixin.java
Original file line number Diff line number Diff line change
@@ -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<? extends Mob> 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);
}
}
}
38 changes: 38 additions & 0 deletions src/main/java/carpet/mixins/ZombieVillager_bugFixMixin.java
Original file line number Diff line number Diff line change
@@ -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<? extends Mob> 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());
}
}
}
37 changes: 37 additions & 0 deletions src/main/java/carpet/mixins/Zombie_bugFixMixin.java
Original file line number Diff line number Diff line change
@@ -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<? extends Mob> 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<? extends Zombie> 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());
}
}
}
7 changes: 7 additions & 0 deletions src/main/resources/carpet.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",

Expand Down