From a2dec941492c9b7e56e3e34600e3fba9937cbf65 Mon Sep 17 00:00:00 2001 From: panikon Date: Sat, 10 May 2014 01:36:18 -0300 Subject: Small changes in npc loading/reloading Compartmentalized npc file processing Corrected event initalisation order in npc_reload Changed loading order, now item db constants are loaded before npc processing in order to avoid labels overwriting constants values, like Aegis Names Added information regarding reloading scripts in /doc/script_commands.txt --- src/map/map.c | 2 +- src/map/npc.c | 105 +++++++++++++++++++++++++++++----------------------------- src/map/npc.h | 2 +- 3 files changed, 55 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/map/map.c b/src/map/map.c index bccb51d7e..0d6445021 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -5832,7 +5832,7 @@ int do_init(int argc, char *argv[]) exit(EXIT_SUCCESS); } - npc->event_do_oninit(); // Init npcs (OnInit) + npc->event_do_oninit( false ); // Init npcs (OnInit) npc->market_fromsql(); /* after OnInit */ if (battle_config.pk_mode) diff --git a/src/map/npc.c b/src/map/npc.c index 247d7109b..5596b8e23 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -450,14 +450,17 @@ int npc_event_do_clock(int tid, int64 tick, int id, intptr_t data) { return c; } -/*========================================== - * OnInit Event execution (the start of the event and watch) - *------------------------------------------*/ -void npc_event_do_oninit(void) +/** + * OnInit event execution (the start of the event and watch) + * @param reload Is the server reloading? + **/ +void npc_event_do_oninit( bool reload ) { ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs."CL_CLL"\n", npc->event_doall("OnInit")); - timer->add_interval(timer->gettick()+100,npc->event_do_clock,0,0,1000); + // This interval has already been added on startup + if( !reload ) + timer->add_interval(timer->gettick()+100,npc->event_do_clock,0,0,1000); } /*========================================== @@ -4294,9 +4297,30 @@ int npc_ev_label_db_clear_sub(DBKey key, DBData *data, va_list args) return 0; } +/** + * Main npc file processing + * @param npc_min Minimum npc id - used to know how many NPCs were loaded + **/ +void npc_process_files( int npc_min ) { + struct npc_src_list *file; // Current file + + 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, false); + } + 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" + "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", + npc_id - npc_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); +} + //Clear then reload npcs files int npc_reload(void) { - struct npc_src_list *nsl; int16 m, i; int npc_new_min = npc_id; struct s_mapiterator* iter; @@ -4358,46 +4382,35 @@ int npc_reload(void) { // reset mapflags map->flags_init(); - //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,false); - } - 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" - "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", - npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); - + // Reprocess npc files and reload constants itemdb->name_constants(); - + npc_process_files( npc_new_min ); + instance->reload(); map->zone_init(); - + npc->motd = npc->name2id("HerculesMOTD"); /* [Ind/Hercules] */ - + //Re-read the NPC Script Events cache. npc->read_event_script(); - /* refresh guild castle flags on both woe setups */ - npc->event_doall("OnAgitInit"); - npc->event_doall("OnAgitInit2"); - - //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")); - - npc->market_fromsql();/* after OnInit */ - + // Execute main initialisation events + // The correct initialisation order is: + // OnInit -> OnInterIfInit -> OnInterIfInitOnce -> OnAgitInit -> OnAgitInit2 + npc->event_do_oninit( true ); + npc->market_fromsql(); // Execute rest of the startup events if connected to char-server. [Lance] - if(!intif->CheckForCharServer()){ + // Executed when connection is established with char-server in chrif_connectack + if( !intif->CheckForCharServer() ) { ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInit")); ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInitOnce")); } + // Refresh guild castle flags on both woe setups + // These events are only executed after receiving castle information from char-server + npc->event_doall("OnAgitInit"); + npc->event_doall("OnAgitInit2"); + return 0; } @@ -4479,7 +4492,6 @@ static void npc_debug_warps(void) { * npc initialization *------------------------------------------*/ int do_init_npc(bool minimal) { - struct npc_src_list *file; int i; memset(&npc->base_ud, 0, sizeof( struct unit_data) ); @@ -4508,28 +4520,17 @@ int do_init_npc(bool minimal) { npc_last_npd = NULL; npc_last_path = NULL; npc_last_ref = NULL; - + + // Should be loaded before npc processing, otherwise labels could overwrite constant values + // and lead to undefined behavior [Panikon] + itemdb->name_constants(); + if (!minimal) { npc->timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE); - // 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,false); - } - 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" - "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n" - "\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); + npc_process_files(START_NPC_NUM); } - itemdb->name_constants(); - if (!minimal) { map->zone_init(); diff --git a/src/map/npc.h b/src/map/npc.h index a277d4968..6e9686d33 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -193,7 +193,7 @@ struct npc_interface { int (*event_doall_id) (const char *name, int rid); int (*event_doall) (const char *name); int (*event_do_clock) (int tid, int64 tick, int id, intptr_t data); - void (*event_do_oninit) (void); + void (*event_do_oninit) ( bool reload ); int (*timerevent_export) (struct npc_data *nd, int i); int (*timerevent) (int tid, int64 tick, int id, intptr_t data); int (*timerevent_start) (struct npc_data *nd, int rid); -- cgit v1.2.3-60-g2f50