diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 0504b6b7..2c917074 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -310,24 +310,22 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) bot->SetPower(bot->getPowerType(), bot->GetMaxPower(bot->getPowerType())); } - if (!CanUpdateAI()) - return; - - // check activity AllowActivity(); - // if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) { - // return; - // } Spell* currentSpell = bot->GetCurrentSpell(CURRENT_GENERIC_SPELL); - if (currentSpell && currentSpell->getState() == SPELL_STATE_CASTING && currentSpell->GetCastTime()) + if (currentSpell && currentSpell->getState() == SPELL_STATE_PREPARING) { - nextAICheckDelay = currentSpell->GetCastTime() + sPlayerbotAIConfig->reactDelay; - SetNextCheckDelay(nextAICheckDelay); - if (!CanUpdateAI()) - return; + if (currentSpell->m_targets.GetUnitTarget() && !currentSpell->m_targets.GetUnitTarget()->IsAlive()) + { + bot->InterruptSpell(CURRENT_GENERIC_SPELL); + SetNextCheckDelay(sPlayerbotAIConfig->reactDelay); + } + return; } + if (!CanUpdateAI()) + return; + if (!bot->InBattleground() && !bot->inRandomLfgDungeon() && bot->GetGroup()) { Player* leader = bot->GetGroup()->GetLeader(); @@ -898,9 +896,9 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) p >> casterGuid.ReadAsPacked(); if (casterGuid != bot->GetGUID()) return; - + uint8 count, result; uint32 spellId; - p >> spellId; + p >> count >> spellId >> result; SpellInterrupted(spellId); return; } @@ -1135,21 +1133,15 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) void PlayerbotAI::SpellInterrupted(uint32 spellid) { + for (uint8 type = CURRENT_MELEE_SPELL; type < CURRENT_CHANNELED_SPELL; type++) + { + Spell* spell = bot->GetCurrentSpell((CurrentSpellTypes)type); + if (!spell) + continue; + if (spell->GetSpellInfo()->Id == spellid) + bot->InterruptSpell((CurrentSpellTypes)type); + } LastSpellCast& lastSpell = aiObjectContext->GetValue("last spell cast")->Get(); - if (!spellid || lastSpell.id != spellid) - return; - - time_t now = time(nullptr); - if (now <= lastSpell.timer) - return; - - uint32 castTimeSpent = 1000 * (now - lastSpell.timer); - int32 globalCooldown = CalculateGlobalCooldown(lastSpell.id); - if (static_cast(castTimeSpent) < globalCooldown) - SetNextCheckDelay(globalCooldown - castTimeSpent); - else - SetNextCheckDelay(sPlayerbotAIConfig->reactDelay); - lastSpell.id = 0; } @@ -1513,14 +1505,15 @@ void PlayerbotAI::ApplyInstanceStrategies(uint32 mapId, bool tellMaster) default: break; } - + if (strategyName.empty()) + return; engines[BOT_STATE_COMBAT]->addStrategy(strategyName); engines[BOT_STATE_NON_COMBAT]->addStrategy(strategyName); if (tellMaster && !strategyName.empty()) { std::ostringstream out; out << "Add " << strategyName << " instance strategy"; - TellMaster(out.str()); + TellMasterNoFacing(out.str()); } } @@ -3617,6 +3610,7 @@ bool PlayerbotAI::IsInVehicle(bool canControl, bool canCast, bool canAttack, boo void PlayerbotAI::WaitForSpellCast(Spell* spell) { + return; SpellInfo const* spellInfo = spell->GetSpellInfo(); uint32 castTime = spell->GetCastTime(); // float castTime = spell->GetCastTime(); diff --git a/src/factory/PlayerbotFactory.cpp b/src/factory/PlayerbotFactory.cpp index a6dc88b7..5b5eba2e 100644 --- a/src/factory/PlayerbotFactory.cpp +++ b/src/factory/PlayerbotFactory.cpp @@ -3880,7 +3880,7 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destoryOld) } availableGems.push_back(enchantGem); } - + StatsWeightCalculator calculator(bot); for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot) { if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY) @@ -3940,7 +3940,6 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destoryOld) { continue; } - StatsWeightCalculator calculator(bot); float score = calculator.CalculateEnchant(enchant_id); if (score >= bestScore) { diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index 57eb4255..bafccd83 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -814,39 +814,25 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance) float combatDistance = bot->GetCombatReach() + target->GetCombatReach(); distance += combatDistance; - if (target->HasUnitMovementFlag(MOVEMENTFLAG_FORWARD)) // target is moving forward, predict the position - { - float needToGo = bot->GetExactDist(target) - distance; - float timeToGo = MoveDelay(abs(needToGo)) + sPlayerbotAIConfig->reactDelay / 1000.0f; - float targetMoveDist = timeToGo * target->GetSpeed(MOVE_RUN); - targetMoveDist = std::min(5.0f, targetMoveDist); - tx += targetMoveDist * cos(target->GetOrientation()); - ty += targetMoveDist * sin(target->GetOrientation()); - if (!target->GetMap()->CheckCollisionAndGetValidCoords(target, target->GetPositionX(), target->GetPositionY(), - target->GetPositionZ(), tx, ty, tz)) - { - // disable prediction if position is invalid - tx = target->GetPositionX(); - ty = target->GetPositionY(); - tz = target->GetPositionZ(); - } - // Prediction may cause this, which makes ShortenPathUntilDist fail - if (bot->GetExactDist(tx, ty, tz) <= distance) - { - tx = target->GetPositionX(); - ty = target->GetPositionY(); - tz = target->GetPositionZ(); - } - } if (bot->GetExactDist(tx, ty, tz) <= distance) return false; + PathGenerator path(bot); path.CalculatePath(tx, ty, tz, false); PathType type = path.GetPathType(); int typeOk = PATHFIND_NORMAL | PATHFIND_INCOMPLETE; if (!(type & typeOk)) return false; - path.ShortenPathUntilDist(G3D::Vector3(tx, ty, tz), distance); + float shortenTo = distance; + + // Avoid walking too far when moving towards each other + if (bot->GetDistance(tx, ty, tz) >= 10.0f) + shortenTo = std::max(distance, bot->GetDistance(tx, ty, tz) / 2); + + if (bot->GetExactDist(tx, ty, tz) <= shortenTo) + return false; + + path.ShortenPathUntilDist(G3D::Vector3(tx, ty, tz), shortenTo); G3D::Vector3 endPos = path.GetPath().back(); return MoveTo(target->GetMapId(), endPos.x, endPos.y, endPos.z, false, false, false, false, MovementPriority::MOVEMENT_COMBAT); diff --git a/src/strategy/actions/TellTargetAction.cpp b/src/strategy/actions/TellTargetAction.cpp index d1d05384..f6f05639 100644 --- a/src/strategy/actions/TellTargetAction.cpp +++ b/src/strategy/actions/TellTargetAction.cpp @@ -29,13 +29,14 @@ bool TellAttackersAction::Execute(Event event) botAI->TellMaster("--- Attackers ---"); GuidVector attackers = context->GetValue("attackers")->Get(); + int32 count = 0; for (ObjectGuid const guid : attackers) { Unit* unit = botAI->GetUnit(guid); if (!unit || !unit->IsAlive()) continue; - botAI->TellMaster(unit->GetName()); + botAI->TellMaster(std::to_string(++count) + std::string(".") + unit->GetName()); } botAI->TellMaster("--- Threat ---"); diff --git a/src/strategy/values/DpsTargetValue.cpp b/src/strategy/values/DpsTargetValue.cpp index 5fc276df..88c52ccf 100644 --- a/src/strategy/values/DpsTargetValue.cpp +++ b/src/strategy/values/DpsTargetValue.cpp @@ -50,6 +50,7 @@ public: CasterFindTargetSmartStrategy(PlayerbotAI* botAI, float dps) : FindTargetStrategy(botAI), dps_(dps), targetExpectedLifeTime(1000000) { + result = nullptr; } void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override @@ -86,13 +87,15 @@ public: { float new_time = new_unit->GetHealth() / dps_; float old_time = old_unit->GetHealth() / dps_; - // [5-20] > (5-0] > (20-inf) - if (GetIntervalLevel(new_unit) > GetIntervalLevel(old_unit)) + // [5-30] > (5-0] > (20-inf) + int new_level = GetIntervalLevel(new_unit); + int old_level = GetIntervalLevel(old_unit); + if (new_level != old_level) { - return true; + return new_level > old_level; } - int32_t level = GetIntervalLevel(new_unit); - if (level % 10 == 2 || level % 10 == 1) + int32_t level = new_level; + if (level % 10 == 2 || level % 10 == 0) { return new_time < old_time; } @@ -116,15 +119,15 @@ public: botAI->IsRanged(botAI->GetBot()) ? sPlayerbotAIConfig->spellDistance : sPlayerbotAIConfig->meleeDistance; attackRange += 5.0f; int level = dis < attackRange ? 10 : 0; - if (time >= 3 && time <= 20) + if (time >= 5 && time <= 30) { return level + 2; } - if (time > 20) + if (time > 30) { - return level + 1; + return level; } - return level; + return level + 1; } protected: @@ -176,12 +179,14 @@ public: float new_time = new_unit->GetHealth() / dps_; float old_time = old_unit->GetHealth() / dps_; // [5-20] > (5-0] > (20-inf) - if (GetIntervalLevel(new_unit) > GetIntervalLevel(old_unit)) + int new_level = GetIntervalLevel(new_unit); + int old_level = GetIntervalLevel(old_unit); + if (new_level != old_level) { - return true; + return new_level > old_level; } // attack enemy in range and with lowest health - int level = GetIntervalLevel(new_unit); + int level = new_level; if (level == 10) { return new_time < old_time; @@ -249,12 +254,14 @@ public: float new_time = new_unit->GetHealth() / dps_; float old_time = old_unit->GetHealth() / dps_; // [5-20] > (5-0] > (20-inf) - if (GetIntervalLevel(new_unit) > GetIntervalLevel(old_unit)) + int new_level = GetIntervalLevel(new_unit); + int old_level = GetIntervalLevel(old_unit); + if (new_level != old_level) { - return true; + return new_level > old_level; } // attack enemy in range and with lowest health - int level = GetIntervalLevel(new_unit); + int level = new_level; Player* bot = botAI->GetBot(); if (level == 10) {