* 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.
|
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.
|
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
|
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]
|
* 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
|
2008/11/07
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
//= A reference manual for the eAthena scripting language.
|
//= A reference manual for the eAthena scripting language.
|
||||||
//= Commands are sorted depending on their functionality.
|
//= Commands are sorted depending on their functionality.
|
||||||
//===== Version ===========================================
|
//===== Version ===========================================
|
||||||
//= 3.23.20080909
|
//= 3.34.20081111
|
||||||
//=========================================================
|
//=========================================================
|
||||||
//= 1.0 - First release, filled will as much info as I could
|
//= 1.0 - First release, filled will as much info as I could
|
||||||
//= remember or figure out, most likely there are errors,
|
//= remember or figure out, most likely there are errors,
|
||||||
@ -124,6 +124,8 @@
|
|||||||
//= Adjusted the 'getequipname' description to match src [ultramage]
|
//= Adjusted the 'getequipname' description to match src [ultramage]
|
||||||
//= 3.23.20080909
|
//= 3.23.20080909
|
||||||
//= Added WoE SE related commands. [L0ne_W0lf]
|
//= 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
|
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
|
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 -
|
notable exception is Zeny, which you can and often will address directly -
|
||||||
setting it will make the character own this number of zeny.
|
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
|
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 id>,<amount>{,<account ID>};
|
||||||
*delitem "<item name>",<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
|
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
|
'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
|
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 502,10 // The person will lose 10 apples
|
||||||
delitem 617,1 // The person will lose 1 Old Violet Box
|
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
|
It is always a good idea to check if the player actually has the items before you delete them.
|
||||||
you take it from them, Otherwise, you could try to delete items which the
|
If you try to delete more items that the player has, the player will lose the ones he/she has
|
||||||
players don't actually have, which won't fail and won't give an error message,
|
and the script will be terminated with an error.
|
||||||
but might open up ways to exploit your script.
|
|
||||||
|
|
||||||
Like 'getitem' this command will also accept an 'english name' field from the
|
Like 'getitem' this command will also accept an 'english name' field from the
|
||||||
database. If the name is not found, nothing will be deleted.
|
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 id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<account ID>};
|
||||||
*delitem2 "<Item name>",<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.
|
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;
|
sd->status.status_point = val;
|
||||||
break;
|
break;
|
||||||
case SP_ZENY:
|
case SP_ZENY:
|
||||||
|
if( val < 0 )
|
||||||
|
return 0;// can't set negative zeny
|
||||||
sd->status.zeny = cap_value(val, 0, MAX_ZENY);
|
sd->status.zeny = cap_value(val, 0, MAX_ZENY);
|
||||||
break;
|
break;
|
||||||
case SP_BASEEXP:
|
case SP_BASEEXP:
|
||||||
|
132
src/map/script.c
132
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
|
{// integer variable
|
||||||
int val = (int)value;
|
int val = (int)value;
|
||||||
if(str_data[num&0x00ffffff].type == C_PARAM)
|
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) {
|
switch (prefix) {
|
||||||
case '@':
|
case '@':
|
||||||
@ -5367,9 +5379,12 @@ BUILDIN_FUNC(makeitem)
|
|||||||
|
|
||||||
return 0;
|
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)
|
BUILDIN_FUNC(delitem)
|
||||||
{
|
{
|
||||||
int nameid=0,amount,i,important_item=0;
|
int nameid=0,amount,i,important_item=0;
|
||||||
@ -5377,30 +5392,45 @@ BUILDIN_FUNC(delitem)
|
|||||||
struct script_data *data;
|
struct script_data *data;
|
||||||
|
|
||||||
if( script_hasdata(st,4) )
|
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
|
else
|
||||||
sd=script_rid2sd(st); // Attached player
|
{
|
||||||
|
sd = script_rid2sd(st);// attached player
|
||||||
if( sd == NULL ) // no target
|
if( sd == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
data = script_getdata(st,2);
|
data = script_getdata(st,2);
|
||||||
get_val(st,data);
|
get_val(st,data);
|
||||||
if( data_isstring(data) ){
|
if( data_isstring(data) )
|
||||||
const char *name=conv_str(st,data);
|
{
|
||||||
struct item_data *item_data = itemdb_searchname(name);
|
const char* item_name = conv_str(st,data);
|
||||||
//nameid=UNKNOWN_ITEM_ID;
|
struct item_data* id = itemdb_searchname(item_name);
|
||||||
if( item_data )
|
if( id == NULL )
|
||||||
nameid=item_data->nameid;
|
{
|
||||||
}else
|
ShowError("script:delitem: unknown item \"%s\".\n", item_name);
|
||||||
nameid=conv_num(st,data);
|
st->state = END;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
nameid = id->nameid;// "<item name>"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nameid = conv_num(st,data);// <item id>
|
||||||
|
|
||||||
amount=script_getnum(st,3);
|
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
|
if( amount <= 0 )
|
||||||
//eprintf("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount);
|
return 0;// nothing to do
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//1st pass
|
//1st pass
|
||||||
//here we won't delete items with CARDS, named items but we count them
|
//here we won't delete items with CARDS, named items but we count them
|
||||||
for(i=0;i<MAX_INVENTORY;i++){
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==========================================
|
/// Deletes items from the target/attached player.
|
||||||
* advanced version of delitem [modified by Mihilion]
|
///
|
||||||
*------------------------------------------*/
|
/// 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)
|
BUILDIN_FUNC(delitem2)
|
||||||
{
|
{
|
||||||
int nameid=0,amount,i=0;
|
int nameid=0,amount,i=0;
|
||||||
@ -5487,23 +5520,39 @@ BUILDIN_FUNC(delitem2)
|
|||||||
struct script_data *data;
|
struct script_data *data;
|
||||||
|
|
||||||
if( script_hasdata(st,11) )
|
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
|
else
|
||||||
sd=script_rid2sd(st); // Attached player
|
{
|
||||||
|
sd = script_rid2sd(st);// attached player
|
||||||
if( sd == NULL ) // no target
|
if( sd == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
data = script_getdata(st,2);
|
data = script_getdata(st,2);
|
||||||
get_val(st,data);
|
get_val(st,data);
|
||||||
if( data_isstring(data) ){
|
if( data_isstring(data) )
|
||||||
const char *name=conv_str(st,data);
|
{
|
||||||
struct item_data *item_data = itemdb_searchname(name);
|
const char* item_name = conv_str(st,data);
|
||||||
//nameid=UNKNOWN_ITEM_ID;
|
struct item_data* id = itemdb_searchname(item_name);
|
||||||
if( item_data )
|
if( id == NULL )
|
||||||
nameid=item_data->nameid;
|
{
|
||||||
}else
|
ShowError("script:delitem2: unknown item \"%s\".\n", item_name);
|
||||||
nameid=conv_num(st,data);
|
st->state = END;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
nameid = id->nameid;// "<item name>"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nameid = conv_num(st,data);// <item id>
|
||||||
|
|
||||||
amount=script_getnum(st,3);
|
amount=script_getnum(st,3);
|
||||||
iden=script_getnum(st,4);
|
iden=script_getnum(st,4);
|
||||||
@ -5514,10 +5563,8 @@ BUILDIN_FUNC(delitem2)
|
|||||||
c3=script_getnum(st,9);
|
c3=script_getnum(st,9);
|
||||||
c4=script_getnum(st,10);
|
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
|
if( amount <= 0 )
|
||||||
//eprintf("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount);
|
return 0;// nothing to do
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0;i<MAX_INVENTORY;i++){
|
for(i=0;i<MAX_INVENTORY;i++){
|
||||||
//we don't delete wrong item or equipped item
|
//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);
|
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