diff --git a/sql/scriptdev2/scriptdev2.sql b/sql/scriptdev2/scriptdev2.sql index 541d4a41a9..cc2b93be97 100644 --- a/sql/scriptdev2/scriptdev2.sql +++ b/sql/scriptdev2/scriptdev2.sql @@ -778,6 +778,7 @@ UPDATE creature_template SET ScriptName='boss_krosh_firehand' WHERE entry=18832; UPDATE creature_template SET ScriptName='boss_broggok' WHERE entry=17380; UPDATE creature_template SET ScriptName='boss_kelidan_the_breaker' WHERE entry=17377; UPDATE creature_template SET ScriptName='mob_shadowmoon_channeler' WHERE entry=17653; +UPDATE creature_template SET ScriptName='npc_fel_orc' WHERE entry IN (17398, 17429); UPDATE gameobject_template SET ScriptName='go_prison_cell_lever' WHERE entry=181982; UPDATE instance_template SET ScriptName='instance_blood_furnace' WHERE map=542; diff --git a/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.cpp b/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.cpp index 9dec487898..b5c00b7afd 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.cpp +++ b/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.cpp @@ -26,10 +26,11 @@ EndScriptData */ instance_blood_furnace::instance_blood_furnace(Map* map) : ScriptedInstance(map), m_uiBroggokEventTimer(90 * IN_MILLISECONDS), + m_uiBroggokEventDelay(0), m_uiBroggokEventPhase(0), m_uiRandYellTimer(90000), m_crackTimer(30000), - m_firstPlayer(false) + m_uiBroggokEventDelaySpawn(false) { Initialize(); } @@ -50,16 +51,30 @@ void instance_blood_furnace::OnCreatureCreate(Creature* creature) case NPC_IN_COMBAT_TRIGGER: m_npcEntryGuidStore[creature->GetEntry()] = creature->GetObjectGuid(); break; - case NPC_NASCENT_FEL_ORC: - case NPC_FEL_ORC_NEOPHYTE: - m_luiNascentOrcGuids.push_back(creature->GetObjectGuid()); - break; case NPC_SHADOWMOON_CHANNELER: m_lChannelersGuids.push_back(creature->GetObjectGuid()); break; } } +void instance_blood_furnace::OnCreatureRespawn(Creature* creature) +{ + switch (creature->GetEntry()) + { + case NPC_NASCENT_FEL_ORC: + case NPC_FEL_ORC_NEOPHYTE: + if (creature->HasStringId(FIRST_BROGGOK_CELL_STRING) || creature->HasStringId(SECOND_BROGGOK_CELL_STRING) || creature->HasStringId(THIRD_BROGGOK_CELL_STRING) || creature->HasStringId(FOURTH_BROGGOK_CELL_STRING)) + { + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); // ones in cages + creature->setFaction(14); // sniffed value + m_broggokEventGuids.push_back(creature->GetDbGuid()); + } + else if (creature->HasStringId(FIFTH_BROGGOK_CELL_STRING)) + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE | UNIT_FLAG_IMMUNE_TO_NPC); + break; + } +} + void instance_blood_furnace::OnObjectCreate(GameObject* go) { switch (go->GetEntry()) @@ -117,6 +132,30 @@ void instance_blood_furnace::OnObjectCreate(GameObject* go) m_goEntryGuidStore[go->GetEntry()] = go->GetObjectGuid(); } +void instance_blood_furnace::OnCreatureGroupDespawn(CreatureGroup* pGroup, Creature* /*pCreature*/) +{ + switch (pGroup->GetGroupId()) + { + // Only release next group if not already released from timer + case SPAWN_GROUP_PRISON_CELL_1: + if (m_uiBroggokEventPhase == SECOND_ORC_WAVE) + DoNextBroggokEventPhase(); + break; + case SPAWN_GROUP_PRISON_CELL_2: + if (m_uiBroggokEventPhase == THIRD_ORC_WAVE) + DoNextBroggokEventPhase(); + break; + case SPAWN_GROUP_PRISON_CELL_3: + if (m_uiBroggokEventPhase == FOURTH_ORC_WAVE) + DoNextBroggokEventPhase(); + break; + case SPAWN_GROUP_PRISON_CELL_4: + if (m_uiBroggokEventPhase == MAX_ORC_WAVES) + DoNextBroggokEventPhase(); + break; + } +} + void instance_blood_furnace::SetData(uint32 type, uint32 data) { switch (type) @@ -150,46 +189,37 @@ void instance_blood_furnace::SetData(uint32 type, uint32 data) if (m_uiBroggokEventPhase <= MAX_ORC_WAVES) { m_uiBroggokEventPhase = 0; - - if (m_aBroggokEvent[0].m_sSortedOrcGuids.empty()) - DoSortBroggokOrcs(); // open first cage DoNextBroggokEventPhase(); + + // Confirmed on Sniffs that lever gets uninteractable while even is in progress + m_lLeverGO->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT, true); } } else if (data == FAIL) { // On wipe we reset only the orcs; if the party wipes at the boss itself then the orcs don't reset if (m_uiBroggokEventPhase <= MAX_ORC_WAVES) - { + { + // Respawn all Groups + RespawnDbGuids(m_broggokEventGuids, 0); + m_broggokEventGuids.clear(); + + // Close all Cells for (auto& i : m_aBroggokEvent) { - // Reset Orcs if (!i.m_bIsCellOpened) continue; - i.m_uiKilledOrcCount = 0; - for (GuidSet::const_iterator itr = i.m_sSortedOrcGuids.begin(); itr != i.m_sSortedOrcGuids.end(); ++itr) - { - if (Creature* pOrc = instance->GetCreature(*itr)) - { - pOrc->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); - - if (pOrc->IsAlive()) - pOrc->ForcedDespawn(); - - pOrc->Respawn(); - } - } - // Close Door DoUseDoorOrButton(i.m_cellGuid); i.m_bIsCellOpened = false; } - + if (m_lLeverGO) { + m_lLeverGO->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); m_lLeverGO->SetRespawnTime(time(nullptr)); m_lLeverGO->Respawn(); } @@ -227,33 +257,6 @@ void instance_blood_furnace::SetData(uint32 type, uint32 data) } } -void instance_blood_furnace::OnPlayerEnter(Player* /*player*/) -{ - if (!m_firstPlayer) - { - m_firstPlayer = true; - for (GuidList::const_iterator itr = m_luiNascentOrcGuids.begin(); itr != m_luiNascentOrcGuids.end(); ++itr) - { - if (Creature* pOrc = instance->GetCreature(*itr)) - { - for (uint8 i = 0; i < MAX_ORC_WAVES; ++i) - { - if (GameObject* pDoor = instance->GetGameObject(m_aBroggokEvent[i].m_cellGuid)) - { - if (pOrc->IsWithinDistInMap(pDoor, 15.0f) && pOrc->GetPositionZ() < 15.0f) - { - pOrc->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); // ones in cages - pOrc->setFaction(14); // sniffed value - } - } - } - if (pOrc->GetPositionZ() > 20.0f) // ones above - pOrc->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE | UNIT_FLAG_IMMUNE_TO_NPC); - } - } - } -} - void instance_blood_furnace::DoNextBroggokEventPhase() { // Open door to the final boss now and move boss to the center of the room @@ -277,86 +280,91 @@ void instance_blood_furnace::DoNextBroggokEventPhase() m_aBroggokEvent[m_uiBroggokEventPhase].m_bIsCellOpened = true; - // TODO: add small delay - after gate opened - for (auto m_sSortedOrcGuid : m_aBroggokEvent[m_uiBroggokEventPhase].m_sSortedOrcGuids) + // First Wave spawns instantly + if (m_uiBroggokEventPhase == FIRST_ORC_WAVE) { - if (Creature* pOrc = instance->GetCreature(m_sSortedOrcGuid)) + auto pOrc = instance->GetCreatures(FIRST_BROGGOK_CELL_STRING); + for (Creature* creature : *pOrc) { - pOrc->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); - pOrc->SetInCombatWithZone(); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); + creature->SetInCombatWithZone(); } + ++m_uiBroggokEventPhase; } - } - - // Prepare for further handling - m_uiBroggokEventTimer = 90 * IN_MILLISECONDS; - ++m_uiBroggokEventPhase; -} - -void instance_blood_furnace::OnCreatureEvade(Creature* creature) -{ - if (m_auiEncounter[TYPE_BROGGOK_EVENT] == FAIL) - return; - - if (creature->GetEntry() == NPC_BROGGOK) - SetData(TYPE_BROGGOK_EVENT, FAIL); - - else if (creature->GetEntry() == NPC_NASCENT_FEL_ORC || creature->GetEntry() == NPC_FEL_ORC_NEOPHYTE) - { - for (uint8 i = 0; i < std::min(m_uiBroggokEventPhase, MAX_ORC_WAVES); ++i) + else { - if (m_aBroggokEvent[i].m_sSortedOrcGuids.find(creature->GetObjectGuid()) != m_aBroggokEvent[i].m_sSortedOrcGuids.end()) - SetData(TYPE_BROGGOK_EVENT, FAIL); + // All other waves have a 2 second delay after cell openes + m_uiBroggokEventDelay = 2000; + m_uiBroggokEventDelaySpawn = true; } + + // Always reset Timer if a cell already got opened because the previous group died + m_uiBroggokEventTimer = 90000; } } -void instance_blood_furnace::OnCreatureDeath(Creature* creature) +void instance_blood_furnace::Update(uint32 uiDiff) { - if (m_auiEncounter[TYPE_BROGGOK_EVENT] != IN_PROGRESS) - return; - - if (creature->GetEntry() == NPC_NASCENT_FEL_ORC || creature->GetEntry() == NPC_FEL_ORC_NEOPHYTE) + if (m_auiEncounter[TYPE_BROGGOK_EVENT] == IN_PROGRESS) { - uint8 uiClearedCells = 0; - for (uint8 i = 0; i < std::min(m_uiBroggokEventPhase, MAX_ORC_WAVES); ++i) + // 2nd, 3rd and 4th Orc wave will attack 2 seconds after cell opened + if (m_uiBroggokEventDelaySpawn) { - if (m_aBroggokEvent[i].m_sSortedOrcGuids.size() == m_aBroggokEvent[i].m_uiKilledOrcCount) + if (m_uiBroggokEventDelay < uiDiff) { - ++uiClearedCells; - continue; + if (m_uiBroggokEventPhase == SECOND_ORC_WAVE) + { + auto pOrc = instance->GetCreatures(SECOND_BROGGOK_CELL_STRING); + for (Creature* creature : *pOrc) + { + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); + creature->SetInCombatWithZone(); + } + ++m_uiBroggokEventPhase; + m_uiBroggokEventDelaySpawn = false; + m_uiBroggokEventDelay = 2000; + } + else if (m_uiBroggokEventPhase == THIRD_ORC_WAVE) + { + auto pOrc = instance->GetCreatures(THIRD_BROGGOK_CELL_STRING); + for (Creature* creature : *pOrc) + { + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); + creature->SetInCombatWithZone(); + } + ++m_uiBroggokEventPhase; + m_uiBroggokEventDelaySpawn = false; + m_uiBroggokEventDelay = 2000; + } + else if (m_uiBroggokEventPhase == FOURTH_ORC_WAVE) + { + auto pOrc = instance->GetCreatures(FOURTH_BROGGOK_CELL_STRING); + for (Creature* creature : *pOrc) + { + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNINTERACTIBLE); + creature->SetInCombatWithZone(); + } + ++m_uiBroggokEventPhase; + m_uiBroggokEventDelaySpawn = false; + m_uiBroggokEventDelay = 2000; + } } - - // Increase kill counter, if we found a mob of this cell - if (m_aBroggokEvent[i].m_sSortedOrcGuids.find(creature->GetObjectGuid()) != m_aBroggokEvent[i].m_sSortedOrcGuids.end()) - m_aBroggokEvent[i].m_uiKilledOrcCount++; - - if (m_aBroggokEvent[i].m_sSortedOrcGuids.size() == m_aBroggokEvent[i].m_uiKilledOrcCount) - ++uiClearedCells; + else + m_uiBroggokEventDelay -= uiDiff; } - // Increase phase when all opened cells are cleared - if (uiClearedCells == m_uiBroggokEventPhase) - DoNextBroggokEventPhase(); - } -} - -void instance_blood_furnace::Update(uint32 uiDiff) -{ - // Broggok Event: For the last wave we don't check the timer; the boss is released only when all mobs die - if (m_auiEncounter[TYPE_BROGGOK_EVENT] == IN_PROGRESS) + // Broggok Event: For the last wave we don't check the timer; the boss is released only when all mobs die if (m_uiBroggokEventPhase <= MAX_ORC_WAVES) { - if (!GetPlayerInMap(true, false)) - SetData(TYPE_BROGGOK_EVENT, FAIL); - else if (!instance->IsRegularDifficulty()) - { - if (m_uiBroggokEventTimer < uiDiff) - DoNextBroggokEventPhase(); - else - m_uiBroggokEventTimer -= uiDiff; - } + // on wotlk ptr normal and heroic both used 90 seconds timer + if (m_uiBroggokEventTimer < uiDiff) + DoNextBroggokEventPhase(); + else + m_uiBroggokEventTimer -= uiDiff; + } + } + if (m_uiRandYellTimer < uiDiff) { @@ -440,31 +448,6 @@ void instance_blood_furnace::ExecuteChatCommand(ChatHandler* handler, char* args } } -// Sort all nascent orcs & fel orc neophytes in the instance in order to get only those near broggok doors -void instance_blood_furnace::DoSortBroggokOrcs() -{ - for (GuidList::const_iterator itr = m_luiNascentOrcGuids.begin(); itr != m_luiNascentOrcGuids.end(); ++itr) - { - if (Creature* pOrc = instance->GetCreature(*itr)) - { - for (auto& i : m_aBroggokEvent) - { - if (GameObject* pDoor = instance->GetGameObject(i.m_cellGuid)) - { - Position orcPos = pOrc->GetRespawnPosition(); - if (pDoor->IsWithinDist3d(orcPos.x, orcPos.y, orcPos.z, 16.0f) && orcPos.GetPositionZ() < 15.0f) - { - i.m_sSortedOrcGuids.insert(pOrc->GetObjectGuid()); - if (!pOrc->IsAlive()) - pOrc->Respawn(); - break; - } - } - } - } - } -} - bool GOUse_go_prison_cell_lever(Player* /*player*/, GameObject* go) { ScriptedInstance* pInstance = static_cast(go->GetInstanceData()); diff --git a/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h b/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h index fef605aead..f1368c2127 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h +++ b/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h @@ -8,6 +8,10 @@ enum { MAX_ENCOUNTER = 3, + FIRST_ORC_WAVE = 0, + SECOND_ORC_WAVE = 1, + THIRD_ORC_WAVE = 2, + FOURTH_ORC_WAVE = 3, MAX_ORC_WAVES = 4, TYPE_THE_MAKER_EVENT = 0, @@ -54,19 +58,29 @@ enum NPC_IN_COMBAT_TRIGGER = 16006, SAY_BROGGOK_INTRO = 15115, + + // Prison Cell SpawnGroups + SPAWN_GROUP_PRISON_CELL_1 = 5420044, // Back Left + SPAWN_GROUP_PRISON_CELL_2 = 5420045, // Back Right + SPAWN_GROUP_PRISON_CELL_3 = 5420042, // Front Left + SPAWN_GROUP_PRISON_CELL_4 = 5420043, // Front Right }; +const std::string FIRST_BROGGOK_CELL_STRING = "BF_PRISON_CELL_GROUP_01"; +const std::string SECOND_BROGGOK_CELL_STRING = "BF_PRISON_CELL_GROUP_02"; +const std::string THIRD_BROGGOK_CELL_STRING = "BF_PRISON_CELL_GROUP_03"; +const std::string FOURTH_BROGGOK_CELL_STRING = "BF_PRISON_CELL_GROUP_04"; +const std::string FIFTH_BROGGOK_CELL_STRING = "BF_PRISON_CELL_GROUP_05"; + // Random Magtheridon taunt static const int32 aRandomTaunt[] = { -1544000, -1544001, -1544002, -1544003, -1544004, -1544005}; struct BroggokEventInfo { - BroggokEventInfo() : m_bIsCellOpened(false), m_uiKilledOrcCount(0) {} + BroggokEventInfo() : m_bIsCellOpened(false) {} ObjectGuid m_cellGuid; bool m_bIsCellOpened; - uint8 m_uiKilledOrcCount; - GuidSet m_sSortedOrcGuids; }; class instance_blood_furnace : public ScriptedInstance @@ -76,13 +90,12 @@ class instance_blood_furnace : public ScriptedInstance void Initialize() override; - void OnPlayerEnter(Player* player) override; - void OnCreatureCreate(Creature* creature) override; void OnObjectCreate(GameObject* go) override; - void OnCreatureDeath(Creature* creature) override; - void OnCreatureEvade(Creature* creature) override; + void OnCreatureRespawn(Creature* creature) override; + + void OnCreatureGroupDespawn(CreatureGroup* pGroup, Creature* pCreature) override; void SetData(uint32 type, uint32 data) override; uint32 GetData(uint32 type) const override; @@ -98,7 +111,6 @@ class instance_blood_furnace : public ScriptedInstance void ExecuteChatCommand(ChatHandler* handler, char* args) override; private: - void DoSortBroggokOrcs(); void DoNextBroggokEventPhase(); uint32 m_auiEncounter[MAX_ENCOUNTER]; @@ -106,18 +118,21 @@ class instance_blood_furnace : public ScriptedInstance BroggokEventInfo m_aBroggokEvent[MAX_ORC_WAVES]; - uint32 m_uiBroggokEventTimer; // Timer for opening the event cages; 90s on normal, 30s on heroic difficulty + uint32 m_uiBroggokEventTimer; // Timer for opening the event cages; 90s on normal and heroic uint32 m_uiBroggokEventPhase; uint32 m_uiRandYellTimer; // Random yell for Magtheridon uint32 m_crackTimer; + uint32 m_uiBroggokEventDelay; + bool m_uiBroggokEventDelaySpawn; + std::vector m_broggokEventGuids; + + CreatureGroup* m_cellGroup; GameObject* m_lLeverGO; GuidList m_cracks; GuidList m_luiNascentOrcGuids; GuidList m_lChannelersGuids; - - bool m_firstPlayer; }; #endif diff --git a/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp b/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp index 23bce9f3c5..82351ecadb 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp +++ b/src/game/AI/ScriptDevAI/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp @@ -29,6 +29,8 @@ enum { SAY_AGGRO = 14259, + SAY_FEL_ORC_AGGRO = 11999, + SPELL_SUMMON_INCOMBAT_TRIGGER = 26837, // TODO: probably cast on spawn not sure what c.16006 does SPELL_SLIME_SPRAY = 30913, SPELL_SLIME_SPRAY_H = 38458, @@ -48,21 +50,13 @@ enum enum BroggokActions { - BROGGOK_SLIME_SPRAY, - BROGGOK_POISON_BOLT, - BROGGOK_POISON_CLOUD, BROGGOK_ACTION_MAX, }; struct boss_broggokAI : public CombatAI { boss_broggokAI(Creature* creature) : CombatAI(creature, BROGGOK_ACTION_MAX), m_instance(static_cast(creature->GetInstanceData())), - m_isRegularMode(creature->GetMap()->IsRegularDifficulty()) - { - AddCombatAction(BROGGOK_SLIME_SPRAY, 10000u); - AddCombatAction(BROGGOK_POISON_BOLT, 12000u); - AddCombatAction(BROGGOK_POISON_CLOUD, 10000u); - } + m_isRegularMode(creature->GetMap()->IsRegularDifficulty()){} ScriptedInstance* m_instance; bool m_isRegularMode; @@ -73,6 +67,12 @@ struct boss_broggokAI : public CombatAI m_instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS); } + void EnterEvadeMode() override + { + if (m_instance) + m_instance->SetData(TYPE_BROGGOK_EVENT, FAIL); + } + void JustSummoned(Creature* summoned) override { if (summoned->GetEntry() == NPC_IN_COMBAT_TRIGGER) @@ -113,24 +113,32 @@ struct boss_broggokAI : public CombatAI AttackClosestEnemy(); } } +}; + +enum FelOrcAction +{ + FEL_ORC_ACTION_MAX, +}; - void ExecuteAction(uint32 action) override +struct npc_fel_orc : public CombatAI +{ + npc_fel_orc(Creature* creature) : CombatAI(creature, FEL_ORC_ACTION_MAX), m_instance(static_cast(creature->GetInstanceData())) {} + + ScriptedInstance* m_instance; + + void Aggro(Unit* /*who*/) override { - switch (action) - { - case BROGGOK_SLIME_SPRAY: - if (DoCastSpellIfCan(m_creature, m_isRegularMode ? SPELL_SLIME_SPRAY : SPELL_SLIME_SPRAY_H) == CAST_OK) - ResetCombatAction(action, urand(4000, 12000)); - break; - case BROGGOK_POISON_BOLT: - if (DoCastSpellIfCan(m_creature, m_isRegularMode ? SPELL_POISON_BOLT : SPELL_POISON_BOLT_H) == CAST_OK) - ResetCombatAction(action, urand(4000, 12000)); - break; - case BROGGOK_POISON_CLOUD: - if (DoCastSpellIfCan(m_creature, SPELL_POISON_CLOUD) == CAST_OK) - ResetCombatAction(action, 20000); - break; - } + if (urand(0, 4) > 2) + DoBroadcastText(SAY_FEL_ORC_AGGRO, m_creature); + } + + void JustReachedHome() override + { + CombatAI::JustReachedHome(); + // Only Event Envolved NPCs should trigger fail condition + if (m_creature->HasStringId(FIRST_BROGGOK_CELL_STRING) || m_creature->HasStringId(SECOND_BROGGOK_CELL_STRING) || m_creature->HasStringId(THIRD_BROGGOK_CELL_STRING) || m_creature->HasStringId(FOURTH_BROGGOK_CELL_STRING)) + if (m_instance->GetData(TYPE_BROGGOK_EVENT == IN_PROGRESS)) + m_instance->SetData(TYPE_BROGGOK_EVENT, FAIL); } }; @@ -140,4 +148,9 @@ void AddSC_boss_broggok() pNewScript->Name = "boss_broggok"; pNewScript->GetAI = &GetNewAIInstance; pNewScript->RegisterSelf(); + + pNewScript = new Script; + pNewScript->Name = "npc_fel_orc"; + pNewScript->GetAI = &GetNewAIInstance; + pNewScript->RegisterSelf(); }