mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
D157: objective MinDificulty read at wrong byte on LE -> campaign never unlocks
ROOT CAUSE of 'complete Dam, Facility stays locked'. The type-23 objective record's MinDificulty is a big-endian s32 at word 3; on N64 the value is its low byte == offset 0xF, and struct objective_entry reads 'difficulty' as s8 @0xF. d88_propdefs.py bswap32's word 3, so on little-endian the value moves to offset 0xC -> objective_entry.difficulty @0xF reads 0 for EVERY objective. get_difficulty_for_objective() then returns Agent(0) for all, so objectiveIsAllComplete() on Agent evaluates objectives that should be difficulty-gated out (Dam obj 0 'Neutralize all alarms' is Secret Agent; obj 1/2 are 00 Agent) -> they're incomplete -> never returns TRUE -> end_of_mission_briefing() / the unlock write never runs. User was right: you don't touch an alarm on Agent Dam. Fix (D151-class, #ifdef PORT): reorder struct objective_entry's word-3 tail so 'difficulty' reads @0xC (post-swap position); N64 layout kept under #else. Also fixes dump_objectives.py (was reading byte 0xC = the BE high byte = always 0; hence LEVEL-OBJECTIVES.md said 'Agent' for everything). Dam now decodes obj0=Secret Agent, obj1/2=00 Agent, obj3=Agent. -level_09 coverage identical (phash delta is the M-30 RC2 texture change, not this).
This commit is contained in:
1 parent
9c23e5bcb6
commit
4cd8ccaeac
3 files changed
+17
-6
No files matched your search
+9
-1
@@ -4055,13 +4055,21 @@ struct objective_entry
|
|||||||
enum WATCH_BRIEFING_PAGE menu; // 4
|
enum WATCH_BRIEFING_PAGE menu; // 4
|
||||||
#ifdef PORT
|
#ifdef PORT
|
||||||
u32 text; // 8 (D151: full-word slot id, see above)
|
u32 text; // 8 (D151: full-word slot id, see above)
|
||||||
|
/* D157: the setup converter (d88_propdefs.py) bswap32's word 3 of the
|
||||||
|
type-23 record (MissionObjectiveRecord.MinDificulty). On N64 (BE) the
|
||||||
|
difficulty is the low byte of that word == offset 0xF; after the swap it
|
||||||
|
lands at 0xC on LE. N64 layout kept under #else. */
|
||||||
|
s8 difficulty; // c
|
||||||
|
u8 _md_b2; // d
|
||||||
|
u8 unkD; // e (N64 0xD, post-swap)
|
||||||
|
u8 _md_b0; // f
|
||||||
#else
|
#else
|
||||||
u16 reserved; // 8
|
u16 reserved; // 8
|
||||||
u16 text; // a
|
u16 text; // a
|
||||||
#endif
|
|
||||||
u16 unkC; // c
|
u16 unkC; // c
|
||||||
u8 unkD; // d
|
u8 unkD; // d
|
||||||
s8 difficulty; // f
|
s8 difficulty; // f
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#pragma endregion Objectives
|
#pragma endregion Objectives
|
||||||
|
|
||||||
|
|||||||
@@ -299,12 +299,13 @@ OBJECTIVESTATUS get_status_of_objective(s32 objectiveNum) //#MATCH
|
|||||||
#ifdef PORT
|
#ifdef PORT
|
||||||
if (g_savelogObjOnce && getenv("GE_SAVELOG")) {
|
if (g_savelogObjOnce && getenv("GE_SAVELOG")) {
|
||||||
u32 *rw = (u32 *)objective;
|
u32 *rw = (u32 *)objective;
|
||||||
osSyncPrintf("SAVELOG: crit obj=%d type=%d ObjRefID=%d(0x%x) "
|
osSyncPrintf("SAVELOG: crit obj=%d type=%d ObjRefID=%d "
|
||||||
"TextID=0x%x stride=%d words=[%08x %08x %08x] curstat=%d\n",
|
"TextID=0x%x MinDif=%d stride=%d words=[%08x %08x %08x %08x] "
|
||||||
|
"curstat=%d\n",
|
||||||
objectiveNum, (int)objective->type, (int)objective->ObjRefID,
|
objectiveNum, (int)objective->type, (int)objective->ObjRefID,
|
||||||
(unsigned)objective->ObjRefID, (unsigned)objective->TextID,
|
(unsigned)objective->TextID, (int)objective->MinDificulty,
|
||||||
(int)sizepropdef((PropDefHeaderRecord *)objective),
|
(int)sizepropdef((PropDefHeaderRecord *)objective),
|
||||||
rw[0], rw[1], rw[2], (int)currentstatus);
|
rw[0], rw[1], rw[2], rw[3], (int)currentstatus);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (status == OBJECTIVESTATUS_COMPLETE)
|
if (status == OBJECTIVESTATUS_COMPLETE)
|
||||||
|
|||||||
@@ -156,7 +156,9 @@ def dump_level(levelid, lav_name):
|
|||||||
nblocks += 1
|
nblocks += 1
|
||||||
idx = bs32(buf, off + 4)
|
idx = bs32(buf, off + 4)
|
||||||
textid = be32(buf, off + 8)
|
textid = be32(buf, off + 8)
|
||||||
diff = buf[off + 12]
|
# MinDificulty is a big-endian s32 at word 3 (offset 0xC); the value
|
||||||
|
# lives in its low byte == offset 0xF.
|
||||||
|
diff = buf[off + 15]
|
||||||
print(f"Objective {idx} [briefing text id {textid}] min difficulty: "
|
print(f"Objective {idx} [briefing text id {textid}] min difficulty: "
|
||||||
f"{DIFF_NAMES.get(diff, diff)}")
|
f"{DIFF_NAMES.get(diff, diff)}")
|
||||||
j = i + 1
|
j = i + 1
|
||||||
|
|||||||
Reference in new issue
Block a user