As many of you know, script-eval is limited to being able to call
31 32 characters worth of script. This leads to *fun* workarounds like really short script names and using variables (also with short names) to hold script parameters. Then Axem said to me on IRC the other day, "What if all the script-eval arguments could be concatenated together and passed to the scripting system?" Intriguing concept... and this is the result
commit c7363f011de4260572fcfe3bf9d25c5961be6579
Author: niffiwan <[email protected]>
Date: Sun Mar 30 15:04:17 2014 +1000
allow script-eval to run scripts longer than 31 chars
It's a workaround to the sexp TOKEN_LENGTH limit
The script can be broken up across multiple arguments
e.g.
( script-eval
"ba.warning('foo"
" more and more and more"
" and the rest')"
)
Kudos to Axem for suggesting the idea
diff --git a/code/parse/scripting.cpp b/code/parse/scripting.cpp
index 1c3060f..6d04a80 100644
--- a/code/parse/scripting.cpp
+++ b/code/parse/scripting.cpp
@@ -1068,7 +1068,7 @@ int script_state::OutputMeta(char *filename)
return 1;
}
-bool script_state::EvalString(char* string, char *format, void *rtn, char *debug_str)
+bool script_state::EvalString(const char* string, char *format, void *rtn, const char *debug_str)
{
char lastchar = string[strlen(string)-1];
diff --git a/code/parse/scripting.h b/code/parse/scripting.h
index 9d28528..f7f8056 100644
--- a/code/parse/scripting.h
+++ b/code/parse/scripting.h
@@ -189,7 +189,7 @@ public:
void RemHookVars(unsigned int num, ...);
//***Hook creation functions
- bool EvalString(char* string, char *format=NULL, void *rtn=NULL, char *debug_str=NULL);
+ bool EvalString(const char* string, char *format=NULL, void *rtn=NULL, const char *debug_str=NULL);
void ParseChunk(script_hook *dest, char* debug_str=NULL);
bool ParseCondition(const char *filename="<Unknown>");
diff --git a/code/parse/sexp.cpp b/code/parse/sexp.cpp
index 18d0d71..50024d7 100644
--- a/code/parse/sexp.cpp
+++ b/code/parse/sexp.cpp
@@ -21391,6 +21391,7 @@ int sexp_script_eval(int node, int return_type)
{
int n = node;
char *s = CTEXT(n);
+ SCP_string lua_cmd;
bool success = false;
int r = -1;
@@ -21406,9 +21407,10 @@ int sexp_script_eval(int node, int return_type)
case OPR_NULL:
while(n != -1)
{
- success = Script_system.EvalString(s, NULL, NULL, CTEXT(n));
+ lua_cmd.append(CTEXT(n));
n = CDR(n);
}
+ success = Script_system.EvalString(lua_cmd.c_str(), NULL, NULL, lua_cmd.c_str());
break;
default:
Error(LOCATION, "Bad type passed to sexp_script_eval - get a coder");
@@ -32560,9 +32562,11 @@ sexp_help_struct Sexp_help[] = {
},
{OP_SCRIPT_EVAL, "script-eval\r\n"
- "\tEvaluates script"
+ "\tEvaluates one script\r\n"
+ "\tAdditional arguments are the rest of the script in 31 (+NULL character) chunks\r\n\r\n"
"Takes at least 1 argument...\r\n"
"\t1:\tScript to evaluate\r\n"
+ "\tRest:\tRemainder of script if the script length exceeds 32 characters\r\n"
},
{OP_FORCE_GLIDE, "force-glide\r\n"
In other words, at the cost of a little ugliness in the script-eval arguments, you can now pass an arbitrary
1 length script to script-eval.
Before I consider committing this to trunk, I'd like some wider testing of the solution, so please grab the executables linked here and let me know the results.
http://www.mediafire.com/download/e9u1z5bkpv9o0wc/new-script-eval.7zLastly, please note that script-eval was already designed to accept multiple parameters, but the implementation was broken. It called the 1st argument in place of all arguments. i.e. 3 arguments equalled three calls of the 1st argument. Therefore I'm confident that changing the sexp like this won't break any existing missions.
1. There are no prizes if you break it by passing 11MB of text to script-eval
edit: (yep, its 32 chars, not 31)