* Updated script_commands.txt
* Made scripts terminate with an error: (fixes bugreport:2429) - when getitem/getitem2 tries to delete more items than the player has - when trying to set Zeny to a negative number. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13368 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
227444c5d6
commit
f74b445add
@ -3,6 +3,11 @@ Date Added
|
||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2008/11/11
|
||||
* Updated script_commands.txt [FlavioJS]
|
||||
* Made scripts terminate with an error: (fixes bugreport:2429)
|
||||
- when getitem/getitem2 tries to delete more items than the player has
|
||||
- when trying to set Zeny to a negative number.
|
||||
2008/11/09
|
||||
* Added a check to make sure killed monster's level was greater than half of the mercenary owner's level before incrementing mercenary's killcount. (bugreport:2410) [Paradox924X]
|
||||
2008/11/07
|
||||
|
@ -4,7 +4,7 @@
|
||||
//= A reference manual for the eAthena scripting language.
|
||||
//= Commands are sorted depending on their functionality.
|
||||
//===== Version ===========================================
|
||||
//= 3.23.20080909
|
||||
//= 3.34.20081111
|
||||
//=========================================================
|
||||
//= 1.0 - First release, filled will as much info as I could
|
||||
//= remember or figure out, most likely there are errors,
|
||||
@ -124,6 +124,8 @@
|
||||
//= Adjusted the 'getequipname' description to match src [ultramage]
|
||||
//= 3.23.20080909
|
||||
//= Added WoE SE related commands. [L0ne_W0lf]
|
||||
//= 3.34.20081111
|
||||
//= Changed the error behaviour of delitem/delitem2/Zeny. [FlavioJS]
|
||||
//=========================================================
|
||||
|
||||
This document is a reference manual for all the scripting commands and functions
|
||||
@ -631,6 +633,7 @@ not certain whether this will work for all of them. Whenever there is a command
|
||||
or a function to set something, it's usually preferable to use that instead. The
|
||||
notable exception is Zeny, which you can and often will address directly -
|
||||
setting it will make the character own this number of zeny.
|
||||
If you try to set Zeny to a negative number, the script will be terminated with an error.
|
||||
|
||||
Strings
|
||||
-------
|
||||
@ -3872,7 +3875,7 @@ If the map name is given as "this", the map the invoking character is on will be
|
||||
*delitem <item id>,<amount>{,<account ID>};
|
||||
*delitem "<item name>",<amount>{,<account ID>};
|
||||
|
||||
This command will take a specified amount of items from the invoking character.
|
||||
This command will take a specified amount of items from the invoking/target character.
|
||||
As all the item commands, this one uses the ID of the item found inside
|
||||
'db/item_db.txt'. The items are destroyed - there is no way an NPC can simply
|
||||
own items and have an inventory of them, other as by destroying and recreating
|
||||
@ -3881,10 +3884,9 @@ them when needed.
|
||||
delitem 502,10 // The person will lose 10 apples
|
||||
delitem 617,1 // The person will lose 1 Old Violet Box
|
||||
|
||||
It is always a good idea to to check if the player actually has the item before
|
||||
you take it from them, Otherwise, you could try to delete items which the
|
||||
players don't actually have, which won't fail and won't give an error message,
|
||||
but might open up ways to exploit your script.
|
||||
It is always a good idea to check if the player actually has the items before you delete them.
|
||||
If you try to delete more items that the player has, the player will lose the ones he/she has
|
||||
and the script will be terminated with an error.
|
||||
|
||||
Like 'getitem' this command will also accept an 'english name' field from the
|
||||
database. If the name is not found, nothing will be deleted.
|
||||
@ -3894,7 +3896,7 @@ database. If the name is not found, nothing will be deleted.
|
||||
*delitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
*delitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||
|
||||
This command will take a specified amount of items from the invoking character.
|
||||
This command will take a specified amount of items from the invoking/target character.
|
||||
Check 'getitem2' to understand its expanded parameters.
|
||||
|
||||
---------------------------------------
|
||||
|
@ -5399,6 +5399,8 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
|
||||
sd->status.status_point = val;
|
||||
break;
|
||||
case SP_ZENY:
|
||||
if( val < 0 )
|
||||
return 0;// can't set negative zeny
|
||||
sd->status.zeny = cap_value(val, 0, MAX_ZENY);
|
||||
break;
|
||||
case SP_BASEEXP:
|
||||
|
140
src/map/script.c
140
src/map/script.c
@ -2273,7 +2273,19 @@ static int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* nam
|
||||
{// integer variable
|
||||
int val = (int)value;
|
||||
if(str_data[num&0x00ffffff].type == C_PARAM)
|
||||
return pc_setparam(sd, str_data[num&0x00ffffff].val, val);
|
||||
{
|
||||
if( pc_setparam(sd, str_data[num&0x00ffffff].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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (prefix) {
|
||||
case '@':
|
||||
@ -5367,9 +5379,12 @@ BUILDIN_FUNC(makeitem)
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*==========================================
|
||||
* script DELITEM command (fixed 2 bugs by Lupus, added deletion priority by Lupus)
|
||||
*------------------------------------------*/
|
||||
|
||||
/// Deletes items from the target/attached player.
|
||||
/// Prioritizes ordinary items.
|
||||
///
|
||||
/// delitem <item id>,<amount>{,<account id>}
|
||||
/// delitem "<item name>",<amount>{,<account id>}
|
||||
BUILDIN_FUNC(delitem)
|
||||
{
|
||||
int nameid=0,amount,i,important_item=0;
|
||||
@ -5377,30 +5392,45 @@ BUILDIN_FUNC(delitem)
|
||||
struct script_data *data;
|
||||
|
||||
if( script_hasdata(st,4) )
|
||||
sd=map_id2sd(script_getnum(st,4)); // <Account ID>
|
||||
{
|
||||
int account_id = script_getnum(st,4);
|
||||
sd = map_id2sd(account_id); // <account id>
|
||||
if( sd == NULL )
|
||||
{
|
||||
ShowError("script:delitem: player not found (AID=%d).\n", account_id);
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
{
|
||||
sd = script_rid2sd(st);// attached player
|
||||
if( sd == NULL )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( sd == NULL ) // no target
|
||||
return 0;
|
||||
|
||||
data=script_getdata(st,2);
|
||||
data = script_getdata(st,2);
|
||||
get_val(st,data);
|
||||
if( data_isstring(data) ){
|
||||
const char *name=conv_str(st,data);
|
||||
struct item_data *item_data = itemdb_searchname(name);
|
||||
//nameid=UNKNOWN_ITEM_ID;
|
||||
if( item_data )
|
||||
nameid=item_data->nameid;
|
||||
}else
|
||||
nameid=conv_num(st,data);
|
||||
if( data_isstring(data) )
|
||||
{
|
||||
const char* item_name = conv_str(st,data);
|
||||
struct item_data* id = itemdb_searchname(item_name);
|
||||
if( id == NULL )
|
||||
{
|
||||
ShowError("script:delitem: unknown item \"%s\".\n", item_name);
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
nameid = id->nameid;// "<item name>"
|
||||
}
|
||||
else
|
||||
nameid = conv_num(st,data);// <item id>
|
||||
|
||||
amount=script_getnum(st,3);
|
||||
|
||||
if (nameid<500 || amount<=0 ) {//by Lupus. Don't run FOR if u got wrong item ID or amount<=0
|
||||
//eprintf("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount);
|
||||
return 0;
|
||||
}
|
||||
if( amount <= 0 )
|
||||
return 0;// nothing to do
|
||||
|
||||
//1st pass
|
||||
//here we won't delete items with CARDS, named items but we count them
|
||||
for(i=0;i<MAX_INVENTORY;i++){
|
||||
@ -5473,12 +5503,15 @@ BUILDIN_FUNC(delitem)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).\n", amount, sd->status.account_id, nameid);
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* advanced version of delitem [modified by Mihilion]
|
||||
*------------------------------------------*/
|
||||
/// Deletes items from the target/attached player.
|
||||
///
|
||||
/// delitem2 <item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
|
||||
/// delitem2 "<Item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>}
|
||||
BUILDIN_FUNC(delitem2)
|
||||
{
|
||||
int nameid=0,amount,i=0;
|
||||
@ -5487,23 +5520,39 @@ BUILDIN_FUNC(delitem2)
|
||||
struct script_data *data;
|
||||
|
||||
if( script_hasdata(st,11) )
|
||||
sd=map_id2sd(script_getnum(st,11)); // <Account ID>
|
||||
{
|
||||
int account_id = script_getnum(st,11);
|
||||
sd = map_id2sd(account_id); // <account id>
|
||||
if( sd == NULL )
|
||||
{
|
||||
ShowError("script:delitem2: player not found (AID=%d).\n", account_id);
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
sd=script_rid2sd(st); // Attached player
|
||||
{
|
||||
sd = script_rid2sd(st);// attached player
|
||||
if( sd == NULL )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( sd == NULL ) // no target
|
||||
return 0;
|
||||
|
||||
data=script_getdata(st,2);
|
||||
data = script_getdata(st,2);
|
||||
get_val(st,data);
|
||||
if( data_isstring(data) ){
|
||||
const char *name=conv_str(st,data);
|
||||
struct item_data *item_data = itemdb_searchname(name);
|
||||
//nameid=UNKNOWN_ITEM_ID;
|
||||
if( item_data )
|
||||
nameid=item_data->nameid;
|
||||
}else
|
||||
nameid=conv_num(st,data);
|
||||
if( data_isstring(data) )
|
||||
{
|
||||
const char* item_name = conv_str(st,data);
|
||||
struct item_data* id = itemdb_searchname(item_name);
|
||||
if( id == NULL )
|
||||
{
|
||||
ShowError("script:delitem2: unknown item \"%s\".\n", item_name);
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
nameid = id->nameid;// "<item name>"
|
||||
}
|
||||
else
|
||||
nameid = conv_num(st,data);// <item id>
|
||||
|
||||
amount=script_getnum(st,3);
|
||||
iden=script_getnum(st,4);
|
||||
@ -5514,10 +5563,8 @@ BUILDIN_FUNC(delitem2)
|
||||
c3=script_getnum(st,9);
|
||||
c4=script_getnum(st,10);
|
||||
|
||||
if (!itemdb_exists(nameid) || amount<=0 ) {//by Lupus. Don't run FOR if u got wrong item ID or amount<=0
|
||||
//eprintf("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount);
|
||||
return 0;
|
||||
}
|
||||
if( amount <= 0 )
|
||||
return 0;// nothing to do
|
||||
|
||||
for(i=0;i<MAX_INVENTORY;i++){
|
||||
//we don't delete wrong item or equipped item
|
||||
@ -5553,7 +5600,10 @@ BUILDIN_FUNC(delitem2)
|
||||
pc_delitem(sd,i,sd->status.inventory[i].amount,0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).\n", amount, sd->status.account_id, nameid);
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
|
Loading…
x
Reference in New Issue
Block a user