More advanced scripting

This commit is contained in:
Ryan Shepherd 2018-09-25 16:55:45 -04:00
parent 17337d547d
commit 2b5777b1ad
3 changed files with 81 additions and 12 deletions

View File

@ -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'}) {

View File

@ -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);

View File

@ -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