diff options
-rw-r--r-- | src/bindings/scripts/include/sc_creature.cpp | 28 | ||||
-rw-r--r-- | src/game/Creature.cpp | 26 | ||||
-rw-r--r-- | src/game/Creature.h | 1 | ||||
-rw-r--r-- | src/game/GridNotifiers.h | 23 | ||||
-rw-r--r-- | src/game/SpellHandler.cpp | 3 | ||||
-rw-r--r-- | src/game/Unit.cpp | 10 |
6 files changed, 53 insertions, 38 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 0c946b8f26d..ca7dc435b09 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -73,17 +73,7 @@ bool ScriptedAI::IsVisible(Unit* who) const void ScriptedAI::MoveInLineOfSight(Unit *who) { - if(m_creature->getVictim() || !m_creature->IsHostileTo(who) || !who->isInAccessiblePlaceFor(m_creature)) - return; - - if(!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) - return; - - if(!m_creature->IsWithinDistInMap(who, m_creature->GetAttackDistance(who)) || !m_creature->IsWithinLOSInMap(who)) - return; - - if(m_creature->canAttack(who)) - //who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + if(!m_creature->getVictim() && m_creature->canStartAttack(who)) AttackStart(who); } @@ -679,10 +669,10 @@ void ScriptedAI::DoZoneInCombat(Unit* pUnit) return; } - Map::PlayerList const &PlayerList = map->GetPlayers();
- for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* i_pl = i->getSource())
- if (!i_pl->isAlive())
+ Map::PlayerList const &PlayerList = map->GetPlayers(); + for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player* i_pl = i->getSource()) + if (!i_pl->isAlive()) pUnit->AddThreat(i_pl, 0.0f); } @@ -725,10 +715,10 @@ void ScriptedAI::DoTeleportAll(float x, float y, float z, float o) if (!map->IsDungeon()) return; - Map::PlayerList const &PlayerList = map->GetPlayers();
- for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* i_pl = i->getSource())
- if (!i_pl->isAlive())
+ Map::PlayerList const &PlayerList = map->GetPlayers(); + for(Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player* i_pl = i->getSource()) + if (!i_pl->isAlive()) i_pl->TeleportTo(m_creature->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT); } diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 33d1fd2ea02..91eb04b07f5 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1543,6 +1543,19 @@ bool Creature::IsWithinSightDist(Unit const* u) const return IsWithinDistInMap(u, sWorld.getConfig(CONFIG_SIGHT_MONSTER)); } +bool Creature::canStartAttack(Unit const* who) const +{ + if(!who->isInAccessiblePlaceFor(this) + || !canFly() && GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE + || !IsWithinDistInMap(who, GetAttackDistance(who))) + return false; + + if(!canAttack(who)) + return false; + + return IsWithinLOSInMap(who); +} + float Creature::GetAttackDistance(Unit const* pl) const { float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO); @@ -1824,12 +1837,12 @@ void Creature::DoFleeToGetAssistance(float radius) // Optional parameter Unit* Creature::SelectNearestTarget(float dist) const { - /*CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); + CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - Unit *target; + Unit *target = NULL; { Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist); @@ -1839,10 +1852,11 @@ Unit* Creature::SelectNearestTarget(float dist) const TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, p); - cell_lock->Visit(cell_lock, world_unit_searcher, GetMap()); - cell_lock->Visit(cell_lock, grid_unit_searcher, GetMap()); - }*/ - return NULL; + cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap()); + cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap()); + } + + return target; } void Creature::CallAssistence() diff --git a/src/game/Creature.h b/src/game/Creature.h index eb5b2d711f0..5d0ca5b5946 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -557,6 +557,7 @@ class TRINITY_DLL_SPEC Creature : public Unit bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList) const; bool IsWithinSightDist(Unit const* u) const; + bool canStartAttack(Unit const* u) const; float GetAttackDistance(Unit const* pl) const; Unit* SelectNearestTarget(float dist = 0) const; diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index 57abea4d5a2..3561f30861c 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -701,35 +701,34 @@ namespace Trinity class NearestHostileUnitInAttackDistanceCheck { public: - explicit NearestHostileUnitInAttackDistanceCheck(Creature* creature, float dist = 0) : m_creature(creature) + explicit NearestHostileUnitInAttackDistanceCheck(Creature const* creature, float dist = 0) : m_creature(creature) { m_range = (dist == 0 ? 9999 : dist); m_force = (dist == 0 ? false : true); } bool operator()(Unit* u) { - if(!u->isAlive() || !m_creature->IsHostileTo(u)) + // TODO: addthreat for every enemy in range? + if(!m_creature->IsWithinDistInMap(u, m_range)) return false; - float dist; - if(m_force) dist = m_range; + if(m_force) + { + if(!m_creature->canAttack(u)) + return false; + } else { - dist = m_creature->GetAttackDistance(u); - if(dist > m_range) dist = m_range; + if(!m_creature->canStartAttack(u)) + return false; } - if(!m_creature->IsWithinDistInMap(u, dist)) - return false; - - if(!m_creature->canSeeOrDetect(u, true, false)) - return false; m_range = m_creature->GetDistance(u); return true; } float GetLastRange() const { return m_range; } private: - Creature* const m_creature; + Creature const *m_creature; float m_range; bool m_force; NearestHostileUnitInAttackDistanceCheck(NearestHostileUnitInAttackDistanceCheck const&); diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 0e318eb5ddc..07d8b18b543 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -368,10 +368,11 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_CHARM || spellInfo->EffectApplyAuraName[i] == SPELL_AURA_BIND_SIGHT) { + // Fix me: creature may be killed during player aura cancel _player->RemoveAurasDueToSpellByCancel(spellId); if (_player->GetCharm()) _player->GetCharm()->RemoveAurasDueToSpellByCancel(spellId); - else if (_player->GetFarsightTarget()->GetTypeId() != TYPEID_DYNAMICOBJECT) + else if (_player->GetFarsightTarget() && _player->GetFarsightTarget()->GetTypeId() != TYPEID_DYNAMICOBJECT) ((Unit*)_player->GetFarsightTarget())->RemoveAurasDueToSpellByCancel(spellId); return; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9a78c50857f..94f647cdd46 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8542,6 +8542,9 @@ bool Unit::canAttack(Unit const* target) const { assert(target); + if(!IsHostileTo(target)) + return false; + if(!target->isAttackableByAOE() || target->hasUnitState(UNIT_STAT_DIED)) return false; @@ -9126,6 +9129,13 @@ bool Unit::SelectHostilTarget() } } + // search nearby enemy before enter evade mode + if(Unit *target = ((Creature*)this)->SelectNearestTarget()) + { + ((Creature*)this)->AI()->AttackStart(target); + return true; + } + // enter in evade mode in other case ((Creature*)this)->AI()->EnterEvadeMode(); |