Argent77 / PST-UB-reloaded

A mod that makes Qwinn's original "PS:T Unfinished Business" available for PST:EE
42 stars 4 forks source link

Broken timers - e.g. `KESAI_TIMER` #5

Closed SomeTroglodyte closed 7 months ago

SomeTroglodyte commented 1 year ago

I just came across this, and cannot comment on the beamdog discussion - registration torture.

My tests show there is a bug, and it's not yours. So perhaps this info helps.

Summary:

Conclusion: The SetGlobalTimer("Kesai_Timer","GLOBAL",ONE_DAY) (the function, not the call) as used in DKESAI.DLG State 92 Response 268 Action 32 is buggy.

Verbose:

Save game where quest has just progressed to the "1 Day wait" stage, NearInfinity shows:

Now the question: When does that timer actually expire? I manipulated KESAI_TIMER in NI and did a binary search to narrow it down. Regrettably I used a different base, quest started later and already rested four times after getting to the 1 Day stage. The save had "Game Seconds" = 100073, "Real seconds" = 2646564, "KESAI_TIMER" = 2663274. ...surprise, with KESAI_TIMER = 1501200 I get a state I can load, run to Kesai and I get the greeting with the 'Are you ready, Kesai?' question, while waiting just a few seconds before initiating dialogue, I get the 'wow Nenny is a sick weirdo' thing. So - that's suspiciously close to "Game Seconds" * 15. Waiting 1 day realworld without quitting the game wouldn't have helped after all. The quest will stall completely for all players that rarely rest, even when a gamer rests often enough so game seconds nears real ticks, so they can eventually progress the quest, that "one day" will never actually be one day. Have previously rested enough, and you can immediately re-enter dialogue after she says 'gimme a day' and her "one day" will already be elapsed.

Argent77 commented 1 year ago

I think you're right. From my own tests it looks like SetGlobalTimer() calculates the expired time based on the "real time" value. That means any subsequent GlobalTimerExpired() checks won't work correctly. You'd have to use RealGlobalTimerExpired() instead for a meaningful check. I'll try to find a workaround.

SomeTroglodyte commented 1 year ago
SetGlobalTimerRandom("Kesai_Timer","GLOBAL",1,1)
IncrementGlobal("Kesai_Timer","GLOBAL",108000)

... madness, but does it.

There's six /.*Set.*Timer/ actions - of the 3 Global ones, Real seems exactly the same as the default Set, but SetGlobalTimerRandom does work relative to game time. But - it's buggy too - with Min=ONE_DAY and Max=ONE_DAY, it will output a random 0..Max not Min..Max. Maybe 7199..7200 would work or Min is ignored altogether, didn't test enough. But using it as a base only... Pity one cannot write ONE_DAY15 or ONE_DAY-1 or such in DLG actions.

Argent77 commented 1 year ago

but SetGlobalTimerRandom does work relative to game time. But - it's buggy too - with Min=ONE_DAY and Max=ONE_DAY, it will output a random 0..Max not Min..Max. Maybe 7199..7200 would work or Min is ignored altogether, didn't test enough. But using it as a base only... Pity one cannot write ONE_DAY*15 or ONE_DAY-1 or such in DLG actions.

It appears to work correctly in regular scripts, but not in dialog action blocks. Using min/max values for SetGlobalTimerRandom() that are only 1 apart seems to work though.

SomeTroglodyte commented 1 year ago

Well, I leave it to you to translate this insight into weidu "code" - or not - no attribution required