summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/script.c')
-rw-r--r--src/map/script.c568
1 files changed, 292 insertions, 276 deletions
diff --git a/src/map/script.c b/src/map/script.c
index 04d834f74..09c19cb3e 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -97,9 +97,7 @@ int str_hash[SCRIPT_HASH_SIZE];
//#define SCRIPT_HASH_SDBM
#define SCRIPT_HASH_ELF
-static DBMap* userfunc_db=NULL; // const char* func_name -> struct script_code*
static int parse_options=0;
-DBMap* script_get_userfunc_db(void){ return userfunc_db; }
// important buildin function references for usage in scripts
static int buildin_set_ref = 0;
@@ -107,26 +105,6 @@ static int buildin_callsub_ref = 0;
static int buildin_callfunc_ref = 0;
static int buildin_getelementofarray_ref = 0;
-// Caches compiled autoscript item code.
-// Note: This is not cleared when reloading itemdb.
-static DBMap* autobonus_db=NULL; // char* script -> char* bytecode
-
-struct Script_Config script_config = {
- 1, // warn_func_mismatch_argtypes
- 1, 65535, 2048, //warn_func_mismatch_paramnum/check_cmdcount/check_gotocount
- 0, INT_MAX, // input_min_value/input_max_value
- "OnPCDieEvent", //die_event_name
- "OnPCKillEvent", //kill_pc_event_name
- "OnNPCKillEvent", //kill_mob_event_name
- "OnPCLoginEvent", //login_event_name
- "OnPCLogoutEvent", //logout_event_name
- "OnPCLoadMapEvent", //loadmap_event_name
- "OnPCBaseLvUpEvent", //baselvup_event_name
- "OnPCJobLvUpEvent", //joblvup_event_name
- "OnTouch_", //ontouch_name (runs on first visible char to enter area, picks another char if the first char leaves)
- "OnTouch", //ontouch2_name (run whenever a char walks into the OnTouch area)
-};
-
static jmp_buf error_jump;
static char* error_msg;
static const char* error_pos;
@@ -171,21 +149,15 @@ const char* parse_syntax(const char* p);
static int parse_syntax_for_flag = 0;
extern int status_current_equip_item_index; //for New CARDS Scripts. It contains Inventory Index of the EQUIP_SCRIPT caller item. [Lupus]
-int potion_flag=0; //For use on Alchemist improved potions/Potion Pitcher. [Skotlex]
-int potion_hp=0, potion_per_hp=0, potion_sp=0, potion_per_sp=0;
-int potion_target=0;
-
struct script_interface script_s;
-c_op get_com(unsigned char *script,int *pos);
-int get_num(unsigned char *script,int *pos);
+c_op get_com(unsigned char *scriptbuf,int *pos);
+int get_num(unsigned char *scriptbuf,int *pos);
/*==========================================
* (Only those needed) local declaration prototype
*------------------------------------------*/
-const char* parse_subexpr(const char* p,int limit);
-int run_func(struct script_state *st);
enum {
MF_NOMEMO, //0
@@ -431,7 +403,7 @@ static void script_reportfunc(struct script_state* st)
if( params > 0 )
{
- ShowDebug("Function: %s (%d parameter%s):\n", get_str(id), params, ( params == 1 ) ? "" : "s");
+ ShowDebug("Function: %s (%d parameter%s):\n", script->get_str(id), params, ( params == 1 ) ? "" : "s");
for( i = 2; i <= script_lastdata(st); i++ )
{
@@ -440,7 +412,7 @@ static void script_reportfunc(struct script_state* st)
}
else
{
- ShowDebug("Function: %s (no parameters)\n", get_str(id));
+ ShowDebug("Function: %s (no parameters)\n", script->get_str(id));
}
}
@@ -509,19 +481,19 @@ static unsigned int calc_hash(const char* p)
*------------------------------------------*/
/// Looks up string using the provided id.
-const char* get_str(int id)
+const char* script_get_str(int id)
{
Assert( id >= LABEL_START && id < script->str_size );
return script->str_buf+script->str_data[id].str;
}
/// Returns the uid of the string, or -1.
-static int search_str(const char* p)
+int script_search_str(const char* p)
{
int i;
for( i = str_hash[calc_hash(p)]; i != 0; i = script->str_data[i].next )
- if( strcasecmp(get_str(i),p) == 0 )
+ if( strcasecmp(script->get_str(i),p) == 0 )
return i;
return -1;
@@ -529,7 +501,7 @@ static int search_str(const char* p)
/// Stores a copy of the string and returns its id.
/// If an identical string is already present, returns its id instead.
-int add_str(const char* p)
+int script_add_str(const char* p)
{
int i, h;
int len;
@@ -540,7 +512,7 @@ int add_str(const char* p)
str_hash[h] = script->str_num;
} else {// scan for end of list, or occurence of identical string
for( i = str_hash[h]; ; i = script->str_data[i].next ) {
- if( strcasecmp(get_str(i),p) == 0 )
+ if( strcasecmp(script->get_str(i),p) == 0 )
return i; // string already in list
if( script->str_data[i].next == 0 )
break; // reached the end
@@ -687,7 +659,7 @@ void set_label(int l,int pos, const char* script_pos)
}
/// Skips spaces and/or comments.
-const char* skip_space(const char* p)
+const char* script_skip_space(const char* p)
{
if( p == NULL )
return NULL;
@@ -706,7 +678,7 @@ const char* skip_space(const char* p)
for(;;)
{
if( *p == '\0' )
- return p;//disp_error_message("script:skip_space: end of file while parsing block comment. expected "CL_BOLD"*/"CL_NORM, p);
+ return p;//disp_error_message("script:script->skip_space: end of file while parsing block comment. expected "CL_BOLD"*/"CL_NORM, p);
if( *p == '*' && p[1] == '/' )
{// end of block comment
p += 2;
@@ -750,7 +722,7 @@ static const char* skip_word(const char* p) {
}
/// Adds a word to script->str_data.
/// @see skip_word
-/// @see add_str
+/// @see script->add_str
static int add_word(const char* p) {
int len;
int i;
@@ -768,7 +740,7 @@ static int add_word(const char* p) {
script->word_buf[len] = 0;
// add the word
- i = add_str(script->word_buf);
+ i = script->add_str(script->word_buf);
return i;
}
@@ -803,8 +775,8 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom)
++arg; // count func as argument
} else {
#ifdef SCRIPT_CALLFUNC_CHECK
- const char* name = get_str(func);
- if( !is_custom && strdb_get(userfunc_db, name) == NULL ) {
+ const char* name = script->get_str(func);
+ if( !is_custom && strdb_get(script->userfunc_db, name) == NULL ) {
#endif
disp_error_message("parse_line: expect command, missing function name or calling undeclared function",p);
#ifdef SCRIPT_CALLFUNC_CHECK
@@ -821,13 +793,13 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom)
}
p = skip_word(p);
- p = skip_space(p);
+ p = script->skip_space(p);
syntax.curly[syntax.curly_count].type = TYPE_ARGLIST;
syntax.curly[syntax.curly_count].count = 0;
if( *p == ';' )
{// <func name> ';'
syntax.curly[syntax.curly_count].flag = ARGLIST_NO_PAREN;
- } else if( *p == '(' && *(p2=skip_space(p+1)) == ')' )
+ } else if( *p == '(' && *(p2=script->skip_space(p+1)) == ')' )
{// <func name> '(' ')'
syntax.curly[syntax.curly_count].flag = ARGLIST_PAREN;
p = p2;
@@ -849,13 +821,13 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom)
}
++syntax.curly_count;
while( *arg ) {
- p2=parse_subexpr(p,-1);
+ p2=script->parse_subexpr(p,-1);
if( p == p2 )
break; // not an argument
if( *arg != '*' )
++arg; // next argument
- p=skip_space(p2);
+ p=script->skip_space(p2);
if( *arg == 0 || *p != ',' )
break; // no more arguments
++p; // skip comma
@@ -863,7 +835,7 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom)
--syntax.curly_count;
}
if( arg && *arg && *arg != '?' && *arg != '*' )
- disp_error_message2("parse_callfunc: not enough arguments, expected ','", p, script_config.warn_func_mismatch_paramnum);
+ disp_error_message2("parse_callfunc: not enough arguments, expected ','", p, script->config.warn_func_mismatch_paramnum);
if( syntax.curly[syntax.curly_count].type != TYPE_ARGLIST )
disp_error_message("parse_callfunc: DEBUG last curly is not an argument list",p);
if( syntax.curly[syntax.curly_count].flag == ARGLIST_PAREN ){
@@ -903,7 +875,7 @@ const char* parse_variable(const char* p) {
// skip the variable where applicable
p = skip_word(p);
- p = skip_space(p);
+ p = script->skip_space(p);
if( p == NULL ) {// end of the line or invalid buffer
return NULL;
@@ -915,7 +887,7 @@ const char* parse_variable(const char* p) {
if( *p == '[' ) ++ j;
}
- if( !(p = skip_space(p)) ) {// end of line or invalid characters remaining
+ if( !(p = script->skip_space(p)) ) {// end of line or invalid characters remaining
disp_error_message("Missing right expression or closing bracket for variable.", p);
}
}
@@ -942,18 +914,18 @@ const char* parse_variable(const char* p) {
switch( type ) {
case C_EQ: {// incremental modifier
- p = skip_space( &p[1] );
+ p = script->skip_space( &p[1] );
}
break;
case C_L_SHIFT:
case C_R_SHIFT: {// left or right shift modifier
- p = skip_space( &p[3] );
+ p = script->skip_space( &p[3] );
}
break;
default: {// normal incremental command
- p = skip_space( &p[2] );
+ p = script->skip_space( &p[2] );
}
}
@@ -990,8 +962,8 @@ const char* parse_variable(const char* p) {
add_scriptl(word);
// process the sub-expression for this assignment
- p3 = parse_subexpr(p2 + 1, 1);
- p3 = skip_space(p3);
+ p3 = script->parse_subexpr(p2 + 1, 1);
+ p3 = script->skip_space(p3);
if( *p3 != ']' ) {// closing parenthesis is required for this script
disp_error_message("Missing closing ']' parenthesis for the variable assignment.", p3);
@@ -1011,7 +983,7 @@ const char* parse_variable(const char* p) {
add_scripti(1);
add_scriptc(type == C_ADD_PP ? C_ADD : C_SUB);
} else {// process the value as an expression
- p = parse_subexpr(p, -1);
+ p = script->parse_subexpr(p, -1);
if( type != C_EQ )
{// push the type of modifier onto the stack
@@ -1035,15 +1007,15 @@ const char* parse_variable(const char* p) {
const char* parse_simpleexpr(const char *p)
{
int i;
- p=skip_space(p);
+ p=script->skip_space(p);
if(*p==';' || *p==',')
disp_error_message("parse_simpleexpr: unexpected end of expression",p);
if(*p=='('){
if( (i=syntax.curly_count-1) >= 0 && syntax.curly[i].type == TYPE_ARGLIST )
++syntax.curly[i].count;
- p=parse_subexpr(p+1,-1);
- p=skip_space(p);
+ p=script->parse_subexpr(p+1,-1);
+ p=script->skip_space(p);
if( (i=syntax.curly_count-1) >= 0 && syntax.curly[i].type == TYPE_ARGLIST &&
syntax.curly[i].flag == ARGLIST_UNDEFINED && --syntax.curly[i].count == 0
){
@@ -1096,8 +1068,8 @@ const char* parse_simpleexpr(const char *p)
return parse_callfunc(p,1,0);
#ifdef SCRIPT_CALLFUNC_CHECK
else {
- const char* name = get_str(l);
- if( strdb_get(userfunc_db,name) != NULL ) {
+ const char* name = script->get_str(l);
+ if( strdb_get(script->userfunc_db,name) != NULL ) {
return parse_callfunc(p,1,1);
}
}
@@ -1115,8 +1087,8 @@ const char* parse_simpleexpr(const char *p)
add_scriptc(C_ARG);
add_scriptl(l);
- p=parse_subexpr(p+1,-1);
- p=skip_space(p);
+ p=script->parse_subexpr(p+1,-1);
+ p=script->skip_space(p);
if( *p != ']' )
disp_error_message("parse_simpleexpr: unmatched ']'",p);
++p;
@@ -1132,15 +1104,15 @@ const char* parse_simpleexpr(const char *p)
/*==========================================
* Analysis of the expression
*------------------------------------------*/
-const char* parse_subexpr(const char* p,int limit)
+const char* script_parse_subexpr(const char* p,int limit)
{
int op,opl,len;
const char* tmpp;
- p=skip_space(p);
+ p=script->skip_space(p);
if( *p == '-' ){
- tmpp = skip_space(p+1);
+ tmpp = script->skip_space(p+1);
if( *tmpp == ';' || *tmpp == ',' ){
add_scriptl(LABEL_NEXTLINE);
p++;
@@ -1149,11 +1121,11 @@ const char* parse_subexpr(const char* p,int limit)
}
if((op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~')){
- p=parse_subexpr(p+1,10);
+ p=script->parse_subexpr(p+1,10);
add_scriptc(op);
} else
p=parse_simpleexpr(p);
- p=skip_space(p);
+ p=script->skip_space(p);
while((
(op=C_OP3,opl=0,len=1,*p=='?') ||
(op=C_ADD,opl=8,len=1,*p=='+') ||
@@ -1176,16 +1148,16 @@ const char* parse_subexpr(const char* p,int limit)
(op=C_LT,opl=3,len=1,*p=='<')) && opl>limit){
p+=len;
if(op == C_OP3) {
- p=parse_subexpr(p,-1);
- p=skip_space(p);
+ p=script->parse_subexpr(p,-1);
+ p=script->skip_space(p);
if( *(p++) != ':')
disp_error_message("parse_subexpr: need ':'", p-1);
- p=parse_subexpr(p,-1);
+ p=script->parse_subexpr(p,-1);
} else {
- p=parse_subexpr(p,opl);
+ p=script->parse_subexpr(p,opl);
}
add_scriptc(op);
- p=skip_space(p);
+ p=script->skip_space(p);
}
return p; /* return first untreated operator */
@@ -1201,7 +1173,7 @@ const char* parse_expr(const char *p)
case '}':
disp_error_message("parse_expr: unexpected char",p);
}
- p=parse_subexpr(p,-1);
+ p=script->parse_subexpr(p,-1);
return p;
}
@@ -1212,7 +1184,7 @@ const char* parse_line(const char* p)
{
const char* p2;
- p=skip_space(p);
+ p=script->skip_space(p);
if(*p==';') {
//Close decision for if(); for(); while();
p = parse_syntax_close(p + 1);
@@ -1221,7 +1193,7 @@ const char* parse_line(const char* p)
if(*p==')' && parse_syntax_for_flag)
return p+1;
- p = skip_space(p);
+ p = script->skip_space(p);
if(p[0] == '{') {
syntax.curly[syntax.curly_count].type = TYPE_NULL;
syntax.curly[syntax.curly_count].count = -1;
@@ -1246,7 +1218,7 @@ const char* parse_line(const char* p)
}
p = parse_callfunc(p,0,0);
- p = skip_space(p);
+ p = script->skip_space(p);
if(parse_syntax_for_flag) {
if( *p != ')' )
@@ -1292,7 +1264,7 @@ const char* parse_curly_close(const char* p)
// You are here labeled
sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos, p);
if(syntax.curly[pos].flag) {
@@ -1305,7 +1277,7 @@ const char* parse_curly_close(const char* p)
// Label end
sprintf(label,"__SW%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos, p);
linkdb_final(&syntax.curly[pos].case_label); // free the list of case label
syntax.curly_count--;
@@ -1355,7 +1327,7 @@ const char* parse_syntax(const char* p)
parse_line(label);
syntax.curly_count--;
}
- p = skip_space(p2);
+ p = script->skip_space(p2);
if(*p != ';')
disp_error_message("parse_syntax: need ';'",p);
// Closing decision if, for , while
@@ -1384,11 +1356,11 @@ const char* parse_syntax(const char* p)
// You are here labeled
sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos, p);
}
//Decision statement switch
- p = skip_space(p2);
+ p = script->skip_space(p2);
if(p == p2) {
disp_error_message("parse_syntax: expect space ' '",p);
}
@@ -1409,7 +1381,7 @@ const char* parse_syntax(const char* p)
if(np != p)
disp_error_message("parse_syntax: 'case' label is not an integer",np);
}
- p = skip_space(p);
+ p = script->skip_space(p);
if(*p != ':')
disp_error_message("parse_syntax: expect ':'",p);
sprintf(label,"if(%d != $@__SW%x_VAL) goto __SW%x_%x;",
@@ -1422,7 +1394,7 @@ const char* parse_syntax(const char* p)
if(syntax.curly[pos].count != 1) {
// Label after the completion of FALLTHRU
sprintf(label,"__SW%x_%xJ",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
}
// check duplication of case label [Rayce]
@@ -1463,7 +1435,7 @@ const char* parse_syntax(const char* p)
parse_line(label);
syntax.curly_count--;
}
- p = skip_space(p2);
+ p = script->skip_space(p2);
if(*p != ';')
disp_error_message("parse_syntax: need ';'",p);
//Closing decision if, for , while
@@ -1484,12 +1456,12 @@ const char* parse_syntax(const char* p)
char label[256];
int l;
// Put the label location
- p = skip_space(p2);
+ p = script->skip_space(p2);
if(*p != ':') {
disp_error_message("parse_syntax: need ':'",p);
}
sprintf(label,"__SW%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
// Skip to the next link w/o condition
@@ -1500,7 +1472,7 @@ const char* parse_syntax(const char* p)
// The default label
sprintf(label,"__SW%x_DEF",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
syntax.curly[syntax.curly_count - 1].flag = 1;
@@ -1510,7 +1482,7 @@ const char* parse_syntax(const char* p)
} else if(p2 - p == 2 && !strncasecmp(p,"do",2)) {
int l;
char label[256];
- p=skip_space(p2);
+ p=script->skip_space(p2);
syntax.curly[syntax.curly_count].type = TYPE_DO;
syntax.curly[syntax.curly_count].count = 1;
@@ -1518,7 +1490,7 @@ const char* parse_syntax(const char* p)
syntax.curly[syntax.curly_count].flag = 0;
// Label of the (do) form here
sprintf(label,"__DO%x_BGN",syntax.curly[syntax.curly_count].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
syntax.curly_count++;
return p;
@@ -1536,7 +1508,7 @@ const char* parse_syntax(const char* p)
syntax.curly[syntax.curly_count].flag = 0;
syntax.curly_count++;
- p=skip_space(p2);
+ p=script->skip_space(p2);
if(*p != '(')
disp_error_message("parse_syntax: need '('",p);
@@ -1549,21 +1521,21 @@ const char* parse_syntax(const char* p)
// Form the start of label decision
sprintf(label,"__FR%x_J",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
- p=skip_space(p);
+ p=script->skip_space(p);
if(*p == ';') {
// For (; Because the pattern of always true ;)
;
} else {
// Skip to the end point if the condition is false
sprintf(label,"__FR%x_FIN",syntax.curly[pos].index);
- add_scriptl(add_str("jump_zero"));
+ add_scriptl(script->add_str("jump_zero"));
add_scriptc(C_ARG);
p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
+ p=script->skip_space(p);
+ add_scriptl(script->add_str(label));
add_scriptc(C_FUNC);
}
if(*p != ';')
@@ -1578,7 +1550,7 @@ const char* parse_syntax(const char* p)
// Labels to form the next loop
sprintf(label,"__FR%x_NXT",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
// Process the next time you enter the loop
@@ -1597,7 +1569,7 @@ const char* parse_syntax(const char* p)
// Loop start labeling
sprintf(label,"__FR%x_BGN",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
return p;
}
@@ -1605,11 +1577,11 @@ const char* parse_syntax(const char* p)
{// internal script function
const char *func_name;
- func_name = skip_space(p2);
+ func_name = script->skip_space(p2);
p = skip_word(func_name);
if( p == func_name )
disp_error_message("parse_syntax:function: function name is missing or invalid", p);
- p2 = skip_space(p);
+ p2 = script->skip_space(p);
if( *p2 == ';' )
{// function <name> ;
// function declaration - just register the name
@@ -1656,7 +1628,7 @@ const char* parse_syntax(const char* p)
else
disp_error_message("parse_syntax:function: function name is invalid", func_name);
- return skip_space(p);
+ return script->skip_space(p);
}
else
{
@@ -1669,7 +1641,7 @@ const char* parse_syntax(const char* p)
if(p2 - p == 2 && !strncasecmp(p,"if",2)) {
// If process
char label[256];
- p=skip_space(p2);
+ p=script->skip_space(p2);
if(*p != '(') { //Prevent if this {} non-c syntax. from Rayce (jA)
disp_error_message("need '('",p);
}
@@ -1679,11 +1651,11 @@ const char* parse_syntax(const char* p)
syntax.curly[syntax.curly_count].flag = 0;
sprintf(label,"__IF%x_%x",syntax.curly[syntax.curly_count].index,syntax.curly[syntax.curly_count].count);
syntax.curly_count++;
- add_scriptl(add_str("jump_zero"));
+ add_scriptl(script->add_str("jump_zero"));
add_scriptc(C_ARG);
p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
+ p=script->skip_space(p);
+ add_scriptl(script->add_str(label));
add_scriptc(C_FUNC);
return p;
}
@@ -1693,7 +1665,7 @@ const char* parse_syntax(const char* p)
if(p2 - p == 6 && !strncasecmp(p,"switch",6)) {
// Processing of switch ()
char label[256];
- p=skip_space(p2);
+ p=script->skip_space(p2);
if(*p != '(') {
disp_error_message("need '('",p);
}
@@ -1703,11 +1675,11 @@ const char* parse_syntax(const char* p)
syntax.curly[syntax.curly_count].flag = 0;
sprintf(label,"$@__SW%x_VAL",syntax.curly[syntax.curly_count].index);
syntax.curly_count++;
- add_scriptl(add_str("set"));
+ add_scriptl(script->add_str("set"));
add_scriptc(C_ARG);
- add_scriptl(add_str(label));
+ add_scriptl(script->add_str(label));
p=parse_expr(p);
- p=skip_space(p);
+ p=script->skip_space(p);
if(*p != '{') {
disp_error_message("parse_syntax: need '{'",p);
}
@@ -1720,7 +1692,7 @@ const char* parse_syntax(const char* p)
if(p2 - p == 5 && !strncasecmp(p,"while",5)) {
int l;
char label[256];
- p=skip_space(p2);
+ p=script->skip_space(p2);
if(*p != '(') {
disp_error_message("need '('",p);
}
@@ -1730,17 +1702,17 @@ const char* parse_syntax(const char* p)
syntax.curly[syntax.curly_count].flag = 0;
// Form the start of label decision
sprintf(label,"__WL%x_NXT",syntax.curly[syntax.curly_count].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
// Skip to the end point if the condition is false
sprintf(label,"__WL%x_FIN",syntax.curly[syntax.curly_count].index);
syntax.curly_count++;
- add_scriptl(add_str("jump_zero"));
+ add_scriptl(script->add_str("jump_zero"));
add_scriptc(C_ARG);
p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
+ p=script->skip_space(p);
+ add_scriptl(script->add_str(label));
add_scriptc(C_FUNC);
return p;
}
@@ -1787,28 +1759,28 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
// Put the label of the location
sprintf(label,"__IF%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
syntax.curly[pos].count++;
- p = skip_space(p);
+ p = script->skip_space(p);
p2 = skip_word(p);
if(!syntax.curly[pos].flag && p2 - p == 4 && !strncasecmp(p,"else",4)) {
// else or else - if
- p = skip_space(p2);
+ p = script->skip_space(p2);
p2 = skip_word(p);
if(p2 - p == 2 && !strncasecmp(p,"if",2)) {
// else - if
- p=skip_space(p2);
+ p=script->skip_space(p2);
if(*p != '(') {
disp_error_message("need '('",p);
}
sprintf(label,"__IF%x_%x",syntax.curly[pos].index,syntax.curly[pos].count);
- add_scriptl(add_str("jump_zero"));
+ add_scriptl(script->add_str("jump_zero"));
add_scriptc(C_ARG);
p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
+ p=script->skip_space(p);
+ add_scriptl(script->add_str(label));
add_scriptc(C_FUNC);
*flag = 0;
return p;
@@ -1825,7 +1797,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
syntax.curly_count--;
// Put the label of the final location
sprintf(label,"__IF%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
if(syntax.curly[pos].flag == 1) {
// Because the position of the pointer is the same if not else for this
@@ -1840,17 +1812,17 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
if(syntax.curly[pos].flag) {
// (Come here continue) to form the label here
sprintf(label,"__DO%x_NXT",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
}
// Skip to the end point if the condition is false
- p = skip_space(p);
+ p = script->skip_space(p);
p2 = skip_word(p);
if(p2 - p != 5 || strncasecmp(p,"while",5))
disp_error_message("parse_syntax: need 'while'",p);
- p = skip_space(p2);
+ p = script->skip_space(p2);
if(*p != '(') {
disp_error_message("need '('",p);
}
@@ -1859,11 +1831,11 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
parse_nextline(false, p);
sprintf(label,"__DO%x_FIN",syntax.curly[pos].index);
- add_scriptl(add_str("jump_zero"));
+ add_scriptl(script->add_str("jump_zero"));
add_scriptc(C_ARG);
p=parse_expr(p);
- p=skip_space(p);
- add_scriptl(add_str(label));
+ p=script->skip_space(p);
+ add_scriptl(script->add_str(label));
add_scriptc(C_FUNC);
// Skip to the starting point
@@ -1874,9 +1846,9 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
// Form label of the end point conditions
sprintf(label,"__DO%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
- p = skip_space(p);
+ p = script->skip_space(p);
if(*p != ';') {
disp_error_message("parse_syntax: need ';'",p);
return p+1;
@@ -1896,7 +1868,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
// End for labeling
sprintf(label,"__FR%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
syntax.curly_count--;
return p;
@@ -1912,7 +1884,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
// End while labeling
sprintf(label,"__WL%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
syntax.curly_count--;
return p;
@@ -1928,7 +1900,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
// Put the label of the location
sprintf(label,"__FN%x_FIN",syntax.curly[pos].index);
- l=add_str(label);
+ l=script->add_str(label);
set_label(l,script_pos,p);
syntax.curly_count--;
return p;
@@ -1941,7 +1913,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag)
/// Retrieves the value of a constant.
bool script_get_constant(const char* name, int* value)
{
- int n = search_str(name);
+ int n = script->search_str(name);
if( n == -1 || script->str_data[n].type != C_INT )
{// not found or not a constant
@@ -1954,7 +1926,7 @@ bool script_get_constant(const char* name, int* value)
/// Creates new constant or parameter with given value.
void script_set_constant(const char* name, int value, bool isparameter) {
- int n = add_str(name);
+ int n = script->add_str(name);
if( script->str_data[n].type == C_NOP ) {// new
script->str_data[n].type = isparameter ? C_PARAM : C_INT;
@@ -1967,7 +1939,7 @@ void script_set_constant(const char* name, int value, bool isparameter) {
}
/* adds data to a existent constant in the database, inserted normally via parse */
void script_set_constant2(const char *name, int value, bool isparameter) {
- int n = add_str(name);
+ int n = script->add_str(name);
if( ( script->str_data[n].type == C_NAME || script->str_data[n].type == C_PARAM ) && ( script->str_data[n].val != 0 || script->str_data[n].backpatch != -1 ) ) { // existing parameter or constant
ShowNotice("Conflicting item/script var '%s', prioritising the script var\n",name);
@@ -1986,7 +1958,7 @@ void script_set_constant2(const char *name, int value, bool isparameter) {
}
/* same as constant2 except it will override if necessary, used to clear conflicts during reload */
void script_set_constant_force(const char *name, int value, bool isparameter) {
- int n = add_str(name);
+ int n = script->add_str(name);
if( script->str_data[n].type == C_PARAM )
return;/* the one type we don't mess with, reload doesn't affect it. */
@@ -2120,7 +2092,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
int i;
const int size = ARRAYLENGTH(syntax.curly);
if( error_report )
- script_error(src,file,line,error_msg,error_pos);
+ script->error(src,file,line,error_msg,error_pos);
aFree( error_msg );
aFree( script_buf );
script_pos = 0;
@@ -2135,7 +2107,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
parse_syntax_for_flag=0;
p=src;
- p=skip_space(p);
+ p=script->skip_space(p);
if( options&SCRIPT_IGNORE_EXTERNAL_BRACKETS )
{// does not require brackets around the script
if( *p == '\0' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
@@ -2152,7 +2124,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
{// requires brackets around the script
if( *p != '{' )
disp_error_message("not found '{'",p);
- p = skip_space(p+1);
+ p = script->skip_space(p+1);
if( *p == '}' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) )
{// empty script and can return NULL
aFree( script_buf );
@@ -2181,20 +2153,20 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
if( *p == '\0' )
disp_error_message("unexpected end of script",p);
// Special handling only label
- tmpp=skip_space(skip_word(p));
+ tmpp=script->skip_space(skip_word(p));
if(*tmpp==':' && !(!strncasecmp(p,"default:",8) && p + 7 == tmpp)){
i=add_word(p);
set_label(i,script_pos,p);
if( parse_options&SCRIPT_USE_LABEL_DB )
script->label_add(i,script_pos);
p=tmpp+1;
- p=skip_space(p);
+ p=script->skip_space(p);
continue;
}
// All other lumped
p=parse_line(p);
- p=skip_space(p);
+ p=script->skip_space(p);
parse_nextline(false, p);
}
@@ -2255,7 +2227,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o
break;
case C_NAME:
j = (*(int*)(script_buf+i)&0xffffff);
- ShowMessage(" %s", ( j == 0xffffff ) ? "?? unknown ??" : get_str(j));
+ ShowMessage(" %s", ( j == 0xffffff ) ? "?? unknown ??" : script->get_str(j));
i += 3;
break;
case C_STR:
@@ -2527,12 +2499,12 @@ static int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* nam
int set_var(TBL_PC* sd, char* name, void* val)
{
- return set_reg(NULL, sd, reference_uid(add_str(name),0), name, val, NULL);
+ return set_reg(NULL, sd, reference_uid(script->add_str(name),0), name, val, NULL);
}
void setd_sub(struct script_state *st, TBL_PC *sd, const char *varname, int elem, void *value, struct DBMap **ref)
{
- set_reg(st, sd, reference_uid(add_str(varname),elem), varname, value, ref);
+ set_reg(st, sd, reference_uid(script->add_str(varname),elem), varname, value, ref);
}
/// Converts the data to a string
@@ -2720,7 +2692,7 @@ void pop_stack(struct script_state* st, int start, int end)
{
struct script_retinfo* ri = data->u.ri;
if( ri->var_function )
- script_free_vars(ri->var_function);
+ script->free_vars(ri->var_function);
if( data->ref )
aFree(data->ref);
aFree(ri);
@@ -2761,7 +2733,7 @@ void script_free_vars(struct DBMap* storage)
void script_free_code(struct script_code* code)
{
- script_free_vars( code->script_vars );
+ script->free_vars( code->script_vars );
aFree( code->script_buf );
aFree( code );
}
@@ -2812,16 +2784,16 @@ void script_free_state(struct script_state* st) {
}
if( st->sleep.timer != INVALID_TIMER )
- iTimer->delete_timer(st->sleep.timer, run_script_timer);
+ iTimer->delete_timer(st->sleep.timer, script->run_timer);
if( st->stack ) {
- script_free_vars(st->stack->var_function);
+ script->free_vars(st->stack->var_function);
script->pop_stack(st, 0, st->stack->sp);
aFree(st->stack->stack_data);
ers_free(script->stack_ers, st->stack);
st->stack = NULL;
}
if( st->script && st->script->script_vars && !db_size(st->script->script_vars) ) {
- script_free_vars(st->script->script_vars);
+ script->free_vars(st->script->script_vars);
st->script->script_vars = NULL;
}
st->pos = -1;
@@ -2839,32 +2811,32 @@ void script_free_state(struct script_state* st) {
/*==========================================
* Read command
*------------------------------------------*/
-c_op get_com(unsigned char *script,int *pos)
+c_op get_com(unsigned char *scriptbuf,int *pos)
{
int i = 0, j = 0;
- if(script[*pos]>=0x80){
+ if(scriptbuf[*pos]>=0x80){
return C_INT;
}
- while(script[*pos]>=0x40){
- i=script[(*pos)++]<<j;
+ while(scriptbuf[*pos]>=0x40){
+ i=scriptbuf[(*pos)++]<<j;
j+=6;
}
- return (c_op)(i+(script[(*pos)++]<<j));
+ return (c_op)(i+(scriptbuf[(*pos)++]<<j));
}
/*==========================================
* Income figures
*------------------------------------------*/
-int get_num(unsigned char *script,int *pos)
+int get_num(unsigned char *scriptbuf,int *pos)
{
int i,j;
i=0; j=0;
- while(script[*pos]>=0xc0){
- i+=(script[(*pos)++]&0x7f)<<j;
+ while(scriptbuf[*pos]>=0xc0){
+ i+=(scriptbuf[(*pos)++]&0x7f)<<j;
j+=6;
}
- return i+((script[(*pos)++]&0x7f)<<j);
+ return i+((scriptbuf[(*pos)++]&0x7f)<<j);
}
/*==========================================
@@ -3200,7 +3172,7 @@ static void script_check_buildin_argtype(struct script_state* st, int func)
}
if(invalid) {
- ShowDebug("Function: %s\n", get_str(func));
+ ShowDebug("Function: %s\n", script->get_str(func));
script_reportsrc(st);
}
}
@@ -3240,8 +3212,7 @@ int run_func(struct script_state *st)
return 1;
}
- if( script_config.warn_func_mismatch_argtypes )
- {
+ if( script->config.warn_func_mismatch_argtypes ) {
script_check_buildin_argtype(st, func);
}
@@ -3249,7 +3220,7 @@ int run_func(struct script_state *st)
if (!(script->str_data[func].func(st))) //Report error
script_reportsrc(st);
} else {
- ShowError("script:run_func: '%s' (id=%d type=%s) has no C function. please report this!!!\n", get_str(func), func, script_op2name(script->str_data[func].type));
+ ShowError("script:run_func: '%s' (id=%d type=%s) has no C function. please report this!!!\n", script->get_str(func), func, script_op2name(script->str_data[func].type));
script_reportsrc(st);
st->state = END;
}
@@ -3273,7 +3244,7 @@ int run_func(struct script_state *st)
st->state = END;
return 1;
}
- script_free_vars( st->stack->var_function );
+ script->free_vars( st->stack->var_function );
ri = st->stack->stack_data[st->stack->defsp-1].u.ri;
nargs = ri->nargs;
@@ -3303,9 +3274,9 @@ void run_script(struct script_code *rootscript,int pos,int rid,int oid) {
// TODO In jAthena, this function can take over the pending script in the player. [FlavioJS]
// It is unclear how that can be triggered, so it needs the be traced/checked in more detail.
// NOTE At the time of this change, this function wasn't capable of taking over the script state because st->scriptroot was never set.
- st = script_alloc_state(rootscript, pos, rid, oid);
+ st = script->alloc_state(rootscript, pos, rid, oid);
- run_script_main(st);
+ script->run_main(st);
}
void script_stop_instances(struct script_code *code) {
@@ -3319,7 +3290,7 @@ void script_stop_instances(struct script_code *code) {
for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) {
if( st->script == code ) {
- script_free_state(st);
+ script->free_state(st);
}
}
@@ -3341,7 +3312,7 @@ int run_script_timer(int tid, unsigned int tick, int id, intptr_t data) {
st->sleep.timer = INVALID_TIMER;
if(st->state != RERUNLINE)
st->sleep.tick = 0;
- run_script_main(st);
+ script->run_main(st);
}
return 0;
}
@@ -3381,7 +3352,7 @@ static void script_detach_state(struct script_state* st, bool dequeue_event)
ShowError("script_detach_state: Found previous script state without attached player (rid=%d, oid=%d, state=%d, bk_npcid=%d)\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
script_reportsrc(st->bk_st);
- script_free_state(st->bk_st);
+ script->free_state(st->bk_st);
st->bk_st = NULL;
}
}
@@ -3389,8 +3360,7 @@ static void script_detach_state(struct script_state* st, bool dequeue_event)
/// Attaches script state to possibly attached character and backups it's previous script, if any.
///
/// @param st Script state to attach.
-static void script_attach_state(struct script_state* st)
-{
+void script_attach_state(struct script_state* st) {
struct map_session_data* sd;
if(st->rid && (sd = iMap->id2sd(st->rid))!=NULL)
@@ -3423,13 +3393,13 @@ static void script_attach_state(struct script_state* st)
*------------------------------------------*/
void run_script_main(struct script_state *st)
{
- int cmdcount = script_config.check_cmdcount;
- int gotocount = script_config.check_gotocount;
+ int cmdcount = script->config.check_cmdcount;
+ int gotocount = script->config.check_gotocount;
TBL_PC *sd;
struct script_stack *stack = st->stack;
struct npc_data *nd;
- script_attach_state(st);
+ script->attach_state(st);
nd = iMap->id2nd(st->oid);
if( nd && nd->bl.m >= 0 )
@@ -3538,7 +3508,7 @@ void run_script_main(struct script_state *st)
sd = iMap->id2sd(st->rid); // Get sd since script might have attached someone while running. [Inkfish]
st->sleep.charid = sd?sd->status.char_id:0;
st->sleep.timer = iTimer->add_timer(iTimer->gettick()+st->sleep.tick,
- run_script_timer, st->sleep.charid, (intptr_t)st->id);
+ script->run_timer, st->sleep.charid, (intptr_t)st->id);
} else if(st->state != END && st->rid){
//Resume later (st is already attached to player).
if(st->bk_st) {
@@ -3549,7 +3519,7 @@ void run_script_main(struct script_state *st)
ShowDebug("Current script:\n");
script_reportsrc(st);
- script_free_state(st->bk_st);
+ script->free_state(st->bk_st);
st->bk_st = NULL;
}
} else {
@@ -3566,25 +3536,22 @@ void run_script_main(struct script_state *st)
if (sd->state.reg_dirty&1)
intif_saveregistry(sd,1);
}
- script_free_state(st);
+ script->free_state(st);
st = NULL;
}
}
-int script_config_read(char *cfgName)
-{
+int script_config_read(char *cfgName) {
int i;
char line[1024],w1[1024],w2[1024];
FILE *fp;
- fp=fopen(cfgName,"r");
- if(fp==NULL){
+ if( !( fp = fopen(cfgName,"r") ) ){
ShowError("File not found: %s\n", cfgName);
return 1;
}
- while(fgets(line, sizeof(line), fp))
- {
+ while(fgets(line, sizeof(line), fp)) {
if(line[0] == '/' && line[1] == '/')
continue;
i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
@@ -3592,25 +3559,25 @@ int script_config_read(char *cfgName)
continue;
if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
- script_config.warn_func_mismatch_paramnum = config_switch(w2);
+ script->config.warn_func_mismatch_paramnum = config_switch(w2);
}
else if(strcmpi(w1,"check_cmdcount")==0) {
- script_config.check_cmdcount = config_switch(w2);
+ script->config.check_cmdcount = config_switch(w2);
}
else if(strcmpi(w1,"check_gotocount")==0) {
- script_config.check_gotocount = config_switch(w2);
+ script->config.check_gotocount = config_switch(w2);
}
else if(strcmpi(w1,"input_min_value")==0) {
- script_config.input_min_value = config_switch(w2);
+ script->config.input_min_value = config_switch(w2);
}
else if(strcmpi(w1,"input_max_value")==0) {
- script_config.input_max_value = config_switch(w2);
+ script->config.input_max_value = config_switch(w2);
}
else if(strcmpi(w1,"warn_func_mismatch_argtypes")==0) {
- script_config.warn_func_mismatch_argtypes = config_switch(w2);
+ script->config.warn_func_mismatch_argtypes = config_switch(w2);
}
else if(strcmpi(w1,"import")==0){
- script_config_read(w2);
+ script->config_read(w2);
}
else {
ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
@@ -3628,29 +3595,27 @@ static int db_script_free_code_sub(DBKey key, DBData *data, va_list ap)
{
struct script_code *code = DB->data2ptr(data);
if (code)
- script_free_code(code);
+ script->free_code(code);
return 0;
}
void script_run_autobonus(const char *autobonus, int id, int pos)
{
- struct script_code *script = (struct script_code *)strdb_get(autobonus_db, autobonus);
+ struct script_code *scriptroot = (struct script_code *)strdb_get(script->autobonus_db, autobonus);
- if( script )
- {
+ if( scriptroot ) {
iStatus->current_equip_item_index = pos;
- run_script(script,0,id,0);
+ script->run(scriptroot,0,id,0);
}
}
void script_add_autobonus(const char *autobonus)
{
- if( strdb_get(autobonus_db, autobonus) == NULL )
- {
- struct script_code *script = parse_script(autobonus, "autobonus", 0, 0);
+ if( strdb_get(script->autobonus_db, autobonus) == NULL ) {
+ struct script_code *scriptroot = script->parse(autobonus, "autobonus", 0, 0);
- if( script )
- strdb_put(autobonus_db, autobonus, script);
+ if( scriptroot )
+ strdb_put(script->autobonus_db, autobonus, scriptroot);
}
}
@@ -3667,7 +3632,7 @@ void script_cleararray_pc(struct map_session_data* sd, const char* varname, void
return;
}
- key = add_str(varname);
+ key = script->add_str(varname);
if( is_string_variable(varname) )
{
@@ -3704,7 +3669,7 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8
return;
}
- key = ( refcache && refcache[0] ) ? refcache[0] : add_str(varname);
+ key = ( refcache && refcache[0] ) ? refcache[0] : script->add_str(varname);
if( is_string_variable(varname) )
{
@@ -3716,7 +3681,7 @@ void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8
}
if( refcache )
- {// save to avoid repeated add_str calls
+ {// save to avoid repeated script->add_str calls
refcache[0] = key;
}
}
@@ -3745,8 +3710,8 @@ void do_final_script(void) {
fprintf(fp,"num : hash : data_name\n");
fprintf(fp,"---------------------------------------------------------------\n");
for(i=LABEL_START; i<script->str_num; i++) {
- unsigned int h = calc_hash(get_str(i));
- fprintf(fp,"%04d : %4u : %s\n",i,h, get_str(i));
+ unsigned int h = calc_hash(script->get_str(i));
+ fprintf(fp,"%04d : %4u : %s\n",i,h, script->get_str(i));
++count[h];
}
fprintf(fp,"--------------------\n\n");
@@ -3786,15 +3751,15 @@ void do_final_script(void) {
iter = db_iterator(script->st_db);
for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) {
- script_free_state(st);
+ script->free_state(st);
}
dbi_destroy(iter);
mapreg_final();
- userfunc_db->destroy(userfunc_db, db_script_free_code_sub);
- autobonus_db->destroy(autobonus_db, db_script_free_code_sub);
+ script->userfunc_db->destroy(script->userfunc_db, db_script_free_code_sub);
+ script->autobonus_db->destroy(script->autobonus_db, db_script_free_code_sub);
if (script->str_data)
aFree(script->str_data);
@@ -3849,8 +3814,8 @@ void do_final_script(void) {
*------------------------------------------*/
void do_init_script(void) {
script->st_db = idb_alloc(DB_OPT_BASE);
- userfunc_db = strdb_alloc(DB_OPT_DUP_KEY,0);
- autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0);
+ script->userfunc_db = strdb_alloc(DB_OPT_DUP_KEY,0);
+ script->autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0);
script->st_ers = ers_new(sizeof(struct script_state), "script.c::st_ers", ERS_OPT_NONE);
script->stack_ers = ers_new(sizeof(struct script_stack), "script.c::script_stack", ERS_OPT_NONE);
@@ -3871,12 +3836,12 @@ int script_reload() {
iter = db_iterator(script->st_db);
for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) {
- script_free_state(st);
+ script->free_state(st);
}
dbi_destroy(iter);
- userfunc_db->clear(userfunc_db, db_script_free_code_sub);
+ script->userfunc_db->clear(script->userfunc_db, db_script_free_code_sub);
script->label_count = 0;
for( i = 0; i < atcommand->binding_count; i++ ) {
@@ -4150,7 +4115,7 @@ BUILDIN(menu)
st->state = END;
return false;
}
- pc->setreg(sd, add_str("@menu"), menu);
+ pc->setreg(sd, script->add_str("@menu"), menu);
st->pos = script_getnum(st, i + 1);
st->state = GOTO;
}
@@ -4227,7 +4192,7 @@ BUILDIN(select)
if( sd->npc_menu <= 0 )
break;// entry found
}
- pc->setreg(sd, add_str("@menu"), menu);
+ pc->setreg(sd, script->add_str("@menu"), menu);
script_pushint(st, menu);
st->state = RUN;
}
@@ -4298,7 +4263,7 @@ BUILDIN(prompt)
else if( sd->npc_menu == 0xff )
{// Cancel was pressed
sd->state.menu_or_input = 0;
- pc->setreg(sd, add_str("@menu"), 0xff);
+ pc->setreg(sd, script->add_str("@menu"), 0xff);
script_pushint(st, 0xff);
st->state = RUN;
}
@@ -4314,7 +4279,7 @@ BUILDIN(prompt)
if( sd->npc_menu <= 0 )
break;// entry found
}
- pc->setreg(sd, add_str("@menu"), menu);
+ pc->setreg(sd, script->add_str("@menu"), menu);
script_pushint(st, menu);
st->state = RUN;
}
@@ -4354,7 +4319,7 @@ BUILDIN(callfunc)
const char* str = script_getstr(st,2);
DBMap **ref = NULL;
- scr = (struct script_code*)strdb_get(userfunc_db, str);
+ scr = (struct script_code*)strdb_get(script->userfunc_db, str);
if( !scr )
{
ShowError("script:callfunc: function not found! [%s]\n", str);
@@ -4891,9 +4856,9 @@ BUILDIN(itemheal)
hp=script_getnum(st,2);
sp=script_getnum(st,3);
- if(potion_flag==1) {
- potion_hp = hp;
- potion_sp = sp;
+ if(script->potion_flag==1) {
+ script->potion_hp = hp;
+ script->potion_sp = sp;
return true;
}
@@ -4913,9 +4878,9 @@ BUILDIN(percentheal)
hp=script_getnum(st,2);
sp=script_getnum(st,3);
- if(potion_flag==1) {
- potion_per_hp = hp;
- potion_per_sp = sp;
+ if(script->potion_flag==1) {
+ script->potion_per_hp = hp;
+ script->potion_per_sp = sp;
return true;
}
@@ -4994,8 +4959,8 @@ BUILDIN(input)
}
uid = reference_getuid(data);
name = reference_getname(data);
- min = (script_hasdata(st,3) ? script_getnum(st,3) : script_config.input_min_value);
- max = (script_hasdata(st,4) ? script_getnum(st,4) : script_config.input_max_value);
+ min = (script_hasdata(st,3) ? script_getnum(st,3) : script->config.input_min_value);
+ max = (script_hasdata(st,4) ? script_getnum(st,4) : script->config.input_max_value);
#ifdef SECURE_NPCTIMEOUT
sd->npc_idle_type = NPCT_WAIT;
@@ -6721,19 +6686,19 @@ BUILDIN(getpartymember)
if(p->party.member[i].account_id){
switch (type) {
case 2:
- mapreg_setreg(reference_uid(add_str("$@partymemberaid"), j),p->party.member[i].account_id);
+ mapreg_setreg(reference_uid(script->add_str("$@partymemberaid"), j),p->party.member[i].account_id);
break;
case 1:
- mapreg_setreg(reference_uid(add_str("$@partymembercid"), j),p->party.member[i].char_id);
+ mapreg_setreg(reference_uid(script->add_str("$@partymembercid"), j),p->party.member[i].char_id);
break;
default:
- mapreg_setregstr(reference_uid(add_str("$@partymembername$"), j),p->party.member[i].name);
+ mapreg_setregstr(reference_uid(script->add_str("$@partymembername$"), j),p->party.member[i].name);
}
j++;
}
}
}
- mapreg_setreg(add_str("$@partymembercount"),j);
+ mapreg_setreg(script->add_str("$@partymembercount"),j);
return true;
}
@@ -8528,13 +8493,13 @@ BUILDIN(getmobdrops)
if( itemdb->exists(mob->dropitem[i].nameid) == NULL )
continue;
- mapreg_setreg(reference_uid(add_str("$@MobDrop_item"), j), mob->dropitem[i].nameid);
- mapreg_setreg(reference_uid(add_str("$@MobDrop_rate"), j), mob->dropitem[i].p);
+ mapreg_setreg(reference_uid(script->add_str("$@MobDrop_item"), j), mob->dropitem[i].nameid);
+ mapreg_setreg(reference_uid(script->add_str("$@MobDrop_rate"), j), mob->dropitem[i].p);
j++;
}
- mapreg_setreg(add_str("$@MobDrop_count"), j);
+ mapreg_setreg(script->add_str("$@MobDrop_count"), j);
script_pushint(st, 1);
return true;
@@ -9217,7 +9182,7 @@ BUILDIN(itemeffect) {
return false;
}
- run_script( item_data->script, 0, sd->bl.id, nd->bl.id );
+ script->run( item_data->script, 0, sd->bl.id, nd->bl.id );
return true;
}
@@ -9513,9 +9478,9 @@ BUILDIN(sc_start)
tick = skill->get_time(iStatus->sc2skill(type), val1);
}
- if( potion_flag == 1 && potion_target )
+ if( script->potion_flag == 1 && script->potion_target )
{ //skill.c set the flags before running the script, this must be a potion-pitched effect.
- bl = iMap->id2bl(potion_target);
+ bl = iMap->id2bl(script->potion_target);
tick /= 2;// Thrown potions only last half.
val4 = 1;// Mark that this was a thrown sc_effect
}
@@ -9552,9 +9517,9 @@ BUILDIN(sc_start2)
tick = skill->get_time(iStatus->sc2skill(type), val1);
}
- if( potion_flag == 1 && potion_target )
+ if( script->potion_flag == 1 && script->potion_target )
{ //skill.c set the flags before running the script, this must be a potion-pitched effect.
- bl = iMap->id2bl(potion_target);
+ bl = iMap->id2bl(script->potion_target);
tick /= 2;// Thrown potions only last half.
val4 = 1;// Mark that this was a thrown sc_effect
}
@@ -9594,9 +9559,9 @@ BUILDIN(sc_start4)
tick = skill->get_time(iStatus->sc2skill(type), val1);
}
- if( potion_flag == 1 && potion_target )
+ if( script->potion_flag == 1 && script->potion_target )
{ //skill.c set the flags before running the script, this must be a potion-pitched effect.
- bl = iMap->id2bl(potion_target);
+ bl = iMap->id2bl(script->potion_target);
tick /= 2;// Thrown potions only last half.
}
@@ -9620,8 +9585,8 @@ BUILDIN(sc_end)
else
bl = iMap->id2bl(st->rid);
- if (potion_flag == 1 && potion_target) //##TODO how does this work [FlavioJS]
- bl = iMap->id2bl(potion_target);
+ if (script->potion_flag == 1 && script->potion_target) //##TODO how does this work [FlavioJS]
+ bl = iMap->id2bl(script->potion_target);
if (!bl)
return true;
@@ -10231,7 +10196,7 @@ BUILDIN(warpwaitingpc)
pc->payzeny(sd, cd->zeny, LOG_TYPE_NPC, NULL);
}
- mapreg_setreg(reference_uid(add_str("$@warpwaitingpc"), i), sd->bl.id);
+ mapreg_setreg(reference_uid(script->add_str("$@warpwaitingpc"), i), sd->bl.id);
if( strcmp(map_name,"Random") == 0 )
pc->randomwarp(sd,CLR_TELEPORT);
@@ -10240,7 +10205,7 @@ BUILDIN(warpwaitingpc)
else
pc->setpos(sd, mapindex_name2id(map_name), x, y, CLR_OUTSIGHT);
}
- mapreg_setreg(add_str("$@warpwaitingpcnum"), i);
+ mapreg_setreg(script->add_str("$@warpwaitingpcnum"), i);
return true;
}
@@ -10269,7 +10234,7 @@ BUILDIN(attachrid)
script_detach_rid(st);
st->rid = rid;
- script_attach_state(st);
+ script->attach_state(st);
script_pushint(st,1);
} else
script_pushint(st,0);
@@ -11759,22 +11724,22 @@ BUILDIN(getinventorylist)
if(!sd) return true;
for(i=0;i<MAX_INVENTORY;i++){
if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0){
- pc->setreg(sd,reference_uid(add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid);
- pc->setreg(sd,reference_uid(add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount);
- pc->setreg(sd,reference_uid(add_str("@inventorylist_equip"), j),sd->status.inventory[i].equip);
- pc->setreg(sd,reference_uid(add_str("@inventorylist_refine"), j),sd->status.inventory[i].refine);
- pc->setreg(sd,reference_uid(add_str("@inventorylist_identify"), j),sd->status.inventory[i].identify);
- pc->setreg(sd,reference_uid(add_str("@inventorylist_attribute"), j),sd->status.inventory[i].attribute);
+ pc->setreg(sd,reference_uid(script->add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid);
+ pc->setreg(sd,reference_uid(script->add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount);
+ pc->setreg(sd,reference_uid(script->add_str("@inventorylist_equip"), j),sd->status.inventory[i].equip);
+ pc->setreg(sd,reference_uid(script->add_str("@inventorylist_refine"), j),sd->status.inventory[i].refine);
+ pc->setreg(sd,reference_uid(script->add_str("@inventorylist_identify"), j),sd->status.inventory[i].identify);
+ pc->setreg(sd,reference_uid(script->add_str("@inventorylist_attribute"), j),sd->status.inventory[i].attribute);
for (k = 0; k < MAX_SLOTS; k++)
{
sprintf(card_var, "@inventorylist_card%d",k+1);
- pc->setreg(sd,reference_uid(add_str(card_var), j),sd->status.inventory[i].card[k]);
+ pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.inventory[i].card[k]);
}
- pc->setreg(sd,reference_uid(add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
+ pc->setreg(sd,reference_uid(script->add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time);
j++;
}
}
- pc->setreg(sd,add_str("@inventorylist_count"),j);
+ pc->setreg(sd,script->add_str("@inventorylist_count"),j);
return true;
}
@@ -11785,13 +11750,13 @@ BUILDIN(getskilllist)
if(!sd) return true;
for(i=0;i<MAX_SKILL;i++){
if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0){
- pc->setreg(sd,reference_uid(add_str("@skilllist_id"), j),sd->status.skill[i].id);
- pc->setreg(sd,reference_uid(add_str("@skilllist_lv"), j),sd->status.skill[i].lv);
- pc->setreg(sd,reference_uid(add_str("@skilllist_flag"), j),sd->status.skill[i].flag);
+ pc->setreg(sd,reference_uid(script->add_str("@skilllist_id"), j),sd->status.skill[i].id);
+ pc->setreg(sd,reference_uid(script->add_str("@skilllist_lv"), j),sd->status.skill[i].lv);
+ pc->setreg(sd,reference_uid(script->add_str("@skilllist_flag"), j),sd->status.skill[i].flag);
j++;
}
}
- pc->setreg(sd,add_str("@skilllist_count"),j);
+ pc->setreg(sd,script->add_str("@skilllist_count"),j);
return true;
}
@@ -12849,7 +12814,7 @@ BUILDIN(getmapxy)
//Set MapName$
num=st->stack->stack_data[st->start+2].u.num;
- name=get_str(num&0x00ffffff);
+ name=script->get_str(num&0x00ffffff);
prefix=*name;
if(not_server_variable(prefix))
@@ -12860,7 +12825,7 @@ BUILDIN(getmapxy)
//Set MapX
num=st->stack->stack_data[st->start+3].u.num;
- name=get_str(num&0x00ffffff);
+ name=script->get_str(num&0x00ffffff);
prefix=*name;
if(not_server_variable(prefix))
@@ -12871,7 +12836,7 @@ BUILDIN(getmapxy)
//Set MapY
num=st->stack->stack_data[st->start+4].u.num;
- name=get_str(num&0x00ffffff);
+ name=script->get_str(num&0x00ffffff);
prefix=*name;
if(not_server_variable(prefix))
@@ -14193,9 +14158,9 @@ BUILDIN(setd)
}
if( is_string_variable(varname) ) {
- setd_sub(st, sd, varname, elem, (void *)script_getstr(st, 3), NULL);
+ script->setd_sub(st, sd, varname, elem, (void *)script_getstr(st, 3), NULL);
} else {
- setd_sub(st, sd, varname, elem, (void *)__64BPTRSIZE(script_getnum(st, 3)), NULL);
+ script->setd_sub(st, sd, varname, elem, (void *)__64BPTRSIZE(script_getnum(st, 3)), NULL);
}
return true;
@@ -14272,9 +14237,9 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle)
data = script_getdata(st, j+3);
name = reference_getname(data);
if( is_string_variable(name) )
- setd_sub(st, sd, name, i, (void *)(str?str:""), reference_getref(data));
+ script->setd_sub(st, sd, name, i, (void *)(str?str:""), reference_getref(data));
else
- setd_sub(st, sd, name, i, (void *)__64BPTRSIZE((str?atoi(str):0)), reference_getref(data));
+ script->setd_sub(st, sd, name, i, (void *)__64BPTRSIZE((str?atoi(str):0)), reference_getref(data));
}
}
if( i == max_rows && max_rows < SQL->NumRows(handle) ) {
@@ -14328,7 +14293,7 @@ BUILDIN(getd)
elem = 0;
// Push the 'pointer' so it's more flexible [Lance]
- script->push_val(st->stack, C_NAME, reference_uid(add_str(varname), elem),NULL);
+ script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem),NULL);
return true;
}
@@ -14563,9 +14528,9 @@ BUILDIN(setitemscript)
break;
}
if(*dstscript)
- script_free_code(*dstscript);
+ script->free_code(*dstscript);
- *dstscript = new_bonus_script[0] ? parse_script(new_bonus_script, "script_setitemscript", 0, 0) : NULL;
+ *dstscript = new_bonus_script[0] ? script->parse(new_bonus_script, "script_setitemscript", 0, 0) : NULL;
script_pushint(st,1);
return true;
}
@@ -15240,11 +15205,11 @@ BUILDIN(awake) {
tst->rid = 0;
}
- iTimer->delete_timer(tst->sleep.timer, run_script_timer);
+ iTimer->delete_timer(tst->sleep.timer, script->run_timer);
tst->sleep.timer = INVALID_TIMER;
if(tst->state != RERUNLINE)
tst->sleep.tick = 0;
- run_script_main(tst);
+ script->run_main(tst);
}
}
@@ -15731,12 +15696,12 @@ BUILDIN(waitingroom2bg)
for( i = 0; i < n && i < MAX_BG_MEMBERS; i++ )
{
if( (sd = cd->usersd[i]) != NULL && bg_team_join(bg_id, sd) )
- mapreg_setreg(reference_uid(add_str("$@arenamembers"), i), sd->bl.id);
+ mapreg_setreg(reference_uid(script->add_str("$@arenamembers"), i), sd->bl.id);
else
- mapreg_setreg(reference_uid(add_str("$@arenamembers"), i), 0);
+ mapreg_setreg(reference_uid(script->add_str("$@arenamembers"), i), 0);
}
- mapreg_setreg(add_str("$@arenamembersnum"), i);
+ mapreg_setreg(script->add_str("$@arenamembersnum"), i);
script_pushint(st,bg_id);
return true;
}
@@ -16697,7 +16662,7 @@ BUILDIN(getcharip)
BUILDIN(is_function) {
const char* str = script_getstr(st,2);
- if( strdb_exists(userfunc_db, str) )
+ if( strdb_exists(script->userfunc_db, str) )
script_pushint(st,1);
else
script_pushint(st,0);
@@ -17563,7 +17528,7 @@ BUILDIN(bg_match_over) {
#endif
bool script_hp_add(char *name, char *args, bool (*func)(struct script_state *st)) {
- int n = add_str(name), i = 0;
+ int n = script->add_str(name), i = 0;
if( script->str_data[n].type == C_FUNC ) {
script->str_data[n].func = func;
@@ -18101,7 +18066,7 @@ void script_parse_builtin(void) {
ShowWarning("script_parse_builtin: ignoring function with invalid name \"%s\" (must be a word).\n", BUILDIN[i].name);
} else {
int slen = strlen(BUILDIN[i].arg), offset = start + i;
- n = add_str(BUILDIN[i].name);
+ n = script->add_str(BUILDIN[i].name);
if (!strcmp(BUILDIN[i].name, "set")) buildin_set_ref = n;
else if (!strcmp(BUILDIN[i].name, "callsub")) buildin_callsub_ref = n;
@@ -18174,10 +18139,25 @@ void script_defaults(void) {
script->label_count = 0;
script->labels_size = 0;
+ memset(&script->config, 0, sizeof(script->config));
+
+ script->autobonus_db = NULL;
+ script->userfunc_db = NULL;
+
+ script->potion_flag = script->potion_hp = script->potion_per_hp =
+ script->potion_sp = script->potion_per_sp = script->potion_target = 0;
+
script->init = do_init_script;
script->final = do_final_script;
+ script->reload = script_reload;
+ /* parse */
+ script->parse = parse_script;
script->parse_builtin = script_parse_builtin;
+ script->skip_space = script_skip_space;
+ script->error = script_error;
+ script->parse_subexpr = script_parse_subexpr;
+
script->addScript = script_hp_add;
script->conv_num = conv_num;
script->conv_str = conv_str;
@@ -18194,6 +18174,24 @@ void script_defaults(void) {
script->set_constant_force = script_set_constant_force;
script->get_constant = script_get_constant;
script->label_add = script_label_add;
+ script->run = run_script;
+ script->run_main = run_script_main;
+ script->run_timer = run_script_timer;
+ script->set_var = set_var;
+ script->stop_instances = script_stop_instances;
+ script->free_code = script_free_code;
+ script->free_vars = script_free_vars;
+ script->alloc_state = script_alloc_state;
+ script->free_state = script_free_state;
+ script->run_autobonus = script_run_autobonus;
+ script->cleararray_pc = script_cleararray_pc;
+ script->setarray_pc = script_setarray_pc;
+ script->config_read = script_config_read;
+ script->add_str = script_add_str;
+ script->get_str = script_get_str;
+ script->search_str = script_search_str;
+ script->setd_sub = setd_sub;
+ script->attach_state = script_attach_state;
script->queue = script_hqueue_get;
script->queue_add = script_hqueue_add;
@@ -18201,4 +18199,22 @@ void script_defaults(void) {
script->queue_remove = script_hqueue_remove;
script->queue_create = script_hqueue_create;
script->queue_clear = script_hqueue_clear;
+
+ /* script_config base */
+ script->config.warn_func_mismatch_argtypes = 1;
+ script->config.warn_func_mismatch_paramnum = 1;
+ script->config.check_cmdcount = 65535;
+ script->config.check_gotocount = 2048;
+ script->config.input_min_value = 0;
+ script->config.input_max_value = INT_MAX;
+ script->config.die_event_name = "OnPCDieEvent";
+ script->config.kill_pc_event_name = "OnPCKillEvent";
+ script->config.kill_mob_event_name = "OnNPCKillEvent";
+ script->config.login_event_name = "OnPCLoginEvent";
+ script->config.logout_event_name = "OnPCLogoutEvent";
+ script->config.loadmap_event_name = "OnPCLoadMapEvent";
+ script->config.baselvup_event_name = "OnPCBaseLvUpEvent";
+ script->config.joblvup_event_name = "OnPCJobLvUpEvent";
+ script->config.ontouch_name = "OnTouch_";//ontouch_name (runs on first visible char to enter area, picks another char if the first char leaves)
+ script->config.ontouch2_name = "OnTouch";//ontouch2_name (run whenever a char walks into the OnTouch area)
}