diff options
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 449 |
1 files changed, 256 insertions, 193 deletions
diff --git a/src/map/script.c b/src/map/script.c index 312e40696..9fe746c8c 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -2,58 +2,63 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams +#define HERCULES_CORE + +#include "../config/core.h" // RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL +#include "script.h" + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "atcommand.h" +#include "battle.h" +#include "battleground.h" +#include "chat.h" +#include "chrif.h" +#include "clif.h" +#include "elemental.h" +#include "guild.h" +#include "homunculus.h" +#include "instance.h" +#include "intif.h" +#include "itemdb.h" +#include "log.h" +#include "mail.h" +#include "map.h" +#include "mapreg.h" +#include "mercenary.h" +#include "mob.h" +#include "npc.h" +#include "party.h" +#include "path.h" +#include "pc.h" +#include "pet.h" +#include "pet.h" +#include "quest.h" +#include "skill.h" +#include "status.h" +#include "status.h" +#include "storage.h" +#include "unit.h" #include "../common/cbasetypes.h" #include "../common/malloc.h" #include "../common/md5calc.h" +#include "../common/mmo.h" // NEW_CARTS #include "../common/nullpo.h" #include "../common/random.h" #include "../common/showmsg.h" #include "../common/socket.h" // usage: getcharip #include "../common/strlib.h" +#include "../common/sysinfo.h" #include "../common/timer.h" #include "../common/utils.h" -#include "map.h" -#include "path.h" -#include "clif.h" -#include "chrif.h" -#include "itemdb.h" -#include "pc.h" -#include "status.h" -#include "storage.h" -#include "mob.h" -#include "npc.h" -#include "pet.h" -#include "mapreg.h" -#include "homunculus.h" -#include "instance.h" -#include "mercenary.h" -#include "intif.h" -#include "skill.h" -#include "status.h" -#include "chat.h" -#include "battle.h" -#include "battleground.h" -#include "party.h" -#include "guild.h" -#include "atcommand.h" -#include "log.h" -#include "unit.h" -#include "pet.h" -#include "mail.h" -#include "script.h" -#include "quest.h" -#include "elemental.h" -#include "../config/core.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> #ifndef WIN32 #include <sys/time.h> #endif -#include <time.h> static inline int GETVALUE(const unsigned char* buf, int i) { return (int)MakeDWord(MakeWord(buf[i], buf[i+1]), MakeWord(buf[i+2], 0)); @@ -1497,9 +1502,9 @@ const char* parse_syntax(const char* p) script->set_label(l,script->pos,p); } // check duplication of case label [Rayce] - if(linkdb_search(&script->syntax.curly[pos].case_label, (void*)__64BPTRSIZE(v)) != NULL) + if(linkdb_search(&script->syntax.curly[pos].case_label, (void*)h64BPTRSIZE(v)) != NULL) disp_error_message("parse_syntax: dup 'case'",p); - linkdb_insert(&script->syntax.curly[pos].case_label, (void*)__64BPTRSIZE(v), (void*)1); + linkdb_insert(&script->syntax.curly[pos].case_label, (void*)h64BPTRSIZE(v), (void*)1); sprintf(label,"set $@__SW%x_VAL,0;",script->syntax.curly[pos].index); script->syntax.curly[script->syntax.curly_count++].type = TYPE_NULL; @@ -2241,8 +2246,7 @@ void script_warning(const char* src, const char* file, int start_line, const cha /*========================================== * Analysis of the script *------------------------------------------*/ -struct script_code* parse_script(const char *src,const char *file,int line,int options) -{ +struct script_code* parse_script(const char *src,const char *file,int line,int options, int *retval) { const char *p,*tmpp; int i; struct script_code* code = NULL; @@ -2288,6 +2292,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o script->parser_current_file = NULL; script->parser_current_line = 0; #endif // ENABLE_CASE_CHECK + if (retval) *retval = EXIT_FAILURE; return NULL; } @@ -2314,8 +2319,10 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o } else {// requires brackets around the script - if( *p != '{' ) + if( *p != '{' ) { disp_error_message("not found '{'",p); + if (retval) *retval = EXIT_FAILURE; + } p = script->skip_space(p+1); if( *p == '}' && !(options&SCRIPT_RETURN_EMPTY_SCRIPT) ) {// empty script and can return NULL @@ -2390,13 +2397,14 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o else if( script->str_data[i].type == C_USERFUNC ) {// 'function name;' without follow-up code ShowError("parse_script: function '%s' declared but not defined.\n", script->str_buf+script->str_data[i].str); + if (retval) *retval = EXIT_FAILURE; unresolved_names = true; } } - if( unresolved_names ) - { + if( unresolved_names ) { disp_error_message("parse_script: unresolved function references", p); + if (retval) *retval = EXIT_FAILURE; } #ifdef SCRIPT_DEBUG_DISP @@ -2619,7 +2627,7 @@ void* get_val2(struct script_state* st, int64 uid, struct reg_db *ref) { script->push_val(st->stack, C_NAME, uid, ref); data = script_getdatatop(st, -1); script->get_val(st, data); - return (data->type == C_INT ? (void*)__64BPTRSIZE((int32)data->u.num) : (void*)__64BPTRSIZE(data->u.str)); // u.num is int32 because it comes from script->get_val + return (data->type == C_INT ? (void*)h64BPTRSIZE((int32)data->u.num) : (void*)h64BPTRSIZE(data->u.str)); // u.num is int32 because it comes from script->get_val } /** * Because, currently, array members with key 0 are indifferenciable from normal variables, we should ensure its actually in @@ -2640,7 +2648,7 @@ void script_array_ensure_zero(struct script_state *st, struct map_session_data * insert = true; script_removetop(st, -1, 0); } else { - int32 num = (int32)__64BPTRSIZE(script->get_val2(st, uid, ref)); + int32 num = (int32)h64BPTRSIZE(script->get_val2(st, uid, ref)); if( num ) insert = true; script_removetop(st, -1, 0); @@ -2757,7 +2765,7 @@ void script_array_add_member(struct script_array *sa, unsigned int idx) { } /** * Obtains the source of the array database for this type and scenario - * Initializes such database when not yet initialised. + * Initializes such database when not yet initialized. **/ struct reg_db *script_array_src(struct script_state *st, struct map_session_data *sd, const char *name, struct reg_db *ref) { struct reg_db *src = NULL; @@ -2907,14 +2915,20 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co return pc_setglobalreg_str(sd, num, str); } } else {// integer variable - int val = (int)__64BPTRSIZE(value); + // FIXME: This isn't safe, in 32bits systems we're converting a 64bit pointer + // to a 32bit int, this will lead to overflows! [Panikon] + int val = (int)h64BPTRSIZE(value); if(script->str_data[script_getvarid(num)].type == C_PARAM) { if( pc->setparam(sd, script->str_data[script_getvarid(num)].val, val) == 0 ) { if( st != NULL ) { ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val); script->reportsrc(st); - st->state = END; + // Instead of just stop the script execution we let the character close + // the window if it was open. + st->state = (sd->state.dialog) ? CLOSE : END; + if( st->state == CLOSE ) + clif->scriptclose(sd, st->oid); } return 0; } @@ -3216,6 +3230,8 @@ void script_free_vars(struct DBMap* var_storage) { void script_free_code(struct script_code* code) { + nullpo_retv(code); + if( code->instances ) script->stop_instances(code); else { @@ -4200,7 +4216,7 @@ void script_run_autobonus(const char *autobonus, int id, int pos) void script_add_autobonus(const char *autobonus) { if( strdb_get(script->autobonus_db, autobonus) == NULL ) { - struct script_code *scriptroot = script->parse(autobonus, "autobonus", 0, 0); + struct script_code *scriptroot = script->parse(autobonus, "autobonus", 0, 0, NULL); if( scriptroot ) strdb_put(script->autobonus_db, autobonus, scriptroot); @@ -4499,6 +4515,8 @@ int script_reload(void) { itemdb->name_constants(); + sysinfo->vcsrevision_reload(); + return 0; } /* returns name of current function being run, from within the stack [Ind/Hercules] */ @@ -5647,7 +5665,7 @@ BUILDIN(input) else { int amount = sd->npc_amount; - script->set_reg(st, sd, uid, name, (void*)__64BPTRSIZE(cap_value(amount,min,max)), script_getref(st,2)); + script->set_reg(st, sd, uid, name, (void*)h64BPTRSIZE(cap_value(amount,min,max)), script_getref(st,2)); script_pushint(st, (amount > max ? 1 : amount < min ? -1 : 0)); } st->state = RUN; @@ -5735,7 +5753,7 @@ BUILDIN(setr) { if( is_string_variable(name) ) script->set_reg(st,sd,num,name,(void*)script_getstr(st,3),script_getref(st,2)); else - script->set_reg(st,sd,num,name,(void*)__64BPTRSIZE(script_getnum(st,3)),script_getref(st,2)); + script->set_reg(st,sd,num,name,(void*)h64BPTRSIZE(script_getnum(st,3)),script_getref(st,2)); return true; } @@ -5790,7 +5808,7 @@ BUILDIN(setarray) else {// int array for( i = 3; start < end; ++start, ++i ) - script->set_reg(st, sd, reference_uid(id, start), name, (void*)__64BPTRSIZE(script_getnum(st,i)), reference_getref(data)); + script->set_reg(st, sd, reference_uid(id, start), name, (void*)h64BPTRSIZE(script_getnum(st,i)), reference_getref(data)); } return true; } @@ -5832,7 +5850,7 @@ BUILDIN(cleararray) if( is_string_variable(name) ) v = (void*)script_getstr(st, 3); else - v = (void*)__64BPTRSIZE(script_getnum(st, 3)); + v = (void*)h64BPTRSIZE(script_getnum(st, 3)); end = start + script_getnum(st, 4); if( end > SCRIPT_MAX_ARRAYSIZE ) @@ -6190,10 +6208,8 @@ BUILDIN(countitem) { struct item_data* id = NULL; TBL_PC* sd = script->rid2sd(st); - if (!sd) { - script_pushint(st,0); + if( !sd ) return true; - } if( script_isstringtype(st, 2) ) { // item name @@ -6230,10 +6246,8 @@ BUILDIN(countitem2) { struct item_data* id = NULL; TBL_PC* sd = script->rid2sd(st); - if (!sd) { - script_pushint(st,0); + if( !sd ) return true; - } if( script_isstringtype(st, 2) ) { // item name @@ -6377,7 +6391,9 @@ BUILDIN(checkweight2) int nb_it, nb_nb; //array size TBL_PC *sd = script->rid2sd(st); - nullpo_retr(false,sd); + + if( sd == NULL ) + return false; data_it = script_getdata(st, 2); data_nb = script_getdata(st, 3); @@ -6409,9 +6425,9 @@ BUILDIN(checkweight2) slots = pc->inventoryblank(sd); for(i=0; i<nb_it; i++) { - nameid = (int32)__64BPTRSIZE(script->get_val2(st,reference_uid(id_it,idx_it+i),reference_getref(data_it))); + nameid = (int32)h64BPTRSIZE(script->get_val2(st,reference_uid(id_it,idx_it+i),reference_getref(data_it))); script_removetop(st, -1, 0); - amount = (int32)__64BPTRSIZE(script->get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb))); + amount = (int32)h64BPTRSIZE(script->get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb))); script_removetop(st, -1, 0); if(fail) continue; //cpntonie to depop rest @@ -6711,11 +6727,8 @@ BUILDIN(getnameditem) { TBL_PC *sd, *tsd; sd = script->rid2sd(st); - if (sd == NULL) { - //Player not attached! - script_pushint(st,0); + if (sd == NULL) // Player not attached! return true; - } if( script_isstringtype(st, 2) ) { const char *name = script_getstr(st, 2); @@ -7410,10 +7423,9 @@ BUILDIN(strcharinfo) struct party_data* p; sd=script->rid2sd(st); - if (!sd) { //Avoid crashing.... - script_pushconststr(st,""); + if (!sd) //Avoid crashing.... return true; - } + num=script_getnum(st,2); switch(num) { case 0: @@ -7964,6 +7976,9 @@ BUILDIN(delequip) if(i >= 0) { pc->unequipitem(sd,i,3); //recalculate bonus pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); + script_pushint(st,1); + } else { + script_pushint(st,0); } return true; @@ -8263,20 +8278,36 @@ BUILDIN(addtoskill) { /// guildskill <skill id>,<amount>; /// guildskill "<skill name>",<amount>; BUILDIN(guildskill) { - int id; + int skill_id, id, max_points; int level; + TBL_PC* sd; - int i; + struct guild *gd; + struct guild_skill gd_skill; sd = script->rid2sd(st); if( sd == NULL ) - return true;// no player attached, report source + return false; // no player attached, report source - id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + if( (gd = sd->guild) == NULL ) + return true; + + skill_id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); level = script_getnum(st,3); - for( i=0; i < level; i++ ) - guild->skillup(sd, id); + id = skill_id - GD_SKILLBASE; + max_points = guild->skill_get_max(skill_id); + + if( (gd->skill[id].lv + level) > max_points ) + level = max_points - gd->skill[id].lv; + + if( level <= 0 ) + return true; + + memcpy(&gd_skill, &(gd->skill[id]), sizeof(gd->skill[id])); + gd_skill.lv += level; + + intif->guild_change_basicinfo( gd->guild_id, GBI_SKILLLV, &(gd_skill), sizeof(gd_skill) ); return true; } @@ -8935,7 +8966,7 @@ BUILDIN(getexp) base = (int) cap_value(base * bonus, 0, INT_MAX); job = (int) cap_value(job * bonus, 0, INT_MAX); - pc->gainexp(sd, NULL, base, job, true); + pc->gainexp(sd, &sd->bl, base, job, true); return true; } @@ -9722,8 +9753,13 @@ BUILDIN(itemeffect) { TBL_PC *sd; struct item_data *item_data; - nullpo_retr( false, ( sd = script->rid2sd( st ) ) ); - nullpo_retr( false, ( nd = (TBL_NPC *)map->id2bl( sd->npc_id ) ) ); + sd = script->rid2sd(st); + if( sd == NULL ) + return false; + + nd = (TBL_NPC *)map->id2bl(sd->npc_id); + if( nd == NULL ) + return false; if( script_isstringtype(st, 2) ) { const char *name = script_getstr(st, 2); @@ -10404,10 +10440,8 @@ BUILDIN(eaclass) else { TBL_PC *sd; sd=script->rid2sd(st); - if (!sd) { - script_pushint(st,-1); + if( !sd ) return true; - } class_ = sd->status.class_; } script_pushint(st,pc->jobid2mapid(class_)); @@ -10478,6 +10512,8 @@ BUILDIN(resetstatus) { TBL_PC *sd; sd=script->rid2sd(st); + if( sd == NULL ) + return false; pc->resetstate(sd); return true; } @@ -10489,6 +10525,8 @@ BUILDIN(resetskill) { TBL_PC *sd; sd=script->rid2sd(st); + if( sd == NULL ) + return false; pc->resetskill(sd,1); return true; } @@ -10500,6 +10538,8 @@ BUILDIN(skillpointcount) { TBL_PC *sd; sd=script->rid2sd(st); + if( sd == NULL ) + return false; script_pushint(st,sd->status.skill_point + pc->resetskill(sd,2)); return true; } @@ -10550,6 +10590,9 @@ BUILDIN(changesex) TBL_PC *sd = NULL; sd = script->rid2sd(st); + if( sd == NULL ) + return false; + pc->resetskill(sd,4); // to avoid any problem with equipment and invalid sex, equipment is unequiped. for( i=0; i<EQI_MAX; i++ ) @@ -11017,7 +11060,7 @@ BUILDIN(setmapflag) { char empty[1] = "\0"; char params[MAP_ZONE_MAPFLAG_LENGTH]; memcpy(params, val2, MAP_ZONE_MAPFLAG_LENGTH); - npc->parse_mapflag(map->list[m].name, empty, zone, params, empty, empty, empty); + npc->parse_mapflag(map->list[m].name, empty, zone, params, empty, empty, empty, NULL); } break; case MF_NOCOMMAND: map->list[m].nocommand = (val <= 0) ? 100 : val; break; @@ -11501,6 +11544,10 @@ BUILDIN(getequipcardcnt) num=script_getnum(st,2); sd=script->rid2sd(st); + + if( sd == NULL ) + return false; + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); @@ -11533,6 +11580,9 @@ BUILDIN(successremovecards) { TBL_PC* sd = script->rid2sd(st); int num = script_getnum(st,2); + if( sd == NULL ) + return false; + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); @@ -11600,6 +11650,9 @@ BUILDIN(failedremovecards) { int num = script_getnum(st,2); int typefail = script_getnum(st,3); + if( sd == NULL ) + return false; + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); @@ -11746,12 +11799,11 @@ BUILDIN(mobcount) { if( strcmp(mapname, "this") == 0 ) { struct map_session_data *sd = script->rid2sd(st); - if( sd ) - m = sd->bl.m; - else { - script_pushint(st,-1); - return true; - } + + if( sd == NULL ) + return false; + + m = sd->bl.m; } else if( (m = map->mapname2mapid(mapname)) < 0 ) { script_pushint(st,-1); return true; @@ -11783,10 +11835,10 @@ BUILDIN(wedding_effect) { TBL_PC *sd=script->rid2sd(st); struct block_list *bl; - if(sd==NULL) { - bl=map->id2bl(st->oid); - } else - bl=&sd->bl; + if( sd == NULL ) + return false; //bl=map->id2bl(st->oid); + + bl=&sd->bl; clif->wedding_effect(bl); return true; } @@ -11816,10 +11868,8 @@ BUILDIN(ispartneron) { BUILDIN(getpartnerid) { TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; script_pushint(st,sd->status.partner_id); return true; @@ -11827,10 +11877,8 @@ BUILDIN(getpartnerid) { BUILDIN(getchildid) { TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; script_pushint(st,sd->status.child); return true; @@ -11838,10 +11886,8 @@ BUILDIN(getchildid) { BUILDIN(getmotherid) { TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; script_pushint(st,sd->status.mother); return true; @@ -11849,10 +11895,8 @@ BUILDIN(getmotherid) { BUILDIN(getfatherid) { TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; script_pushint(st,sd->status.father); return true; @@ -12177,6 +12221,10 @@ BUILDIN(getequipcardid) num=script_getnum(st,2); slot=script_getnum(st,3); sd=script->rid2sd(st); + + if( sd == NULL ) + return false; + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0 && slot>=0 && slot<4) @@ -12364,18 +12412,18 @@ BUILDIN(undisguise) } /*========================================== - * Transform a bl to another _class, + * Transform a bl to another class, * @type unused *------------------------------------------*/ BUILDIN(classchange) { - int _class,type; + int class_,type; struct block_list *bl=map->id2bl(st->oid); if(bl==NULL) return true; - _class=script_getnum(st,2); + class_=script_getnum(st,2); type=script_getnum(st,3); - clif->class_change(bl,_class,type); + clif->class_change(bl,class_,type); return true; } @@ -12722,6 +12770,9 @@ BUILDIN(skilleffect) { uint16 skill_lv=script_getnum(st,3); sd=script->rid2sd(st); + if( sd == NULL ) + return false; + /* ensure we're standing because the following packet causes the client to virtually set the char to stand, * which leaves the server thinking it still is sitting. */ if( pc_issit(sd) ) { @@ -12785,12 +12836,14 @@ BUILDIN(specialeffect) { } BUILDIN(specialeffect2) { - TBL_PC *sd=script->rid2sd(st); + TBL_PC *sd; int type = script_getnum(st,2); enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA; if( script_hasdata(st,4) ) sd = map->nick2sd(script_getstr(st,4)); + else + sd = script->rid2sd(st); if (sd) clif->specialeffect(&sd->bl, type, target); @@ -12836,6 +12889,8 @@ BUILDIN(atcommand) { if (st->rid) { sd = script->rid2sd(st); + if( sd == NULL ) + return false; fd = sd->fd; } else { //Use a dummy character. sd = dummy_sd = pc->get_dummy_sd(); @@ -12977,10 +13032,8 @@ BUILDIN(getmercinfo) { return false; } } else { - if( ( sd = script->rid2sd(st) ) == NULL ) { - script_pushnil(st); + if( ( sd = script->rid2sd(st) ) == NULL ) return true; - } } md = ( sd->status.mer_id && sd->md ) ? sd->md : NULL; @@ -13016,25 +13069,27 @@ BUILDIN(getmercinfo) { *------------------------------------------*/ BUILDIN(checkequipedcard) { + int n,i,c=0; TBL_PC *sd=script->rid2sd(st); - if(sd) { - int n,i,c=0; - c=script_getnum(st,2); + if( sd == NULL ) + return false; - for(i=0;i<MAX_INVENTORY;i++) { - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]) { - if (itemdb_isspecial(sd->status.inventory[i].card[0])) - continue; - for(n=0;n<sd->inventory_data[i]->slot;n++) { - if(sd->status.inventory[i].card[n]==c) { - script_pushint(st,1); - return true; - } + c = script_getnum(st,2); + + for( i=0; i<MAX_INVENTORY; i++) { + if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]) { + if (itemdb_isspecial(sd->status.inventory[i].card[0])) + continue; + for(n=0;n<sd->inventory_data[i]->slot;n++) { + if(sd->status.inventory[i].card[n]==c) { + script_pushint(st,1); + return true; } } } } + script_pushint(st,0); return true; } @@ -13174,6 +13229,8 @@ BUILDIN(getlook) int type,val; TBL_PC *sd; sd=script->rid2sd(st); + if( sd == NULL ) + return false; type=script_getnum(st,2); val = -1; @@ -13203,10 +13260,8 @@ BUILDIN(getsavepoint) int type; sd = script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; type = script_getnum(st,2); @@ -13384,7 +13439,7 @@ BUILDIN(getmapxy) sd=script->rid2sd(st); else sd=NULL; - script->set_reg(st,sd,num,name,(void*)__64BPTRSIZE(x),script_getref(st,3)); + script->set_reg(st,sd,num,name,(void*)h64BPTRSIZE(x),script_getref(st,3)); //Set MapY num=st->stack->stack_data[st->start+4].u.num; @@ -13395,7 +13450,7 @@ BUILDIN(getmapxy) sd=script->rid2sd(st); else sd=NULL; - script->set_reg(st,sd,num,name,(void*)__64BPTRSIZE(y),script_getref(st,4)); + script->set_reg(st,sd,num,name,(void*)h64BPTRSIZE(y),script_getref(st,4)); //Return Success value script_pushint(st,0); @@ -13421,7 +13476,7 @@ BUILDIN(logmes) BUILDIN(summon) { - int _class, timeout=0; + int class_, timeout=0; const char *str,*event=""; TBL_PC *sd; struct mob_data *md; @@ -13431,7 +13486,7 @@ BUILDIN(summon) if (!sd) return true; str = script_getstr(st,2); - _class = script_getnum(st,3); + class_ = script_getnum(st,3); if( script_hasdata(st,4) ) timeout=script_getnum(st,4); if( script_hasdata(st,5) ) { @@ -13441,7 +13496,7 @@ BUILDIN(summon) clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick); - md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, _class, event, SZ_MEDIUM, AI_NONE); + md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, class_, event, SZ_MEDIUM, AI_NONE); if (md) { md->master_id=sd->bl.id; md->special_state.ai = AI_ATTACK; @@ -13479,10 +13534,8 @@ BUILDIN(isequippedcnt) int ret = 0; sd = script->rid2sd(st); - if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing... - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; for (i=0; id!=0; i++) { script_fetch(st,i+2, id); @@ -13535,10 +13588,8 @@ BUILDIN(isequipped) sd = script->rid2sd(st); - if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing... - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; setitem_hash = sd->bonus.setitem_hash; setitem_hash2 = sd->bonus.setitem_hash2; @@ -13616,6 +13667,9 @@ BUILDIN(cardscnt) { sd = script->rid2sd(st); + if( sd == NULL ) + return false; + for (i=0; id!=0; i++) { script_fetch(st,i+2, id); if (id <= 0) @@ -13650,10 +13704,12 @@ BUILDIN(cardscnt) { *-------------------------------------------------------*/ BUILDIN(getrefine) { TBL_PC *sd; - if ((sd = script->rid2sd(st))!= NULL) - script_pushint(st,sd->status.inventory[status->current_equip_item_index].refine); - else - script_pushint(st,0); + + sd = script->rid2sd(st); + if( sd == NULL ) + return false; + + script_pushint(st,sd->status.inventory[status->current_equip_item_index].refine); return true; } @@ -13696,6 +13752,8 @@ BUILDIN(equip) struct item_data *item_data; sd = script->rid2sd(st); + if( sd == NULL ) + return false; nameid=script_getnum(st,2); if((item_data = itemdb->exists(nameid)) == NULL) @@ -14342,7 +14400,7 @@ BUILDIN(sscanf) { if(sscanf(str, buf, &ref_int)==0) { break; } - script->set_reg(st, sd, reference_uid( reference_getid(data), reference_getindex(data) ), buf_p, (void *)__64BPTRSIZE(ref_int), reference_getref(data)); + script->set_reg(st, sd, reference_uid( reference_getid(data), reference_getindex(data) ), buf_p, (void *)h64BPTRSIZE(ref_int), reference_getref(data)); } arg++; @@ -14709,7 +14767,7 @@ BUILDIN(setd) if( is_string_variable(varname) ) { script->setd_sub(st, sd, varname, elem, (void *)script_getstr(st, 3), NULL); } else { - script->setd_sub(st, sd, varname, elem, (void *)__64BPTRSIZE(script_getnum(st, 3)), NULL); + script->setd_sub(st, sd, varname, elem, (void *)h64BPTRSIZE(script_getnum(st, 3)), NULL); } return true; @@ -14733,11 +14791,8 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) name = reference_getname(data); if( not_server_variable(*name) && sd == NULL ) { // requires a player sd = script->rid2sd(st); - if( sd == NULL ) { // no player attached - script->reportdata(data); - st->state = END; + if( sd == NULL )// no player attached return false; - } } } else { ShowError("script:query_sql: not a variable\n"); @@ -14786,7 +14841,7 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) if( is_string_variable(name) ) script->setd_sub(st, sd, name, i, (void *)(str?str:""), reference_getref(data)); else - script->setd_sub(st, sd, name, i, (void *)__64BPTRSIZE((str?atoi(str):0)), reference_getref(data)); + script->setd_sub(st, sd, name, i, (void *)h64BPTRSIZE((str?atoi(str):0)), reference_getref(data)); } } if( i == max_rows && max_rows < SQL->NumRows(handle) ) { @@ -14881,10 +14936,8 @@ BUILDIN(callshop) const char *shopname; int flag = 0; sd = script->rid2sd(st); - if (!sd) { - script_pushint(st,0); - return true; - } + if( sd == NULL ) + return false; shopname = script_getstr(st, 2); if( script_hasdata(st,3) ) flag = script_getnum(st,3); @@ -15076,7 +15129,7 @@ BUILDIN(setitemscript) if(*dstscript) script->free_code(*dstscript); - *dstscript = new_bonus_script[0] ? script->parse(new_bonus_script, "script_setitemscript", 0, 0) : NULL; + *dstscript = new_bonus_script[0] ? script->parse(new_bonus_script, "script_setitemscript", 0, 0, NULL) : NULL; script_pushint(st,1); return true; } @@ -15342,7 +15395,7 @@ BUILDIN(searchitem) for( i = 0; i < count; ++start, ++i ) {// Set array - void* v = (void*)__64BPTRSIZE((int)items[i]->nameid); + void* v = (void*)h64BPTRSIZE((int)items[i]->nameid); script->set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data)); } @@ -16204,7 +16257,9 @@ BUILDIN(setquest) { struct map_session_data *sd = script->rid2sd(st); unsigned short i; int quest_id; - nullpo_retr(false,sd); + + if( sd == NULL ) + return false; quest_id = script_getnum(st, 2); @@ -16227,7 +16282,9 @@ BUILDIN(setquest) { BUILDIN(erasequest) { struct map_session_data *sd = script->rid2sd(st); - nullpo_retr(false,sd); + + if( sd == NULL ) + return false; quest->delete(sd, script_getnum(st, 2)); return true; @@ -16235,7 +16292,9 @@ BUILDIN(erasequest) { BUILDIN(completequest) { struct map_session_data *sd = script->rid2sd(st); - nullpo_retr(false,sd); + + if( sd == NULL ) + return false; quest->update_status(sd, script_getnum(st, 2), Q_COMPLETE); return true; @@ -16243,7 +16302,9 @@ BUILDIN(completequest) { BUILDIN(changequest) { struct map_session_data *sd = script->rid2sd(st); - nullpo_retr(false,sd); + + if( sd == NULL ) + return false; quest->change(sd, script_getnum(st, 2),script_getnum(st, 3)); return true; @@ -16253,7 +16314,8 @@ BUILDIN(checkquest) { struct map_session_data *sd = script->rid2sd(st); enum quest_check_type type = HAVEQUEST; - nullpo_retr(false,sd); + if( sd == NULL ) + return false; if( script_hasdata(st, 3) ) type = (enum quest_check_type)script_getnum(st, 3); @@ -17315,19 +17377,6 @@ BUILDIN(is_function) { return true; } /** - * get_revision() -> retrieves the current svn revision (if available) - **/ -BUILDIN(get_revision) { - const char *svn = get_svn_revision(); - - if ( svn[0] != HERC_UNKNOWN_VER ) - script_pushint(st,atoi(svn)); - else - script_pushint(st,-1);//unknown - - return true; -} -/** * freeloop(<toggle>) -> toggles this script instance's looping-check ability **/ BUILDIN(freeloop) { @@ -17345,12 +17394,14 @@ BUILDIN(freeloop) { BUILDIN(sit) { struct map_session_data *sd = NULL; - if (script_hasdata(st, 2)) + if( script_hasdata(st, 2) ) sd = map->nick2sd(script_getstr(st, 2)); - - if (sd == NULL) + else sd = script->rid2sd(st); + if( sd == NULL ) + return false; + if (!pc_issit(sd)) { pc_setsit(sd); @@ -17363,12 +17414,14 @@ BUILDIN(sit) { BUILDIN(stand) { struct map_session_data *sd = NULL; - if (script_hasdata(st, 2)) + if( script_hasdata(st, 2) ) sd = map->nick2sd(script_getstr(st, 2)); - - if (sd == NULL) + else sd = script->rid2sd(st); + if( sd == NULL ) + return false; + if (pc_issit(sd)) { pc->setstand(sd); @@ -17381,12 +17434,14 @@ BUILDIN(stand) { BUILDIN(issit) { struct map_session_data *sd = NULL; - if (script_hasdata(st, 2)) + if( script_hasdata(st, 2) ) sd = map->nick2sd(script_getstr(st, 2)); - - if (sd == NULL) + else sd = script->rid2sd(st); + if( sd == NULL ) + return false; + if (pc_issit(sd)) script_pushint(st, 1); else @@ -17498,6 +17553,8 @@ BUILDIN(useatcmd) { if( st->rid ) { sd = script->rid2sd(st); + if( sd == NULL ) + return false; fd = sd->fd; } else { // Use a dummy character. @@ -17700,7 +17757,7 @@ BUILDIN(npcskill) { ShowError("npcskill: level exceeded maximum of %d.\n", MAX_LEVEL); return false; } - if (sd == NULL || nd == NULL) { //ain't possible, but I don't trust people. + if (sd == NULL || nd == NULL) { return false; } @@ -18546,6 +18603,13 @@ BUILDIN(tradertype) { npc->market_delfromsql(nd,USHRT_MAX); } +#if PACKETVER < 20131223 + if( type == NST_MARKET ) { + ShowWarning("buildin_tradertype: NST_MARKET is only available with PACKETVER 20131223 or newer!\n"); + script->reportsrc(st); + } +#endif + nd->u.scr.shop->type = type; return true; @@ -19152,7 +19216,6 @@ void script_parse_builtin(void) { BUILDIN_DEF(getargcount,""), BUILDIN_DEF(getcharip,"?"), BUILDIN_DEF(is_function,"s"), - BUILDIN_DEF(get_revision,""), BUILDIN_DEF(freeloop,"i"), BUILDIN_DEF(getrandgroupitem,"ii"), BUILDIN_DEF(cleanmap,"s"), |