diff --git a/src/server/game/AI/NpcBots/bot_ai.cpp b/src/server/game/AI/NpcBots/bot_ai.cpp index 81f5129939c07..1807c1efdc50e 100644 --- a/src/server/game/AI/NpcBots/bot_ai.cpp +++ b/src/server/game/AI/NpcBots/bot_ai.cpp @@ -2397,7 +2397,7 @@ void bot_ai::SetStats(bool force) case DRUID_TREE_FORM: case DRUID_TRAVEL_FORM: case DRUID_AQUATIC_FORM: - //case DRUID_FLIGHT_FORM: + case DRUID_FLIGHT_FORM: case BOT_CLASS_BM: case BOT_CLASS_SPHYNX: case BOT_CLASS_ARCHMAGE: @@ -2468,7 +2468,7 @@ void bot_ai::SetStats(bool force) case DRUID_TREE_FORM: case DRUID_TRAVEL_FORM: case DRUID_AQUATIC_FORM: - //case DRUID_FLIGHT_FORM: + case DRUID_FLIGHT_FORM: strmult = 2.f; agimult = 0.f; break; case BOT_CLASS_BM: strmult = 0.f; agimult = 9.f; break; @@ -4579,7 +4579,7 @@ bool bot_ai::CheckAttackTarget() case DRUID_TREE_FORM: case DRUID_TRAVEL_FORM: case DRUID_AQUATIC_FORM: - //case DRUID_FLIGHT_FORM: + case DRUID_FLIGHT_FORM: ranged = true; break; case DRUID_MOONKIN_FORM: @@ -5854,19 +5854,24 @@ uint32 bot_ai::_selectMountSpell() const } else //if (can_fly) { - static const MountArray MOUNTS_150_ALLIANCE = { BOT_MOUNT_FLY_ALLIANCE_150_1, BOT_MOUNT_FLY_ALLIANCE_150_2, BOT_MOUNT_FLY_ALLIANCE_150_3 }; - static const MountArray MOUNTS_150_HORDE = { BOT_MOUNT_FLY_HORDE_150_1, BOT_MOUNT_FLY_HORDE_150_2, BOT_MOUNT_FLY_HORDE_150_3 }; - static const MountArray MOUNTS_280_ALLIANCE = { BOT_MOUNT_FLY_ALLIANCE_280_1, BOT_MOUNT_FLY_ALLIANCE_280_2, BOT_MOUNT_FLY_ALLIANCE_280_3 }; - static const MountArray MOUNTS_280_HORDE = { BOT_MOUNT_FLY_HORDE_280_1, BOT_MOUNT_FLY_HORDE_280_2, BOT_MOUNT_FLY_HORDE_280_3 }; + if (GetBotClass() == BOT_CLASS_DRUID && GetSpell(33943)) + myMountSpellId = useSlowMount ? 33943 : GetSpell(33943); + else + { + static const MountArray MOUNTS_150_ALLIANCE = { BOT_MOUNT_FLY_ALLIANCE_150_1, BOT_MOUNT_FLY_ALLIANCE_150_2, BOT_MOUNT_FLY_ALLIANCE_150_3 }; + static const MountArray MOUNTS_150_HORDE = { BOT_MOUNT_FLY_HORDE_150_1, BOT_MOUNT_FLY_HORDE_150_2, BOT_MOUNT_FLY_HORDE_150_3 }; + static const MountArray MOUNTS_280_ALLIANCE = { BOT_MOUNT_FLY_ALLIANCE_280_1, BOT_MOUNT_FLY_ALLIANCE_280_2, BOT_MOUNT_FLY_ALLIANCE_280_3 }; + static const MountArray MOUNTS_280_HORDE = { BOT_MOUNT_FLY_HORDE_280_1, BOT_MOUNT_FLY_HORDE_280_2, BOT_MOUNT_FLY_HORDE_280_3 }; - Optional myMounts; - if (me->GetRaceMask() & RACEMASK_ALLIANCE) - myMounts = useSlowMount ? MOUNTS_150_ALLIANCE : MOUNTS_280_ALLIANCE; - else if (me->GetRaceMask() & RACEMASK_HORDE) - myMounts = useSlowMount ? MOUNTS_150_HORDE : MOUNTS_280_HORDE; + Optional myMounts; + if (me->GetRaceMask() & RACEMASK_ALLIANCE) + myMounts = useSlowMount ? MOUNTS_150_ALLIANCE : MOUNTS_280_ALLIANCE; + else if (me->GetRaceMask() & RACEMASK_HORDE) + myMounts = useSlowMount ? MOUNTS_150_HORDE : MOUNTS_280_HORDE; - if (myMounts) - myMountSpellId = (*myMounts)[me->GetEntry() % myMounts->size()]; + if (myMounts) + myMountSpellId = (*myMounts)[me->GetEntry() % myMounts->size()]; + } } } @@ -5885,22 +5890,26 @@ void bot_ai::_updateMountedState() bool aura = me->HasAuraType(SPELL_AURA_MOUNTED); bool mounted = me->IsMounted() && (_botclass != BOT_CLASS_ARCHMAGE || aura); bool template_fly = me->GetCreatureTemplate()->Movement.Flight != CreatureFlightMovementType::None; + bool druid_fly = GetBotStance() == DRUID_FLIGHT_FORM; Unit const* victim = me->GetVictim(); //allow dismount - if (!CanMount() && !aura && !mounted) + if (!CanMount() && !aura && !mounted && !druid_fly) return; - if ((aura || mounted || template_fly) && - (!master->IsMounted() || aura != mounted || (!mounted && template_fly) || + if ((aura || mounted || template_fly || druid_fly) && + (!master->IsMounted() || aura != mounted || (!mounted && !druid_fly && template_fly) || (me->IsInCombat() && (opponent || disttarget)) || (IAmFree() && victim && me->IsWithinDist(victim, IsMelee() ? 5.0f : GetSpellAttackRange(true), false)))) { - DismountBot(); + if (druid_fly) + removeShapeshiftForm(); + else + DismountBot(); return; } - if (me->IsMounted() || me->GetVehicle() || me->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) || !IsOutdoors() || + if (druid_fly || me->IsMounted() || me->GetVehicle() || me->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) || !IsOutdoors() || master->IsInCombat() || me->IsInCombat() || me->GetVictim() || IsCasting() || IsFlagCarrier(me) || (HasBotCommandState(BOT_COMMAND_STAY) && GetBG() && GetBG()->GetStatus() != STATUS_IN_PROGRESS)) return; @@ -7401,7 +7410,7 @@ void bot_ai::OnSpellHit(Unit* caster, SpellInfo const* spell) { uint32 const auraname = spell->_effects[i].ApplyAuraName; //remove pet on mount - if (auraname == SPELL_AURA_MOUNTED) + if (auraname == SPELL_AURA_MOUNTED || (!spell->HasAura(SPELL_AURA_MOUNTED) && auraname == SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED)) { //TC_LOG_ERROR("entities.unit", "OnSpellHit: mount on {}", me->GetName()); if (master->HasAuraType(SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED) || @@ -7419,7 +7428,8 @@ void bot_ai::OnSpellHit(Unit* caster, SpellInfo const* spell) { if (spell->_effects[j].ApplyAuraName != SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED && spell->_effects[j].ApplyAuraName != SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - spell->_effects[j].ApplyAuraName != SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED) + spell->_effects[j].ApplyAuraName != SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED && + !(GetBotStance() == DRUID_FLIGHT_FORM && spell->_effects[j].ApplyAuraName == SPELL_AURA_MOD_INCREASE_SPEED)) continue; if (AuraEffect* meff = mount->GetEffect(j)) { diff --git a/src/server/game/AI/NpcBots/bot_druid_ai.cpp b/src/server/game/AI/NpcBots/bot_druid_ai.cpp index 08f5ce2bfbe7a..2bab904a127fa 100644 --- a/src/server/game/AI/NpcBots/bot_druid_ai.cpp +++ b/src/server/game/AI/NpcBots/bot_druid_ai.cpp @@ -81,7 +81,7 @@ enum DruidBaseSpells TREE_OF_LIFE_FORM_1 = 33891, TRAVEL_FORM_1 = 783, AQUATIC_FORM_1 = 1066, - //FLIGHT_FORM_1 = 0,//niy + FLIGHT_FORM_1 = 33943, ABOLISH_POISON_1 = 2893,//manual use only CURE_POISON_1 = 8946, REMOVE_CURSE_1 = 2782, @@ -316,6 +316,9 @@ class druid_bot : public CreatureScript break; //case FORM_FLIGHT: //case FORM_FLIGHT_EPIC: + case DRUID_FLIGHT_FORM: + me->RemoveAurasDueToSpell(GetSpell(FLIGHT_FORM_1)); + break; default: break; } @@ -1199,9 +1202,9 @@ class druid_bot : public CreatureScript case DRUID_CAT_FORM: sshift = GetSpell(CAT_FORM_1); break; case DRUID_MOONKIN_FORM: sshift = GetSpell(MOONKIN_FORM_1); break; case DRUID_TREE_FORM: sshift = GetSpell(TREE_OF_LIFE_FORM_1);break; - //case DRUID_FLIGHT_FORM: sshift = GetSpell(FLIGHT_FORM_1); break; case DRUID_TRAVEL_FORM: sshift = GetSpell(TRAVEL_FORM_1); break; case DRUID_AQUATIC_FORM: sshift = GetSpell(AQUATIC_FORM_1); break; + case DRUID_FLIGHT_FORM: sshift = GetSpell(FLIGHT_FORM_1); break; case BOT_STANCE_NONE: sshift = GetSpell(TRAVEL_FORM_1); break; default: sshift = 0; break; } @@ -1666,13 +1669,13 @@ class druid_bot : public CreatureScript me->SetPowerType(POWER_MANA); } break; - //case DRUID_FLIGHT_FORM: - // if (me->GetPowerType() != POWER_MANA) - // { - // //TC_LOG_ERROR("entities.player", "druid_bot::setStats(): has to set powerType to POWER_MANA (flight)"); - // me->SetPowerType(POWER_MANA); - // } - // break; + case DRUID_FLIGHT_FORM: + if (me->GetPowerType() != POWER_MANA) + { + //TC_LOG_ERROR("entities.player", "druid_bot::setStats(): has to set powerType to POWER_MANA (flight)"); + me->SetPowerType(POWER_MANA); + } + break; case BOT_STANCE_NONE: if (me->GetPowerType() != POWER_MANA) { @@ -2461,8 +2464,8 @@ class druid_bot : public CreatureScript setStats(DRUID_TRAVEL_FORM); else if (baseId == AQUATIC_FORM_1) setStats(DRUID_AQUATIC_FORM); - //else if (baseId == FLIGHT_FORM_1) - // setStats(DRUID_FLIGHT_FORM); + else if (baseId == FLIGHT_FORM_1) + setStats(DRUID_FLIGHT_FORM); //Cat Form: delay prowl just a little bit if (baseId == CAT_FORM_1 && GetSpell(PROWL_1) && GetSpellCooldown(PROWL_1) < 300) @@ -2725,6 +2728,7 @@ class druid_bot : public CreatureScript InitSpellMap(FAERIE_FIRE_NORMAL_1); InitSpellMap(TRAVEL_FORM_1); InitSpellMap(AQUATIC_FORM_1); + InitSpellMap(FLIGHT_FORM_1); InitSpellMap(CURE_POISON_1); InitSpellMap(ABOLISH_POISON_1); InitSpellMap(REMOVE_CURSE_1); @@ -2835,6 +2839,8 @@ class druid_bot : public CreatureScript return true; case AQUATIC_FORM_1: return me->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && me->IsUnderWater(); + case FLIGHT_FORM_1: + return master->IsMounted() && !me->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) && !me->IsUnderWater(); case TYPHOON_1: case STARFALL_1: case MOONKIN_FORM_1: diff --git a/src/server/game/AI/NpcBots/botcommon.h b/src/server/game/AI/NpcBots/botcommon.h index 4f241c6867142..0e12782e0a597 100644 --- a/src/server/game/AI/NpcBots/botcommon.h +++ b/src/server/game/AI/NpcBots/botcommon.h @@ -226,7 +226,7 @@ enum BotStances DRUID_TREE_FORM, DRUID_TRAVEL_FORM, DRUID_AQUATIC_FORM, - //DRUID_FLIGHT_FORM //NYI + DRUID_FLIGHT_FORM }; enum BotRoles : uint32