diff options
Diffstat (limited to 'src/map/script.c')
-rw-r--r-- | src/map/script.c | 449 |
1 files changed, 246 insertions, 203 deletions
diff --git a/src/map/script.c b/src/map/script.c index a1886d043..48c377d24 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -2825,7 +2825,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) { char postfix; struct map_session_data *sd = NULL; - if( !data_isreference(data) ) + if (!data_isreference(data)) return data;// not a variable/constant name = reference_getname(data); @@ -2840,10 +2840,10 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) { } //##TODO use reference_tovariable(data) when it's confirmed that it works [FlavioJS] - if( !reference_toconstant(data) && not_server_variable(prefix) ) { + if (!reference_toconstant(data) && not_server_variable(prefix) && reference_getref(data) == NULL) { sd = script->rid2sd(st); - if( sd == NULL ) {// needs player attached - if( postfix == '$' ) {// string variable + if (sd == NULL) {// needs player attached + if (postfix == '$') {// string variable ShowWarning("script_get_val: cannot access player variable '%s', defaulting to \"\"\n", name); data->type = C_CONSTSTR; data->u.str = ""; @@ -2919,7 +2919,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) { } else if( reference_toparam(data) ) { data->u.num = pc->readparam(sd, reference_getparamtype(data)); } else { - switch(prefix) { + switch (prefix) { case '@': if (data->ref) { data->u.num = script->get_val_ref_num(st, data->ref, data); @@ -2933,7 +2933,7 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) { case '#': if (data->ref) { data->u.num = script->get_val_ref_num(st, data->ref, data); - } else if(name[1] == '#') { + } else if (name[1] == '#') { data->u.num = pc_readaccountreg2(sd, data->u.num);// global } else { data->u.num = pc_readaccountreg(sd, data->u.num);// local @@ -2960,7 +2960,6 @@ struct script_data *get_val(struct script_state* st, struct script_data* data) { break; } } - } data->ref = NULL; @@ -3133,38 +3132,43 @@ void script_array_add_member(struct script_array *sa, unsigned int idx) { **/ 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; - nullpo_retr(NULL, name); - switch( name[0] ) { + + switch (name[0]) { /* from player */ - default: /* char reg */ - case '@':/* temp char reg */ - case '#':/* account reg */ + default: /* char reg */ + case '@':/* temp char reg */ + case '#':/* account reg */ + if (ref != NULL) { + src = ref; + } else { nullpo_retr(NULL, sd); src = &sd->regs; - break; - case '$':/* map reg */ - src = &mapreg->regs; - break; - case '.':/* npc/script */ - if (ref != NULL) { - src = ref; - } else { - nullpo_retr(NULL, st); - src = (name[1] == '@') ? &st->stack->scope : &st->script->local; - } - break; - case '\'':/* instance */ + } + break; + case '$':/* map reg */ + src = &mapreg->regs; + break; + case '.':/* npc/script */ + if (ref != NULL) { + src = ref; + } else { nullpo_retr(NULL, st); - if( st->instance_id >= 0 ) { - src = &instance->list[st->instance_id].regs; - } - break; + src = (name[1] == '@') ? &st->stack->scope : &st->script->local; + } + break; + case '\'':/* instance */ + nullpo_retr(NULL, st); + if (st->instance_id >= 0) { + src = &instance->list[st->instance_id].regs; + } + break; } - if( src ) { - if( !src->arrays ) + if (src) { + if (!src->arrays) { src->arrays = idb_alloc(DB_OPT_BASE); + } return src; } return NULL; @@ -3317,7 +3321,7 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con return 0; } - if(is_string_variable(name)) {// string variable + if (is_string_variable(name)) {// string variable const char *str = (const char*)value; switch (prefix) { @@ -3329,7 +3333,8 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con } return 1; case '$': - return mapreg->setregstr(num, str); + mapreg->setregstr(num, str); + return 1; case '#': if (ref) { script->set_reg_ref_str(st, ref, num, name, str); @@ -3364,16 +3369,17 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con // 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 ) { + 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); // 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 ) + if(st->state == CLOSE) { clif->scriptclose(sd, st->oid); + } } return 0; } @@ -3389,7 +3395,8 @@ int set_reg(struct script_state *st, struct map_session_data *sd, int64 num, con } return 1; case '$': - return mapreg->setreg(num, val); + mapreg->setreg(num, val); + return 1; case '#': if (ref) { script->set_reg_ref_num(st, ref, num, name, val); @@ -6665,61 +6672,67 @@ BUILDIN(warpparty) } /*========================================== * Warpguild - [Fredzilla] - * Syntax: warpguild "mapname",x,y,Guild_ID; + * Syntax: warpguild "mapname",x,y,Guild_ID,{"from_mapname"}; *------------------------------------------*/ BUILDIN(warpguild) { struct map_session_data *sd = NULL; - struct map_session_data *pl_sd; struct guild* g; - struct s_mapiterator* iter; int type; + int i; + int16 map_id = -1; - const char* str = script_getstr(st,2); - int x = script_getnum(st,3); - int y = script_getnum(st,4); - int gid = script_getnum(st,5); + const char *str = script_getstr(st, 2); + int x = script_getnum(st, 3); + int y = script_getnum(st, 4); + int gid = script_getnum(st, 5); + + if (script_hasdata(st, 6)) { + map_id = map->mapname2mapid(script_getstr(st, 6)); + } g = guild->search(gid); - if( g == NULL ) + if (g == NULL) return true; - type = ( strcmp(str,"Random")==0 ) ? 0 - : ( strcmp(str,"SavePointAll")==0 ) ? 1 - : ( strcmp(str,"SavePoint")==0 ) ? 2 + type = (strcmp(str, "Random") == 0) ? 0 + : (strcmp(str, "SavePointAll") == 0) ? 1 + : (strcmp(str, "SavePoint") == 0) ? 2 : 3; - if( type == 2 && ( sd = script->rid2sd(st) ) == NULL ) + if (type == 2 && (sd = script->rid2sd(st)) == NULL) {// "SavePoint" uses save point of the currently attached player return true; } - iter = mapit_getallusers(); - for (pl_sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); pl_sd = BL_UCAST(BL_PC, mapit->next(iter))) { - if( pl_sd->status.guild_id != gid ) - continue; + for (i = 0; i < MAX_GUILD; i++) { + if (g->member[i].online && g->member[i].sd != NULL) { + struct map_session_data *pl_sd = g->member[i].sd; - switch( type ) - { + if (map_id >= 0 && map_id != pl_sd->bl.m) + continue; + + switch (type) + { case 0: // Random - if(!map->list[pl_sd->bl.m].flag.nowarp) - pc->randomwarp(pl_sd,CLR_TELEPORT); + if (!map->list[pl_sd->bl.m].flag.nowarp) + pc->randomwarp(pl_sd, CLR_TELEPORT); break; case 1: // SavePointAll - if(!map->list[pl_sd->bl.m].flag.noreturn) - pc->setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT); + if (!map->list[pl_sd->bl.m].flag.noreturn) + pc->setpos(pl_sd, pl_sd->status.save_point.map, pl_sd->status.save_point.x, pl_sd->status.save_point.y, CLR_TELEPORT); break; case 2: // SavePoint - if(!map->list[pl_sd->bl.m].flag.noreturn) - pc->setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); + if (!map->list[pl_sd->bl.m].flag.noreturn) + pc->setpos(pl_sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); break; case 3: // m,x,y - if(!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp) - pc->setpos(pl_sd,script->mapindexname2id(st,str),x,y,CLR_TELEPORT); + if (!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp) + pc->setpos(pl_sd, script->mapindexname2id(st, str), x, y, CLR_TELEPORT); break; + } } } - mapit->free(iter); return true; } @@ -8740,39 +8753,48 @@ BUILDIN(getguildmember) *------------------------------------------*/ BUILDIN(strcharinfo) { - int num; struct guild* g; struct party_data* p; - struct map_session_data *sd = script->rid2sd(st); - if (sd == NULL) //Avoid crashing.... + struct map_session_data *sd; + + if (script_hasdata(st, 4)) + sd = map->id2sd(script_getnum(st, 4)); + else + sd = script->rid2sd(st); + + if (sd == NULL) { + if(script_hasdata(st, 3)) { + script_pushcopy(st, 3); + } else { + script_pushconststr(st, ""); + } return true; + } - num=script_getnum(st,2); - switch(num) { - case 0: - script_pushstrcopy(st,sd->status.name); - break; - case 1: - if( ( p = party->search(sd->status.party_id) ) != NULL ) { - script_pushstrcopy(st,p->party.name); - } else { - script_pushconststr(st,""); - } - break; - case 2: - if( ( g = sd->guild ) != NULL ) { - script_pushstrcopy(st,g->name); - } else { - script_pushconststr(st,""); - } - break; - case 3: - script_pushconststr(st,map->list[sd->bl.m].name); - break; - default: - ShowWarning("buildin_strcharinfo: unknown parameter.\n"); - script_pushconststr(st,""); - break; + switch (script_getnum(st, 2)) { + case 0: + script_pushstrcopy(st, sd->status.name); + break; + case 1: + if ((p = party->search(sd->status.party_id)) != NULL) { + script_pushstrcopy(st, p->party.name); + } else { + script_pushconststr(st, ""); + } + break; + case 2: + if ((g = sd->guild) != NULL) { + script_pushstrcopy(st, g->name); + } else { + script_pushconststr(st, ""); + } + break; + case 3: + script_pushconststr(st, map->list[sd->bl.m].name); + break; + default: + ShowWarning("script:strcharinfo: unknown parameter.\n"); + script_pushconststr(st, ""); } return true; @@ -8789,41 +8811,51 @@ BUILDIN(strcharinfo) *------------------------------------------*/ BUILDIN(strnpcinfo) { - int num; char *buf,*name=NULL; - struct npc_data *nd = map->id2nd(st->oid); + struct npc_data *nd; + + if (script_hasdata(st, 4)) + nd = map->id2nd(script_getnum(st, 4)); + else + nd = map->id2nd(st->oid); + if (nd == NULL) { - script_pushconststr(st, ""); + if (script_hasdata(st, 3)) { + script_pushcopy(st, 3); + } else { + script_pushconststr(st, ""); + } return true; } - num = script_getnum(st,2); - switch(num) { - case 0: // display name + switch (script_getnum(st,2)) { + case 0: // display name + name = aStrdup(nd->name); + break; + case 1: // visible part of display name + if ((buf = strchr(nd->name,'#')) != NULL) { name = aStrdup(nd->name); - break; - case 1: // visible part of display name - if((buf = strchr(nd->name,'#')) != NULL) - { - name = aStrdup(nd->name); - name[buf - nd->name] = 0; - } else // Return the name, there is no '#' present - name = aStrdup(nd->name); - break; - case 2: // # fragment - if((buf = strchr(nd->name,'#')) != NULL) - name = aStrdup(buf+1); - break; - case 3: // unique name - name = aStrdup(nd->exname); - break; - case 4: // map name - if( nd->bl.m >= 0 ) // Only valid map indexes allowed (issue:8034) - name = aStrdup(map->list[nd->bl.m].name); - break; + name[buf - nd->name] = 0; + } else { // Return the name, there is no '#' present + name = aStrdup(nd->name); + } + break; + case 2: // # fragment + if ((buf = strchr(nd->name,'#')) != NULL) { + name = aStrdup(buf+1); + } + break; + case 3: // unique name + name = aStrdup(nd->exname); + break; + case 4: // map name + if (nd->bl.m >= 0) { // Only valid map indexes allowed (issue:8034) + name = aStrdup(map->list[nd->bl.m].name); + } + break; } - if(name) + if (name) script_pushstr(st, name); else script_pushconststr(st, ""); @@ -10759,19 +10791,29 @@ BUILDIN(donpcevent) *------------------------------------------*/ BUILDIN(addtimer) { - int tick = script_getnum(st,2); + int tick = script_getnum(st, 2); const char* event = script_getstr(st, 3); struct map_session_data *sd; script->check_event(st, event); - sd = script->rid2sd(st); - if( sd == NULL ) - return true; - if (!pc->addeventtimer(sd,tick,event)) { - ShowWarning("buildin_addtimer: Event timer is full, can't add new event timer. (cid:%d timer:%s)\n",sd->status.char_id,event); + if (script_hasdata(st, 4)) + sd = map->id2sd(script_getnum(st, 4)); + else + sd = script->rid2sd(st); + + if (sd == NULL) { + script_pushint(st, 0); + return false; + } + + if (!pc->addeventtimer(sd, tick, event)) { + ShowWarning("script:addtimer: Event timer is full, can't add new event timer. (cid:%d timer:%s)\n", sd->status.char_id, event); + script_pushint(st, 0); return false; } + + script_pushint(st, 1); return true; } /*========================================== @@ -10782,12 +10824,17 @@ BUILDIN(deltimer) struct map_session_data *sd; event=script_getstr(st, 2); - sd = script->rid2sd(st); - if( sd == NULL ) + + if (script_hasdata(st, 3)) + sd = map->id2sd(script_getnum(st, 3)); + else + sd = script->rid2sd(st); + + if (sd == NULL) return true; script->check_event(st, event); - pc->deleventtimer(sd,event); + pc->deleventtimer(sd, event); return true; } /*========================================== @@ -10798,14 +10845,19 @@ BUILDIN(addtimercount) int tick; struct map_session_data *sd; - event=script_getstr(st, 2); - tick=script_getnum(st,3); - sd = script->rid2sd(st); - if( sd == NULL ) + event = script_getstr(st, 2); + tick = script_getnum(st, 3); + + if (script_hasdata(st, 4)) + sd = map->id2sd(script_getnum(st, 4)); + else + sd = script->rid2sd(st); + + if (sd == NULL) return true; script->check_event(st, event); - pc->addeventtimercount(sd,event,tick); + pc->addeventtimercount(sd, event, tick); return true; } @@ -16549,11 +16601,7 @@ BUILDIN(escape_sql) return true; } -BUILDIN(getd) -{ - struct block_list *bl = NULL; - struct map_session_data *sd; - struct npc_data *nd; +BUILDIN(getd) { char varname[100]; const char *buffer; int elem; @@ -16563,63 +16611,8 @@ BUILDIN(getd) if (sscanf(buffer, "%99[^[][%d]", varname, &elem) < 2) elem = 0; - if (strlen(varname) < 1) { - ShowError("script:getd: variable cannot be empty\n"); - script->reportdata(script_getdata(st, 2)); - script_pushnil(st); - st->state = END; - return false; - } - - if (script_hasdata(st, 3)) { - bl = map->id2bl(script_getnum(st, 3)); - - if (bl == NULL) { - // being not found, push default value - if (script_hasdata(st, 4)) { - script_pushcopy(st, 4); - } else if (varname[strlen(varname) - 1] == '$') { - script_pushconststr(st, ""); - } else { - script_pushint(st, 0); - } - return false; - } else if (bl->type == BL_NPC && (varname[0] != '.' || varname[1] == '@')) { - ShowError("script:getd: invalid scope (not npc variable)\n"); - script->reportdata(script_getdata(st, 2)); - script_pushnil(st); - st->state = END; - return false; - } else if (bl->type == BL_PC && (varname[0] == '.' || varname[0] == '$' || varname[0] == '\'')) { - ShowError("script:getd: invalid scope (not pc variable)\n"); - script->reportdata(script_getdata(st, 2)); - script_pushnil(st); - st->state = END; - return false; - } - } - // Push the 'pointer' so it's more flexible [Lance] - - if (bl != NULL) { - switch (bl->type) { - case BL_PC: - sd = map->id2sd(bl->id); - script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem), &sd->regs); - break; - case BL_NPC: - nd = map->id2nd(bl->id); - script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem), &nd->u.scr.script->local); - break; - default: - ShowError("script:getd: invalid being type (not npc or pc)\n"); - script_pushnil(st); - st->state = END; - return false; - } - } else { - script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem), NULL); - } + script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem),NULL); return true; } @@ -17646,6 +17639,55 @@ BUILDIN(getvariableofnpc) return true; } +BUILDIN(getvariableofpc) +{ + const char* name; + struct script_data* data = script_getdata(st, 2); + struct map_session_data *sd = map->id2sd(script_getnum(st, 3)); + + if (!data_isreference(data)) { + ShowError("script:getvariableofpc: not a variable\n"); + script->reportdata(data); + script_pushnil(st); + st->state = END; + return false; + } + + name = reference_getname(data); + + switch (*name) + { + case '#': + case '$': + case '.': + case '\'': + ShowError("script:getvariableofpc: illegal scope (not pc variable)\n"); + script->reportdata(data); + script_pushnil(st); + st->state = END; + return false; + } + + if (sd == NULL) + { + // player not found, return default value + if (script_hasdata(st, 4)) { + script_pushcopy(st, 4); + } else if (is_string_variable(name)) { + script_pushconststr(st, ""); + } else { + script_pushint(st, 0); + } + return true; + } + + if (!sd->regs.vars) + sd->regs.vars = i64db_alloc(DB_OPT_RELEASE_DATA); + + script->push_val(st->stack, C_NAME, reference_getuid(data), &sd->regs); + return true; +} + /// Opens a warp portal. /// Has no "portal opening" effect/sound, it opens the portal immediately. /// @@ -20965,7 +21007,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(areawarp,"siiiisii??"), BUILDIN_DEF(warpchar,"siii"), // [LuzZza] BUILDIN_DEF(warpparty,"siii?"), // [Fredzilla] [Paradox924X] - BUILDIN_DEF(warpguild,"siii"), // [Fredzilla] + BUILDIN_DEF(warpguild,"siii?"), // [Fredzilla] BUILDIN_DEF(setlook,"ii"), BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it BUILDIN_DEF2(__setr,"set","rv"), @@ -21006,8 +21048,8 @@ void script_parse_builtin(void) { BUILDIN_DEF(getguildmaster,"i"), BUILDIN_DEF(getguildmasterid,"i"), BUILDIN_DEF(getguildmember,"i?"), - BUILDIN_DEF(strcharinfo,"i"), - BUILDIN_DEF(strnpcinfo,"i"), + BUILDIN_DEF(strcharinfo,"i??"), + BUILDIN_DEF(strnpcinfo,"i??"), BUILDIN_DEF(charid2rid,"i"), BUILDIN_DEF(getequipid,"i"), BUILDIN_DEF(getequipname,"i"), @@ -21070,9 +21112,9 @@ void script_parse_builtin(void) { BUILDIN_DEF(clone,"siisi????"), BUILDIN_DEF(doevent,"s"), BUILDIN_DEF(donpcevent,"s"), - BUILDIN_DEF(addtimer,"is"), - BUILDIN_DEF(deltimer,"s"), - BUILDIN_DEF(addtimercount,"si"), + BUILDIN_DEF(addtimer,"is?"), + BUILDIN_DEF(deltimer,"s?"), + BUILDIN_DEF(addtimercount,"si?"), BUILDIN_DEF(initnpctimer,"??"), BUILDIN_DEF(stopnpctimer,"??"), BUILDIN_DEF(startnpctimer,"??"), @@ -21257,7 +21299,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(md5,"s"), BUILDIN_DEF(swap,"rr"), // [zBuffer] List of dynamic var commands ---> - BUILDIN_DEF(getd,"s??"), + BUILDIN_DEF(getd,"s"), BUILDIN_DEF(setd,"sv"), // <--- [zBuffer] List of dynamic var commands BUILDIN_DEF(petstat,"i"), @@ -21305,6 +21347,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(sleep2,"i"), BUILDIN_DEF(awake,"s"), BUILDIN_DEF(getvariableofnpc,"rs"), + BUILDIN_DEF(getvariableofpc,"ri?"), BUILDIN_DEF(warpportal,"iisii"), BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn] BUILDIN_DEF2(homunculus_mutate,"hommutate","?"), |