From 73db1cbe0125924e2564481ca7c912bbcbfab920 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 27 Apr 2009 03:36:31 +0400 Subject: [PATCH] [7723] New AI call EnterCombat called at enter creature to combat (and re-enter if leave by some reason). --- src/game/AggressorAI.cpp | 10 +++++----- src/game/CreatureAI.h | 3 +++ src/game/CreatureEventAI.cpp | 11 +++-------- src/game/CreatureEventAI.h | 2 +- src/game/GuardAI.cpp | 4 ++-- src/game/ReactorAI.cpp | 5 +++-- src/game/Spell.cpp | 2 +- src/game/Unit.cpp | 14 ++++++++++---- src/game/Unit.h | 2 +- src/shared/revision_nr.h | 2 +- 10 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 086f32864..50878ee59 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -60,8 +60,8 @@ AggressorAI::MoveInLineOfSight(Unit *u) } else if(sMapStore.LookupEntry(m_creature->GetMapId())->IsDungeon()) { - u->SetInCombatWith(m_creature); m_creature->AddThreat(u, 0.0f); + u->SetInCombatWith(m_creature); } } } @@ -152,13 +152,13 @@ AggressorAI::AttackStart(Unit *u) if(m_creature->Attack(u,true)) { - m_creature->SetInCombatWith(u); - u->SetInCombatWith(m_creature); - - m_creature->AddThreat(u, 0.0f); // DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", m_creature->GetName(), u->GetGUIDLow()); i_victimGuid = u->GetGUID(); + m_creature->AddThreat(u, 0.0f); + m_creature->SetInCombatWith(u); + u->SetInCombatWith(m_creature); + m_creature->GetMotionMaster()->MoveChase(u); } } diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index af2fb5e21..e64214ff4 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -46,6 +46,9 @@ class MANGOS_DLL_SPEC CreatureAI // Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter virtual void MoveInLineOfSight(Unit *) {} + // Called for reaction at enter to combat if not in combat yet (enemy can be NULL) + virtual void EnterCombat(Unit* /*enemy*/) {} + // Called for reaction at stopping attack at no attackers or targets virtual void EnterEvadeMode() {} diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 46a13d7e3..e337351f7 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -1118,7 +1118,7 @@ void CreatureEventAI::JustSummoned(Creature* pUnit) } } -void CreatureEventAI::Aggro(Unit *who) +void CreatureEventAI::EnterCombat(Unit *enemy) { //Check for on combat start events if (!bEmptyList) @@ -1129,7 +1129,7 @@ void CreatureEventAI::Aggro(Unit *who) { case EVENT_T_AGGRO: (*i).Enabled = true; - ProcessEvent(*i, who); + ProcessEvent(*i, enemy); break; //Reset all in combat timers case EVENT_T_TIMER: @@ -1164,17 +1164,12 @@ void CreatureEventAI::AttackStart(Unit *who) if (!who) return; - bool inCombat = m_creature->isInCombat(); - if (m_creature->Attack(who, MeleeEnabled)) { m_creature->AddThreat(who, 0.0f); m_creature->SetInCombatWith(who); who->SetInCombatWith(m_creature); - if (!inCombat) - Aggro(who); - if (CombatMovementEnabled) { m_creature->GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle); @@ -1233,8 +1228,8 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who) } else if (m_creature->GetMap()->IsDungeon()) { - who->SetInCombatWith(m_creature); m_creature->AddThreat(who, 0.0f); + who->SetInCombatWith(m_creature); } } } diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index af1f4871b..56bccc947 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -257,11 +257,11 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI void JustRespawned(); void Reset(); void JustReachedHome(); + void EnterCombat(Unit *enemy); void EnterEvadeMode(); void JustDied(Unit* killer); void KilledUnit(Unit* victim); void JustSummoned(Creature* pUnit); - void Aggro(Unit *who); void AttackStart(Unit *who); void MoveInLineOfSight(Unit *who); void SpellHit(Unit* pUnit, const SpellEntry* pSpell); diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp index aad95c2ff..8e0e5ba18 100644 --- a/src/game/GuardAI.cpp +++ b/src/game/GuardAI.cpp @@ -137,11 +137,11 @@ void GuardAI::AttackStart(Unit *u) // DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow()); if(m_creature->Attack(u,true)) { + i_victimGuid = u->GetGUID(); + m_creature->AddThreat(u, 0.0f); m_creature->SetInCombatWith(u); u->SetInCombatWith(m_creature); - m_creature->AddThreat(u, 0.0f); - i_victimGuid = u->GetGUID(); m_creature->GetMotionMaster()->MoveChase(u); } } diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp index 0fd68dfe3..a27c39f11 100644 --- a/src/game/ReactorAI.cpp +++ b/src/game/ReactorAI.cpp @@ -48,11 +48,12 @@ ReactorAI::AttackStart(Unit *p) if(m_creature->Attack(p,true)) { DEBUG_LOG("Tag unit GUID: %u (TypeId: %u) as a victim", p->GetGUIDLow(), p->GetTypeId()); + i_victimGuid = p->GetGUID(); + m_creature->AddThreat(p, 0.0f); + m_creature->SetInCombatWith(p); p->SetInCombatWith(m_creature); - m_creature->AddThreat(p, 0.0f); - i_victimGuid = p->GetGUID(); m_creature->GetMotionMaster()->MoveChase(p); } } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 0ace79988..7d95ed83a 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1158,6 +1158,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI()) ((Creature*)unit)->AI()->AttackedBy(m_caster); + unit->AddThreat(m_caster, 0.0f); unit->SetInCombatWith(m_caster); m_caster->SetInCombatWith(unit); @@ -1165,7 +1166,6 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) { m_caster->SetContestedPvP(attackedPlayer); } - unit->AddThreat(m_caster, 0.0f); } } else diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index f8469a39f..f5e5f8c90 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8678,7 +8678,7 @@ void Unit::SetInCombatWith(Unit* enemy) Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf(); if(eOwner->IsPvP()) { - SetInCombatState(true); + SetInCombatState(true,enemy); return; } @@ -8688,14 +8688,14 @@ void Unit::SetInCombatWith(Unit* enemy) Unit const* myOwner = GetCharmerOrOwnerOrSelf(); if(((Player const*)eOwner)->duel->opponent == myOwner) { - SetInCombatState(true); + SetInCombatState(true,enemy); return; } } - SetInCombatState(false); + SetInCombatState(false,enemy); } -void Unit::SetInCombatState(bool PvP) +void Unit::SetInCombatState(bool PvP, Unit* enemy) { // only alive units can be in combat if(!isAlive()) @@ -8703,10 +8703,16 @@ void Unit::SetInCombatState(bool PvP) if(PvP) m_CombatTimer = 5000; + + bool creatureNotInCombat = GetTypeId()==TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); if(isCharmed() || (GetTypeId()!=TYPEID_PLAYER && ((Creature*)this)->isPet())) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT); + + if(creatureNotInCombat && ((Creature*)this)->AI()) + ((Creature*)this)->AI()->EnterCombat(enemy); } void Unit::ClearInCombat() diff --git a/src/game/Unit.h b/src/game/Unit.h index 8c5ccc78e..2b9b14352 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1018,7 +1018,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool isInFlight() const { return hasUnitState(UNIT_STAT_IN_FLIGHT); } bool isInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); } - void SetInCombatState(bool PvP); + void SetInCombatState(bool PvP, Unit* enemy = NULL); void SetInCombatWith(Unit* enemy); void ClearInCombat(); uint32 GetCombatTimer() const { return m_CombatTimer; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7d9b6dd16..d6c51267c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7722" + #define REVISION_NR "7723" #endif // __REVISION_NR_H__