- Updated the Dancer job quest to attach a player to the main timer script.

- Updated script commands startnpctimer, stopnpctimer, initnpctimer so you can attach a player to them, this is done because the attach/detach functions can't be used to attach to a different script than the one currently running.
- Some script code cleaning
- Updated the script_command reference with the new flag values of [start/stop/init]npctimer.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9872 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2007-02-16 20:53:05 +00:00
parent dddd48f15d
commit 5ed686f6a8
5 changed files with 139 additions and 55 deletions

View File

@ -4,6 +4,12 @@ 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/16
* Updated script commands startnpctimer, stopnpctimer, initnpctimer so you
can attach a player to them, this is done because the attach/detach
functions can't be used to attach to a different script than the one
currently running.
* Updated the script_command reference with the new flag values of
[start/stop/init]npctimer.
* Modified the "guardian" spawn script command, it no longer receives a
"amount" argument (since that only leads to trouble), if the class is
negative, it'll pick a random class the same way the monster spawn script

View File

@ -59,6 +59,10 @@
//= 3.02.20070209
//= Corrected/updated info on Xor/setd/getd/callfunc/callsub/return and
//= updated some examples to use "better" code. [FlavioJS]
//= 3.03.20070216
//= Expanded/clarified information on npc timers, added info about the
//= new attach flag for script commands startnpctimer/ stopnpctimer/
//= initnpctimer [Skotlex]
//===== Compatible With ===================================
//= LOL, can be used by anyone hopefully
//===== Description =======================================
@ -4815,9 +4819,12 @@ is.
---------------------------------------
*initnpctimer{ "<NPC object name>"};
*stopnpctimer{ "<NPC object name>"};
*startnpctimer{ "<NPC object name>"};
*initnpctimer{ "<NPC object name>" {, <Attach Flag>} } |
{"<NPC object name>" | <Attach Flag> };
*stopnpctimer{ "<NPC object name>" {, <Detach Flag>} } |
{ "<NPC object name>" | <Detach Flag> };
*startnpctimer{ "<NPC object name>" {, <Attach Flag>} } |
{ "<NPC object name>" | <Attach Flag> };
*setnpctimer <tick>{,"<NPC object name>"};
*getnpctimer(<type of information>{,"<NPC object name>"});
*attachnpctimer {"<character name>"};
@ -4844,17 +4851,19 @@ To create the timer, use the 'initnpctimer', which will start it running.
'stopnpctimer' will pause the timer, without clearing the current tick, while
'startnpctimer' will let the paused timer continue.
It is not quite clear whether the new invocations will always have a RID.
Apparently, the RID that was in effect when the timer was initialised will still
be attached to these executions in some cases, but it's not quite clear -
experiment with RID-dependent commands, like 'mes', and tell us what happens and
who gets the message, if anyone.
By default timers do not have a RID attached, which lets the timers continue even
if the player that started them logs off. To attach a RID to a timer, you can
either use the "attach flag" optional value when using initnpctimer/startnpctimer,
likewise, the optional flag of stopnpctimer detaches any RID after stopping
the timer. One a player is attached to a timer, it stays attached to all
timers from that script until detached manually. You can have multiple
npctimers going on at the same time as long as each one has a different player
attached (think of each RID being used as an independant timer).
Even if they don't have a RID by default, 'attachnpctimer' will allow you to
explicitly attach a character's RID to the timer, which will make them the
target for all character-referencing commands and functions, not to mention
variables. 'detachnpctimer' will make the RID zero, making all character-
referencing functions fail with an error.
The other method to attach/detach a RID is through the script commands
'attachnpctimer' and 'detachnpctimer'. Once attached, that will make the
character the target for all character-referencing commands and functions,
not to mention variables.
'setnpctimer' will explicitly set the timer to a given tick. To make it useful,
you will need the 'getnpctimer' function, which the type of information argument

View File

@ -26,7 +26,8 @@ KarLaeda
Date Added
======
2007/02/17
2007/02/16
* Updated the Dancer job quest to attach a player to the main timer script.
* Updated WoE scripts since the "guardian" script command no longer has a
"amount" argument. [Skotlex]
2007/02/15

View File

