Galactygon Posted May 25, 2017 Share Posted May 25, 2017 (edited) When I try to compile ssl scripts from a .bat file run from the main game directory I am unable to specify a directory if ssl.exe is located somewhere else relative to the .bat file in the manner of: LCTests/SSL/ssl.exe "LCTests/SSL/testactions.ssl LCTests/SSL/testssl.ssl -l LCTests/SSL/testlib.slb IsLich=True&CreType=Undead" I get the message "LCTests is not recognized as an internal or external command" I do manage to compile them if ssl.exe is located in the same folder as the .bat file and use the following instead. ssl.exe "LCTests/SSL/testactions.ssl LCTests/SSL/testssl.ssl -l LCTests/SSL/testlib.slb IsLich=True&CreType=Undead" Is this intentional or is it an oversight? I guess one could either COPY ssl.exe to the main (game) directory or generate the .bat file in the folder where ssl.exe is located. EDIT: Using AT_NOW in the manner below works: AT_NOW ~LCTests/SSL/ssl.exe "LCTests/SSL/testactions.ssl LCTests/SSL/testssl.ssl -l LCTests/SSL/testlib.slb IsLich=True&CreType=Undead"~ Edited May 26, 2017 by Galactygon Quote Link to comment
Wisp Posted May 26, 2017 Share Posted May 26, 2017 I would be entirely unsurprised if bat files only worked with backslashes. Quote Link to comment
Galactygon Posted May 31, 2017 Share Posted May 31, 2017 (edited) I went ahead and wrote a function that can handle .ssl => .baf => .bcs compilation in one go. The modder has to specify the following 3 things: 1. The path of SSL.exe (default is %MOD_FOLDER%/SSL/ssl.exe) 2. The name of the array with a list of .ssl libraries with their file paths specified (valid format either .slb or .ssl). Default value is "SSL_LIB". 3. The name of the associative array with of individual .ssl files compiled as .bcs files in the override folder. Default value is "SSL_LIST". 4. (optional) Any ssl variables can be defined in STR_VAR ssl_variables. Default value is "". All filepaths are relative to Setup-MyMod.exe, including any INCLUDE() syntaxes within any of the .ssl files. The code generates a valid list of .ssl files and libraries, runs ssl.exe, and compiles the resulting .baf files into the override folder. See the full code below with an example application: // Compile a list of .ssl files into .baf format and then proceed to .bcs format in the override folder // Example usage: //ACTION_DEFINE_ARRAY "SSL_LIB" BEGIN // list of .slb files // "%MOD_FOLDER%/SSL/testlib" // list of .ssl files (i.e. to define actions) // "%MOD_FOLDER%/SSL/testactions" //END //ACTION_DEFINE_ASSOCIATIVE_ARRAY "SSL_LIST" BEGIN // Compiles test1.ssl into override/testssl.bcs // "%MOD_FOLDER%/SSL/test1.ssl" => "testssl" // Compiles test2.ssl into override/testtwo.bcs // "%MOD_FOLDER%/SSL/test2" => "testtwo.bcs" // Compiles test3.ssl into %MOD_FOLDER%/SSL/ssl_out/test3.baf without compiling into the override as a .bcs // useful for patching (i.e. EXTEND_TOP) // "%MOD_FOLDER%/SSL/test3" => "" //END //LAF "SSL" // STR_VAR ssl_lib = "SSL_LIB" // List of arrays // ssl_files = "SSL_LIST" // List of associative arrays // ssl_exe = EVAL "%MOD_FOLDER%/SSL/ssl.exe" // directory to where ssl.exe is located //END DEFINE_ACTION_FUNCTION "SSL" STR_VAR ssl_lib = "SSL_LIB" // name of the array array (default: "SSL_LIB") ssl_files = "SSL_LIST" // name of the associative array (default: "SSL_LIST") ssl_variables = "" // List of variables ssl_exe = EVAL "%MOD_FOLDER%/SSL/ssl.exe" // directory to where ssl.exe is located (default is in an ssl folder within %MOD_FOLDER%) BEGIN OUTER_SPRINT ssl_execute_ssl "" OUTER_SPRINT ssl_execute_lib "" ACTION_IF "%ssl_variables%" STRING_CONTAINS_REGEXP "[0-9A-Za-z]+=[0-9A-Za-z]+" = 0 BEGIN OUTER_PATCH_SAVE ssl_variables "%ssl_variables%" BEGIN REPLACE_TEXTUALLY "[ %TAB%,;|]*=[ %TAB%,;|]*" "=" REPLACE_TEXTUALLY "[ %TAB%,;|]*" "&" REPLACE_TEXTUALLY "^&" "" REPLACE_TEXTUALLY "&$" "" END OUTER_SPRINT ssl_variables " %ssl_variables%" END ELSE BEGIN OUTER_SPRINT ssl_variables "" END ACTION_IF FILE_EXISTS "%ssl_exe%" AND "%ssl_exe%" STRING_MATCHES_REGEXP "^.*ssl\.exe$" = 0 BEGIN // If ssl.exe exists // Record information ACTION_PHP_EACH "%ssl_lib%" AS ssl_lib_index => ssl_lib_src BEGIN // Add .slb or .ssl at the end if no file extension is given (attempt to find .slb file first then do the same for .ssl) ACTION_IF NOT "%ssl_lib_src%" STRING_MATCHES_REGEXP "^.+\.[0-9A-Za-z]+$" = 0 AND NOT "%ssl_lib_src%" STRING_MATCHES_REGEXP "^.+\.\(slb\|ssl\)$" = 0 BEGIN ACTION_IF FILE_EXISTS "%ssl_lib_src%.slb" BEGIN OUTER_SPRINT ssl_lib_src "%ssl_lib_src%.slb" END ELSE ACTION_IF FILE_EXISTS "%ssl_lib_src%.ssl" BEGIN OUTER_SPRINT ssl_lib_src "%ssl_lib_src%.ssl" END END ACTION_IF FILE_EXISTS "%ssl_lib_src%" AND "%ssl_lib_src%" STRING_MATCHES_REGEXP "^.+\.slb$" = 0 BEGIN // If valid .slb file // Append %ssl_execute_lib% with file path ACTION_IF "%ssl_execute_lib%" STRING_EQUAL_CASE "" BEGIN // If first item in list OUTER_SPRINT ssl_execute_lib "%ssl_lib_src%" END ELSE BEGIN // If not first item in list OUTER_SPRINT ssl_execute_lib "%ssl_lib_src% %ssl_execute_lib%" END END ACTION_IF FILE_EXISTS "%ssl_lib_src%" AND "%ssl_lib_src%" STRING_MATCHES_REGEXP "^.+\.ssl$" = 0 BEGIN // If valid .ssl file // Append %ssl_execute_ssl% with file path ACTION_IF "%ssl_execute_ssl%" STRING_EQUAL_CASE "" BEGIN // If first item in list OUTER_SPRINT ssl_execute_ssl "%ssl_lib_src%" END ELSE BEGIN // If not first item in list OUTER_SPRINT ssl_execute_ssl "%ssl_execute_ssl% %ssl_lib_src%" END // Make directory "ssl_out" in same folder as .ssl file & copy blank .baf file to destination OUTER_PATCH_SAVE ssl_out "%ssl_lib_src%" BEGIN REPLACE_TEXTUALLY "^\(.+\)/[^/]+\.ssl$" "\1/ssl_out" END MKDIR ~%ssl_out%/~ OUTER_PATCH_SAVE ssl_out_res "%ssl_lib_src%" BEGIN REPLACE_TEXTUALLY "^\(.+\)/\([^/]+\)\.ssl$" "\2" END <<<<<<<< .../%MOD_FOLDER%-Inlined/blank.txt >>>>>>>> COPY ".../%MOD_FOLDER%-Inlined/blank.txt" "%ssl_out%/%ssl_out_res%.baf" END END ACTION_PHP_EACH "%ssl_files%" AS ssl_src => ssl_dest BEGIN // Add .ssl at the end if no file extension is given ACTION_IF NOT "%ssl_src%" STRING_MATCHES_REGEXP "^.+\.[0-9A-Za-z]+$" = 0 AND NOT "%ssl_src%" STRING_MATCHES_REGEXP "^.+\.ssl$" = 0 BEGIN OUTER_SPRINT ssl_src "%ssl_src%.ssl" END ACTION_IF FILE_EXISTS EVAL "%ssl_src%" AND "%ssl_src%" STRING_MATCHES_REGEXP "^.+\.ssl$" = 0 BEGIN // If valid .ssl file // Append %ssl_execute_ssl% with file path ACTION_IF "%ssl_execute_ssl%" STRING_EQUAL_CASE "" BEGIN // If first item in list OUTER_SPRINT ssl_execute_ssl "%ssl_src%" END ELSE BEGIN // If not first item in list OUTER_SPRINT ssl_execute_ssl "%ssl_execute_ssl% %ssl_src%" END // Make directory "ssl_out" in same folder as .ssl file & copy blank .baf file to destination OUTER_PATCH_SAVE ssl_out "%ssl_src%" BEGIN REPLACE_TEXTUALLY "^\(.+\)/[^/]+\.ssl$" "\1/ssl_out" END MKDIR ~%ssl_out%/~ OUTER_PATCH_SAVE ssl_out_res "%ssl_src%" BEGIN REPLACE_TEXTUALLY "^\(.+\)/\([^/]+\)\.ssl$" "\2" END <<<<<<<< .../%MOD_FOLDER%-Inlined/blank.txt >>>>>>>> COPY ".../%MOD_FOLDER%-Inlined/blank.txt" "%ssl_out%/%ssl_out_res%.baf" END END // Launch ssl.exe if there are valid library and ssl files & generate .baf files ACTION_IF NOT "%ssl_execute_ssl%" STRING_EQUAL_CASE "" AND NOT "%ssl_execute_lib%" STRING_EQUAL_CASE "" BEGIN AT_NOW ~%ssl_exe% "%ssl_execute_ssl% -l %ssl_execute_lib%%ssl_variables%"~ END // Compile generated .baf files ACTION_PHP_EACH "%ssl_files%" AS ssl_src => ssl_dest BEGIN // Get ssl_out/xxx.baf path // Add .ssl at the end if no file extension is given ACTION_IF NOT "%ssl_src%" STRING_MATCHES_REGEXP "^.+\.[0-9A-Za-z]+$" = 0 AND NOT "%ssl_src%" STRING_MATCHES_REGEXP "^.+\.ssl$" = 0 BEGIN OUTER_SPRINT ssl_src "%ssl_src%.ssl" END // Get location of resulting .baf file OUTER_PATCH_SAVE ssl_out "%ssl_src%" BEGIN REPLACE_TEXTUALLY "^\(.+\)/[^/]+\.ssl$" "\1/ssl_out" END OUTER_PATCH_SAVE ssl_out_res "%ssl_src%" BEGIN REPLACE_TEXTUALLY "^\(.+\)/\([^/]+\)\.ssl$" "\2" END // Generate new .bcs if valid input at => "%ssl_dest%" ACTION_IF "%ssl_dest%" STRING_MATCHES_REGEXP "^[-_!@#a-zA-Z0-9]+\(\.baf\|\.bcs\)?$" = 0 BEGIN ACTION_IF FILE_EXISTS "%ssl_out%/%ssl_out_res%.baf" BEGIN // Record contents of resulting .baf file in %ssl_out_contents% COPY - "%ssl_out%/%ssl_out_res%.baf" "" READ_ASCII 0 ssl_out_contents (BUFFER_LENGTH) // truncate file extensions OUTER_PATCH_SAVE ssl_dest "%ssl_dest%" BEGIN REPLACE_TEXTUALLY "^\(.+\)\..+$" "\1" END // Generate temporary .baf file (in case original .ssl/.baf and destination .bcs resnames do not match) <<<<<<<< .../%MOD_FOLDER%-Inlined/SSL_DEST/%ssl_dest%.baf %ssl_out_contents% >>>>>>>> COMPILE EVAL ".../%MOD_FOLDER%-Inlined/SSL_DEST/%ssl_dest%.baf" END END END END END Edited June 18, 2017 by Galactygon Quote Link to comment
Angel Posted June 23, 2017 Share Posted June 23, 2017 Okay, I have NO idea what I'm doing wrong, but I just can't get this to work. I got this script, for a friendly cleric who wants to help the party: BEGIN_ACTION_DEFINITION Name(Heal_PC) TRIGGER !GlobalTimerNotExpired("heal_pc", "LOCALS") HaveSpell(scsargument1) Allegiance(Myself, NEUTRAL) ACTION RESPONSE #scsprob1 SetGlobalTimer("heal_pc", "LOCALS", ONE_ROUND) Spell(scstarget, scsargument1) END IF TRIGGER TargetBlock(PCsInOrder) StateCheck(scstarget, STATE_POISONED) THEN DO Action(Heal_PC, CLERIC_NEUTRALIZE_POISON) Action(Heal_PC, CLERIC_SLOW_POISON) END [...] But when I try to compile it, I get this: angel@phoenix /virtual/warbler/baldur $ perl ssl.pl mh#cath.ssl -l library.slb This is Stratagems Scripting Language Input file is mh#cath.ssl Unrecognised TargetBlock (PCsInOrder) near line 14 at ssl.pl line 252. The library.slb file is an unaltered copy of the one in SCS (stratagems/ssl/library.slb) and it has the TARGET=PCsInOrder right there at line 300. Does anyone have any idea what I am doing wrong? (By the way, the above is done on Linux, but I get the same on Windows as well.) Btw, it also took me way too long to figure out BEGIN_ACTION_DEFINITION is supposed to have underscores, the tutorial makes it look like they are three separate words with spaces. Quote Link to comment
DavidW Posted February 7, 2019 Author Share Posted February 7, 2019 A quick note for the 2-3 people other than me who use SSL: the version of SSL that ships with SCS v32 has three changes from the previous version. Two of them are documented above (TRIGGER_REPLACE/TARGET_REPLACE and Booleans) though that documentation refers to ‘v31’. (In fact v31 came to be the maintenance release put together by Cam and others, and the version I was working on became v32). The third is that you can now use scsargumentN in trigger blocks and it’ll be correctly evaluated (previously evaluation occurred before the trigger was subbed in). Quote Link to comment
Luke Posted July 23, 2019 Share Posted July 23, 2019 (edited) @DavidW So, I keep getting the following error: Unrecognised TriggerBlock: Attacked Here's my .tp2 file: ACTION_IF !FILE_EXISTS_IN_GAME ~GTTEST.bcs~ BEGIN // Sanity check AT_NOW ~chmod 755 %MOD_FOLDER%/ssl/ssl.pl~ AT_NOW ~/usr/bin/perl %MOD_FOLDER%/ssl/ssl.pl %MOD_FOLDER%/components/test/GTTEST.ssl -l %MOD_FOLDER%/ssl/library.slb~ EXACT COMPILE ~%MOD_FOLDER%/components/test/ssl_out~ END Here's what library.slb contains: TRIGGER = Attacked OR(2) AttackedBy([GOODCUTOFF],DEFAULT) SpellCastOnMe([GOODCUTOFF],0) And here's GTTEST.ssl: BEGIN_ACTION_DEFINITION Name(Test) TRIGGER HaveSpell(scsargument1) Global("gttest","GLOBAL",0) ACTION RESPONSE #scsprob1 Spell(scstarget,scsargument1) SetGlobal("gttest","GLOBAL",1) END IF TRIGGER TriggerBlock(Attacked) Target(Protagonist) THEN DO Action(Test,WIZARD_CHARM_PERSON) END Am I missing something? Why doesn't it recognize "Attacked" defined in library.slb? It seems @Angel bumped into this issue too... Moreover, there's a typo in all the examples provided in the first page: "#scsprob" should be "#scsprob1" Edited July 23, 2019 by Luke Quote Link to comment
Luke Posted July 23, 2019 Share Posted July 23, 2019 @DavidW, @Angel OK, I found the culprit: TRIGGER = Attacked should be TRIGGER=Attacked I.e.: you do not need to put spaces between the keyword TRIGGER and its name Quote Link to comment
Luke Posted July 25, 2019 Share Posted July 25, 2019 (edited) I have a question about Combine(): Is it possible to combine two actions so that certain triggers only appear in one of two final blocks (i.e., the two blocks containing LastSeenBy(Myself))? Example below: Spoiler IF // Possibly some other trigger(s)... See(FifthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() IF // Possibly some other trigger(s)... See(FourthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() IF // Possibly some other trigger(s)... See(ThirdNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() IF // Possibly some other trigger(s)... See(SecondNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() IF // Possibly some other trigger(s)... See(NearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() IF Allegiance(Myself,EVILCUTOFF) // Only in this block Allegiance(LastSeenBy(Myself),GOODCUTOFF) // Only in this block See(LastSeenBy(Myself)) THEN RESPONSE #100 Attack(LastSeenBy(Myself)) END IF Allegiance(Myself,GOODCUTOFF) // Only in this block ActionListEmpty() // Only in this block Allegiance(LastSeenBy(Myself),EVILCUTOFF) // Only in this block See(LastSeenBy(Myself)) THEN RESPONSE #100 Attack(LastSeenBy(Myself)) END Moreover, could you provide a couple of lessons about ConditionalTargetBlock() and LOOP? If I'm not mistaken, the first one can be used to restrict the triggers specified in the second argument to the targets specified in the first argument. For instance: IF TRIGGER ConditionalTargetBlock(PCsPreferringWeak;Gender(scstarget,MALE)) TargetBlock(EnemiesInOrderShort) TriggerBlock(MR100|Enemy|SIConjuration) THEN DO Action(Spell,WIZARD_FLAME_ARROW,50,SPELLFAILUREMAGE|100|50) END Both "PCsPreferringWeak" and "EnemiesInShortOrder" are subjected to !CheckStatGT(scstarget,99,RESISTMAGIC) Allegiance(Myself,ENEMY) !Allegiance(scstarget(Myself),ENEMY) !CheckStat(scstarget,2,WIZARD_SPELL_IMMUNITY) whereas only "PCsPreferringWeak" are subjected to Gender(scstarget,MALE) Am I correct? Edited July 25, 2019 by Luke Quote Link to comment
DavidW Posted July 28, 2019 Author Share Posted July 28, 2019 Combine() - no. ConditionalTargetBlock() - you have it right. LOOP - basically does multiple copies of a chunk of SSL code, with a different value of a variable each time. Look at SCS, there are quite a few examples. Quote Link to comment
Luke Posted July 28, 2019 Share Posted July 28, 2019 (edited) I see, thank you for clarifying. 7 hours ago, DavidW said: Combine() - no. This means that I need to define two separate ACTIONs, right? Alternatively – When dealing with ACTION blocks, can "scsargument" be a script trigger? For instance, I noticed you can do something like this Spoiler BEGIN_ACTION_DEFINITION Name(Test) TRIGGER scsargument1 ACTION RESPONSE #scsprob1 Turn() END IF TRIGGER THEN DO Action(Test,True()) END but you cannot do this Spoiler BEGIN_ACTION_DEFINITION Name(Test) TRIGGER scsargument1 ACTION RESPONSE #scsprob1 Turn() END IF TRIGGER THEN DO Action(Test,Allegiance(Myself,GOODCUTOFF)) END because "," (commas) are used to separate arguments, so the SSL compiler cannot resolve this comma => Allegiance(Myself,GOODCUTOFF). It basically thinks there's another argument after "Allegiance(Myself". The resulting BAF file is: Spoiler IF Allegiance(Myself THEN RESPONSE #100 Turn() END To tell the truth, I also noticed you cannot write Spoiler IF TRIGGER THEN DO Action(Test,~~) END i.e., feed your ACTION with the empty string in case you don't need any additional trigger, so this is probably not the best solution... Edited July 28, 2019 by Luke Quote Link to comment
Luke Posted July 29, 2019 Share Posted July 29, 2019 I'd like to ask a question about an SSL block: the following two SSL blocks generate the same BAF file: Spoiler IF TRIGGER Target(NearestEnemyOf(Myself)) !GlobalTimerNotExpired("Dispel","LOCALS") THEN DO Action(Spell,WIZARD_DISPEL_MAGIC) SetGlobalTimer("Dispel","LOCALS",18) END ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// IF TRIGGER !GlobalTimerNotExpired("Dispel","LOCALS") Target(NearestEnemyOf(Myself)) THEN DO Action(Spell,WIZARD_DISPEL_MAGIC) SetGlobalTimer("Dispel","LOCALS",18) END => the triggers present in the ACTION "Spell" are the first ones, then comes "See(NearestEnemyOf(Myself)" (i.e., Target and TargetBlock()) and finally all the other triggers (in this case "!GlobalTimerNotExpired("Dispel","LOCALS")"), regardless of what comes first in the IF TRIGGER part. Is it intended? Quote Link to comment
Luke Posted August 13, 2019 Share Posted August 13, 2019 (edited) On 7/28/2019 at 4:10 PM, DavidW said: Combine() - no. To tell the truth, it seems to be partially possible. This SSL block Spoiler BEGIN_ACTION_DEFINITION Name(Spell1) TRIGGER !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(scsargument1) Allegiance(Myself,EVILCUTOFF) !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,scsargument2,scsargument3) Allegiance(scstarget,GOODCUTOFF) ACTION RESPONSE #scsprob1 SetGlobalTimer("gt_cast","LOCALS",ONE_ROUND) Spell(scstarget,scsargument1) END BEGIN_ACTION_DEFINITION Name(Spell2) TRIGGER !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(scsargument1) Allegiance(Myself,GOODCUTOFF) ActionListEmpty() !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,scsargument2,scsargument3) Allegiance(scstarget,EVILCUTOFF) !InParty(scstarget) ACTION RESPONSE #scsprob1 SetGlobalTimer("gt_cast","LOCALS",ONE_ROUND) Spell(scstarget,scsargument1) END IF TRIGGER TargetBlock(EnemiesInReverseOrder) TriggerBlock(MR50|SIConjuration) !StateCheck(scstarget,STATE_REALLY_DEAD) THEN DO Combine() Action(Spell1,WIZARD_SPOOK,50,SPELLFAILUREMAGE) Action(Spell2,WIZARD_SPOOK,50,SPELLFAILUREMAGE) END generates the following BAF code: Spoiler IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) CheckStatLT(NearestEnemyOf(Myself),50,RESISTMAGIC) !CheckStat(NearestEnemyOf(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(NearestEnemyOf(Myself),STATE_REALLY_DEAD) See(NearestEnemyOf(Myself)) False() THEN RESPONSE #100 Continue() END IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) CheckStatLT(SecondNearestEnemyOf(Myself),50,RESISTMAGIC) !CheckStat(SecondNearestEnemyOf(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(SecondNearestEnemyOf(Myself),STATE_REALLY_DEAD) See(SecondNearestEnemyOf(Myself)) False() THEN RESPONSE #100 Continue() END IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) CheckStatLT(ThirdNearestEnemyOf(Myself),50,RESISTMAGIC) !CheckStat(ThirdNearestEnemyOf(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(ThirdNearestEnemyOf(Myself),STATE_REALLY_DEAD) See(ThirdNearestEnemyOf(Myself)) False() THEN RESPONSE #100 Continue() END IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) CheckStatLT(FourthNearestEnemyOf(Myself),50,RESISTMAGIC) !CheckStat(FourthNearestEnemyOf(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(FourthNearestEnemyOf(Myself),STATE_REALLY_DEAD) See(FourthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 Continue() END IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) CheckStatLT(FifthNearestEnemyOf(Myself),50,RESISTMAGIC) !CheckStat(FifthNearestEnemyOf(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(FifthNearestEnemyOf(Myself),STATE_REALLY_DEAD) See(FifthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 Continue() END IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) CheckStatLT(SixthNearestEnemyOf(Myself),50,RESISTMAGIC) !CheckStat(SixthNearestEnemyOf(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(SixthNearestEnemyOf(Myself),STATE_REALLY_DEAD) See(SixthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 Continue() END IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) Allegiance(Myself,EVILCUTOFF) // Only in this script block => intended? !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) Allegiance(LastSeenBy(Myself),GOODCUTOFF) // Only in this script block => intended? CheckStatLT(LastSeenBy(Myself),50,RESISTMAGIC) !CheckStat(LastSeenBy(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(LastSeenBy(Myself),STATE_REALLY_DEAD) See(LastSeenBy(Myself)) THEN RESPONSE #100 SetGlobalTimer("gt_cast","LOCALS",ONE_ROUND) Spell(LastSeenBy(Myself),WIZARD_SPOOK) // SPWI125.SPL (Spook) END IF !GlobalTimerNotExpired("gt_cast","LOCALS") HaveSpell(WIZARD_SPOOK) // SPWI125.SPL (Spook) Allegiance(Myself,GOODCUTOFF) // Only in this script block => intended? ActionListEmpty() // Only in this script block => intended? !StateCheck(Myself,STATE_SILENCED) CheckStatLT(Myself,50,SPELLFAILUREMAGE) Allegiance(LastSeenBy(Myself),EVILCUTOFF) // Only in this script block => intended? !InParty(LastSeenBy(Myself)) // Only in this script block => intended? CheckStatLT(LastSeenBy(Myself),50,RESISTMAGIC) !CheckStat(LastSeenBy(Myself),2,WIZARD_SPELL_IMMUNITY) !StateCheck(LastSeenBy(Myself),STATE_REALLY_DEAD) See(LastSeenBy(Myself)) THEN RESPONSE #100 SetGlobalTimer("gt_cast","LOCALS",ONE_ROUND) Spell(LastSeenBy(Myself),WIZARD_SPOOK) // SPWI125.SPL (Spook) END To sum up: could you explain why some triggers (e.g., 'Allegiance()' and '!InParty()') defined in the ACTION definition only appear in the 'LastSeenBy(Myself)' block instead of everywhere? Edited August 13, 2019 by Luke Quote Link to comment
DavidW Posted August 13, 2019 Author Share Posted August 13, 2019 Combine()'s False() blocks only contain the intersection of the trigger lists for the various actions being Combine()d. Quote Link to comment
Luke Posted August 15, 2019 Share Posted August 15, 2019 (edited) On 8/13/2019 at 8:40 PM, DavidW said: Combine()'s False() blocks only contain the intersection of the trigger lists for the various actions being Combine()d. Good to know, thanks for clarifying (the triggers I previously pointed out don't belong to the intersection, so they appear only in the final 'LastSeenBy(Myself)' blocks). Edited August 15, 2019 by Luke 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.