Aller au contenu principal

Session 134bis — Correctifs progression (porte exit + pickup cles + ejection)

Resume

Session de stabilisation faisant suite à 134 : trois bugs bloquants identifies
et corriges. La progression du niveau A est maintenant fonctionnelle de bout
en bout (spawn -> passkey -> porte exit -> fin de niveau).

Bug 1 — Porte exit s’ouvre sans avoir ramasse la cle

Cause : LevelBinaryParser inversait les masques doorLocks <-> liftLocks
lors du parsing du LONG EntT_DoorsAndLiftsHeld_l (bytes +50..+53 d’un EntT).

L’ASM anim_bss.s:11-12 declare Anim_DoorAndLiftLocks_l comme une UNION
de deux WORDs :
– bytes 50-51 = Anim_DoorAndLiftLocks_l (MSW) -> testee par les DOORS (newanims.s:1420)
– bytes 52-53 = anim_LiftOnlyLocks_w (LSW) -> testee par les LIFTS (newanims.s:1025)

Le big-endian Java ByteBuffer.getInt() lit bytes 50,51,52,53. Donc :
doorLocks = high word = (longVal >> 16) & 0xFFFF
liftLocks = low word = longVal & 0xFFFF

Avant le fix, c’etait l’inverse, ce qui faisait que le bit 10 du passkey LEVEL_A
(qui devrait verrouiller la porte d’index 10 = exit) atterrissait dans
LIFT_MASK au lieu de DOOR_MASK -> aucune porte verrouillee.

  • MODIFIED : src/main/java/com/ab3d2/core/level/LevelBinaryParser.java
    Inversion des deux lignes d’attribution dans le parsing ObjData.

Bug 2 — Aliens (Red Alien notamment) ejectent le joueur hors du niveau

Cause : GameAppState.applyAlienCollision() utilisait setPhysicsLocation()
qui contourne completement Bullet (pas de sweep test, pas de collision murs).
Quand plusieurs Red Aliens convergeaient en chargeant le joueur contre un mur,
la somme des pushes pouvait depasser 1 m/frame -> teleportation a travers le
mur -> ejection du niveau.

La methode CharacterControl.warp() que je voulais utiliser n’existe pas dans
cette version de Minie, donc on garde setPhysicsLocation() mais on plafonne
le delta total a MAX_PUSH_PER_FRAME = 0.3f JME (= 30 cm/frame, soit ~18 m/s
a 60 FPS). Comme tous les murs AB3D2 font au moins 1 JME d’epaisseur cote
collision mesh, un push de 0.3 ne peut jamais transpercer.

  • MODIFIED : src/main/java/com/ab3d2/app/GameAppState.java
    Ajout constante MAX_PUSH_PER_FRAME, clamp du delta dans
    applyAlienCollision().

Bug 3 — Pickup impossible (passkey et tous les autres items)

Cause : PickupSystem chargeait definitions.json depuis le mauvais chemin
(src/main/resources/levels/ = assetsRoot qui contient les binaires Amiga)
au lieu de assets/levels/ (= jmeAssets qui contient le JSON genere par
convertLevels). Resultat : 0 defs chargees -> defs.get(defIndex) toujours
null -> aucun pickup possible.

Fix sur 2 niveaux :

  1. Le passkey doit etre collectable meme sans inventaire a donner (ASM-fidele,
    newaliencontrol.s:554-556). Avant ce fix, meme avec les defs chargees,
    le passkey serait reste au sol car son ammoGive/gunGive est entierement
    nul (sa seule utilite etant de liberer le bit doorLocks=0x400).
    – MODIFIED : src/main/java/com/ab3d2/world/PickupSystem.java
    Verification isLockKey qui force la collecte si doorLocks != 0
    ou liftLocks != 0, meme si rien n’a ete ajoute a l’inventaire.

  2. Le chemin definitions.json corrige :
    – MODIFIED : src/main/java/com/ab3d2/app/GameAppState.java
    new PickupSystem(..., jmeAssets) au lieu de ..., assetsRoot).
    Le FloorDamageSystem utilisait deja le bon chemin, c’etait juste
    le PickupSystem qui avait herite de la mauvaise convention.

Autres ameliorations

  • PickupSystem.update() : usage explicite de Integer.intValue() au lieu de
    l’autobox Integer != int qui peut piegier avec les valeurs > 127 (zoneId
    peut atteindre 134 dans LEVEL_A).
  • Le LevelSceneBuilder.addItems normalise displayText: 65535 (unsigned)
    en -1 (signed) pour matcher le test blt.s .notext de l’ASM
    (newaliencontrol.s:597).

Procedure de validation

# 1. Regenerer les JSON et J3O avec le LevelBinaryParser corrige
.\gradlew convertLevels buildScenes
# 2. Compiler
.\gradlew compileJava
# 3. Lancer
.\gradlew run

Tests reussis (zone progression LEVEL_A) :
– Spawn -> aller vers la porte exit (zone 132) sans avoir le passkey :
la porte reste fermee. ✅
– Aller chercher le passkey (zone 108) : il est ramassable. ✅
Log : Collected: Passkey (defIdx=9) [Key:doors=0x400]
– Revenir a la porte exit : elle s’ouvre. ✅
– Affronter des Red Aliens dans un couloir : pousse le joueur sans
l’ejecter du niveau. ✅

Fichiers touches

MOD   src/main/java/com/ab3d2/core/level/LevelBinaryParser.java  (Bug 1)
MOD   src/main/java/com/ab3d2/app/GameAppState.java              (Bug 2 + Bug 3 path)
MOD   src/main/java/com/ab3d2/world/PickupSystem.java            (Bug 3 isLockKey)
MOD   src/main/java/com/ab3d2/tools/convert/LevelSceneBuilder.java (displayText unsigned)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *