Przeglądaj źródła

- 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

skotlex 18 lat temu
rodzic
commit
5ed686f6a8
5 zmienionych plików z 140 dodań i 56 usunięć
  1. 6 0
      Changelog-Trunk.txt
  2. 23 14
      doc/script_commands.txt
  3. 2 1
      npc/Changelog.txt
  4. 4 3
      npc/jobs/2-2/dancer.txt
  5. 105 38
      src/map/script.c

+ 6 - 0
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

+ 23 - 14
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 

+ 2 - 1
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

+ 4 - 3
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;
 //}

+ 105 - 38
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);