diff options
author | panikon <panikon@zoho.com> | 2014-05-10 01:36:18 -0300 |
---|---|---|
committer | panikon <panikon@zoho.com> | 2014-05-10 01:36:18 -0300 |
commit | a2dec941492c9b7e56e3e34600e3fba9937cbf65 (patch) | |
tree | b7fa54d2d8736e355efd8a0738a453f1417a4cbf | |
parent | 6d4ae7670d0acca504d17d27b5c971be6625a311 (diff) | |
download | hercules-a2dec941492c9b7e56e3e34600e3fba9937cbf65.tar.gz hercules-a2dec941492c9b7e56e3e34600e3fba9937cbf65.tar.bz2 hercules-a2dec941492c9b7e56e3e34600e3fba9937cbf65.tar.xz hercules-a2dec941492c9b7e56e3e34600e3fba9937cbf65.zip |
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
-rw-r--r-- | doc/script_commands.txt | 3 | ||||
-rw-r--r-- | src/map/map.c | 2 | ||||
-rw-r--r-- | src/map/npc.c | 105 | ||||
-rw-r--r-- | src/map/npc.h | 2 |
4 files changed, 57 insertions, 55 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 898e4e331..31574d0a2 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -1013,7 +1013,8 @@ OnInit will execute every time the scripts loading is complete, including when they are reloaded with @reloadscript command. OnInterIfInit will execute when the map server connects to a char server, OnInterIfInitOnce will only execute once and will not execute if the map server reconnects -to the char server later. +to the char server later. Note that all those events will be executed upon +scripts reloading. OnAgitStart: OnAgitEnd: 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); |