From 9d1b39d3facc6d9f1268e036e7b23bd410c683ec Mon Sep 17 00:00:00 2001 From: ultramage Date: Tue, 13 Jan 2009 10:38:54 +0000 Subject: Mobs with nonzero spawn time can now be cached as well, saving some more cpu/memory (bugreport:1197). Fixed dynamic mobs being unloaded without stopping their respawn timer. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13445 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 2 ++ src/map/map.c | 13 ++++++++----- src/map/mob.c | 2 +- src/map/mob.h | 1 + src/map/npc.c | 39 ++++++++++++++++----------------------- src/map/unit.c | 7 ++++++- 6 files changed, 34 insertions(+), 30 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 708fc491a..c4a488f88 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,8 @@ 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. 2009/01/12 + * Mobs with nonzero spawn time can now be cached as well (bugreport:1197) + * Fixed dynamic mobs being unloaded without stopping their respawn timer * Added regen_db to reduce hp/sp processing delays (bugreport:2256) [ultramage] * #command parsing cleaned up. [SketchyPhoenix] - Fixed charname reading problems from r13441 diff --git a/src/map/map.c b/src/map/map.c index a7374a309..14a93c669 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -2129,14 +2129,17 @@ int map_removemobs_sub(struct block_list *bl, va_list ap) struct mob_data *md = (struct mob_data *)bl; nullpo_retr(0, md); - //When not to remove: - //Mob doesn't respawn and is not a slave + //When not to remove mob: + // doesn't respawn and is not a slave if( !md->spawn && !md->master_id ) return 0; - //Mob respawn data is not in cache + // respawn data is not in cache if( md->spawn && !md->spawn->state.dynamic ) return 0; - //Mob is damaged and mob_remove_damaged is off + // hasn't spawned yet + if( md->spawn_timer != INVALID_TIMER ) + return 0; + // is damaged and mob_remove_damaged is off if( !battle_config.mob_remove_damaged && md->status.hp < md->status.max_hp ) return 0; @@ -2174,7 +2177,7 @@ int map_removemobs_timer(int tid, unsigned int tick, int id, intptr data) void map_removemobs(int m) { - if (map[m].mob_delete_timer != -1) + if (map[m].mob_delete_timer != -1) // should never happen return; //Mobs are already scheduled for removal map[m].mob_delete_timer = add_timer(gettick()+battle_config.mob_remove_delay, map_removemobs_timer, m, 0); diff --git a/src/map/mob.c b/src/map/mob.c index 8b522548f..91f5e4600 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -719,7 +719,7 @@ int mob_linksearch(struct block_list *bl,va_list ap) /*========================================== * mob spawn with delay (timer function) *------------------------------------------*/ -static int mob_delayspawn(int tid, unsigned int tick, int id, intptr data) +int mob_delayspawn(int tid, unsigned int tick, int id, intptr data) { struct block_list *bl = map_id2bl(id); if (bl && bl->type == BL_MOB && bl->prev == NULL) diff --git a/src/map/mob.h b/src/map/mob.h index 5e4492e69..bef8324d4 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -216,6 +216,7 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist); int mob_unlocktarget(struct mob_data *md, unsigned int tick); struct mob_data* mob_spawn_dataset(struct spawn_data *data); int mob_spawn(struct mob_data *md); +int mob_delayspawn(int tid, unsigned int tick, int id, intptr data); int mob_setdelayspawn(struct mob_data *md); int mob_parse_dataset(struct spawn_data *data); void mob_log_damage(struct mob_data *md, struct block_list *src, int damage); diff --git a/src/map/npc.c b/src/map/npc.c index fd44ded3a..49ffa8e89 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2531,34 +2531,27 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c } } - //Now that all has been validated. We allocate the actual memory - //that the re-spawn data will use. + //Now that all has been validated. We allocate the actual memory that the re-spawn data will use. data = (struct spawn_data*)aMalloc(sizeof(struct spawn_data)); memcpy(data, &mob, sizeof(struct spawn_data)); - - if( !battle_config.dynamic_mobs || data->delay1 || data->delay2 ) { + + // spawn / cache the new mobs + if( battle_config.dynamic_mobs && map_addmobtolist(data->m, data) >= 0 ) + { + data->state.dynamic = true; + npc_cache_mob += data->num; + + // check if target map has players + // (usually shouldn't occur when map server is just starting, + // but not the case when we do @reloadscript + if( map[data->m].users > 0 ) + npc_parse_mob2(data); + } + else + { data->state.dynamic = false; npc_parse_mob2(data); npc_delay_mob += data->num; - } else { - int index = map_addmobtolist(data->m, data); - if( index >= 0 ) { - data->state.dynamic = true; - // check if target map has players - // (usually shouldn't occur when map server is just starting, - // but not the case when we do @reloadscript - if (map[data->m].users > 0) - npc_parse_mob2(data); - npc_cache_mob += data->num; - } else { - // mobcache is full - // create them as delayed with one second - data->state.dynamic = false; - data->delay1 = 1000; - data->delay2 = 1000; - npc_parse_mob2(data); - npc_delay_mob += data->num; - } } npc_mob++; diff --git a/src/map/unit.c b/src/map/unit.c index 6695abf6b..787b25765 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2029,7 +2029,12 @@ int unit_free(struct block_list *bl, int clrtype) case BL_MOB: { struct mob_data *md = (struct mob_data*)bl; - if( md->deletetimer != -1 ) + if( md->spawn_timer != INVALID_TIMER ) + { + delete_timer(md->spawn_timer,mob_delayspawn); + md->spawn_timer = INVALID_TIMER; + } + if( md->deletetimer != INVALID_TIMER ) { delete_timer(md->deletetimer,mob_timer_delete); md->deletetimer = INVALID_TIMER; -- cgit v1.2.3-70-g09d2