diff --git a/conf/battle/monster.conf b/conf/battle/monster.conf index 0c616db30d..de4e69f664 100644 --- a/conf/battle/monster.conf +++ b/conf/battle/monster.conf @@ -280,3 +280,7 @@ boss_nopc_move_rate: 100 // When killing a monster, do AG_BATTLE type achievements trigger for everyone in the same party within the area? // Area is limited to area_size battle config. 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 diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 71b153f616..853e537539 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -8952,6 +8952,7 @@ static const struct _battle_data { { "ping_time", &battle_config.ping_time, 20, 0, 99999999, }, { "show_skill_scale", &battle_config.show_skill_scale, 1, 0, 1, }, { "achievement_mob_share", &battle_config.achievement_mob_share, 0, 0, 1, }, + { "slave_stick_with_master", &battle_config.slave_stick_with_master, 0, 0, 1, }, #include "../custom/battle_config_init.inc" }; diff --git a/src/map/battle.hpp b/src/map/battle.hpp index a6ebe78a20..755fde6386 100644 --- a/src/map/battle.hpp +++ b/src/map/battle.hpp @@ -682,6 +682,7 @@ struct Battle_Config int ping_time; int show_skill_scale; int achievement_mob_share; + int slave_stick_with_master; #include "../custom/battle_config_struct.inc" }; diff --git a/src/map/mob.cpp b/src/map/mob.cpp index c573f0aef5..b375a46c0f 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -1437,34 +1437,36 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md,t_tick tick) if(status_has_mode(&md->status,MD_CANMOVE)) { //If the mob can move, follow around. [Check by Skotlex] - int old_dist; + int old_dist = md->master_dist; // Distance with between slave and master is measured. - old_dist=md->master_dist; - md->master_dist=distance_bl(&md->bl, bl); + md->master_dist = distance_bl(&md->bl, bl); - // Since the master was in near immediately before, teleport is carried out and it pursues. - if(bl->m != md->bl.m || - (old_dist<10 && md->master_dist>18) || - md->master_dist > MAX_MINCHASE - ){ - md->master_dist = 0; - unit_warp(&md->bl,bl->m,bl->x,bl->y,CLR_TELEPORT); - return 1; + if (battle_config.slave_stick_with_master) { + // Since the master was in near immediately before, teleport is carried out and it pursues. + if (bl->m != md->bl.m || (old_dist < 10 && md->master_dist > 18) || md->master_dist > MAX_MINCHASE) { + md->master_dist = 0; + unit_warp(&md->bl, bl->m, bl->x, bl->y, CLR_TELEPORT); + return 1; + } } if(md->target_id) //Slave is busy with a target. return 0; // Approach master if within view range, chase back to Master's area also if standing on top of the master. - if((md->master_dist>MOB_SLAVEDISTANCE || md->master_dist == 0) && - unit_can_move(&md->bl)) - { - short x = bl->x, y = bl->y; - mob_stop_attack(md); - if(map_search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1) - && unit_walktoxy(&md->bl, x, y, 0)) - return 1; + if ((md->master_dist > MOB_SLAVEDISTANCE || md->master_dist == 0) && unit_can_move(&md->bl)) { + int16 x = bl->x, y = bl->y; + + if (map_search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1)) { + if (unit_walktoxy(&md->bl, x, y, 0) == 0) { // Slave is too far from master (outside of battle_config.max_walk_path range), stay put + mob_stop_walking(md, USW_FIXPOS); + return 0; // Fail here so target will be picked back up when in range + } else { // Slave will walk back to master if in range + mob_stop_attack(md); + return 1; + } + } } } else if (bl->m != md->bl.m && map_flag_gvg2(md->bl.m)) { //Delete the summoned mob if it's in a gvg ground and the master is elsewhere. [Skotlex] @@ -1803,9 +1805,14 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick) md->attacked_id = md->norm_attacked_id = 0; } + bool slave_lost_target = false; + // Processing of slave monster - if (md->master_id > 0 && mob_ai_sub_hard_slavemob(md, tick)) - return true; + if (md->master_id > 0) { + if (mob_ai_sub_hard_slavemob(md, tick) == 1) + return true; + slave_lost_target = true; + } // Scan area for targets if (!tbl && can_move && mode&MD_LOOTER && md->lootitems && DIFF_TICK(tick, md->ud.canact_tick) > 0 && @@ -1814,7 +1821,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick) map_foreachinshootrange (mob_ai_sub_hard_lootsearch, &md->bl, view_range, BL_ITEM, md, &tbl); } - if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW) + if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW || slave_lost_target) { map_foreachinallrange (mob_ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode); }