Jump to content
DavidW

Coding scripts in SSL: some lessons

Recommended Posts

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 by Galactygon

Share this post


Link to post

I would be entirely unsurprised if bat files only worked with backslashes.

Share this post


Link to post

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 by Galactygon

Share this post


Link to post

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.

Share this post


Link to post

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).

Share this post


Link to post
Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×