From 2b5777b1adce02b9386f5f411ee3439b0cd49069 Mon Sep 17 00:00:00 2001 From: Ryan Shepherd Date: Tue, 25 Sep 2018 16:55:45 -0400 Subject: [PATCH] More advanced scripting --- PerlRPG/Game.pm | 6 +++- PerlRPG/Script.pm | 69 ++++++++++++++++++++++++++++++++++++++++++--- Resources/script.gs | 18 +++++++----- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/PerlRPG/Game.pm b/PerlRPG/Game.pm index 2757590..6433c37 100644 --- a/PerlRPG/Game.pm +++ b/PerlRPG/Game.pm @@ -14,7 +14,7 @@ use PerlRPG::Controls; use vars qw/$app @ISA @EXPORT @EXPORT_OK/; @ISA = qw/Exporter/; -@EXPORT = qw/InitApp Run RunScript GetOption SetOption/; +@EXPORT = qw/InitApp Run RunScript GetOption SetOption ExitGame/; @EXPORT_OK = @EXPORT; $app = undef; @@ -45,6 +45,10 @@ sub InitApp { return $app; } +sub ExitGame { + SetOption('Running', 0); +} + sub Run { my $tick = SDL::get_ticks(); while($opt{'Running'}) { diff --git a/PerlRPG/Script.pm b/PerlRPG/Script.pm index b0eba0b..9ea4dd0 100644 --- a/PerlRPG/Script.pm +++ b/PerlRPG/Script.pm @@ -24,6 +24,7 @@ my %script_commands = ( 'Wait' => {'sub' => sub {}, 'wait' => 1}, 'AddSayer' => {'sub' => \&AddSayer, 'wait' => 0}, 'Define' => {'sub' => \&DefGameVar, 'wait' => 0}, + 'ExitGame' => {'sub' => \&PerlRPG::Game::ExitGame, 'wait' => 1}, 'Jump' => {'sub' => \&PerlRPG::Script::RunScript, 'wait' => 0}, @@ -179,8 +180,68 @@ sub AddSayer { sub EvalString { my $val = shift(@_); # Perform math calculations and the like - LogData(ERROR, "Doing incomplete EvalString for '$val'"); - return $val; + + # Check for simple numbers + if(my($v) = $val=~/^\s*(\d+)\s*$/) { + return $v; + } + + #LogData(DEBUG, "Doing complex Eval"); + # Ensure spacing around tokens + while(my($full,$f,$o,$s)=$val=~/((\S)([+-\/\*\(\)\.])(\S))/) { + #LogData(DEBUG, "Replacing '$full' with '$f $o $s'"); + $val=~s/\Q$full\E/$f $o $s/; + } + while(my($full,$f,$o)=$val=~/((\S)([+-\/\*\(\)\.]))\s/) { + #LogData(DEBUG, "Replacing '$full' with '$f $o'"); + $val=~s/\Q$full\E/$f $o/; + } + while(my($full,$o,$s)=$val=~/\s(([+-\/\*\(\)\.])(\S))/) { + #LogData(DEBUG, "Replacing '$full' with '$o $s'"); + $val=~s/\Q$full\E/$o $s/; + } + if($val=~/^[+-\/\*\(\)\.]\S/) { + substr($val, 1, 0)=' '; + #LogData(DEBUG, "Inserting space after initial character"); + } + if($val=~/\S[+-\/\*\(\)\.]$/) { + substr($val, -1, 0)=' '; + #LogData(DEBUG, "Inserting space before last character"); + } + + LogData(DEBUG, "Val is '$val'"); + + # Tokenize + my @tokens = split(/\s+/,$val); + + + for(my $i=0;$i<@tokens-0;$i++) { LogData(DEBUG, "Pass 1 Token [%i], '%s'", $i, $tokens[$i]); } + + for(my $i=0;$i<@tokens-0;$i++) { + my $t = $tokens[$i]; + if($i < @tokens-1 && $tokens[$i+1] eq '(') { + # This is a function call; Don't replace it + } elsif(exists $game_vars{$t}) { + # Token matches a game var, replace it + $tokens[$i] = GetGameVar($t); + } elsif(IsString($tokens[$i])) { + # Looks like a string, Call StringSubst on it + $tokens[$i] = '"' . StringSubst($tokens[$i]) . '"'; + } + } + + for(my $i=0;$i<@tokens-0;$i++) { LogData(DEBUG, "Pass 2 Token [%i], '%s'", $i, $tokens[$i]); } + + my $eval_str = '$eval_res = ' . join(' ', @tokens) . ';'; + LogData(DEBUG, "About to eval '$eval_str'"); + my $eval_res; + eval $eval_str; + if($@) { + LogData(ERROR, "Error in eval: $@"); + return 0; + } + LogData(DEBUG, "Got result of '$eval_res'"); + return $eval_res; } sub StringSubst { @@ -193,7 +254,7 @@ sub StringSubst { while(my($f,$n)=$text=~/(\[(\S+)\])/) { my $v=GetGameVar($n); - if(!$v) { + if(!defined $v) { $v = '!!INVALID!!'; } $text=~s/\Q$f\E/$v/g; @@ -205,7 +266,7 @@ sub StringSubst { sub SayLine { my($ref, $text)=@_; - LogData(INFO, "%s saying \"%s\"", $ref->{'DisplayName'}, $text); + LogData(DEVALL, "%s saying \"%s\"", $ref->{'DisplayName'}, $text); $text = StringSubst($text); DrawSpeech($ref, $text); diff --git a/Resources/script.gs b/Resources/script.gs index 64627ca..3266171 100644 --- a/Resources/script.gs +++ b/Resources/script.gs @@ -1,21 +1,25 @@ __init__: SetBackground 128 128 128 255 SetAssetOption spritesheet.png Animated - Define VarName "Foo" + Define LoopCount 0 + Define TestVar 1 Show aka spritesheet.png 0 0 1 flip Show aka2 spritesheet.png 100 0 2 Reverse Show aka3 spritesheet.png 200 0 3 max_loops=10 - AddSayer h Hermione aka01.png 200 200 200 255 - AddSayer h2 Hermione aka05.png 255 0 0 255 + AddSayer h "Hermione" aka01.png 200 200 200 255 + AddSayer h2 "Topless Hermione" aka05.png 255 0 0 255 Jump donothing donothing: Wait - Wait - h "Some text here\nNext line" - h2 "Say Foo here [VarName]" - VarName = "[VarName]." + LoopCount=LoopCount+1 + h "Loop number [LoopCount]" + TestVar=lc("Foo").uc(lc("Foo")) + h "TestVar [TestVar]" + TestVar = uc("[TestVar]") + h "TestVar2 [TestVar]" + ExitGame Jump donothing