From beb293383cb54ef5c1a3e805ee20f2797daa6e4c Mon Sep 17 00:00:00 2001 From: megamage Date: Tue, 27 Jan 2009 15:23:26 -0600 Subject: *Add creature extra flag "immune to taunt" and "charmed ai". *Fix the bug that creature still use its ai when charmed. Only creature with charmed ai flag can use its ai when charmed. --HG-- branch : trunk --- src/game/Creature.cpp | 14 +++++++++++++- src/game/Creature.h | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 8c72efff03d..56b5ff2ed3f 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -375,6 +375,12 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) else SetReactState(REACT_AGGRESSIVE); + if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_TAUNT) + { + ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); + ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); + } + return true; } @@ -482,7 +488,7 @@ void Creature::Update(uint32 diff) if(!isAlive()) break; - if(!IsInEvadeMode()) + if(!IsInEvadeMode() && m_AI_enabled) { // do not allow the AI to be changed during update m_AI_locked = true; @@ -599,6 +605,7 @@ bool Creature::AIM_Initialize(CreatureAI* ai) i_AI = ai ? ai : FactorySelector::selectAI(this); if (oldAI) delete oldAI; + m_AI_enabled = true; return true; } @@ -611,6 +618,9 @@ void Creature::InitPossessedAI() // Signal the old AI that it's been disabled i_AI->OnPossess(true); + + if(!(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CHARM_AI)) + m_AI_enabled = false; } void Creature::DisablePossessedAI() @@ -621,6 +631,8 @@ void Creature::DisablePossessedAI() // Signal the old AI that it's been re-enabled i_AI->OnPossess(false); + + m_AI_enabled = true; } bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data) diff --git a/src/game/Creature.h b/src/game/Creature.h index 563a9ddb80c..f51f5f6be47 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -132,6 +132,8 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging) + CREATURE_FLAG_EXTRA_CHARM_AI = 0x00008000, // use ai when charmed + CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00010000, // cannot be taunted }; // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform @@ -671,6 +673,7 @@ class TRINITY_DLL_SPEC Creature : public Unit bool m_AlreadyCallAssistance; bool m_regenHealth; bool m_AI_locked; + bool m_AI_enabled; bool m_isDeadByDefault; SpellSchoolMask m_meleeDamageSchoolMask; -- cgit v1.2.3 From f9754e36309dd37c69109d5966d4be9fdfd902fd Mon Sep 17 00:00:00 2001 From: megamage Date: Tue, 27 Jan 2009 17:30:21 -0600 Subject: *Fix broken cone spells and chain spells. --HG-- branch : trunk --- src/game/Spell.cpp | 10 +++++----- src/game/Spell.h | 7 +------ 2 files changed, 6 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index bf6959e1479..e17a360f90f 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1397,11 +1397,6 @@ void Spell::SearchAreaTarget(std::list &TagUnitMap, float radius, const u x = m_targets.m_destX; y = m_targets.m_destY; } - else if(type == PUSH_SELF_CENTER) - { - x = m_caster->GetPositionX(); - y = m_caster->GetPositionY(); - } else if(type == PUSH_TARGET_CENTER) { Unit *target = m_targets.getUnitTarget(); @@ -1413,6 +1408,11 @@ void Spell::SearchAreaTarget(std::list &TagUnitMap, float radius, const u x = target->GetPositionX(); y = target->GetPositionY(); } + else + { + x = m_caster->GetPositionX(); + y = m_caster->GetPositionY(); + } Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry); if((m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY) diff --git a/src/game/Spell.h b/src/game/Spell.h index 68d18fdeec1..7faa75a8cd8 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -81,7 +81,6 @@ enum SpellNotifyPushType PUSH_IN_FRONT, PUSH_IN_BACK, PUSH_IN_LINE, - PUSH_SELF_CENTER, PUSH_DEST_CENTER, PUSH_TARGET_CENTER, }; @@ -653,11 +652,7 @@ namespace Trinity if(i_caster->isInLine((Unit*)(itr->getSource()), i_radius )) i_data->push_back(itr->getSource()); break; - case PUSH_SELF_CENTER: - if(i_caster->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) - i_data->push_back(itr->getSource()); - break; - case PUSH_DEST_CENTER: + default: if((itr->getSource()->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius )) i_data->push_back(itr->getSource()); break; -- cgit v1.2.3 From 6de869d8f62464742ea18d34753f1898728d9f53 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 28 Jan 2009 00:01:52 -0600 Subject: *Fix the bug that event ai mobs sometimes chase victims even when polymorphed. --HG-- branch : trunk --- src/bindings/scripts/scripts/creature/mob_event_ai.cpp | 8 +++----- src/game/Creature.cpp | 14 ++------------ src/game/Unit.cpp | 1 + 3 files changed, 6 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp index eee4269e12c..6b46b7aecde 100644 --- a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp +++ b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp @@ -1225,7 +1225,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI void UpdateAI(const uint32 diff) { //Check if we are in combat (also updates calls threat update code) - bool Combat = InCombat ? (m_creature->SelectHostilTarget() && m_creature->getVictim()) : false; + bool Combat = InCombat ? m_creature->SelectHostilTarget() : false; //Must return if creature isn't alive. Normally select hostil target and get victim prevent this if (!m_creature->isAlive()) @@ -1233,11 +1233,9 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI if (IsFleeing) { - if(TimetoFleeLeft < diff - || m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE - && m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLEEING_MOTION_TYPE) + if(TimetoFleeLeft < diff) { - m_creature->GetMotionMaster()->Clear(false); + m_creature->SetControlled(false, UNIT_STAT_FLEEING); m_creature->SetNoCallAssistance(false); m_creature->CallAssistance(); if(m_creature->getVictim()) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 56b5ff2ed3f..553beb79509 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1870,22 +1870,12 @@ void Creature::DoFleeToGetAssistance(float radius) // Optional parameter return; Creature* pCreature = NULL; - - CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); - Trinity::NearestAssistCreatureInCreatureRangeCheck u_check(this,getVictim(),radius); Trinity::CreatureLastSearcher searcher(pCreature, u_check); - - TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); - - CellLock cell_lock(cell, p); - cell_lock->Visit(cell_lock, grid_creature_searcher, *(GetMap())); + VisitNearbyGridObject(radius, searcher); if(!pCreature) - GetMotionMaster()->MoveFleeing(getVictim()); + SetControlled(true, UNIT_STAT_FLEEING); else GetMotionMaster()->MovePoint(0,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ()); } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9d9b1fdc101..0296f7ceb4d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -12904,6 +12904,7 @@ void Unit::SetFeared(bool apply) Unit::AuraList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR); if(!fearAuras.empty()) caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID()); + if(!caster) caster = getVictim(); GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing } else -- cgit v1.2.3 From 53e646d23056bac858a370fdf1949237b201ebea Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 28 Jan 2009 00:25:06 -0600 Subject: *Clear combat flag when creature is created. This fix the bug that some creatures do not fight back. Thanks to tlexii for pointing out the bug. --HG-- branch : trunk --- src/game/Creature.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 553beb79509..8a7b8f5c47d 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -336,6 +336,8 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->unit_flags); SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + SetMeleeDamageSchool(SpellSchools(GetCreatureInfo()->dmgschool)); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor)); SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(GetCreatureInfo()->resistance1)); -- cgit v1.2.3 From 6e6e64cf67477e14dfcb590704d00a08f15a4611 Mon Sep 17 00:00:00 2001 From: Blaymoira Date: Wed, 28 Jan 2009 14:53:51 +0100 Subject: *Fixed 34700 *Set random target select for summoned creatures in Laj - by Iskander --HG-- branch : trunk --- .../scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp | 6 ++++++ src/game/SpellEffects.cpp | 3 +-- src/game/SpellMgr.cpp | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp index 87fe0f92641..c7e138e0918 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp @@ -144,6 +144,12 @@ struct TRINITY_DLL_DECL boss_lajAI : public ScriptedAI { } + void JustSummoned(Creature *summon) + { + if(summon && m_creature->getVictim()) + summon->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0)); + } + void UpdateAI(const uint32 diff) { if( !m_creature->SelectHostilTarget() || !m_creature->getVictim() ) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index fa1b957c243..2141c95a21b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4814,10 +4814,9 @@ void Spell::EffectScriptEffect(uint32 effIndex) { if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); + unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); break; } - // Netherbloom case 28702: { diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 0892ddabeab..7b33c94de07 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -507,6 +507,7 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex) case 37675: // Chaos Blast case 41519: // Mark of Stormrage case 34877: // Custodian of Time + case 34700: return false; } -- cgit v1.2.3 From 3a229014dca17012b623d5d4524ba8a5e069822f Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 28 Jan 2009 11:50:12 -0600 Subject: *Fix broken chain spells. --HG-- branch : trunk --- src/game/Object.cpp | 8 ++++++++ src/game/Object.h | 1 + src/game/Spell.cpp | 7 +++++-- src/game/Spell.h | 10 ++++++---- 4 files changed, 20 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/game/Object.cpp b/src/game/Object.cpp index d114d1e82ca..7599245eaac 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1159,6 +1159,14 @@ float WorldObject::GetDistance(const float x, const float y, const float z) cons return ( dist > 0 ? dist : 0); } +float WorldObject::GetDistanceSq(const float &x, const float &y, const float &z) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float dz = GetPositionZ() - z; + return dx*dx + dy*dy + dz*dz; +} + float WorldObject::GetDistance2d(const WorldObject* obj) const { float dx = GetPositionX() - obj->GetPositionX(); diff --git a/src/game/Object.h b/src/game/Object.h index 187092d5779..d4d9759ed1b 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -435,6 +435,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object float GetDistance( const WorldObject* obj ) const; float GetDistance(const float x, const float y, const float z) const; + float GetDistanceSq(const float &x, const float &y, const float &z) const; float GetDistance2d(const WorldObject* obj) const; float GetDistance2d(const float x, const float y) const; float GetDistanceZ(const WorldObject* obj) const; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index e17a360f90f..6f3f60a817a 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1386,7 +1386,7 @@ void Spell::SearchChainTarget(std::list &TagUnitMap, float max_range, uin void Spell::SearchAreaTarget(std::list &TagUnitMap, float radius, const uint32 &type, SpellTargets TargetType, uint32 entry) { - float x, y; + float x, y, z; if(type == PUSH_DEST_CENTER) { if(!m_targets.HasDest()) @@ -1396,6 +1396,7 @@ void Spell::SearchAreaTarget(std::list &TagUnitMap, float radius, const u } x = m_targets.m_destX; y = m_targets.m_destY; + z = m_targets.m_destZ; } else if(type == PUSH_TARGET_CENTER) { @@ -1407,14 +1408,16 @@ void Spell::SearchAreaTarget(std::list &TagUnitMap, float radius, const u } x = target->GetPositionX(); y = target->GetPositionY(); + z = target->GetPositionZ(); } else { x = m_caster->GetPositionX(); y = m_caster->GetPositionY(); + z = m_caster->GetPositionZ(); } - Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry); + Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry, x, y, z); if((m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY) || TargetType == SPELL_TARGETS_ENTRY && !entry) m_caster->GetMap()->VisitWorld(x, y, radius, notifier); diff --git a/src/game/Spell.h b/src/game/Spell.h index 7faa75a8cd8..d7ca8cdd2b6 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -580,14 +580,16 @@ namespace Trinity std::list *i_data; Spell &i_spell; const uint32& i_push_type; - float i_radius; + float i_radius, i_radiusSq; SpellTargets i_TargetType; Unit* i_caster; uint32 i_entry; + float i_x, i_y, i_z; SpellNotifierCreatureAndPlayer(Spell &spell, std::list &data, float radius, const uint32 &type, - SpellTargets TargetType = SPELL_TARGETS_ENEMY, uint32 entry = 0) - : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType), i_entry(entry) + SpellTargets TargetType = SPELL_TARGETS_ENEMY, uint32 entry = 0, float x = 0, float y = 0, float z = 0) + : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_radiusSq(radius*radius) + , i_TargetType(TargetType), i_entry(entry), i_x(x), i_y(y), i_z(z) { i_caster = spell.GetCaster(); } @@ -653,7 +655,7 @@ namespace Trinity i_data->push_back(itr->getSource()); break; default: - if((itr->getSource()->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius )) + if((itr->getSource()->GetDistanceSq(i_x, i_y, i_z) < i_radiusSq)) i_data->push_back(itr->getSource()); break; } -- cgit v1.2.3 From 30c5bff102bc089bcc18677352bf506ac0219111 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 28 Jan 2009 20:16:11 -0600 Subject: *Fix critter AI. *Some AI structure change. --HG-- branch : trunk --- .../scripts/zone/stormwind/stormwind_city.cpp | 1 - src/game/AggressorAI.cpp | 2 +- src/game/AggressorAI.h | 2 +- src/game/CreatureAI.cpp | 26 +++++++++++++------ src/game/CreatureAI.h | 19 +++++++------- src/game/CreatureAIImpl.h | 2 +- src/game/CreatureAIRegistry.cpp | 2 ++ src/game/CreatureAISelector.cpp | 4 ++- src/game/GuardAI.cpp | 2 +- src/game/GuardAI.h | 2 +- src/game/NullCreatureAI.cpp | 14 ++++++++++ src/game/NullCreatureAI.h | 30 +++++++++++++++++----- src/game/OutdoorPvPObjectiveAI.cpp | 2 +- src/game/OutdoorPvPObjectiveAI.h | 2 +- src/game/PetAI.cpp | 6 ++--- src/game/PetAI.h | 4 +-- src/game/PossessedAI.h | 3 +-- src/game/ReactorAI.h | 2 +- src/game/TotemAI.cpp | 2 +- src/game/TotemAI.h | 2 +- src/game/Unit.cpp | 21 ++++++++------- 21 files changed, 97 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp index c6ef71f25e5..6a11c455f67 100644 --- a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp +++ b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp @@ -149,7 +149,6 @@ struct TRINITY_DLL_DECL npc_dashel_stonefistAI : public ScriptedAI //m_creature->CombatStop(); EnterEvadeMode(); } - AttackedBy(done_by); } void Aggro(Unit *who) {} diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 1e29cd1df30..99e39618f53 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -38,7 +38,7 @@ AggressorAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +AggressorAI::AggressorAI(Creature *c) : i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) { } diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h index 51c123237f8..f6e2a649c8a 100644 --- a/src/game/AggressorAI.h +++ b/src/game/AggressorAI.h @@ -36,7 +36,7 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI public: - AggressorAI(Creature &c); + AggressorAI(Creature *c); void MoveInLineOfSight(Unit *); void AttackStart(Unit *); diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 71046e2f154..66c9d5af0b0 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -27,37 +27,47 @@ CreatureAI::~CreatureAI() { } -SimpleCharmedAI::SimpleCharmedAI(Unit &u) : me(u) +void CreatureAI::EnterEvadeMode() { + if(!me) return; + + me->RemoveAllAuras(); + me->DeleteThreatList(); + me->CombatStop(); + me->LoadCreaturesAddon(); + me->SetLootRecipient(NULL); + + if(me->isAlive()) + me->GetMotionMaster()->MoveTargetedHome(); } void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) { - Creature *charmer = (Creature*)me.GetCharmer(); + Creature *charmer = (Creature*)me->GetCharmer(); //kill self if charm aura has infinite duration if(charmer->IsInEvadeMode()) { - Unit::AuraList const& auras = me.GetAurasByType(SPELL_AURA_MOD_CHARM); + Unit::AuraList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM); for(Unit::AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->IsPermanent()) { - charmer->Kill(&me); + charmer->Kill(me); return; } } if(!charmer->isInCombat()) - me.GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - Unit *target = me.getVictim(); + Unit *target = me->getVictim(); if(!target || !charmer->canAttack(target)) { target = charmer->SelectNearestTarget(); if(!target) return; - me.GetMotionMaster()->MoveChase(target); - me.Attack(target, true); + me->GetMotionMaster()->MoveChase(target); + me->Attack(target, true); } } diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index b5fda95ef85..72e911cceaf 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -72,21 +72,25 @@ enum SelectAggroTarget class TRINITY_DLL_SPEC UnitAI { public: + UnitAI(Unit *u) : me(u) {} virtual void UpdateAI(const uint32 diff) = 0; + protected: + Unit *me; }; -class TRINITY_DLL_SPEC SimpleCharmedAI +class TRINITY_DLL_SPEC SimpleCharmedAI : public UnitAI { public: - SimpleCharmedAI(Unit &u); virtual void UpdateAI(const uint32 diff); - private: - Unit &me; }; class TRINITY_DLL_SPEC CreatureAI : public UnitAI { + protected: + Creature *me; public: + CreatureAI() : UnitAI(NULL), me(NULL) {} + CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c) {} virtual ~CreatureAI(); @@ -97,10 +101,10 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI virtual void AttackStart(Unit *) = 0; // Called at stopping attack by any attacker - virtual void EnterEvadeMode() = 0; + virtual void EnterEvadeMode(); // Called at any Damage from any attacker (before damage apply) - virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) { AttackedBy(done_by); } + virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {} // Is unit visible for MoveInLineOfSight virtual bool IsVisible(Unit *) const = 0; @@ -128,9 +132,6 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI // Called when vitim entered water and creature can not enter water virtual bool canReachByRangeAttack(Unit*) { return false; } - // Called when the creature is attacked - virtual void AttackedBy(Unit * /*attacker*/) {} - // Called when creature is spawned or respawned (for reseting variables) virtual void JustRespawned() {} diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index 76ba93a3cb5..2122adeb61c 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -27,6 +27,6 @@ inline CreatureAI* CreatureAIFactory::Create(void *data) const { Creature* creature = reinterpret_cast(data); - return (new REAL_AI(*creature)); + return (new REAL_AI(creature)); } #endif diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index a4ee030c34e..12b4aa97d0d 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -41,6 +41,8 @@ namespace AIRegistry (new CreatureAIFactory("NullCreatureAI"))->RegisterSelf(); (new CreatureAIFactory("AggressorAI"))->RegisterSelf(); (new CreatureAIFactory("ReactorAI"))->RegisterSelf(); + (new CreatureAIFactory("PassiveAI"))->RegisterSelf(); + (new CreatureAIFactory("CritterAI"))->RegisterSelf(); (new CreatureAIFactory("GuardAI"))->RegisterSelf(); (new CreatureAIFactory("PetAI"))->RegisterSelf(); (new CreatureAIFactory("TotemAI"))->RegisterSelf(); diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index 9927ff34df3..9e53fe0f641 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -65,6 +65,8 @@ namespace FactorySelector ai_factory = ai_registry.GetRegistryItem("TotemAI"); else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); + else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER) + ai_factory = ai_registry.GetRegistryItem("CritterAI"); } // select by permit check @@ -91,7 +93,7 @@ namespace FactorySelector ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key(); DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() ); - return ( ai_factory == NULL ? new NullCreatureAI : ai_factory->Create(creature) ); + return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) ); } MovementGenerator* selectMovementGenerator(Creature *creature) diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp index 806b4a1a112..e5a7ce87092 100644 --- a/src/game/GuardAI.cpp +++ b/src/game/GuardAI.cpp @@ -33,7 +33,7 @@ int GuardAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -GuardAI::GuardAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +GuardAI::GuardAI(Creature *c) : i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) { } diff --git a/src/game/GuardAI.h b/src/game/GuardAI.h index 07a638ea17a..16e0c6e8bd6 100644 --- a/src/game/GuardAI.h +++ b/src/game/GuardAI.h @@ -36,7 +36,7 @@ class TRINITY_DLL_DECL GuardAI : public CreatureAI public: - GuardAI(Creature &c); + GuardAI(Creature *c); void MoveInLineOfSight(Unit *); void AttackStart(Unit *); diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp index 4c1cb592967..67839ab9315 100644 --- a/src/game/NullCreatureAI.cpp +++ b/src/game/NullCreatureAI.cpp @@ -19,7 +19,21 @@ */ #include "NullCreatureAI.h" +#include "Creature.h" NullCreatureAI::~NullCreatureAI() { } + +void CritterAI::DamageTaken(Unit *done_by, uint32 &) +{ + if(!me->hasUnitState(UNIT_STAT_FLEEING)) + me->SetControlled(true, UNIT_STAT_FLEEING); +} + +void CritterAI::EnterEvadeMode() +{ + if(me->hasUnitState(UNIT_STAT_FLEEING)) + me->SetControlled(false, UNIT_STAT_FLEEING); + CreatureAI::EnterEvadeMode(); +} diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h index 3a93805fae2..a6a072fb48e 100644 --- a/src/game/NullCreatureAI.h +++ b/src/game/NullCreatureAI.h @@ -23,22 +23,38 @@ #include "CreatureAI.h" -class TRINITY_DLL_DECL NullCreatureAI : public CreatureAI +class TRINITY_DLL_DECL PassiveAI : public CreatureAI { public: - - NullCreatureAI(Creature &) {} - NullCreatureAI() {} - - ~NullCreatureAI(); + PassiveAI(Creature *c) : CreatureAI(c) {} + ~PassiveAI() {} void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *) {} - void EnterEvadeMode() {} bool IsVisible(Unit *) const { return false; } void UpdateAI(const uint32) {} static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; + +class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI +{ + public: + NullCreatureAI(Creature *c) : PassiveAI(c) {} + ~NullCreatureAI(); + + void EnterEvadeMode() {} +}; + +class TRINITY_DLL_DECL CritterAI : public PassiveAI +{ + public: + CritterAI(Creature *c) : PassiveAI(c) {} + ~CritterAI(); + + void DamageTaken(Unit *done_by, uint32 & /*damage*/); + void EnterEvadeMode(); +}; + #endif diff --git a/src/game/OutdoorPvPObjectiveAI.cpp b/src/game/OutdoorPvPObjectiveAI.cpp index e27c583eb25..ab82b6633ae 100644 --- a/src/game/OutdoorPvPObjectiveAI.cpp +++ b/src/game/OutdoorPvPObjectiveAI.cpp @@ -25,7 +25,7 @@ #define MAX_OUTDOOR_PVP_DISTANCE 200 // the max value in capture point type go data0 is 100 currently, so use twice that much to handle leaving as well -OutdoorPvPObjectiveAI::OutdoorPvPObjectiveAI(Creature &c) : i_creature(c) +OutdoorPvPObjectiveAI::OutdoorPvPObjectiveAI(Creature *c) : i_creature(*c) { sLog.outDebug("OutdoorPvP objective AI assigned to creature guid %u", c.GetGUIDLow()); c.SetReactState(REACT_AGGRESSIVE); diff --git a/src/game/OutdoorPvPObjectiveAI.h b/src/game/OutdoorPvPObjectiveAI.h index 19302a31305..2da9086dbd3 100644 --- a/src/game/OutdoorPvPObjectiveAI.h +++ b/src/game/OutdoorPvPObjectiveAI.h @@ -27,7 +27,7 @@ class TRINITY_DLL_DECL OutdoorPvPObjectiveAI : public CreatureAI { public: - OutdoorPvPObjectiveAI(Creature &c); + OutdoorPvPObjectiveAI(Creature *c); void MoveInLineOfSight(Unit *); bool IsVisible(Unit *) const; diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index abb62ade7da..85c2a77c921 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -38,7 +38,7 @@ int PetAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -PetAI::PetAI(Creature &c) : i_pet(c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false) +PetAI::PetAI(Creature *c) : i_pet(*c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false) { m_AllySet.clear(); UpdateAllies(); @@ -339,10 +339,10 @@ void PetAI::UpdateAllies() m_AllySet.insert(owner->GetGUID()); } -void PetAI::AttackedBy(Unit *attacker) +/*void PetAI::AttackedBy(Unit *attacker) { //when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) && (!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.IsWithinMeleeRange(attacker))) AttackStart(attacker); -} +}*/ diff --git a/src/game/PetAI.h b/src/game/PetAI.h index 33118dabdcb..8583404b669 100644 --- a/src/game/PetAI.h +++ b/src/game/PetAI.h @@ -31,13 +31,11 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI { public: - PetAI(Creature &c); + PetAI(Creature *c); void MoveInLineOfSight(Unit *); void AttackStart(Unit *); void EnterEvadeMode(); - void DamageTaken(Unit *done_by, uint32& /*damage*/) { AttackedBy(done_by); } - void AttackedBy(Unit*); bool IsVisible(Unit *) const; void JustDied(Unit* who) { _stopAttack(); } diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h index c33da2c3595..16c3172b6bf 100644 --- a/src/game/PossessedAI.h +++ b/src/game/PossessedAI.h @@ -28,7 +28,7 @@ class Creature; class TRINITY_DLL_DECL PossessedAI : public CreatureAI { public: - PossessedAI(Creature &c) : i_pet(c), i_victimGuid(0) {} + PossessedAI(Creature *c) : i_pet(*c), i_victimGuid(0) {} // Possessed creatures shouldn't aggro by themselves void MoveInLineOfSight(Unit *) {} @@ -36,7 +36,6 @@ class TRINITY_DLL_DECL PossessedAI : public CreatureAI void EnterEvadeMode() {} void JustDied(Unit*); void KilledUnit(Unit* victim); - void AttackedBy(Unit*) {} bool IsVisible(Unit * u) const { return _isVisible(u); } void UpdateAI(const uint32); diff --git a/src/game/ReactorAI.h b/src/game/ReactorAI.h index c71c48d0985..b2bfa3501c2 100644 --- a/src/game/ReactorAI.h +++ b/src/game/ReactorAI.h @@ -29,7 +29,7 @@ class TRINITY_DLL_DECL ReactorAI : public CreatureAI { public: - ReactorAI(Creature &c) : i_creature(c), i_victimGuid(0) {} + ReactorAI(Creature *c) : i_creature(*c), i_victimGuid(0) {} void MoveInLineOfSight(Unit *); void AttackStart(Unit *); diff --git a/src/game/TotemAI.cpp b/src/game/TotemAI.cpp index 7b99a8f0358..72a43cfc97b 100644 --- a/src/game/TotemAI.cpp +++ b/src/game/TotemAI.cpp @@ -40,7 +40,7 @@ TotemAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -TotemAI::TotemAI(Creature &c) : i_totem(static_cast(c)), i_victimGuid(0) +TotemAI::TotemAI(Creature *c) : i_totem(static_cast(*c)), i_victimGuid(0) { } diff --git a/src/game/TotemAI.h b/src/game/TotemAI.h index 1b4f96e6067..8ce40e60c81 100644 --- a/src/game/TotemAI.h +++ b/src/game/TotemAI.h @@ -31,7 +31,7 @@ class TRINITY_DLL_DECL TotemAI : public CreatureAI { public: - TotemAI(Creature &c); + TotemAI(Creature *c); void MoveInLineOfSight(Unit *); void AttackStart(Unit *); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 0296f7ceb4d..b2e214f915e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -650,9 +650,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa // no xp,health if type 8 /critters/ if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER) { - // critters run away when hit - pVictim->GetMotionMaster()->MoveFleeing(this); - // allow loot only if has loot_id in creature_template if(damage >= pVictim->GetHealth()) { @@ -750,13 +747,13 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa if(damagetype != DOT) { - if(getVictim()) - { + if(!getVictim()) + /*{ // if have target and damage pVictim just call AI reaction if(pVictim != getVictim() && pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI()) ((Creature*)pVictim)->AI()->AttackedBy(this); } - else + else*/ { // if not have main target then attack state with target (including AI call) //start melee attacks only after melee hit @@ -8195,8 +8192,8 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) m_attacking = victim; m_attacking->_addAttacker(this); - if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI()) - ((Creature*)m_attacking)->AI()->AttackedBy(this); + //if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI()) + // ((Creature*)m_attacking)->AI()->AttackedBy(this); if(GetTypeId()==TYPEID_UNIT) { @@ -12904,7 +12901,13 @@ void Unit::SetFeared(bool apply) Unit::AuraList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR); if(!fearAuras.empty()) caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID()); - if(!caster) caster = getVictim(); + if(!caster) + { + if(getVictim()) + caster = getVictim(); + else if(m_attackers.size()) + caster = *m_attackers.begin(); + } GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing } else -- cgit v1.2.3 From 1d19b6bcca688147814f07503a70a4d676c9b761 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 28 Jan 2009 20:54:54 -0600 Subject: *Fix the bug that critters do not enterevademode. --HG-- branch : trunk --- src/game/NullCreatureAI.cpp | 4 +++- src/game/NullCreatureAI.h | 4 +--- src/game/Unit.cpp | 13 ++++++------- 3 files changed, 10 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp index 67839ab9315..164aa2f7974 100644 --- a/src/game/NullCreatureAI.cpp +++ b/src/game/NullCreatureAI.cpp @@ -21,8 +21,10 @@ #include "NullCreatureAI.h" #include "Creature.h" -NullCreatureAI::~NullCreatureAI() +void PassiveAI::UpdateAI(const uint32) { + if(me->isInCombat() && me->getAttackers().empty()) + EnterEvadeMode(); } void CritterAI::DamageTaken(Unit *done_by, uint32 &) diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h index a6a072fb48e..821b42f7e76 100644 --- a/src/game/NullCreatureAI.h +++ b/src/game/NullCreatureAI.h @@ -34,7 +34,7 @@ class TRINITY_DLL_DECL PassiveAI : public CreatureAI bool IsVisible(Unit *) const { return false; } - void UpdateAI(const uint32) {} + void UpdateAI(const uint32); static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; @@ -42,7 +42,6 @@ class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI { public: NullCreatureAI(Creature *c) : PassiveAI(c) {} - ~NullCreatureAI(); void EnterEvadeMode() {} }; @@ -51,7 +50,6 @@ class TRINITY_DLL_DECL CritterAI : public PassiveAI { public: CritterAI(Creature *c) : PassiveAI(c) {} - ~CritterAI(); void DamageTaken(Unit *done_by, uint32 & /*damage*/); void EnterEvadeMode(); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b2e214f915e..7c8c9179962 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10409,6 +10409,10 @@ Unit* Creature::SelectHostilTarget() //next-victim-selection algorithm and evade mode are called //threat list sorting etc. + //This should not be called by unit who does not have a threatlist + //or who does not have threat (totem/pet/critter) + //otherwise enterevademode every update + Unit* target = NULL; //This function only useful once AI has been initialized @@ -10446,7 +10450,7 @@ Unit* Creature::SelectHostilTarget() for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr) { if( (*itr)->IsInMap(this) && canAttack(*itr) && (*itr)->isInAccessiblePlaceFor((Creature*)this) ) - return false; + return NULL; } }*/ @@ -12902,12 +12906,7 @@ void Unit::SetFeared(bool apply) if(!fearAuras.empty()) caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID()); if(!caster) - { - if(getVictim()) - caster = getVictim(); - else if(m_attackers.size()) - caster = *m_attackers.begin(); - } + caster = getAttackerForHelper(); GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing } else -- cgit v1.2.3 From adee7cab17e191ab9d735c326cd611f0380736d6 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 28 Jan 2009 22:51:12 -0600 Subject: *Fix build. --HG-- branch : trunk --- src/game/Creature.cpp | 2 +- src/game/OutdoorPvPObjectiveAI.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 8a7b8f5c47d..9949effb975 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -616,7 +616,7 @@ void Creature::InitPossessedAI() if (!isPossessed()) return; if (!i_AI_possessed) - i_AI_possessed = new PossessedAI(*this); + i_AI_possessed = new PossessedAI(this); // Signal the old AI that it's been disabled i_AI->OnPossess(true); diff --git a/src/game/OutdoorPvPObjectiveAI.cpp b/src/game/OutdoorPvPObjectiveAI.cpp index ab82b6633ae..a99afbfbe5a 100644 --- a/src/game/OutdoorPvPObjectiveAI.cpp +++ b/src/game/OutdoorPvPObjectiveAI.cpp @@ -27,8 +27,8 @@ OutdoorPvPObjectiveAI::OutdoorPvPObjectiveAI(Creature *c) : i_creature(*c) { - sLog.outDebug("OutdoorPvP objective AI assigned to creature guid %u", c.GetGUIDLow()); - c.SetReactState(REACT_AGGRESSIVE); + sLog.outDebug("OutdoorPvP objective AI assigned to creature guid %u", i_creature.GetGUIDLow()); + i_creature.SetReactState(REACT_AGGRESSIVE); } void OutdoorPvPObjectiveAI::MoveInLineOfSight(Unit *u) -- cgit v1.2.3