diff --git a/src/main/java/com/tiedup/remake/core/TiedUpMod.java b/src/main/java/com/tiedup/remake/core/TiedUpMod.java index 6b13fd9..3aa3615 100644 --- a/src/main/java/com/tiedup/remake/core/TiedUpMod.java +++ b/src/main/java/com/tiedup/remake/core/TiedUpMod.java @@ -137,6 +137,9 @@ public class TiedUpMod { // Register dispenser behaviors (must be on main thread) event.enqueueWork(DispenserBehaviors::register); + + // RIG Phase 2 — dispatcher EntityType → EntityPatch (PLAYER Phase 2, NPCs Phase 5) + event.enqueueWork(com.tiedup.remake.rig.patch.EntityPatchProvider::registerEntityPatches); } /** @@ -185,6 +188,9 @@ public class TiedUpMod { // Initialize animation system event.enqueueWork(() -> { + // RIG Phase 2 — override client dispatch PLAYER → Local/Client/ServerPlayerPatch + com.tiedup.remake.rig.patch.EntityPatchProvider.registerEntityPatchesClient(); + // Initialize unified BondageAnimationManager com.tiedup.remake.client.animation.BondageAnimationManager.init(); LOGGER.info("BondageAnimationManager initialized"); diff --git a/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelBaker.java b/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelBaker.java index 86f72e5..bcc3b2a 100644 --- a/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelBaker.java +++ b/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelBaker.java @@ -32,11 +32,14 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.registries.ForgeRegistries; import com.tiedup.remake.rig.mesh.SkinnedMesh; import com.tiedup.remake.rig.mesh.HumanoidMesh; import com.tiedup.remake.rig.TiedUpRigConstants; +@OnlyIn(Dist.CLIENT) public class HumanoidModelBaker { static final Map BAKED_MODELS = Maps.newHashMap(); static final List MODEL_TRANSFORMERS = Lists.newArrayList(); @@ -85,7 +88,12 @@ public class HumanoidModelBaker { if (!EXCEPTIONAL_MODELS.contains(armorItem)) { if (forgeModel == originalModel || !(forgeModel instanceof HumanoidModel humanoidModel)) { - return entityMesh.getHumanoidArmorModel(slot).get(); + // RIG Phase 0 : Meshes.HELMET/CHESTPLATE/LEGGINS/BOOTS strippés → + // HumanoidMesh.getHumanoidArmorModel(slot) retourne null. + // Safe-guard ici pour éviter NPE si bakeArmor est appelé avant que + // V3-REW-04 soit implémenté (armor rendering rework). + var armorAccessor = entityMesh.getHumanoidArmorModel(slot); + return armorAccessor != null ? armorAccessor.get() : null; } for (HumanoidModelTransformer modelTransformer : MODEL_TRANSFORMERS) { diff --git a/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelTransformer.java b/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelTransformer.java index e7c340d..3bdfd80 100644 --- a/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelTransformer.java +++ b/src/main/java/com/tiedup/remake/rig/mesh/transformer/HumanoidModelTransformer.java @@ -14,10 +14,14 @@ import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.client.model.HumanoidModel; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + import com.tiedup.remake.rig.mesh.MeshPartDefinition; import com.tiedup.remake.rig.mesh.SingleGroupVertexBuilder; import com.tiedup.remake.rig.mesh.SkinnedMesh; +@OnlyIn(Dist.CLIENT) public abstract class HumanoidModelTransformer { public abstract SkinnedMesh transformArmorModel(HumanoidModel humanoidModel); diff --git a/src/main/java/com/tiedup/remake/rig/mesh/transformer/VanillaModelTransformer.java b/src/main/java/com/tiedup/remake/rig/mesh/transformer/VanillaModelTransformer.java index bb78f81..8ee4571 100644 --- a/src/main/java/com/tiedup/remake/rig/mesh/transformer/VanillaModelTransformer.java +++ b/src/main/java/com/tiedup/remake/rig/mesh/transformer/VanillaModelTransformer.java @@ -36,8 +36,12 @@ import com.tiedup.remake.rig.math.OpenMatrix4f; import com.tiedup.remake.rig.math.QuaternionUtils; import com.tiedup.remake.rig.math.Vec2f; import com.tiedup.remake.rig.math.Vec3f; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + import com.tiedup.remake.rig.mixin.client.MixinAgeableListModel; +@OnlyIn(Dist.CLIENT) public class VanillaModelTransformer extends HumanoidModelTransformer { public static final SimpleTransformer HEAD = new SimpleTransformer(AABB.ofSize(new Vec3(0.0D, -4.0D, 0.0D), 8.0D, 8.0D, 8.0D), 9); public static final SimpleTransformer LEFT_FEET = new SimpleTransformer(AABB.ofSize(new Vec3(0.0D, -4.0D, 0.0D), 8.0D, 8.0D, 8.0D), 5); diff --git a/src/main/java/com/tiedup/remake/rig/patch/EntityPatchProvider.java b/src/main/java/com/tiedup/remake/rig/patch/EntityPatchProvider.java index f696fae..7ad9701 100644 --- a/src/main/java/com/tiedup/remake/rig/patch/EntityPatchProvider.java +++ b/src/main/java/com/tiedup/remake/rig/patch/EntityPatchProvider.java @@ -148,4 +148,14 @@ public class EntityPatchProvider implements ICapabilityProvider, NonNullSupplier public LazyOptional getCapability(Capability cap, Direction side) { return cap == TiedUpCapabilities.CAPABILITY_ENTITY ? this.optional.cast() : LazyOptional.empty(); } + + /** + * Invalide la {@link LazyOptional} portée par ce provider. À appeler depuis + * {@code AttachCapabilitiesEvent.addListener} — sans ça les références vers + * le patch, l'animator et l'armature persistent à chaque respawn / dimension + * change → fuite mémoire. + */ + public void invalidate() { + this.optional.invalidate(); + } } diff --git a/src/main/java/com/tiedup/remake/rig/patch/TiedUpCapabilityEvents.java b/src/main/java/com/tiedup/remake/rig/patch/TiedUpCapabilityEvents.java index 4419e69..c59ec3e 100644 --- a/src/main/java/com/tiedup/remake/rig/patch/TiedUpCapabilityEvents.java +++ b/src/main/java/com/tiedup/remake/rig/patch/TiedUpCapabilityEvents.java @@ -69,5 +69,10 @@ public class TiedUpCapabilityEvents { // l'entity commence son premier tick. patch.onConstructed(entity); event.addCapability(ENTITY_CAPABILITY_KEY, provider); + + // CRITICAL : invalide la LazyOptional au respawn / dim change, sinon + // chaque mort fuit patch + animator + armature. Pattern Forge standard + // (cf. V2BondageEquipmentProvider.invalidate, CapabilityEventHandler:50). + event.addListener(provider::invalidate); } }