From e35d07ad81f5acedcbe436bf429db5581edc6b81 Mon Sep 17 00:00:00 2001 From: megamage Date: Sat, 9 May 2009 10:50:41 -0500 Subject: *Update Sapphiron script. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 22 +++++++++++++++++++--- src/bindings/scripts/include/sc_creature.h | 3 +-- 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src/bindings/scripts/include') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 258c7627dce..a76fbb8e1ef 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -785,13 +785,29 @@ void LoadOverridenSQLData() goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN } +#define SPELL(x) const_cast(GetSpellStore()->LookupEntry(x)) + void LoadOverridenDBCData() { SpellEntry *spellInfo; // Black Temple : Illidan : Parasitic Shadowfiend Passive - spellInfo = const_cast(GetSpellStore()->LookupEntry(41913)); - if(spellInfo) + if(spellInfo = SPELL(41913)) spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends -} + // Naxxramas : Sapphiron : Frost Breath Visual Effect + //if(spellInfo = SPELL(30101)) + // spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST; // orig 18 + + //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)) + { + spellInfo->DurationIndex = 21; + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + } +} diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 638b6926a27..c2c93a520a9 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -137,7 +137,7 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void JustRespawned(); //Called at waypoint reached or PointMovement end - void MovementInform(uint32, uint32){} + void MovementInform(uint32 type, uint32 id){} // Called when AI is temporarily replaced or put back when possess is applied or removed void OnPossess(bool apply) {} @@ -264,7 +264,6 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *) {} void EnterEvadeMode() {} - bool IsVisible(Unit *) const { return false; } void UpdateAI(const uint32) {} }; -- cgit v1.2.3 From 1576a44d38eb1d9c035652e2bc109488d12f1ce4 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 01:22:51 -0500 Subject: *Update naxx script. --HG-- branch : trunk --- sql/updates/3233_world_scripts_naxx.sql | 34 +++++++++ src/bindings/scripts/include/sc_creature.cpp | 13 +++- .../scripts/scripts/zone/naxxramas/boss_noth.cpp | 87 +++++++++++++++++++--- .../scripts/zone/naxxramas/boss_sapphiron.cpp | 5 +- 4 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 sql/updates/3233_world_scripts_naxx.sql (limited to 'src/bindings/scripts/include') diff --git a/sql/updates/3233_world_scripts_naxx.sql b/sql/updates/3233_world_scripts_naxx.sql new file mode 100644 index 00000000000..7272b328f8e --- /dev/null +++ b/sql/updates/3233_world_scripts_naxx.sql @@ -0,0 +1,34 @@ +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (-28169); +INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES +(-28169, 28206, 0, 'Mutating Injection - Mutagen Explosion'), +(-28169, 28240, 0, 'Mutating Injection - Poison Cloud'); + +UPDATE creature_template SET scriptname = 'boss_grobbulus' WHERE entry = 15931; + +INSERT INTO creature_template (entry, spell1, flags_extra, scriptname) VALUES +(16363, 28158, 128, ''), # Grobbulus Cloud +(29379, 54362, 128, '') # Grobbulus Cloud (H) +ON DUPLICATE KEY UPDATE +spell1 = VALUES(spell1), +flags_extra = VALUES(flags_extra), +scriptname = VALUES(scriptname); + +INSERT INTO creature_template (entry, spell1, spell2, flags_extra, scriptname) VALUES +(16474, 28547, 1000, 128, 'trigger_periodic'), # Blizzard (Sapphiron) +(30000, 55699, 1000, 128, 'trigger_periodic') # Blizzard (Sapphiron) (H) +ON DUPLICATE KEY UPDATE +spell1 = VALUES(spell1), +spell2 = VALUES(spell2), +flags_extra = VALUES(flags_extra), +scriptname = VALUES(scriptname); + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (29912); +INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `quest_id`, `cast_flags`) VALUES +(29912, 55479, 0, 1); # Obedience Crystal - Force Obedience + +DELETE FROM `spell_script_target` WHERE `entry` IN (55479); +INSERT INTO `spell_script_target` (`entry`, `type`, `targetEntry`) VALUES +(55479, 1, 16803); # Force Obedience - Death Knight Understudy + +# Death Knight Understudy +UPDATE creature_template SET spell1=0, spell2=0, spell3=0, spell4=61696, spell5=29060, spell6=29061 WHERE entry IN (16803,29941); diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index a76fbb8e1ef..82743bcd9e5 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -775,14 +775,21 @@ void Scripted_NoMovementAI::AttackStart(Unit* who) } } +#define GOBJECT(x) (const_cast(GetGameObjectInfo(x))) + void LoadOverridenSQLData() { GameObjectInfo *goInfo; // Sunwell Plateau : Kalecgos : Spectral Rift - goInfo = const_cast(GetGameObjectInfo(187055)); - if(goInfo && goInfo->type == GAMEOBJECT_TYPE_GOOBER) - goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN + if(goInfo = GOBJECT(187055)) + if(goInfo->type == GAMEOBJECT_TYPE_GOOBER) + goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN + + // Naxxramas : Sapphiron Birth + if(goInfo = GOBJECT(181356)) + if(goInfo->type == GAMEOBJECT_TYPE_TRAP) + goInfo->trap.radius = 50; } #define SPELL(x) const_cast(GetSpellStore()->LookupEntry(x)) diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp index a0ab51a9a2b..22796094557 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_noth.cpp @@ -34,6 +34,7 @@ EndScriptData */ #define SPELL_CURSE_PLAGUEBRINGER HEROIC(29213,54835) #define SPELL_BLINK RAND(29208,29209,29210,29211) #define SPELL_CRIPPLE HEROIC(29212,54814) +#define SPELL_TELEPORT 29216 #define MOB_WARRIOR 16984 #define MOB_CHAMPION 16983 @@ -62,6 +63,9 @@ enum Events EVENT_CURSE, EVENT_BLINK, EVENT_WARRIOR, + EVENT_BALCONY, + EVENT_WAVE, + EVENT_GROUND, }; struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI @@ -74,6 +78,7 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI EventMap events; SummonList summons; ScriptedInstance *instance; + uint32 waveCount, balconyCount; void Reset() { @@ -86,27 +91,38 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI void EnterCombat(Unit *who) { DoScriptText(SAY_AGGRO, me); - DoZoneInCombat(); me->setActive(true); - - events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000); - events.ScheduleEvent(EVENT_WARRIOR, 30000); - if(HeroicMode) - events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000); - + balconyCount = 0; + EnterPhaseGround(); instance->SetBossState(BOSS_NOTH, IN_PROGRESS); } + void EnterPhaseGround() + { + DoZoneInCombat(); + if(me->getThreatManager().isThreatListEmpty()) + EnterEvadeMode(); + else + { + events.ScheduleEvent(EVENT_BALCONY, 11000); + events.ScheduleEvent(EVENT_CURSE, 20000+rand()%10000); + events.ScheduleEvent(EVENT_WARRIOR, 30000); + if(HeroicMode) + events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000); + } + } + void KilledUnit(Unit* victim) { - DoScriptText(SAY_SLAY, me); + if(!(rand()%5)) + DoScriptText(SAY_SLAY, me); } void JustSummoned(Creature *summon) { summons.Summon(summon); summon->setActive(true); - DoZoneInCombat(summon); + summon->AI()->DoZoneInCombat(); } void SummonedCreatureDespawn(Creature *summon) { summons.Despawn(summon); } @@ -130,8 +146,19 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI void UpdateAI(const uint32 diff) { - if(!UpdateVictim()) - return; + if(me->HasReactState(REACT_AGGRESSIVE)) // ground + { + if(!UpdateVictim()) + return; + } + else // balcony + { + if(me->getThreatManager().isThreatListEmpty()) // if no enemy, go back at once + { + events.Reset(); + events.ScheduleEvent(EVENT_GROUND, 0); + } + } events.Update(diff); @@ -154,10 +181,46 @@ struct TRINITY_DLL_DECL boss_nothAI : public ScriptedAI DoResetThreat(); events.ScheduleEvent(EVENT_BLINK, 20000+rand()%10000); return; + case EVENT_BALCONY: + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->AttackStop(); + me->RemoveAllAuras(); + me->NearTeleportTo(TELE_X, TELE_Y, TELE_Z, TELE_O); + events.Reset(); + events.ScheduleEvent(EVENT_WAVE, 2000); + waveCount = 0; + return; + case EVENT_WAVE: + DoScriptText(SAY_SUMMON, me); + switch(balconyCount) + { + case 0: SummonUndead(MOB_CHAMPION, HEROIC(2,4)); break; + case 1: SummonUndead(MOB_CHAMPION, HEROIC(1,2)); + SummonUndead(MOB_GUARDIAN, HEROIC(1,2)); break; + case 2: SummonUndead(MOB_GUARDIAN, HEROIC(2,4)); break; + default:SummonUndead(MOB_CHAMPION, HEROIC(5,10)); + SummonUndead(MOB_GUARDIAN, HEROIC(5,10));break; + } + ++waveCount; + events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, 34000); + return; + case EVENT_GROUND: + { + ++balconyCount; + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + float x, y, z, o; + me->GetHomePosition(x, y, z, o); + me->NearTeleportTo(x, y, z, o); + EnterPhaseGround(); + return; + } } } - DoMeleeAttackIfReady(); + if(me->HasReactState(REACT_AGGRESSIVE)) + DoMeleeAttackIfReady(); } }; diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp index 9ba4bd1f7ee..682f6cee3a9 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp @@ -89,6 +89,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI me->GetPosition(x, y, z); me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0); me->SetVisibility(VISIBILITY_OFF); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_PASSIVE); Reset(); @@ -207,10 +208,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI float x, y, z; me->GetGroundPointAroundUnit(x, y, z, rand_norm()*20, rand_norm()*2*M_PI); if(Creature *summon = me->SummonCreature(MOB_BLIZZARD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 25000+rand()%5000)) - { - summon->setFaction(me->getFaction()); summon->GetMotionMaster()->MoveRandom(40); - } events.ScheduleEvent(EVENT_BLIZZARD, HEROIC(20000,7000), 0, PHASE_GROUND); break; } @@ -295,6 +293,7 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI return; case EVENT_BIRTH: me->SetVisibility(VISIBILITY_ON); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); return; } -- cgit v1.2.3 From 40a8e6d3aba7410fe34c4b6b81f4036f26e0f338 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 14:29:28 -0500 Subject: *Rename some script functions (no real change). --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 150 +-------------------- src/bindings/scripts/include/sc_creature.h | 4 +- .../shadow_labyrinth/boss_grandmaster_vorpil.cpp | 2 +- .../aunchindoun/shadow_labyrinth/boss_murmur.cpp | 4 +- .../scripts/zone/black_temple/boss_illidan.cpp | 12 +- .../scripts/zone/black_temple/boss_supremus.cpp | 4 +- .../zone/black_temple/boss_warlord_najentus.cpp | 2 +- .../zone/caverns_of_time/hyjal/boss_anetheron.cpp | 6 +- .../zone/caverns_of_time/hyjal/boss_azgalor.cpp | 6 +- .../hyjal/boss_rage_winterchill.cpp | 2 +- .../zone/caverns_of_time/hyjal/hyjal_trash.cpp | 2 +- .../serpent_shrine/boss_lurker_below.cpp | 2 +- .../serpent_shrine/boss_morogrim_tidewalker.cpp | 4 +- .../underbog/boss_the_black_stalker.cpp | 2 +- .../scripts/scripts/zone/naxxramas/boss_gothik.cpp | 5 +- .../scripts/zone/sunwell_plateau/boss_felmyst.cpp | 8 +- .../zone/sunwell_plateau/boss_kiljaeden.cpp | 8 +- .../scripts/zone/sunwell_plateau/boss_muru.cpp | 10 +- .../zone/tempest_keep/the_eye/boss_alar.cpp | 2 +- .../zone/tempest_keep/the_eye/boss_astromancer.cpp | 4 +- .../zone/tempest_keep/the_eye/boss_kaelthas.cpp | 6 +- .../zone/temple_of_ahnqiraj/boss_twinemperors.cpp | 6 +- .../scripts/scripts/zone/zulaman/boss_akilzon.cpp | 2 +- .../scripts/scripts/zone/zulaman/boss_hexlord.cpp | 2 +- .../scripts/scripts/zone/zulaman/boss_nalorakk.cpp | 2 +- src/game/CreatureAI.cpp | 144 ++++++++++++++++++++ src/game/CreatureAI.h | 34 ++++- src/game/Object.cpp | 8 ++ src/game/Object.h | 1 + src/game/Unit.cpp | 4 +- src/game/Unit.h | 4 +- 31 files changed, 246 insertions(+), 206 deletions(-) (limited to 'src/bindings/scripts/include') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 82743bcd9e5..4a9f8ec61e8 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -259,147 +259,7 @@ Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position) return NULL; } -struct TargetDistanceOrder : public std::binary_function -{ - const Unit* me; - TargetDistanceOrder(const Unit* Target) : me(Target) {}; - // functor for operator ">" - bool operator()(const Unit* _Left, const Unit* _Right) const - { - return (me->GetDistance(_Left) < me->GetDistance(_Right)); - } -}; - -Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly) -{ - if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - { - std::list &m_threatlist = m_creature->getThreatManager().getThreatList(); - if(m_threatlist.empty()) return NULL; - std::list targetList; - std::list::iterator itr = m_threatlist.begin(); - for(; itr!= m_threatlist.end(); ++itr) - { - Unit *target = (*itr)->getTarget(); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - continue; - } - targetList.push_back(target); - } - if(position >= targetList.size()) - return NULL; - targetList.sort(TargetDistanceOrder(m_creature)); - if(targetType == SELECT_TARGET_NEAREST) - { - std::list::iterator i = targetList.begin(); - advance(i, position); - return *i; - } - else - { - std::list::reverse_iterator i = targetList.rbegin(); - advance(i, position); - return *i; - } - } - else - { - std::list m_threatlist = m_creature->getThreatManager().getThreatList(); - std::list::iterator i; - Unit *target; - while(position < m_threatlist.size()) - { - if(targetType == SELECT_TARGET_BOTTOMAGGRO) - { - i = m_threatlist.end(); - advance(i, - (int32)position - 1); - } - else - { - i = m_threatlist.begin(); - if(targetType == SELECT_TARGET_TOPAGGRO) - advance(i, position); - else // random - advance(i, position + rand()%(m_threatlist.size() - position)); - } - - target = (*i)->getTarget(); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - m_threatlist.erase(i); - } - else - { - return target; - } - } - } - - return NULL; -} - -void ScriptedAI::SelectUnitList(std::list &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly) -{ - if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - { - std::list &m_threatlist = m_creature->getThreatManager().getThreatList(); - if(m_threatlist.empty()) return; - std::list::iterator itr = m_threatlist.begin(); - for(; itr!= m_threatlist.end(); ++itr) - { - Unit *target = (*itr)->getTarget(); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - continue; - } - targetList.push_back(target); - } - targetList.sort(TargetDistanceOrder(m_creature)); - targetList.resize(num); - if(targetType == SELECT_TARGET_FARTHEST) - targetList.reverse(); - } - else - { - std::list m_threatlist = m_creature->getThreatManager().getThreatList(); - std::list::iterator i; - Unit *target; - while(m_threatlist.size() && num) - { - if(targetType == SELECT_TARGET_BOTTOMAGGRO) - { - i = m_threatlist.end(); - --i; - } - else - { - i = m_threatlist.begin(); - if(targetType == SELECT_TARGET_RANDOM) - advance(i, rand()%m_threatlist.size()); - } - - target = (*i)->getTarget(); - m_threatlist.erase(i); - if(!target - || playerOnly && target->GetTypeId() != TYPEID_PLAYER - || dist && !m_creature->IsWithinCombatRange(target, dist)) - { - continue; - } - targetList.push_back(target); - --num; - } - } -} - -SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects) +SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTargetType Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects) { //No target so we can't cast if (!Target) @@ -531,7 +391,7 @@ void FillSpellSummary() SpellEntry const* TempSpell; - for (int i=0; i < GetSpellStore()->GetNumRows(); i++ ) + for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i) { SpellSummary[i].Effects = 0; SpellSummary[i].Targets = 0; @@ -541,7 +401,7 @@ void FillSpellSummary() if (!TempSpell) continue; - for (int j=0; j<3; j++) + for(uint32 j = 0; j < 3; ++j) { //Spell targets self if ( TempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ) @@ -802,10 +662,6 @@ void LoadOverridenDBCData() if(spellInfo = SPELL(41913)) spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends - // Naxxramas : Sapphiron : Frost Breath Visual Effect - //if(spellInfo = SPELL(30101)) - // spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST; // orig 18 - //temp, not needed in 310 if(spellInfo = SPELL(28531)) { diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index c2c93a520a9..44caf063162 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -227,13 +227,11 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI //Selects a unit from the creature's current aggro list Unit* SelectUnit(SelectAggroTarget target, uint32 position); - Unit* SelectUnit(SelectAggroTarget target, uint32 position, float dist, bool playerOnly); - void SelectUnitList(std::list &targetList, uint32 num, SelectAggroTarget target, float dist, bool playerOnly); bool HealthBelowPct(uint32 pct) const { return me->GetHealth() * 100 < m_creature->GetMaxHealth() * pct; } //Returns spells that meet the specified criteria from the creatures spell list - SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect); + SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTargetType Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect); //Checks if you can cast the specified spell bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered = false); diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp index 89fd75b9bc8..52e5a3e8915 100644 --- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp +++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp @@ -262,7 +262,7 @@ struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI if (HeroicMode && banish_Timer < diff) { - Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0,30,false); + Unit *target = SelectTarget(SELECT_TARGET_RANDOM,0,30,false); if (target) { DoCast(target,SPELL_BANISH); diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp index 99bce54be62..599767b591f 100644 --- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp +++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp @@ -118,7 +118,7 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI // Murmur's Touch if (MurmursTouch_Timer < diff) { - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,80,true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,80,true)) DoCast(target, SPELL_MURMURS_TOUCH); MurmursTouch_Timer = 25000 + rand()%10000; }else MurmursTouch_Timer -= diff; @@ -162,7 +162,7 @@ struct TRINITY_DLL_DECL boss_murmurAI : public Scripted_NoMovementAI // Sonic Shock if(SonicShock_Timer < diff) { - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,20,false)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,20,false)) if(target->isAlive()) DoCast(target, SPELL_SONIC_SHOCK); SonicShock_Timer = 10000+rand()%10000; diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp index 60c51f0be33..68431cb81ee 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp @@ -785,7 +785,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI case EVENT_PARASITIC_SHADOWFIEND: { - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 200, true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true)) m_creature->CastSpell(target, SPELL_PARASITIC_SHADOWFIEND, true); Timer[EVENT_PARASITIC_SHADOWFIEND] = 35000 + rand()%10000; }break; @@ -907,7 +907,7 @@ struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI void ChargeCheck() { - Unit* target = SelectUnit(SELECT_TARGET_FARTHEST, 0, 200, false); + Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0, 200, false); if(target && (!m_creature->IsWithinCombatRange(target, FLAME_CHARGE_DISTANCE))) { m_creature->AddThreat(target, 5000000.0f); @@ -1765,7 +1765,7 @@ struct TRINITY_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI { if(!m_creature->getVictim()) { - if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true)) + if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true)) AttackStart(target); else { @@ -1862,15 +1862,15 @@ void boss_illidan_stormrageAI::JustSummoned(Creature* summon) summon->setDeathState(JUST_DIED); return; } - Unit *target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0, 999, true); + Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 999, true); if(!target || target->HasAura(SPELL_PARASITIC_SHADOWFIEND) || target->HasAura(SPELL_PARASITIC_SHADOWFIEND2)) - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true); if(target) summon->AI()->AttackStart(target); }break; case SHADOW_DEMON: - if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true)) // only on players. + if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true)) // only on players. { summon->AddThreat(target, 5000000.0f); summon->AI()->AttackStart(target); diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp index c01db75bd58..fdfdef396bb 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp @@ -198,7 +198,7 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE); break; case EVENT_SWITCH_TARGET: - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 100, true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true)) { DoResetThreat(); m_creature->AddThreat(target, 5000000.0f); @@ -208,7 +208,7 @@ struct TRINITY_DLL_DECL boss_supremusAI : public ScriptedAI break; case EVENT_VOLCANO: { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 999, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true); if(!target) target = m_creature->getVictim(); if(target) { diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp index 7d6b7140a9d..032bccc57ed 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp @@ -171,7 +171,7 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI { //m_creature->CastSpell(m_creature, SPELL_NEEDLE_SPINE, true); std::list target; - SelectUnitList(target, 3, SELECT_TARGET_RANDOM, 80, true); + SelectTargetList(target, 3, SELECT_TARGET_RANDOM, 80, true); for(std::list::iterator i = target.begin(); i != target.end(); ++i) m_creature->CastSpell(*i, 39835, true); events.ScheduleEvent(EVENT_NEEDLE, 15000+rand()%10000, GCD_CAST); diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp index 21b39fa378b..13b0c78ebc1 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp @@ -148,7 +148,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI if(SwarmTimer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,100,true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,100,true); if(target) DoCast(target,SPELL_CARRION_SWARM); @@ -170,7 +170,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI { for(uint8 i=0;i<3;++i) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,100,true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,100,true); if(target) target->CastSpell(target,SPELL_SLEEP,true); } @@ -194,7 +194,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI }else AuraTimer -= diff; if(InfernoTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,100,true), SPELL_INFERNO); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,100,true), SPELL_INFERNO); InfernoTimer = 45000; switch(rand()%2) { diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp index 15085963b20..33e3d344da2 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp @@ -140,13 +140,13 @@ struct TRINITY_DLL_DECL boss_azgalorAI : public hyjal_trashAI if(RainTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,30,true), SPELL_RAIN_OF_FIRE); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,30,true), SPELL_RAIN_OF_FIRE); RainTimer = 20000+rand()%15000; }else RainTimer -= diff; if(DoomTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,1,100,true), SPELL_DOOM);//never on tank + DoCast(SelectTarget(SELECT_TARGET_RANDOM,1,100,true), SPELL_DOOM);//never on tank DoomTimer = 45000+rand()%5000; }else DoomTimer -= diff; @@ -260,7 +260,7 @@ struct TRINITY_DLL_DECL mob_lesser_doomguardAI : public hyjal_trashAI if(CrippleTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,100,true), SPELL_CRIPPLE); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,100,true), SPELL_CRIPPLE); CrippleTimer = 25000+rand()%5000; }else CrippleTimer -= diff; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp index addbddab5b8..3e6b2bc8e98 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp @@ -169,7 +169,7 @@ struct TRINITY_DLL_DECL boss_rage_winterchillAI : public hyjal_trashAI }else NovaTimer -= diff; if(IceboltTimer < diff) { - DoCast(SelectUnit(SELECT_TARGET_RANDOM,0,40,true), SPELL_ICEBOLT); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,0,40,true), SPELL_ICEBOLT); IceboltTimer = 11000+rand()%20000; }else IceboltTimer -= diff; diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp index 583c7831af5..30f0c14caaf 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp @@ -724,7 +724,7 @@ struct mob_necromancerAI : public hyjal_trashAI void JustSummoned(Creature* summon) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,30,true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM,0,30,true); if(target && summon) summon->Attack(target,false); summons.Summon(summon); diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp index eb35a3c74b4..254a4d1d899 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp @@ -322,7 +322,7 @@ struct TRINITY_DLL_DECL boss_the_lurker_belowAI : public Scripted_NoMovementAI if(WaterboltTimer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_NEAREST,0,14,true); + Unit* target = SelectTarget(SELECT_TARGET_NEAREST,0,14,true); if(!target) { target = SelectUnit(SELECT_TARGET_RANDOM,0); diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp index cea591182d5..f8d27df5bb0 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp @@ -235,7 +235,7 @@ struct TRINITY_DLL_DECL boss_morogrim_tidewalkerAI : public ScriptedAI for(uint8 i = 0; i < 4; i++) { counter = 0; - do{target = SelectUnit(SELECT_TARGET_RANDOM, 1, 50, true); //target players only + do{target = SelectTarget(SELECT_TARGET_RANDOM, 1, 50, true); //target players only if(counter < Playercount) break; if(target) itr = list.find(target->GetGUID()); @@ -272,7 +272,7 @@ struct TRINITY_DLL_DECL boss_morogrim_tidewalkerAI : public ScriptedAI for (int8 g = 0; g < 4; g++) //one unit cant cast more than one spell per update, so some players have to cast for us XD { counter = 0; - do {globuletarget = SelectUnit(SELECT_TARGET_RANDOM, 0,50,true); + do {globuletarget = SelectTarget(SELECT_TARGET_RANDOM, 0,50,true); if(globuletarget) itr = globulelist.find(globuletarget->GetGUID()); if (counter > Playercount) break; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp index 370b07c8adc..72c7992e109 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/underbog/boss_the_black_stalker.cpp @@ -165,7 +165,7 @@ struct TRINITY_DLL_DECL boss_the_black_stalkerAI : public ScriptedAI // Static Charge if(StaticCharge_Timer < diff) { - if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0,30,true)) + if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM,0,30,true)) DoCast(target, SPELL_STATIC_CHARGE); StaticCharge_Timer = 10000; }else StaticCharge_Timer -= diff; diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp index 0becff399da..3a9c6a5b47a 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_gothik.cpp @@ -30,8 +30,9 @@ EndScriptData */ //Gothik #define SPELL_HARVESTSOUL 28679 -#define SPELL_SHADOWBOLT 29317 -#define H_SPELL_SHADOWBOLT 56405 +#define SPELL_SHADOWBOLT HEROIC(29317,56405) +#define SPELL_SOUL_SIPHON 43591 // cannot find the correct spell + //Unrelenting Trainee #define SPELL_EAGLECLAW 30285 #define SPELL_KNOCKDOWN_PASSIVE 6961 diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp index 8e42d074f88..e753d0b6047 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp @@ -306,7 +306,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI case 2:{ error_log("Summon Vapor case 2"); Unit* target; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true); if(!target) target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_PLAYER_GUID)); if(target) { @@ -331,7 +331,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI error_log("Summon Vapor case3"); //m_creature->CastSpell(m_creature, SPELL_VAPOR_SELECT); need core support Unit* target; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true); if(!target) target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_PLAYER_GUID)); if(target) { @@ -358,7 +358,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI break; case 5:{ Unit* target; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true); if(!target) target = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_PLAYER_GUID)); if(target) { @@ -471,7 +471,7 @@ struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI Timer[EVENT_GAS_NOVA] = 20000 + rand()%5 * 1000; break; case EVENT_ENCAPSULATE: - if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 150, true)) + if(Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150, true)) { m_creature->CastSpell(target, SPELL_ENCAPSULATE_CHANNEL, false); target->CastSpell(target, SPELL_ENCAPSULATE_EFFECT, true);// linked aura, need core patch to remove this hack diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp index 98cbfda7a7f..a0bd75cb156 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp @@ -540,7 +540,7 @@ struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI float x,y,z; Unit* target; for(uint8 z = 0; z < 6; ++z){ - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!target->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break; } target->GetPosition(x,y,z); @@ -584,7 +584,7 @@ struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI if(!m_creature->IsNonMeleeSpellCasted(false)){ m_creature->RemoveAurasDueToSpell(SPELL_SOUL_FLAY); for(uint8 z = 0; z < 6; ++z){ - randomPlayer = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + randomPlayer = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!randomPlayer->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break; } if(randomPlayer)DoCast(randomPlayer, SPELL_LEGION_LIGHTNING, false); @@ -658,7 +658,7 @@ struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI case TIMER_ARMAGEDDON: //Phase 4 Unit* target; for(uint8 z = 0; z < 6; ++z){ - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if (!target->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break; } if(target){ @@ -1199,7 +1199,7 @@ struct TRINITY_DLL_DECL mob_sinster_reflectionAI : public ScriptedAI Timer[1] = 4000; } if(Timer[2] < diff){ - DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_SR_CURSE_OF_AGONY, true); + DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_SR_CURSE_OF_AGONY, true); Timer[2] = 3000; } DoMeleeAttackIfReady(); diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp index 6000ee474e0..b38607e1a7f 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_muru.cpp @@ -155,7 +155,7 @@ struct TRINITY_DLL_DECL boss_entropiusAI : public ScriptedAI m_creature->SummonCreature(CREATURE_DARK_FIENDS, x,y,z,o, TEMPSUMMON_CORPSE_DESPAWN, 0); break; } - summoned->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM,0, 50, true)); + summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM,0, 50, true)); Summons.Summon(summoned); } @@ -180,10 +180,10 @@ struct TRINITY_DLL_DECL boss_entropiusAI : public ScriptedAI }else EnrageTimer -= diff; if(BlackHoleSummonTimer < diff){ - Unit* random = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + Unit* random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if(!random)return; DoCast(random, SPELL_DARKNESS_E, false); - random = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true); + random = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); if(!random)return; random->CastSpell(random, SPELL_BLACKHOLE, false); BlackHoleSummonTimer = 15000; @@ -260,7 +260,7 @@ struct TRINITY_DLL_DECL boss_muruAI : public Scripted_NoMovementAI summoned->CastSpell(summoned,SPELL_DARKFIEND_VISUAL,false); break; } - summoned->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM,0, 50, true)); + summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM,0, 50, true)); Summons.Summon(summoned); } @@ -441,7 +441,7 @@ struct TRINITY_DLL_DECL npc_dark_fiendAI : public ScriptedAI if(!InAction){ m_creature->clearUnitState(UNIT_STAT_STUNNED); DoCastAOE(SPELL_DARKFIEND_SKIN, false); - AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true)); + AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)); InAction = true; WaitTimer = 500; }else{ diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp index 168f0f48e3a..af44d96d417 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp @@ -352,7 +352,7 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI if(Charge_Timer < diff) { - Unit *target= SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_CHARGE), true); + Unit *target= SelectTarget(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_CHARGE), true); if(target) DoCast(target, SPELL_CHARGE); Charge_Timer = 30000; diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp index 83cb789b189..6af14eceeed 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp @@ -230,7 +230,7 @@ struct TRINITY_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI if( Wrath_Timer < diff) { m_creature->InterruptNonMeleeSpells(false); - DoCast(SelectUnit(SELECT_TARGET_RANDOM,1,100,true), SPELL_WRATH_OF_THE_ASTROMANCER, true); + DoCast(SelectTarget(SELECT_TARGET_RANDOM,1,100,true), SPELL_WRATH_OF_THE_ASTROMANCER, true); Wrath_Timer = 20000+rand()%5000; }else Wrath_Timer -= diff; @@ -260,7 +260,7 @@ struct TRINITY_DLL_DECL boss_high_astromancer_solarianAI : public ScriptedAI if (MarkOfTheAstromancer_Timer < diff) //A debuff that lasts for 5 seconds, cast several times each phase on a random raid member, but not the main tank { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1, 100, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); if(target) DoCast(target, SPELL_MARK_OF_THE_ASTROMANCER); else DoCast(m_creature->getVictim(), SPELL_MARK_OF_THE_ASTROMANCER); diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp index 6745c4fd9ec..7557e03f8e5 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp @@ -804,7 +804,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI if (FlameStrike_Timer < diff) { - if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0, 70, true)) + if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true)) DoCast(pUnit, SPELL_FLAME_STRIKE); FlameStrike_Timer = 30000; @@ -816,7 +816,7 @@ struct TRINITY_DLL_DECL boss_kaelthasAI : public ScriptedAI for (uint32 i = 0; i < 3; i++) { - Unit* target =SelectUnit(SELECT_TARGET_RANDOM, 1, 70, true); + Unit* target =SelectTarget(SELECT_TARGET_RANDOM, 1, 70, true); if(!target) target = m_creature->getVictim(); debug_log("TSCR: Kael'Thas mind control not supported."); if(target) @@ -1080,7 +1080,7 @@ struct TRINITY_DLL_DECL boss_thaladred_the_darkenerAI : public advisorbase_ai //Gaze_Timer if(Gaze_Timer < diff) { - if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { DoResetThreat(); if(target) diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp index c3d4d0f35eb..d2fff0e569f 100644 --- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp +++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp @@ -465,7 +465,7 @@ struct TRINITY_DLL_DECL boss_veknilashAI : public boss_twinemperorsAI if (UpperCut_Timer < diff) { - Unit* randomMelee = SelectUnit(SELECT_TARGET_RANDOM, 0, NOMINAL_MELEE_RANGE, true); + Unit* randomMelee = SelectTarget(SELECT_TARGET_RANDOM, 0, NOMINAL_MELEE_RANGE, true); if (randomMelee) DoCast(randomMelee,SPELL_UPPERCUT); UpperCut_Timer = 15000+rand()%15000; @@ -560,7 +560,7 @@ struct TRINITY_DLL_DECL boss_veklorAI : public boss_twinemperorsAI if (Blizzard_Timer < diff) { Unit* target = NULL; - target = SelectUnit(SELECT_TARGET_RANDOM, 0, 45, true); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45, true); if (target) DoCast(target,SPELL_BLIZZARD); Blizzard_Timer = 15000+rand()%15000; @@ -569,7 +569,7 @@ struct TRINITY_DLL_DECL boss_veklorAI : public boss_twinemperorsAI if (ArcaneBurst_Timer < diff) { Unit *mvic; - if ((mvic=SelectUnit(SELECT_TARGET_NEAREST, 0, NOMINAL_MELEE_RANGE, true))!=NULL) + if ((mvic=SelectTarget(SELECT_TARGET_NEAREST, 0, NOMINAL_MELEE_RANGE, true))!=NULL) { DoCast(mvic,SPELL_ARCANEBURST); ArcaneBurst_Timer = 5000; diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp index f31f944a3d4..85ba26ef20d 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_akilzon.cpp @@ -297,7 +297,7 @@ struct TRINITY_DLL_DECL boss_akilzonAI : public ScriptedAI } if (ElectricalStorm_Timer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 50, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); if(!target) { EnterEvadeMode(); diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp index 7fb8dc9b321..26229261905 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp @@ -383,7 +383,7 @@ struct TRINITY_DLL_DECL boss_hex_lord_malacrassAI : public ScriptedAI if(SiphonSoul_Timer < diff) { - Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 70, true); + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); Unit *trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); if(!target || !trigger) { diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp index 9fc50e621ac..68b92590025 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp @@ -406,7 +406,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI { DoYell(YELL_SURGE, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_YELL_SURGE); - Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_SURGE), true); + Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_SURGE), true); if(target) DoCast(target, SPELL_SURGE); Surge_Timer = 15000 + rand()%5000; diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 5cde80aaccb..0713ef592d3 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -71,6 +71,8 @@ void CreatureAI::OnCharmed(bool apply) me->IsAIEnabled = false; } +AISpellInfoType *AISpellInfo; + void CreatureAI::DoZoneInCombat(Creature* creature) { if (!creature) @@ -151,6 +153,148 @@ void CreatureAI::EnterEvadeMode() me->GetMotionMaster()->MoveTargetedHome(); } +inline bool SelectTargetHelper(const Unit * me, const Unit * target, const bool &playerOnly, const float &dist, const int32 &aura) +{ + if(playerOnly && target->GetTypeId() != TYPEID_PLAYER) + return false; + + if(dist && !me->IsWithinCombatRange(target, dist)) + return false; + + if(aura) + { + if(aura > 0) + { + if(!target->HasAura(aura)) + return false; + } + else + { + if(target->HasAura(aura)) + return false; + } + } + + return true; +} + +struct TargetDistanceOrder : public std::binary_function +{ + const Unit * me; + TargetDistanceOrder(const Unit* Target) : me(Target) {}; + // functor for operator ">" + bool operator()(const Unit * _Left, const Unit * _Right) const + { + return (me->GetDistanceSq(_Left) < me->GetDistanceSq(_Right)); + } +}; + +Unit* CreatureAI::SelectTarget(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly, int32 aura) +{ + if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) + { + std::list &m_threatlist = me->getThreatManager().getThreatList(); + if(position >= m_threatlist.size()) + return NULL; + + std::list targetList; + for(std::list::iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) + if(SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) + targetList.push_back((*itr)->getTarget()); + + if(position >= targetList.size()) + return NULL; + + targetList.sort(TargetDistanceOrder(m_creature)); + + if(targetType == SELECT_TARGET_NEAREST) + { + std::list::iterator i = targetList.begin(); + advance(i, position); + return *i; + } + else + { + std::list::reverse_iterator i = targetList.rbegin(); + advance(i, position); + return *i; + } + } + else + { + std::list m_threatlist = me->getThreatManager().getThreatList(); + std::list::iterator i; + while(position < m_threatlist.size()) + { + if(targetType == SELECT_TARGET_BOTTOMAGGRO) + { + i = m_threatlist.end(); + advance(i, - (int32)position - 1); + } + else + { + i = m_threatlist.begin(); + if(targetType == SELECT_TARGET_TOPAGGRO) + advance(i, position); + else // random + advance(i, position + rand()%(m_threatlist.size() - position)); + } + + if(SelectTargetHelper(me, (*i)->getTarget(), playerOnly, dist, aura)) + return (*i)->getTarget(); + else + m_threatlist.erase(i); + } + } + + return NULL; +} + +void CreatureAI::SelectTargetList(std::list &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly, int32 aura) +{ + if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) + { + std::list &m_threatlist = m_creature->getThreatManager().getThreatList(); + if(m_threatlist.empty()) + return; + + for(std::list::iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) + if(SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) + targetList.push_back((*itr)->getTarget()); + + targetList.sort(TargetDistanceOrder(me)); + targetList.resize(num); + if(targetType == SELECT_TARGET_FARTHEST) + targetList.reverse(); + } + else + { + std::list m_threatlist = me->getThreatManager().getThreatList(); + std::list::iterator i; + while(!m_threatlist.empty() && num) + { + if(targetType == SELECT_TARGET_BOTTOMAGGRO) + { + i = m_threatlist.end(); + --i; + } + else + { + i = m_threatlist.begin(); + if(targetType == SELECT_TARGET_RANDOM) + advance(i, rand()%m_threatlist.size()); + } + + if(SelectTargetHelper(me, (*i)->getTarget(), playerOnly, dist, aura)) + { + targetList.push_back((*i)->getTarget()); + --num; + } + m_threatlist.erase(i); + } + } +} + void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) { Creature *charmer = (Creature*)me->GetCharmer(); diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index e3a5a674e68..16271775728 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -37,7 +37,7 @@ struct SpellEntry; #define VISIBILITY_RANGE 10000 //Spell targets used by SelectSpell -enum SelectTarget +enum SelectTargetType { SELECT_TARGET_DONTCARE = 0, //All target types allowed @@ -77,6 +77,35 @@ enum SCEquip EQUIP_UNEQUIP = 0 }; +enum AITarget +{ + AITARGET_SELF, + AITARGET_VICTIM, + AITARGET_ENEMY, + AITARGET_ALLY, + AITARGET_BUFF, + AITARGET_DEBUFF, +}; + +enum AICondition +{ + AICOND_AGGRO, + AICOND_COMBAT, + AICOND_DIE, +}; + +#define AI_DEFAULT_COOLDOWN 5000 + +struct AISpellInfoType +{ + AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} + AITarget target; + AICondition condition; + uint32 cooldown; +}; + +extern AISpellInfoType *AISpellInfo; + class EventMap : private std::map { private: @@ -273,6 +302,9 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI // Pointer to controlled by AI creature //Creature* const m_creature; + + Unit* SelectTarget(SelectAggroTarget target, uint32 position = 0, float dist = 0, bool playerOnly = false, int32 aura = 0); + void SelectTargetList(std::list &targetList, uint32 num, SelectAggroTarget target, float dist = 0, bool playerOnly = false, int32 aura = 0); }; struct SelectableAI : public FactoryHolder, public Permissible diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 6b7a3cdd4ac..a436732f0a6 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1194,6 +1194,14 @@ float WorldObject::GetDistanceSq(const float &x, const float &y, const float &z) return dx*dx + dy*dy + dz*dz; } +float WorldObject::GetDistanceSq(const WorldObject *obj) const +{ + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float dz = GetPositionZ() - obj->GetPositionZ(); + 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 e7e03501dc1..01c31d5b9b4 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -463,6 +463,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 GetDistanceSq(const WorldObject *obj) const; float GetDistance2d(const WorldObject* obj) const; float GetDistance2d(const float x, const float y) const; float GetExactDistance2d(const float x, const float y) const; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6a9f122adf4..3f09eec9351 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -413,7 +413,7 @@ void Unit::resetAttackTimer(WeaponAttackType type) m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); } -bool Unit::IsWithinCombatRange(Unit *obj, float dist2compare) const +bool Unit::IsWithinCombatRange(const Unit *obj, float dist2compare) const { if (!obj || !IsInMap(obj)) return false; @@ -428,7 +428,7 @@ bool Unit::IsWithinCombatRange(Unit *obj, float dist2compare) const return distsq < maxdist * maxdist; } -bool Unit::IsWithinMeleeRange(Unit *obj, float dist) const +bool Unit::IsWithinMeleeRange(const Unit *obj, float dist) const { if (!obj || !IsInMap(obj)) return false; diff --git a/src/game/Unit.h b/src/game/Unit.h index 5d08cbfa2fb..bb303473e7b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -940,8 +940,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void SetCanDualWield(bool value) { m_canDualWield = value; } float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; } float GetMeleeReach() const { float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; } - bool IsWithinCombatRange(Unit *obj, float dist2compare) const; - bool IsWithinMeleeRange(Unit *obj, float dist = MELEE_RANGE) const; + bool IsWithinCombatRange(const Unit *obj, float dist2compare) const; + bool IsWithinMeleeRange(const Unit *obj, float dist = MELEE_RANGE) const; void GetRandomContactPoint( const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const; uint32 m_extraAttacks; bool m_canDualWield; -- cgit v1.2.3 From dcf41256ddaa341b532bd7c565c3d18a7c3b6757 Mon Sep 17 00:00:00 2001 From: megamage Date: Sun, 10 May 2009 16:07:49 -0500 Subject: *Move some AI functions to core. No real change. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 1 - src/bindings/scripts/include/sc_creature.h | 76 ++----- src/game/CMakeLists.txt | 5 +- src/game/CreatureAI.cpp | 64 +----- src/game/CreatureAI.h | 166 +------------- src/game/CreatureAIFactory.h | 53 +++++ src/game/CreatureAIImpl.h | 153 ++++++++++++- src/game/CreatureAIRegistry.cpp | 3 +- src/game/CreatureAISelector.cpp | 2 +- src/game/InstanceSaveMgr.cpp | 2 + src/game/NullCreatureAI.h | 1 + src/game/PossessedAI.cpp | 20 -- src/game/PossessedAI.h | 25 --- src/game/UnitAI.cpp | 84 ++++++++ src/game/UnitAI.h | 68 ++++++ win/VC80/game.vcproj | 224 +++++++++---------- win/VC90/game.vcproj | 309 ++++++++++++++------------- 17 files changed, 653 insertions(+), 603 deletions(-) create mode 100644 src/game/CreatureAIFactory.h delete mode 100644 src/game/PossessedAI.cpp delete mode 100644 src/game/PossessedAI.h create mode 100644 src/game/UnitAI.cpp create mode 100644 src/game/UnitAI.h (limited to 'src/bindings/scripts/include') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 4a9f8ec61e8..42ee15074ed 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -375,7 +375,6 @@ bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered) return true; } - float GetSpellMaxRangeForHostile(uint32 id) { SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(id); diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 44caf063162..8336df545b6 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -8,75 +8,25 @@ #ifndef SC_CREATURE_H #define SC_CREATURE_H -#include "CreatureAI.h" #include "Creature.h" - -#define HEROIC(n,h) (HeroicMode ? h : n) - -template -inline -const T& RAND(const T& v1, const T& v2) -{ - return rand()%2 ? v1 : v2; -} - -template -inline -const T& RAND(const T& v1, const T& v2, const T& v3) -{ - switch(rand()%3) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - } -} - -template -inline -const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) -{ - switch(rand()%4) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - case 3: return v4; - } -} - -template -inline -const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) -{ - switch(rand()%4) - { - default: - case 0: return v1; - case 1: return v2; - case 2: return v3; - case 3: return v4; - case 4: return v5; - } -} - -float GetSpellMaxRangeForHostile(uint32 id); +#include "CreatureAI.h" +#include "CreatureAIImpl.h" class SummonList : private std::list { -public: - explicit SummonList(Creature* creature) : m_creature(creature) {} - void Summon(Creature *summon) { push_back(summon->GetGUID()); } - void Despawn(Creature *summon) { remove(summon->GetGUID()); } - void DespawnEntry(uint32 entry); - void DespawnAll(); - void DoAction(uint32 entry, uint32 info); -private: - Creature *m_creature; + public: + explicit SummonList(Creature* creature) : m_creature(creature) {} + void Summon(Creature *summon) { push_back(summon->GetGUID()); } + void Despawn(Creature *summon) { remove(summon->GetGUID()); } + void DespawnEntry(uint32 entry); + void DespawnAll(); + void DoAction(uint32 entry, uint32 info); + private: + Creature *m_creature; }; +float GetSpellMaxRangeForHostile(uint32 id); + //Get a single creature of given entry Unit* FindCreature(uint32 entry, float range, Unit* Finder); diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 081d9669696..89a9e460968 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -68,6 +68,7 @@ SET(game_STAT_SRCS Corpse.h CreatureAI.cpp CreatureAI.h + CreatureAIFactory.h CreatureAIImpl.h CreatureAIRegistry.cpp CreatureAIRegistry.h @@ -208,8 +209,6 @@ SET(game_STAT_SRCS PointMovementGenerator.h PoolHandler.cpp PoolHandler.h - PossessedAI.cpp - PossessedAI.h QueryHandler.cpp QuestDef.cpp QuestDef.h @@ -262,6 +261,8 @@ SET(game_STAT_SRCS Traveller.h Unit.cpp Unit.h + UnitAI.cpp + UnitAI.h UnitEvents.h UpdateData.cpp UpdateData.h diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 0713ef592d3..2390b359731 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -19,50 +19,12 @@ */ #include "CreatureAI.h" +#include "CreatureAIImpl.h" #include "Creature.h" #include "Player.h" #include "Pet.h" -#include "SpellAuras.h" #include "World.h" -void UnitAI::AttackStart(Unit *victim) -{ - if(!victim) - return; - - if(me->Attack(victim, true)) - { - //DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", me->GetName(), victim->GetGUIDLow()); - me->GetMotionMaster()->MoveChase(victim); - } -} - -void UnitAI::DoMeleeAttackIfReady() -{ - //Make sure our attack is ready and we aren't currently casting before checking distance - if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) - { - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); - } - } - if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) - { - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - me->AttackerStateUpdate(me->getVictim(), OFF_ATTACK); - me->resetAttackTimer(OFF_ATTACK); - } - } -} - -//Enable PlayerAI when charmed -void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } - //Disable CreatureAI when charmed void CreatureAI::OnCharmed(bool apply) { @@ -295,30 +257,6 @@ void CreatureAI::SelectTargetList(std::list &targetList, uint32 num, Sele } } -void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) -{ - Creature *charmer = (Creature*)me->GetCharmer(); - - //kill self if charm aura has infinite duration - if(charmer->IsInEvadeMode()) - { - Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM); - for(Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) - if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent()) - { - charmer->Kill(me); - return; - } - } - - if(!charmer->isInCombat()) - me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - - Unit *target = me->getVictim(); - if(!target || !charmer->canAttack(target)) - AttackStart(charmer->SelectNearestTarget()); -} - /*void CreatureAI::AttackedBy( Unit* attacker ) { if(!m_creature->getVictim()) diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 16271775728..6df7dcfbe95 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -23,9 +23,7 @@ #include "Common.h" #include "Platform/Define.h" -#include "Policies/Singleton.h" -#include "Dynamic/ObjectRegistry.h" -#include "Dynamic/FactoryHolder.h" +#include "UnitAI.h" class WorldObject; class Unit; @@ -77,149 +75,11 @@ enum SCEquip EQUIP_UNEQUIP = 0 }; -enum AITarget -{ - AITARGET_SELF, - AITARGET_VICTIM, - AITARGET_ENEMY, - AITARGET_ALLY, - AITARGET_BUFF, - AITARGET_DEBUFF, -}; - -enum AICondition -{ - AICOND_AGGRO, - AICOND_COMBAT, - AICOND_DIE, -}; - -#define AI_DEFAULT_COOLDOWN 5000 - -struct AISpellInfoType -{ - AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} - AITarget target; - AICondition condition; - uint32 cooldown; -}; - -extern AISpellInfoType *AISpellInfo; - -class EventMap : private std::map -{ - private: - uint32 m_time, m_phase; - public: - explicit EventMap() : m_phase(0), m_time(0) {} - - void Reset() { clear(); m_time = 0; m_phase = 0; } - - void Update(uint32 time) { m_time += time; } - - void SetPhase(uint32 phase) - { - if(phase && phase < 9) - m_phase = (1 << (phase + 24)); - } - - void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) - { - time += m_time; - if(gcd && gcd < 9) - eventId |= (1 << (gcd + 16)); - if(phase && phase < 9) - eventId |= (1 << (phase + 24)); - iterator itr = find(time); - while(itr != end()) - { - ++time; - itr = find(time); - } - insert(std::make_pair(time, eventId)); - } - - uint32 ExecuteEvent() - { - while(!empty()) - { - if(begin()->first > m_time) - return 0; - else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) - erase(begin()); - else - { - uint32 eventId = (begin()->second & 0x0000FFFF); - erase(begin()); - return eventId; - } - } - return 0; - } - - void DelayEvents(uint32 time, uint32 gcd) - { - time += m_time; - gcd = (1 << (gcd + 16)); - for(iterator itr = begin(); itr != end();) - { - if(itr->first >= time) - break; - if(itr->second & gcd) - { - ScheduleEvent(time, itr->second); - erase(itr++); - } - else - ++itr; - } - } -}; - -class TRINITY_DLL_SPEC UnitAI -{ - protected: - Unit* const me; - public: - explicit UnitAI(Unit *u) : me(u) {} - virtual void AttackStart(Unit *); - virtual void UpdateAI(const uint32 diff) = 0; - - virtual void InitializeAI() { Reset(); } - - virtual void Reset() {}; - - // Called when unit is charmed - virtual void OnCharmed(bool apply) = 0; - - // Pass parameters between AI - virtual void DoAction(const int32 param) {} - - //Do melee swing of current victim if in rnage and ready and not casting - void DoMeleeAttackIfReady(); -}; - -class TRINITY_DLL_SPEC PlayerAI : public UnitAI -{ - protected: - Player* const me; - public: - explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {} - - void OnCharmed(bool apply); -}; - -class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI -{ - public: - void UpdateAI(const uint32 diff); -}; - class TRINITY_DLL_SPEC CreatureAI : public UnitAI { protected: - Creature* const me; - Creature* const m_creature; + Creature * const me; + Creature * const m_creature; bool UpdateVictim(); public: @@ -307,22 +167,6 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI void SelectTargetList(std::list &targetList, uint32 num, SelectAggroTarget target, float dist = 0, bool playerOnly = false, int32 aura = 0); }; -struct SelectableAI : public FactoryHolder, public Permissible -{ - - SelectableAI(const char *id) : FactoryHolder(id) {} -}; - -template -struct CreatureAIFactory : public SelectableAI -{ - CreatureAIFactory(const char *name) : SelectableAI(name) {} - - CreatureAI* Create(void *) const; - - int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } -}; - enum Permitions { PERMIT_BASE_NO = -1, @@ -333,8 +177,4 @@ enum Permitions PERMIT_BASE_SPECIAL = 800 }; -typedef FactoryHolder CreatureAICreator; -typedef FactoryHolder::FactoryHolderRegistry CreatureAIRegistry; -typedef FactoryHolder::FactoryHolderRepository CreatureAIRepository; #endif - diff --git a/src/game/CreatureAIFactory.h b/src/game/CreatureAIFactory.h new file mode 100644 index 00000000000..d546c2b1720 --- /dev/null +++ b/src/game/CreatureAIFactory.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2009 Trinity + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef TRINITY_CREATUREAIFACTORY_H +#define TRINITY_CREATUREAIFACTORY_H + +//#include "Policies/Singleton.h" +#include "Dynamic/ObjectRegistry.h" +#include "Dynamic/FactoryHolder.h" + +struct SelectableAI : public FactoryHolder, public Permissible +{ + SelectableAI(const char *id) : FactoryHolder(id) {} +}; + +template +struct CreatureAIFactory : public SelectableAI +{ + CreatureAIFactory(const char *name) : SelectableAI(name) {} + + CreatureAI* Create(void *) const; + + int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } +}; + +template +inline CreatureAI* +CreatureAIFactory::Create(void *data) const +{ + Creature* creature = reinterpret_cast(data); + return (new REAL_AI(creature)); +} + +typedef FactoryHolder CreatureAICreator; +typedef FactoryHolder::FactoryHolderRegistry CreatureAIRegistry; +typedef FactoryHolder::FactoryHolderRepository CreatureAIRepository; +#endif diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index a8b8271c5ff..823f4cbcca6 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -20,14 +20,155 @@ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H -#include "CreatureAI.h" +#define HEROIC(n,h) (HeroicMode ? h : n) -template -inline CreatureAI* -CreatureAIFactory::Create(void *data) const +template +inline +const T& RAND(const T& v1, const T& v2) { - Creature* creature = reinterpret_cast(data); - return (new REAL_AI(creature)); + return rand()%2 ? v1 : v2; } + +template +inline +const T& RAND(const T& v1, const T& v2, const T& v3) +{ + switch(rand()%3) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + } +} + +template +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) +{ + switch(rand()%4) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + } +} + +template +inline +const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) +{ + switch(rand()%4) + { + default: + case 0: return v1; + case 1: return v2; + case 2: return v3; + case 3: return v4; + case 4: return v5; + } +} + +class EventMap : private std::map +{ + private: + uint32 m_time, m_phase; + public: + explicit EventMap() : m_phase(0), m_time(0) {} + + void Reset() { clear(); m_time = 0; m_phase = 0; } + + void Update(uint32 time) { m_time += time; } + + void SetPhase(uint32 phase) + { + if(phase && phase < 9) + m_phase = (1 << (phase + 24)); + } + + void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) + { + time += m_time; + if(gcd && gcd < 9) + eventId |= (1 << (gcd + 16)); + if(phase && phase < 9) + eventId |= (1 << (phase + 24)); + iterator itr = find(time); + while(itr != end()) + { + ++time; + itr = find(time); + } + insert(std::make_pair(time, eventId)); + } + + uint32 ExecuteEvent() + { + while(!empty()) + { + if(begin()->first > m_time) + return 0; + else if(m_phase && (begin()->second & 0xFF000000) && !(begin()->second & m_phase)) + erase(begin()); + else + { + uint32 eventId = (begin()->second & 0x0000FFFF); + erase(begin()); + return eventId; + } + } + return 0; + } + + void DelayEvents(uint32 time, uint32 gcd) + { + time += m_time; + gcd = (1 << (gcd + 16)); + for(iterator itr = begin(); itr != end();) + { + if(itr->first >= time) + break; + if(itr->second & gcd) + { + ScheduleEvent(time, itr->second); + erase(itr++); + } + else + ++itr; + } + } +}; + +enum AITarget +{ + AITARGET_SELF, + AITARGET_VICTIM, + AITARGET_ENEMY, + AITARGET_ALLY, + AITARGET_BUFF, + AITARGET_DEBUFF, +}; + +enum AICondition +{ + AICOND_AGGRO, + AICOND_COMBAT, + AICOND_DIE, +}; + +#define AI_DEFAULT_COOLDOWN 5000 + +struct AISpellInfoType +{ + AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT), cooldown(AI_DEFAULT_COOLDOWN) {} + AITarget target; + AICondition condition; + uint32 cooldown; +}; + +extern AISpellInfoType *AISpellInfo; + #endif diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index 6253c06b8bc..36f49d28521 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -28,11 +28,12 @@ #include "OutdoorPvPObjectiveAI.h" #include "CreatureEventAI.h" #include "RandomMovementGenerator.h" -#include "CreatureAIImpl.h" #include "MovementGeneratorImpl.h" #include "CreatureAIRegistry.h" #include "WaypointMovementGenerator.h" +#include "CreatureAIFactory.h" +#include "CreatureAIImpl.h" namespace AIRegistry { void Initialize() diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index a698d094e18..b270de289c7 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -19,7 +19,6 @@ */ #include "Creature.h" -#include "CreatureAIImpl.h" #include "CreatureAISelector.h" #include "NullCreatureAI.h" #include "Policies/SingletonImp.h" @@ -27,6 +26,7 @@ #include "ScriptCalls.h" #include "Pet.h" #include "TemporarySummon.h" +#include "CreatureAIFactory.h" INSTANTIATE_SINGLETON_1(CreatureAIRegistry); INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry); diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 9332f4b8f0a..131d26e90f7 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -40,6 +40,8 @@ #include "Group.h" #include "InstanceData.h" #include "ProgressBar.h" +#include "Policies/Singleton.h" +#include "Policies/SingletonImp.h" INSTANTIATE_SINGLETON_1( InstanceSaveManager ); diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h index d5c12d8c9a0..f8a5d8480f0 100644 --- a/src/game/NullCreatureAI.h +++ b/src/game/NullCreatureAI.h @@ -22,6 +22,7 @@ #define TRINITY_NULLCREATUREAI_H #include "CreatureAI.h" +#include "CreatureAIImpl.h" class TRINITY_DLL_DECL PassiveAI : public CreatureAI { diff --git a/src/game/PossessedAI.cpp b/src/game/PossessedAI.cpp deleted file mode 100644 index 8fd2e5ca014..00000000000 --- a/src/game/PossessedAI.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2008-2009 Trinity - * - * Thanks to the original authors: MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h deleted file mode 100644 index bef7853246e..00000000000 --- a/src/game/PossessedAI.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2008-2009 Trinity - * - * Thanks to the original authors: MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MANGOS_POSSESSEDAI_H -#define MANGOS_POSSESSEDAI_H - - -#endif diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp new file mode 100644 index 00000000000..4914bd36b7c --- /dev/null +++ b/src/game/UnitAI.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2009 Trinity + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "UnitAI.h" +#include "SpellAuras.h" + +void UnitAI::AttackStart(Unit *victim) +{ + if(!victim) + return; + + if(me->Attack(victim, true)) + { + //DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", me->GetName(), victim->GetGUIDLow()); + me->GetMotionMaster()->MoveChase(victim); + } +} + +void UnitAI::DoMeleeAttackIfReady() +{ + //Make sure our attack is ready and we aren't currently casting before checking distance + if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) + { + //If we are within range melee the target + if (me->IsWithinMeleeRange(me->getVictim())) + { + me->AttackerStateUpdate(me->getVictim()); + me->resetAttackTimer(); + } + } + if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) + { + //If we are within range melee the target + if (me->IsWithinMeleeRange(me->getVictim())) + { + me->AttackerStateUpdate(me->getVictim(), OFF_ATTACK); + me->resetAttackTimer(OFF_ATTACK); + } + } +} + +//Enable PlayerAI when charmed +void PlayerAI::OnCharmed(bool apply) { me->IsAIEnabled = apply; } + +void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) +{ + Creature *charmer = (Creature*)me->GetCharmer(); + + //kill self if charm aura has infinite duration + if(charmer->IsInEvadeMode()) + { + Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM); + for(Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter) + if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent()) + { + charmer->Kill(me); + return; + } + } + + if(!charmer->isInCombat()) + me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + + Unit *target = me->getVictim(); + if(!target || !charmer->canAttack(target)) + AttackStart(charmer->SelectNearestTarget()); +} diff --git a/src/game/UnitAI.h b/src/game/UnitAI.h new file mode 100644 index 00000000000..04de74f480e --- /dev/null +++ b/src/game/UnitAI.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2009 MaNGOS + * + * Copyright (C) 2008-2009 Trinity + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TRINITY_UNITAI_H +#define TRINITY_UNITAI_H + +#include "Platform/Define.h" + +class Unit; +class Player; + +class TRINITY_DLL_SPEC UnitAI +{ + protected: + Unit * const me; + public: + explicit UnitAI(Unit *u) : me(u) {} + virtual void AttackStart(Unit *); + virtual void UpdateAI(const uint32 diff) = 0; + + virtual void InitializeAI() { Reset(); } + + virtual void Reset() {}; + + // Called when unit is charmed + virtual void OnCharmed(bool apply) = 0; + + // Pass parameters between AI + virtual void DoAction(const int32 param) {} + + //Do melee swing of current victim if in rnage and ready and not casting + void DoMeleeAttackIfReady(); +}; + +class TRINITY_DLL_SPEC PlayerAI : public UnitAI +{ + protected: + Player* const me; + public: + explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {} + + void OnCharmed(bool apply); +}; + +class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI +{ + public: + void UpdateAI(const uint32 diff); +}; + +#endif diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index 7cd964ca9a1..002b5e7fb2d 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -1069,14 +1069,6 @@ - - - - @@ -1137,50 +1129,6 @@ RelativePath="..\..\src\game\Creature.h" > - - - - - - - - - - - - - - - - - - - - - - @@ -1229,14 +1177,6 @@ RelativePath="..\..\src\game\GameObject.h" > - - - - @@ -1305,14 +1245,6 @@ RelativePath="..\..\src\game\MovementGenerator.h" > - - - - @@ -1341,14 +1273,6 @@ RelativePath="..\..\src\game\ObjectMgr.h" > - - - - @@ -1357,14 +1281,6 @@ RelativePath="..\..\src\game\Pet.h" > - - - - @@ -1381,14 +1297,6 @@ RelativePath="..\..\src\game\PointMovementGenerator.h" > - - - - @@ -1397,14 +1305,6 @@ RelativePath="..\..\src\game\RandomMovementGenerator.h" > - - - - @@ -1465,14 +1365,6 @@ RelativePath="..\..\src\game\Totem.h" > - - - - @@ -1682,6 +1574,122 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index fcd4f3c3ddd..15fc293a02c 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -1,11 +1,12 @@ @@ -185,7 +183,7 @@ /> @@ -1069,14 +1070,6 @@ - - - - @@ -1137,50 +1130,6 @@ RelativePath="..\..\src\game\Creature.h" > - - - - - - - - - - - - - - - - - - - - - - @@ -1229,14 +1178,6 @@ RelativePath="..\..\src\game\GameObject.h" > - - - - @@ -1305,14 +1246,6 @@ RelativePath="..\..\src\game\MovementGenerator.h" > - - - - @@ -1341,14 +1274,6 @@ RelativePath="..\..\src\game\ObjectMgr.h" > - - - - @@ -1357,14 +1282,6 @@ RelativePath="..\..\src\game\Pet.h" > - - - - @@ -1381,14 +1298,6 @@ RelativePath="..\..\src\game\PointMovementGenerator.h" > - - - - @@ -1397,14 +1306,6 @@ RelativePath="..\..\src\game\RandomMovementGenerator.h" > - - - - @@ -1465,14 +1366,6 @@ RelativePath="..\..\src\game\Totem.h" > - - - - @@ -1682,6 +1575,122 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1695,7 +1704,7 @@ /> Date: Sun, 10 May 2009 22:48:22 -0500 Subject: *Update AI scripts. Use better default AI. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 32 +++++++ src/bindings/scripts/include/sc_creature.h | 27 ++++++ src/game/AggressorAI.cpp | 125 +++++++++++++-------------- src/game/AggressorAI.h | 34 ++++---- src/game/CreatureAI.cpp | 38 +++++++- src/game/CreatureAIRegistry.cpp | 1 + src/game/CreatureAISelector.cpp | 12 +++ src/game/SpellMgr.cpp | 3 + src/game/Unit.cpp | 16 ++-- src/game/UnitAI.cpp | 7 +- 10 files changed, 205 insertions(+), 90 deletions(-) (limited to 'src/bindings/scripts/include') diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 42ee15074ed..e5a6eb958e0 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -55,6 +55,7 @@ void SummonList::DespawnAll() else { erase(begin()); + summon->SetVisibility(VISIBILITY_OFF); summon->setDeathState(JUST_DIED); summon->RemoveCorpse(); } @@ -634,6 +635,37 @@ void Scripted_NoMovementAI::AttackStart(Unit* who) } } +void BossAI::_Reset() +{ + events.Reset(); + summons.DespawnAll(); + instance->SetBossState(bossId, NOT_STARTED); +} + +void BossAI::_JustDied() +{ + events.Reset(); + summons.DespawnAll(); + instance->SetBossState(bossId, DONE); +} + +void BossAI::_EnterCombat() +{ + DoZoneInCombat(); + instance->SetBossState(bossId, IN_PROGRESS); +} + +void BossAI::JustSummoned(Creature *summon) +{ + summons.Summon(summon); + DoZoneInCombat(summon); +} + +void BossAI::SummonedCreatureDespawn(Creature *summon) +{ + summons.Despawn(summon); +} + #define GOBJECT(x) (const_cast(GetGameObjectInfo(x))) void LoadOverridenSQLData() diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 8336df545b6..26bf5fb400b 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -12,6 +12,8 @@ #include "CreatureAI.h" #include "CreatureAIImpl.h" +class ScriptedInstance; + class SummonList : private std::list { public: @@ -216,5 +218,30 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI void UpdateAI(const uint32) {} }; +struct TRINITY_DLL_DECL BossAI : public ScriptedAI +{ + BossAI(Creature *c, uint32 id) : ScriptedAI(c), bossId(id) + , summons(me), instance((ScriptedInstance*)c->GetInstanceData()) + {} + + uint32 bossId; + EventMap events; + SummonList summons; + ScriptedInstance *instance; + + void JustSummoned(Creature *summon); + void SummonedCreatureDespawn(Creature *summon); + + void UpdateAI(const uint32 diff) = 0; + + void _Reset(); + void _EnterCombat(); + void _JustDied(); + + void Reset() { _Reset(); } + void EnterCombat(Unit *who) { _EnterCombat(); } + void JustDied(Unit *killer) { _JustDied(); } +}; + #endif diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index a637e7e40f0..286138fc991 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -19,16 +19,9 @@ */ #include "AggressorAI.h" -#include "Errors.h" -#include "Creature.h" -#include "ObjectAccessor.h" -#include "VMapFactory.h" -#include "World.h" +#include "SpellMgr.h" -#include - -int -AggressorAI::Permissible(const Creature *creature) +int AggressorAI::Permissible(const Creature *creature) { // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight if( !creature->isCivilian() && !creature->IsNeutralToAll() ) @@ -37,79 +30,83 @@ AggressorAI::Permissible(const Creature *creature) return PERMIT_BASE_NO; } -AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK) +void AggressorAI::UpdateAI(const uint32 /*diff*/) { + if(!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); } -void AggressorAI::EnterEvadeMode() +int SpellAI::Permissible(const Creature *creature) { - if( !m_creature->isAlive() ) - { - DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow()); - i_victimGuid = 0; - m_creature->CombatStop(true); - m_creature->DeleteThreatList(); - return; - } + return PERMIT_BASE_NO; +} - Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid ); +void SpellAI::InitializeAI() +{ + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + if(me->m_spells[i] && GetSpellStore()->LookupEntry(me->m_spells[i])) + spells.push_back(me->m_spells[i]); +} - if( !victim ) - { - DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow()); - } - else if( !victim->isAlive() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", m_creature->GetGUIDLow()); - } - else if( victim->HasStealthAura() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow()); - } - else if( victim->isInFlight() ) - { - DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow()); - } - else - { - DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", m_creature->GetGUIDLow()); - //i_state = STATE_LOOK_AT_VICTIM; - //i_tracker.Reset(TIME_INTERVAL_LOOK); - } +void SpellAI::Reset() +{ + events.Reset(); +} - if(!m_creature->GetCharmerOrOwner()) - { - m_creature->RemoveAllAuras(); +void SpellAI::JustDied(Unit *killer) +{ + for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) + if(AISpellInfo[*i].condition == AICOND_DIE) + me->CastSpell(killer, *i, true); +} - // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead - if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE ) - m_creature->GetMotionMaster()->MoveTargetedHome(); +void SpellAI::EnterCombat(Unit *who) +{ + for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) + { + if(AISpellInfo[*i].condition == AICOND_AGGRO) + me->CastSpell(who, *i, true); + else if(AISpellInfo[*i].condition == AICOND_COMBAT) + events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown); } - else if (m_creature->GetOwner() && m_creature->GetOwner()->isAlive()) - m_creature->GetMotionMaster()->MoveFollow(m_creature->GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); - - m_creature->DeleteThreatList(); - i_victimGuid = 0; - m_creature->CombatStop(true); - m_creature->SetLootRecipient(NULL); } -void -AggressorAI::UpdateAI(const uint32 /*diff*/) +void SpellAI::UpdateAI(const uint32 diff) { - // update i_victimGuid if m_creature->getVictim() !=0 and changed if(!UpdateVictim()) return; - i_victimGuid = m_creature->getVictim()->GetGUID(); + events.Update(diff); - if( m_creature->isAttackReady() ) + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + if(uint32 spellId = events.ExecuteEvent()) { - if( m_creature->IsWithinMeleeRange(m_creature->getVictim())) + Unit *target = NULL; + //sLog.outError("aggre %u %u", spellId, (uint32)AISpellInfo[spellId].target); + switch(AISpellInfo[spellId].target) { - m_creature->AttackerStateUpdate(m_creature->getVictim()); - m_creature->resetAttackTimer(); + default: + case AITARGET_SELF: target = me; break; + case AITARGET_VICTIM: target = me->getVictim(); break; + case AITARGET_ENEMY: target = SelectTarget(SELECT_TARGET_RANDOM); break; + case AITARGET_ALLY: target = me; break; + case AITARGET_BUFF: target = me; break; + case AITARGET_DEBUFF: + { + const SpellEntry * spellInfo = GetSpellStore()->LookupEntry(spellId); + bool playerOnly = spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY; + float range = GetSpellMaxRange(spellInfo, false); + target = SelectTarget(SELECT_TARGET_RANDOM, 0, range, playerOnly, -(int32)spellId); + break; + } } + me->CastSpell(target, spellId, false); + events.ScheduleEvent(spellId, AISpellInfo[spellId].cooldown + rand()%AISpellInfo[spellId].cooldown); } + else + DoMeleeAttackIfReady(); } - diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h index 983498716e6..94a6b0b3bf1 100644 --- a/src/game/AggressorAI.h +++ b/src/game/AggressorAI.h @@ -22,31 +22,35 @@ #define TRINITY_AGGRESSORAI_H #include "CreatureAI.h" -#include "Timer.h" +#include "CreatureAIImpl.h" class Creature; class TRINITY_DLL_DECL AggressorAI : public CreatureAI { - enum AggressorState - { - STATE_NORMAL = 1, - STATE_LOOK_AT_VICTIM = 2 - }; - public: - - explicit AggressorAI(Creature *c); - - void EnterEvadeMode(); + explicit AggressorAI(Creature *c) : CreatureAI(c) {} void UpdateAI(const uint32); static int Permissible(const Creature *); +}; + +typedef std::vector SpellVct; +class TRINITY_DLL_DECL SpellAI : public CreatureAI +{ + public: + explicit SpellAI(Creature *c) : CreatureAI(c) {} + + void InitializeAI(); + void Reset(); + void EnterCombat(Unit* who); + void JustDied(Unit *killer); + void UpdateAI(const uint32 diff); + static int Permissible(const Creature *); private: - uint64 i_victimGuid; - AggressorState i_state; - TimeTracker i_tracker; + EventMap events; + SpellVct spells; }; -#endif +#endif diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 011ffab22e5..123fa1182a1 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -21,9 +21,8 @@ #include "CreatureAI.h" #include "CreatureAIImpl.h" #include "Creature.h" -#include "Player.h" -#include "Pet.h" #include "World.h" +#include "SpellMgr.h" //Disable CreatureAI when charmed void CreatureAI::OnCharmed(bool apply) @@ -261,16 +260,47 @@ void CreatureAI::FillAISpellInfo() { AISpellInfo = new AISpellInfoType[GetSpellStore()->GetNumRows()]; + AISpellInfoType *AIInfo = AISpellInfo; const SpellEntry * spellInfo; - for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i) + for(uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i, ++AIInfo) { spellInfo = GetSpellStore()->LookupEntry(i); - if (!spellInfo) + if(!spellInfo) continue; + if(spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD) + AIInfo->condition = AICOND_DIE; + else if(IsPassiveSpell(i) || GetSpellDuration(spellInfo) == -1) + AIInfo->condition = AICOND_AGGRO; + else + AIInfo->condition = AICOND_COMBAT; + + if(AIInfo->cooldown < spellInfo->RecoveryTime) + AIInfo->cooldown = spellInfo->RecoveryTime; + for(uint32 j = 0; j < 3; ++j) { + if(spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY + || spellInfo->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY) + { + if(AIInfo->target < AITARGET_VICTIM) + AIInfo->target = AITARGET_VICTIM; + } + + if(spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA) + { + if(spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY) + { + if(AIInfo->target < AITARGET_DEBUFF) + AIInfo->target = AITARGET_DEBUFF; + } + else if(IsPositiveSpell(i)) + { + if(AIInfo->target < AITARGET_BUFF) + AIInfo->target = AITARGET_BUFF; + } + } } } } diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index fc7130b0913..162ebd9b47c 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -46,6 +46,7 @@ namespace AIRegistry (new CreatureAIFactory("PetAI"))->RegisterSelf(); (new CreatureAIFactory("TotemAI"))->RegisterSelf(); (new CreatureAIFactory("OutdoorPvPObjectiveAI"))->RegisterSelf(); + (new CreatureAIFactory("SpellAI"))->RegisterSelf(); (new CreatureAIFactory("EventAI"))->RegisterSelf(); (new MovementGeneratorFactory >(RANDOM_MOTION_TYPE))->RegisterSelf(); diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index b270de289c7..bac4f3a4973 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -69,6 +69,18 @@ namespace FactorySelector ai_factory = ai_registry.GetRegistryItem("CritterAI"); } + if(!ai_factory) + { + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + { + if(creature->m_spells[i]) + { + ai_factory = ai_registry.GetRegistryItem("SpellAI"); + break; + } + } + } + // select by permit check if(!ai_factory) { diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index a23f32d1a52..9b1cb798849 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -27,6 +27,7 @@ #include "Chat.h" #include "Spell.h" #include "BattleGroundMgr.h" +#include "CreatureAI.h" bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS]; @@ -2520,6 +2521,8 @@ void SpellMgr::LoadSpellCustomAttr() SummonPropertiesEntry *properties = const_cast(sSummonPropertiesStore.LookupEntry(121)); properties->Type = SUMMON_TYPE_TOTEM; + + CreatureAI::FillAISpellInfo(); } void SpellMgr::LoadSpellLinked() diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3f09eec9351..28d2fbd619b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11607,11 +11607,14 @@ void CharmInfo::InitPossessCreateSpells() { for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { - uint32 spellid = ((Creature*)m_unit)->m_spells[i]; - if(IsPassiveSpell(spellid)) - m_unit->CastSpell(m_unit, spellid, true); + uint32 spellId = ((Creature*)m_unit)->m_spells[i]; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(spellInfo && spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD) + spellId = 0; + if(IsPassiveSpell(spellId)) + m_unit->CastSpell(m_unit, spellId, true); else - AddSpellToAB(0, spellid, ACT_DISABLED); + AddSpellToAB(0, spellId, ACT_DISABLED); } } } @@ -11629,6 +11632,10 @@ void CharmInfo::InitCharmCreateSpells() for(uint32 x = 0; x < MAX_SPELL_CHARM; ++x) { uint32 spellId = ((Creature*)m_unit)->m_spells[x]; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(spellInfo && spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_DEAD) + spellId = 0; + m_charmspells[x].spellId = spellId; if(!spellId) @@ -11643,7 +11650,6 @@ void CharmInfo::InitCharmCreateSpells() { ActiveStates newstate; bool onlyselfcast = true; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if(!spellInfo) onlyselfcast = false; for(uint32 i = 0;i<3 && onlyselfcast;++i) //non existent spell will not make any problems as onlyselfcast would be false -> break right away diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp index 4914bd36b7c..c991c75603d 100644 --- a/src/game/UnitAI.cpp +++ b/src/game/UnitAI.cpp @@ -35,8 +35,11 @@ void UnitAI::AttackStart(Unit *victim) void UnitAI::DoMeleeAttackIfReady() { + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + //Make sure our attack is ready and we aren't currently casting before checking distance - if (me->isAttackReady() && !me->hasUnitState(UNIT_STAT_CASTING)) + if (me->isAttackReady()) { //If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) @@ -45,7 +48,7 @@ void UnitAI::DoMeleeAttackIfReady() me->resetAttackTimer(); } } - if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK) && !me->hasUnitState(UNIT_STAT_CASTING)) + if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK)) { //If we are within range melee the target if (me->IsWithinMeleeRange(me->getVictim())) -- cgit v1.2.3 From f9f5d078fda410c0551f1376197094bc4a7bfe08 Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 11 May 2009 03:17:13 -0500 Subject: *Update instance script functions. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.h | 4 +-- src/bindings/scripts/include/sc_instance.h | 13 ------- .../shadow_labyrinth/instance_shadow_labyrinth.cpp | 2 +- .../azjol_nerub/ahnkahet/instance_ahnkahet.cpp | 2 +- .../azjol_nerub/instance_azjol_nerub.cpp | 2 +- .../zone/black_temple/instance_black_temple.cpp | 2 +- .../blackrock_depths/instance_blackrock_depths.cpp | 2 +- .../zone/caverns_of_time/hyjal/instance_hyjal.cpp | 2 +- .../serpent_shrine/instance_serpent_shrine.cpp | 2 +- .../steam_vault/instance_steam_vault.cpp | 2 +- .../zone/gruuls_lair/instance_gruuls_lair.cpp | 2 +- .../scripts/zone/karazhan/instance_karazhan.cpp | 2 +- .../scripts/zone/naxxramas/instance_naxxramas.cpp | 20 +++++++++-- .../shadowfang_keep/instance_shadowfang_keep.cpp | 2 +- .../sunwell_plateau/instance_sunwell_plateau.cpp | 2 +- .../zone/tempest_keep/the_eye/instance_the_eye.cpp | 2 +- .../utgarde_keep/instance_utgarde_keep.cpp | 2 +- .../scripts/zone/zulaman/instance_zulaman.cpp | 2 +- src/game/InstanceData.cpp | 41 ++++++++++++++++++---- src/game/InstanceData.h | 21 +++++------ src/game/InstanceSaveMgr.cpp | 8 ++--- src/game/Map.cpp | 2 +- 22 files changed, 83 insertions(+), 56 deletions(-) (limited to 'src/bindings/scripts/include') diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 26bf5fb400b..444b16e6cdf 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -221,13 +221,13 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI struct TRINITY_DLL_DECL BossAI : public ScriptedAI { BossAI(Creature *c, uint32 id) : ScriptedAI(c), bossId(id) - , summons(me), instance((ScriptedInstance*)c->GetInstanceData()) + , summons(me), instance(c->GetInstanceData()) {} uint32 bossId; EventMap events; SummonList summons; - ScriptedInstance *instance; + InstanceData *instance; void JustSummoned(Creature *summon); void SummonedCreatureDespawn(Creature *summon); diff --git a/src/bindings/scripts/include/sc_instance.h b/src/bindings/scripts/include/sc_instance.h index cdf0e03aa37..0620e89af07 100644 --- a/src/bindings/scripts/include/sc_instance.h +++ b/src/bindings/scripts/include/sc_instance.h @@ -17,20 +17,7 @@ class TRINITY_DLL_DECL ScriptedInstance : public InstanceData { public: - ScriptedInstance(Map *map) : InstanceData(map) {} - ~ScriptedInstance() {} - - //All-purpose data storage 64 bit - virtual uint64 GetData64(uint32 Data) { return 0; } - virtual void SetData64(uint32 Data, uint64 Value) { } - - // Called every instance update - virtual void Update(uint32) {} - - // Save and Load instance data to the database - const char* Save() { return NULL; } - void Load(const char* in) { } }; #endif diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp index 3cfb0af2fa1..37194a89b21 100644 --- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp +++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp @@ -191,7 +191,7 @@ struct TRINITY_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp index 41cb91f86b7..595a05a727f 100644 --- a/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp +++ b/src/bindings/scripts/scripts/zone/azjol_nerub/ahnkahet/instance_ahnkahet.cpp @@ -129,7 +129,7 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; diff --git a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp index bd3fccd98d9..7e0252f2009 100644 --- a/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp +++ b/src/bindings/scripts/scripts/zone/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp @@ -117,7 +117,7 @@ struct TRINITY_DLL_DECL instance_azjol_nerub : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; diff --git a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp index 43646746505..bf5d62a7b86 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp @@ -303,7 +303,7 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp index 6e26f3a0c03..d9f3ecd808a 100644 --- a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp +++ b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp @@ -265,7 +265,7 @@ struct TRINITY_DLL_DECL instance_blackrock_depths : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp index 0dfa99198ac..cdcd6cb6b66 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp @@ -279,7 +279,7 @@ struct TRINITY_DLL_DECL instance_mount_hyjal : public ScriptedInstance }else debug_log("TSCR: Instance Hyjal: UpdateWorldState, but PlayerList is empty!"); } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp index 6c4ae72aec1..8aa759a87c8 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp @@ -236,7 +236,7 @@ struct TRINITY_DLL_DECL instance_serpentshrine_cavern : public ScriptedInstance } return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp index 6d01da7f625..d375d073c35 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp @@ -209,7 +209,7 @@ struct TRINITY_DLL_DECL instance_steam_vault : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp index 34943449b1e..4c90fdf49a8 100644 --- a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp +++ b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp @@ -144,7 +144,7 @@ struct TRINITY_DLL_DECL instance_gruuls_lair : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp index e8dccdd62a4..62ad6fcf42c 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/instance_karazhan.cpp @@ -247,7 +247,7 @@ struct TRINITY_DLL_DECL instance_karazhan : public ScriptedInstance } } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index 4dc189723f3..23f44f5daf8 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -77,9 +77,9 @@ inline uint32 GetEruptionSection(float x, float y) return 3; } -struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance +struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData { - instance_naxxramas(Map *map) : ScriptedInstance(map) + instance_naxxramas(Map *map) : InstanceData(map) , Sapphiron(NULL) { SetBossNumber(MAX_BOSS_NUMBER); @@ -88,12 +88,14 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance std::set HeiganEruption[4]; Creature *Sapphiron; + std::set Worshipper; void OnCreatureCreate(Creature *creature, bool add) { switch(creature->GetEntry()) { case 15989: Sapphiron = add ? creature : NULL; break; + case 16506: if(add) Worshipper.insert(creature); else Worshipper.erase(creature); break; } } @@ -117,6 +119,20 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance AddDoor(go, add); } + void SetBossState(uint32 id, EncounterState state) + { + InstanceData::SetBossState(id, state); + switch(id) + { + case BOSS_FAERLINA: + if(state == NOT_STARTED) + for(std::set::iterator itr = Worshipper.begin(); itr != Worshipper.end(); ++itr) + if(!(*itr)->isAlive()) + (*itr)->Respawn(); + break; + } + } + void SetData(uint32 id, uint32 value) { switch(id) diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp index caf18778abb..30f843badb0 100644 --- a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp +++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp @@ -185,7 +185,7 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { return str_data.c_str(); } diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp index f8bba5acf21..597103b62cf 100644 --- a/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp +++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp @@ -236,7 +236,7 @@ struct TRINITY_DLL_DECL instance_sunwell_plateau : public ScriptedInstance { } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp index 66e595ab729..55ef8c60bbd 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp @@ -129,7 +129,7 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; std::ostringstream stream; diff --git a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp index d6f5828d295..d483006642d 100644 --- a/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp +++ b/src/bindings/scripts/scripts/zone/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp @@ -231,7 +231,7 @@ struct TRINITY_DLL_DECL instance_utgarde_keep : public ScriptedInstance return 0; } - const char* Save() + std::string GetSaveData() { OUT_SAVE_INST_DATA; diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp index 4ebf541515b..8ff01927908 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp @@ -179,7 +179,7 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance instance->SendToPlayers(&data); } - const char* Save() + std::string GetSaveData() { std::ostringstream ss; ss << "S " << BossKilled << " " << ChestLooted << " " << QuestMinute; diff --git a/src/game/InstanceData.cpp b/src/game/InstanceData.cpp index 80e728f7b3c..96c10f7b85c 100644 --- a/src/game/InstanceData.cpp +++ b/src/game/InstanceData.cpp @@ -26,8 +26,9 @@ void InstanceData::SaveToDB() { - if(!Save()) return; - std::string data = Save(); + std::string data = GetSaveData(); + if(data.empty()) + return; CharacterDatabase.escape_string(data); CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId()); } @@ -124,13 +125,41 @@ void InstanceData::SetBossState(uint32 id, EncounterState state) if(id < bosses.size()) { BossInfo *bossInfo = &bosses[id]; - if(bossInfo->state == state) - return; - - bossInfo->state = state; + if(bossInfo->state == TO_BE_DECIDED) // loading + bossInfo->state = state; + else + { + if(bossInfo->state == state) + return; + bossInfo->state = state; + SaveToDB(); + } + for(uint32 type = 0; type < MAX_DOOR_TYPES; ++type) for(DoorSet::iterator i = bossInfo->door[type].begin(); i != bossInfo->door[type].end(); ++i) UpdateDoorState(*i); } } +std::string InstanceData::LoadBossState(const char * data) +{ + if(!data) return NULL; + std::istringstream loadStream(data); + uint32 buff; + uint32 bossId = 0; + for(std::vector::iterator i = bosses.begin(); i != bosses.end(); ++i, ++bossId) + { + loadStream >> buff; + if(buff < TO_BE_DECIDED) + SetBossState(bossId, (EncounterState)buff); + } + return loadStream.str(); +} + +std::string InstanceData::GetBossSaveData() +{ + std::ostringstream saveStream; + for(std::vector::iterator i = bosses.begin(); i != bosses.end(); ++i) + saveStream << (uint32)i->state << " "; + return saveStream.str(); +} diff --git a/src/game/InstanceData.h b/src/game/InstanceData.h index d68cb7ff7f8..91f589384a0 100644 --- a/src/game/InstanceData.h +++ b/src/game/InstanceData.h @@ -37,7 +37,8 @@ enum EncounterState IN_PROGRESS = 1, FAIL = 2, DONE = 3, - SPECIAL = 4 + SPECIAL = 4, + TO_BE_DECIDED = 5, }; typedef std::set DoorSet; @@ -51,7 +52,7 @@ enum DoorType struct BossInfo { - BossInfo() : state(NOT_STARTED) {} + BossInfo() : state(TO_BE_DECIDED) {} EncounterState state; DoorSet door[MAX_DOOR_TYPES]; }; @@ -85,10 +86,10 @@ class TRINITY_DLL_SPEC InstanceData virtual void Initialize() {} //On load - virtual void Load(const char* /*data*/) {} + virtual void Load(const char * data) { LoadBossState(data); } //When save is needed, this function generates the data - virtual const char* Save() { return ""; } + virtual std::string GetSaveData() { return GetBossSaveData(); } void SaveToDB(); @@ -121,7 +122,7 @@ class TRINITY_DLL_SPEC InstanceData //use HandleGameObject(GUID,boolen,NULL); in any other script void HandleGameObject(uint64 GUID, bool open, GameObject *go = NULL); - void SetBossState(uint32 id, EncounterState state); + virtual void SetBossState(uint32 id, EncounterState state); protected: void LoadDoorData(const DoorData *data); @@ -129,14 +130,8 @@ class TRINITY_DLL_SPEC InstanceData void AddDoor(GameObject *door, bool add); void UpdateDoorState(GameObject *door); - std::string GetBossSave() - { - std::ostringstream saveStream; - for(std::vector::iterator i = bosses.begin(); i != bosses.end(); ++i) - saveStream << (uint32)i->state << " "; - return saveStream.str(); - } - + std::string LoadBossState(const char * data); + std::string GetBossSaveData(); private: std::vector bosses; DoorInfoMap doors; diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 131d26e90f7..7e2ad67c518 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -165,11 +165,11 @@ void InstanceSave::SaveToDB() if(map) { assert(map->IsDungeon()); - InstanceData *iData = ((InstanceMap *)map)->GetInstanceData(); - if(iData && iData->Save()) + if(InstanceData *iData = ((InstanceMap*)map)->GetInstanceData()) { - data = iData->Save(); - CharacterDatabase.escape_string(data); + data = iData->GetSaveData(); + if(!data.empty()) + CharacterDatabase.escape_string(data); } } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 3884f39f5a4..3280970750b 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -2503,7 +2503,7 @@ void InstanceMap::CreateInstanceData(bool load) { Field* fields = result->Fetch(); const char* data = fields[0].GetString(); - if(data) + if(data && data != "") { sLog.outDebug("Loading instance data for `%s` with id %u", objmgr.GetScriptName(i_script_id), i_InstanceId); i_data->Load(data); -- cgit v1.2.3 From f631b2a2d69775b818814f6c2ee0bc3daa3d616b Mon Sep 17 00:00:00 2001 From: megamage Date: Mon, 11 May 2009 11:46:48 -0500 Subject: *Update creature AI functions. --HG-- branch : trunk --- src/bindings/scripts/include/precompiled.h | 3 ++- src/bindings/scripts/include/sc_creature.cpp | 26 +++++----------------- src/bindings/scripts/include/sc_creature.h | 20 ----------------- .../scripts/zone/black_temple/boss_supremus.cpp | 4 +++- src/game/AggressorAI.h | 2 +- src/game/CreatureAI.cpp | 2 ++ src/game/CreatureAI.h | 2 +- src/game/NullCreatureAI.h | 18 ++++++++++----- src/game/TemporarySummon.h | 2 +- 9 files changed, 27 insertions(+), 52 deletions(-) (limited to 'src/bindings/scripts/include') diff --git a/src/bindings/scripts/include/precompiled.h b/src/bindings/scripts/include/precompiled.h index 2c36cc924e0..fa676f460ef 100644 --- a/src/bindings/scripts/include/precompiled.h +++ b/src/bindings/scripts/include/precompiled.h @@ -12,10 +12,11 @@ #include "GridNotifiersImpl.h" #include "Unit.h" #include "GameObject.h" -#include "TemporarySummon.h" #include "sc_creature.h" #include "sc_gossip.h" #include "sc_instance.h" +#include "AggressorAI.h" +#include "NullCreatureAI.h" #ifdef WIN32 #include diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index e5a6eb958e0..0b874773ffc 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -9,6 +9,7 @@ #include "Item.h" #include "Spell.h" #include "ObjectMgr.h" +#include "TemporarySummon.h" // Spell summary for ScriptedAI::SelectSpell struct TSpellSummary { @@ -56,7 +57,10 @@ void SummonList::DespawnAll() { erase(begin()); summon->SetVisibility(VISIBILITY_OFF); - summon->setDeathState(JUST_DIED); + if(summon->HasSummonMask(SUMMON_MASK_SUMMON) && !summon->isPet()) + ((TempSummon*)summon)->UnSummon(); + else + summon->setDeathState(JUST_DIED); summon->RemoveCorpse(); } } @@ -109,26 +113,6 @@ void ScriptedAI::UpdateAI(const uint32 diff) } } -void ScriptedAI::EnterEvadeMode() -{ - //m_creature->InterruptNonMeleeSpells(true); - m_creature->RemoveAllAuras(); - m_creature->DeleteThreatList(); - m_creature->CombatStop(); - m_creature->LoadCreaturesAddon(); - m_creature->SetLootRecipient(NULL); - - if(m_creature->isAlive()) - m_creature->GetMotionMaster()->MoveTargetedHome(); - - Reset(); -} - -void ScriptedAI::JustRespawned() -{ - Reset(); -} - void ScriptedAI::DoStartMovement(Unit* victim, float distance, float angle) { if (!victim) diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 444b16e6cdf..0fb716bbe0e 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -58,9 +58,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void AttackStart(Unit *); void AttackStart(Unit *, bool melee); - //Called at stoping attack by any attacker - void EnterEvadeMode(); - // Called at any Damage from any attacker (before damage apply) void DamageTaken(Unit *done_by, uint32 &damage) {} @@ -85,9 +82,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI // Called when spell hits a target void SpellHitTarget(Unit* target, const SpellEntry*) {} - // Called when creature is spawned or respawned (for reseting variables) - void JustRespawned(); - //Called at waypoint reached or PointMovement end void MovementInform(uint32 type, uint32 id){} @@ -204,20 +198,6 @@ struct TRINITY_DLL_DECL Scripted_NoMovementAI : public ScriptedAI void AttackStart(Unit *); }; -struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI -{ - NullCreatureAI(Creature* c) : ScriptedAI(c) {} - ~NullCreatureAI() {} - - void Reset() {} - void EnterCombat(Unit*) {} - void MoveInLineOfSight(Unit *) {} - void AttackStart(Unit *) {} - void EnterEvadeMode() {} - - void UpdateAI(const uint32) {} -}; - struct TRINITY_DLL_DECL BossAI : public ScriptedAI { BossAI(Creature *c, uint32 id) : ScriptedAI(c), bossId(id) diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp index fdfdef396bb..ff90f7e6a81 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp @@ -53,7 +53,9 @@ EndScriptData */ struct TRINITY_DLL_DECL molten_flameAI : public NullCreatureAI { - molten_flameAI(Creature *c) : NullCreatureAI(c) + molten_flameAI(Creature *c) : NullCreatureAI(c) {} + + void InitializeAI() { float x, y, z; me->GetNearPoint(me, x, y, z, 1, 50, M_PI*2*rand_norm()); diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h index 94a6b0b3bf1..2c43ccf82b7 100644 --- a/src/game/AggressorAI.h +++ b/src/game/AggressorAI.h @@ -37,7 +37,7 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI typedef std::vector SpellVct; -class TRINITY_DLL_DECL SpellAI : public CreatureAI +class TRINITY_DLL_SPEC SpellAI : public CreatureAI { public: explicit SpellAI(Creature *c) : CreatureAI(c) {} diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 123fa1182a1..8633ee2e1f4 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -112,6 +112,8 @@ void CreatureAI::EnterEvadeMode() if(me->isAlive()) me->GetMotionMaster()->MoveTargetedHome(); + + Reset(); } inline bool SelectTargetHelper(const Unit * me, const Unit * target, const bool &playerOnly, const float &dist, const int32 &aura) diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index ca13275dea1..6b031005463 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -123,7 +123,7 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI //virtual void AttackedBy(Unit* attacker); // Called when creature is spawned or respawned (for reseting variables) - virtual void JustRespawned() {} + virtual void JustRespawned() { Reset(); } // Called at waypoint reached or point movement finished virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {} diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h index f8a5d8480f0..347f52228b4 100644 --- a/src/game/NullCreatureAI.h +++ b/src/game/NullCreatureAI.h @@ -28,35 +28,41 @@ class TRINITY_DLL_DECL PassiveAI : public CreatureAI { public: explicit PassiveAI(Creature *c) : CreatureAI(c) {} - ~PassiveAI() {} void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *) {} - void UpdateAI(const uint32); + static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; -class TRINITY_DLL_DECL PossessedAI : public PassiveAI +class TRINITY_DLL_DECL PossessedAI : public CreatureAI { public: - explicit PossessedAI(Creature *c) : PassiveAI(c) {} + explicit PossessedAI(Creature *c) : CreatureAI(c) {} + void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *target); void UpdateAI(const uint32); void EnterEvadeMode() {} void JustDied(Unit*); void KilledUnit(Unit* victim); + + static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; -class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI +class TRINITY_DLL_DECL NullCreatureAI : public CreatureAI { public: - explicit NullCreatureAI(Creature *c) : PassiveAI(c) {} + explicit NullCreatureAI(Creature *c) : CreatureAI(c) {} + void MoveInLineOfSight(Unit *) {} + void AttackStart(Unit *) {} void UpdateAI(const uint32) {} void EnterEvadeMode() {} + + static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; } }; class TRINITY_DLL_DECL CritterAI : public PassiveAI diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h index 09e7f22afb0..e089c77c96e 100644 --- a/src/game/TemporarySummon.h +++ b/src/game/TemporarySummon.h @@ -23,7 +23,7 @@ #include "Creature.h" -class TempSummon : public Creature +class TRINITY_DLL_SPEC TempSummon : public Creature { public: explicit TempSummon(SummonPropertiesEntry const *properties, Unit *owner); -- cgit v1.2.3 From 8994cbe08188b483c8c85a23d456003816157cad Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 13 May 2009 10:54:11 -0500 Subject: *Update some script functions. --HG-- branch : trunk --- src/bindings/scripts/include/sc_creature.cpp | 79 +++++++++++++++++++++------- src/bindings/scripts/include/sc_creature.h | 4 ++ src/game/AggressorAI.cpp | 2 +- src/game/CreatureAI.cpp | 55 +++++++++++-------- src/game/CreatureAI.h | 3 ++ 5 files changed, 101 insertions(+), 42 deletions(-) (limited to 'src/bindings/scripts/include') 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(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 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 -- cgit v1.2.3