diff --git a/src/main/java/net/modfest/fireblanket/mixin/accessor/ArmorStandEntityAccessor.java b/src/main/java/net/modfest/fireblanket/mixin/accessor/ArmorStandEntityAccessor.java new file mode 100644 index 0000000..a5fe3fd --- /dev/null +++ b/src/main/java/net/modfest/fireblanket/mixin/accessor/ArmorStandEntityAccessor.java @@ -0,0 +1,11 @@ +package net.modfest.fireblanket.mixin.accessor; + +import net.minecraft.entity.decoration.ArmorStandEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ArmorStandEntity.class) +public interface ArmorStandEntityAccessor { + @Accessor + void setDisabledSlots(int d); +} diff --git a/src/main/java/net/modfest/fireblanket/mixin/accessor/ItemFrameAccessor.java b/src/main/java/net/modfest/fireblanket/mixin/accessor/ItemFrameAccessor.java new file mode 100644 index 0000000..c8c8c80 --- /dev/null +++ b/src/main/java/net/modfest/fireblanket/mixin/accessor/ItemFrameAccessor.java @@ -0,0 +1,11 @@ +package net.modfest.fireblanket.mixin.accessor; + +import net.minecraft.entity.decoration.ItemFrameEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ItemFrameEntity.class) +public interface ItemFrameAccessor { + @Accessor + void setFixed(boolean v); +} diff --git a/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinArmorStand.java b/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinArmorStand.java deleted file mode 100644 index 46bdef6..0000000 --- a/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinArmorStand.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.modfest.fireblanket.mixin.entity_immutability; - -import net.minecraft.entity.EntityType; -import net.minecraft.entity.decoration.ArmorStandEntity; -import net.minecraft.world.World; -import net.modfest.fireblanket.Fireblanket; -import net.modfest.fireblanket.mixinsupport.ImmmovableLivingEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ArmorStandEntity.class) -public class MixinArmorStand { - @Shadow - private int disabledSlots; - - @Inject(method = "(Lnet/minecraft/entity/EntityType;Lnet/minecraft/world/World;)V", at = @At("RETURN")) - private void onInit(EntityType entityType, World world, CallbackInfo ci) { - if (world.getGameRules().getBoolean(Fireblanket.NEW_ENTITIES_IMMUTABLE)) { - // Disable all slots by default - this.disabledSlots = 4144959; - // Disable movement (prevents abuse of fishing rods) - if (this instanceof ImmmovableLivingEntity im) { - im.setNoMovement(true); - } - } - } -} diff --git a/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinDecorationItem.java b/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinDecorationItem.java new file mode 100644 index 0000000..4a98789 --- /dev/null +++ b/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinDecorationItem.java @@ -0,0 +1,23 @@ +package net.modfest.fireblanket.mixin.entity_immutability; + +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.entity.decoration.AbstractDecorationEntity; +import net.minecraft.item.DecorationItem; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.util.ActionResult; +import net.modfest.fireblanket.Fireblanket; +import net.modfest.fireblanket.util.ImmutableEntities; +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.CallbackInfoReturnable; + +@Mixin(DecorationItem.class) +public class MixinDecorationItem { + @Inject(method = "useOnBlock(Lnet/minecraft/item/ItemUsageContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getOrDefault(Lnet/minecraft/component/ComponentType;Ljava/lang/Object;)Ljava/lang/Object;")) + private void onInitSpawnedEntity(ItemUsageContext context, CallbackInfoReturnable cir, @Local AbstractDecorationEntity entity) { + if (context.getWorld().getGameRules().getBoolean(Fireblanket.NEW_ENTITIES_IMMUTABLE)) { + ImmutableEntities.makeImmutable(entity); + } + } +} diff --git a/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinEntityType.java b/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinEntityType.java new file mode 100644 index 0000000..301f7b3 --- /dev/null +++ b/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinEntityType.java @@ -0,0 +1,31 @@ +package net.modfest.fireblanket.mixin.entity_immutability; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnReason; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.modfest.fireblanket.Fireblanket; +import net.modfest.fireblanket.util.ImmutableEntities; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import java.util.function.Consumer; + +@Mixin(EntityType.class) +public class MixinEntityType { + @WrapOperation(method = "create(Lnet/minecraft/server/world/ServerWorld;Ljava/util/function/Consumer;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/SpawnReason;ZZ)Lnet/minecraft/entity/Entity;", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityType;create(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;")) + private Entity afterCreated(EntityType instance, World world, Operation original, ServerWorld world2, @Nullable Consumer afterConsumer, BlockPos pos, SpawnReason reason, boolean alignPosition, boolean invertY) { + var entity = original.call(instance, world); + if (world.getGameRules().getBoolean(Fireblanket.NEW_ENTITIES_IMMUTABLE) && reason == SpawnReason.SPAWN_EGG) { + if (entity != null) { + ImmutableEntities.makeImmutable(entity); + } + } + return entity; + } +} diff --git a/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinItemFrame.java b/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinItemFrame.java deleted file mode 100644 index cba2e90..0000000 --- a/src/main/java/net/modfest/fireblanket/mixin/entity_immutability/MixinItemFrame.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.modfest.fireblanket.mixin.entity_immutability; - -import net.minecraft.entity.EntityType; -import net.minecraft.entity.decoration.ItemFrameEntity; -import net.minecraft.world.World; -import net.modfest.fireblanket.Fireblanket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ItemFrameEntity.class) -public class MixinItemFrame { - @Shadow - private boolean fixed; - - @Inject(method = "(Lnet/minecraft/entity/EntityType;Lnet/minecraft/world/World;)V", at = @At("RETURN")) - private void onInit(EntityType entityType, World world, CallbackInfo ci) { - if (world.getGameRules().getBoolean(Fireblanket.NEW_ENTITIES_IMMUTABLE)) { - this.fixed = true; - } - } -} diff --git a/src/main/java/net/modfest/fireblanket/util/ImmutableEntities.java b/src/main/java/net/modfest/fireblanket/util/ImmutableEntities.java new file mode 100644 index 0000000..b2cf27d --- /dev/null +++ b/src/main/java/net/modfest/fireblanket/util/ImmutableEntities.java @@ -0,0 +1,27 @@ +package net.modfest.fireblanket.util; + +import net.minecraft.entity.Entity; +import net.modfest.fireblanket.mixin.accessor.ArmorStandEntityAccessor; +import net.modfest.fireblanket.mixin.accessor.ItemFrameAccessor; +import net.modfest.fireblanket.mixinsupport.ImmmovableLivingEntity; + +public class ImmutableEntities { + public static void makeImmutable(Entity entity) { + // Set invulnerability + entity.setInvulnerable(true); + + if (entity instanceof ArmorStandEntityAccessor ae) { + // Disable all slots + ae.setDisabledSlots(4144959); + // Disable movement (prevents abuse of fishing rods) + if (entity instanceof ImmmovableLivingEntity im) { + im.setNoMovement(true); + } + } + + if (entity instanceof ItemFrameAccessor ie) { + // Make item frames fixed + ie.setFixed(true); + } + } +} diff --git a/src/main/resources/fireblanket.mixins.json b/src/main/resources/fireblanket.mixins.json index 6ee460e..f3cfcb8 100644 --- a/src/main/resources/fireblanket.mixins.json +++ b/src/main/resources/fireblanket.mixins.json @@ -4,9 +4,11 @@ "compatibilityLevel": "JAVA_17", "plugin": "net.modfest.fireblanket.FireblanketMixin", "mixins": [ + "accessor.ArmorStandEntityAccessor", "accessor.BlockEntityTypeAccessor", "accessor.ClientConnectionAccessor", "accessor.EntityTypeAccessor", + "accessor.ItemFrameAccessor", "accessor.ServerChunkManagerAccessor", "accessor.ServerLoginNetworkHandlerAccessor", "adventure_fix.MixinItemStack", @@ -17,8 +19,8 @@ "be_sync.MixinChunkHolder", "block.MixinCommandBlock", "block_format.MixinChunkSection", - "entity_immutability.MixinArmorStand", - "entity_immutability.MixinItemFrame", + "entity_immutability.MixinDecorationItem", + "entity_immutability.MixinEntityType", "entity_ticking.MixinDebugStickItem", "entity_ticking.MixinEntity", "entity_ticking.MixinItemGroups",