Quests: main quest items no longer refused, restart resets bit-field variables
AddMainQuestItem refused every new main quest item once the list held an entry with script id 0 (scripts give such items); the Goldbeeren of quest 402 were picked up and lost. The script id test is patched out. Quest variables are bit fields (op 0x44 sets a bit): the quest giver restart now writes the values directly, 0 and 1 (available) for the variable named after the quest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e539cab604
commit
55e48dd302
6 files changed
+126
-20
No files matched your search
+38
-3
@@ -196,7 +196,8 @@ Dialogs without a quest (healers, closed shops: `geschlossen101`,
|
||||
4 trigger area, 0x0f end quest, 0x14 start quest (#id), 0x17 named
|
||||
position, 0x1a dialog text, 0x35 book text, 0x3a / 0x42 if / else if
|
||||
(0x49 var == n, 0x40 "@npc"), 0x3c dialog answer (text, label), 0x3f
|
||||
compass, 0x44 set variable, 0x48 move NPC, 0x56 dialog state.
|
||||
compass, 0x43 / 0x44 / 0x45 / 0x4b variables (see below), 0x48 move NPC,
|
||||
0x56 dialog state.
|
||||
- Script NPC names: "Res:<n>" is a script id (object +0x3c, `0x44a390`); the
|
||||
quest manager maps it to the object (`0x464ec0`, map +0x7668); a spawn sets
|
||||
the entry.
|
||||
@@ -227,8 +228,8 @@ load we need a repair ... if not completed or correctly running".
|
||||
`mods/questgiver.cpp`: a quest's giver is the NPC whose spawn instruction
|
||||
carries a dialog with an answer that accepts the quest (85 givers). When a
|
||||
label of a running quest runs for its dead giver, it is skipped, the quest
|
||||
restarts (failed entry at the giver, the variables only its labels set back to
|
||||
0), and once the body is gone the spawn instruction runs again. After a load,
|
||||
restarts (failed entry at the giver, the variables only its labels set back:
|
||||
0, the one named after the quest 1), and once the body is gone the spawn instruction runs again. After a load,
|
||||
an accepted quest (flag 4) without its giver gets the same. Not yet seen in
|
||||
the game (the escort of "Hetzjagd" arrived alive); see `docs/todo.md` for the
|
||||
audit of how quests can fail.
|
||||
@@ -237,6 +238,40 @@ Lesson (2026-10-26): flag 1 means available, not running; a first version
|
||||
took it for running and reset 16 available quests and spawned their NPCs on
|
||||
Borf (repaired once, then saved).
|
||||
|
||||
## Quest variables are bit fields (measured 2026-10-28)
|
||||
|
||||
Found while repairing "Kräuter für Kräuterhexe" (402; the user knows it as
|
||||
Windgeflüster). Variables live in the quest manager's vector +0x7550 /
|
||||
+0x7554 (0x24-byte entries: name[0x20], value +0x20; `game::ScriptVariable`).
|
||||
Script writes: 0x43 sets the value, 0x44 sets bit n (0x49bb30: value |= 1 <<
|
||||
n), 0x45 clears bit n (0x49c450), 0x4b adds n (0x49cc20). Conditions
|
||||
(`Script_Condition` 0x498aa0): 0x49 bit n set, 0x4a bit n clear (logged "if
|
||||
IsNotVarBit"), 0x48 value == n; a missing variable is false. The variable
|
||||
named after a quest has bit 0 while the quest is available: all 87 quests not
|
||||
yet accepted in a dwarf save had value 1, and nothing in the quest's own labels
|
||||
sets it. Quest 402: accepting sets bit 1, the berries bit 2, the reward bit 3;
|
||||
the giver's dialog offers the quest on bit 0.
|
||||
|
||||
The quest giver restart first ran 0x44 with 0 ("variable = 0"), which set bit
|
||||
0 and cleared nothing: the giver kept saying "Zögerst du in deinen Taten?".
|
||||
A reset to 0 then matched no dialog branch at all. Now the value is written
|
||||
directly: 0, or 1 for the quest's own variable. Confirmed 2026-10-28.
|
||||
|
||||
## Main quest items refused (request 2026-10-28)
|
||||
|
||||
"I cannot finish the Quest Windgeflüster." The berries (type 6029) are an item
|
||||
`Region4Init` places once on the ground near the Goldbeerenbusch (op 0x5e,
|
||||
pickup label `take402`); picking it up logged "cInventoryEntry::addMainQuestItem()
|
||||
Already has mainQuestItem(6029)" and the item was gone.
|
||||
`cInventoryEntry::AddMainQuestItem` (0x5d8240, thiscall (type, script id,
|
||||
notify)) keeps {type, script id} pairs and refuses a new item when an entry
|
||||
has the same type or script id 0 (0x5d83c6); scripts that give an item
|
||||
without a "Res:" id add it with 0 (0x486bd8). The dwarf held {4609, 0}, so
|
||||
every later main quest item was refused (a bug of the original).
|
||||
`mods/questitems.cpp` removes the script id test. The save was repaired once
|
||||
by running `take402` for the hero after the load (quest accepted, bit 2
|
||||
missing); the quest then finished. Confirmed 2026-10-28.
|
||||
|
||||
## Escorts never left behind (2026-10-26)
|
||||
|
||||
"I have lost a follower NPC from the quest 'Die Sklaven der Orks', it's no
|
||||
|
||||
Reference in new issue
Block a user