diff options
-rw-r--r-- | Changelog-Trunk.txt | 5 | ||||
-rw-r--r-- | src/map/atcommand.c | 12 | ||||
-rw-r--r-- | src/map/clif.c | 22 | ||||
-rw-r--r-- | src/map/clif.h | 1 | ||||
-rw-r--r-- | src/map/map.h | 3 | ||||
-rw-r--r-- | src/map/pc.c | 36 | ||||
-rw-r--r-- | src/map/script.c | 154 |
7 files changed, 144 insertions, 89 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 70e09b5db..9f279b6af 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,11 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2007/02/12 + * A bit more work on Ticket #41. + * Added 'r' (variable reference) to the script argument definitions. + * Added a simple define for suspitious actions. (empty at the moment) + * Added clif_clearcart and moved sending cart packets to pc_setoption. + * clif_parse_ChangeCart checking the player level. [FlavioJS] * Fixed clif_parse_GMmessage cutting off messages randomly [ultramage] (due to a typo in revision r9778) * Fixed Wand of Hermod diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 9a427547c..98304925a 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -2218,10 +2218,6 @@ int atcommand_option(const int fd, struct map_session_data* sd, const char* comm sd->sc.opt1 = param1; sd->sc.opt2 = param2; - if (!(sd->sc.option & OPTION_CART) && param3 & OPTION_CART) { - clif_cartlist(sd); - clif_updatestatus(sd, SP_CARTINFO); - } pc_setoption(sd, param3); clif_displaymessage(fd, msg_txt(9)); // Options changed. @@ -5666,14 +5662,14 @@ int atcommand_mount_peco(const int fd, struct map_session_data* sd, const char* if (!pc_isriding(sd)) { // if actually no peco if (pc_checkskill(sd, KN_RIDING)) { - pc_setoption(sd, sd->sc.option | 0x0020); + pc_setoption(sd, sd->sc.option | OPTION_RIDING); clif_displaymessage(fd, msg_txt(102)); // Mounted Peco. } else { clif_displaymessage(fd, msg_txt(213)); // You can not mount a peco with your job. return -1; } } else { //Dismount - pc_setoption(sd, sd->sc.option & ~0x0020); + pc_setoption(sd, sd->sc.option & ~OPTION_RIDING); clif_displaymessage(fd, msg_txt(214)); // Unmounted Peco. } @@ -5700,14 +5696,14 @@ int atcommand_char_mount_peco(const int fd, struct map_session_data* sd, const c if (!pc_isriding(pl_sd)) { // if actually no peco if (pc_checkskill(pl_sd, KN_RIDING)) { - pc_setoption(pl_sd, pl_sd->sc.option | 0x0020); + pc_setoption(pl_sd, pl_sd->sc.option | OPTION_RIDING); clif_displaymessage(fd, msg_txt(216)); // Mounted Peco. } else { clif_displaymessage(fd, msg_txt(217)); // You can not mount a peco with your job. return -1; } } else { //Dismount - pc_setoption(pl_sd, pl_sd->sc.option & ~0x0020); + pc_setoption(pl_sd, pl_sd->sc.option & ~OPTION_RIDING); clif_displaymessage(fd, msg_txt(218)); // Unmounted Peco. } } else { diff --git a/src/map/clif.c b/src/map/clif.c index fdd548913..26312a138 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2391,6 +2391,15 @@ void clif_cartlist(struct map_session_data *sd) return; } +/// Client behaviour: +/// Closes the cart storage and removes all it's items from memory. +/// The Num & Weight values of the cart are left untouched and the cart is NOT removed. +void clif_clearcart(int fd) +{ + WFIFOHEAD(fd, packet_len(0x12b)); + WFIFOW(fd,0) = 0x12b; +} + // Guild XY locators [Valaris] int clif_guild_xy(struct map_session_data *sd) { @@ -9612,8 +9621,19 @@ void clif_parse_RemoveOption(int fd,struct map_session_data *sd) */ void clif_parse_ChangeCart(int fd,struct map_session_data *sd) { + int type; + RFIFOHEAD(fd); - pc_setcart(sd,RFIFOW(fd,2)); + type = (int)RFIFOW(fd,2); + + if( (type == 5 && sd->status.base_level <= 90) || + (type == 4 && sd->status.base_level <= 80) || + (type == 3 && sd->status.base_level <= 65) || + (type == 2 && sd->status.base_level <= 40) || + pc_setcart(sd,type) ) + { + LOG_SUSPICIOUS(sd,"clif_parse_ChangeCart: player doesn't have the required level"); + } } /*========================================== diff --git a/src/map/clif.h b/src/map/clif.h index b18c11201..61d9e1b3f 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -225,6 +225,7 @@ void clif_equiplist(struct map_session_data *sd); int clif_cart_additem(struct map_session_data*,int,int,int); int clif_cart_delitem(struct map_session_data*,int,int); void clif_cartlist(struct map_session_data *sd); +void clif_clearcart(int fd); int clif_item_identify_list(struct map_session_data *sd); int clif_item_identified(struct map_session_data *sd,int idx,int flag); diff --git a/src/map/map.h b/src/map/map.h index fb0756c65..a8e24d7fe 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -546,6 +546,9 @@ struct homunculus_db; //[orn] struct item_data; struct square; +// The player performed a suspicious action (not used right now) [FlavioJS] +#define LOG_SUSPICIOUS(sd,msg) + struct map_session_data { struct block_list bl; struct unit_data ud; diff --git a/src/map/pc.c b/src/map/pc.c index 3fba85898..ee30f5bc8 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5737,15 +5737,18 @@ int pc_setoption(struct map_session_data *sd,int type) } if(type&OPTION_CART && !(p_type&OPTION_CART)) { //Cart On + clif_cartlist(sd); + clif_updatestatus(sd, SP_CARTINFO); if(pc_checkskill(sd, MC_PUSHCART) < 10) status_calc_pc(sd,0); //Apply speed penalty. } else if(!(type&OPTION_CART) && p_type&OPTION_CART) { //Cart Off + clif_clearcart(sd->fd); if(pc_checkskill(sd, MC_PUSHCART) < 10) status_calc_pc(sd,0); //Remove speed penalty. } - + if (type&OPTION_FALCON && !(p_type&OPTION_FALCON)) //Falcon ON clif_status_load(&sd->bl,SI_FALCON,1); else if (!(type&OPTION_FALCON) && p_type&OPTION_FALCON) //Falcon OFF @@ -5784,27 +5787,22 @@ int pc_setoption(struct map_session_data *sd,int type) */ int pc_setcart(struct map_session_data *sd,int type) { - int cart[6]={0x0000,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5}; + int cart[6] = {0x0000,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5}; int option; + nullpo_retr(0, sd); - - if (type < 0 || type > 5) - return 0; //Never trust the values sent by the client! [Skotlex] - if(pc_checkskill(sd,MC_PUSHCART)>0){ // プッシュカ?トスキル所持 - option = sd->sc.option; - //This should preserve the current option, only modifying the cart bit. - option&=~OPTION_CART; - option|=cart[type]; - if(!pc_iscarton(sd)){ // カ?トを付けていない - pc_setoption(sd,option); - clif_cartlist(sd); - clif_updatestatus(sd,SP_CARTINFO); - } - else{ - pc_setoption(sd,option); - } - } + if( type < 0 || type > 5 ) + return 1;// Never trust the values sent by the client! [Skotlex] + + if( pc_checkskill(sd,MC_PUSHCART) <= 0 ) + return 1;// Push cart is required + + // Update option + option = sd->sc.option; + option &= ~OPTION_CART;// clear cart bits + option |= cart[type]; // set cart + pc_setoption(sd, option); return 0; } diff --git a/src/map/script.c b/src/map/script.c index f369dc031..832647b7f 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -52,9 +52,10 @@ #include <time.h> #include <setjmp.h> +// +// struct script_state* st; +// - -/////////////////////////////////////////////////////////////////////////////// /// Returns the stack_data at the target index #define script_getdata(st,i) &((st)->stack->stack_data[(st)->start+(i)]) /// Returns if the stack contains data at the target index @@ -63,10 +64,17 @@ #define script_lastdata(st) ( (st)->end - (st)->start - 1 ) /// Pushes an int into the stack #define script_pushint(st,val) push_val((st)->stack, C_INT, (val)) -/// Returns if the stack data is a string -#define script_isstring(data) ( (data)->type == C_STR || (data)->type == C_CONSTSTR ) -/// Returns if the stack data is an int -#define script_isint(data) ( (data)->type == C_INT ) + +// +// struct script_data* data; +// + +/// Returns if the script data is a string +#define data_isstring(data) ( (data)->type == C_STR || (data)->type == C_CONSTSTR ) +/// Returns if the script data is an int +#define data_isint(data) ( (data)->type == C_INT ) +/// Returns if the script data is a reference +#define data_isreference(data) ( (data)->type == C_NAME ) #define FETCH(n, t) \ if( script_hasdata(st,n) ) \ @@ -1567,15 +1575,16 @@ static void add_buildin_func(void) int i,n; const char* p; for( i=0; buildin_func[i].func; i++ ){ - /// arg must follow the pattern: (v|s|i|l)*\?*\*? - /// 'v' - value (either string or int) - /// 's' - string - /// 'i' - int - /// 'l' - label - /// '?' - one optional parameter - /// '*' - unknown number of optional parameters + // arg must follow the pattern: (v|s|i|r|l)*\?*\*? + // 'v' - value (either string or int or reference) + // 's' - string + // 'i' - int + // 'r' - reference (of a variable) + // 'l' - label + // '?' - one optional parameter + // '*' - unknown number of optional parameters p=buildin_func[i].arg; - while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'l' ) ++p; + while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'r' || *p == 'l' ) ++p; while( *p == '?' ) ++p; if( *p == '*' ) ++p; if( *p != 0){ @@ -3355,6 +3364,7 @@ static int do_final_userfunc_sub (DBKey key,void *data,va_list ap) */ int do_final_script() { +#ifdef DEBUG_RUN if (battle_config.etc_log) { FILE *fp = fopen("hash_dump.txt","wt"); @@ -3408,6 +3418,7 @@ int do_final_script() fclose(fp); } } +#endif if(mapreg_dirty>=0) script_save_mapreg(); @@ -4138,7 +4149,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(sleep,"i"), BUILDIN_DEF(sleep2,"i"), BUILDIN_DEF(awake,"s"), - BUILDIN_DEF(getvariableofnpc,"is"), + BUILDIN_DEF(getvariableofnpc,"rs"), // [blackhole89] --> BUILDIN_DEF(warpportal,"iisii"), // <--- [blackhole89] @@ -5346,7 +5357,7 @@ BUILDIN_FUNC(getitem) data=script_getdata(st,2); get_val(st,data); - if( script_isstring(data) ) + if( data_isstring(data) ) {// "<item name>" const char *name=conv_str(st,data); struct item_data *item_data = itemdb_searchname(name); @@ -5356,7 +5367,7 @@ BUILDIN_FUNC(getitem) return 1; //No item created. } nameid=item_data->nameid; - } else if( script_isint(data) ) + } else if( data_isint(data) ) {// <item id> nameid=conv_num(st,data); //Violet Box, Blue Box, etc - random item pick @@ -9665,10 +9676,10 @@ BUILDIN_FUNC(guardian) } else if( script_hasdata(st,8) ){ data=script_getdata(st,8); get_val(st,data); - if( script_isstring(data) ) + if( data_isstring(data) ) {// "<event label>" evt=conv_str(st,script_getdata(st,8)); - } else if( script_isint(data) ) + } else if( data_isint(data) ) {// <guardian index> guardian=conv_num(st,script_getdata(st,8)); } else { @@ -12860,63 +12871,84 @@ BUILDIN_FUNC(awake) return 0; } -// getvariableofnpc(<param>, <npc name>); +/// Returns a reference to a variable of the target NPC. +/// Returns 0 if an error occurs. +/// +/// getvariableofnpc(<variable>, "<npc name>") -> <reference> BUILDIN_FUNC(getvariableofnpc) { - if( st->stack->stack_data[st->start+2].type != C_NAME ) { - // 第一引数が変数名じゃない - printf("getvariableofnpc: param not name\n"); - push_val(st->stack,C_INT,0); - } else { - int num = st->stack->stack_data[st->start+2].u.num; - char *var_name = str_buf+str_data[num&0x00ffffff].str; - char *npc_name = conv_str(st,& (st->stack->stack_data[st->start+3])); - struct npc_data *nd = npc_name2id(npc_name); - if( var_name[0] != '.' || var_name[1] == '@' ) { - // ' 変数以外はダメ - printf("getvariableofnpc: invalid scope %s\n", var_name); - push_val(st->stack,C_INT,0); - } else if( nd == NULL || nd->bl.subtype != SCRIPT || !nd->u.scr.script) { - // NPC が見つからない or SCRIPT以外のNPC - printf("getvariableofnpc: can't find npc %s\n", npc_name); - push_val(st->stack,C_INT,0); - } else { - push_val2(st->stack,C_NAME,num, &nd->u.scr.script->script_vars ); + struct script_data* data; + + data = script_getdata(st,2); + if( !data_isreference(data) ) + {// Not a reference (aka varaible name) + ShowError("script: getvariableofnpc: first argument is not a variable name\n"); + st->state = END; + return 1; + } + else + { + int num = data->u.num; + char* var_name = str_buf + str_data[num&0x00ffffff].str; + char* npc_name = conv_str(st, script_getdata(st,3)); + struct npc_data* nd = npc_name2id(npc_name); + if( var_name[0] != '.' || var_name[1] == '@' ) + {// not a npc variable + ShowError("script: getvariableofnpc: invalid scope %s (not npc variable)\n", var_name); + st->state = END; + return 1; + } + else if( nd == NULL || nd->bl.subtype != SCRIPT || nd->u.scr.script == NULL ) + {// NPC not found or has no script + ShowError("script: getvariableofnpc: can't find npc %s\n", npc_name); + st->state = END; + return 1; + } + else + {// push variable reference + push_val2(st->stack, C_NAME, num, &nd->u.scr.script->script_vars ); } } return 0; } -// [blackhole89] ---> - -// Set a warp portal. +/// Opens a warp portal. +/// Has no "portal opening" effect/sound, it opens the portal immediately. +/// +/// warpportal(<src x>,<src y>,"<target map>",<target x>,<target y>); +/// +/// @author blackhole89 BUILDIN_FUNC(warpportal) { - struct skill_unit_group *group; + int spx; + int spy; unsigned short mapindex; - long spx,spy,tpx,tpy; - struct block_list *bl=map_id2bl(st->oid); - - nullpo_retr(0,bl); + int tpx; + int tpy; + struct skill_unit_group* group; + struct block_list* bl; - spx=conv_num(st, & (st->stack->stack_data[st->start+2])); - spy=conv_num(st, & (st->stack->stack_data[st->start+3])); - mapindex = mapindex_name2id((char*)conv_str(st,& (st->stack->stack_data[st->start+4]))); - printf("mapindex: %d\n",mapindex); - tpx=conv_num(st, & (st->stack->stack_data[st->start+5])); - tpy=conv_num(st, & (st->stack->stack_data[st->start+6])); + bl = map_id2bl(st->oid); + if( bl == NULL ) + { + ShowError("script: warpportal: npc is needed"); + return 1; + } - if(!mapindex) return 0; + spx = conv_num(st, script_getdata(st,2)); + spy = conv_num(st, script_getdata(st,3)); + mapindex = mapindex_name2id(conv_str(st, script_getdata(st,4))); + tpx = conv_num(st, script_getdata(st,5)); + tpy = conv_num(st, script_getdata(st,6)); - if((group=skill_unitsetting(bl,AL_WARP,4,spx,spy,1))==NULL) { - return 0; - } + if( mapindex == 0 ) + return 0;// map not found - group->val2=(tpx<<16)|tpy; + group = skill_unitsetting(bl, AL_WARP, 4, spx, spy, 1); + if( group == NULL ) + return 0;// failed + group->val2 = (tpx<<16) | tpy; group->val3 = mapindex; return 0; } - -// <-- [blackhole89] - |