summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt16
-rw-r--r--conf/script_athena.conf5
-rw-r--r--npc/Changelog.txt1
-rw-r--r--npc/airports/airships.txt4
-rw-r--r--npc/quests/The_Sign_Quest.txt2
-rw-r--r--src/login/login.c1
-rw-r--r--src/map/map.c51
-rw-r--r--src/map/map.h4
-rw-r--r--src/map/npc.c326
-rw-r--r--src/map/npc.h3
-rw-r--r--src/map/pc.c22
-rw-r--r--src/map/script.c187
-rw-r--r--src/map/script.h1
13 files changed, 147 insertions, 476 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 87efc60de..464827e39 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -3,6 +3,22 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
+2007/10/06
+ * the mapserver won't exit when no mapcache is found, with use_grf: yes
+ * Fixed some \r uses, now looks better; /thx to Ai4rei (topic:165952)
+ * Removed that ridiculous spinner that displays during map/npc loading
+ - and added a more informative progress indicator (idea from jA/eapp)
+ * Removed loads of code that supported these functions
+ - -100b per npc => -1,5MB of wasted memory
+ * Fixed related npcs that erroneously used 'stoptimer'
+ * Checked/fixed/removed some old script and npc commands
+ + cmdothernpc
+ - a specialized 'donpcevent' with the event specified as two arguments
+ + enablearena/disablearena
+ - completely equivalent to enablewaitingroomevent & co.
+ - do we need these 'synonyms' ?
+ + inittimer/stoptimer
+ - removed since its logic was incompatible with the code it depended on
2007/10/05
* REALLY fixed emblem not displaying when a char logs in
(compromise between r10624 and r11033 that hopefully works)
diff --git a/conf/script_athena.conf b/conf/script_athena.conf
index 1c426a634..40d2237a3 100644
--- a/conf/script_athena.conf
+++ b/conf/script_athena.conf
@@ -15,11 +15,6 @@
//--------------------------------------------------------
-//If you are getting crashes during script loading, you can set this to yes
-//to find out which script causes it. Otherwise leave it as no since the amount
-//of extra console output is staggering.
-verbose_mode: no
-
warn_func_mismatch_paramnum: yes
check_cmdcount: 655360
diff --git a/npc/Changelog.txt b/npc/Changelog.txt
index fe1fdd154..457a9e353 100644
--- a/npc/Changelog.txt
+++ b/npc/Changelog.txt
@@ -1,6 +1,7 @@
Date Added
======
2007/10/06
+ * Fixed scripts that used 'stoptimer' instead of 'stopnpctimer' [ultramage]
* Updated Atroce's respawn time on Veins fields [Playtester]
2007/10/05
* Fixed a bug in Hugel Bingo which caused wrong rotation in player locations. [SinSloth]
diff --git a/npc/airports/airships.txt b/npc/airports/airships.txt
index 3ea1ae87e..481fa1cc2 100644
--- a/npc/airports/airships.txt
+++ b/npc/airports/airships.txt
@@ -171,7 +171,7 @@ OnTimer250000:
mapannounce "airplane","Currently, we are in Yuno. The Airship will leave shortly.",1,0x70DBDB;
end;
OnTimer260000:
- stoptimer;
+ stopnpctimer;
}
}
@@ -753,7 +753,7 @@ OnTimer185000:
mapannounce "airplane_01","Currently, we are in Rachel. The Airship will leave shortly.",1,0xFF8600;
end;
OnTimer195000:
- stoptimer;
+ stopnpctimer;
}
OnReturn:
killmonsterall "airplane_01";
diff --git a/npc/quests/The_Sign_Quest.txt b/npc/quests/The_Sign_Quest.txt
index 9e2a4fe1d..91d8e31d7 100644
--- a/npc/quests/The_Sign_Quest.txt
+++ b/npc/quests/The_Sign_Quest.txt
@@ -3862,7 +3862,7 @@ OnPlayerLogout:
OnTimer3000:
enablewaitingroomevent "Waiting Room#SignDance";
- stoptimer;
+ stopnpctimer;
end;
OnInit:
diff --git a/src/login/login.c b/src/login/login.c
index f0ca3c29f..d087097d3 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -3933,7 +3933,6 @@ void do_final(void)
{
int i, fd;
ShowInfo("Terminating...\n");
- fflush(stdout);
mmo_auth_sync();
online_db->destroy(online_db, NULL);
diff --git a/src/map/map.c b/src/map/map.c
index 967edbab9..b18b93753 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2607,48 +2607,29 @@ int map_readgat (struct map_data* m)
int map_readallmaps (void)
{
int i;
+ FILE* fp;
int maps_removed = 0;
- FILE *fp;
- if(!(fp = fopen(map_cache_file, "rb")))
+ if( enable_grf )
+ ShowStatus("Loading maps (using GRF files)...\n");
+ else
{
- ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", map_cache_file);
- exit(1); //No use launching server if maps can't be read.
+ ShowStatus("Loading maps (using %s as map cache)...\n", map_cache_file);
+ if( (fp = fopen(map_cache_file, "rb")) == NULL )
+ {
+ ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", map_cache_file);
+ exit(1); //No use launching server if maps can't be read.
+ }
}
- if(enable_grf) ShowStatus("Loading maps (using GRF files)...\n");
- else ShowStatus("Loading maps (using %s as map cache)...\n", map_cache_file);
-
for(i = 0; i < map_num; i++)
{
- static int lasti = -1;
- static int last_time = -1;
- int j = i*20/map_num;
size_t size;
// show progress
- if (j != lasti || last_time != time(0))
- {
- char progress[21] = " ";
- char c = '-';
- int k;
-
- lasti = j;
- printf("\r");
- ShowStatus("Progress: [");
- for (k=0; k < j; k++) progress[k] = '#';
- printf(progress);
- last_time = (int)time(0);
- switch(last_time % 4) {
- case 0: c='\\'; break;
- case 1: c='|'; break;
- case 2: c='/'; break;
- case 3: c='-'; break;
- }
- printf("] Working: [%c]",c);
- fflush(stdout);
- }
+ ShowStatus("Loading maps [%i/%i]: %s"CL_CLL"\r", i, map_num, map[i].name);
+ // try to load the map
if( !
(enable_grf?
map_readgat(&map[i])
@@ -2662,7 +2643,8 @@ int map_readallmaps (void)
map[i].index = mapindex_name2id(map[i].name);
- if (uidb_get(map_db,(unsigned int)map[i].index) != NULL) {
+ if (uidb_get(map_db,(unsigned int)map[i].index) != NULL)
+ {
ShowWarning("Map %s already loaded!\n", map[i].name);
if (map[i].gat) {
aFree(map[i].gat);
@@ -2703,11 +2685,12 @@ int map_readallmaps (void)
map[i].block_mob_count = (int*)aCallocA(size, 1);
}
- fclose(fp);
+ if( !enable_grf )
+ fclose(fp);
// finished map loading
printf("\r");
- ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps.%30s\n",map_num,"");
+ ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps."CL_CLL"\n",map_num);
if (maps_removed)
ShowNotice("Maps removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed);
diff --git a/src/map/map.h b/src/map/map.h
index eef71e7c1..34345a740 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -837,10 +837,6 @@ struct npc_data {
int chat_id;
unsigned int next_walktime;
- char eventqueue[MAX_EVENTQUEUE][50];
- int eventtimer[MAX_EVENTTIMER];
- short arenaflag;
-
void* chatdb; // pointer to a npc_parse struct (see npc_chat.c)
struct npc_data *master_nd;
diff --git a/src/map/npc.c b/src/map/npc.c
index b469878eb..177612b50 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -6,6 +6,7 @@
#include "../common/nullpo.h"
#include "../common/malloc.h"
#include "../common/showmsg.h"
+#include "../common/strlib.h"
#include "../common/utils.h"
#include "../common/ers.h"
#include "../common/db.h"
@@ -184,99 +185,6 @@ int npc_event_dequeue(struct map_session_data* sd)
}
/*==========================================
- * イベントの遅延実行
- *------------------------------------------*/
-int npc_event_timer(int tid, unsigned int tick, int id, int data)
-{
- char* eventname = (char *)data;
- struct event_data* ev = strdb_get(ev_db,eventname);
- struct npc_data* nd;
- struct map_session_data* sd = map_id2sd(id);
- size_t i;
-
- if((ev==NULL || (nd=ev->nd)==NULL))
- {
- if(battle_config.error_log)
- ShowWarning("npc_event: event not found [%s]\n",eventname);
- }
- else
- {
- for(i=0;i<MAX_EVENTTIMER;i++) {
- if( nd->eventtimer[i]==tid ) {
- nd->eventtimer[i]=-1;
- npc_event(sd,eventname,0); // sd NULL check is within
- break;
- }
- }
- if(i==MAX_EVENTTIMER && battle_config.error_log)
- ShowWarning("npc_event_timer: event timer not found [%s]!\n",eventname);
- }
-
- aFree(eventname);
- return 0;
-}
-
-int npc_timer_event(const char* eventname) // Added by RoVeRT
-{
- struct event_data* ev = strdb_get(ev_db, eventname);
- struct npc_data *nd;
-// int xs,ys;
-
- if((ev==NULL || (nd=ev->nd)==NULL)){
- ShowWarning("npc_timer_event: event not found [%s]\n",eventname);
- return 0;
- }
-
- run_script(nd->u.scr.script,ev->pos,nd->bl.id,nd->bl.id);
-
- return 0;
-}
-/*
-int npc_timer_sub_sub(DBKey key,void *data,va_list ap) // Added by RoVeRT
-{
- char *p=(char *)key;
- struct event_data *ev=(struct event_data *)data;
- int *c=va_arg(ap,int *);
- int tick=0,ctick=gettick();
- char temp[10];
- char event[100];
-
- if(ev->nd->bl.id==(int)*c && (p=strchr(p,':')) && p && strncasecmp("::OnTimer",p,8)==0 ){
- sscanf(&p[9],"%s",temp);
- tick=atoi(temp);
-
- strcpy( event, ev->nd->name);
- strcat( event, p);
-
- if (ctick >= ev->nd->lastaction && ctick - ev->nd->timer >= tick) {
- npc_timer_event(event);
- ev->nd->lastaction = ctick;
- }
- }
- return 0;
-}
-
-int npc_timer_sub(DBKey key,void *data,va_list ap) // Added by RoVeRT
-{
- struct npc_data *nd=(struct npc_data*)data;
-
- if(nd->timer == -1)
- return 0;
-
- sv_db->foreach(ev_db,npc_timer_sub_sub,&nd->bl.id);
-
- return 0;
-}
-
-int npc_timer(int tid,unsigned int tick,int id,int data) // Added by RoVeRT
-{
- npcname_db->foreach(npcname_db,npc_timer_sub);
-
- aFree((void*)data);
- return 0;
-}*/
-
-/*==========================================
* exports a npc event label
* npc_parse_script->strdb_foreachから呼ばれる
*------------------------------------------*/
@@ -444,93 +352,7 @@ int npc_event_do_oninit(void)
return 0;
}
-/*==========================================
- * OnTimer NPC event - by RoVeRT
- *------------------------------------------*/
-int npc_addeventtimer(struct npc_data* nd, int tick, const char* name)
-{
- int i;
- char* evname;
-
- for(i=0;i<MAX_EVENTTIMER;i++)
- if( nd->eventtimer[i]==-1 )
- break;
- if(i<MAX_EVENTTIMER){
- if (!strdb_get(ev_db,name)) {
- if (battle_config.error_log)
- ShowError("npc_addeventimer: Event %s does not exists.\n", name);
- return 1; //Event does not exists!
- }
- evname = (char *)aMallocA(NAME_LENGTH*sizeof(char));
- if(evname==NULL){
- ShowFatalError("npc_addeventtimer: out of memory !\n");exit(1);
- }
- strncpy(evname,name,NAME_LENGTH);
- evname[NAME_LENGTH-1] = '\0';
- nd->eventtimer[i]=add_timer(gettick()+tick,
- npc_event_timer,nd->bl.id,(int)evname);
- }else
- ShowWarning("npc_addtimer: event timer is full !\n");
-
- return 0;
-}
-
-int npc_deleventtimer(struct npc_data* nd, const char* name)
-{
- int i;
- for(i=0;i<MAX_EVENTTIMER;i++)
- if( nd->eventtimer[i]!=-1 && strcmp((char *)(get_timer(nd->eventtimer[i])->data), name)==0 ){
- delete_timer(nd->eventtimer[i],npc_event_timer);
- nd->eventtimer[i]=-1;
- break;
- }
- return 0;
-}
-
-int npc_cleareventtimer(struct npc_data* nd)
-{
- int i;
- for(i=0;i<MAX_EVENTTIMER;i++)
- if( nd->eventtimer[i]!=-1 ){
- delete_timer(nd->eventtimer[i],npc_event_timer);
- nd->eventtimer[i]=-1;
- }
-
- return 0;
-}
-
-int npc_do_ontimer_sub(DBKey key, void* data, va_list ap)
-{
- const char *p = key.str;
- struct event_data *ev = (struct event_data *)data;
- int *c = va_arg(ap,int *);
-// struct map_session_data *sd=va_arg(ap,struct map_session_data *);
- int option = va_arg(ap,int);
- int tick = 0;
- char temp[10];
- char event[50];
-
- if(ev->nd->bl.id == (int)*c && (p = strchr(p,':')) && strnicmp("::OnTimer",p,8) == 0){
- sscanf(&p[9], "%s", temp);
- tick = atoi(temp);
-
- strcpy(event, ev->nd->name);
- strcat(event, p);
-
- if (option!=0) {
- npc_addeventtimer(ev->nd, tick, event);
- } else {
- npc_deleventtimer(ev->nd, event);
- }
- }
- return 0;
-}
-int npc_do_ontimer(int npc_id, int option)
-{
- ev_db->foreach(ev_db, npc_do_ontimer_sub, &npc_id, option);
- return 0;
-}
/*==========================================
* タイマーイベント用ラベルの取り込み
* npc_parse_script->strdb_foreachから呼ばれる
@@ -817,19 +639,21 @@ int npc_settimerevent_tick(struct npc_data* nd, int newtimer)
int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char* eventname)
{
- if ( sd->npc_id!=0) {
+ if ( sd->npc_id != 0 )
+ {
//Enqueue the event trigger.
int i;
- for(i=0;i<MAX_EVENTQUEUE && sd->eventqueue[i][0];i++);
-
- if (i==MAX_EVENTQUEUE) {
- if (battle_config.error_log)
+ ARR_FIND( 0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0' );
+ if( i < MAX_EVENTQUEUE )
+ safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
+ else
+ if( battle_config.error_log )
ShowWarning("npc_event: event queue is full !\n");
- }else //Event enqueued.
- memcpy(sd->eventqueue[i],eventname,50);
+
return 1;
}
- if (ev->nd->sc.option&OPTION_INVISIBLE) {
+ if( ev->nd->sc.option&OPTION_INVISIBLE )
+ {
//Disabled npc, shouldn't trigger event.
npc_event_dequeue(sd);
return 2;
@@ -890,31 +714,6 @@ int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill)
return npc_event_sub(sd,ev,eventname);
}
-
-int npc_command_sub(DBKey key,void *data,va_list ap)
-{
- const char* p = (const char*)key.str;
- struct event_data *ev=(struct event_data *)data;
- const char* npcname = va_arg(ap, const char*);
- const char* command = va_arg(ap, const char*);
- char temp[100];
-
- if(strcmp(ev->nd->name,npcname)==0 && (p=strchr(p,':')) && strnicmp("::OnCommand",p,10)==0 ){
- sscanf(&p[11],"%s",temp);
-
- if (strcmp(command,temp)==0)
- run_script(ev->nd->u.scr.script,ev->pos,0,ev->nd->bl.id);
- }
-
- return 0;
-}
-
-int npc_command(struct map_session_data* sd, const char* npcname, const char* command)
-{
- ev_db->foreach(ev_db, npc_command_sub, npcname, command);
-
- return 0;
-}
/*==========================================
* 接触型のNPC処理
*------------------------------------------*/
@@ -1523,7 +1322,6 @@ int npc_unload(struct npc_data* nd)
ers_free(timer_event_ers, (struct event_timer_data*)td->data);
delete_timer(nd->u.scr.timerid, npc_timerevent);
}
- npc_cleareventtimer (nd);
if (nd->u.scr.timer_event)
aFree(nd->u.scr.timer_event);
if (nd->u.scr.src_id == 0) {
@@ -1723,7 +1521,6 @@ static int npc_parse_shop(char* w1, char* w2, char* w3, char* w4)
nd->u.shop_item[pos].value = value;
// check for bad prices that can possibly cause exploits
if (value/124. < id->value_sell/75.) { //Clened up formula to prevent overflows.
- printf("\r"); //Carriage return to clear the 'loading..' line. [Skotlex]
if (value < id->value_sell)
ShowWarning ("Item %s [%d] buying price (%d) is less than selling price (%d) at %s\n",
id->name, id->nameid, value, id->value_sell, current_file);
@@ -1749,8 +1546,7 @@ static int npc_parse_shop(char* w1, char* w2, char* w3, char* w4)
nd->bl.x = x;
nd->bl.y = y;
nd->bl.id = npc_get_new_npc_id();
- memcpy(nd->name, w3, NAME_LENGTH);
- nd->name[NAME_LENGTH-1] = '\0';
+ safestrncpy(nd->name, w3, NAME_LENGTH);
nd->class_ = m==-1?-1:atoi(w4);
nd->speed = 200;
@@ -1810,8 +1606,7 @@ int npc_convertlabel_db(DBKey key, void* data, va_list ap)
ShowError("npc_parse_script: label name longer than 23 chars! '%s'\n (%s)", lname, current_file);
exit(1);
}
- memcpy(lst[num].name, lname, len);
- lst[num].name[len]=0;
+ safestrncpy(lst[num].name, lname, NAME_LENGTH);
lst[num].pos = pos;
nd->u.scr.label_list = lst;
nd->u.scr.label_list_num = num+1;
@@ -2047,8 +1842,6 @@ static int npc_parse_script(char* w1, char* w2, char* w3, char* w4, char* first_
nd->bl.type = BL_NPC;
nd->bl.subtype = SCRIPT;
- for (i = 0; i < MAX_EVENTTIMER; i++)
- nd->eventtimer[i] = -1;
if (m >= 0) {
nd->n = map_addnpc(m, nd);
status_change_init(&nd->bl);
@@ -2298,7 +2091,6 @@ static int npc_parse_function(char* w1, char* w2, char* w3, char* w4, char* firs
user_db = script_get_userfunc_db();
oldscript = (struct script_code *)strdb_get(user_db, p);
if(oldscript != NULL) {
- printf("\r"); //Carriage return to clear the 'loading..' line. [Skotlex]
ShowInfo("parse_function: Overwriting user function [%s] (%s:%d)\n", p, file, *lines);
script_free_vars( &oldscript->script_vars );
aFree( oldscript->script_buf );
@@ -2782,10 +2574,8 @@ void npc_parsesrcfile(const char* name)
if ((count = sscanf(line, "%s %s %[^\t]\t %n%[^\n]", w1, w2, w3, &w4pos, w4)) == 4 ||
(count = sscanf(line, "%s %s %s %n%[^\n]\n", w1, w2, w3, &w4pos, w4)) >= 3)
{
- ShowWarning("\r");
ShowWarning("Incorrect separator syntax in file '%s', line '%i'. Use tabs instead of spaces!\n * %s %s %s %s\n",current_file,lines,w1,w2,w3,w4);
} else {
- ShowError("\r"); //Erase the npc spinner.
ShowError("Could not parse file '%s', line '%i'.\n * %s %s %s %s\n",current_file,lines,w1,w2,w3,w4);
continue;
}
@@ -2926,11 +2716,9 @@ void npc_read_event_script(void)
}
}
-/*==========================================
- *
- *------------------------------------------*/
-static int npc_cleanup_sub(struct block_list* bl, va_list ap)
+static int npc_cleanup_dbsub(DBKey key, void* data, va_list ap)
{
+ struct block_list* bl = (struct block_list*)data;
nullpo_retr(0, bl);
switch(bl->type) {
@@ -2945,18 +2733,11 @@ static int npc_cleanup_sub(struct block_list* bl, va_list ap)
return 0;
}
-static int npc_cleanup_dbsub(DBKey key, void* data, va_list ap)
-{
- return npc_cleanup_sub((struct block_list*)data, 0);
-}
-
int npc_reload(void)
{
struct npc_src_list *nsl;
int m, i;
- time_t last_time = time(0);
- int busy = 0, npc_new_min = npc_id;
- char c = '-';
+ int npc_new_min = npc_id;
//Remove all npcs/mobs. [Skotlex]
map_foreachiddb(npc_cleanup_dbsub);
@@ -2971,36 +2752,21 @@ int npc_reload(void)
}
mob_clear_spawninfo();
- // anything else we should cleanup?
- // Reloading npc's now
+ // clear npc-related data structures
ev_db->clear(ev_db,NULL);
npcname_db->clear(npcname_db,NULL);
npc_warp = npc_shop = npc_script = 0;
npc_mob = npc_cache_mob = npc_delay_mob = 0;
- for (nsl = npc_src_files; nsl; nsl = nsl->next) {
+ //TODO: the following code is copy-pasted from do_init_npc(); clean it up
+ // Reloading npcs now
+ for (nsl = npc_src_files; nsl; nsl = nsl->next)
+ {
+ ShowStatus("Loading NPC file: %s"CL_CLL"\r", nsl->name);
npc_parsesrcfile(nsl->name);
- if (script_config.verbose_mode) {
- printf("\r");
- ShowStatus("Loading NPCs... %-53s", nsl->name);
- } else {
- if (last_time != time(0)) {
- printf("\r");
- ShowStatus("Loading NPCs... Working: ");
- last_time = time(0);
- switch(busy) {
- case 0: c='\\'; busy++; break;
- case 1: c='|'; busy++; break;
- case 2: c='/'; busy++; break;
- case 3: c='-'; busy=0;
- }
- printf("[%c]",c);
- }
- }
- fflush(stdout);
}
- printf("\r");
- ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:\n"
+
+ ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Warps\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Shops\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Scripts\n"
@@ -3013,8 +2779,7 @@ int npc_reload(void)
npc_read_event_script();
//Execute the OnInit event for freshly loaded npcs. [Skotlex]
- ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"
- CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
+ ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n",npc_event_doall("OnInit"));
// Execute rest of the startup events if connected to char-server. [Lance]
if(!CheckForCharServer()){
ShowStatus("Event '"CL_WHITE"OnCharIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnCharIfInit"));
@@ -3090,10 +2855,7 @@ static void npc_debug_warps(void)
int do_init_npc(void)
{
struct npc_src_list *file;
- time_t last_time = time(NULL);
- int busy = 0;
int i;
- char c = '-';
//Stock view data for normal npcs.
memset(&npc_viewdb, 0, sizeof(npc_viewdb));
@@ -3101,38 +2863,21 @@ int do_init_npc(void)
for( i = 1; i < MAX_NPC_CLASS; i++ )
npc_viewdb[i].class_ = i;
- // comparing only the first 24 chars of labels that are 50 chars long isn't that nice
- // will cause "duplicated" labels where actually no dup is...
- ev_db = db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,51);
+ ev_db = db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1);
npcname_db = db_alloc(__FILE__,__LINE__,DB_STRING,DB_OPT_BASE,NAME_LENGTH);
memset(&ev_tm_b, -1, sizeof(ev_tm_b));
timer_event_ers = ers_new(sizeof(struct timer_event_data));
- for( file = npc_src_files; file != NULL; file = file->next) {
+ // process all npc files
+ ShowStatus("Loading NPCs...\r");
+ for( file = npc_src_files; file != NULL; file = file->next )
+ {
+ ShowStatus("Loading NPC file: %s"CL_CLL"\r", file->name);
npc_parsesrcfile(file->name);
- printf("\r");
- if (script_config.verbose_mode)
- ShowStatus("Loading NPCs... %-53s", file->name);
- else
- {
- ShowStatus("Loading NPCs... Working: ");
- if (last_time != time(NULL))
- {// change character at least every second
- last_time = time(NULL);
- switch(busy) {
- case 0: c='\\'; busy++; break;
- case 1: c='|'; busy++; break;
- case 2: c='/'; busy++; break;
- case 3: c='-'; busy=0;
- }
- }
- printf("[%c]",c);
- }
- fflush(stdout);
}
- printf("\r");
- ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:\n"
+
+ ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Warps\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Shops\n"
"\t-'"CL_WHITE"%d"CL_RESET"' Scripts\n"
@@ -3141,13 +2886,14 @@ int do_init_npc(void)
"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
+ // set up the events cache
memset(script_event, 0, sizeof(script_event));
npc_read_event_script();
+
//Debug function to locate all endless loop warps.
if (battle_config.warp_point_debug)
npc_debug_warps();
- add_timer_func_list(npc_event_timer,"npc_event_timer");
add_timer_func_list(npc_event_do_clock,"npc_event_do_clock");
add_timer_func_list(npc_timerevent,"npc_timerevent");
@@ -3157,8 +2903,6 @@ int do_init_npc(void)
fake_nd->bl.id = npc_get_new_npc_id();
fake_nd->class_ = -1;
fake_nd->speed = 200;
- for (i = 0; i < MAX_EVENTTIMER; i++)
- fake_nd->eventtimer[i] = -1;
strcpy(fake_nd->name,"FAKE_NPC");
memcpy(fake_nd->exname, fake_nd->name, 9);
diff --git a/src/map/npc.h b/src/map/npc.h
index 9b3c5782b..39aad1cf8 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -41,10 +41,7 @@ enum {
struct view_data* npc_get_viewdata(int class_);
int npc_chat_sub(struct block_list* bl, va_list ap);
int npc_event_dequeue(struct map_session_data* sd);
-int npc_event_timer(int tid,unsigned int tick, int id, int data);
int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill);
-int npc_timer_event(const char* eventname); // Added by RoVeRT
-int npc_command(struct map_session_data* sd, const char* npcname, const char* command);
int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y);
int npc_touch_areanpc2(struct block_list* bl); // [Skotlex]
int npc_check_areanpc(int flag, int m, int x, int y, int range);
diff --git a/src/map/pc.c b/src/map/pc.c
index 9acfd92a3..d30f41873 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -6198,13 +6198,14 @@ static int pc_eventtimer(int tid,unsigned int tick,int id,int data)
if(sd==NULL)
return 0;
- for(i=0;i < MAX_EVENTTIMER && sd->eventtimer[i]!=tid; i++);
-
- if(i < MAX_EVENTTIMER){
+ ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == tid );
+ if( i < MAX_EVENTTIMER )
+ {
+ sd->eventtimer[i] = -1;
sd->eventcount--;
- sd->eventtimer[i]=-1;
npc_event(sd,p,0);
- } else if(battle_config.error_log)
+ }
+ else if( battle_config.error_log )
ShowError("pc_eventtimer: no such event timer\n");
if (p) aFree(p);
@@ -6217,18 +6218,15 @@ static int pc_eventtimer(int tid,unsigned int tick,int id,int data)
int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
{
int i;
- char *evname;
-
+ char* evname;
nullpo_retr(0, sd);
- for(i=0;i<MAX_EVENTTIMER && sd->eventtimer[i]!=-1;i++);
-
- if(i==MAX_EVENTTIMER)
+ ARR_FIND( 0, MAX_EVENTTIMER, i, sd->eventtimer[i] == -1 );
+ if( i == MAX_EVENTTIMER )
return 0;
evname = aStrdup(name);
- sd->eventtimer[i]=add_timer(gettick()+tick,
- pc_eventtimer,sd->bl.id,(int)evname);
+ sd->eventtimer[i] = add_timer(gettick()+tick, pc_eventtimer,sd->bl.id,(int)evname);
sd->eventcount++;
return 1;
diff --git a/src/map/script.c b/src/map/script.c
index 09113d577..90ecbb82e 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3479,10 +3479,7 @@ int script_config_read_sub(char *cfgName)
if(i!=2)
continue;
- if(strcmpi(w1,"verbose_mode")==0) {
- script_config.verbose_mode = config_switch(w2);
- }
- else if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
+ if(strcmpi(w1,"warn_func_mismatch_paramnum")==0) {
script_config.warn_func_mismatch_paramnum = config_switch(w2);
}
else if(strcmpi(w1,"check_cmdcount")==0) {
@@ -3550,7 +3547,6 @@ int script_config_read(char *cfgName)
{ //Script related variables should be initialized once! [Skotlex]
memset (&script_config, 0, sizeof(script_config));
- script_config.verbose_mode = 0;
script_config.warn_func_mismatch_paramnum = 1;
script_config.check_cmdcount = 65535;
script_config.check_gotocount = 2048;
@@ -3813,6 +3809,7 @@ BUILDIN_FUNC(killmonsterall);
BUILDIN_FUNC(clone);
BUILDIN_FUNC(doevent);
BUILDIN_FUNC(donpcevent);
+BUILDIN_FUNC(cmdothernpc);
BUILDIN_FUNC(addtimer);
BUILDIN_FUNC(deltimer);
BUILDIN_FUNC(addtimercount);
@@ -3834,8 +3831,6 @@ BUILDIN_FUNC(getareausers);
BUILDIN_FUNC(getareadropitem);
BUILDIN_FUNC(enablenpc);
BUILDIN_FUNC(disablenpc);
-BUILDIN_FUNC(enablearena); // Added by RoVeRT
-BUILDIN_FUNC(disablearena); // Added by RoVeRT
BUILDIN_FUNC(hideoffnpc);
BUILDIN_FUNC(hideonnpc);
BUILDIN_FUNC(sc_start);
@@ -3859,6 +3854,8 @@ BUILDIN_FUNC(enablewaitingroomevent);
BUILDIN_FUNC(disablewaitingroomevent);
BUILDIN_FUNC(getwaitingroomstate);
BUILDIN_FUNC(warpwaitingpc);
+BUILDIN_FUNC(enablearena); // Added by RoVeRT
+BUILDIN_FUNC(disablearena); // Added by RoVeRT
BUILDIN_FUNC(attachrid);
BUILDIN_FUNC(detachrid);
BUILDIN_FUNC(isloggedin);
@@ -3904,9 +3901,6 @@ BUILDIN_FUNC(soundeffect);
BUILDIN_FUNC(soundeffectall);
BUILDIN_FUNC(setcastledata);
BUILDIN_FUNC(mapwarp);
-BUILDIN_FUNC(inittimer);
-BUILDIN_FUNC(stoptimer);
-BUILDIN_FUNC(cmdothernpc);
BUILDIN_FUNC(mobcount);
BUILDIN_FUNC(strmobinfo); // Script for displaying mob info [Valaris]
BUILDIN_FUNC(guardian); // Script for displaying mob info [Valaris]
@@ -4149,6 +4143,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(clone,"siisi*"),
BUILDIN_DEF(doevent,"s"),
BUILDIN_DEF(donpcevent,"s"),
+ BUILDIN_DEF(cmdothernpc,"ss"),
BUILDIN_DEF(addtimer,"is"),
BUILDIN_DEF(deltimer,"s"),
BUILDIN_DEF(addtimercount,"si"),
@@ -4170,8 +4165,6 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(getareadropitem,"siiiii"),
BUILDIN_DEF(enablenpc,"s"),
BUILDIN_DEF(disablenpc,"s"),
- BUILDIN_DEF(enablearena,""), // Added by RoVeRT
- BUILDIN_DEF(disablearena,""), // Added by RoVeRT
BUILDIN_DEF(hideoffnpc,"s"),
BUILDIN_DEF(hideonnpc,"s"),
BUILDIN_DEF(sc_start,"iii?"),
@@ -4193,6 +4186,8 @@ struct script_function buildin_func[] = {
BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"),
BUILDIN_DEF(enablewaitingroomevent,"?"),
BUILDIN_DEF(disablewaitingroomevent,"?"),
+ BUILDIN_DEF2(enablewaitingroomevent,"enablearena",""), // Added by RoVeRT
+ BUILDIN_DEF2(disablewaitingroomevent,"disablearena",""), // Added by RoVeRT
BUILDIN_DEF(getwaitingroomstate,"i?"),
BUILDIN_DEF(warpwaitingpc,"sii?"),
BUILDIN_DEF(attachrid,"i"),
@@ -4255,9 +4250,6 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(specialeffect2,"i*"), // skill effect on players[Valaris]
BUILDIN_DEF(nude,""), // nude command [Valaris]
BUILDIN_DEF(mapwarp,"ssii*"), // Added by RoVeRT
- BUILDIN_DEF(inittimer,""),
- BUILDIN_DEF(stoptimer,""),
- BUILDIN_DEF(cmdothernpc,"ss"),
BUILDIN_DEF(atcommand,"*"), // [MouseJstr]
BUILDIN_DEF(charcommand,"*"), // [MouseJstr]
BUILDIN_DEF(movenpc,"sii"), // [MouseJstr]
@@ -4737,46 +4729,53 @@ BUILDIN_FUNC(goto)
*------------------------------------------*/
BUILDIN_FUNC(callfunc)
{
+ int i, j;
+ struct linkdb_node** oldval;
struct script_code *scr, *oldscr;
- const char *str=script_getstr(st,2);
+ const char* str = script_getstr(st,2);
- if( (scr = strdb_get(userfunc_db, str)) ){
- int i,j;
- struct linkdb_node **oldval = st->stack->var_function;
- for(i=st->start+3,j=0;i<st->end;i++,j++)
- push_copy(st->stack,i);
+ scr = strdb_get(userfunc_db, str);
+ if( !scr )
+ {
+ ShowError("script:callfunc: function not found! [%s]\n", str);
+ st->state = END;
+ return 1;
+ }
- script_pushint(st,j); // 引数の数をプッシュ
- script_pushint(st,st->stack->defsp); // 現在の基準スタックポインタをプッシュ
- script_pushint(st,(int)st->script); // 現在のスクリプトをプッシュ
- script_pushint(st,(int)st->stack->var_function); // 現在の関数依存変数をプッシュ
- push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ
+ for( i = st->start+3, j = 0; i < st->end; i++, j++ )
+ push_copy(st->stack,i);
- oldscr = st->script;
- st->pos=0;
- st->script=scr;
- st->stack->defsp=st->start+5+j;
- st->state=GOTO;
- st->stack->var_function = (struct linkdb_node**)aCalloc(1, sizeof(struct linkdb_node*));
+ script_pushint(st,j); // 引数の数をプッシュ
+ script_pushint(st,st->stack->defsp); // 現在の基準スタックポインタをプッシュ
+ script_pushint(st,(int)st->script); // 現在のスクリプトをプッシュ
+ script_pushint(st,(int)st->stack->var_function); // 現在の関数依存変数をプッシュ
+ push_val(st->stack,C_RETINFO,st->pos); // 現在のスクリプト位置をプッシュ
- // ' 変数の引き継ぎ
- for(i = 0; i < j; i++) {
- struct script_data *s = &st->stack->stack_data[st->stack->sp-6-i];
- if( data_isreference(s) && !s->ref ) {
- char *name = str_buf+str_data[s->u.num&0x00ffffff].str;
- // '@ 変数の引き継ぎ
- if( name[0] == '.' && name[1] == '@' ) {
- s->ref = oldval;
- } else if( name[0] == '.' ) {
- s->ref = &oldscr->script_vars;
- }
+ oldscr = st->script;
+ oldval = st->stack->var_function;
+
+ st->pos = 0;
+ st->script = scr;
+ st->stack->defsp = st->start+5+j;
+ st->state = GOTO;
+ st->stack->var_function = (struct linkdb_node**)aCalloc(1, sizeof(struct linkdb_node*));
+
+ // ' 変数の引き継ぎ
+ for( i = 0; i < j; i++ )
+ {
+ struct script_data* s = script_getdatatop(st, -6-i);
+ if( data_isreference(s) && !s->ref )
+ {
+ char* name = str_buf + str_data[s->u.num&0x00ffffff].str;
+ // '@ 変数の引き継ぎ
+ if( name[0] == '.' && name[1] == '@' ) {
+ s->ref = oldval;
+ } else if( name[0] == '.' ) {
+ s->ref = &oldscr->script_vars;
}
}
- }else{
- ShowError("script:callfunc: function not found! [%s]\n",str);
- st->state=END;
- return 1;
}
+
return 0;
}
/*==========================================
@@ -7974,8 +7973,7 @@ BUILDIN_FUNC(clone)
*------------------------------------------*/
BUILDIN_FUNC(doevent)
{
- const char *event;
- event=script_getstr(st,2);
+ const char* event = script_getstr(st,2);
check_event(st, event);
npc_event(map_id2sd(st->rid),event,0);
return 0;
@@ -7985,21 +7983,33 @@ BUILDIN_FUNC(doevent)
*------------------------------------------*/
BUILDIN_FUNC(donpcevent)
{
- const char *event;
- event=script_getstr(st,2);
+ const char* event = script_getstr(st,2);
check_event(st, event);
npc_event_do(event);
return 0;
}
+
+/// for Aegis compatibility
+/// basically a specialized 'donpcevent', with the event specified as two arguments instead of one
+BUILDIN_FUNC(cmdothernpc) // Added by RoVeRT
+{
+ const char* npc = script_getstr(st,2);
+ const char* command = script_getstr(st,3);
+ char event[51];
+ snprintf(event, 51, "%s::OnCommand%s", npc, command);
+ check_event(st, event);
+ npc_event_do(event);
+ return 0;
+}
+
/*==========================================
* イベントタイマー追加
*------------------------------------------*/
BUILDIN_FUNC(addtimer)
{
- const char *event;
- int tick;
- tick=script_getnum(st,2);
- event=script_getstr(st, 3);
+ int tick = script_getnum(st,2);
+ const char* event = script_getstr(st, 3);
+
check_event(st, event);
pc_addeventtimer(script_rid2sd(st),tick,event);
return 0;
@@ -9168,42 +9178,6 @@ BUILDIN_FUNC(warpwaitingpc)
// ...
//
-/// TODO what is this suposed to do?
-///
-/// @author RoVeRT
-BUILDIN_FUNC(enablearena)
-{
- struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
- struct chat_data *cd;
-
-
- if(nd==NULL || (cd=(struct chat_data *)map_id2bl(nd->chat_id))==NULL)
- return 0;
-
- npc_enable(nd->name, 1);
- nd->arenaflag = 1;
-
- if( cd->users >= cd->trigger && cd->npc_event[0] )
- npc_timer_event(cd->npc_event);
-
- return 0;
-}
-
-/// TODO what is this suposed to do?
-///
-/// @author RoVeRT
-BUILDIN_FUNC(disablearena)
-{
- struct npc_data *nd=(struct npc_data *)map_id2bl(st->oid);
- nd->arenaflag=0;
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////
-// ...
-//
-
/*==========================================
* RIDのアタッチ
*------------------------------------------*/
@@ -10003,37 +9977,6 @@ BUILDIN_FUNC(mapwarp) // Added by RoVeRT
return 0;
}
-BUILDIN_FUNC(cmdothernpc) // Added by RoVeRT
-{
- const char *npc,*command;
-
- npc=script_getstr(st,2);
- command=script_getstr(st,3);
-
- npc_command(map_id2sd(st->rid),npc,command);
- return 0;
-}
-
-BUILDIN_FUNC(inittimer) // Added by RoVeRT
-{
-// struct npc_data *nd=(struct npc_data*)map_id2bl(st->oid);
-// nd->lastaction=nd->timer=gettick();
-
- npc_do_ontimer(st->oid, 1);
-
- return 0;
-}
-
-BUILDIN_FUNC(stoptimer) // Added by RoVeRT
-{
-// struct npc_data *nd=(struct npc_data*)map_id2bl(st->oid);
-// nd->lastaction=nd->timer=-1;
-
- npc_do_ontimer(st->oid, 0);
-
- return 0;
-}
-
static int buildin_mobcount_sub(struct block_list *bl,va_list ap) // Added by RoVeRT
{
char *event=va_arg(ap,char *);
diff --git a/src/map/script.h b/src/map/script.h
index b207bd36e..2260724a5 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -9,7 +9,6 @@ extern int potion_hp, potion_per_hp, potion_sp, potion_per_sp;
extern int potion_target;
extern struct Script_Config {
- unsigned verbose_mode : 1;
unsigned warn_func_mismatch_paramnum : 1;
int check_cmdcount;
int check_gotocount;