summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt5
-rw-r--r--src/map/atcommand.c12
-rw-r--r--src/map/clif.c22
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/map.h3
-rw-r--r--src/map/pc.c36
-rw-r--r--src/map/script.c154
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]
-