@ -4,7 +4,7 @@
//= Kalen - Original jAthena
//= Fredzilla - Converted
//===== Current Version: =====================================
//= 2.2
//= 2.3
//===== Compatible With: =====================================
//= eAthena Final
//===== Description: =========================================
@ -24,6 +24,7 @@
//= 2.0 Changed numbers to constants. [Vicious]
//= 2.1 Script check #1. [Lance]
//= 2.2 Fixed unpassable part, thx2 Alis [Lupus]
//= 2.3 Updated initnpctimer to attach player to jobDq script [Skotlex]
//============================================================
//= Warning Warp to escape the quest if need be
@ -689,7 +690,7 @@ job_duncer.gat,32,152,6 script Guide::dancew 69,{
OnWarp:
warpwaitingpc "job_duncer.gat",70,112,1;
disablewaitingroomevent;
initnpctimer "jobDq";
initnpctimer "jobDq",1;
end;
OnInit:
waitingroom "Dance lesson waiting room",20,"dancew::OnWarp",1;
@ -1052,6 +1053,6 @@ OnInit:
// close;
//Lgo:
// warp "job_duncer.gat",70,112;
// initnpctimer "jobDq";
// initnpctimer "jobDq",1;
// end;
//}

View File

@ -3922,13 +3922,13 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(addtimer,"is"),
BUILDIN_DEF(deltimer,"s"),
BUILDIN_DEF(addtimercount,"si"),
BUILDIN_DEF(initnpctimer,"*"),
BUILDIN_DEF(stopnpctimer,"*"),
BUILDIN_DEF(startnpctimer,"*"),
BUILDIN_DEF(setnpctimer,"*"),
BUILDIN_DEF(getnpctimer,"i*"),
BUILDIN_DEF(attachnpctimer,"*"), // attached the player id to the npc timer [Celest]
BUILDIN_DEF(detachnpctimer,"*"), // detached the player id from the npc timer [Celest]
BUILDIN_DEF(initnpctimer,"??"),
BUILDIN_DEF(stopnpctimer,"??"),
BUILDIN_DEF(startnpctimer,"??"),
BUILDIN_DEF(setnpctimer,"i?"),
BUILDIN_DEF(getnpctimer,"i?"),
BUILDIN_DEF(attachnpctimer,"?"), // attached the player id to the npc timer [Celest]
BUILDIN_DEF(detachnpctimer,"?"), // detached the player id from the npc timer [Celest]
BUILDIN_DEF(playerattached,""), // returns id of the current attached player. [Skotlex]
BUILDIN_DEF(announce,"si*"),
BUILDIN_DEF(mapannounce,"ssi*"),
@ -7342,8 +7342,8 @@ BUILDIN_FUNC(addtimer)
{
char *event;
int tick;
tick=conv_num(st,& (st->stack->stack_data[st->start+2]));
event=conv_str(st,& (st->stack->stack_data[st->start+3]));
tick=conv_num(st, script_getdata(st,2));
event=conv_str(st, script_getdata(st,3));
check_event(st, event);
pc_addeventtimer(script_rid2sd(st),tick,event);
return 0;
@ -7355,7 +7355,7 @@ BUILDIN_FUNC(addtimer)
BUILDIN_FUNC(deltimer)
{
char *event;
event=conv_str(st,& (st->stack->stack_data[st->start+2]));
event=conv_str(st, script_getdata(st,2));
check_event(st, event);
pc_deleventtimer(script_rid2sd(st),event);
return 0;
@ -7368,8 +7368,8 @@ BUILDIN_FUNC(addtimercount)
{
char *event;
int tick;
event=conv_str(st,& (st->stack->stack_data[st->start+2]));
tick=conv_num(st,& (st->stack->stack_data[st->start+3]));
event=conv_str(st, script_getdata(st,2));
tick=conv_num(st, script_getdata(st,3));
check_event(st, event);
pc_addeventtimercount(script_rid2sd(st),event,tick);
return 0;
@ -7382,11 +7382,35 @@ BUILDIN_FUNC(addtimercount)
BUILDIN_FUNC(initnpctimer)
{
struct npc_data *nd;
if( st->end > st->start+2 )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2])));
else
int flag = 0;
if( script_hasdata(st,3) )
{ //Two arguments: NPC name and attach flag.
nd = npc_name2id(conv_str(st, script_getdata(st,2)));
flag = conv_num(st, script_getdata(st,3));
} else
if( script_hasdata(st,2) )
{ //Check if argument is numeric (flag) or string (npc name)
struct script_data *data;
data = script_getdata(st,2);
get_val(st,data);
if( data_isstring(data) ) //NPC name
nd = npc_name2id(conv_str(st, script_getdata(st,2)));
else if( data_isint(data) ) { //Flag
nd = (struct npc_data *)map_id2bl(st->oid);
flag = conv_num(st, script_getdata(st,3));
} else {
ShowError("initnpctimer: invalid argument type #1 (needs be int or string)).\n");
return 1;
}
} else
nd=(struct npc_data *)map_id2bl(st->oid);
if (!nd) return 0;
if (flag) { //Attach
TBL_PC* sd = script_rid2sd(st);
if (sd) nd->u.scr.rid = sd->bl.id;
}
npc_settimerevent_tick(nd,0);
npc_timerevent_start(nd, st->rid);
return 0;
@ -7398,11 +7422,35 @@ BUILDIN_FUNC(initnpctimer)
BUILDIN_FUNC(startnpctimer)
{
struct npc_data *nd;
if( st->end > st->start+2 )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2])));
else
int flag = 0;
if( script_hasdata(st,3) )
{ //Two arguments: NPC name and attach flag.
nd = npc_name2id(conv_str(st, script_getdata(st,2)));
flag = conv_num(st, script_getdata(st,3));
} else
if( script_hasdata(st,2) )
{ //Check if argument is numeric (flag) or string (npc name)
struct script_data *data;
data = script_getdata(st,2);
get_val(st,data);
if( data_isstring(data) ) //NPC name
nd = npc_name2id(conv_str(st, script_getdata(st,2)));
else if( data_isint(data) ) { //Flag
nd = (struct npc_data *)map_id2bl(st->oid);
flag = conv_num(st, script_getdata(st,3));
} else {
ShowError("startnpctimer: invalid argument type #1 (needs be int or string)).\n");
return 1;
}
} else
nd=(struct npc_data *)map_id2bl(st->oid);
if (!nd) return 0;
if (flag) { //Attach
TBL_PC* sd = script_rid2sd(st);
if (sd) nd->u.scr.rid = sd->bl.id;
}
npc_timerevent_start(nd, st->rid);
return 0;
}
@ -7413,11 +7461,33 @@ BUILDIN_FUNC(startnpctimer)
BUILDIN_FUNC(stopnpctimer)
{
struct npc_data *nd;
if( st->end > st->start+2 )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2])));
else
int flag = 0;
if( script_hasdata(st,3) )
{ //Two arguments: NPC name and attach flag.
nd = npc_name2id(conv_str(st, script_getdata(st,2)));
flag = conv_num(st, script_getdata(st,3));
} else
if( script_hasdata(st,2) )
{ //Check if argument is numeric (flag) or string (npc name)
struct script_data *data;
data = script_getdata(st,2);
get_val(st,data);
if( data_isstring(data) ) //NPC name
nd = npc_name2id(conv_str(st, script_getdata(st,2)));
else if( data_isint(data) ) { //Flag
nd = (struct npc_data *)map_id2bl(st->oid);
flag = conv_num(st, script_getdata(st,3));
} else {
ShowError("stopnpctimer: invalid argument type #1 (needs be int or string)).\n");
return 1;
}
} else
nd=(struct npc_data *)map_id2bl(st->oid);
if (!nd) return 0;
if (flag) //Detach
nd->u.scr.rid = 0;
npc_timerevent_stop(nd);
return 0;
}
@ -7429,12 +7499,12 @@ BUILDIN_FUNC(getnpctimer)
{
struct npc_data *nd;
struct map_session_data *sd;
int type=conv_num(st,& (st->stack->stack_data[st->start+2]));
int type=conv_num(st, script_getdata(st,2));
int val=0;
if( st->end > st->start+3 )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+3])));
if( script_hasdata(st,3) )
nd = npc_name2id(conv_str(st,script_getdata(st,3)));
else
nd=(struct npc_data *)map_id2bl(st->oid);
nd = (struct npc_data *)map_id2bl(st->oid);
if (!nd || nd->bl.type != BL_NPC)
{
@ -7471,9 +7541,9 @@ BUILDIN_FUNC(setnpctimer)
{
int tick;
struct npc_data *nd;
tick=conv_num(st,& (st->stack->stack_data[st->start+2]));
if( st->end > st->start+3 )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+3])));
tick=conv_num(st,script_getdata(st,2));
if( script_hasdata(st,3) )
nd=npc_name2id(conv_str(st,script_getdata(st,3)));
else
nd=(struct npc_data *)map_id2bl(st->oid);
@ -7491,12 +7561,10 @@ BUILDIN_FUNC(attachnpctimer)
struct npc_data *nd;
nd=(struct npc_data *)map_id2bl(st->oid);
if( st->end > st->start+2 ) {
char *name = conv_str(st,& (st->stack->stack_data[st->start+2]));
sd=map_nick2sd(name);
} else {
if( script_hasdata(st,2) )
sd=map_nick2sd(conv_str(st,script_getdata(st,2)));
else
sd = script_rid2sd(st);
}
if (sd==NULL)
return 0;
@ -7512,8 +7580,8 @@ BUILDIN_FUNC(attachnpctimer)
BUILDIN_FUNC(detachnpctimer)
{
struct npc_data *nd;
if( st->end > st->start+2 )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2])));
if( script_hasdata(st,2) )
nd=npc_name2id(conv_str(st,script_getdata(st,2)));
else
nd=(struct npc_data *)map_id2bl(st->oid);
@ -7524,13 +7592,12 @@ BUILDIN_FUNC(detachnpctimer)
/*==========================================
* To avoid "player not attached" script errors, this function is provided,
* it checks if there is a player attached to the current script. [Skotlex]
* If no, returns 0, if yes, returns the char_id of the attached player.
* If no, returns 0, if yes, returns the account_id of the attached player.
*------------------------------------------
*/
BUILDIN_FUNC(playerattached)
{
struct map_session_data *sd;
if (st->rid == 0 || (sd = map_id2sd(st->rid)) == NULL)
if(st->rid == 0 || map_id2sd(st->rid) == NULL)
push_val(st->stack,C_INT,0);
else
push_val(st->stack,C_INT,st->rid);