Sfoglia il codice sorgente

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://svn.code.sf.net/p/rathena/svn/trunk@13445 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 16 anni fa
parent
commit
95d25086a6
6 ha cambiato i file con 34 aggiunte e 30 eliminazioni
  1. 2 0
      Changelog-Trunk.txt
  2. 8 5
      src/map/map.c
  3. 1 1
      src/map/mob.c
  4. 1 0
      src/map/mob.h
  5. 16 23
      src/map/npc.c
  6. 6 1
      src/map/unit.c

+ 2 - 0
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 

+ 8 - 5
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);

+ 1 - 1
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)

+ 1 - 0
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);

+ 16 - 23
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++;

+ 6 - 1
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;