summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt2
-rw-r--r--src/map/map.c13
-rw-r--r--src/map/mob.c2
-rw-r--r--src/map/mob.h1
-rw-r--r--src/map/npc.c39
-rw-r--r--src/map/unit.c7
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;