Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing a global script variable does not re-trigger an important info dependent on it #719

Open
mmind opened this issue Jan 15, 2025 · 6 comments
Labels
bug Something isn't working

Comments

@mmind
Copy link
Contributor

mmind commented Jan 15, 2025

Of course again Gothic 1 ;-) .

Reaching the Fokus mission with gorn, the important info at the gate does not trigger a response.

All previous steps work, Gorn + Player reach the closed gate and Gorn tells the story about nobody being able to open the gate.

Then the player transforms into a meatbug, crawls through a tiny crack in the wall and opens the gate from the other side, and the story continues.

The condition for that continuation is Npc_KnowsInfo(hero, Info_Gorn_RUINJOIN) || Npc_KnowsInfo(hero, Info_Gorn_RUINLEAVE)) && MonasteryRuin_GateOpen , checking that global variable MonasteryRuin_GateOpen .

Handling the monastery gate, sets that global variable, but Gorn will stay stuck in front of the gate. I checked the value being correct after opening the gate.

If I cheat over the wall fast, while Gorn is still walking towards the gate, it will actually trigger the correct sequence. Only after he reaches the gate, opening it will not trigger the Npc to reevaluate that condition it seems - but I'm not sure.

After digging around for a while, I don't really know which part to still poke about this ;-) .

@mmind mmind added the bug Something isn't working label Jan 15, 2025
@mmind
Copy link
Contributor Author

mmind commented Jan 15, 2025

Alternatively, opening the gate, retrieving the Fokus alone and returning to Gorn then trigger both the "You opened the gate" and also the "You found the Fokus" info blocks - of course we're in the very wrong place then for the Troll that appears then.

@Try
Copy link
Owner

Try commented Jan 15, 2025

Dialog system has 2 major point of checking condition:

  1. GameScript::npc_checkinfo - npc calls it from time-to-time
  2. GameScript::dialogChoices - when player starts dialog

I'm assuming for now, that Gorm uses npc_checkinfo route and evaluates conditional. There is no result caching in C++ side on purpose.
More likely MC_MONASTERYRUIN_GATE was never called and global state wasn't updated

@mmind
Copy link
Contributor Author

mmind commented Jan 16, 2025

I've overridden the printdebugnpc function, to make the script less talkative ;-) and found that that yes MC_MONASTERYRUIN_GATE runs and the variable also is set correctly

[zspy,24]: ### MC_MONASTERYRUIN_GATE
[zspy,24]: ### ...noch nie ge�ffnet // first action
[zspy,24]: ### MC_MONASTERYRUIN_GATE
[zspy,24]: ### ...schonmal ge�ffnet // output on second interaction if the variable was set already

I've also looked up a Lets play again to verify that yes, Gorn is supposed to start talking to me on his own :-)

From even more digging through the logs (thankfully the G1 scripts are full of them), I see some valuable information.
Is it possible that the engine ended in a strange state after ending the meatbug spell?

When reaching the gate and the important info works, I see

// earlier action point
[zspy,6]: ### Gorn ### -> PrintGlobals
[zspy,6]: ### Gorn ### -> ...self:   Gorn
[zspy,6]: ### Gorn ### -> ...other:  Ich
[zspy,6]: ### Gorn ### -> ...victim: Ich
[zspy,6]: ### Gorn ### -> ...hero:   Ich
[zspy,6]: ### Gorn ### -> ...item:   Krallen
[zspy,6]: ### Gorn ### -> ... to far
[zspy,6]: ### Gorn ### -> B_AssessSc
[zspy,8]: ### Gorn ### -> ...SC sichtbar und in Dialogreichweite!
--> hlp_getinstanceid 7264
--> hlp_getinstanceid -1
--> hlp_getinstanceid 7264
--> hlp_getinstanceid 7264
[zspy,6]: ### Gorn ### -> B_CheckForImportantInfo
[zspy,9]: ### Gorn ### -> C_NpcIsHuman
[zspy,9]: ### Gorn ### -> ...name: Ich
[zspy,9]: ### Gorn ### -> ...true
[zspy,8]: ### Gorn ### -> ...SC spricht nicht!
--> hlp_getinstanceid 7264
--> hlp_getinstanceid -1
--> hlp_getinstanceid 7264
--> hlp_getinstanceid 7264
--> npc_checkinfo npc Gorn hero Ich imp 1

