- 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. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2007/02/16 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 * Modified the "guardian" spawn script command, it no longer receives a
"amount" argument (since that only leads to trouble), if the class is "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 negative, it'll pick a random class the same way the monster spawn script

View File

@ -59,6 +59,10 @@
//= 3.02.20070209 //= 3.02.20070209
//= Corrected/updated info on Xor/setd/getd/callfunc/callsub/return and //= Corrected/updated info on Xor/setd/getd/callfunc/callsub/return and
//= updated some examples to use "better" code. [FlavioJS] //= 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 =================================== //===== Compatible With ===================================
//= LOL, can be used by anyone hopefully //= LOL, can be used by anyone hopefully
//===== Description ======================================= //===== Description =======================================
@ -4815,9 +4819,12 @@ is.
--------------------------------------- ---------------------------------------
*initnpctimer{ "<NPC object name>"}; *initnpctimer{ "<NPC object name>" {, <Attach Flag>} } |
*stopnpctimer{ "<NPC object name>"}; {"<NPC object name>" | <Attach Flag> };
*startnpctimer{ "<NPC object name>"}; *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>"}; *setnpctimer <tick>{,"<NPC object name>"};
*getnpctimer(<type of information>{,"<NPC object name>"}); *getnpctimer(<type of information>{,"<NPC object name>"});
*attachnpctimer {"<character 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 'stopnpctimer' will pause the timer, without clearing the current tick, while
'startnpctimer' will let the paused timer continue. 'startnpctimer' will let the paused timer continue.
It is not quite clear whether the new invocations will always have a RID. By default timers do not have a RID attached, which lets the timers continue even
Apparently, the RID that was in effect when the timer was initialised will still if the player that started them logs off. To attach a RID to a timer, you can
be attached to these executions in some cases, but it's not quite clear - either use the "attach flag" optional value when using initnpctimer/startnpctimer,
experiment with RID-dependent commands, like 'mes', and tell us what happens and likewise, the optional flag of stopnpctimer detaches any RID after stopping
who gets the message, if anyone. 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 The other method to attach/detach a RID is through the script commands
explicitly attach a character's RID to the timer, which will make them the 'attachnpctimer' and 'detachnpctimer'. Once attached, that will make the
target for all character-referencing commands and functions, not to mention character the target for all character-referencing commands and functions,
variables. 'detachnpctimer' will make the RID zero, making all character- not to mention variables.
referencing functions fail with an error.
'setnpctimer' will explicitly set the timer to a given tick. To make it useful, '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 you will need the 'getnpctimer' function, which the type of information argument

View File

@ -26,7 +26,8 @@ KarLaeda
Date Added 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 * Updated WoE scripts since the "guardian" script command no longer has a
"amount" argument. [Skotlex] "amount" argument. [Skotlex]
2007/02/15 2007/02/15

View File

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

View File

@ -3922,13 +3922,13 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(addtimer,"is"), BUILDIN_DEF(addtimer,"is"),
BUILDIN_DEF(deltimer,"s"), BUILDIN_DEF(deltimer,"s"),
BUILDIN_DEF(addtimercount,"si"), BUILDIN_DEF(addtimercount,"si"),
BUILDIN_DEF(initnpctimer,"*"), BUILDIN_DEF(initnpctimer,"??"),
BUILDIN_DEF(stopnpctimer,"*"), BUILDIN_DEF(stopnpctimer,"??"),
BUILDIN_DEF(startnpctimer,"*"), BUILDIN_DEF(startnpctimer,"??"),
BUILDIN_DEF(setnpctimer,"*"), BUILDIN_DEF(setnpctimer,"i?"),
BUILDIN_DEF(getnpctimer,"i*"), BUILDIN_DEF(getnpctimer,"i?"),
BUILDIN_DEF(attachnpctimer,"*"), // attached the player id to the npc timer [Celest] 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(detachnpctimer,"?"), // detached the player id from the npc timer [Celest]
BUILDIN_DEF(playerattached,""), // returns id of the current attached player. [Skotlex] BUILDIN_DEF(playerattached,""), // returns id of the current attached player. [Skotlex]
BUILDIN_DEF(announce,"si*"), BUILDIN_DEF(announce,"si*"),
BUILDIN_DEF(mapannounce,"ssi*"), BUILDIN_DEF(mapannounce,"ssi*"),
@ -7342,8 +7342,8 @@ BUILDIN_FUNC(addtimer)
{ {
char *event; char *event;
int tick; int tick;
tick=conv_num(st,& (st->stack->stack_data[st->start+2])); tick=conv_num(st, script_getdata(st,2));
event=conv_str(st,& (st->stack->stack_data[st->start+3])); event=conv_str(st, script_getdata(st,3));
check_event(st, event); check_event(st, event);
pc_addeventtimer(script_rid2sd(st),tick,event); pc_addeventtimer(script_rid2sd(st),tick,event);
return 0; return 0;
@ -7355,7 +7355,7 @@ BUILDIN_FUNC(addtimer)
BUILDIN_FUNC(deltimer) BUILDIN_FUNC(deltimer)
{ {
char *event; 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); check_event(st, event);
pc_deleventtimer(script_rid2sd(st),event); pc_deleventtimer(script_rid2sd(st),event);
return 0; return 0;
@ -7368,8 +7368,8 @@ BUILDIN_FUNC(addtimercount)
{ {
char *event; char *event;
int tick; int tick;
event=conv_str(st,& (st->stack->stack_data[st->start+2])); event=conv_str(st, script_getdata(st,2));
tick=conv_num(st,& (st->stack->stack_data[st->start+3])); tick=conv_num(st, script_getdata(st,3));
check_event(st, event); check_event(st, event);
pc_addeventtimercount(script_rid2sd(st),event,tick); pc_addeventtimercount(script_rid2sd(st),event,tick);
return 0; return 0;
@ -7382,11 +7382,35 @@ BUILDIN_FUNC(addtimercount)
BUILDIN_FUNC(initnpctimer) BUILDIN_FUNC(initnpctimer)
{ {
struct npc_data *nd; struct npc_data *nd;
if( st->end > st->start+2 ) int flag = 0;
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); if( script_hasdata(st,3) )
else { //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); 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_settimerevent_tick(nd,0);
npc_timerevent_start(nd, st->rid); npc_timerevent_start(nd, st->rid);
return 0; return 0;
@ -7398,11 +7422,35 @@ BUILDIN_FUNC(initnpctimer)
BUILDIN_FUNC(startnpctimer) BUILDIN_FUNC(startnpctimer)
{ {
struct npc_data *nd; struct npc_data *nd;
if( st->end > st->start+2 ) int flag = 0;
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); if( script_hasdata(st,3) )
else { //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); 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); npc_timerevent_start(nd, st->rid);
return 0; return 0;
} }
@ -7413,11 +7461,33 @@ BUILDIN_FUNC(startnpctimer)
BUILDIN_FUNC(stopnpctimer) BUILDIN_FUNC(stopnpctimer)
{ {
struct npc_data *nd; struct npc_data *nd;
if( st->end > st->start+2 ) int flag = 0;
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); if( script_hasdata(st,3) )
else { //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); nd=(struct npc_data *)map_id2bl(st->oid);
if (!nd) return 0;
if (flag) //Detach
nd->u.scr.rid = 0;
npc_timerevent_stop(nd); npc_timerevent_stop(nd);
return 0; return 0;
} }
@ -7429,12 +7499,12 @@ BUILDIN_FUNC(getnpctimer)
{ {
struct npc_data *nd; struct npc_data *nd;
struct map_session_data *sd; 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; int val=0;
if( st->end > st->start+3 ) if( script_hasdata(st,3) )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+3]))); nd = npc_name2id(conv_str(st,script_getdata(st,3)));
else else
nd=(struct npc_data *)map_id2bl(st->oid); nd = (struct npc_data *)map_id2bl(st->oid);
if (!nd || nd->bl.type != BL_NPC) if (!nd || nd->bl.type != BL_NPC)
{ {
@ -7471,9 +7541,9 @@ BUILDIN_FUNC(setnpctimer)
{ {
int tick; int tick;
struct npc_data *nd; struct npc_data *nd;
tick=conv_num(st,& (st->stack->stack_data[st->start+2])); tick=conv_num(st,script_getdata(st,2));
if( st->end > st->start+3 ) if( script_hasdata(st,3) )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+3]))); nd=npc_name2id(conv_str(st,script_getdata(st,3)));
else else
nd=(struct npc_data *)map_id2bl(st->oid); nd=(struct npc_data *)map_id2bl(st->oid);
@ -7491,12 +7561,10 @@ BUILDIN_FUNC(attachnpctimer)
struct npc_data *nd; struct npc_data *nd;
nd=(struct npc_data *)map_id2bl(st->oid); nd=(struct npc_data *)map_id2bl(st->oid);
if( st->end > st->start+2 ) { if( script_hasdata(st,2) )
char *name = conv_str(st,& (st->stack->stack_data[st->start+2])); sd=map_nick2sd(conv_str(st,script_getdata(st,2)));
sd=map_nick2sd(name); else
} else {
sd = script_rid2sd(st); sd = script_rid2sd(st);
}
if (sd==NULL) if (sd==NULL)
return 0; return 0;
@ -7512,8 +7580,8 @@ BUILDIN_FUNC(attachnpctimer)
BUILDIN_FUNC(detachnpctimer) BUILDIN_FUNC(detachnpctimer)
{ {
struct npc_data *nd; struct npc_data *nd;
if( st->end > st->start+2 ) if( script_hasdata(st,2) )
nd=npc_name2id(conv_str(st,& (st->stack->stack_data[st->start+2]))); nd=npc_name2id(conv_str(st,script_getdata(st,2)));
else else
nd=(struct npc_data *)map_id2bl(st->oid); 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, * To avoid "player not attached" script errors, this function is provided,
* it checks if there is a player attached to the current script. [Skotlex] * 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) BUILDIN_FUNC(playerattached)
{ {
struct map_session_data *sd; if(st->rid == 0 || map_id2sd(st->rid) == NULL)
if (st->rid == 0 || (sd = map_id2sd(st->rid)) == NULL)
push_val(st->stack,C_INT,0); push_val(st->stack,C_INT,0);
else else
push_val(st->stack,C_INT,st->rid); push_val(st->stack,C_INT,st->rid);