diff options
author | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-01-07 16:39:01 +0100 |
---|---|---|
committer | Vincent_Michael <Vincent_Michael@gmx.de> | 2013-01-07 16:39:01 +0100 |
commit | ecedb798aa3094f02bedaadf459cfec7cb7c58a4 (patch) | |
tree | 1666ff41bed0084e13094ac53c1b2334a22bec3f /src | |
parent | d5163d846fcbbd94655f0ba93c81a3e2bd302b3c (diff) | |
parent | d0e4e202658206aa40e656101334b446ebc9f18e (diff) |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts:
src/server/game/Conditions/ConditionMgr.h
Diffstat (limited to 'src')
18 files changed, 832 insertions, 518 deletions
diff --git a/src/server/collision/Management/VMapFactory.cpp b/src/server/collision/Management/VMapFactory.cpp index 428ef320f5d..4d3719cf288 100644 --- a/src/server/collision/Management/VMapFactory.cpp +++ b/src/server/collision/Management/VMapFactory.cpp @@ -16,99 +16,12 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <sys/types.h> #include "VMapFactory.h" #include "VMapManager2.h" -#include "G3D/Table.h" - -using namespace G3D; namespace VMAP { - void chompAndTrim(std::string& str) - { - while (str.length() >0) - { - char lc = str[str.length()-1]; - if (lc == '\r' || lc == '\n' || lc == ' ' || lc == '"' || lc == '\'') - { - str = str.substr(0, str.length()-1); - } - else - { - break; - } - } - while (str.length() >0) - { - char lc = str[0]; - if (lc == ' ' || lc == '"' || lc == '\'') - { - str = str.substr(1, str.length()-1); - } - else - { - break; - } - } - } - - IVMapManager* gVMapManager = 0; - Table<unsigned int, bool>* iIgnoreSpellIds=0; - - //=============================================== - // result false, if no more id are found - - bool getNextId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId) - { - bool result = false; - unsigned int i; - for (i=pStartPos;i<pString.size(); ++i) - { - if (pString[i] == ',') - { - break; - } - } - if (i>pStartPos) - { - std::string idString = pString.substr(pStartPos, i-pStartPos); - pStartPos = i+1; - chompAndTrim(idString); - pId = atoi(idString.c_str()); - result = true; - } - return(result); - } - - //=============================================== - /** - parameter: String of map ids. Delimiter = "," - */ - - void VMapFactory::preventSpellsFromBeingTestedForLoS(const char* pSpellIdString) - { - if (!iIgnoreSpellIds) - iIgnoreSpellIds = new Table<unsigned int, bool>(); - if (pSpellIdString != NULL) - { - unsigned int pos =0; - unsigned int id; - std::string confString(pSpellIdString); - chompAndTrim(confString); - while (getNextId(confString, pos, id)) - { - iIgnoreSpellIds->set(id, true); - } - } - } - - //=============================================== - - bool VMapFactory::checkSpellForLoS(unsigned int pSpellId) - { - return(!iIgnoreSpellIds->containsKey(pSpellId)); - } + IVMapManager* gVMapManager = NULL; //=============================================== // just return the instance @@ -123,9 +36,6 @@ namespace VMAP // delete all internal data structures void VMapFactory::clear() { - delete iIgnoreSpellIds; - iIgnoreSpellIds = NULL; - delete gVMapManager; gVMapManager = NULL; } diff --git a/src/server/collision/Management/VMapFactory.h b/src/server/collision/Management/VMapFactory.h index 05fdc193c74..1545a8f6977 100644 --- a/src/server/collision/Management/VMapFactory.h +++ b/src/server/collision/Management/VMapFactory.h @@ -34,9 +34,6 @@ namespace VMAP public: static IVMapManager* createOrGetVMapManager(); static void clear(); - - static void preventSpellsFromBeingTestedForLoS(const char* pSpellIdString); - static bool checkSpellForLoS(unsigned int pSpellId); }; } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 88d20307d86..1ef035d8f87 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -489,6 +489,7 @@ uint32 Condition::GetMaxAvailableConditionTargets() case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: case CONDITION_SOURCE_TYPE_NPC_VENDOR: + case CONDITION_SOURCE_TYPE_SPELL_PROC: return 2; default: return 1; @@ -1427,6 +1428,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) break; } case CONDITION_SOURCE_TYPE_SPELL: + case CONDITION_SOURCE_TYPE_SPELL_PROC: { SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry); if (!spellProto) diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 8826c7cc484..cd3cf7bbbd8 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -128,8 +128,9 @@ enum ConditionSourceType CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21, CONDITION_SOURCE_TYPE_SMART_EVENT = 22, CONDITION_SOURCE_TYPE_NPC_VENDOR = 23, - CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 24, - CONDITION_SOURCE_TYPE_MAX = 25 // MAX + CONDITION_SOURCE_TYPE_SPELL_PROC = 24, + CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 25, + CONDITION_SOURCE_TYPE_MAX = 26 // MAX }; enum ComparisionType diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp index 8cd36827ab9..fefb51323c4 100644 --- a/src/server/game/Conditions/DisableMgr.cpp +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -310,6 +310,8 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags } else if (spellFlags & SPELL_DISABLE_DEPRECATED_SPELL) // call not from spellcast return true; + else if (flags & SPELL_DISABLE_LOS) + return spellFlags & SPELL_DISABLE_LOS; break; } diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h index e84f3347df8..89761931048 100644 --- a/src/server/game/Conditions/DisableMgr.h +++ b/src/server/game/Conditions/DisableMgr.h @@ -42,8 +42,10 @@ enum SpellDisableTypes SPELL_DISABLE_DEPRECATED_SPELL = 0x8, SPELL_DISABLE_MAP = 0x10, SPELL_DISABLE_AREA = 0x20, + SPELL_DISABLE_LOS = 0x40, MAX_SPELL_DISABLE_TYPE = ( SPELL_DISABLE_PLAYER | SPELL_DISABLE_CREATURE | SPELL_DISABLE_PET | - SPELL_DISABLE_DEPRECATED_SPELL | SPELL_DISABLE_MAP | SPELL_DISABLE_AREA) + SPELL_DISABLE_DEPRECATED_SPELL | SPELL_DISABLE_MAP | SPELL_DISABLE_AREA | + SPELL_DISABLE_LOS) }; enum VmapDisableTypes diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index c2d98a412b7..155ce911a65 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11459,7 +11459,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) if (GetTypeId() == TYPEID_UNIT) { Unit* pOwner = GetCharmerOrOwner(); - if (isPet() && !isInCombat() && pOwner) // Must check for owner or crash on "Tame Beast" + if ((isPet() || isGuardian()) && !isInCombat() && pOwner) // Must check for owner or crash on "Tame Beast" { // For every yard over 5, increase speed by 0.01 // to help prevent pet from lagging behind and despawning @@ -13518,6 +13518,12 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u } } + Unit* actor = isVictim ? target : this; + Unit* actionTarget = !isVictim ? target : this; + + DamageInfo damageInfo = DamageInfo(actor, actionTarget, damage, procSpell, procSpell ? SpellSchoolMask(procSpell->SchoolMask) : SPELL_SCHOOL_MASK_NORMAL, SPELL_DIRECT_DAMAGE); + ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, 0, procExtra, NULL, &damageInfo, NULL /*HealInfo*/); + ProcTriggeredList procTriggered; // Fill procTriggered list for (AuraApplicationMap::const_iterator itr = GetAppliedAuras().begin(); itr!= GetAppliedAuras().end(); ++itr) @@ -13541,6 +13547,12 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u if (!IsTriggeredAtSpellProcEvent(target, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, active, triggerData.spellProcEvent)) continue; + // do checks using conditions table + ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id); + ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget()); + if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions)) + continue; + // Triggered spells not triggering additional spells bool triggered = !(spellProto->AttributesEx3 & SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ? (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 77059b794ff..764ec68bbcc 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1702,8 +1702,13 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI if (!sSpellMgr->CanSpellTriggerProcOnEvent(*procEntry, eventInfo)) return false; + // do checks using conditions table + ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetSpellInfo()->Id); + ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget()); + if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions)) + return false; + // TODO: - // - do checks using conditions table for eventInfo->GetActor() and eventInfo->GetActionTarget() // - add DoCheckProc() AuraScript hook // to allow additional requirements for procs // this is needed because this is the last moment in which you can prevent aura charge drop on proc diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 6f29caeeee4..abfda74d555 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4944,7 +4944,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_NOT_INFRONT; if (m_caster->GetEntry() != WORLD_TRIGGER) // Ignore LOS for gameobjects casts (wrongly casted by a trigger) - if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target)) + if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOSInMap(target)) return SPELL_FAILED_LINE_OF_SIGHT; } } @@ -4955,7 +4955,7 @@ SpellCastResult Spell::CheckCast(bool strict) float x, y, z; m_targets.GetDstPos()->GetPosition(x, y, z); - if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOS(x, y, z)) + if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z)) return SPELL_FAILED_LINE_OF_SIGHT; } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 39ff431161f..d291d1d2fe9 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1164,15 +1164,13 @@ void World::LoadConfigSettings(bool reload) bool enableLOS = ConfigMgr::GetBoolDefault("vmap.enableLOS", true); bool enableHeight = ConfigMgr::GetBoolDefault("vmap.enableHeight", true); bool enablePetLOS = ConfigMgr::GetBoolDefault("vmap.petLOS", true); - std::string ignoreSpellIds = ConfigMgr::GetStringDefault("vmap.ignoreSpellIds", ""); if (!enableHeight) sLog->outError(LOG_FILTER_SERVER_LOADING, "VMap height checking disabled! Creatures movements and other various things WILL be broken! Expect no support."); VMAP::VMapFactory::createOrGetVMapManager()->setEnableLineOfSightCalc(enableLOS); VMAP::VMapFactory::createOrGetVMapManager()->setEnableHeightCalc(enableHeight); - VMAP::VMapFactory::preventSpellsFromBeingTestedForLoS(ignoreSpellIds.c_str()); - sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap support included. LineOfSight:%i, getHeight:%i, indoorCheck:%i PetLOS:%i", enableLOS, enableHeight, enableIndoor, enablePetLOS); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap support included. LineOfSight: %i, getHeight: %i, indoorCheck: %i PetLOS: %i", enableLOS, enableHeight, enableIndoor, enablePetLOS); sLog->outInfo(LOG_FILTER_SERVER_LOADING, "VMap data directory is: %svmaps", m_dataPath.c_str()); m_int_configs[CONFIG_MAX_WHO] = ConfigMgr::GetIntDefault("MaxWhoListReturns", 49); diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp index 091c9fd1f91..15c7a10a125 100644 --- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp +++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp @@ -33,12 +33,10 @@ enum Spells SPELL_WING_FLAP = 12882, SPELL_PIERCE_ARMOR = 6016, SPELL_DISARM = 8379, - SPELL_KIRTONOS_TRANSFORM = 16467, - SPELL_SHADOW_BOLT = 17228, SPELL_CURSE_OF_TONGUES = 12889, - SPELL_DONINATE_MIND = 14515 + SPELL_DOMINATE_MIND = 14515 }; enum Events @@ -55,37 +53,15 @@ enum Events EVENT_DISARM = 10, EVENT_SHADOW_BOLT = 11, EVENT_CURSE_OF_TONGUES = 12, - EVENT_DONINATE_MIND = 13, + EVENT_DOMINATE_MIND = 13, EVENT_KIRTONOS_TRANSFORM = 14 }; -enum Points -{ - MAX_KIRTONOS_WAYPOINTS_INTRO = 14, - POINT_KIRTONOS_LAND = 14 -}; - enum Misc { - WEAPON_KIRTONOS_STAFF = 11365 -}; - -Position const kirtonosIntroWaypoint[MAX_KIRTONOS_WAYPOINTS_INTRO] = -{ - {316.7087f, 71.26834f, 104.5843f, 0.0f}, - {321.1605f, 72.80973f, 104.6676f, 0.0f}, - {332.3713f, 77.98991f, 105.8621f, 0.0f}, - {333.3254f, 86.60159f, 106.6399f, 0.0f}, - {334.1263f, 101.6836f, 106.8343f, 0.0f}, - {331.0458f, 114.5935f, 106.3621f, 0.0f}, - {329.5439f, 126.7019f, 106.1399f, 0.0f}, - {335.2471f, 136.5460f, 105.7232f, 0.0f}, - {343.2100f, 139.9459f, 107.6399f, 0.0f}, - {364.3288f, 140.9012f, 109.9454f, 0.0f}, - {362.6760f, 115.6384f, 110.3065f, 0.0f}, - {341.7896f, 91.94390f, 107.1676f, 0.0f}, - {313.4945f, 93.45945f, 104.0565f, 0.0f}, - {306.3839f, 93.61675f, 104.0565f, 0.0f}, + WEAPON_KIRTONOS_STAFF = 11365, + POINT_KIRTONOS_LAND = 13, + KIRTONOS_PATH = 105061 }; class boss_kirtonos_the_herald : public CreatureScript @@ -113,7 +89,7 @@ class boss_kirtonos_the_herald : public CreatureScript events.ScheduleEvent(EVENT_DISARM, urand(22000, 22000)); events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(42000, 42000)); events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, urand(53000, 53000)); - events.ScheduleEvent(EVENT_DONINATE_MIND, urand(34000, 48000)); + events.ScheduleEvent(EVENT_DOMINATE_MIND, urand(34000, 48000)); events.ScheduleEvent(EVENT_KIRTONOS_TRANSFORM, urand(20000, 20000)); _EnterCombat(); } @@ -142,12 +118,7 @@ class boss_kirtonos_the_herald : public CreatureScript me->DespawnOrUnsummon(5000); } - void DamageTaken(Unit* /*killer*/, uint32 &damage) - { - - } - - void IsSummonedBy(Unit* summoner) + void IsSummonedBy(Unit* /*summoner*/) { me->SetDisableGravity(true); me->SetReactState(REACT_PASSIVE); @@ -163,12 +134,13 @@ class boss_kirtonos_the_herald : public CreatureScript BossAI::JustSummoned(summon); } - void MovementInform(uint32 movementType, uint32 pointId) + void MovementInform(uint32 type, uint32 id) { - if (movementType != POINT_MOTION_TYPE) - return; - - _currentPoint = pointId + 1; + if (type == WAYPOINT_MOTION_TYPE && id == POINT_KIRTONOS_LAND) + { + _introTimer = 1500; + _introEvent = INTRO_2; + } } void UpdateAI(uint32 const diff) @@ -180,13 +152,8 @@ class boss_kirtonos_the_herald : public CreatureScript switch (_introEvent) { case INTRO_1: - if (_currentPoint < POINT_KIRTONOS_LAND) - me->GetMotionMaster()->MovePoint(_currentPoint, kirtonosIntroWaypoint[_currentPoint]); - else - { - _introTimer = 1000; - _introEvent = INTRO_2; - } + me->GetMotionMaster()->MovePath(KIRTONOS_PATH,false); + _introEvent = 0; break; case INTRO_2: me->SetWalk(true); @@ -204,6 +171,7 @@ class boss_kirtonos_the_herald : public CreatureScript case INTRO_4: if (GameObject* brazier = me->GetMap()->GetGameObject(instance->GetData64(GO_BRAZIER_OF_THE_HERALD))) brazier->SetGoState(GO_STATE_READY); + me->SetWalk(true); me->SetDisableGravity(false); DoCast(me, SPELL_KIRTONOS_TRANSFORM); _introTimer = 1000; @@ -227,7 +195,7 @@ class boss_kirtonos_the_herald : public CreatureScript _introTimer -= diff; } - if (!UpdateVictim()) + if (!UpdateVictim()) return; events.Update(diff); @@ -241,31 +209,31 @@ class boss_kirtonos_the_herald : public CreatureScript { case EVENT_SWOOP: DoCast(me, SPELL_SWOOP); - events.ScheduleEvent(EVENT_SWOOP, urand(15000, 15000)); + events.ScheduleEvent(EVENT_SWOOP, 15000); break; case EVENT_WING_FLAP: DoCast(me, SPELL_WING_FLAP); - events.ScheduleEvent(EVENT_WING_FLAP, urand(13000, 13000)); + events.ScheduleEvent(EVENT_WING_FLAP, 13000); break; case EVENT_PIERCE_ARMOR: DoCastVictim(SPELL_PIERCE_ARMOR, true); - events.ScheduleEvent(EVENT_PIERCE_ARMOR, urand(12000, 12000)); + events.ScheduleEvent(EVENT_PIERCE_ARMOR, 12000); break; case EVENT_DISARM: DoCastVictim(SPELL_DISARM, true); - events.ScheduleEvent(EVENT_DISARM, urand(11000, 11000)); + events.ScheduleEvent(EVENT_DISARM, 11000); break; case EVENT_SHADOW_BOLT: DoCastVictim(SPELL_SHADOW_BOLT, true); - events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(42000, 42000)); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 42000); break; case EVENT_CURSE_OF_TONGUES: DoCastVictim(SPELL_CURSE_OF_TONGUES, true); - events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, urand(35000, 35000)); + events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, 35000); break; - case EVENT_DONINATE_MIND: - DoCastVictim(SPELL_DONINATE_MIND, true); - events.ScheduleEvent(EVENT_DONINATE_MIND, urand(44000, 48000)); + case EVENT_DOMINATE_MIND: + DoCastVictim(SPELL_DOMINATE_MIND, true); + events.ScheduleEvent(EVENT_DOMINATE_MIND, urand(44000, 48000)); break; case EVENT_KIRTONOS_TRANSFORM: if (me->HasAura(SPELL_KIRTONOS_TRANSFORM)) @@ -312,16 +280,16 @@ enum Brazier_Of_The_Herald class go_brazier_of_the_herald : public GameObjectScript { -public: - go_brazier_of_the_herald() : GameObjectScript("go_brazier_of_the_herald") { } + public: + go_brazier_of_the_herald() : GameObjectScript("go_brazier_of_the_herald") { } - bool OnGossipHello(Player* player, GameObject* go) - { - go->UseDoorOrButton(); - go->PlayDirectSound(SOUND_SCREECH,0); - player->SummonCreature(NPC_KIRTONOS, 315.028f, 70.53845f, 102.1496f, 0.3859715f, TEMPSUMMON_DEAD_DESPAWN, 900000); - return true; - } + bool OnGossipHello(Player* player, GameObject* go) + { + go->UseDoorOrButton(); + go->PlayDirectSound(SOUND_SCREECH, 0); + player->SummonCreature(NPC_KIRTONOS, 315.028f, 70.53845f, 102.1496f, 0.3859715f, TEMPSUMMON_DEAD_DESPAWN, 900000); + return true; + } }; void AddSC_boss_kirtonos_the_herald() diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index 372811b8a8c..80f38dbd7cf 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -29,13 +29,14 @@ EndScriptData */ #include "Player.h" #include "TemporarySummon.h" -#define MAX_ENCOUNTER 6 -#define RAND_VENDOR 2 +enum Misc +{ + MAX_ENCOUNTER = 7, + RAND_VENDOR = 2, + WORLDSTATE_SHOW_TIMER = 3104, + WORLDSTATE_TIME_TO_SACRIFICE = 3106 +}; -//187021 //Harkor's Satchel -//186648 //Tanzar's Trunk -//186672 //Ashli's Bag -//186667 //Kraz's Package // Chests spawn at bear/eagle/dragonhawk/lynx bosses // The loots depend on how many bosses have been killed, but not the entries of the chests // But we cannot add loots to gameobject, so we have to use the fixed loot_template @@ -51,9 +52,10 @@ static SHostageInfo HostageInfo[] = {23999, 187021, 400, 1414, 74.36f, 3.3f}, // eagle {24001, 186672, -35, 1134, 18.71f, 1.9f}, // dragonhawk {24024, 186667, 413, 1117, 6.32f, 3.1f} // lynx - }; +Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f}; + class instance_zulaman : public InstanceMapScript { public: @@ -70,9 +72,11 @@ class instance_zulaman : public InstanceMapScript uint64 TanzarsTrunkGUID; uint64 AshlisBagGUID; uint64 KrazsPackageGUID; + uint64 StrangeGongGUID; uint64 HexLordGateGUID; uint64 ZulJinGateGUID; + uint64 MassiveGateGUID; uint64 AkilzonDoorGUID; uint64 ZulJinDoorGUID; uint64 HalazziDoorGUID; @@ -93,20 +97,24 @@ class instance_zulaman : public InstanceMapScript TanzarsTrunkGUID = 0; AshlisBagGUID = 0; KrazsPackageGUID = 0; - + StrangeGongGUID = 0; HexLordGateGUID = 0; ZulJinGateGUID = 0; + MassiveGateGUID = 0; AkilzonDoorGUID = 0; HalazziDoorGUID = 0; ZulJinDoorGUID = 0; QuestTimer = 0; - QuestMinute = 21; + QuestMinute = 0; BossKilled = 0; ChestLooted = 0; for (uint8 i = 0; i < RAND_VENDOR; ++i) RandVendor[i] = NOT_STARTED; + + m_auiEncounter[DATA_GONGEVENT] = NOT_STARTED; + instance->SummonCreature(NPC_HARRISON_JONES, HarrisonJonesLoc); } bool IsEncounterInProgress() const @@ -122,11 +130,11 @@ class instance_zulaman : public InstanceMapScript { switch (creature->GetEntry()) { - case 23578://janalai - case 23863://zuljin - case 24239://hexlord - case 23577://halazzi - case 23576://nalorakk + case NPC_JANALAI: + case NPC_ZULJIN: + case NPC_HEXLORD: + case NPC_HALAZZI: + case NPC_NALORAKK: default: break; } } @@ -135,18 +143,19 @@ class instance_zulaman : public InstanceMapScript { switch (go->GetEntry()) { - case 186303: HalazziDoorGUID = go->GetGUID(); break; - case 186304: ZulJinGateGUID = go->GetGUID(); break; - case 186305: HexLordGateGUID = go->GetGUID(); break; - case 186858: AkilzonDoorGUID = go->GetGUID(); break; - case 186859: ZulJinDoorGUID = go->GetGUID(); break; - - case 187021: HarkorsSatchelGUID = go->GetGUID(); break; - case 186648: TanzarsTrunkGUID = go->GetGUID(); break; - case 186672: AshlisBagGUID = go->GetGUID(); break; - case 186667: KrazsPackageGUID = go->GetGUID(); break; + case GO_DOOR_HALAZZI: HalazziDoorGUID = go->GetGUID(); break; + case GO_GATE_ZULJIN: ZulJinGateGUID = go->GetGUID(); break; + case GO_GATE_HEXLORD: HexLordGateGUID = go->GetGUID(); break; + case GO_MASSIVE_GATE: MassiveGateGUID = go->GetGUID(); break; + case GO_DOOR_AKILZON: AkilzonDoorGUID = go->GetGUID(); break; + case GO_DOOR_ZULJIN: ZulJinDoorGUID = go->GetGUID(); break; + + case GO_HARKORS_SATCHEL: HarkorsSatchelGUID = go->GetGUID(); break; + case GO_TANZARS_TRUNK: TanzarsTrunkGUID = go->GetGUID(); break; + case GO_ASHLIS_BAG: AshlisBagGUID = go->GetGUID(); break; + case GO_KRAZS_PACKAGE: KrazsPackageGUID = go->GetGUID(); break; + case GO_STRANGE_GONG: StrangeGongGUID = go->GetGUID(); break; default: break; - } CheckInstanceStatus(); } @@ -173,10 +182,13 @@ class instance_zulaman : public InstanceMapScript void CheckInstanceStatus() { - if (BossKilled >= 4) + if (m_auiEncounter[DATA_GONGEVENT] == DONE) + HandleGameObject(MassiveGateGUID, true); + + if (BossKilled >= DATA_HALAZZIEVENT) HandleGameObject(HexLordGateGUID, true); - if (BossKilled >= 5) + if (BossKilled >= DATA_HEXLORDEVENT) HandleGameObject(ZulJinGateGUID, true); } @@ -214,49 +226,57 @@ class instance_zulaman : public InstanceMapScript { switch (type) { + case DATA_GONGEVENT: + m_auiEncounter[DATA_GONGEVENT] = data; + if (data == SPECIAL) + SaveToDB(); + if (data == DONE) + QuestMinute = 21; + break; case DATA_NALORAKKEVENT: - m_auiEncounter[0] = data; + m_auiEncounter[DATA_NALORAKKEVENT] = data; if (data == DONE) { if (QuestMinute) { QuestMinute += 15; - DoUpdateWorldState(3106, QuestMinute); + DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); } SummonHostage(0); } break; case DATA_AKILZONEVENT: - m_auiEncounter[1] = data; + m_auiEncounter[DATA_AKILZONEVENT] = data; HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS); if (data == DONE) { if (QuestMinute) { QuestMinute += 10; - DoUpdateWorldState(3106, QuestMinute); + DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); } SummonHostage(1); } break; case DATA_JANALAIEVENT: - m_auiEncounter[2] = data; - if (data == DONE) SummonHostage(2); + m_auiEncounter[DATA_JANALAIEVENT] = data; + if (data == DONE) + SummonHostage(2); break; case DATA_HALAZZIEVENT: - m_auiEncounter[3] = data; + m_auiEncounter[DATA_HALAZZIEVENT] = data; HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS); if (data == DONE) SummonHostage(3); break; case DATA_HEXLORDEVENT: - m_auiEncounter[4] = data; + m_auiEncounter[DATA_HEXLORDEVENT] = data; if (data == IN_PROGRESS) HandleGameObject(HexLordGateGUID, false); else if (data == NOT_STARTED) CheckInstanceStatus(); break; case DATA_ZULJINEVENT: - m_auiEncounter[5] = data; + m_auiEncounter[DATA_ZULJINEVENT] = data; HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS); break; case DATA_CHESTLOOTED: @@ -274,10 +294,10 @@ class instance_zulaman : public InstanceMapScript if (data == DONE) { ++BossKilled; - if (QuestMinute && BossKilled >= 4) + if (QuestMinute && BossKilled >= DATA_HALAZZIEVENT) { QuestMinute = 0; - DoUpdateWorldState(3104, 0); + DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); } CheckInstanceStatus(); SaveToDB(); @@ -288,12 +308,13 @@ class instance_zulaman : public InstanceMapScript { switch (type) { - case DATA_NALORAKKEVENT: return m_auiEncounter[0]; - case DATA_AKILZONEVENT: return m_auiEncounter[1]; - case DATA_JANALAIEVENT: return m_auiEncounter[2]; - case DATA_HALAZZIEVENT: return m_auiEncounter[3]; - case DATA_HEXLORDEVENT: return m_auiEncounter[4]; - case DATA_ZULJINEVENT: return m_auiEncounter[5]; + case DATA_GONGEVENT: return m_auiEncounter[DATA_GONGEVENT]; + case DATA_NALORAKKEVENT: return m_auiEncounter[DATA_NALORAKKEVENT]; + case DATA_AKILZONEVENT: return m_auiEncounter[DATA_AKILZONEVENT]; + case DATA_JANALAIEVENT: return m_auiEncounter[DATA_JANALAIEVENT]; + case DATA_HALAZZIEVENT: return m_auiEncounter[DATA_HALAZZIEVENT]; + case DATA_HEXLORDEVENT: return m_auiEncounter[DATA_HEXLORDEVENT]; + case DATA_ZULJINEVENT: return m_auiEncounter[DATA_ZULJINEVENT]; case DATA_CHESTLOOTED: return ChestLooted; case TYPE_RAND_VENDOR_1: return RandVendor[0]; case TYPE_RAND_VENDOR_2: return RandVendor[1]; @@ -312,13 +333,27 @@ class instance_zulaman : public InstanceMapScript QuestTimer += 60000; if (QuestMinute) { - DoUpdateWorldState(3104, 1); - DoUpdateWorldState(3106, QuestMinute); - } else DoUpdateWorldState(3104, 0); + DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); + DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); + } else DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); } QuestTimer -= diff; } } + + uint64 GetData64(uint32 type) const + { + switch (type) + { + case GO_STRANGE_GONG: + return StrangeGongGUID; + case GO_MASSIVE_GATE: + return MassiveGateGUID; + } + + return 0; + } + }; InstanceScript* GetInstanceScript(InstanceMap* map) const diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp index 660f144c2dd..d140c349a4b 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp @@ -33,6 +33,7 @@ EndContentData */ #include "zulaman.h" #include "Player.h" #include "SpellInfo.h" +#include "SpellScript.h" /*###### ## npc_forest_frog @@ -199,9 +200,303 @@ class npc_zulaman_hostage : public CreatureScript } }; +/*###### +## npc_harrison_jones +######*/ + +enum Says +{ + SAY_HARRISON_0 = 0, + SAY_HARRISON_1 = 1, + SAY_HARRISON_2 = 0, + SAY_HARRISON_3 = 1 +}; + +enum Spells +{ + SPELL_BANGING_THE_GONG = 45225, + SPELL_STEALTH = 34189, + SPELL_COSMETIC_SPEAR_THROW = 43647 +}; + +enum Events +{ + GONG_EVENT_1 = 1, + GONG_EVENT_2 = 2, + GONG_EVENT_3 = 3, + GONG_EVENT_4 = 4, + GONG_EVENT_5 = 5, + GONG_EVENT_6 = 6, + GONG_EVENT_7 = 7, + GONG_EVENT_8 = 8, + GONG_EVENT_9 = 9, + GONG_EVENT_10 = 10, + GONG_EVENT_11 = 11, + GONG_EVENT_12 = 12 +}; + +enum Waypoints +{ + HARRISON_MOVE_1 = 860440, + HARRISON_MOVE_2 = 860441, + HARRISON_MOVE_3 = 860442 +}; + +enum DisplayIds +{ + MODEL_HARRISON_JONES_0 = 22340, + MODEL_HARRISON_JONES_1 = 22354, + MODEL_HARRISON_JONES_2 = 22347 +}; + +enum EntryIds +{ + NPC_HARRISON_JONES_1 = 24375, + NPC_HARRISON_JONES_2 = 24365, + NPC_AMANISHI_GUARDIAN = 23597, +}; + +enum Weapons +{ + WEAPON_MACE = 5301, + WEAPON_SPEAR = 13631 +}; + +Position const AmanishiGuardianLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f}; + +class npc_harrison_jones : public CreatureScript +{ + public: + + npc_harrison_jones() + : CreatureScript("npc_harrison_jones") + { + } + + struct npc_harrison_jonesAI : public ScriptedAI + { + npc_harrison_jonesAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } + + InstanceScript* instance; + + uint8 _gongEvent; + uint32 _gongTimer; + uint64 uiTargetGUID; + + void Reset() + { + _gongEvent = 0; + _gongTimer = 0; + uiTargetGUID = 0; + } + + void EnterCombat(Unit* /*who*/) {} + + void sGossipSelect(Player* player, uint32 sender, uint32 action) + { + if (me->GetCreatureTemplate()->GossipMenuId == sender && !action) + { + player->CLOSE_GOSSIP_MENU(); + me->SetInFront(player); + me->SendMovementFlagUpdate(true); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + Talk(SAY_HARRISON_0); + instance->SetData(DATA_GONGEVENT, IN_PROGRESS); + _gongEvent = GONG_EVENT_1; + _gongTimer = 4000; + } + } + + void SpellHit(Unit*, const SpellInfo* spell) + { + if (spell->Id == SPELL_COSMETIC_SPEAR_THROW) + { + me->RemoveAllAuras(); + me->SetEntry(NPC_HARRISON_JONES_2); + me->SetDisplayId(MODEL_HARRISON_JONES_2); + me->SetTarget(0); + me->SetByteValue(UNIT_FIELD_BYTES_1,0,UNIT_STAND_STATE_DEAD); + me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + if (instance) + instance->SetData(DATA_GONGEVENT, DONE); + } + } + + void UpdateAI(uint32 const diff) + { + if (_gongEvent) + { + if (_gongTimer <= diff) + { + switch (_gongEvent) + { + case GONG_EVENT_1: + me->GetMotionMaster()->MovePath(HARRISON_MOVE_1,false); + _gongTimer = 12000; + _gongEvent = GONG_EVENT_2; + break; + case GONG_EVENT_2: + me->SetFacingTo(6.235659f); + Talk(SAY_HARRISON_1); + DoCast(me, SPELL_BANGING_THE_GONG); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_MACE)); + me->SetSheath(SHEATH_STATE_MELEE); + _gongTimer = 4000; + _gongEvent = GONG_EVENT_3; + break; + case GONG_EVENT_3: + if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG))) + gong->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_NOT_SELECTABLE); + _gongTimer = 105000; + _gongEvent = GONG_EVENT_4; + break; + case GONG_EVENT_4: + me->RemoveAura(SPELL_BANGING_THE_GONG); + if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG))) + gong->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_NOT_SELECTABLE); + + // trigger or gong will need to be scripted to set SPECIAL if enough players click gong. + // This is temp workaround. + if (instance) + instance->SetData(DATA_GONGEVENT, SPECIAL); // to be removed. + + if (instance->GetData(DATA_GONGEVENT) == SPECIAL) + { + // Players are Now Saved to instance at SPECIAL (Player should be notified?) + me->GetMotionMaster()->MovePath(HARRISON_MOVE_2,false); + _gongTimer = 5000; + _gongEvent = 5; + } + else + { + _gongTimer = 1000; + _gongEvent = 10; + } + break; + case GONG_EVENT_5: + me->SetEntry(NPC_HARRISON_JONES_1); + me->SetDisplayId(MODEL_HARRISON_JONES_1); + Talk(SAY_HARRISON_2); + _gongTimer = 14000; + _gongEvent = 6; + break; + case GONG_EVENT_6: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); + Talk(SAY_HARRISON_3); + _gongTimer = 7000; + _gongEvent = 7; + break; + case GONG_EVENT_7: + if (!uiTargetGUID) + { + std::list<Creature*> targetList; + GetCreatureListWithEntryInGrid(targetList, me, NPC_AMANISHI_GUARDIAN, 26.0f); + if (!targetList.empty()) + { + for (std::list<Creature*>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr) + { + if (Creature* ptarget = *itr) + { + if (ptarget->GetPositionX() > 120) + { + ptarget->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_SPEAR)); + ptarget->AI()->SetData(0,1); + } + } + } + } + } + + if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_MASSIVE_GATE))) + gate->SetGoState(GO_STATE_ACTIVE); + _gongTimer = 1000; + _gongEvent = 8; + case GONG_EVENT_8: + DoCast(me, SPELL_STEALTH); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(0)); + me->GetMotionMaster()->MovePath(HARRISON_MOVE_3,false); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + _gongTimer = 100; + _gongEvent = 9; + case GONG_EVENT_9: + // If player in 10.0f range + // Send setdata to SAI for previous target + // SAI BELOW + // move 23597, guid 86194 to be deleted + // path 138.2242 Y: 1586.994 Z: 43.5488 + // path 131.8407 Y: 1590.247 Z: 43.61384 + // Reach end of path turnto 2.024582 cast Spell ID: 43647 on self hits 24365 update UNIT_VIRTUAL_ITEM_SLOT_ID: 33979 + // wait 2 sec say text 0 + // Set below after complete above + _gongTimer = 0; + _gongEvent = 0; + break; + case GONG_EVENT_10: + me->GetMotionMaster()->MovePoint(0, 120.687f, 1674.0f, 42.0217f); + _gongTimer = 12000; + _gongEvent = 11; + break; + case GONG_EVENT_11: + me->SetFacingTo(1.59044f); + _gongTimer = 6000; + _gongEvent = 12; + break; + case GONG_EVENT_12: + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + if (instance) + instance->SetData(DATA_GONGEVENT, NOT_STARTED); + _gongTimer = 0; + _gongEvent = 0; + break; + } + } + else + _gongTimer -= diff; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_harrison_jonesAI(creature); + } +}; + +class spell_banging_the_gong : public SpellScriptLoader +{ + public: + spell_banging_the_gong() : SpellScriptLoader("spell_banging_the_gong") { } + + class spell_banging_the_gong_SpellScript : public SpellScript + { + PrepareSpellScript(spell_banging_the_gong_SpellScript); + + void Activate(SpellEffIndex index) + { + PreventHitDefaultEffect(index); + GetHitGObj()->SendCustomAnim(0); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_banging_the_gong_SpellScript::Activate, EFFECT_1, SPELL_EFFECT_ACTIVATE_OBJECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_banging_the_gong_SpellScript(); + } +}; + + void AddSC_zulaman() { new npc_forest_frog(); new npc_zulaman_hostage(); + new npc_harrison_jones(); + new spell_banging_the_gong(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index 7227dfaedf4..c3386f8c996 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -19,15 +19,43 @@ #ifndef DEF_ZULAMAN_H #define DEF_ZULAMAN_H -#define DATA_NALORAKKEVENT 1 -#define DATA_AKILZONEVENT 2 -#define DATA_JANALAIEVENT 3 -#define DATA_HALAZZIEVENT 4 -#define DATA_HEXLORDEVENT 5 -#define DATA_ZULJINEVENT 6 -#define DATA_CHESTLOOTED 7 -#define TYPE_RAND_VENDOR_1 8 -#define TYPE_RAND_VENDOR_2 9 +enum DataTypes +{ + DATA_GONGEVENT = 0, + DATA_NALORAKKEVENT = 1, + DATA_AKILZONEVENT = 2, + DATA_JANALAIEVENT = 3, + DATA_HALAZZIEVENT = 4, + DATA_HEXLORDEVENT = 5, + DATA_ZULJINEVENT = 6, + DATA_CHESTLOOTED = 7, + TYPE_RAND_VENDOR_1 = 8, + TYPE_RAND_VENDOR_2 = 9 +}; -#endif +enum CreatureIds +{ + NPC_HARRISON_JONES = 24358, + NPC_JANALAI = 23578, + NPC_ZULJIN = 23863, + NPC_HEXLORD = 24239, + NPC_HALAZZI = 23577, + NPC_NALORAKK = 23576 +}; + +enum GameobjectIds +{ + GO_DOOR_HALAZZI = 186303, + GO_GATE_ZULJIN = 186304, + GO_GATE_HEXLORD = 186305, + GO_MASSIVE_GATE = 186728, + GO_DOOR_AKILZON = 186858, + GO_DOOR_ZULJIN = 186859, + GO_HARKORS_SATCHEL = 187021, + GO_TANZARS_TRUNK = 186648, + GO_ASHLIS_BAG = 186672, + GO_KRAZS_PACKAGE = 186667, + GO_STRANGE_GONG = 187359 +}; +#endif diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp index 6d33efb4515..e99128fbbf9 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp @@ -16,229 +16,245 @@ */ #include "ScriptMgr.h" +#include "SpellScript.h" #include "ScriptedCreature.h" #include "drak_tharon_keep.h" -enum Spells +enum Misc { - SPELL_ARCANE_BLAST = 49198, - H_SPELL_ARCANE_BLAST = 59909, - SPELL_ARCANE_FIELD = 47346, - SPELL_BLIZZARD = 49034, - H_SPELL_BLIZZARD = 59854, - SPELL_FROSTBOLT = 49037, - H_SPELL_FROSTBOLT = 59855, - SPELL_WRATH_OF_MISERY = 50089, - H_SPELL_WRATH_OF_MISERY = 59856, - SPELL_SUMMON_MINIONS = 59910 //Summons an army of Fetid Troll Corpses to assist the caster. + ACTION_RESET_CRYSTALS, + ACTION_ACTIVATE_CRYSTAL, + ACTION_DEACTIVATE, + EVENT_ATTACK, + EVENT_SUMMON_MINIONS, + DATA_NOVOS_ACHIEV }; -//not in db -enum Yells +enum Creatures { - SAY_AGGRO = 0, - SAY_KILL = 1, - SAY_DEATH = 2, - SAY_NECRO_ADD = 3, - SAY_REUBBLE = 4 + NPC_CRYSTAL_CHANNEL_TARGET = 26712, + NPC_FETID_TROLL_CORPSE = 27597, + NPC_RISEN_SHADOWCASTER = 27600, + NPC_HULKING_CORPSE = 27597 }; -enum Creatures +enum Spells { - CREATURE_RISEN_SHADOWCASTER = 27600, - CREATURE_FETID_TROLL_CORPSE = 27598, - CREATURE_HULKING_CORPSE = 27597, - CREATURE_CRYSTAL_HANDLER = 26627 + SPELL_BEAM_CHANNEL = 52106, + SPELL_ARCANE_FIELD = 47346, + + SPELL_SUMMON_RISEN_SHADOWCASTER = 49105, + SPELL_SUMMON_FETID_TROLL_CORPSE = 49103, + SPELL_SUMMON_HULKING_CORPSE = 49104, + SPELL_SUMMON_CRYSTAL_HANDLER = 49179, + + SPELL_ARCANE_BLAST = 49198, + SPELL_BLIZZARD = 49034, + SPELL_FROSTBOLT = 49037, + SPELL_WRATH_OF_MISERY = 50089, + SPELL_SUMMON_MINIONS = 59910 }; -enum CombatPhase +struct SummonerInfo { - IDLE, - PHASE_1, - PHASE_2 + uint32 data, spell, timer; }; -#define ACTION_MINION_REACHED 1 -#define DATA_OH_NOVOS 2 +const SummonerInfo summoners[] = +{ + { DATA_NOVOS_SUMMONER_1, SPELL_SUMMON_RISEN_SHADOWCASTER, 15000 }, + { DATA_NOVOS_SUMMONER_2, SPELL_SUMMON_FETID_TROLL_CORPSE, 5000 }, + { DATA_NOVOS_SUMMONER_3, SPELL_SUMMON_HULKING_CORPSE, 30000 }, + { DATA_NOVOS_SUMMONER_4, SPELL_SUMMON_CRYSTAL_HANDLER, 30000 } +}; -static Position AddSpawnPoint = { -379.20f, -816.76f, 59.70f, 0.0f }; -static Position CrystalHandlerSpawnPoint = { -326.626343f, -709.956604f, 27.813314f, 0.0f }; -static Position AddDestinyPoint = { -379.314545f, -772.577637f, 28.58837f, 0.0f }; +#define MAX_Y_COORD_OH_NOVOS -771.95f class boss_novos : public CreatureScript { public: boss_novos() : CreatureScript("boss_novos") { } - struct boss_novosAI : public Scripted_NoMovementAI + struct boss_novosAI : public BossAI { - boss_novosAI(Creature* creature) : Scripted_NoMovementAI(creature), lSummons(me) + boss_novosAI(Creature* creature) : BossAI(creature, DATA_NOVOS_EVENT) {} + + void Reset() { - instance = creature->GetInstanceScript(); + events.Reset(); + summons.DespawnAll(); + instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED); + + _ohNovos = true; + _crystalHandlerCount = 0; + SetCrystalsStatus(false); + SetSummonerStatus(false); + SetBubbled(false); } - uint32 uiTimer; - uint32 uiCrystalHandlerTimer; - uint8 crystalHandlerAmount; + void EnterCombat(Unit* /* victim */) + { + me->setActive(true); + DoZoneInCombat(); + instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS); - bool ohNovos; + SetCrystalsStatus(true); + SetSummonerStatus(true); + SetBubbled(true); + } - SummonList lSummons; + void AttackStart(Unit* target) + { + if (!target) + return; - std::list<uint64> luiCrystals; + if (me->Attack(target, true)) + DoStartNoMovement(target); + } - CombatPhase Phase; + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim() || _bubbled) + return; - InstanceScript* instance; + events.Update(diff); - void Reset() - { - Phase = IDLE; - luiCrystals.clear(); - ohNovos = true; - me->CastStop(); - lSummons.DespawnAll(); - crystalHandlerAmount = 0; - - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)) - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - if (instance) - { - instance->SetData(DATA_NOVOS_EVENT, NOT_STARTED); - for (uint8 n = 0; n < 4; ++n) - luiCrystals.push_back(instance->GetData64(DATA_NOVOS_CRYSTAL_1 + n)); - for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr) - { - if (GameObject* temp = instance->instance->GetGameObject(*itr)) - temp->SetGoState(GO_STATE_READY); - } - } - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void EnterCombat(Unit* /*who*/) - { - Talk(SAY_AGGRO); - Phase = PHASE_1; - uiCrystalHandlerTimer = 30*IN_MILLISECONDS; - uiTimer = 1*IN_MILLISECONDS; - DoCast(SPELL_ARCANE_FIELD); - if (instance) + if (uint32 eventId = events.ExecuteEvent()) { - for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr) + switch (eventId) { - if (GameObject* temp = instance->instance->GetGameObject(*itr)) - temp->SetGoState(GO_STATE_ACTIVE); + case EVENT_SUMMON_MINIONS: + DoCast(SPELL_SUMMON_MINIONS); + events.ScheduleEvent(EVENT_SUMMON_MINIONS, 15000); + break; + case EVENT_ATTACK: + if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(victim, RAND(SPELL_ARCANE_BLAST, SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_WRATH_OF_MISERY)); + events.ScheduleEvent(EVENT_ATTACK, 3000); + break; + default: + break; } - instance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS); } - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } - void UpdateAI(const uint32 diff) + void DoAction(int32 const action) { - switch (Phase) - { - case PHASE_1: - if (uiTimer <= diff) - { - Creature* summon = me->SummonCreature(RAND(CREATURE_FETID_TROLL_CORPSE, CREATURE_HULKING_CORPSE, CREATURE_RISEN_SHADOWCASTER), AddSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS); - summon->GetMotionMaster()->MovePoint(0, AddDestinyPoint); - //If spell is casted stops casting arcane field so no spell casting - //DoCast(me, SPELL_SUMMON_MINIONS); - uiTimer = 3*IN_MILLISECONDS; - } else uiTimer -= diff; - if (crystalHandlerAmount < 4) - { - if (uiCrystalHandlerTimer <= diff) - { - Talk(SAY_NECRO_ADD); - Creature* pCrystalHandler = me->SummonCreature(CREATURE_CRYSTAL_HANDLER, CrystalHandlerSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20*IN_MILLISECONDS); - pCrystalHandler->GetMotionMaster()->MovePoint(0, AddDestinyPoint); - uiCrystalHandlerTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS); - } else uiCrystalHandlerTimer -= diff; - } - break; - case PHASE_2: - if (uiTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, DUNGEON_MODE(RAND(SPELL_ARCANE_BLAST, SPELL_BLIZZARD, SPELL_FROSTBOLT, SPELL_WRATH_OF_MISERY), - RAND(H_SPELL_ARCANE_BLAST, H_SPELL_BLIZZARD, H_SPELL_FROSTBOLT, H_SPELL_WRATH_OF_MISERY))); - uiTimer = urand(1*IN_MILLISECONDS, 3*IN_MILLISECONDS); - } else uiTimer -= diff; - break; - default: - break; - } + if (action == ACTION_CRYSTAL_HANDLER_DIED) + CrystalHandlerDied(); } - void JustDied(Unit* /*killer*/) + + void MoveInLineOfSight(Unit* who) { - Talk(SAY_DEATH); - if (instance) - instance->SetData(DATA_NOVOS_EVENT, DONE); - lSummons.DespawnAll(); + BossAI::MoveInLineOfSight(who); + + if (!_ohNovos || !who || who->GetTypeId() != TYPEID_UNIT || who->GetPositionY() > MAX_Y_COORD_OH_NOVOS) + return; + + uint32 entry = who->GetEntry(); + if (entry == NPC_HULKING_CORPSE || entry == NPC_RISEN_SHADOWCASTER || entry == NPC_FETID_TROLL_CORPSE) + _ohNovos = false; } - void KilledUnit(Unit* victim) + uint32 GetData(uint32 type) const { - if (victim == me) - return; - Talk(SAY_KILL); + return type == DATA_NOVOS_ACHIEV && _ohNovos ? 1 : 0; } void JustSummoned(Creature* summon) { - if (summon->GetEntry() == CREATURE_CRYSTAL_HANDLER) - crystalHandlerAmount++; - - lSummons.Summon(summon); + summons.Summon(summon); } - void DoAction(int32 const action) + private: + void SetBubbled(bool state) { - if (action == ACTION_MINION_REACHED) - ohNovos = false; + _bubbled = state; + if (!state) + { + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)) + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + if (me->HasUnitState(UNIT_STATE_CASTING)) + me->CastStop(); + } + else + { + if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)) + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + DoCast(SPELL_ARCANE_FIELD); + } } - uint32 GetData(uint32 type) const + void SetSummonerStatus(bool active) { - if (type == DATA_OH_NOVOS) - return ohNovos ? 1 : 0; + for (uint8 i = 0; i < 4; i++) + if (uint64 guid = instance->GetData64(summoners[i].data)) + if (Creature* crystalChannelTarget = instance->instance->GetCreature(guid)) + { + if (active) + crystalChannelTarget->AI()->SetData(summoners[i].spell, summoners[i].timer); + else + crystalChannelTarget->AI()->Reset(); + } + } - return 0; + void SetCrystalsStatus(bool active) + { + for (uint8 i = 0; i < 4; i++) + if (uint64 guid = instance->GetData64(DATA_NOVOS_CRYSTAL_1 + i)) + if (GameObject* crystal = instance->instance->GetGameObject(guid)) + SetCrystalStatus(crystal, active); } - void RemoveCrystal() + void SetCrystalStatus(GameObject* crystal, bool active) { - if (!luiCrystals.empty()) - { - if (instance) - if (GameObject* temp = instance->instance->GetGameObject(luiCrystals.back())) - temp->SetGoState(GO_STATE_READY); - luiCrystals.pop_back(); - } - if (luiCrystals.empty()) + if (!crystal) + return; + + crystal->SetGoState(active ? GO_STATE_ACTIVE : GO_STATE_READY); + if (Creature* crystalChannelTarget = crystal->FindNearestCreature(NPC_CRYSTAL_CHANNEL_TARGET, 5.0f)) { - me->CastStop(); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Phase = PHASE_2; - uiTimer = 1*IN_MILLISECONDS; + if (active) + crystalChannelTarget->AI()->DoCastAOE(SPELL_BEAM_CHANNEL); + else if (crystalChannelTarget->HasUnitState(UNIT_STATE_CASTING)) + crystalChannelTarget->CastStop(); } } - Unit* GetRandomTarget() + void CrystalHandlerDied() { - return SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); + for (uint8 i = 0; i < 4; i++) + if (uint64 guid = instance->GetData64(DATA_NOVOS_CRYSTAL_1 + i)) + if (GameObject* crystal = instance->instance->GetGameObject(guid)) + if (crystal->GetGoState() == GO_STATE_ACTIVE) + { + SetCrystalStatus(crystal, false); + break; + } + + if (++_crystalHandlerCount >= 4) + { + SetSummonerStatus(false); + SetBubbled(false); + events.ScheduleEvent(EVENT_ATTACK, 3000); + if (IsHeroic()) + events.ScheduleEvent(EVENT_SUMMON_MINIONS, 15000); + } + else if (uint64 guid = instance->GetData64(DATA_NOVOS_SUMMONER_4)) + if (Creature* crystalChannelTarget = instance->instance->GetCreature(guid)) + crystalChannelTarget->AI()->SetData(SPELL_SUMMON_CRYSTAL_HANDLER, 15000); } + + uint8 _crystalHandlerCount; + bool _ohNovos; + bool _bubbled; }; CreatureAI* GetAI(Creature* creature) const @@ -247,126 +263,116 @@ public: } }; -enum CrystalHandlerSpells -{ - SPELL_FLASH_OF_DARKNESS = 49668, - H_SPELL_FLASH_OF_DARKNESS = 59004 -}; - -class mob_crystal_handler : public CreatureScript +class npc_crystal_channel_target : public CreatureScript { public: - mob_crystal_handler() : CreatureScript("mob_crystal_handler") { } + npc_crystal_channel_target() : CreatureScript("npc_crystal_channel_target") {} - struct mob_crystal_handlerAI : public ScriptedAI + struct npc_crystal_channel_targetAI : public ScriptedAI { - mob_crystal_handlerAI(Creature* creature) : ScriptedAI(creature) + npc_crystal_channel_targetAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() { - instance = creature->GetInstanceScript(); + _spell = 0; + _timer = 0; + _temp = 0; } - uint32 uiFlashOfDarknessTimer; - - InstanceScript* instance; - - void Reset() + void UpdateAI(const uint32 diff) { - uiFlashOfDarknessTimer = 5*IN_MILLISECONDS; + if (_spell) + { + if (_temp <= diff) + { + DoCast(_spell); + _temp = _timer; + } + else + _temp -= diff; + } } - void JustDied(Unit* /*killer*/) + void SetData(uint32 id, uint32 value) { - if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0)) - CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->RemoveCrystal(); + _spell = id; + _timer = value; + _temp = value; } - void UpdateAI(const uint32 diff) + void JustSummoned(Creature* summon) { - if (!UpdateVictim()) - return; + if (InstanceScript* instance = me->GetInstanceScript()) + if (uint64 guid = instance->GetData64(DATA_NOVOS)) + if (Creature* novos = Creature::GetCreature(*me, guid)) + novos->AI()->JustSummoned(summon); - if (uiFlashOfDarknessTimer <= diff) - { - DoCast(me->getVictim(), DUNGEON_MODE(SPELL_FLASH_OF_DARKNESS, H_SPELL_FLASH_OF_DARKNESS)); - uiFlashOfDarknessTimer = 5*IN_MILLISECONDS; - } else uiFlashOfDarknessTimer -= diff; + if (summon) + summon->GetMotionMaster()->MovePath(summon->GetEntry() * 100, false); - DoMeleeAttackIfReady(); + if (_spell == SPELL_SUMMON_CRYSTAL_HANDLER) + Reset(); } - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE || id != 0) - return; - if (Creature* pNovos = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0)) - if (Unit* target = CAST_AI(boss_novos::boss_novosAI, pNovos->AI())->GetRandomTarget()) - AttackStart(target); - } + private: + uint32 _spell; + uint32 _timer; + uint32 _temp; }; CreatureAI* GetAI(Creature* creature) const { - return new mob_crystal_handlerAI(creature); + return new npc_crystal_channel_targetAI(creature); } }; -class mob_novos_minion : public CreatureScript +class achievement_oh_novos : public AchievementCriteriaScript { public: - mob_novos_minion() : CreatureScript("mob_novos_minion") { } + achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") {} - struct mob_novos_minionAI : public ScriptedAI + bool OnCheck(Player* /*player*/, Unit* target) { - mob_novos_minionAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } + return target && target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->AI()->GetData(DATA_NOVOS_ACHIEV); + } +}; - InstanceScript* instance; +enum SummonMinions +{ + SPELL_COPY_OF_SUMMON_MINIONS = 59933 +}; - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE || id !=0) - return; - if (Creature* Novos = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_NOVOS) : 0)) - { - Novos->AI()->DoAction(ACTION_MINION_REACHED); - if (Unit* target = CAST_AI(boss_novos::boss_novosAI, Novos->AI())->GetRandomTarget()) - AttackStart(target); - } - } - }; +class spell_summon_minions : public SpellScriptLoader +{ +public: + spell_summon_minions() : SpellScriptLoader("spell_summon_minions") { } - CreatureAI* GetAI(Creature* creature) const + class spell_summon_minions_SpellScript : public SpellScript { - return new mob_novos_minionAI(creature); - } -}; + PrepareSpellScript(spell_summon_minions_SpellScript); -class achievement_oh_novos : public AchievementCriteriaScript -{ - public: - achievement_oh_novos() : AchievementCriteriaScript("achievement_oh_novos") + void HandleScript(SpellEffIndex /*effIndex*/) { + GetCaster()->CastSpell((Unit*)NULL, SPELL_COPY_OF_SUMMON_MINIONS, true); + GetCaster()->CastSpell((Unit*)NULL, SPELL_COPY_OF_SUMMON_MINIONS, true); } - bool OnCheck(Player* /*player*/, Unit* target) + void Register() { - if (!target) - return false; - - if (Creature* Novos = target->ToCreature()) - if (Novos->AI()->GetData(DATA_OH_NOVOS)) - return true; - - return false; + OnEffectHitTarget += SpellEffectFn(spell_summon_minions_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } + }; + + SpellScript* GetSpellScript() const + { + return new spell_summon_minions_SpellScript(); + } }; void AddSC_boss_novos() { new boss_novos(); - new mob_crystal_handler(); - new mob_novos_minion(); + new npc_crystal_channel_target(); + new spell_summon_minions(); new achievement_oh_novos(); } diff --git a/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h b/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h index dc8428f9104..e17cba4bccd 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h +++ b/src/server/scripts/Northrend/DraktharonKeep/drak_tharon_keep.h @@ -31,9 +31,16 @@ enum Data64 DATA_NOVOS, DATA_DRED, DATA_THARON_JA, + DATA_NOVOS_CRYSTAL_1, DATA_NOVOS_CRYSTAL_2, DATA_NOVOS_CRYSTAL_3, - DATA_NOVOS_CRYSTAL_4 + DATA_NOVOS_CRYSTAL_4, + DATA_NOVOS_SUMMONER_1, + DATA_NOVOS_SUMMONER_2, + DATA_NOVOS_SUMMONER_3, + DATA_NOVOS_SUMMONER_4, + + ACTION_CRYSTAL_HANDLER_DIED }; #endif diff --git a/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp b/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp index 52c5c9eab8e..28bea60fb87 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp @@ -16,6 +16,7 @@ */ #include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "InstanceScript.h" #include "drak_tharon_keep.h" @@ -30,17 +31,23 @@ enum Creatures { - NPC_TROLLGORE = 26630, - NPC_NOVOS = 26631, - NPC_KING_DRED = 27483, - NPC_THARON_JA = 26632 + NPC_TROLLGORE = 26630, + NPC_NOVOS = 26631, + NPC_KING_DRED = 27483, + NPC_THARON_JA = 26632, + NPC_CRYSTAL_CHANNEL_TARGET = 26712, + NPC_CRYSTAL_HANDLER = 26627 }; enum GameObjects { - GO_NOVOS_CRYSTAL_1 = 189299, - GO_NOVOS_CRYSTAL_2 = 189300, - GO_NOVOS_CRYSTAL_3 = 189301, - GO_NOVOS_CRYSTAL_4 = 189302 + GO_NOVOS_CRYSTAL_1 = 189299, + GO_NOVOS_CRYSTAL_2 = 189300, + GO_NOVOS_CRYSTAL_3 = 189301, + GO_NOVOS_CRYSTAL_4 = 189302 +}; +enum Achievements +{ + ACM_CRITERIA_OH_NOVOS = 7361 }; class instance_drak_tharon : public InstanceMapScript @@ -52,17 +59,22 @@ public: { instance_drak_tharon_InstanceScript(Map* map) : InstanceScript(map) {} - uint8 uiDredAchievCounter; + uint8 dredAchievCounter; - uint64 uiTrollgore; - uint64 uiNovos; - uint64 uiDred; - uint64 uiTharonJa; + uint64 trollgoreGUID; + uint64 novosGUID; + uint64 dredGUID; + uint64 tharonJaGUID; - uint64 uiNovosCrystal1; - uint64 uiNovosCrystal2; - uint64 uiNovosCrystal3; - uint64 uiNovosCrystal4; + uint64 novosCrystalGUID1; + uint64 novosCrystalGUID2; + uint64 novosCrystalGUID3; + uint64 novosCrystalGUID4; + + uint64 novosSummonerGUID1; + uint64 novosSummonerGUID2; + uint64 novosSummonerGUID3; + uint64 novosSummonerGUID4; uint16 m_auiEncounter[MAX_ENCOUNTER]; @@ -71,15 +83,23 @@ public: void Initialize() { memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - uiTrollgore = 0; - uiNovos = 0; - uiDred = 0; - uiTharonJa = 0; - uiNovosCrystal1 = 0; - uiNovosCrystal2 = 0; - uiNovosCrystal3 = 0; - uiNovosCrystal4 = 0; - uiDredAchievCounter = 0; + + dredAchievCounter = 0; + + trollgoreGUID = 0; + novosGUID = 0; + dredGUID = 0; + tharonJaGUID = 0; + + novosCrystalGUID1 = 0; + novosCrystalGUID2 = 0; + novosCrystalGUID3 = 0; + novosCrystalGUID4 = 0; + + novosSummonerGUID1 = 0; + novosSummonerGUID2 = 0; + novosSummonerGUID3 = 0; + novosSummonerGUID4 = 0; } bool IsEncounterInProgress() const @@ -96,16 +116,20 @@ public: switch (go->GetEntry()) { case GO_NOVOS_CRYSTAL_1: - uiNovosCrystal1 = go->GetGUID(); + novosCrystalGUID1 = go->GetGUID(); + go->SetGoState(GO_STATE_READY); break; case GO_NOVOS_CRYSTAL_2: - uiNovosCrystal2 = go->GetGUID(); + novosCrystalGUID2 = go->GetGUID(); + go->SetGoState(GO_STATE_READY); break; case GO_NOVOS_CRYSTAL_3: - uiNovosCrystal3 = go->GetGUID(); + novosCrystalGUID3 = go->GetGUID(); + go->SetGoState(GO_STATE_READY); break; case GO_NOVOS_CRYSTAL_4: - uiNovosCrystal4 = go->GetGUID(); + novosCrystalGUID4 = go->GetGUID(); + go->SetGoState(GO_STATE_READY); break; } } @@ -115,32 +139,55 @@ public: switch (creature->GetEntry()) { case NPC_TROLLGORE: - uiTrollgore = creature->GetGUID(); + trollgoreGUID = creature->GetGUID(); break; case NPC_NOVOS: - uiNovos = creature->GetGUID(); + novosGUID = creature->GetGUID(); break; case NPC_KING_DRED: - uiDred = creature->GetGUID(); + dredGUID = creature->GetGUID(); break; case NPC_THARON_JA: - uiTharonJa = creature->GetGUID(); + tharonJaGUID = creature->GetGUID(); + break; + case NPC_CRYSTAL_CHANNEL_TARGET: + InitializeNovosSummoner(creature); break; } } + void InitializeNovosSummoner(Creature* creature) + { + float x = creature->GetPositionX(); + float y = creature->GetPositionY(); + float z = creature->GetPositionZ(); + + if (x < -374.0f && x > -379.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f) + novosSummonerGUID1 = creature->GetGUID(); + else if (x < -379.0f && x > -385.0f && y > -820.0f && y < -815.0f && z < 60.0f && z > 58.0f) + novosSummonerGUID2 = creature->GetGUID(); + else if (x < -374.0f && x > -385.0f && y > -827.0f && y < -820.0f && z < 60.0f && z > 58.0f) + novosSummonerGUID3 = creature->GetGUID(); + else if (x < -338.0f && x > -344.0f && y > -727.0f && y < 721.0f && z < 30.0f && z > 26.0f) + novosSummonerGUID4 = creature->GetGUID(); + } + uint64 GetData64(uint32 identifier) const { switch (identifier) { - case DATA_TROLLGORE: return uiTrollgore; - case DATA_NOVOS: return uiNovos; - case DATA_DRED: return uiDred; - case DATA_THARON_JA: return uiTharonJa; - case DATA_NOVOS_CRYSTAL_1: return uiNovosCrystal1; - case DATA_NOVOS_CRYSTAL_2: return uiNovosCrystal2; - case DATA_NOVOS_CRYSTAL_3: return uiNovosCrystal3; - case DATA_NOVOS_CRYSTAL_4: return uiNovosCrystal4; + case DATA_TROLLGORE: return trollgoreGUID; + case DATA_NOVOS: return novosGUID; + case DATA_DRED: return dredGUID; + case DATA_THARON_JA: return tharonJaGUID; + case DATA_NOVOS_CRYSTAL_1: return novosCrystalGUID1; + case DATA_NOVOS_CRYSTAL_2: return novosCrystalGUID2; + case DATA_NOVOS_CRYSTAL_3: return novosCrystalGUID3; + case DATA_NOVOS_CRYSTAL_4: return novosCrystalGUID4; + case DATA_NOVOS_SUMMONER_1: return novosSummonerGUID1; + case DATA_NOVOS_SUMMONER_2: return novosSummonerGUID2; + case DATA_NOVOS_SUMMONER_3: return novosSummonerGUID3; + case DATA_NOVOS_SUMMONER_4: return novosSummonerGUID4; } return 0; @@ -164,7 +211,7 @@ public: break; case DATA_KING_DRED_ACHIEV: - uiDredAchievCounter = data; + dredAchievCounter = data; break; } @@ -182,7 +229,7 @@ public: case DATA_NOVOS_EVENT: return m_auiEncounter[1]; case DATA_DRED_EVENT: return m_auiEncounter[2]; case DATA_THARON_JA_EVENT: return m_auiEncounter[3]; - case DATA_KING_DRED_ACHIEV: return uiDredAchievCounter; + case DATA_KING_DRED_ACHIEV: return dredAchievCounter; } return 0; } @@ -199,6 +246,14 @@ public: return saveStream.str(); } + void OnUnitDeath(Unit* unit) + { + if (unit->GetEntry() == NPC_CRYSTAL_HANDLER) + if (novosGUID) + if (Creature* novos = instance->GetCreature(novosGUID)) + novos->AI()->DoAction(ACTION_CRYSTAL_HANDLER_DIED); + } + void Load(const char* in) { if (!in) diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 8b8e45432c8..05c756c757c 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -281,15 +281,6 @@ vmap.enableLOS = 1 vmap.enableHeight = 1 # -# vmap.ignoreSpellIds -# Description: These spells are ignored for LoS calculation. -# List of ids with delimiter ','. -# Example: "7720,1337" -# Default: "7720" - -vmap.ignoreSpellIds = "7720" - -# # vmap.petLOS # Description: Check line of sight for pets, to avoid them attacking through walls. # Default: 1 - (Enabled, each pet attack will be checked for line of sight) |