summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt6
-rw-r--r--doc/script_commands.txt37
-rw-r--r--npc/Changelog.txt3
-rw-r--r--npc/jobs/2-2/dancer.txt7
-rw-r--r--src/map/script.c143
5 files changed, 140 insertions, 56 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index cd2bd8dac..477cfebb2 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -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
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index a6293172f..4d55df25f 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -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.
-
-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.
+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).
+
+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
diff --git a/npc/Changelog.txt b/npc/Changelog.txt
index e66311020..951e85959 100644
--- a/npc/Changelog.txt
+++ b/npc/Changelog.txt
@@ -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
diff --git a/npc/jobs/2-2/dancer.txt b/npc/jobs/2-2/dancer.txt
index 459e93c94..b49fb7a3b 100644
--- a/npc/jobs/2-2/dancer.txt
+++ b/npc/jobs/2-2/dancer.txt
@@ -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;
//}
diff --git a/src/map/script.c b/src/map/script.c
index e64034276..c8d1ef2a8 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -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);