But after returning from the meatbug spell and opening the gate this looks differently:

[zspy,6]: ### Gorn ### -> PrintGlobals
[zspy,6]: ### Gorn ### -> ...self:   Gorn
[zspy,6]: ### Gorn ### -> ...other:  Ich
[zspy,6]: ### Gorn ### -> ...victim: Ich
[zspy,6]: ### Gorn ### -> ...hero:   Fleischwanze  //meatbug
[zspy,6]: ### Gorn ### -> ...item:   Wanzenfleisch

[zspy,6]: ### Gorn ### -> B_CheckForImportantInfo
[zspy,9]: ### Gorn ### -> C_NpcIsHuman
[zspy,9]: ### Gorn ### -> ...name: Ich
[zspy,9]: ### Gorn ### -> ...true
[zspy,8]: ### Gorn ### -> ...SC spricht nicht!
--> hlp_getinstanceid 6071
--> hlp_getinstanceid -1
--> hlp_getinstanceid 6071
--> hlp_getinstanceid 7264

With the script doing at that place:

B_CheckForImportantInfo {
    var C_NPC her;  her = Hlp_GetNpc(PC_Hero);
    var C_NPC rock; rock = Hlp_GetNpc(PC_Rockefeller);

    if ( (Hlp_GetInstanceID(her)!=Hlp_GetInstanceID(Hero))&&(Hlp_GetInstanceID(rock)!=Hlp_GetInstanceID(Hero)) )
        return false;
    ...
    //reached at earlier action-points, but not after opening the gate
}

So somehow I'd think the Hero global is still the meatbug?

@mmind
Copy link
Contributor Author

mmind commented Jan 17, 2025

2 things I found out this morning:

  • vm.global_hero() seems to be set correctly ... initializeInstanceNpc (from transform-casting), global_hero() is "Ich" before and Meatbug after ... and when hlp_getinstanceid is called at least global_hero() does point to "Ich" again
  • PrintGlobals is a debug function from the Gothic 1 scripts, and there hero seems to be a Meatbug though
  • when I save the game after opening the gate and loading that again, hero is correct again and Gorn will talk to me

Discrepancy between Script-"hero" being meatbug, while findNpc(vm.global_hero())->displayName() is "Ich"

