diff options
-rw-r--r-- | Changelog-Trunk.txt | 16 | ||||
-rw-r--r-- | conf/script_athena.conf | 5 | ||||
-rw-r--r-- | npc/Changelog.txt | 1 | ||||
-rw-r--r-- | npc/airports/airships.txt | 4 | ||||
-rw-r--r-- | npc/quests/The_Sign_Quest.txt | 2 | ||||
-rw-r--r-- | src/login/login.c | 1 | ||||
-rw-r--r-- | src/map/map.c | 51 | ||||
-rw-r--r-- | src/map/map.h | 4 | ||||
-rw-r--r-- | src/map/npc.c | 326 | ||||
-rw-r--r-- | src/map/npc.h | 3 | ||||
-rw-r--r-- | src/map/pc.c | 22 | ||||
-rw-r--r-- | src/map/script.c | 187 | ||||
-rw-r--r-- | src/map/script.h | 1 |
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; |