diff --git a/src/main/java/com/tiedup/remake/rig/TiedUpArmatures.java b/src/main/java/com/tiedup/remake/rig/TiedUpArmatures.java index e004a66..202ec42 100644 --- a/src/main/java/com/tiedup/remake/rig/TiedUpArmatures.java +++ b/src/main/java/com/tiedup/remake/rig/TiedUpArmatures.java @@ -89,7 +89,20 @@ public final class TiedUpArmatures { * le cache.

*/ private static final class Holder { - static final HumanoidArmature INSTANCE = buildBiped(); + static final HumanoidArmature INSTANCE; + static { + // Signal visible au dev que les joints sont en identity transform. + // Sans ça, Phase 2.6+ câblera le renderer et le mesh apparaîtra + // "effondré à l'origine" sans signal — debug cauchemar. Le warn + // n'apparaît qu'une fois (class-init lock JVM). + TiedUpRigConstants.LOGGER.warn( + "TiedUpArmatures.BIPED initialized with IDENTITY joint transforms (Phase 2.4 stub). " + + "Mesh will render collapsed-to-origin until Phase 2.7 provides biped.json " + + "Blender-authored offsets. See docs/plans/rig/PHASE0_DEGRADATIONS.md " + + "Phase 2.4 backlog entry #1." + ); + INSTANCE = buildBiped(); + } private Holder() {} } diff --git a/src/main/java/com/tiedup/remake/rig/render/PHumanoidRenderer.java b/src/main/java/com/tiedup/remake/rig/render/PHumanoidRenderer.java index d656efc..d88ba71 100644 --- a/src/main/java/com/tiedup/remake/rig/render/PHumanoidRenderer.java +++ b/src/main/java/com/tiedup/remake/rig/render/PHumanoidRenderer.java @@ -76,7 +76,20 @@ public class PHumanoidRenderer renderer, T entitypatch, E entity, OpenMatrix4f[] poses, MultiBufferSource buffer, PoseStack poseStack, int packedLight, float partialTicks) { float f = MathUtils.lerpBetween(entity.yBodyRotO, entity.yBodyRot, partialTicks); float f1 = MathUtils.lerpBetween(entity.yHeadRotO, entity.yHeadRot, partialTicks); @@ -203,7 +202,12 @@ public abstract class PatchedLivingEntityRenderer layer : renderer.layers) { + // P0-BUG-002 (review Phase 2.5) : copie défensive de renderer.layers — + // la liste est mutable et peut être touchée par des mods tiers (cosmetics, + // wildfire gender, skin layers 3D) qui ajoutent un layer runtime via + // AddLayers event. Sans copie, CME garantie dès qu'un autre mod mute + // la liste pendant notre itération. + for (RenderLayer layer : Lists.newArrayList(renderer.layers)) { Class layerClass = layer.getClass(); if (layerClass.isAnonymousClass()) { @@ -211,14 +215,19 @@ public abstract class PatchedLivingEntityRenderer → PatchedLayer>. + @SuppressWarnings({ "rawtypes", "unchecked" }) PatchedLayer patchedLayer = this.patchedLayers.get(layerClass); patchedLayer.renderLayer(entity, entitypatch, layer, poseStack, buffer, packedLight, poses, bob, f2, f7, partialTicks); } } for (PatchedLayer> patchedLayer : this.customLayers) { - @SuppressWarnings("rawtypes") + @SuppressWarnings({ "rawtypes", "unchecked" }) PatchedLayer raw = patchedLayer; raw.renderLayer(entity, entitypatch, null, poseStack, buffer, packedLight, poses, bob, f2, f7, partialTicks); } diff --git a/src/main/java/com/tiedup/remake/rig/render/TiedUpPlayerRenderer.java b/src/main/java/com/tiedup/remake/rig/render/TiedUpPlayerRenderer.java index 310724a..cd85720 100644 --- a/src/main/java/com/tiedup/remake/rig/render/TiedUpPlayerRenderer.java +++ b/src/main/java/com/tiedup/remake/rig/render/TiedUpPlayerRenderer.java @@ -9,6 +9,7 @@ package com.tiedup.remake.rig.render; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.layers.PlayerItemInHandLayer; import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.world.entity.EntityType; import net.minecraftforge.api.distmarker.Dist; @@ -38,9 +39,16 @@ import com.tiedup.remake.rig.patch.ClientPlayerPatch; *
  • {@code ArrowLayer} — flèches plantées dans le player (V3-REW-09)
  • *
  • {@code BeeStingerLayer} — dards d'abeille plantés (V3-REW-09)
  • *
  • {@code CapeLayer} — cape vanilla (V3-REW-08, compat skin layers)
  • - *
  • {@code PlayerItemInHandLayer} — items en main (version player-spécifique, - * distincte de {@link net.minecraft.client.renderer.entity.layers.ItemInHandLayer}) — - * le layer vanilla continue de dessiner jusqu'à la Phase 3
  • + * + * + *

    Layers mappés Phase 2.5 :

    + *
      + *
    • {@code HumanoidArmorLayer} → {@code PatchedArmorLayer} (hérité de PHumanoidRenderer)
    • + *
    • {@code ItemInHandLayer} → {@code PatchedItemInHandLayer} (hérité de PHumanoidRenderer)
    • + *
    • {@link PlayerItemInHandLayer} → {@code PatchedItemInHandLayer} (ajouté ici, + * P1-RISK-003 review Phase 2.5 : dispatch par classe stricte, PlayerItemInHandLayer + * extends ItemInHandLayer mais {@code .getClass()} diffère → sans mapping explicite, + * double-draw item quand Phase 3 câblera le vrai rendu)
    • *
    * *

    Fork conceptuel de {@code yesman.epicfight.client.renderer.patched.entity.PPlayerRenderer} @@ -51,6 +59,17 @@ public class TiedUpPlayerRenderer extends PHumanoidRenderer entityType) { super(Meshes.BIPED, context, entityType); + + // P1-RISK-003 (review Phase 2.5) : PlayerItemInHandLayer extends ItemInHandLayer + // mais le dispatch `patchedLayers.containsKey(layer.getClass())` fait un + // match strict de classe — sans mapping explicite, le stub parent n'est + // pas reconnu et le layer vanilla continue de dessiner (double-draw + // quand Phase 3 activera le vrai rendu item). On réutilise le même stub + // no-op PatchedItemInHandLayer. + // + // Note : pas de problème Phase 2.5 tant que PatchedItemInHandLayer est + // no-op complet (aucun draw dans les 2 layers). Préventif pour Phase 3+. + this.addPatchedLayer(PlayerItemInHandLayer.class, new PatchedItemInHandLayer<>()); } @Override