diff options
| author | treeston <treeston.mmoc@gmail.com> | 2016-03-24 16:12:53 +0100 |
|---|---|---|
| committer | joschiwald <joschiwald.trinity@gmail.com> | 2017-01-07 21:33:28 +0100 |
| commit | 489027703e2d8cc0a974b68b6610e7b84d1d7899 (patch) | |
| tree | 4da77193b0dbe0211eaaabe8db32d7dea1c919bb | |
| parent | f93730b160fbd5bf47e2abdbc86cec8780aab18e (diff) | |
Entities/Unit: Finally fix no-path evasion.
- When a creature cannot find a path to its victim, it begins evading all attacks and regenerating health.
- If this persists for 5 seconds, it evades back to spawn position with new EvadeReason value EVADE_REASON_NO_PATH.
- Also some SmartAI cleanup (why oh why does it have so much duplicated code) and getting rid of #defines in favor of type-checked compile-time constants.
(cherry picked from commit 7b1560fccba77ecbdfecd7b33af740aea41b7087)
| -rw-r--r-- | src/server/game/AI/CoreAI/CombatAI.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/AI/CreatureAI.cpp | 19 | ||||
| -rw-r--r-- | src/server/game/AI/CreatureAI.h | 1 | ||||
| -rw-r--r-- | src/server/game/AI/ScriptedAI/ScriptedCreature.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 7 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 57 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 23 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 14 | ||||
| -rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 8 | ||||
| -rwxr-xr-x | src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 11 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 2 |
12 files changed, 82 insertions, 70 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp index 7cfb82a6c1d..f4a557d25b3 100644 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -50,7 +50,7 @@ void AggressorAI::UpdateAI(uint32 /*diff*/) void CombatAI::InitializeAI() { - for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i) if (me->m_spells[i] && sSpellMgr->GetSpellInfo(me->m_spells[i])) spells.push_back(me->m_spells[i]); diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 379834a7e3d..5e98945e1de 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -268,6 +268,7 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/) me->SetLootRecipient(NULL); me->ResetPlayerDamageReq(); me->SetLastDamagedTime(0); + me->SetCannotReachTarget(false); if (me->IsInEvadeMode()) return false; @@ -275,11 +276,11 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/) return true; } -#define BOUNDARY_VISUALIZE_CREATURE 15425 -#define BOUNDARY_VISUALIZE_CREATURE_SCALE 0.25f -#define BOUNDARY_VISUALIZE_STEP_SIZE 1 -#define BOUNDARY_VISUALIZE_FAILSAFE_LIMIT 750 -#define BOUNDARY_VISUALIZE_SPAWN_HEIGHT 5 +const uint32 BOUNDARY_VISUALIZE_CREATURE = 15425; +const float BOUNDARY_VISUALIZE_CREATURE_SCALE = 0.25f; +const int8 BOUNDARY_VISUALIZE_STEP_SIZE = 1; +const int32 BOUNDARY_VISUALIZE_FAILSAFE_LIMIT = 750; +const float BOUNDARY_VISUALIZE_SPAWN_HEIGHT = 5.0f; int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) const { typedef std::pair<int32, int32> coordinate; @@ -295,13 +296,13 @@ int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) con std::unordered_set<coordinate> outOfBounds; Position startPosition = owner->GetPosition(); - if (!CheckBoundary(&startPosition)) // fall back to creature position - { + if (!CheckBoundary(&startPosition)) + { // fall back to creature position startPosition = me->GetPosition(); if (!CheckBoundary(&startPosition)) - { + { // fall back to creature home position startPosition = me->GetHomePosition(); - if (!CheckBoundary(&startPosition)) // fall back to creature home position + if (!CheckBoundary(&startPosition)) return LANG_CREATURE_NO_INTERIOR_POINT_FOUND; } } diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 4b7eb1618e7..00c45491efc 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -87,6 +87,7 @@ class TC_GAME_API CreatureAI : public UnitAI { EVADE_REASON_NO_HOSTILES, // the creature's threat list is empty EVADE_REASON_BOUNDARY, // the creature has moved outside its evade boundary + EVADE_REASON_NO_PATH, // the creature was unable to reach its target for over 5 seconds EVADE_REASON_SEQUENCE_BREAK, // this is a boss and the pre-requisite encounters for engaging it are not defeated yet EVADE_REASON_OTHER }; diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index d8a4b54574f..4be8995d802 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -190,15 +190,15 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec return NULL; //Using the extended script system we first create a list of viable spells - SpellInfo const* apSpell[CREATURE_MAX_SPELLS]; - memset(apSpell, 0, CREATURE_MAX_SPELLS * sizeof(SpellInfo*)); + SpellInfo const* apSpell[MAX_CREATURE_SPELLS]; + memset(apSpell, 0, MAX_CREATURE_SPELLS * sizeof(SpellInfo*)); uint32 spellCount = 0; SpellInfo const* tempSpell = NULL; //Check if each spell is viable(set it to null if not) - for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++) + for (uint32 i = 0; i < MAX_CREATURE_SPELLS; i++) { tempSpell = sSpellMgr->GetSpellInfo(me->m_spells[i]); diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 9e47b1e499f..e921318afed 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -416,12 +416,7 @@ void SmartAI::EnterEvadeMode(EvadeReason /*why*/) me->RemoveAurasOnEvade(); me->AddUnitState(UNIT_STATE_EVADE); - me->DeleteThreatList(); - me->CombatStop(true); - me->LoadCreaturesAddon(); - me->SetLootRecipient(NULL); - me->ResetPlayerDamageReq(); - me->SetLastDamagedTime(0); + _EnterEvadeMode(); GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 94a7101f1e8..3ff1ec0bedb 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -184,14 +184,14 @@ m_groupLootTimer(0), m_PlayerDamageReq(0), _pickpocketLootRestore(0), m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), -m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), +m_AlreadySearchedAssistance(false), m_regenHealth(true), m_cannotReachTarget(false), m_cannotReachTimer(0), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_focusSpell(nullptr), m_focusDelay(0) { m_regenTimer = CREATURE_REGEN_INTERVAL; m_valuesCount = UNIT_END; _dynamicValuesCount = UNIT_DYNAMIC_END; - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i) m_spells[i] = 0; DisableReputationGain = false; @@ -400,7 +400,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) if (!m_respawnradius && m_defaultMovementType == RANDOM_MOTION_TYPE) m_defaultMovementType = IDLE_MOTION_TYPE; - for (uint8 i=0; i < CREATURE_MAX_SPELLS; ++i) + for (uint8 i=0; i < MAX_CREATURE_SPELLS; ++i) m_spells[i] = GetCreatureTemplate()->spells[i]; return true; @@ -656,33 +656,32 @@ void Creature::Update(uint32 diff) m_regenTimer -= diff; } - if (m_regenTimer != 0) - break; - - bool bInCombat = IsInCombat() && (!GetVictim() || // if IsInCombat() is true and this has no victim - !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself() || // or the victim/owner/charmer is not a player - !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()->IsGameMaster()); // or the victim/owner/charmer is not a GameMaster + if (m_regenTimer == 0) + { + bool bInCombat = IsInCombat() && (!GetVictim() || // if IsInCombat() is true and this has no victim + !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself() || // or the victim/owner/charmer is not a player + !EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()->IsGameMaster()); // or the victim/owner/charmer is not a GameMaster - /*if (m_regenTimer <= diff) - {*/ - if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed())) // regenerate health if not in combat or if polymorphed - RegenerateHealth(); + if (!IsInEvadeMode() && (!bInCombat || IsPolymorphed() || CanNotReachTarget())) // regenerate health if not in combat or if polymorphed + RegenerateHealth(); - if (HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER)) - { - if (getPowerType() == POWER_ENERGY) - Regenerate(POWER_ENERGY); - else - RegenerateMana(); + if (HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER)) + { + if (getPowerType() == POWER_ENERGY) + Regenerate(POWER_ENERGY); + else + RegenerateMana(); + } + m_regenTimer = CREATURE_REGEN_INTERVAL; } - /*if (!bIsPolymorphed) // only increase the timer if not polymorphed - m_regenTimer += CREATURE_REGEN_INTERVAL - diff; + if (CanNotReachTarget() && !IsInEvadeMode() && !GetMap()->IsRaid()) + { + m_cannotReachTimer += diff; + if (m_cannotReachTimer >= CREATURE_NOPATH_EVADE_TIME) + if (IsAIEnabled) + AI()->EnterEvadeMode(CreatureAI::EVADE_REASON_NO_PATH); } - else - if (!bIsPolymorphed) // if polymorphed, skip the timer - m_regenTimer -= diff;*/ - m_regenTimer = CREATURE_REGEN_INTERVAL; break; } default: @@ -1859,7 +1858,7 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim) if (!victim) return nullptr; - for (uint32 i=0; i < CREATURE_MAX_SPELLS; ++i) + for (uint32 i=0; i < MAX_CREATURE_SPELLS; ++i) { if (!m_spells[i]) continue; @@ -1911,7 +1910,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim) if (!victim) return nullptr; - for (uint32 i=0; i < CREATURE_MAX_SPELLS; ++i) + for (uint32 i=0; i < MAX_CREATURE_SPELLS; ++i) { if (!m_spells[i]) continue; @@ -2357,10 +2356,10 @@ void Creature::SetInCombatWithZone() bool Creature::HasSpell(uint32 spellID) const { uint8 i; - for (i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (i = 0; i < MAX_CREATURE_SPELLS; ++i) if (spellID == m_spells[i]) break; - return i < CREATURE_MAX_SPELLS; //broke before end of iteration of known spells + return i < MAX_CREATURE_SPELLS; //broke before end of iteration of known spells } time_t Creature::GetRespawnTimeEx() const diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index ca88643dc94..d31a295d34d 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -290,13 +290,14 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_SKILLGAIN | CREATURE_FLAG_EXTRA_TAUNT_DIMINISH | CREATURE_FLAG_EXTRA_ALL_DIMINISH | \ CREATURE_FLAG_EXTRA_GUARD | CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING | CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ | CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK) -#define CREATURE_REGEN_INTERVAL 2 * IN_MILLISECONDS +const uint32 CREATURE_REGEN_INTERVAL = 2 * IN_MILLISECONDS; +const uint32 CREATURE_NOPATH_EVADE_TIME = 5 * IN_MILLISECONDS; -#define MAX_KILL_CREDIT 2 -#define MAX_CREATURE_MODELS 4 -#define MAX_CREATURE_NAMES 4 -#define CREATURE_MAX_SPELLS 8 -#define MAX_CREATURE_DIFFICULTIES 3 +const uint8 MAX_KILL_CREDIT = 2; +const uint32 MAX_CREATURE_MODELS = 4; +const uint32 MAX_CREATURE_NAMES = 4; +const uint32 MAX_CREATURE_SPELLS = 8; +const uint32 MAX_CREATURE_DIFFICULTIES = 3; // from `creature_template` table struct TC_GAME_API CreatureTemplate @@ -344,7 +345,7 @@ struct TC_GAME_API CreatureTemplate uint32 pickpocketLootId; uint32 SkinLootId; int32 resistance[MAX_SPELL_SCHOOL]; - uint32 spells[CREATURE_MAX_SPELLS]; + uint32 spells[MAX_CREATURE_SPELLS]; uint32 VehicleId; uint32 mingold; uint32 maxgold; @@ -745,6 +746,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma uint8 getLevelForTarget(WorldObject const* target) const override; // overwrite Unit::getLevelForTarget for boss level support bool IsInEvadeMode() const { return HasUnitState(UNIT_STATE_EVADE); } + bool IsEvadingAttacks() const { return IsInEvadeMode() || CanNotReachTarget(); } bool AIM_Destroy(); bool AIM_Initialize(CreatureAI* ai = NULL); @@ -827,7 +829,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma SpellInfo const* reachWithSpellAttack(Unit* victim); SpellInfo const* reachWithSpellCure(Unit* victim); - uint32 m_spells[CREATURE_MAX_SPELLS]; + uint32 m_spells[MAX_CREATURE_SPELLS]; bool CanStartAttack(Unit const* u, bool force) const; float GetAttackDistance(Unit const* player) const; @@ -892,6 +894,9 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma virtual uint8 GetPetAutoSpellSize() const { return MAX_SPELL_CHARM; } virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const; + void SetCannotReachTarget(bool cannotReach) { if (cannotReach == m_cannotReachTarget) return; m_cannotReachTarget = cannotReach; m_cannotReachTimer = 0; } + bool CanNotReachTarget() const { return m_cannotReachTarget; } + void SetPosition(float x, float y, float z, float o); void SetPosition(const Position &pos) { SetPosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); } @@ -979,6 +984,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma bool m_AlreadyCallAssistance; bool m_AlreadySearchedAssistance; bool m_regenHealth; + bool m_cannotReachTarget; + uint32 m_cannotReachTimer; bool m_AI_locked; SpellSchoolMask m_meleeDamageSchoolMask; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e3c8913b1b0..eac1445ae20 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21082,7 +21082,7 @@ void Player::VehicleSpellInitialize() for (uint32 i = 0; i < MAX_SPELL_CONTROL_BAR; ++i) petSpells.ActionButtons[i] = MAKE_UNIT_ACTION_BUTTON(0, i + 8); - for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (uint32 i = 0; i < MAX_CREATURE_SPELLS; ++i) { uint32 spellId = vehicle->m_spells[i]; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2c1d7771d5f..742958b02cf 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -602,7 +602,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb) { - if (!victim || !victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())) + if (!victim || !victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())) { if (absorb) *absorb += damage; @@ -1081,7 +1081,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilit if (!victim) return; - if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())) + if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())) return; SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(damageInfo->SpellID); @@ -1292,7 +1292,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) { Unit* victim = damageInfo->target; - if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())) + if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())) return; // Hmmmm dont like this emotes client must by self do all animations @@ -1950,7 +1950,7 @@ void Unit::HandleProcExtraAttackFor(Unit* victim) MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackType attType) const { - if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()) + if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()) return MELEE_HIT_EVADE; // Miss chance based on melee @@ -2532,7 +2532,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spellInfo, boo return SPELL_MISS_NONE; // Return evade for units in evade mode - if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()) + if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks()) return SPELL_MISS_EVADE; // Try victim reflect spell @@ -6939,7 +6939,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack) } else { - if (victim->ToCreature()->IsInEvadeMode()) + if (victim->ToCreature()->IsEvadingAttacks()) return false; } @@ -11421,7 +11421,7 @@ void CharmInfo::InitPossessCreateSpells() break; } - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i) { uint32 spellId = _unit->ToCreature()->m_spells[i]; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index cf5518229e2..f58eb8ba8a7 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -461,7 +461,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields) creatureTemplate.Entry = entry; - for (uint8 i = 0; i < MAX_CREATURE_DIFFICULTIES; ++i) + for (uint32 i = 0; i < MAX_CREATURE_DIFFICULTIES; ++i) creatureTemplate.DifficultyEntry[i] = fields[1 + i].GetUInt32(); for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) @@ -510,7 +510,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields) for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) creatureTemplate.resistance[i] = fields[45 + i - 1].GetInt16(); - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i) creatureTemplate.spells[i] = fields[51 + i].GetUInt32(); creatureTemplate.VehicleId = fields[59].GetUInt32(); @@ -860,7 +860,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) if (!displayScaleEntry) TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) does not have any existing display id in Modelid1/Modelid2/Modelid3/Modelid4.", cInfo->Entry); - for (int k = 0; k < MAX_KILL_CREDIT; ++k) + for (uint8 k = 0; k < MAX_KILL_CREDIT; ++k) { if (cInfo->KillCredit[k]) { @@ -940,7 +940,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) } } - for (uint8 j = 0; j < CREATURE_MAX_SPELLS; ++j) + for (uint8 j = 0; j < MAX_CREATURE_SPELLS; ++j) { if (cInfo->spells[j] && !sSpellMgr->GetSpellInfo(cInfo->spells[j])) { diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 2caae3fbd4d..1d160aad634 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -37,7 +37,10 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up return; if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature())) + { + owner->ToCreature()->SetCannotReachTarget(true); return; + } if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsFocusing(nullptr, true)) return; @@ -102,8 +105,10 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up bool result = i_path->CalculatePath(x, y, z, forceDest); if (!result || (i_path->GetPathType() & PATHFIND_NOPATH)) { - // Cant reach target + // can't reach target i_recalculateTravel = true; + if (owner->GetTypeId() == TYPEID_UNIT) + owner->ToCreature()->SetCannotReachTarget(true); return; } @@ -111,6 +116,8 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up i_targetReached = false; i_recalculateTravel = false; owner->AddUnitState(UNIT_STATE_CHASE); + if (owner->GetTypeId() == TYPEID_UNIT) + owner->ToCreature()->SetCannotReachTarget(false); Movement::MoveSplineInit init(owner); init.MovebyPath(i_path->GetPath()); @@ -201,6 +208,8 @@ void ChaseMovementGenerator<T>::_reachTarget(T* owner) { if (owner->IsWithinMeleeRange(this->i_target.getTarget())) owner->Attack(this->i_target.getTarget(), true); + if (owner->GetTypeId() == TYPEID_UNIT) + owner->ToCreature()->SetCannotReachTarget(false); } template<> diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 4975e2d96c5..39e0c29fda1 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -669,7 +669,7 @@ void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, uint32 lockoutTim else { Creature* creatureOwner = _owner->ToCreature(); - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i) if (creatureOwner->m_spells[i]) knownSpells.insert(creatureOwner->m_spells[i]); } |
