From 9858bb5591f495b0e622391a00297366b972e09a Mon Sep 17 00:00:00 2001 From: skyleo Date: Tue, 15 Oct 2019 02:15:21 +0200 Subject: Make slave mobs react to master's chase target This fixes slaves not chasing after master's chase target, when master was immobilized by an Ankle Snare for example midway. --- src/map/battle.c | 3 ++- src/map/battle.h | 1 + src/map/mob.c | 70 +++++++++++++++++++++++++++++++++++++++----------------- src/map/mob.h | 1 + 4 files changed, 53 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 37fc03bca..606c79357 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -4343,7 +4343,7 @@ static struct Damage battle_calc_misc_attack(struct block_list *src, struct bloc } break; } - + battle->reflect_trap(target, src, &md, skill_id); return md; @@ -7321,6 +7321,7 @@ static const struct battle_data { { "mob_remove_delay", &battle_config.mob_remove_delay, 60000, 1000, INT_MAX, }, { "mob_active_time", &battle_config.mob_active_time, 0, 0, INT_MAX, }, { "boss_active_time", &battle_config.boss_active_time, 0, 0, INT_MAX, }, + { "slave_chase_masters_chasetarget", &battle_config.slave_chase_masters_chasetarget, 1, 0, 1, }, { "sg_miracle_skill_duration", &battle_config.sg_miracle_skill_duration, 3600000, 0, INT_MAX, }, { "hvan_explosion_intimate", &battle_config.hvan_explosion_intimate, 45000, 0, 100000, }, { "quest_exp_rate", &battle_config.quest_exp_rate, 100, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index 4400d37d1..3dee6f239 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -405,6 +405,7 @@ struct Battle_Config { int mob_remove_delay; // Dynamic Mobs - delay before removing mobs from a map [Skotlex] int mob_active_time; //Duration through which mobs execute their Hard AI after players leave their area of sight. int boss_active_time; + int slave_chase_masters_chasetarget; int show_hp_sp_drain, show_hp_sp_gain; //[Skotlex] int show_katar_crit_bonus; diff --git a/src/map/mob.c b/src/map/mob.c index e04d6944e..c8226cd57 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -1297,6 +1297,27 @@ static int mob_warpchase_sub(struct block_list *bl, va_list ap) } return 0; } + +/** + * Checks if a monster is currently involved in battle, + * may it be due to aggression or being attacked. + * @param bl: monster's bl + * @return true if in battle, false otherwise + */ +static bool mob_is_in_battle_state(const struct mob_data *md) +{ + nullpo_retr(false, md); + switch (md->state.skillstate) { + case MSS_BERSERK: + case MSS_ANGRY: + case MSS_RUSH: + case MSS_FOLLOW: + return true; + default: + return false; + } +} + /*========================================== * Processing of slave monsters *------------------------------------------*/ @@ -1341,8 +1362,11 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) ) { 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)) + const struct mob_data *m_md = BL_CCAST(BL_MOB, bl); + nullpo_retr(0, m_md); + if (map->search_freecell(&md->bl, bl->m, &x, &y, MOB_SLAVEDISTANCE, MOB_SLAVEDISTANCE, 1) + && (battle_config.slave_chase_masters_chasetarget == 0 || !mob->is_in_battle_state(m_md)) + && unit->walktoxy(&md->bl, x, y, 0)) return 1; } } else if (bl->m != md->bl.m && map_flag_gvg(md->bl.m)) { @@ -1353,26 +1377,29 @@ static int mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) //Avoid attempting to lock the master's target too often to avoid unnecessary overload. [Skotlex] if (DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME && !md->target_id) { - struct unit_data *ud = unit->bl2ud(bl); + struct unit_data *ud = unit->bl2ud(bl); + struct mob_data *m_md = BL_CAST(BL_MOB, bl); + nullpo_retr(0, ud); + nullpo_retr(0, m_md); md->last_linktime = tick; - - if (ud) { - struct block_list *tbl=NULL; - if (ud->target && ud->state.attack_continue) - tbl=map->id2bl(ud->target); - else if (ud->skilltarget) { - tbl = map->id2bl(ud->skilltarget); - //Required check as skilltarget is not always an enemy. [Skotlex] - if (tbl && battle->check_target(&md->bl, tbl, BCT_ENEMY) <= 0) - tbl = NULL; - } - if (tbl && status->check_skilluse(&md->bl, tbl, 0, 0)) { - md->target_id=tbl->id; - md->min_chase=md->db->range3+distance_bl(&md->bl, tbl); - if(md->min_chase>MAX_MINCHASE) - md->min_chase=MAX_MINCHASE; - return 1; - } + struct block_list *tbl = NULL; + + if (battle_config.slave_chase_masters_chasetarget == 1 && m_md->target_id != 0) { // possibly chasing something + tbl = map->id2bl(m_md->target_id); + } else if (ud->target != 0 && ud->state.attack_continue != 0) { + tbl = map->id2bl(ud->target); + } else if (ud->skilltarget != 0) { + tbl = map->id2bl(ud->skilltarget); + //Required check as skilltarget is not always an enemy. [Skotlex] + if (tbl != NULL && battle->check_target(&md->bl, tbl, BCT_ENEMY) <= 0) + tbl = NULL; + } + if (tbl != NULL && status->check_skilluse(&md->bl, tbl, 0, 0) != 0) { + md->target_id = tbl->id; + md->min_chase = md->db->range3 + distance_bl(&md->bl, tbl); + if (md->min_chase > MAX_MINCHASE) + md->min_chase = MAX_MINCHASE; + return 1; } } return 0; @@ -5805,6 +5832,7 @@ void mob_defaults(void) mob->ai_sub_hard_bg_ally = mob_ai_sub_hard_bg_ally; mob->ai_sub_hard_lootsearch = mob_ai_sub_hard_lootsearch; mob->warpchase_sub = mob_warpchase_sub; + mob->is_in_battle_state = mob_is_in_battle_state; mob->ai_sub_hard_slavemob = mob_ai_sub_hard_slavemob; mob->unlocktarget = mob_unlocktarget; mob->randomwalk = mob_randomwalk; diff --git a/src/map/mob.h b/src/map/mob.h index a48c4cc74..9b0f6ffe0 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -529,6 +529,7 @@ struct mob_interface { int (*ai_sub_hard_bg_ally) (struct block_list *bl, va_list ap); int (*ai_sub_hard_lootsearch) (struct block_list *bl, va_list ap); int (*warpchase_sub) (struct block_list *bl, va_list ap); + bool (*is_in_battle_state) (const struct mob_data *md); int (*ai_sub_hard_slavemob) (struct mob_data *md, int64 tick); int (*unlocktarget) (struct mob_data *md, int64 tick); int (*randomwalk) (struct mob_data *md, int64 tick); -- cgit v1.2.3-70-g09d2