diff options
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 568 |
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) } |