diff options
-rw-r--r-- | src/bindings/scripts/include/sc_creature.cpp | 79 | ||||
-rw-r--r-- | src/bindings/scripts/include/sc_creature.h | 4 | ||||
-rw-r--r-- | src/game/AggressorAI.cpp | 2 | ||||
-rw-r--r-- | src/game/CreatureAI.cpp | 55 | ||||
-rw-r--r-- | src/game/CreatureAI.h | 3 |
5 files changed, 101 insertions, 42 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 0b874773ffc..e575e40fac1 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -17,13 +17,26 @@ struct TSpellSummary { uint8 Effects; // set of enum SelectEffect } *SpellSummary; +void SummonList::DoZoneInCombat(uint32 entry) +{ + for(iterator i = begin(); i != end();) + { + Creature *summon = Unit::GetCreature(*m_creature, *i); + ++i; + if(summon && summon->IsAIEnabled + && (!entry || summon->GetEntry() == entry)) + summon->AI()->DoZoneInCombat(); + } +} + void SummonList::DoAction(uint32 entry, uint32 info) { for(iterator i = begin(); i != end();) { Creature *summon = Unit::GetCreature(*m_creature, *i); ++i; - if(summon && summon->IsAIEnabled) + if(summon && summon->IsAIEnabled + && (!entry || summon->GetEntry() == entry)) summon->AI()->DoAction(info); } } @@ -213,6 +226,19 @@ Creature* ScriptedAI::DoSpawnCreature(uint32 id, float x, float y, float z, floa return m_creature->SummonCreature(id,m_creature->GetPositionX() + x,m_creature->GetPositionY() + y,m_creature->GetPositionZ() + z, angle, (TempSummonType)type, despawntime); } +Creature *ScriptedAI::DoSummon(uint32 entry, const float pos[4], uint32 despawntime, TempSummonType type) +{ + return me->SummonCreature(entry, pos[0], pos[1], pos[2], pos[3], type, despawntime); +} + +Creature *ScriptedAI::DoSummon(uint32 entry, WorldObject *obj, float radius, uint32 despawntime, TempSummonType type) +{ + float x, y, z; + obj->GetGroundPointAroundUnit(x, y, z, radius * rand_norm(), rand_norm()*2*M_PI); + return me->SummonCreature(entry, x, y, z, me->GetOrientation(), type, despawntime); +} + + Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position) { //ThreatList m_threatlist; @@ -493,6 +519,11 @@ void ScriptedAI::DoTeleportTo(float x, float y, float z, uint32 time) m_creature->SendMonsterMove(x, y, z, time); } +void ScriptedAI::DoTeleportTo(const float pos[4]) +{ + me->NearTeleportTo(pos[0], pos[1], pos[2], pos[3]); +} + void ScriptedAI::DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o) { if(!pUnit || pUnit->GetTypeId() != TYPEID_PLAYER) @@ -642,7 +673,8 @@ void BossAI::_EnterCombat() void BossAI::JustSummoned(Creature *summon) { summons.Summon(summon); - DoZoneInCombat(summon); + if(me->isInCombat()) + DoZoneInCombat(summon); } void BossAI::SummonedCreatureDespawn(Creature *summon) @@ -667,25 +699,36 @@ void LoadOverridenSQLData() goInfo->trap.radius = 50; } -#define SPELL(x) const_cast<SpellEntry*>(GetSpellStore()->LookupEntry(x)) - void LoadOverridenDBCData() { SpellEntry *spellInfo; - - // Black Temple : Illidan : Parasitic Shadowfiend Passive - if(spellInfo = SPELL(41913)) - spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends - - //temp, not needed in 310 - if(spellInfo = SPELL(28531)) - { - spellInfo->DurationIndex = 21; - spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; - } - if(spellInfo = SPELL(55799)) + for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i) { - spellInfo->DurationIndex = 21; - spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + spellInfo = (SpellEntry*)GetSpellStore()->LookupEntry(i); + if(!spellInfo) + continue; + + switch(i) + { + // Black Temple : Illidan : Parasitic Shadowfiend Passive + case 41013: + spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends + break; + //temp, not needed in 310 + case 28531: + case 55799: + spellInfo->DurationIndex = 21; + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + break; + // Naxxramas: Gothik : Inform Inf range + case 27892: + case 27928: + case 27935: + case 27915: + case 27931: + case 27937: + spellInfo->rangeIndex = 13; + break; + } } } diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 0fb716bbe0e..80016619e8b 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -23,6 +23,7 @@ class SummonList : private std::list<uint64> void DespawnEntry(uint32 entry); void DespawnAll(); void DoAction(uint32 entry, uint32 info); + void DoZoneInCombat(uint32 entry = 0); private: Creature *m_creature; }; @@ -152,6 +153,7 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void DoModifyThreatPercent(Unit *pUnit, int32 pct); void DoTeleportTo(float x, float y, float z, uint32 time = 0); + void DoTeleportTo(const float pos[4]); void DoAction(const int32 param) {} @@ -170,6 +172,8 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI //Spawns a creature relative to m_creature Creature* DoSpawnCreature(uint32 id, float x, float y, float z, float angle, uint32 type, uint32 despawntime); + Creature *DoSummon(uint32 entry, const float pos[4], uint32 despawntime = 30000, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN); + Creature *DoSummon(uint32 entry, WorldObject *obj, float radius = 5.0f, uint32 despawntime = 30000, TempSummonType type = TEMPSUMMON_CORPSE_TIMED_DESPAWN); //Selects a unit from the creature's current aggro list Unit* SelectUnit(SelectAggroTarget target, uint32 position); diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 286138fc991..22ebe87cdc6 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -104,7 +104,7 @@ void SpellAI::UpdateAI(const uint32 diff) break; } } - me->CastSpell(target, spellId, false); + if(target) me->CastSpell(target, spellId, false); events.ScheduleEvent(spellId, AISpellInfo[spellId].cooldown + rand()%AISpellInfo[spellId].cooldown); } else diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index ea65d233a17..0864bc973ab 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -39,6 +39,9 @@ void CreatureAI::DoZoneInCombat(Creature* creature) if (!creature) creature = me; + if(!creature->CanHaveThreatList()) + return; + Map *map = creature->GetMap(); if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated { @@ -46,7 +49,7 @@ void CreatureAI::DoZoneInCombat(Creature* creature) return; } - if(!creature->getVictim()) + if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim()) { if(Unit *target = creature->SelectNearestTarget()) creature->AI()->AttackStart(target); @@ -54,29 +57,30 @@ void CreatureAI::DoZoneInCombat(Creature* creature) { if(Unit *summoner = ((TempSummon*)creature)->GetSummoner()) { - if(summoner->getVictim() - && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(summoner->getVictim()))) - creature->AI()->AttackStart(summoner->getVictim()); + Unit *target = summoner->getAttackerForHelper(); + if(!target && summoner->CanHaveThreatList() && !summoner->getThreatManager().isThreatListEmpty()) + target = summoner->getThreatManager().getHostilTarget(); + if(target && (creature->IsFriendlyTo(summoner) || creature->IsHostileTo(target))) + creature->AI()->AttackStart(target); } } } - if (!creature->CanHaveThreatList() || !creature->getVictim()) + if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim()) { - sLog.outError("DoZoneInCombat called for creature that either cannot have threat list or has empty threat list (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? ((Creature*)creature)->GetEntry() : 0); + sLog.outError("DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry()); 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()) - { - creature->SetInCombatWith(i_pl); - i_pl->SetInCombatWith(creature); - creature->AddThreat(i_pl, 0.0f); - } + if (i->getSource()->isAlive()) + { + creature->SetInCombatWith(i->getSource()); + i->getSource()->SetInCombatWith(creature); + creature->AddThreat(i->getSource(), 0.0f); + } } } @@ -102,10 +106,10 @@ bool CreatureAI::UpdateVictim() return me->getVictim(); } -void CreatureAI::EnterEvadeMode() +bool CreatureAI::_EnterEvadeMode() { - if(me->IsInEvadeMode()) - return; + if(me->IsInEvadeMode() || !me->isAlive()) + return false; me->RemoveAllAuras(); me->DeleteThreatList(); @@ -113,13 +117,18 @@ void CreatureAI::EnterEvadeMode() me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); - if(me->isAlive()) - { - if(Unit *owner = me->GetCharmerOrOwner()) - me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE); - else - me->GetMotionMaster()->MoveTargetedHome(); - } + return true; +} + +void CreatureAI::EnterEvadeMode() +{ + if(!_EnterEvadeMode()) + return; + + if(Unit *owner = me->GetCharmerOrOwner()) + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE); + else + me->GetMotionMaster()->MoveTargetedHome(); Reset(); } diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 605e904c71a..c46dd2a54f2 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -168,6 +168,9 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI static AISpellInfoType *AISpellInfo; static void FillAISpellInfo(); + + protected: + bool _EnterEvadeMode(); }; enum Permitions |