From da375a04c13cb590405d3491688f1666d2eaf8dc Mon Sep 17 00:00:00 2001 From: Aleos Date: Wed, 14 Dec 2022 14:17:41 -0500 Subject: [PATCH] Adds battle config mob_respawn_time (#7312) * Adjusts the minimum respawn time of a monster to be 1 second as it is officially. * Adds a battle config to allow for easy adjustment. * Monsters that don't define a delay1 for permanent spawn scripts are defaulted to 5 seconds. Thanks to @mrjnumber1, @vstumpf, @Lemongrass3110, and @Atemo! Co-authored-by: Lemongrass3110 --- conf/battle/monster.conf | 5 ++++ doc/script_commands.txt | 3 +- npc/pre-re/mobs/dungeons/nyd_dun.txt | 2 +- npc/pre-re/mobs/dungeons/prt_maze.txt | 2 +- npc/re/mobs/dungeons/glastheim.txt | 14 +++++----- npc/re/mobs/verus.txt | 40 +++++++++++++-------------- src/map/battle.cpp | 2 ++ src/map/battle.hpp | 2 ++ src/map/mob.cpp | 13 ++++----- src/map/npc.cpp | 10 +++++-- 10 files changed, 54 insertions(+), 39 deletions(-) diff --git a/conf/battle/monster.conf b/conf/battle/monster.conf index bfd1217f86..7adb358440 100644 --- a/conf/battle/monster.conf +++ b/conf/battle/monster.conf @@ -297,3 +297,8 @@ achievement_mob_share: no // Should slaves teleport back to their master if they get too far during chase? (Note 1) // Default (Official): no slave_stick_with_master: no + +// Absolute minimum respawn time in milliseconds of a monster. +// Also used in delaying the spawning of guardians when a guild is not loaded. +// Default (Official): 1000 +mob_respawn_time: 1000 diff --git a/doc/script_commands.txt b/doc/script_commands.txt index a6d48a2c0b..113e59535e 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -159,7 +159,8 @@ executed, it is affected by spawn rates in 'battle_athena.conf'. Delay1 and delay2 control monster respawn delays - the first one is the fixed base respawn time, and the second is random variance on top of the base time. Both values are given in milliseconds (1000 = 1 second). -Note that the server also enforces a minimum respawn delay of 5 seconds. +Note that the server also enforces a minimum respawn delay of 1 second (See +/conf/battle/monster.conf::mob_respawn_time). Event is a script event to be executed when the mob is killed. The event must be in the form "NPCName::OnEventName" to execute, and the event name label diff --git a/npc/pre-re/mobs/dungeons/nyd_dun.txt b/npc/pre-re/mobs/dungeons/nyd_dun.txt index 751a1a308a..112a94c7dc 100644 --- a/npc/pre-re/mobs/dungeons/nyd_dun.txt +++ b/npc/pre-re/mobs/dungeons/nyd_dun.txt @@ -14,7 +14,7 @@ // nyd_dun01 - Yggdrasil Root Dungeon //================================================== nyd_dun01,0,0 monster Draco 2013,40 -nyd_dun01,0,0 monster Draco's Egg 2014,10,0,0,0 +nyd_dun01,0,0 monster Draco's Egg 2014,10 nyd_dun01,0,0 monster Aqua Elemental 2016,20 nyd_dun01,0,0 monster Dark Pinguicula 2015,10 nyd_dun01,0,0 monster Rata 2017,2,900000 diff --git a/npc/pre-re/mobs/dungeons/prt_maze.txt b/npc/pre-re/mobs/dungeons/prt_maze.txt index 2b868dd249..abd058709b 100644 --- a/npc/pre-re/mobs/dungeons/prt_maze.txt +++ b/npc/pre-re/mobs/dungeons/prt_maze.txt @@ -84,7 +84,7 @@ prt_maze03,50,150,70,70 monster Vagabond Wolf 1092,1,1920000,150000 prt_maze03,170,170,70,70 monster Mantis 1139,30,60000,30000 prt_maze03,170,170,70,70 monster Eclipse 1093,1,1920000,150000 prt_maze03,23,23,70,70 monster Mastering 1090,1,1920000,150000 -prt_maze03,100,100,80,80 monster Baphomet Jr. 1101,25,0,0,0 +prt_maze03,100,100,80,80 monster Baphomet Jr. 1101,25 prt_maze03,0,0,0,0 boss_monster Baphomet 1039,1,7200000,600000,1 prt_maze03,61,98,10,10 monster Shining Plant 1083,1,1800000,900000 prt_maze03,61,98,10,10 monster Blue Plant 1079,1,1800000,900000 diff --git a/npc/re/mobs/dungeons/glastheim.txt b/npc/re/mobs/dungeons/glastheim.txt index 15d1b990a9..7f29dca520 100644 --- a/npc/re/mobs/dungeons/glastheim.txt +++ b/npc/re/mobs/dungeons/glastheim.txt @@ -184,11 +184,11 @@ gl_step,0,0 monster Mimic 1191,6,5000 //================================================== // gl_cas02_ - Nightmare Mode 2f //================================================== -gl_cas02_,0,0 monster Evil Druid (Nightmare) 2480,4,0,0,0 -gl_cas02_,0,0 monster Chimera (Nightmare) 2485,1,0,0,0 -gl_cas02_,0,0 monster Mimic (Nightmare) 2479,19,0,0,0 -gl_cas02_,0,0 monster Rideword (Nightmare) 2478,10,0,0,0 -gl_cas02_,0,0 monster Wanderer (Nightmare) 2477,60,0,0,0 +gl_cas02_,0,0 monster Evil Druid (Nightmare) 2480,4,5000 +gl_cas02_,0,0 monster Chimera (Nightmare) 2485,1,5000 +gl_cas02_,0,0 monster Mimic (Nightmare) 2479,19,5000 +gl_cas02_,0,0 monster Rideword (Nightmare) 2478,10,5000 +gl_cas02_,0,0 monster Wanderer (Nightmare) 2477,60,5000 gl_cas02_,0,0 monster Mysteltainn 1203,1,7200000,3600000 gl_cas02_,0,0 monster Alice 1275,1,5000 gl_cas02_,102,180 monster Whisper 1185,1,1800000,900000 @@ -197,8 +197,8 @@ gl_cas02_,0,0 monster Baphomet (Nightmare) 2483,1,7200000,0,0 //================================================== // gl_chyard_ - Nightmare Mode Churchyard //================================================== -gl_chyard_,0,0 monster Wraith Dead (Nightmare) 2481,91,0,0,0 -gl_chyard_,0,0 monster Wraith Dead 1291,31,0,0,0 +gl_chyard_,0,0 monster Wraith Dead (Nightmare) 2481,91,5000 +gl_chyard_,0,0 monster Wraith Dead 1291,31,5000 gl_chyard_,0,0 monster Evil Druid (Nightmare) 2480,22,60000,0,0 gl_chyard_,0,0 monster Mimic (Nightmare) 2479,34,60000,0,0 gl_chyard_,0,0,0,0 boss_monster Dark Lord 1272,1,3600000,600000,1 diff --git a/npc/re/mobs/verus.txt b/npc/re/mobs/verus.txt index b98c3ffeee..8f7bf2f9e0 100644 --- a/npc/re/mobs/verus.txt +++ b/npc/re/mobs/verus.txt @@ -10,28 +10,28 @@ //============================================================ // ver_eju -ver_eju,0,0,0,0 monster Recon Robot 3154,50,0,0,0 -ver_eju,0,0,0,0 monster Excavator Robot 3153,10,0,0,0 +ver_eju,0,0,0,0 monster Recon Robot 3154,50,5000 +ver_eju,0,0,0,0 monster Excavator Robot 3153,10,5000 // ver_tunn -ver_tunn,0,0,0,0 monster Recon Robot 3154,5,0,0,0 +ver_tunn,0,0,0,0 monster Recon Robot 3154,5,30000 // verus01 -verus01,0,0,0,0 monster Green Cenere 3247,50,0,0,0 -verus01,0,0,0,0 monster Explorer Robot Turbo 3249,25,0,0,0 -verus01,0,0,0,0 monster Repair Robot Turbo 3248,25,0,0,0 +verus01,0,0,0,0 monster Green Cenere 3247,50,5000 +verus01,0,0,0,0 monster Explorer Robot Turbo 3249,25,5000 +verus01,0,0,0,0 monster Repair Robot Turbo 3248,25,5000 // verus02 -verus02,0,0,0,0 monster Repair Robot Turbo 3248,50,0,0,0 -verus02,0,0,0,0 monster Explorer Robot Turbo 3249,50,0,0,0 +verus02,0,0,0,0 monster Repair Robot Turbo 3248,50,5000 +verus02,0,0,0,0 monster Explorer Robot Turbo 3249,50,5000 // verus03 -verus03,0,0,0,0 monster Illegal Promotion 3159,40,0,0,0 -verus03,0,0,0,0 monster Explorer Robot 3156,50,0,0,0 -verus03,0,0,0,0 monster Repair Robot 3155,50,0,0,0 -verus03,0,0,0,0 monster Ruin Grace Believer 3158,10,0,0,0 +verus03,0,0,0,0 monster Illegal Promotion 3159,40,5000 +verus03,0,0,0,0 monster Explorer Robot 3156,50,5000 +verus03,0,0,0,0 monster Repair Robot 3155,50,5000 +verus03,0,0,0,0 monster Ruin Grace Believer 3158,10,5000 // un_bunker -un_bunker,0,0,0,0 monster Thief Bug 1051,6,0,0,0 -un_bunker,0,0,0,0 monster Smelly Ghoul 3255,68,0,0,0 -un_bunker,0,0,0,0 monster Smelly Zombie 3256,80,0,0,0 -un_bunker,0,0,0,0 monster Machine Component 3250,28,0,0,0 -un_bunker,0,0,0,0 monster DR815 3252,14,0,0,0 -un_bunker,0,0,0,0 monster GC109 3251,10,0,0,0 -un_bunker,0,0,0,0 monster Black Mushroom 1084,1,0,0,0 -un_bunker,0,0,0,0 monster Chonchon 1011,2,0,0,0 +un_bunker,0,0,0,0 monster Thief Bug 1051,6,5000 +un_bunker,0,0,0,0 monster Smelly Ghoul 3255,68,5000 +un_bunker,0,0,0,0 monster Smelly Zombie 3256,80,5000 +un_bunker,0,0,0,0 monster Machine Component 3250,28,5000 +un_bunker,0,0,0,0 monster DR815 3252,14,5000 +un_bunker,0,0,0,0 monster GC109 3251,10,5000 +un_bunker,0,0,0,0 monster Black Mushroom 1084,1,5000 +un_bunker,0,0,0,0 monster Chonchon 1011,2,5000 diff --git a/src/map/battle.cpp b/src/map/battle.cpp index d8998d0758..facd7754f0 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -10283,6 +10283,8 @@ static const struct _battle_data { { "feature.dynamicnpc_rangey", &battle_config.feature_dynamicnpc_rangey, 2, 0, INT_MAX, }, { "feature.dynamicnpc_direction", &battle_config.feature_dynamicnpc_direction, 0, 0, 1, }, + { "mob_respawn_time", &battle_config.mob_respawn_time, 1000, 1000, INT_MAX, }, + #include "../custom/battle_config_init.inc" }; diff --git a/src/map/battle.hpp b/src/map/battle.hpp index 0ead94920d..98ffd16bbc 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -722,6 +722,8 @@ struct Battle_Config int feature_dynamicnpc_rangey; int feature_dynamicnpc_direction; + int mob_respawn_time; + #include "../custom/battle_config_struct.inc" }; diff --git a/src/map/mob.cpp b/src/map/mob.cpp index ec9fab2323..2f1e6fc57b 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -695,8 +695,8 @@ int mob_once_spawn(struct map_session_data* sd, int16 m, int16 x, int16 y, const md->guardian_data->emblem_id = g->emblem_id; memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH); } - else if (gc->guild_id) //Guild not yet available, retry in 5. - add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id); + else if (gc->guild_id) // Guild is not yet available, retry after the configured timespan. + add_timer(gettick() + battle_config.mob_respawn_time,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id); } } // end addition [Valaris] @@ -914,7 +914,7 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam memcpy (md->guardian_data->guild_name, g->name, NAME_LENGTH); md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP); } else if (md->guardian_data->guild_id) - add_timer(gettick()+5000,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id); + add_timer(gettick() + battle_config.mob_respawn_time,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id); mob_spawn(md); return md->bl.id; @@ -1073,8 +1073,7 @@ int mob_setdelayspawn(struct mob_data *md) spawntime = spawntime/100*battle_config.mob_spawn_delay; } - if (spawntime < 5000) //Monsters should never respawn faster than within 5 seconds - spawntime = 5000; + spawntime = u32max(1000, spawntime); //Monsters should never respawn faster than 1 second if( md->spawn_timer != INVALID_TIMER ) delete_timer(md->spawn_timer, mob_delayspawn); @@ -1126,7 +1125,7 @@ int mob_spawn (struct mob_data *md) { // retry again later if( md->spawn_timer != INVALID_TIMER ) delete_timer(md->spawn_timer, mob_delayspawn); - md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0); + md->spawn_timer = add_timer(tick + battle_config.mob_respawn_time,mob_delayspawn,md->bl.id,0); return 1; } } @@ -1134,7 +1133,7 @@ int mob_spawn (struct mob_data *md) { // retry again later (players on sight) if( md->spawn_timer != INVALID_TIMER ) delete_timer(md->spawn_timer, mob_delayspawn); - md->spawn_timer = add_timer(tick+5000,mob_delayspawn,md->bl.id,0); + md->spawn_timer = add_timer(tick + battle_config.mob_respawn_time,mob_delayspawn,md->bl.id,0); return 1; } } diff --git a/src/map/npc.cpp b/src/map/npc.cpp index cf5939f027..2ad192bca6 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -5118,7 +5118,7 @@ void npc_parse_mob2(struct spawn_data* mob) static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) { - int num, mob_id, mob_lv = -1, size = -1, w1count; + int num, mob_id, mob_lv = -1, delay = 5000, size = -1, w1count, w4count; short m, x = 0, y = 0, xs = -1, ys = -1; char mapname[MAP_NAME_LENGTH_EXT], mobname[NAME_LENGTH], sprite[NAME_LENGTH]; struct spawn_data mob, *data; @@ -5133,7 +5133,7 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c // w4=,{,{,{,{,{,}}}}} if( ( w1count = sscanf(w1, "%15[^,],%6hd,%6hd,%6hd,%6hd", mapname, &x, &y, &xs, &ys) ) < 1 || sscanf(w3, "%23[^,],%11d", mobname, &mob_lv) < 1 - || sscanf(w4, "%23[^,],%11d,%11u,%11u,%77[^,],%11d,%11d[^\t\r\n]", sprite, &num, &mob.delay1, &mob.delay2, mob.eventname, &size, &ai) < 2 ) + || ( w4count = sscanf(w4, "%23[^,],%11d,%11u,%11u,%77[^,],%11d,%11d[^\t\r\n]", sprite, &num, &delay, &mob.delay2, mob.eventname, &size, &ai) ) < 2 ) { ShowError("npc_parse_mob: Invalid mob definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); return strchr(start,'\n');// skip and continue @@ -5181,6 +5181,12 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c return strchr(start,'\n');// skip and continue } + if (w4count > 2 && delay != 5000 && delay < battle_config.mob_respawn_time) { + ShowWarning("npc_parse_mob: Invalid delay %u for mob ID %d (file '%s', line '%d'), defaulting to 5 seconds.\n", delay, mob_id, filepath, strline(buffer, start - buffer)); + mob.delay1 = 5000; + } else + mob.delay1 = delay; + if( mob.state.size > SZ_BIG && size != -1 ) { ShowError("npc_parse_mob: Invalid size number %d for mob ID %d (file '%s', line '%d').\n", mob.state.size, mob_id, filepath, strline(buffer, start - buffer));