aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings/scripts/scripts/npc/npcs_special.cpp46
-rw-r--r--src/game/AggressorAI.cpp55
-rw-r--r--src/game/AggressorAI.h12
-rw-r--r--src/game/CreatureAIImpl.h5
-rw-r--r--src/game/Map.cpp1
-rw-r--r--src/game/SpellEffects.cpp1
-rw-r--r--src/game/Unit.cpp4
-rw-r--r--src/game/UnitAI.cpp4
8 files changed, 80 insertions, 48 deletions
diff --git a/src/bindings/scripts/scripts/npc/npcs_special.cpp b/src/bindings/scripts/scripts/npc/npcs_special.cpp
index 9b31a9282d1..f6922745953 100644
--- a/src/bindings/scripts/scripts/npc/npcs_special.cpp
+++ b/src/bindings/scripts/scripts/npc/npcs_special.cpp
@@ -1639,12 +1639,13 @@ CreatureAI* GetAI_mob_mojo(Creature *_Creature)
return new mob_mojoAI (_Creature);
}
-struct TRINITY_DLL_DECL npc_mirror_image : SpellAI
+struct TRINITY_DLL_DECL npc_mirror_image : SpellCasterAI
{
- npc_mirror_image(Creature *c) : SpellAI(c) {Reset();}
+ npc_mirror_image(Creature *c) : SpellCasterAI(c) {}
- void Reset()
+ void InitializeAI()
{
+ SpellCasterAI::InitializeAI();
Unit * owner = me->GetOwner();
if (!owner)
return;
@@ -1656,43 +1657,7 @@ struct TRINITY_DLL_DECL npc_mirror_image : SpellAI
owner->CastSpell(me, 45204, false);
}
- void EnterCombat(Unit *who)
- {
- if (spells.empty())
- return;
-
- uint32 spell = rand() % spells.size();
- uint32 count = 0;
- for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr, ++count)
- {
- uint32 cooldown = GetAISpellInfo(*itr)->cooldown;
- if (count == spell)
- {
- DoCast(spells[spell]);
- cooldown += me->GetCurrentSpellCastTime(*itr);
- }
- events.ScheduleEvent(*itr, cooldown);
- }
- }
-
- void UpdateAI(const uint32 diff)
- {
- if(!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if(me->hasUnitState(UNIT_STAT_CASTING))
- return;
-
- if(uint32 spellId = events.ExecuteEvent())
- {
- DoCast(spellId);
- uint32 casttime = me->GetCurrentSpellCastTime(spellId);
- events.ScheduleEvent(spellId, (casttime ? casttime : 500) + GetAISpellInfo(spellId)->cooldown);
- }
- }
-
+ // Do not reload creature templates on evade mode enter - prevent visual lost
void EnterEvadeMode()
{
if(me->IsInEvadeMode() || !me->isAlive())
@@ -1707,7 +1672,6 @@ struct TRINITY_DLL_DECL npc_mirror_image : SpellAI
me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, m_creature->GetFollowAngle(), MOTION_SLOT_ACTIVE);
}
}
-
};
CreatureAI* GetAI_npc_mirror_image(Creature *_Creature)
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index d827e3e2672..3050c772e28 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -91,3 +91,58 @@ void SpellAI::UpdateAI(const uint32 diff)
else
DoMeleeAttackIfReady();
}
+
+void SpellCasterAI::InitializeAI()
+{
+ SpellAI::InitializeAI();
+ float m_attackDist = 30.0f;
+ for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr)
+ {
+ if (AISpellInfo[*itr].condition == AICOND_COMBAT && m_attackDist > GetAISpellInfo(*itr)->maxRange)
+ m_attackDist = GetAISpellInfo(*itr)->maxRange;
+ }
+ if (m_attackDist == 30.0f)
+ m_attackDist = MELEE_RANGE;
+}
+
+void SpellCasterAI::EnterCombat(Unit *who)
+{
+ if (spells.empty())
+ return;
+
+ uint32 spell = rand() % spells.size();
+ uint32 count = 0;
+ for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr, ++count)
+ {
+ if(AISpellInfo[*itr].condition == AICOND_AGGRO)
+ me->CastSpell(who, *itr, false);
+ else if (AISpellInfo[*itr].condition == AICOND_COMBAT)
+ {
+ uint32 cooldown = GetAISpellInfo(*itr)->realCooldown;
+ if (count == spell)
+ {
+ DoCast(spells[spell]);
+ cooldown += me->GetCurrentSpellCastTime(*itr);
+ }
+ events.ScheduleEvent(*itr, cooldown);
+ }
+ }
+}
+
+void SpellCasterAI::UpdateAI(const uint32 diff)
+{
+ if(!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if(me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ if(uint32 spellId = events.ExecuteEvent())
+ {
+ DoCast(spellId);
+ uint32 casttime = me->GetCurrentSpellCastTime(spellId);
+ events.ScheduleEvent(spellId, (casttime ? casttime : 500) + GetAISpellInfo(spellId)->realCooldown);
+ }
+}
diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h
index 1b0f36da62e..cec11c0fb22 100644
--- a/src/game/AggressorAI.h
+++ b/src/game/AggressorAI.h
@@ -53,4 +53,16 @@ class TRINITY_DLL_SPEC SpellAI : public CreatureAI
SpellVct spells;
};
+class TRINITY_DLL_SPEC SpellCasterAI : public SpellAI
+{
+ public:
+ explicit SpellCasterAI(Creature *c) : SpellAI(c) {m_attackDist = MELEE_RANGE;}
+ void InitializeAI();
+ void AttackStart(Unit * victim){SpellAI::AttackStartCaster(victim, m_attackDist);}
+ void UpdateAI(const uint32 diff);
+ void EnterCombat(Unit *who);
+ private:
+ float m_attackDist;
+};
+
#endif
diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h
index f6653ce40f7..bcedd108d44 100644
--- a/src/game/CreatureAIImpl.h
+++ b/src/game/CreatureAIImpl.h
@@ -246,10 +246,13 @@ enum AICondition
struct AISpellInfoType
{
- AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {}
+ AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT)
+ , cooldown(AI_DEFAULT_COOLDOWN), realCooldown(0), maxRange(0.0f){}
AITarget target;
AICondition condition;
uint32 cooldown;
+ uint32 realCooldown;
+ float maxRange;
};
TRINITY_DLL_SPEC AISpellInfoType * GetAISpellInfo(uint32 i);
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index 91b9c041066..7b2b846c6e7 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -542,7 +542,6 @@ Map::Add(T *obj)
//also, trigger needs to cast spell, if not update, cannot see visual
//if(obj->GetTypeId() != TYPEID_UNIT)
UpdateObjectVisibility(obj,cell,p);
-
AddNotifier(obj);
}
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 5412277d752..afb1b00648a 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -6856,7 +6856,6 @@ void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties
TempSummon *summon = map->SummonCreature(entry, px, py, pz, m_caster->GetOrientation(), properties, duration, caster);
if(!summon)
return;
-
if(summon->HasSummonMask(SUMMON_MASK_GUARDIAN))
((Guardian*)summon)->InitStatsForLevel(level);
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 961fb623b72..918eb0fbbdc 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -11491,10 +11491,6 @@ Unit* Creature::SelectVictim()
//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;
// First checking if we have some taunt on us
const AuraEffectList& tauntAuras = GetAurasByType(SPELL_AURA_MOD_TAUNT);
diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp
index 9118fc075b6..a41ad894097 100644
--- a/src/game/UnitAI.cpp
+++ b/src/game/UnitAI.cpp
@@ -325,6 +325,10 @@ void UnitAI::FillAISpellInfo()
}
}
}
+ AIInfo->realCooldown = spellInfo->RecoveryTime + spellInfo->StartRecoveryTime;
+ SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
+ if (srange)
+ AIInfo->maxRange = srange->maxRangeHostile * 3 / 4;
}
}