[zspy,2]: ### Gorn ### -> ZS_Stay_Loop
[zspy,6]: ### Gorn ### -> B_AssessQuietSound
[zspy,6]: ### Gorn ### -> PrintGlobals
[zspy,6]: ### Gorn ### -> ...self:   Gorn
[zspy,6]: ### Gorn ### -> ...other:  Ich
[zspy,6]: ### Gorn ### -> ...victim: Ich
[zspy,6]: ### Gorn ### -> ...hero:   Fleischwanze
[zspy,6]: ### Gorn ### -> ...item:   Wanzenfleisch
[zspy,6]: ### Gorn ### -> ... to far
[zspy,6]: ### Gorn ### -> B_AssessSc
[zspy,8]: ### Gorn ### -> ...SC sichtbar und in Dialogreichweite!
--> hlp_getinstanceid 6071 hero is Ich
--> hlp_getinstanceid -1 hero is Ich
--> hlp_getinstanceid 6071 hero is Ich
--> hlp_getinstanceid 7264 hero is Ich
[zspy,6]: ### Gorn ### -> B_CheckForImportantInfo
[zspy,9]: ### Gorn ### -> C_NpcIsHuman
[zspy,9]: ### Gorn ### -> ...name: Ich
[zspy,9]: ### Gorn ### -> ...true
[zspy,8]: ### Gorn ### -> ...SC spricht nicht!
--> hlp_getinstanceid 6071 hero is Ich
--> hlp_getinstanceid -1 hero is Ich
--> hlp_getinstanceid 6071 hero is Ich
--> hlp_getinstanceid 7264 hero is Ich
[zspy,8]: ### Gorn ### -> C_NpcIsInFightMode
[zspy,8]: ### Gorn ### -> ...false
[zspy,9]: ### Gorn ### -> C_BodyStateContains()
[zspy,9]: ### Gorn ### -> bodystate: 32770
[zspy,9]: ### Gorn ### -> bodystate&(BS_MAX|BS_FLAG_INTERRUPTABLE|BS_FLAG_FREEHANDS): 32770
[zspy,9]: ### Gorn ### -> Npc_GetBodyState(slf): 3
[zspy,9]: ### Gorn ### -> Npc_GetBodyState(slf)&(BS_MAX|BS_FLAG_INTERRUPTABLE|BS_FLAG_FREEHANDS): 3
[zspy,9]: ### Gorn ### -> ...false
[zspy,8]: ### Gorn ### -> ...SC schleicht NICHT!
[zspy,8]: ### Gorn ### -> ...SC au�erhalb ObserveIntruder-Reichweite!
[zspy,6]: ### Gorn ### -> B_AssessQuietSound
[zspy,6]: ### Gorn ### -> PrintGlobals
[zspy,6]: ### Gorn ### -> ...self:   Gorn
[zspy,6]: ### Gorn ### -> ...other:  Ich
[zspy,6]: ### Gorn ### -> ...victim: Ich
[zspy,6]: ### Gorn ### -> ...hero:   Fleischwanze
[zspy,6]: ### Gorn ### -> ...item:   Wanzenfleisch
[zspy,6]: ### Gorn ### -> ... to far

after save-load cycle everything is in sync again:

[zspy,6]: ### Gorn ### -> B_AssessQuietSound
[zspy,6]: ### Gorn ### -> PrintGlobals
[zspy,6]: ### Gorn ### -> ...self:   Gorn
[zspy,6]: ### Gorn ### -> ...other:  Ich
[zspy,6]: ### Gorn ### -> ...victim: Ich
[zspy,6]: ### Gorn ### -> ...hero:   Ich
[zspy,6]: ### Gorn ### -> ...item:   Wanzenfleisch
[zspy,6]: ### Gorn ### -> ... to far
[zspy,2]: ### Gorn ### -> ZS_Stay_Loop
[zspy,6]: ### Gorn ### -> B_AssessSc
[zspy,8]: ### Gorn ### -> ...SC sichtbar und in Dialogreichweite!
--> hlp_getinstanceid 7264 hero is Ich
--> hlp_getinstanceid -1 hero is Ich
--> hlp_getinstanceid 7264 hero is Ich
--> hlp_getinstanceid 7264 hero is Ich
[zspy,6]: ### Gorn ### -> B_CheckForImportantInfo
[zspy,9]: ### Gorn ### -> C_NpcIsHuman
[zspy,9]: ### Gorn ### -> ...name: Ich
[zspy,9]: ### Gorn ### -> ...true
[zspy,8]: ### Gorn ### -> ...SC spricht nicht!
--> hlp_getinstanceid 7264 hero is Ich
--> hlp_getinstanceid -1 hero is Ich
--> hlp_getinstanceid 7264 hero is Ich
--> hlp_getinstanceid 7264 hero is Ich
--> npc_checkinfo npc Gorn hero Ich imp 1
[zspy,8]: ### Gorn ### -> ...wichtige Info zu vergeben!

@Try
Copy link
Owner

Try commented Jan 22, 2025

Hi,
Can you please provide me a .sav file for this issue as well? Thanks!

@mmind
Copy link
Contributor Author

mmind commented Jan 22, 2025

save_slot_14.zip

In the savegame we're in the middle of that monastery quest. The part in the canyon is already done, we already have the meatbug spell and are on the way to the gate.

So you'll get the "they say this gate has never been opened before" cinematic from Gorn and then:

  • if you transform into the meatbug, crawl under the wall, transform back, open the gate and walk towards gorn - gorn is stuck
  • vault over wall in marvin mode (without transforming), open the gate and walk towards gorn - the expected cinematic plays

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants