* Fixed script command sc_end not supporting the extra argument as stated in script_commands.txt.
* Script command getarg supports an extra argument with a default value that is returned if the requested argument doesn't exist. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10773 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
2c86752e59
commit
2d1ad607c3
@ -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.
|
||||
|
||||
2007/06/15
|
||||
* Fixed script command sc_end not supporting the extra argument as stated
|
||||
in script_commands.txt.
|
||||
* Script command getarg supports an extra argument with a default value
|
||||
that is returned if the requested argument doesn't exist. [FlavioJS]
|
||||
2007/06/11
|
||||
* Fixed NPC_PROVOCATION (now the casting mob doesn't keep attacking)
|
||||
* accumulated clif.c fixes [ultramage]
|
||||
|
@ -1402,7 +1402,7 @@ script.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*getarg(<number>)
|
||||
*getarg(<index>{,<default_value>})
|
||||
|
||||
This function is used when you use the 'callsub' or 'callfunc' commands. In the
|
||||
call you can specify variables that will make that call different from another
|
||||
@ -1446,6 +1446,13 @@ You can pass multiple arguments in a function call:
|
||||
|
||||
getarg(0) would be 5, getarg(1) would be 4 and getarg(2) would be 3.
|
||||
|
||||
Getarg has an optional argument since trunk r10773.
|
||||
If the target argument exists, it is returned.
|
||||
Otherwise, if <default_value> is present it is returned instead,
|
||||
if not the script terminates immediately.
|
||||
|
||||
in the previous example getarg(2,-1) would be 3 and getarg(3,-1) would be -1
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*return {<value>};
|
||||
|
253
src/map/script.c
253
src/map/script.c
@ -51,6 +51,16 @@
|
||||
#include <time.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//## TODO possible enhancements:
|
||||
// - 'callfunc' supporting labels in the current npc "::LabelName"
|
||||
// - 'callfunc' supporting labels in other npcs "NpcName::LabelName"
|
||||
// - 'function FuncName;' function declarations reverting to global functions
|
||||
// if local label isn't found
|
||||
// - join callfunc and callsub's functionality
|
||||
|
||||
|
||||
|
||||
//
|
||||
// struct script_state* st;
|
||||
//
|
||||
@ -3910,7 +3920,7 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(callsub,"i*"),
|
||||
BUILDIN_DEF(callfunc,"s*"),
|
||||
BUILDIN_DEF(return,"?"),
|
||||
BUILDIN_DEF(getarg,"i"),
|
||||
BUILDIN_DEF(getarg,"i?"),
|
||||
BUILDIN_DEF(jobchange,"i*"),
|
||||
BUILDIN_DEF(jobname,"i"),
|
||||
BUILDIN_DEF(input,"v"),
|
||||
@ -4031,10 +4041,10 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(disablearena,""), // Added by RoVeRT
|
||||
BUILDIN_DEF(hideoffnpc,"s"),
|
||||
BUILDIN_DEF(hideonnpc,"s"),
|
||||
BUILDIN_DEF(sc_start,"iii*"),
|
||||
BUILDIN_DEF(sc_start2,"iiii*"),
|
||||
BUILDIN_DEF(sc_start4,"iiiiii*"),
|
||||
BUILDIN_DEF(sc_end,"i"),
|
||||
BUILDIN_DEF(sc_start,"iii?"),
|
||||
BUILDIN_DEF(sc_start2,"iiii?"),
|
||||
BUILDIN_DEF(sc_start4,"iiiiii?"),
|
||||
BUILDIN_DEF(sc_end,"i?"),
|
||||
BUILDIN_DEF(getscrate,"ii*"),
|
||||
BUILDIN_DEF(debugmes,"s"),
|
||||
BUILDIN_DEF2(catchpet,"pet","i"),
|
||||
@ -4685,26 +4695,38 @@ BUILDIN_FUNC(callsub)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* 引数の所得
|
||||
*------------------------------------------*/
|
||||
/// Retrieves an argument provided to callfunc/callsub.
|
||||
/// If the argument doesn't exist
|
||||
///
|
||||
/// getarg(<index>{,<default_value>}) -> <value>
|
||||
BUILDIN_FUNC(getarg)
|
||||
{
|
||||
int num=script_getnum(st,2);
|
||||
int max,stsp;
|
||||
if( st->stack->defsp<5 || st->stack->stack_data[st->stack->defsp-1].type!=C_RETINFO ){
|
||||
ShowWarning("script:getarg without callfunc or callsub!\n");
|
||||
st->state=END;
|
||||
int idx;
|
||||
int count;
|
||||
int stsp;
|
||||
|
||||
if( st->stack->defsp < 5 || st->stack->stack_data[st->stack->defsp - 1].type != C_RETINFO )
|
||||
{
|
||||
ShowWarning("script:getarg: no callfunc or callsub!\n");
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
max=conv_num(st,& (st->stack->stack_data[st->stack->defsp-5]));
|
||||
stsp=st->stack->defsp - max -5;
|
||||
if( num >= max ){
|
||||
ShowWarning("script:getarg arg1(%d) out of range(%d) !\n",num,max);
|
||||
st->state=END;
|
||||
count = conv_num(st, &(st->stack->stack_data[st->stack->defsp - 5]));
|
||||
stsp = st->stack->defsp - count - 5;
|
||||
|
||||
idx = script_getnum(st,2);
|
||||
|
||||
if( idx < count )
|
||||
push_copy(st->stack, stsp + idx);
|
||||
else if( script_hasdata(st,3) )
|
||||
script_pushcopy(st, 3);
|
||||
else
|
||||
{
|
||||
ShowWarning("script:getarg: index (idx=%d) out of range (count=%d) and no default value found\n", idx, count);
|
||||
st->state = END;
|
||||
return 1;
|
||||
}
|
||||
push_copy(st->stack,stsp+num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -8175,133 +8197,153 @@ BUILDIN_FUNC(hideonnpc)
|
||||
npc_enable(str,4);
|
||||
return 0;
|
||||
}
|
||||
/*==========================================
|
||||
* 状態異常にかかる
|
||||
*------------------------------------------*/
|
||||
|
||||
/// Starts a status effect on the target unit or on the attached player.
|
||||
///
|
||||
/// sc_start <effect_id>,<duration>,<val1>{,<unit_id>};
|
||||
BUILDIN_FUNC(sc_start)
|
||||
{
|
||||
struct block_list *bl;
|
||||
int type,tick,val1,val4=0;
|
||||
type=script_getnum(st,2);
|
||||
tick=script_getnum(st,3);
|
||||
val1=script_getnum(st,4);
|
||||
if( script_hasdata(st,5) ) //指定したキャラを状態異常にする
|
||||
struct block_list* bl;
|
||||
int type;
|
||||
int tick;
|
||||
int val1;
|
||||
int val4 = 0;
|
||||
|
||||
type = script_getnum(st,2);
|
||||
tick = script_getnum(st,3);
|
||||
val1 = script_getnum(st,4);
|
||||
if( script_hasdata(st,5) )
|
||||
bl = map_id2bl(script_getnum(st,5));
|
||||
else
|
||||
bl = map_id2bl(st->rid);
|
||||
|
||||
if (potion_flag==1 && potion_target) {
|
||||
if( tick == 0 && val1 > 0 && type >= 0 && type < SC_MAX && StatusSkillChangeTable[type] != 0 )
|
||||
{// When there isn't a duration specified, try to get it from the skill_db
|
||||
tick = skill_get_time(StatusSkillChangeTable[type], val1);
|
||||
}
|
||||
|
||||
if( potion_flag == 1 && potion_target )
|
||||
{//##TODO how does this work [FlavioJS]
|
||||
bl = map_id2bl(potion_target);
|
||||
tick/=2; //Thrown potions only last half.
|
||||
val4 = 1; //Mark that this was a thrown sc_effect
|
||||
tick /= 2;// Thrown potions only last half.
|
||||
val4 = 1;// Mark that this was a thrown sc_effect
|
||||
}
|
||||
if (type >= 0 && type < SC_MAX && val1 && !tick)
|
||||
{ //When there isn't a duration specified, try to get it from the skill_db
|
||||
tick = StatusSkillChangeTable[type];
|
||||
if (tick)
|
||||
tick = skill_get_time(tick,val1);
|
||||
else //Failed to retrieve duration, reset to what it was.
|
||||
tick = 0;
|
||||
}
|
||||
if (bl)
|
||||
status_change_start(bl,type,10000,val1,0,0,val4,tick,11);
|
||||
|
||||
if( bl )
|
||||
status_change_start(bl, type, 10000, val1, 0, 0, val4, tick, 1|2|8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* 状態異常にかかる(確率指定)
|
||||
*------------------------------------------*/
|
||||
/// Starts a status effect on the target unit or on the attached player.
|
||||
///
|
||||
/// sc_start2 <effect_id>,<duration>,<val1>,<percent chance>{,<unit_id>};
|
||||
BUILDIN_FUNC(sc_start2)
|
||||
{
|
||||
struct block_list *bl;
|
||||
int type,tick,val1,val4=0,per;
|
||||
type=script_getnum(st,2);
|
||||
tick=script_getnum(st,3);
|
||||
val1=script_getnum(st,4);
|
||||
per=script_getnum(st,5);
|
||||
if( script_hasdata(st,6) ) //指定したキャラを状態異常にする
|
||||
struct block_list* bl;
|
||||
int type;
|
||||
int tick;
|
||||
int val1;
|
||||
int val4 = 0;
|
||||
int rate;
|
||||
|
||||
type = script_getnum(st,2);
|
||||
tick = script_getnum(st,3);
|
||||
val1 = script_getnum(st,4);
|
||||
rate = script_getnum(st,5);
|
||||
if( script_hasdata(st,6) )
|
||||
bl = map_id2bl(script_getnum(st,6));
|
||||
else
|
||||
bl = map_id2bl(st->rid);
|
||||
|
||||
if (type >= 0 && type < SC_MAX && val1 && !tick)
|
||||
{ //When there isn't a duration specified, try to get it from the skill_db
|
||||
tick = StatusSkillChangeTable[type];
|
||||
if (tick)
|
||||
tick = skill_get_time(tick,val1);
|
||||
else //Failed to retrieve duration, reset to what it was.
|
||||
tick = 0;
|
||||
if( tick == 0 && val1 > 0 && type >= 0 && type < SC_MAX && StatusSkillChangeTable[type] != 0 )
|
||||
{// When there isn't a duration specified, try to get it from the skill_db
|
||||
tick = skill_get_time(StatusSkillChangeTable[type], val1);
|
||||
}
|
||||
|
||||
if (potion_flag==1 && potion_target) {
|
||||
if( potion_flag == 1 && potion_target )
|
||||
{//##TODO how does this work [FlavioJS]
|
||||
bl = map_id2bl(potion_target);
|
||||
tick/=2;
|
||||
val4 = 1;
|
||||
tick /= 2;// Thrown potions only last half.
|
||||
val4 = 1;// Mark that this was a thrown sc_effect
|
||||
}
|
||||
|
||||
if(bl)
|
||||
status_change_start(bl,type,per,val1,0,0,val4,tick,11);
|
||||
if( bl )
|
||||
status_change_start(bl, type, rate, val1, 0, 0, val4, tick, 1|2|8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Starts a SC_ change with the four values passed. [Skotlex]
|
||||
* Final optional argument is the ID of player to affect.
|
||||
* sc_start4 type, duration, val1, val2, val3, val4, <id>;
|
||||
*------------------------------------------*/
|
||||
/// Starts a status effect on the target unit or on the attached player.
|
||||
///
|
||||
/// sc_start4 <effect_id>,<duration>,<val1>,<val2>,<val3>,<val4>{,<unit_id>};
|
||||
BUILDIN_FUNC(sc_start4)
|
||||
{
|
||||
struct block_list *bl;
|
||||
int type,tick,val1,val2,val3,val4;
|
||||
type=script_getnum(st,2);
|
||||
tick=script_getnum(st,3);
|
||||
val1=script_getnum(st,4);
|
||||
val2=script_getnum(st,5);
|
||||
val3=script_getnum(st,6);
|
||||
val4=script_getnum(st,7);
|
||||
struct block_list* bl;
|
||||
int type;
|
||||
int tick;
|
||||
int val1;
|
||||
int val2;
|
||||
int val3;
|
||||
int val4;
|
||||
|
||||
type = script_getnum(st,2);
|
||||
tick = script_getnum(st,3);
|
||||
val1 = script_getnum(st,4);
|
||||
val2 = script_getnum(st,5);
|
||||
val3 = script_getnum(st,6);
|
||||
val4 = script_getnum(st,7);
|
||||
if( script_hasdata(st,8) )
|
||||
bl = map_id2bl(script_getnum(st,8));
|
||||
else
|
||||
bl = map_id2bl(st->rid);
|
||||
|
||||
if (type >= 0 && type < SC_MAX && val1 && !tick)
|
||||
{ //When there isn't a duration specified, try to get it from the skill_db
|
||||
tick = StatusSkillChangeTable[type];
|
||||
if (tick)
|
||||
tick = skill_get_time(tick,val1);
|
||||
else //Failed to retrieve duration, reset to what it was.
|
||||
tick = 0;
|
||||
if( tick == 0 && val1 > 0 && type >= 0 && type < SC_MAX && StatusSkillChangeTable[type] != 0 )
|
||||
{// When there isn't a duration specified, try to get it from the skill_db
|
||||
tick = skill_get_time(StatusSkillChangeTable[type], val1);
|
||||
}
|
||||
|
||||
if (potion_flag==1 && potion_target) {
|
||||
if( potion_flag == 1 && potion_target )
|
||||
{//##TODO how does this work [FlavioJS]
|
||||
bl = map_id2bl(potion_target);
|
||||
tick/=2;
|
||||
tick /= 2;// Thrown potions only last half.
|
||||
}
|
||||
if (bl)
|
||||
status_change_start(bl,type,10000,val1,val2,val3,val4,tick,11);
|
||||
|
||||
if( bl )
|
||||
status_change_start(bl, type, 10000, val1, val2, val3, val4, tick, 1|2|8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* 状態異常が直る
|
||||
*------------------------------------------*/
|
||||
/// Ends one or all status effects on the target unit or on the attached player.
|
||||
///
|
||||
/// sc_end <effect_id>{,<unit_id>};
|
||||
BUILDIN_FUNC(sc_end)
|
||||
{
|
||||
struct block_list *bl;
|
||||
struct block_list* bl;
|
||||
int type;
|
||||
type=script_getnum(st,2);
|
||||
bl = map_id2bl(st->rid);
|
||||
|
||||
if (potion_flag==1 && potion_target)
|
||||
bl = map_id2bl(potion_target);
|
||||
|
||||
if (!bl) return 0;
|
||||
if (type >= 0)
|
||||
status_change_end(bl,type,-1);
|
||||
type = script_getnum(st,2);
|
||||
if( script_hasdata(st,3) )
|
||||
bl = map_id2bl(script_getnum(st,3));
|
||||
else
|
||||
status_change_clear(bl, 2);
|
||||
bl = map_id2bl(st->rid);
|
||||
|
||||
if( potion_flag==1 && potion_target )
|
||||
{//##TODO how does this work [FlavioJS]
|
||||
bl = map_id2bl(potion_target);
|
||||
}
|
||||
|
||||
if( bl )
|
||||
{
|
||||
if( type >= 0 )
|
||||
status_change_end(bl, type, INVALID_TIMER);
|
||||
else
|
||||
status_change_clear(bl, 2);// remove all effects
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* 状態異常耐性を計算した確率を返す
|
||||
*------------------------------------------*/
|
||||
@ -13050,12 +13092,13 @@ BUILDIN_FUNC(unittalk)
|
||||
bl = map_id2bl(unit_id);
|
||||
if( bl != NULL )
|
||||
{
|
||||
struct StringBuf* buf = StringBuf_Malloc();
|
||||
StringBuf_Printf(buf, "%s : %s", status_get_name(bl), message);
|
||||
clif_message(bl, StringBuf_Value(buf));
|
||||
struct StringBuf sbuf;
|
||||
StringBuf_Init(&sbuf);
|
||||
StringBuf_Printf(&sbuf, "%s : %s", status_get_name(bl), message);
|
||||
clif_message(bl, StringBuf_Value(&sbuf));
|
||||
if( bl->type == BL_PC )
|
||||
clif_displaymessage(((TBL_PC*)bl)->fd, StringBuf_Value(buf));
|
||||
StringBuf_Free(buf);
|
||||
clif_displaymessage(((TBL_PC*)bl)->fd, StringBuf_Value(&sbuf));
|
||||
StringBuf_Destroy(&sbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -6072,9 +6072,9 @@ int status_change_clear(struct block_list *bl,int type)
|
||||
case SC_JAILED:
|
||||
continue;
|
||||
}
|
||||
status_change_end(bl, i, -1);
|
||||
status_change_end(bl, i, INVALID_TIMER);
|
||||
|
||||
if (type == 1 && sc->data[i].timer != -1)
|
||||
if( type == 1 && sc->data[i].timer != INVALID_TIMER )
|
||||
{ //If for some reason status_change_end decides to still keep the status when quitting. [Skotlex]
|
||||
(sc->count)--;
|
||||
delete_timer(sc->data[i].timer, status_change_timer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user