Probleme
Les items au sol etaient simplement affiches comme sprites (apres correction
textures de la session 111), mais le joueur pouvait passer a travers sans
rien ramasser. Pas d’inventaire, pas de feedback. Il fallait :
- Detecter la collision joueur ↔ item (memes conditions que l’ASM)
- Lire les tables {@code GLFT_AmmoGive_l} / {@code GLFT_GunGive_l} pour
determiner ce que la collecte donne (sante, ammo, arme, etc.) - Appliquer ces deltas a l’inventaire du joueur
- Retirer le sprite visuellement
- Afficher un feedback (message + indicateur HUD)
Diagnostic ASM
Detection collision (cf. {@code newaliencontrol.s::Plr1_CheckObjectCollide},
ligne ~1700) :
; meme zone ?
move.w Plr1_Zone_w, d7
cmp.w ObjT_ZoneID_w(a0), d7
bne .NotSameZone
; difference Y < ODefT_CollideHeight_w ?
move.l Plr1_YOff_l, d7
asr.l #7, d7
sub.w 4(a0), d7
cmp.w ODefT_CollideHeight_w(a2), d7
bgt .NotSameZone
; distance XZ < ODefT_CollideRadius_w ?
move.w ODefT_CollideRadius_w(a2), d2
muls d2, d2
jsr CheckHit
Application de la collecte (cf. {@code Plr1_CollectItem}, ligne ~1640) :
lea GLFT_AmmoGive_l(a2), a1
add.l #GLFT_GunGive_l, a2
muls #AmmoGiveLen, d0 ; AmmoGiveLen = 22*2 = 44
muls #GunGiveLen, d1 ; GunGiveLen = 12*2 = 24
add.w d1, a2
add.w d0, a1
; a1 -> ammoGive[defIdx] : [Health, JetpackFuel, Ammo[20]]
; a2 -> gunGive[defIdx] : [Shield, JetPack, Weapons[10]]
CALLC Game_AddToInventory ; merge dans Plr1_Invetory
Tables d’inventaire (offsets dans {@code test.lnk}, calcules depuis defs.i) :
| Offset | Table | Taille | Description |
|---|---|---|---|
0x5A08 |
GLFT_ObjectDefs |
30×40 | ODefT (behaviour, gfxType, colRadius…) |
0x5EB8 |
GLFT_ObjectDefAnims_l |
30×120 | Anim repos (cf. session 111) |
0x6CC8 |
GLFT_ObjectActAnims_l |
30×120 | Anim active (computers en pulsation, etc.) |
0x7AD8 |
GLFT_AmmoGive_l |
30×44 | InvCT par def : Health, JetpackFuel, Ammo[20] |
0x7FF8 |
GLFT_GunGive_l |
30×24 | InvIT par def : Shield, JetPack, Weapons[10] |
Architecture Java (4 fichiers modifies + 2 nouveaux)
Pipeline donnees
-
LnkParser.java: ajout des constantes
OFS_OBJECT_ACT_ANIMS=0x6CC8,OFS_AMMO_GIVE=0x7AD8,OFS_GUN_GIVE=0x7FF8
et des methodesgetAmmoGive(defIdx)/getGunGive(defIdx)qui lisent
les structs InvCT (22 WORDs) et InvIT (12 WORDs). -
LevelJsonExporter.java: ajouteammoGiveetgunGive(tableaux
de 22/12 ints) dans chaque entree deobjects[]dudefinitions.json. -
LevelSceneBuilder.addItems: exposecolRadiusetcolHeighten
userDatasur chaque sprite, pour permettre au PickupSystem de tester
la collision sans avoir a re-lire les definitions.
Runtime gameplay
-
combat/PlayerHealthState.java(nouveau) : pendant de
PlayerCombatState, gere les champs PlrT lies a la sante et items :
–health/maxHealth(PlrT_Health_w) – default 200
–jetpackFuel/maxJetpackFuel(PlrT_JetpackFuel_w) – default 200
–shield(PlrT_Shield_w)
–jetpackOwned(PlrT_Jetpack_w)
–keysMask(PlrT_Keys_b, bitmask 8-bit) -
world/PickupSystem.java(nouveau) :
– Charge les definitions d’objets depuisdefinitions.json(ammoGive +
gunGive + colRadius/colHeight + sfx).
–update(playerPos): balayeitemsNode, pour chaque sprite
COLLECTABLE (typeId=1, behaviour=0) dans la meme zone que le joueur,
teste la distance XZ et Y. Si OK : applique les deltas et detache.
– Skip les items deja « max » (= rien a ajouter, comportement ASM-fidele).
– Marge horizontalePICKUP_RADIUS_MARGIN = 0.3JME (~10 cm) pour
faciliter le ramassage en passant. -
app/GameAppState.java: wiring complet :
– ChampshealthState,pickupSystem,hudState
– Initialisation aprescombatStatedans le try{}
– AppelpickupSystem.update(playerPos)apresapplyZoneLogicdansupdate()
– Overlay debug enrichi : ligneHP:200/200 Fuel:N [Jetpack] Picked:5
Comportement actuel
- Ramassable : Medipac (HP), ShotgunShells (ammo), Plasmaclip (ammo),
Passkey (keysMask), grenades (ammo), Plasmagun/Shotgun (weapons), etc. - Non ramassable : Computer / Generator / Ventfan (behaviour=2 DESTRUCTABLE,
necessite des tirs), Lamp / decorations (behaviour=3 DECORATION). - Non implemente : Activatable (computers via SPACE) – viendra plus tard.
Pour tester
./gradlew convertLevels # regen definitions.json avec ammoGive/gunGive
./gradlew buildScenes # regen scenes avec colRadius/colHeight userData
./gradlew run
Avancer sur un Medipac : l’overlay debug doit montrer HP: 200/200 -> +X HP,
le sprite disparait, le compteur Picked:N s’incremente. Les logs montrent :
Collected: Medipac (defIdx=1) +50 HP -> PlayerHealth{HP=200/200 ...}
Limitations / TODO
- Audio : pas encore d’AudioManager. Le son SFX[4] = « collect » devra
etre joue viaAud_SampleNum_w = 4(cf.Plr1_CollectItemASM).
TODO en commentaire dansPickupSystem.collect(). - HUD visuel :
HudAppStateest cree mais pas attache au stateManager
(desactive session 75). Les messages « Got Medipac » sont juste loggues.
Quand on reactivera le HUD ils s’afficheront automatiquement. - Activatable objects : computers / switches qui demandent SPACE.
Necessite la touche SPACE + check distance + animation « activated ». - Destructable : computers a detruire (tir + hitPoints). Probablement
deja partiellement gere parPlayerShootSystemmais a verifier. - Affichage messages level : les
messages[]du JSON (briefings,
hints) ne sont pas affiches a la collecte d’objets ayant un
displayTextnon-nul (cf. ASMPlr1_CollectItem.notext).
Fichiers modifies / nouveaux
Nouveaux :
– combat/PlayerHealthState.java : sante / fuel / shield / jetpack / keys
– world/PickupSystem.java : detection collision + application collecte
Modifies :
– tools/LnkParser.java : offsets et accesseurs getAmmoGive / getGunGive
– tools/LevelJsonExporter.java : ajoute ammoGive / gunGive dans definitions.json
– tools/LevelSceneBuilder.java : expose colRadius / colHeight en userData
– app/GameAppState.java : wiring + appel pickupSystem.update + overlay HP