Gamemacik Posted April 12, 2021 Share Posted April 12, 2021 (edited) 0x4027 Delay(I:Delay*) Delays the next check of the block of triggers where this trigger is, by the number of seconds specified. This value is not stored when the game is saved. Delay is applied immediately before first block execution of delayed script block if block could not be executed because of some different action eg. casting spell or movement , eg. if script block has Delay(60) and then it executes some action eg. casts a spell, before 1st execution game will wait 60 second and then casts a spell a repeats same every 60 seconds. It may happen delayed block will never be executed if another action is in progress, it looks like game gives some tolerance about 1 round if delay block is not executed within this period next chance to execute actions will be at next check in 60 sec. (the 1 round tolerance delay does exist if delayed block never been executed before) What is missing in trigger description is: Delay is not executed for every block separately or better say delay changes time (interval for checking) for delayed blocks. This means delay should not be used like a cooldown for casting spells eg. IF True() //This is First script block with Sring 6 is notification - begining of script loop THEN RESPONSE #100 DisplayString(Myself,6) // Then join us by all means. You are welcome here. Continue() END IF ActionListEmpty() Delay(3) THEN RESPONSE #100 DisplayString(Myself,2) // You played Elminster? END IF ActionListEmpty() Delay(6) THEN RESPONSE #100 DisplayString(Myself,3) // Uh, the yugoloth, was it? Yeah, you stole the show with that one, if I recall. END IF ActionListEmpty() Delay(3) THEN RESPONSE #100 DisplayString(Myself,4) // And, who knows, we were rehearsing for Picoccio's "Three Days in the Ether." Perhaps we can give you a dress matinee. END Code above contains 4 blocks, 1st block is notification block to let us know when script loop begins, then 2nd block ticks every 3 second, 3rd block ticks every 6 seconds and 4th block every 3 seconds. Result is only 2nd block script is executed, this means only "You played Elminster?" is displayed then script returns at beginning " Then join us by all means. You are welcome here." and continues checking blocks again, actions from blocks 3 and 4 are never executed. 1st block ticks always (approx. every 1 sec, this varies from script levels, override scripts and master scripts ticks much faster than class script, slowest is Default script) 2nd blocks ticks every 3 sec, 3,6,9,12,15,18,21,24 3rd blocks ticks every 6 sec, 6,12,18,24 4th blocks ticks every 3 sec, 3,6,9,12,15,18,21,24 Therefore script should not contain blocks with same Delay parameter or rest of blocks below are never executed. We could use Continue() to allow rest of scripts to be checked is such case delayed scripts which are checked in same time interval will be executed, but Continue() checks conditions of following block at once so if 1 block checks health eg.: HPLT(Myself,20) and then cast "CLERIC_HEAL", 2nd block checks HPLT(Myself,30) cast "CLERIC_CURE_MEDIUM_WOUNDS" the second healing is executed even target is already fully healed, because of a way how Continue() changes block checking. *** 0x4047 RandomNum(I:Range*,I:Value*) Generates a random number between 1 and Range. Returns true only if the random number equals the 2nd parameter. Now about RandomNum, RandomNumGT, RandomNumLT, the problem seems to be similar to delay eg.: IF ActionListEmpty() RandomNum(3,1) THEN RESPONSE #100 DisplayString(Myself,2) // You played Elminster? END IF ActionListEmpty() RandomNum(3,1) THEN RESPONSE #100 DisplayString(Myself,3) // Uh, the yugoloth, was it? Yeah, you stole the show with that one, if I recall. END IF ActionListEmpty() RandomNum(3,1) THEN RESPONSE #100 DisplayString(Myself,4) // And, who knows, we were rehearsing for Picoccio's "Three Days in the Ether." Perhaps we can give you a dress matinee. END Similar script, 3 blocks with 33% chance to execute a block, result is 2nd and 3th block is never executed. I did not expect RandomNum works such way, so simply say if blocks contain same parameters as block above they are never executed. RandomNum is checked only once per loop for blocks with same parameters or better say RandomNum is checked at once for all blocks with same parameters? If parameters are unique then each block is checked separately and actions in blocks 2 and 3 have chance to be executed. IF ActionListEmpty() RandomNum(3,1) THEN RESPONSE #100 DisplayString(Myself,2) // CharnameYou played Elminster? END IF ActionListEmpty() RandomNum(4,1) THEN RESPONSE #100 DisplayString(Myself,3) // Uh, the yugoloth, was it? Yeah, you stole the show with that one, if I recall. END IF ActionListEmpty() RandomNum(5,1) THEN RESPONSE #100 DisplayString(Myself,4) // And, who knows, we were rehearsing for Picoccio's "Three Days in the Ether." Perhaps we can give you a dress matinee. END example of script where RandomNum uses same parameters draconis.bcs unique RandomNum parameters: ohryxtra.bcs Edited April 12, 2021 by Gamemacik Quote Link to comment
lynx Posted April 12, 2021 Share Posted April 12, 2021 Delay: so it works like a modulo operator, a sieve. Random: AFAIK all the triggers and actions share the random value (in the same tick). Please just suggest changes or additions to the text on the site. Quote Link to comment
Gamemacik Posted April 12, 2021 Author Share Posted April 12, 2021 (edited) i added to first post some more details to Delay trigger after more testing, now it is even more confusing, it seems to be very unreliable command for long delayed blocks because they may never be executed. IF Delay(58) THEN RESPONSE #100 ForceSpell(Myself,WIZARD_GLOBE_OF_INVULNERABILITY) // SPWI602.SPL (Globe of Invulnerability) END IF Delay(60) THEN RESPONSE #100 ForceSpell(Myself,CLERIC_HEAL) // SPPR607.SPL (Heal) END IF Delay(18) THEN RESPONSE #100 ForceSpell(Myself,WIZARD_MAGIC_MISSILE) // SPWI112.SPL (Magic Missile) END in short from testing of script above. if spawned NPC is idle it will cast WIZARD_GLOBE_OF_INVULNERABILITY immediately but if eg. moves next check is in 58 sec then is should cast 3x MAGIC_MISSILE that means about 54 seconds elapsed NPC waits 4 sec and casts WIZARD_GLOBE_OF_INVULNERABILITY, NPC remains idle, after cast is time 58+6=64 seconds CLERIC_HEAL is not casted because it is too late, required time was at 60 sec, long casting time of WIZARD_GLOBE_OF_INVULNERABILITY prevented NPC to heal self. Edited April 12, 2021 by Gamemacik Quote Link to comment
lynx Posted April 12, 2021 Share Posted April 12, 2021 I imagine with long delays and interspersed blocking actions this is expected behaviour if it's just using game time to modulo against. Quote Link to comment
Bubb Posted April 12, 2021 Share Posted April 12, 2021 (edited) Delay(intArg1) is just the total number script passes performed on the current creature, (including the one in progress), modulus intArg1. Very simple implementation in the engine: return m_nExpectedProcessPendingTriggersCalls % intArg1 <= m_nMissedProcessPendingTriggerCalls Unless an action specifically allows for itself to be interrupted, a currently executing action will block script passes for its duration, but not stop these blocked passes from being counted in m_nExpectedProcessPendingTriggersCalls. TL;DR: Delay() should really be called something like "Interval()" — and this "interval" can be missed if the script is preoccupied with something else when it would otherwise be hit, as is standard behavior with IE scripting. --- And yes, scripting uses the same random value to seed all RandomNum() triggers across a single tick; if you have multiple RandomNum() calls with the same parameters, they will all generate the same result. Edited April 12, 2021 by Bubb Quote Link to comment
lynx Posted April 13, 2021 Share Posted April 13, 2021 Heh, I thought this was something new in ees, so I didn't even bother checking our code. But it matches. Quote Link to comment
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.