Make Scenario Triggers using PHP Script
I am working on my “PHP Genie” project which reads/edits/writes Scenarios and Saved-Games. Currently, I am starting version 2. I will however give a few snippets from version 1 which is still a beta. Version 3 will have a User-Interface. I also intend to make a mini-map viewer in version 3 or 4.
Because I am still working on reading scenario contents, I have used a method to skip to the scenario’s triggers using a Magic-Keyword. For now, here are the snippets…
STEP 1:
Download PHP 5.2 and place the files into a folder in your local disc.
STEP 2:
Download and install PHP Designer
STEP 3:
Run PHP Designer and set the Preferences for debugging to the “php.exe” file.
STEP 4:
Create “Index.php” with the following contents:
<?# Extend limits for huge amounts of triggers:
ini_set ( 'memory_limit' , '1024M' ) ;
ini_set ( 'max_execution_time' , 300 ) ;# Set class:
class Scenario
{
# The output variable:
static $O ;# This function must be absolutely perfect.
# The slightest error is not at all acceptable.
# It writes all triggers into raw scenario data.
# I prefer the PACK function rather than SPRINTF.
function Write ( $I )
{
$W = 0 ;
self :: $X .= pack ( 'L1' , count ( $I ) ) ; #
foreach ( $I as $T )
{
$T [ 4 ] = substr ( $T [ 4 ] , 0 , 64 ) ; # Maximum length 64
$T [ 5 ] = substr ( $T [ 5 ] , 0 , 44 ) ; # Maximum length 44
self :: $X .= pack ( ‘L1’ , ( $T [ 0 ] ? 1 : 0 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( $T [ 1 ] ? 1 : 0 ) ) ; #
self :: $X .= pack ( ‘C1’ , 0 ) ; #
self :: $X .= pack ( ‘C1’ , ( $T [ 2 ] ? 1 : 0 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $T [ 3 ] ) ? $T [ 3 ] : 0 ) ) ; #
self :: $X .= pack ( ‘C1’ , 0 ) ; #
self :: $X .= pack ( ‘C1’ , 0 ) ; #
self :: $X .= pack ( ‘C1’ , 0 ) ; #
self :: $X .= pack ( ‘C1’ , 0 ) ; #
self :: $X .= pack ( ‘L1’ , strlen ( $T [ 4 ] ) + 1 ) ; #
self :: $X .= pack ( ‘A*’ , $T [ 4 ] ) . pack ( ‘C1’ , 0 ) ; #
self :: $X .= pack ( ‘L1’ , strlen ( $T [ 5 ] ) + 1 ) ; #
self :: $X .= pack ( ‘A*’ , $T [ 5 ] ) . pack ( ‘C1’ , 0 ) ; #
self :: $X .= pack ( ‘L1’ , count ( $T [ E ] ) ) ; #
if ( count ( $T [ E ] ) )
{
foreach ( $T [ E ] as $E )
{
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ 0 ] ) ? $E [ 0 ] : 0 ) ) ; #
self :: $X .= pack ( ‘L1’ , 23 ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ Z ] ) ? $E [ Z ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ Q ] ) ? $E [ Q ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ R ] ) ? $E [ R ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ M ] ) ? $E [ M ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( count ( $E [ S ] ) ? count ( $E [ S ] ) : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ O ] ) ? $E [ O ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ U ] ) ? $E [ U ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ P ] ) ? $E [ P ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ E ] ) ? $E [ E ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ H ] ) ? $E [ H ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ B ] ) ? $E [ B ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ K ] ) ? $E [ K ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ T ] ) ? $E [ T ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ I ] ) ? $E [ I ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ L ] ) ? $E [ L ] [ 0 ] : -1 ) ) ; # [X]
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ L ] ) ? $E [ L ] [ 1 ] : -1 ) ) ; # [Y]
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ A ] ) ? $E [ A ] [ 0 ] [ 0 ] : -1 ) ) ; # [0] [X]
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ A ] ) ? $E [ A ] [ 0 ] [ 1 ] : -1 ) ) ; # [0] [Y]
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ A ] ) ? $E [ A ] [ 1 ] [ 0 ] : -1 ) ) ; # [1] [X]
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ A ] ) ? $E [ A ] [ 1 ] [ 1 ] : -1 ) ) ; # [1] [Y]
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ G ] ) ? $E [ G ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ Y ] ) ? $E [ Y ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $E [ N ] ) ? $E [ N ] : -1 ) ) ; #$Y = ( $E [ 0 ] == 3 || $E [ 0 ] == 20 || $E [ 0 ] == 26 ? 1 : 0 ) ;
self :: $X .= pack ( ‘L1’ , strlen ( $E [ X ] ) + $Y ) ; #
self :: $X .= $E [ X ] ; #
if ( $Y ) self :: $X .= pack ( ‘C1’ , 0 ) ;self :: $X .= pack ( ‘L1’ , strlen ( $E [ D ] ) + $Y ) ; #
self :: $X .= $E [ D ] ; #
if ( $Y ) self :: $X .= pack ( ‘C1’ , 0 ) ;if ( count ( $E [ S ] ) )
{
foreach ( $E [ S ] as $S )
{
self :: $X .= pack ( ‘L1’ , $S ) ; #
}
}
}
}
if ( count ( $T [ E ] ) )
{
$Z = 0 ;
foreach ( $T [ E ] as $E )
{
self :: $X .= pack ( ‘L1’ , $Z ) ; #
$Z ++ ;
}
}
self :: $X .= pack ( ‘L1’ , count ( $T [ C ] ) ) ; #
if ( count ( $T [ C ] ) )
{
foreach ( $T [ C ] as $C )
{
self :: $X .= pack ( ‘L1’ , ( $C [ 0 ] ? $C [ 0 ] : 0 ) ) ; #
self :: $X .= pack ( ‘L1’ , 16 ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ Q ] ) ? $C [ Q ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ R ] ) ? $C [ R ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ S ] ) ? $C [ S ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ O ] ) ? $C [ O ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ U ] ) ? $C [ U ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ P ] ) ? $C [ P ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ H ] ) ? $C [ H ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ T ] ) ? $C [ T ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ K ] ) ? $C [ K ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ A ] ) ? $C [ A ] [ 0 ] [ 0 ] : -1 ) ) ; # [0] [X]
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ A ] ) ? $C [ A ] [ 0 ] [ 1 ] : -1 ) ) ; # [0] [Y]
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ A ] ) ? $C [ A ] [ 1 ] [ 0 ] : -1 ) ) ; # [1] [X]
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ A ] ) ? $C [ A ] [ 1 ] [ 1 ] : -1 ) ) ; # [1] [Y]
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ G ] ) ? $C [ G ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ Y ] ) ? $C [ Y ] : -1 ) ) ; #
self :: $X .= pack ( ‘L1’ , ( isset ( $C [ Z ] ) ? $C [ Z ] : -1 ) ) ; #
}
}
if ( count ( $T [ C ] ) )
{
$Z = 0 ;
foreach ( $T [ C ] as $C )
{
self :: $X .= pack ( ‘L1’ , $Z ) ; #
$Z ++ ;
}
}
$W ++ ;
}$Z = 0 ;
foreach ( $I as $T )
{
self :: $X .= pack ( ‘L1’ , $Z ) ; #
$Z ++ ;
}# Write the end:
self :: $X .= pack ( ‘L1’ , 0 ) ; #
self :: $X .= pack ( ‘L1’ , 0 ) ; #
}}
# Scenario:
$Scen = ‘YourScenario.scx’ ;# Keyword:
$Word = ‘TRIGGER_START’ ;# Get scenario’s data:
$Cont = file_get_contents ( $Scen ) ;# Skip 4 bits:
$Head [ ‘Version’ ] [ 1 ] = substr ( $Cont , 0 , 4 ) ;# Get length:
$Head [ ‘Length’ ] = implode ( ” , unpack ( ‘L1’ , substr ( $Cont , 4 ) ) ) ;# Start of body:
$Line = $Head [ ‘Length’ ] + 8 ;# Save head without body:
file_put_contents ( ‘Head.hex’ , substr ( $Cont , 0 , $Line ) ) ;# GZ-Inflate the body:
$Cont = gzinflate ( substr ( $Cont , $Line ) ) ;# Find start of triggers by keyword:
$Line = strpos ( $Cont , $Word ) – 26 ;# Save body without triggers:
file_put_contents ( ‘Body.hex’ , substr ( $Cont , 0 , $Line ) ) ;# Import new triggers:
if ( file_exists ( ‘Triggers.php’ ) ) include ‘Triggers.php’ ; else die ( ‘Triggers.php file does not exist !’ ) ;# Write new triggers:
Scenario :: Write_Triggers ( $I ) ;# Write the end:
Scenario :: $O .= pack ( ‘L1’ , 0 ) ; #
Scenario :: $O .= pack ( ‘L1’ , 0 ) ; ## Remove extention:
$Scen = str_replace ( ‘.scn’ , ” , $Scen ) ;
$Scen = str_replace ( ‘.scx’ , ” , $Scen ) ;# Loop 100 times:
foreach ( range ( 1 , 100 ) as $J )
{
# Set new filename:
$File = $Scen . ‘[‘ . $J . ‘].scx’ ; $J ++ ;# Check for incremented filenames:
if ( ! file_exists ( $File ) )
{
# Deflate body with triggers and merge head with deflation:
file_put_contents ( $File , file_get_contents ( ‘Head.hex’ ) . gzdeflate ( file_get_contents ( ‘Body.hex’ ) . Scenario :: $O ) ) ; break ;
}
}# Write results:
echo ‘' . $File . '
‘ ;
?>
STEP 5:
Make sure to specify your scenario’s name to the “$Scen” variable and Magic-Keyword to the “$Word” variable (refer to Step 6 for clarification).
STEP 6:
Make sure that the first trigger from your scenario has the Magic-Keyword at the absolute start of the Trigger-Description (a keyword such as “TRIGGER_START”).
STEP 7:
Create “Triggers.php” with the following contents:
<?# Trigger 0 …
$I[0][0]=1;#
$I[0][1]=0;#
$I[0][2]=0;#
$I[0][3]=0;#
$I[0][4]=”This is the trigger’s description”;#
$I[0][5]=”New Trigger 1″;#$I[0][E][0][0]=20;# Display-Instructions
$I[0][E][0][T]=0;#
$I[0][E][0][N]=0;#
$I[0][E][0][X]=”Yo yo, hello…”;
$I[0][E][0][D]=”Age Up”;# Or you can skip directly to trigger 1 effect without specifying trigger 1:
$I[1][E][0][X]=”This is the second trigger’s effect text…”;?>
STEP 8:
Open the 2 .php files in PHP Designer. From the “triggers.php”, use the example triggers as a format sample to make your own triggers. After making your triggers, save “triggers.php” and Debug “index.php”. This will create “YourScenario[1].scx” … and “YourScenario[2].scx” (increment) each time you Debug.
FURTHER INFO:
- Note that the AI Script data are contained at the end of the scenario. Any AI Script data will be delimited since I have used a series of 0000 to skip AI Scripts and end the scenario .
- I intend to give the trigger Reader for the scenario’s triggers.
- I intend to give the XML importer/exporter for triggers. It will be the same XML format as AoK:TS for the convenience of those who wish AoK:TS XML import worked.
- When I release version 2, web admins (such as you Leif Ericson, or Voobly.com, AoC-Zone) with a server that supports PHP will find PHP-Genie an excellent tool to read and view information about Scenarios or Saved-Games. Including a mini-map viewer (Version 3 only).
Do you want to comment on this article? Thank the author? Tribute resources for its improvement? Raze it to the ground?
Come by and visit its thread in the University Forum!