Closed thokkat closed 2 months ago
Hi, @thokkat and thanks for finding!
Currently only the time between calls is checked leading to erroneous behavior, e.g. the first call never waits
Fist call has wait in current implementation, since time start at 0
and emitTimeLast
is initialized to zero. In what case trigger doesn't work for you?
I'm assuming that it break when player enters a new non-starting location, for first time, so it should be enough to set
emitTimeLast = world.tickCount();
in constructor.
Currently the last successful activation time is saved and next activation is delayed. So if time distance is large enough trigger would always activate instantly. Instead I want to change it so it always delays before activation regardless when last activation was. Took it from spacer help file:
[TOPIC MEMBER 'zCTrigger::fireDelaySec']
FLOAT sec
Wieviel Zeit nach dem Aktivieren des Triggers muss vergehen, bevor er wirklich feuert.
\\ How much time must pass after activating the trigger before it actually fires.
In what case trigger doesn't work for you?
Here in vanilla cannons pop up over time but in OG all are set up at the beginning of cutscene.
script:
wld_sendtrigger("KAMERA_KANONENEVENT_KANONEN_TRIGGER");
ai_setwalkmode(self, npc_run);
ai_gotowp(self, "PINTA_DSCHUNGEL_40");
ai_playani(self, "T_PLUNDER");
wld_sendtrigger("PINTA_KANONE_01_TRIGGER");
ai_gotowp(self, "PINTA_DSCHUNGEL_41");
ai_playani(self, "T_PLUNDER");
wld_sendtrigger("PINTA_KANONE_02_TRIGGER");
ai_gotowp(self, "PINTA_DSCHUNGEL_42");
ai_playani(self, "T_PLUNDER");
wld_sendtrigger("PINTA_KANONE_03_TRIGGER");
...
Cannon triggers have fireDelaySec
values set to align with plunder animation.
Ok actually emitTimeLast
refers to retriggerWaitSec
instead of fireDelaySec
. Adjusted accordingly.
https://zk.gothickit.dev/engine/objects/zCTrigger/
- retriggerWaitSec The number of seconds that have to elapse after processing an event before the trigger will process additional events. All events received by the trigger during that time are ignored.
- fireDelaySec The number of seconds to wait before emitting the OnTrigger event after processing.
Added a pointer to reference trigger for Triggerevents to assure uniqueness. Pointer is not serialized, so in case of a loaded game Triggerevents only have the string reference like before and pick up pointer before first testing for firedelay
. But this should be extremely rare and thus ok I guess.
Deferred triggers are now tracked in AbstractTrigger class as you suggested. I moved events with a delay applied in triggerlist there as well to be able to assure uniqueness. In case of user save game action events are pushed back to triggerEvents
vector which keeps current save game behavior.
Since delay
from triggerlist is per string target but fireDelay
is per trigger target I think it's best to keep it as is and push delayed triggers back in World::execTriggerEventis
. Only a check for target uniqueness has been added. Triggers with a fireDelay
are then pushed to triggersDeferred
and wait until execution time has come.
@thokkat After reading change multiple time is still look over-engineered and incomplete. Can you please send me a link to mod+save that you using to test this feature?
Short explanation how I think it should be:
wait triggerlist delay -> check if trigger is already allowed (retriggerWaitSec), if not discard -> wait fireDelay -> fire
If trigger is on any delay don't allow retrigger. But tested only fireDelay here.
mod: https://www.worldofgothic.de/dl/download_404.htm I used 1.1 patch. Second link are voice lines (not needed).
save files: saveslot.zip
In quick save talk to npc and use dialog option 1.
There are more bugs in case you wanna look into them as well.
After CsCamera in quicksave another CsCamera is started. Cannons should fire but don't.
Save1 has lava which should kill the player. Problem is
https://github.com/Try/OpenGothic/blob/757ee90abbdd02494e7ec68c32b9c552e0db6061/game/world/worldobjects.cpp#L391
y value of added vector needs to be smaller than i->translateY()*0.2
.
Save2 has a cannon as item which can't be focused. Cause is a change in recent graphics update that changes item mid position.
Save files are not compatible apparently:
unable to open Zen-file: "insel3.zen"
loading error: Cannot init RTN_START_415: not an instance
I'm assuming that problem is me installing mod on top of English game. You have steam+German as a base, right?
Old Gothic II Gold cd version which has only german language available. When I shared non mod save some time ago we had same problem, hoped it wouldn't occur again.
For non delay bugs I can give some marvin goto commands, but delay requires some quests/dialogs before so npc is at right position and has trigger dialog available.
This is how you can get to cutscene by "normal" playing:
Karibik.ini
change start world to World=Karibik\INSEL3.ZEN
We want to use storyhelper (has talk perc but doesn't talk) and have access to all dialog options:
In GameScript::npc_knowsinfo
return always true and in Npc::startDialog
add
if(hnpc->id==3100) {
setOther(&pl);
aiPush(AiQueue::aiProcessInfo(pl));
return;
}
itsc_firerain
) so npc later don't get distracted.Marvin::printVariable
, use marvin p pinta_pflanzen_onetime
and overwrite variable value to 1.insert karibik_storyhelper
and select last dialog option Ins 4.Kapitel (Vor Kanonenevent)
. Augustus and other npc should now be teleported close to your location. Use marvin set time
to force npc to their waypoints.Es kann losgehen!
.For other bugs:
goto pos -1500 200 2900
.World=Karibik\INSEL_2.ZEN
and goto pos 180 -400 1900
unable to open Zen-file: "insel3.zen" When I shared non mod save some time ago we had same problem, hoped it wouldn't occur again.
Finally found time to look into. Also found the problem with saves: command line been missing -game:Karibik.ini
I've pushed my solution to deferred triggers to deferred-triggers branch, commit d3196b65
No focus canon : same start world, goto pos -1500 200 2900
fixed it on the master branch
Save1 has lava which should kill the player. Problem is
I would say the read problem here is misalignment on how BBox is aligned to npc-model here. In vanilla, apparently, origin point of npc is body-center. In OpenGothic origin is in between the foots. While OpenGothic solution is better on handling ground-collision and spawns, it leads to numerious hacks and issues, like translateY
.
This can be addressed as part of https://github.com/Try/OpenGothic/issues/182
This is how processing should look like for a triggerlist after some more testing:
LP_ALL
), othewise go nextretriggerDelay
), otherwise go nextfireDelay
deferred-triggers branch, commit https://github.com/Try/OpenGothic/commit/d3196b652819e3585e2a33fb437502dce70af4ee
Some comments based on the above:
Why vector for delayedEvents
? Trigger can only have one delayed event.
hasDelayerEvents()
typo
Events are discarded if trigger is on retriggerDelay.
if(emitTimeLast>0 && world.tickCount()<emitTimeLast+retriggerDelay) {
world.triggerEvent(evt);
return;
}
triggersDef
is not repopulated on load.
Some comments based on the above
Thanks for checking!
Why vector for delayedEvents? Trigger can only have one delayed event.
If retriggerDelay
is smaller than fireDelay
, then there can be multiple deferred event in-flight
If retriggerDelay is smaller than fireDelay, then there can be multiple deferred event in-flight
Just tested again to be sure with a firedelay of 5s. If trigger is on firedelay and trigger is retriggered no second/third/... trigger execution happens. Only after these 5s a retrigger is possible.
Thanks for double checking! Fixed in b1cb4274
One last remark, emitTimeLast = world.tickCount()
needs to be in implProcessEvent
. Test was 5s retriggerDelay, 5s fireDelay. Constant poking gave first execution after 5s, but all following took 10s.
I think with the above it's good for merge. Haven't done ingame testing though because after driver update aquireNextImage
fails at game start with khr out of date.
One last remark
Fixed; This PR is closed by: https://github.com/Try/OpenGothic/pull/592
Trigger attribute
fireDelay
determines how much time should pass between trigger call and start. Currently only the time between calls is checked leading to erroneous behavior, e.g. the first call never waits.