diff options
-rw-r--r-- | Changelog-Trunk.txt | 6 | ||||
-rw-r--r-- | doc/script_commands.txt | 37 | ||||
-rw-r--r-- | npc/Changelog.txt | 3 | ||||
-rw-r--r-- | npc/jobs/2-2/dancer.txt | 7 | ||||
-rw-r--r-- | src/map/script.c | 143 |
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); |