diff --git a/Common/src/main/java/fuzs/armorstatues/api/world/inventory/data/ArmorStandStyleOptions.java b/Common/src/main/java/fuzs/armorstatues/api/world/inventory/data/ArmorStandStyleOptions.java index 5040407..34b9810 100644 --- a/Common/src/main/java/fuzs/armorstatues/api/world/inventory/data/ArmorStandStyleOptions.java +++ b/Common/src/main/java/fuzs/armorstatues/api/world/inventory/data/ArmorStandStyleOptions.java @@ -19,7 +19,8 @@ public enum ArmorStandStyleOptions implements ArmorStandStyleOption { SEALED("sealed", (armorStand, setting) -> { armorStand.setInvulnerable(setting); ((ArmorStandAccessor) armorStand).setDisabledSlots(setting ? ArmorStandStyleOption.ARMOR_STAND_ALL_SLOTS_DISABLED : 0); - }, Entity::isInvulnerable); + }, Entity::isInvulnerable), + NO_HITBOX("noHitbox", (armorStand, setting) -> ArmorStandStyleOption.setArmorStandData(armorStand, setting, ArmorStand.CLIENT_FLAG_MARKER), armorStand -> ArmorStandStyleOption.getArmorStandData(armorStand, ArmorStand.CLIENT_FLAG_MARKER)); private final String translationId; private final BiConsumer newValue; @@ -56,6 +57,7 @@ public void toTag(CompoundTag tag, boolean currentValue) { case NO_BASE_PLATE -> "NoBasePlate"; case NO_GRAVITY -> "NoGravity"; case SEALED -> "Invulnerable"; + case NO_HITBOX -> "Marker"; }; tag.putBoolean(dataKey, currentValue); if (this == ArmorStandStyleOptions.SEALED) { diff --git a/Common/src/main/java/fuzs/armorstatues/mixin/accessor/ArmorStandAccessor.java b/Common/src/main/java/fuzs/armorstatues/mixin/accessor/ArmorStandAccessor.java index 0e68716..82ddc04 100644 --- a/Common/src/main/java/fuzs/armorstatues/mixin/accessor/ArmorStandAccessor.java +++ b/Common/src/main/java/fuzs/armorstatues/mixin/accessor/ArmorStandAccessor.java @@ -3,6 +3,7 @@ import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; @@ -15,6 +16,9 @@ public interface ArmorStandAccessor { @Accessor NonNullList getHandItems(); + @Invoker("getDimensionsMarker") + EntityDimensions getArmorstandDimensions(boolean marker); + @Accessor NonNullList getArmorItems(); diff --git a/Common/src/main/java/fuzs/armorstatues/mixin/redirect/MarkerArmorStandRaytracer.java b/Common/src/main/java/fuzs/armorstatues/mixin/redirect/MarkerArmorStandRaytracer.java new file mode 100644 index 0000000..67c4ccb --- /dev/null +++ b/Common/src/main/java/fuzs/armorstatues/mixin/redirect/MarkerArmorStandRaytracer.java @@ -0,0 +1,36 @@ +package fuzs.armorstatues.mixin.redirect; + +import fuzs.armorstatues.mixin.accessor.ArmorStandAccessor; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.ProjectileUtil; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.function.Predicate; + +@Mixin(ProjectileUtil.class) +public class MarkerArmorStandRaytracer { + @Redirect(method = "getEntityHitResult(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;D)Lnet/minecraft/world/phys/EntityHitResult;", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getBoundingBox()Lnet/minecraft/world/phys/AABB;")) + private static AABB getBoundingBox(Entity a, Entity p) { + if (a instanceof ArmorStand armorStand && p instanceof Player player && player.isShiftKeyDown() && armorStand.isMarker()) { + return ((ArmorStandAccessor) armorStand).getArmorstandDimensions(false).makeBoundingBox(armorStand.position()); + } + return a.getBoundingBox(); + } + + @Redirect(method = "getEntityHitResult(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;D)Lnet/minecraft/world/phys/EntityHitResult;", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getEntities(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;)Ljava/util/List;")) + private static java.util.List getEntities(Level level, Entity p, AABB aabb, Predicate predicate) { + if (p instanceof Player player && player.isShiftKeyDown()) { + Predicate allowMarkerArmorStands = entity -> (entity instanceof ArmorStand armorStand && armorStand.isMarker()); + return level.getEntities(p, aabb, predicate.or(allowMarkerArmorStands)); + } + return level.getEntities(p, aabb, predicate); + } +} diff --git a/Common/src/main/resources/armorstatues.common.mixins.json b/Common/src/main/resources/armorstatues.common.mixins.json index c543bb7..e2b58c8 100644 --- a/Common/src/main/resources/armorstatues.common.mixins.json +++ b/Common/src/main/resources/armorstatues.common.mixins.json @@ -6,7 +6,8 @@ "refmap": "armorstatues.refmap.json", "mixins": [ "accessor.ArmorStandAccessor", - "accessor.SimpleContainerAccessor" + "accessor.SimpleContainerAccessor", + "redirect.MarkerArmorStandRaytracer" ], "client": [ ], diff --git a/Forge/src/generated/resources/assets/armorstatues/lang/en_us.json b/Forge/src/generated/resources/assets/armorstatues/lang/en_us.json index 2787a16..35c1284 100644 --- a/Forge/src/generated/resources/assets/armorstatues/lang/en_us.json +++ b/Forge/src/generated/resources/assets/armorstatues/lang/en_us.json @@ -60,6 +60,8 @@ "armorstatues.screen.style.noBasePlate.description": "Hide the stone base plate at the statue's feet.", "armorstatues.screen.style.noGravity": "No Gravity", "armorstatues.screen.style.noGravity.description": "Prevents the statue from falling down, so it may float freely.", + "armorstatues.screen.style.noHitbox": "No Hitbox", + "armorstatues.screen.style.noHitbox.description": "Allows to place blocks inside the statue, the statue will not fall down and it is no longer possible to interact with it.", "armorstatues.screen.style.sealed": "Sealed", "armorstatues.screen.style.sealed.description": "The statue can no longer be broken, equipment cannot be changed. Disallows opening this menu in survival mode.", "armorstatues.screen.style.showArms": "Show Arms", diff --git a/Forge/src/main/java/fuzs/armorstatues/data/ModLanguageProvider.java b/Forge/src/main/java/fuzs/armorstatues/data/ModLanguageProvider.java index b27ba2b..7fd18fa 100644 --- a/Forge/src/main/java/fuzs/armorstatues/data/ModLanguageProvider.java +++ b/Forge/src/main/java/fuzs/armorstatues/data/ModLanguageProvider.java @@ -40,6 +40,7 @@ protected void addTranslations() { this.add("armorstatues.screen.style.noGravity", "No Gravity"); this.add("armorstatues.screen.style.glowing", "Glowing"); this.add("armorstatues.screen.style.sealed", "Sealed"); + this.add("armorstatues.screen.style.noHitbox", "No Hitbox"); this.add("armorstatues.screen.style.showArms.description", "Shows the statue's arms, so it may hold items in both hands."); this.add("armorstatues.screen.style.small.description", "Makes the statue half it's size like a baby mob."); this.add("armorstatues.screen.style.invisible.description", "Makes the statue itself invisible, but still shows all equipped items."); @@ -48,6 +49,7 @@ protected void addTranslations() { this.add("armorstatues.screen.style.noGravity.description", "Prevents the statue from falling down, so it may float freely."); this.add("armorstatues.screen.style.glowing.description", "Adds a glowing outline to the statue, visible through blocks."); this.add("armorstatues.screen.style.sealed.description", "The statue can no longer be broken, equipment cannot be changed. Disallows opening this menu in survival mode."); + this.add("armorstatues.screen.style.sealed.noHitbox", "Allows to place blocks inside the statue, the statue will not fall down and it is no longer possible to interact with it."); this.add("armorstatues.screen.position.rotation", "Rotation:"); this.add("armorstatues.screen.position.degrees", "%s\u00B0"); this.add("armorstatues.screen.position.moveBy", "Move By:");