diff options
| -rw-r--r-- | src/bindings/scripts/scripts/npc/npcs_special.cpp | 46 | ||||
| -rw-r--r-- | src/game/AggressorAI.cpp | 55 | ||||
| -rw-r--r-- | src/game/AggressorAI.h | 12 | ||||
| -rw-r--r-- | src/game/CreatureAIImpl.h | 5 | ||||
| -rw-r--r-- | src/game/Map.cpp | 1 | ||||
| -rw-r--r-- | src/game/SpellEffects.cpp | 1 | ||||
| -rw-r--r-- | src/game/Unit.cpp | 4 | ||||
| -rw-r--r-- | src/game/UnitAI.cpp | 4 |
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; } } |
