diff options
Diffstat (limited to 'src')
198 files changed, 3230 insertions, 2581 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp index da55a073679..943919451a9 100644 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -23,6 +23,10 @@ #include "ObjectAccessor.h" #include "Player.h" +///////////////// +// AggressorAI +///////////////// + int AggressorAI::Permissible(const Creature* creature) { // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight @@ -40,26 +44,9 @@ void AggressorAI::UpdateAI(uint32 /*diff*/) DoMeleeAttackIfReady(); } -// some day we will delete these useless things -int CombatAI::Permissible(const Creature* /*creature*/) -{ - return PERMIT_BASE_NO; -} - -int ArcherAI::Permissible(const Creature* /*creature*/) -{ - return PERMIT_BASE_NO; -} - -int TurretAI::Permissible(const Creature* /*creature*/) -{ - return PERMIT_BASE_NO; -} - -int VehicleAI::Permissible(const Creature* /*creature*/) -{ - return PERMIT_BASE_NO; -} +///////////////// +// CombatAI +///////////////// void CombatAI::InitializeAI() { @@ -118,7 +105,7 @@ void CombatAI::SpellInterrupted(uint32 spellId, uint32 unTimeMs) } ///////////////// -//CasterAI +// CasterAI ///////////////// void CasterAI::InitializeAI() @@ -182,7 +169,7 @@ void CasterAI::UpdateAI(uint32 diff) } ////////////// -//ArcherAI +// ArcherAI ////////////// ArcherAI::ArcherAI(Creature* c) : CreatureAI(c) @@ -231,7 +218,7 @@ void ArcherAI::UpdateAI(uint32 /*diff*/) } ////////////// -//TurretAI +// TurretAI ////////////// TurretAI::TurretAI(Creature* c) : CreatureAI(c) @@ -269,17 +256,17 @@ void TurretAI::UpdateAI(uint32 /*diff*/) } ////////////// -//VehicleAI +// VehicleAI ////////////// -VehicleAI::VehicleAI(Creature* c) : CreatureAI(c), m_IsVehicleInUse(false), m_ConditionsTimer(VEHICLE_CONDITION_CHECK_TIME) +VehicleAI::VehicleAI(Creature* creature) : CreatureAI(creature), m_ConditionsTimer(VEHICLE_CONDITION_CHECK_TIME) { LoadConditions(); m_DoDismiss = false; m_DismissTimer = VEHICLE_DISMISS_TIME; } -//NOTE: VehicleAI::UpdateAI runs even while the vehicle is mounted +// NOTE: VehicleAI::UpdateAI runs even while the vehicle is mounted void VehicleAI::UpdateAI(uint32 diff) { CheckConditions(diff); @@ -289,7 +276,6 @@ void VehicleAI::UpdateAI(uint32 diff) if (m_DismissTimer < diff) { m_DoDismiss = false; - me->SetVisible(false); me->DespawnOrUnsummon(); } else @@ -297,24 +283,16 @@ void VehicleAI::UpdateAI(uint32 diff) } } -void VehicleAI::Reset() -{ - me->SetVisible(true); -} - void VehicleAI::OnCharmed(bool apply) { - if (m_IsVehicleInUse && !apply && !conditions.empty())//was used and has conditions + if (!me->GetVehicleKit()->IsVehicleInUse() && !apply && !conditions.empty()) // was used and has conditions { - m_DoDismiss = true;//needs reset - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + m_DoDismiss = true; // needs reset } else if (apply) - m_DoDismiss = false;//in use again + m_DoDismiss = false; // in use again - m_DismissTimer = VEHICLE_DISMISS_TIME;//reset timer - m_IsVehicleInUse = apply; + m_DismissTimer = VEHICLE_DISMISS_TIME; // reset timer } void VehicleAI::LoadConditions() @@ -324,7 +302,7 @@ void VehicleAI::LoadConditions() TC_LOG_DEBUG("condition", "VehicleAI::LoadConditions: loaded %u conditions", uint32(conditions.size())); } -void VehicleAI::CheckConditions(const uint32 diff) +void VehicleAI::CheckConditions(uint32 diff) { if (m_ConditionsTimer < diff) { @@ -339,7 +317,7 @@ void VehicleAI::CheckConditions(const uint32 diff) if (!sConditionMgr->IsObjectMeetToConditions(player, me, conditions)) { player->ExitVehicle(); - return;//check other pessanger in next tick + return; // check other pessanger in next tick } } } diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h index 10716627e85..f73daa2d720 100644 --- a/src/server/game/AI/CoreAI/CombatAI.h +++ b/src/server/game/AI/CoreAI/CombatAI.h @@ -47,7 +47,9 @@ class CombatAI : public CreatureAI void JustDied(Unit* killer); void UpdateAI(uint32 diff); void SpellInterrupted(uint32 spellId, uint32 unTimeMs); - static int Permissible(const Creature*); + + static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + protected: EventMap events; SpellVct spells; @@ -72,7 +74,8 @@ struct ArcherAI : public CreatureAI void AttackStart(Unit* who); void UpdateAI(uint32 diff); - static int Permissible(Creature const*); + static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + protected: float m_minRange; }; @@ -85,29 +88,30 @@ struct TurretAI : public CreatureAI void AttackStart(Unit* who); void UpdateAI(uint32 diff); - static int Permissible(Creature const*); + static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + protected: float m_minRange; }; #define VEHICLE_CONDITION_CHECK_TIME 1000 #define VEHICLE_DISMISS_TIME 5000 + struct VehicleAI : public CreatureAI { public: - explicit VehicleAI(Creature* c); + explicit VehicleAI(Creature* creature); void UpdateAI(uint32 diff); - static int Permissible(Creature const*); - void Reset(); void MoveInLineOfSight(Unit*) { } void AttackStart(Unit*) { } void OnCharmed(bool apply); + static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + private: - bool m_IsVehicleInUse; void LoadConditions(); - void CheckConditions(const uint32 diff); + void CheckConditions(uint32 diff); ConditionList conditions; uint32 m_ConditionsTimer; bool m_DoDismiss; diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index d6aa30dff23..a203aeb6b97 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -439,6 +439,8 @@ void SmartAI::EnterEvadeMode() me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); me->ResetPlayerDamageReq(); + me->SetLastDamagedTime(0); + GetScript()->ProcessEventsFor(SMART_EVENT_EVADE);//must be after aura clear so we can cast spells from db SetRun(mRun); @@ -574,7 +576,7 @@ void SmartAI::JustReachedHome() GetScript()->ProcessEventsFor(SMART_EVENT_REACHED_HOME); if (!UpdateVictim() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE && me->GetWaypointPath()) - me->ToCreature()->GetMotionMaster()->MovePath(me->GetWaypointPath(), true); + me->GetMotionMaster()->MovePath(me->GetWaypointPath(), true); } mJustReset = false; @@ -904,12 +906,6 @@ bool SmartGameObjectAI::QuestReward(Player* player, Quest const* quest, uint32 o return false; } -// Called when the dialog status between a player and the gameobject is requested. -uint32 SmartGameObjectAI::GetDialogStatus(Player* /*player*/) -{ - return DIALOG_STATUS_SCRIPTED_NO_STATUS; -} - // Called when the gameobject is destroyed (destructible buildings only). void SmartGameObjectAI::Destroyed(Player* player, uint32 eventId) { diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 83f2ae0b4d9..dcf64b657f8 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -236,7 +236,7 @@ class SmartAI : public CreatureAI class SmartGameObjectAI : public GameObjectAI { public: - SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) { } + SmartGameObjectAI(GameObject* g) : GameObjectAI(g) { } ~SmartGameObjectAI() { } void UpdateAI(uint32 diff); @@ -250,7 +250,6 @@ class SmartGameObjectAI : public GameObjectAI bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/); bool QuestAccept(Player* player, Quest const* quest); bool QuestReward(Player* player, Quest const* quest, uint32 opt); - uint32 GetDialogStatus(Player* /*player*/); void Destroyed(Player* player, uint32 eventId); void SetData(uint32 id, uint32 value); void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker); @@ -258,8 +257,7 @@ class SmartGameObjectAI : public GameObjectAI void OnStateChanged(uint32 state, Unit* unit); void EventInform(uint32 eventId); - protected: - GameObject* const go; + private: SmartScript mScript; }; #endif diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 5efab2214b6..bd51fe0a85b 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2551,7 +2551,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* { ObjectListMap::iterator itr = mTargetStorage->find(e.target.stored.id); if (itr != mTargetStorage->end()) - l->assign(itr->second->begin(), itr->second->end()); + { + ObjectList* objectList = itr->second->GetObjectList(); + l->assign(objectList->begin(), objectList->end()); + } return l; } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 56b3674bd73..2e1068d1bff 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -99,13 +99,13 @@ class SmartScript if (mTargetStorage->find(id) != mTargetStorage->end()) { // check if already stored - if ((*mTargetStorage)[id] == targets) + if ((*mTargetStorage)[id]->Equals(targets)) return; delete (*mTargetStorage)[id]; } - (*mTargetStorage)[id] = targets; + (*mTargetStorage)[id] = new ObjectGuidList(targets, GetBaseObject()); } bool IsSmart(Creature* c = NULL) @@ -141,7 +141,7 @@ class SmartScript { ObjectListMap::iterator itr = mTargetStorage->find(id); if (itr != mTargetStorage->end()) - return (*itr).second; + return (*itr).second->GetObjectList(); return NULL; } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 543cb9235d3..d912de2a72c 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -766,6 +766,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); return false; } + if (!IsMinMaxValid(e, e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax)) return false; break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index be074c2939f..265df8e2ac4 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -52,9 +52,12 @@ enum SMART_EVENT_PHASE SMART_EVENT_PHASE_4 = 4, SMART_EVENT_PHASE_5 = 5, SMART_EVENT_PHASE_6 = 6, - SMART_EVENT_PHASE_MAX = 7, + SMART_EVENT_PHASE_7 = 7, + SMART_EVENT_PHASE_8 = 8, + SMART_EVENT_PHASE_9 = 9, + SMART_EVENT_PHASE_MAX = 10, - SMART_EVENT_PHASE_COUNT = 6 + SMART_EVENT_PHASE_COUNT = 9 }; enum SMART_EVENT_PHASE_BITS @@ -66,7 +69,10 @@ enum SMART_EVENT_PHASE_BITS SMART_EVENT_PHASE_4_BIT = 8, SMART_EVENT_PHASE_5_BIT = 16, SMART_EVENT_PHASE_6_BIT = 32, - SMART_EVENT_PHASE_ALL = SMART_EVENT_PHASE_1_BIT + SMART_EVENT_PHASE_2_BIT + SMART_EVENT_PHASE_3_BIT + SMART_EVENT_PHASE_4_BIT + SMART_EVENT_PHASE_5_BIT + SMART_EVENT_PHASE_6_BIT + SMART_EVENT_PHASE_7_BIT = 64, + SMART_EVENT_PHASE_8_BIT = 128, + SMART_EVENT_PHASE_9_BIT = 256, + SMART_EVENT_PHASE_ALL = SMART_EVENT_PHASE_1_BIT + SMART_EVENT_PHASE_2_BIT + SMART_EVENT_PHASE_3_BIT + SMART_EVENT_PHASE_4_BIT + SMART_EVENT_PHASE_5_BIT + SMART_EVENT_PHASE_6_BIT + SMART_EVENT_PHASE_7_BIT + SMART_EVENT_PHASE_8_BIT + SMART_EVENT_PHASE_9_BIT }; const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] = @@ -76,7 +82,10 @@ const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] = {SMART_EVENT_PHASE_3, SMART_EVENT_PHASE_3_BIT }, {SMART_EVENT_PHASE_4, SMART_EVENT_PHASE_4_BIT }, {SMART_EVENT_PHASE_5, SMART_EVENT_PHASE_5_BIT }, - {SMART_EVENT_PHASE_6, SMART_EVENT_PHASE_6_BIT } + {SMART_EVENT_PHASE_6, SMART_EVENT_PHASE_6_BIT }, + {SMART_EVENT_PHASE_7, SMART_EVENT_PHASE_7_BIT }, + {SMART_EVENT_PHASE_8, SMART_EVENT_PHASE_8_BIT }, + {SMART_EVENT_PHASE_9, SMART_EVENT_PHASE_9_BIT } }; enum SMART_EVENT @@ -1321,7 +1330,58 @@ struct SmartScriptHolder typedef UNORDERED_MAP<uint32, WayPoint*> WPPath; typedef std::list<WorldObject*> ObjectList; -typedef UNORDERED_MAP<uint32, ObjectList*> ObjectListMap; +typedef std::list<uint64> GuidList; +class ObjectGuidList +{ + ObjectList* m_objectList; + GuidList* m_guidList; + WorldObject* m_baseObject; + +public: + ObjectGuidList(ObjectList* objectList, WorldObject* baseObject) + { + ASSERT(objectList != NULL); + m_objectList = objectList; + m_baseObject = baseObject; + m_guidList = new GuidList(); + + for (ObjectList::iterator itr = objectList->begin(); itr != objectList->end(); ++itr) + { + m_guidList->push_back((*itr)->GetGUID()); + } + } + + ObjectList* GetObjectList() + { + if (m_baseObject) + { + //sanitize list using m_guidList + m_objectList->clear(); + + for (GuidList::iterator itr = m_guidList->begin(); itr != m_guidList->end(); ++itr) + { + if (WorldObject* obj = ObjectAccessor::GetWorldObject(*m_baseObject, *itr)) + m_objectList->push_back(obj); + else + TC_LOG_DEBUG("scripts.ai", "SmartScript::mTargetStorage stores a guid to an invalid object: " UI64FMTD, *itr); + } + } + + return m_objectList; + } + + bool Equals(ObjectList* objectList) + { + return m_objectList == objectList; + } + + ~ObjectGuidList() + { + delete m_objectList; + delete m_guidList; + } +}; +typedef UNORDERED_MAP<uint32, ObjectGuidList*> ObjectListMap; class SmartWaypointMgr { diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 2a10da29c20..dc5a2768668 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -678,6 +678,9 @@ enum RBACPermissions RBAC_PERM_COMMAND_WP_UNLOAD = 772, RBAC_PERM_COMMAND_WP_RELOAD = 773, RBAC_PERM_COMMAND_WP_SHOW = 774, + RBAC_PERM_COMMAND_MODIFY_CURRENCY = 775, // only 4.3.4 + RBAC_PERM_COMMAND_DEBUG_PHASE = 776, // only 4.3.4 + RBAC_PERM_COMMAND_MAILBOX = 777, // custom permissions 1000+ RBAC_PERM_MAX diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp index 300bf44c8a7..8aa58f0ac4b 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.cpp +++ b/src/server/game/Battlefield/BattlefieldMgr.cpp @@ -16,125 +16,130 @@ */ #include "BattlefieldMgr.h" -#include "Zones/BattlefieldWG.h" +#include "BattlefieldWG.h" #include "ObjectMgr.h" #include "Player.h" BattlefieldMgr::BattlefieldMgr() { - m_UpdateTimer = 0; - //TC_LOG_DEBUG("bg.battlefield", "Instantiating BattlefieldMgr"); + _updateTimer = 0; } BattlefieldMgr::~BattlefieldMgr() { - //TC_LOG_DEBUG("bg.battlefield", "Deleting BattlefieldMgr"); - for (BattlefieldSet::iterator itr = m_BattlefieldSet.begin(); itr != m_BattlefieldSet.end(); ++itr) + for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr) delete *itr; + + _battlefieldMap.clear(); } void BattlefieldMgr::InitBattlefield() { - Battlefield* pBf = new BattlefieldWG; + Battlefield* wg = new BattlefieldWG(); // respawn, init variables - if (!pBf->SetupBattlefield()) + if (!wg->SetupBattlefield()) { - TC_LOG_INFO("misc", "Battlefield : Wintergrasp init failed."); - delete pBf; + TC_LOG_INFO("bg.battlefield", "Battlefield: Wintergrasp init failed."); + delete wg; } else { - m_BattlefieldSet.push_back(pBf); - TC_LOG_INFO("misc", "Battlefield : Wintergrasp successfully initiated."); + _battlefieldSet.push_back(wg); + TC_LOG_INFO("bg.battlefield", "Battlefield: Wintergrasp successfully initiated."); } - /* For Cataclysm: Tol Barad - pBf = new BattlefieldTB; - // respawn, init variables - if (!pBf->SetupBattlefield()) - { - TC_LOG_DEBUG("bg.battlefield", "Battlefield : Tol Barad init failed."); - delete pBf; - } - else - { - m_BattlefieldSet.push_back(pBf); - TC_LOG_DEBUG("bg.battlefield", "Battlefield : Tol Barad successfully initiated."); - } */ + /* + For Cataclysm: Tol Barad + Battlefield* tb = new BattlefieldTB; + // respawn, init variables + if (!tb->SetupBattlefield()) + { + TC_LOG_DEBUG("bg.battlefield", "Battlefield: Tol Barad init failed."); + delete tb; + } + else + { + _battlefieldSet.push_back(tb); + TC_LOG_DEBUG("bg.battlefield", "Battlefield: Tol Barad successfully initiated."); + } + */ } -void BattlefieldMgr::AddZone(uint32 zoneid, Battlefield *handle) +void BattlefieldMgr::AddZone(uint32 zoneId, Battlefield* bf) { - m_BattlefieldMap[zoneid] = handle; + _battlefieldMap[zoneId] = bf; } -void BattlefieldMgr::HandlePlayerEnterZone(Player* player, uint32 zoneid) +void BattlefieldMgr::HandlePlayerEnterZone(Player* player, uint32 zoneId) { - BattlefieldMap::iterator itr = m_BattlefieldMap.find(zoneid); - if (itr == m_BattlefieldMap.end()) + BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); + if (itr == _battlefieldMap.end()) return; Battlefield* bf = itr->second; - if (bf->HasPlayer(player) || !bf->IsEnabled()) + if (!bf->IsEnabled() || bf->HasPlayer(player)) return; - bf->HandlePlayerEnterZone(player, zoneid); - TC_LOG_DEBUG("bg.battlefield", "Player %u entered outdoorpvp id %u", player->GetGUIDLow(), bf->GetTypeId()); + bf->HandlePlayerEnterZone(player, zoneId); + TC_LOG_DEBUG("bg.battlefield", "Player %u entered battlefield id %u", player->GetGUIDLow(), bf->GetTypeId()); } -void BattlefieldMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneid) +void BattlefieldMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneId) { - BattlefieldMap::iterator itr = m_BattlefieldMap.find(zoneid); - if (itr == m_BattlefieldMap.end()) + BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); + if (itr == _battlefieldMap.end()) return; // teleport: remove once in removefromworld, once in updatezone if (!itr->second->HasPlayer(player)) return; - itr->second->HandlePlayerLeaveZone(player, zoneid); - TC_LOG_DEBUG("bg.battlefield", "Player %u left outdoorpvp id %u", player->GetGUIDLow(), itr->second->GetTypeId()); + + itr->second->HandlePlayerLeaveZone(player, zoneId); + TC_LOG_DEBUG("bg.battlefield", "Player %u left battlefield id %u", player->GetGUIDLow(), itr->second->GetTypeId()); } -Battlefield *BattlefieldMgr::GetBattlefieldToZoneId(uint32 zoneid) +Battlefield* BattlefieldMgr::GetBattlefieldToZoneId(uint32 zoneId) { - BattlefieldMap::iterator itr = m_BattlefieldMap.find(zoneid); - if (itr == m_BattlefieldMap.end()) + BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); + if (itr == _battlefieldMap.end()) { // no handle for this zone, return return NULL; } + if (!itr->second->IsEnabled()) return NULL; + return itr->second; } -Battlefield *BattlefieldMgr::GetBattlefieldByBattleId(uint32 battleid) +Battlefield* BattlefieldMgr::GetBattlefieldByBattleId(uint32 battleId) { - for (BattlefieldSet::iterator itr = m_BattlefieldSet.begin(); itr != m_BattlefieldSet.end(); ++itr) + for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr) { - if ((*itr)->GetBattleId() == battleid) - return (*itr); + if ((*itr)->GetBattleId() == battleId) + return *itr; } return NULL; } +ZoneScript* BattlefieldMgr::GetZoneScript(uint32 zoneId) +{ + BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId); + if (itr != _battlefieldMap.end()) + return itr->second; + + return NULL; +} + void BattlefieldMgr::Update(uint32 diff) { - m_UpdateTimer += diff; - if (m_UpdateTimer > BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL) + _updateTimer += diff; + if (_updateTimer > BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL) { - for (BattlefieldSet::iterator itr = m_BattlefieldSet.begin(); itr != m_BattlefieldSet.end(); ++itr) + for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr) if ((*itr)->IsEnabled()) - (*itr)->Update(m_UpdateTimer); - m_UpdateTimer = 0; + (*itr)->Update(_updateTimer); + _updateTimer = 0; } } - -ZoneScript* BattlefieldMgr::GetZoneScript(uint32 zoneId) -{ - BattlefieldMap::iterator itr = m_BattlefieldMap.find(zoneId); - if (itr != m_BattlefieldMap.end()) - return itr->second; - else - return NULL; -} diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h index 74ef4a4b2bf..bb8a076d5d0 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.h +++ b/src/server/game/Battlefield/BattlefieldMgr.h @@ -19,60 +19,51 @@ #define BATTLEFIELD_MGR_H_ #include "Battlefield.h" -#include "ace/Singleton.h" +#include <ace/Singleton.h> class Player; -class GameObject; -class Creature; class ZoneScript; -struct GossipMenuItems; // class to handle player enter / leave / areatrigger / GO use events class BattlefieldMgr { - public: - // ctor - BattlefieldMgr(); - // dtor - ~BattlefieldMgr(); + public: + // ctor + BattlefieldMgr(); + // dtor + ~BattlefieldMgr(); - // create battlefield events - void InitBattlefield(); - // called when a player enters an battlefield area - void HandlePlayerEnterZone(Player* player, uint32 areaflag); - // called when player leaves an battlefield area - void HandlePlayerLeaveZone(Player* player, uint32 areaflag); - // called when player resurrects - void HandlePlayerResurrects(Player* player, uint32 areaflag); - // return assigned battlefield - Battlefield* GetBattlefieldToZoneId(uint32 zoneid); - Battlefield* GetBattlefieldByBattleId(uint32 battleid); + // create battlefield events + void InitBattlefield(); - ZoneScript* GetZoneScript(uint32 zoneId); + // called when a player enters an battlefield area + void HandlePlayerEnterZone(Player* player, uint32 zoneId); + // called when player leaves an battlefield area + void HandlePlayerLeaveZone(Player* player, uint32 zoneId); - void AddZone(uint32 zoneid, Battlefield * handle); + // return assigned battlefield + Battlefield* GetBattlefieldToZoneId(uint32 zoneId); + Battlefield* GetBattlefieldByBattleId(uint32 battleId); - void Update(uint32 diff); + ZoneScript* GetZoneScript(uint32 zoneId); - void HandleGossipOption(Player* player, uint64 guid, uint32 gossipid); + void AddZone(uint32 zoneId, Battlefield* bf); - bool CanTalkTo(Player* player, Creature* creature, GossipMenuItems gso); + void Update(uint32 diff); - void HandleDropFlag(Player* player, uint32 spellId); - - typedef std::vector < Battlefield * >BattlefieldSet; - typedef std::map < uint32 /* zoneid */, Battlefield * >BattlefieldMap; - private: - // contains all initiated battlefield events - // used when initing / cleaning up - BattlefieldSet m_BattlefieldSet; - // maps the zone ids to an battlefield event - // used in player event handling - BattlefieldMap m_BattlefieldMap; - // update interval - uint32 m_UpdateTimer; + private: + typedef std::vector<Battlefield*> BattlefieldSet; + typedef std::map<uint32 /*zoneId*/, Battlefield*> BattlefieldMap; + // contains all initiated battlefield events + // used when initing / cleaning up + BattlefieldSet _battlefieldSet; + // maps the zone ids to an battlefield event + // used in player event handling + BattlefieldMap _battlefieldMap; + // update interval + uint32 _updateTimer; }; #define sBattlefieldMgr ACE_Singleton<BattlefieldMgr, ACE_Null_Mutex>::instance() -#endif +#endif // BATTLEFIELD_MGR_H_ diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index b82b5ae3a9c..7ec5a09508a 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -30,14 +30,6 @@ #include "Vehicle.h" #include "WorldSession.h" -enum WGVehicles -{ - NPC_WG_SEIGE_ENGINE_ALLIANCE = 28312, - NPC_WG_SEIGE_ENGINE_HORDE = 32627, - NPC_WG_DEMOLISHER = 28094, - NPC_WG_CATAPULT = 27881 -}; - BattlefieldWG::~BattlefieldWG() { for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) @@ -192,7 +184,7 @@ bool BattlefieldWG::SetupBattlefield() if (GameObject* go = SpawnGameObject(WGPortalDefenderData[i].entry, WGPortalDefenderData[i].x, WGPortalDefenderData[i].y, WGPortalDefenderData[i].z, WGPortalDefenderData[i].o)) { DefenderPortalList.insert(go->GetGUID()); - go->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[GetDefenderTeam()]); + go->SetFaction(WintergraspFaction[GetDefenderTeam()]); } } @@ -222,7 +214,7 @@ void BattlefieldWG::OnBattleStart() if (GameObject* relic = SpawnGameObject(GO_WINTERGRASP_TITAN_S_RELIC, 5440.0f, 2840.8f, 430.43f, 0)) { // Update faction of relic, only attacker can click on - relic->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[GetAttackerTeam()]); + relic->SetFaction(WintergraspFaction[GetAttackerTeam()]); // Set in use (not allow to click on before last door is broken) relic->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); m_titansRelicGUID = relic->GetGUID(); @@ -360,7 +352,7 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer) // Update portal defender faction for (GuidSet::const_iterator itr = DefenderPortalList.begin(); itr != DefenderPortalList.end(); ++itr) if (GameObject* portal = GetGameObject(*itr)) - portal->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[GetDefenderTeam()]); + portal->SetFaction(WintergraspFaction[GetDefenderTeam()]); // Saving data for (GameObjectBuilding::const_iterator itr = BuildingsInZone.begin(); itr != BuildingsInZone.end(); ++itr) @@ -813,6 +805,9 @@ uint32 BattlefieldWG::GetData(uint32 data) const // Graveyards and Workshops are controlled by the same team. if (BfGraveyard const* graveyard = GetGraveyardById(GetSpiritGraveyardId(data))) return graveyard->GetControlTeamId(); + break; + default: + break; } return Battlefield::GetData(data); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index b349aa80318..c54d8915a33 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -1133,7 +1133,7 @@ struct BfWGGameObjectBuilding m_WG->SendUpdateWorldState(m_WorldState, m_State); } UpdateCreatureAndGo(); - build->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[m_Team]); + build->SetFaction(WintergraspFaction[m_Team]); } } diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 58aba1429af..3fcfab81c73 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -976,6 +976,8 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac player->SpawnCorpseBones(); } } + else // try to resurrect the offline player. If he is alive nothing will happen + sObjectAccessor->ConvertCorpseForPlayer(guid); RemovePlayer(player, guid, team); // BG subclass specific code diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h index c151bbd4b8e..cc86cb538ea 100644 --- a/src/server/game/Chat/ChatLink.h +++ b/src/server/game/Chat/ChatLink.h @@ -57,7 +57,7 @@ class ItemChatLink : public ChatLink { public: ItemChatLink() : ChatLink(), _item(NULL), _suffix(NULL), _property(NULL) - { + { memset(_data, 0, sizeof(_data)); } virtual bool Initialize(std::istringstream& iss); @@ -102,7 +102,7 @@ class AchievementChatLink : public ChatLink { public: AchievementChatLink() : ChatLink(), _guid(0), _achievement(NULL) - { + { memset(_data, 0, sizeof(_data)); } virtual bool Initialize(std::istringstream& iss); diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 648b2a435d7..a4b3ded80e5 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -482,7 +482,8 @@ void LoadDBCStores(const std::string& dataPath) continue; for (int x = 0; x < MAX_DIFFICULTY; ++x) - sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); + if (newEntry.SpellID[x]) + sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); } // create talent spells set diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index d5ccaab27da..e4bdc2d58fe 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -182,8 +182,8 @@ void Creature::AddToWorld() ///- Register the creature for guid lookup if (!IsInWorld()) { - if (m_zoneScript) - m_zoneScript->OnCreatureCreate(this); + if (GetZoneScript()) + GetZoneScript()->OnCreatureCreate(this); sObjectAccessor->AddObject(this); Unit::AddToWorld(); SearchFormation(); @@ -197,8 +197,8 @@ void Creature::RemoveFromWorld() { if (IsInWorld()) { - if (m_zoneScript) - m_zoneScript->OnCreatureRemove(this); + if (GetZoneScript()) + GetZoneScript()->OnCreatureRemove(this); if (m_formation) sFormationMgr->RemoveCreatureFromGroup(m_formation, this); Unit::RemoveFromWorld(); @@ -312,7 +312,7 @@ bool Creature::InitEntry(uint32 entry, uint32 /*team*/, const CreatureData* data CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID); if (!minfo) // Cancel load if no model defined { - TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has no model defined in table `creature_template`, can't load. ", entry); + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid model %u defined in table `creature_template`, can't load.", entry, displayID); return false; } @@ -367,7 +367,6 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) if (!GetCreatureAddon()) SetSheath(SHEATH_STATE_MELEE); - SelectLevel(GetCreatureTemplate()); if (team == HORDE) setFaction(cInfo->faction_H); else @@ -381,10 +380,6 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) else SetUInt32Value(UNIT_NPC_FLAGS, npcflag); - SetAttackTime(BASE_ATTACK, cInfo->baseattacktime); - SetAttackTime(OFF_ATTACK, cInfo->baseattacktime); - SetAttackTime(RANGED_ATTACK, cInfo->rangeattacktime); - SetUInt32Value(UNIT_FIELD_FLAGS, unit_flags); SetUInt32Value(UNIT_FIELD_FLAGS_2, cInfo->unit_flags2); @@ -392,6 +387,12 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + SetAttackTime(BASE_ATTACK, cInfo->baseattacktime); + SetAttackTime(OFF_ATTACK, cInfo->baseattacktime); + SetAttackTime(RANGED_ATTACK, cInfo->rangeattacktime); + + SelectLevel(); + SetMeleeDamageSchool(SpellSchools(cInfo->dmgschool)); CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(getLevel(), cInfo->unit_class); float armor = (float)stats->GenerateArmor(cInfo); /// @todo Why is this treated as uint32 when it's a float? @@ -1038,22 +1039,24 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) WorldDatabase.CommitTransaction(trans); } -void Creature::SelectLevel(const CreatureTemplate* cinfo) +void Creature::SelectLevel() { - uint32 rank = IsPet()? 0 : cinfo->rank; + CreatureTemplate const* cInfo = GetCreatureTemplate(); + + uint32 rank = IsPet() ? 0 : cInfo->rank; // level - uint8 minlevel = std::min(cinfo->maxlevel, cinfo->minlevel); - uint8 maxlevel = std::max(cinfo->maxlevel, cinfo->minlevel); + uint8 minlevel = std::min(cInfo->maxlevel, cInfo->minlevel); + uint8 maxlevel = std::max(cInfo->maxlevel, cInfo->minlevel); uint8 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel); SetLevel(level); - CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cinfo->unit_class); + CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cInfo->unit_class); // health float healthmod = _GetHealthMod(rank); - uint32 basehp = stats->GenerateHealth(cinfo); + uint32 basehp = stats->GenerateHealth(cInfo); uint32 health = uint32(basehp * healthmod); SetCreateHealth(health); @@ -1062,10 +1065,10 @@ void Creature::SelectLevel(const CreatureTemplate* cinfo) ResetPlayerDamageReq(); // mana - uint32 mana = stats->GenerateMana(cinfo); + uint32 mana = stats->GenerateMana(cInfo); SetCreateMana(mana); - SetMaxPower(POWER_MANA, mana); //MAX Mana + SetMaxPower(POWER_MANA, mana); // MAX Mana SetPower(POWER_MANA, mana); /// @todo set UNIT_FIELD_POWER*, for some creature class case (energy, etc) @@ -1073,19 +1076,24 @@ void Creature::SelectLevel(const CreatureTemplate* cinfo) SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health); SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana); - //damage + // damage + + float basedamage = stats->GenerateBaseDamage(cInfo); - float basedamage = stats->GenerateBaseDamage(cinfo); + float weaponBaseMinDamage = basedamage; + float weaponBaseMaxDamage = basedamage * 1.5; - SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, ((basedamage + (stats->AttackPower / 14)) * cinfo->dmg_multiplier) * (cinfo->baseattacktime / 1000)); - SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (((basedamage * 1.5) + (stats->AttackPower / 14)) * cinfo->dmg_multiplier) * (cinfo->baseattacktime / 1000)); - SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, (basedamage + (stats->RangedAttackPower / 14)) * (cinfo->rangeattacktime / 1000)); - SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, ((basedamage * 1.5) + (stats->RangedAttackPower / 14)) * (cinfo->rangeattacktime / 1000)); + SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, weaponBaseMinDamage); + SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, weaponBaseMaxDamage); - float damagemod = 1.0f;//_GetDamageMod(rank); + SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, weaponBaseMinDamage); + SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, weaponBaseMaxDamage); - SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower * damagemod); + SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, weaponBaseMinDamage); + SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, weaponBaseMaxDamage); + SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower); + SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower); } float Creature::_GetHealthMod(int32 Rank) @@ -1154,9 +1162,9 @@ float Creature::GetSpellDamageMod(int32 Rank) const bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData* data) { SetZoneScript(); - if (m_zoneScript && data) + if (GetZoneScript() && data) { - Entry = m_zoneScript->GetCreatureEntry(guidlow, data); + Entry = GetZoneScript()->GetCreatureEntry(guidlow, data); if (!Entry) return false; } @@ -1258,6 +1266,12 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap) return true; } +void Creature::SetCanDualWield(bool value) +{ + Unit::SetCanDualWield(value); + UpdateDamagePhysical(OFF_ATTACK); +} + void Creature::LoadEquipment(int8 id, bool force /*= true*/) { if (id == 0) @@ -1517,8 +1531,7 @@ void Creature::Respawn(bool force) if (m_originalEntry != GetEntry()) UpdateEntry(m_originalEntry); - CreatureTemplate const* cinfo = GetCreatureTemplate(); - SelectLevel(cinfo); + SelectLevel(); setDeathState(JUST_RESPAWNED); @@ -1965,7 +1978,7 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const if (IsAIEnabled && !AI()->CanAIAttack(victim)) return false; - if (sMapStore.LookupEntry(GetMapId())->IsDungeon()) + if (GetMap()->IsDungeon()) return true; //Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick. @@ -2427,7 +2440,7 @@ void Creature::SetPosition(float x, float y, float z, float o) return; } - GetMap()->CreatureRelocation(ToCreature(), x, y, z, o); + GetMap()->CreatureRelocation(this, x, y, z, o); if (IsVehicle()) GetVehicleKit()->RelocatePassengers(); } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 2f78d29a968..737e3072091 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -173,11 +173,6 @@ struct CreatureTemplate // Benchmarked: Faster than std::map (insert/find) typedef UNORDERED_MAP<uint32, CreatureTemplate> CreatureTemplateContainer; -// Represents max amount of expansions. -/// @todo: Add MAX_EXPANSION constant. -#define MAX_CREATURE_BASE_HP 3 -#define MAX_CREATURE_BASE_DAMAGE 3 - // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform #if defined(__GNUC__) #pragma pack(1) @@ -188,12 +183,12 @@ typedef UNORDERED_MAP<uint32, CreatureTemplate> CreatureTemplateContainer; // Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage). struct CreatureBaseStats { - uint32 BaseHealth[MAX_CREATURE_BASE_HP]; + uint32 BaseHealth[MAX_EXPANSIONS]; uint32 BaseMana; uint32 BaseArmor; uint32 AttackPower; uint32 RangedAttackPower; - float BaseDamage[MAX_CREATURE_BASE_DAMAGE]; + float BaseDamage[MAX_EXPANSIONS]; // Helpers @@ -444,7 +439,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject bool Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData* data = NULL); bool LoadCreaturesAddon(bool reload = false); - void SelectLevel(const CreatureTemplate* cinfo); + void SelectLevel(); void LoadEquipment(int8 id = 1, bool force = false); uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; } @@ -521,8 +516,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void UpdateMaxHealth(); void UpdateMaxPower(Powers power); void UpdateAttackPowerAndDamage(bool ranged = false); - void UpdateDamagePhysical(WeaponAttackType attType); + void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) OVERRIDE; + void SetCanDualWield(bool value) OVERRIDE; int8 GetOriginalEquipmentId() const { return m_originalEquipmentId; } uint8 GetCurrentEquipmentId() { return m_equipmentId; } void SetCurrentEquipmentId(uint8 id) { m_equipmentId = id; } diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 5455bad904a..e93f66ed726 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -95,7 +95,7 @@ class Guardian : public Minion void UpdateMaxHealth(); void UpdateMaxPower(Powers power); void UpdateAttackPowerAndDamage(bool ranged = false); - void UpdateDamagePhysical(WeaponAttackType attType); + void UpdateDamagePhysical(WeaponAttackType attType) OVERRIDE; int32 GetBonusDamage() const { return m_bonusSpellDamage; } void SetBonusDamage(int32 damage); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 67e8c94f927..0ef03723cb4 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -816,6 +816,9 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map void SetDisplayId(uint32 displayid); uint32 GetDisplayId() const { return GetUInt32Value(GAMEOBJECT_DISPLAYID); } + uint32 GetFaction() const { return GetUInt32Value(GAMEOBJECT_FACTION); } + void SetFaction(uint32 faction) { SetUInt32Value(GAMEOBJECT_FACTION, faction); } + GameObjectModel* m_model; void GetRespawnPosition(float &x, float &y, float &z, float* ori = NULL) const; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index f18c6fdd977..8af48f277bd 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -480,7 +480,10 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const { /// @todo Allow players to aquire this updateflag. *data << uint32(unit->GetVehicleKit()->GetVehicleInfo()->m_ID); - *data << float(unit->GetOrientation()); + if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + *data << float(unit->GetTransOffsetO()); + else + *data << float(unit->GetOrientation()); } // 0x200 diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index edcdf25ba33..8d3b1ff9554 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -537,7 +537,7 @@ class MapObject protected: MapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE) - { + { _newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f); } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index c375cd30ad3..ef5e792e939 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -95,7 +95,7 @@ class Pet : public Guardian void UpdateMaxHealth(); void UpdateMaxPower(Powers power); void UpdateAttackPowerAndDamage(bool ranged = false); - void UpdateDamagePhysical(WeaponAttackType attType); + void UpdateDamagePhysical(WeaponAttackType attType) OVERRIDE; */ void ToggleAutocast(SpellInfo const* spellInfo, bool apply); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d8218ff9689..eab8df2cd9c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -759,7 +759,6 @@ Player::Player(WorldSession* session): Unit(true) m_ArmorProficiency = 0; m_canParry = false; m_canBlock = false; - m_canDualWield = false; m_canTitanGrip = false; m_ammoDPS = 0.0f; @@ -5128,7 +5127,10 @@ void Player::BuildPlayerRepop() // BG - remove insignia related RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); -// SendCorpseReclaimDelay(); + int32 corpseReclaimDelay = CalculateCorpseReclaimDelay(); + + if (corpseReclaimDelay >= 0) + SendCorpseReclaimDelay(corpseReclaimDelay); // to prevent cheating corpse->ResetGhostTime(); @@ -5236,7 +5238,11 @@ void Player::KillPlayer() m_deathTimer = 6 * MINUTE * IN_MILLISECONDS; UpdateCorpseReclaimDelay(); // dependent at use SetDeathPvP() call before kill - SendCorpseReclaimDelay(); + + int32 corpseReclaimDelay = CalculateCorpseReclaimDelay(); + + if (corpseReclaimDelay >= 0) + SendCorpseReclaimDelay(corpseReclaimDelay); // don't create corpse at this moment, player might be falling @@ -7284,8 +7290,8 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto { // Check if allowed to receive it in current map uint8 MapType = sWorld->getIntConfig(CONFIG_PVP_TOKEN_MAP_TYPE); - if ((MapType == 1 && !InBattleground() && !HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) - || (MapType == 2 && !HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + if ((MapType == 1 && !InBattleground() && !IsFFAPvP()) + || (MapType == 2 && !IsFFAPvP()) || (MapType == 3 && !InBattleground())) return true; @@ -7518,14 +7524,9 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) { if (Weather* weather = WeatherMgr::FindWeather(zone->ID)) weather->SendWeatherUpdateToPlayer(this); - else - { - if (!WeatherMgr::AddWeather(zone->ID)) - { - // send fine weather packet to remove old zone's weather - WeatherMgr::SendFineWeatherUpdateToPlayer(this); - } - } + else if (!WeatherMgr::AddWeather(zone->ID)) + // send fine weather packet to remove old zone's weather + WeatherMgr::SendFineWeatherUpdateToPlayer(this); } sScriptMgr->OnPlayerUpdateZone(this, newZone, newArea); @@ -15092,11 +15093,11 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg) if (!CanRewardQuest(quest, msg)) return false; + ItemPosCountVec dest; if (quest->GetRewChoiceItemsCount() > 0) { if (quest->RewardChoiceItemId[reward]) { - ItemPosCountVec dest; InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, quest->RewardChoiceItemId[reward], quest->RewardChoiceItemCount[reward]); if (res != EQUIP_ERR_OK) { @@ -15112,7 +15113,6 @@ bool Player::CanRewardQuest(Quest const* quest, uint32 reward, bool msg) { if (quest->RewardItemId[i]) { - ItemPosCountVec dest; InventoryResult res = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, quest->RewardItemId[i], quest->RewardItemIdCount[i]); if (res != EQUIP_ERR_OK) { @@ -17346,49 +17346,56 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) // NOW player must have valid map // load the player's map here if it's not already loaded Map* map = sMapMgr->CreateMap(mapId, this); + AreaTrigger const* areaTrigger = NULL; + bool check = false; if (!map) { - instanceId = 0; - AreaTrigger const* at = sObjectMgr->GetGoBackTrigger(mapId); - if (at) + areaTrigger = sObjectMgr->GetGoBackTrigger(mapId); + check = true; + } + else if (map->IsDungeon()) // if map is dungeon... + { + if (!((InstanceMap*)map)->CanEnter(this)) // ... and can't enter map, then look for entry point. { - TC_LOG_ERROR("entities.player", "Player (guidlow %d) is teleported to gobacktrigger (Map: %u X: %f Y: %f Z: %f O: %f).", guid, mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); - Relocate(at->target_X, at->target_Y, at->target_Z, GetOrientation()); - mapId = at->target_mapId; + areaTrigger = sObjectMgr->GetGoBackTrigger(mapId); + check = true; } - else + else if (instanceId && !sInstanceSaveMgr->GetInstanceSave(instanceId)) // ... and instance is reseted then look for entrance. { - TC_LOG_ERROR("entities.player", "Player (guidlow %d) is teleported to home (Map: %u X: %f Y: %f Z: %f O: %f).", guid, mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); - RelocateToHomebind(); + areaTrigger = sObjectMgr->GetMapEntranceTrigger(mapId); + check = true; } + } - map = sMapMgr->CreateMap(mapId, this); - if (!map) + if (check) // in case of special event when creating map... + { + if (areaTrigger) // ... if we have an areatrigger, then relocate to new map/coordinates. { - PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass()); - mapId = info->mapId; - Relocate(info->positionX, info->positionY, info->positionZ, 0.0f); - TC_LOG_ERROR("entities.player", "Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.", guid, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); - map = sMapMgr->CreateMap(mapId, this); - if (!map) + Relocate(areaTrigger->target_X, areaTrigger->target_Y, areaTrigger->target_Z, GetOrientation()); + if (mapId != areaTrigger->target_mapId) { - TC_LOG_ERROR("entities.player", "Player (guidlow %d) has invalid default map coordinates (X: %f Y: %f Z: %f O: %f). or instance couldn't be created", guid, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); - return false; + mapId = areaTrigger->target_mapId; + map = sMapMgr->CreateMap(mapId, this); } } + else + { + TC_LOG_ERROR("entities.player", "Player %s (guid: %d) Map: %u, X: %f, Y: %f, Z: %f, O: %f. Areatrigger not found.", m_name.c_str(), guid, mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); + map = NULL; + } } - // if the player is in an instance and it has been reset in the meantime teleport him to the entrance - if (instanceId && !sInstanceSaveMgr->GetInstanceSave(instanceId) && !map->IsBattlegroundOrArena()) + if (!map) { - AreaTrigger const* at = sObjectMgr->GetMapEntranceTrigger(mapId); - if (at) - Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation); - else + PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass()); + mapId = info->mapId; + Relocate(info->positionX, info->positionY, info->positionZ, 0.0f); + map = sMapMgr->CreateMap(mapId, this); + if (!map) { - TC_LOG_ERROR("entities.player", "Player %s(GUID: %u) logged in to a reset instance (map: %u) and there is no area-trigger leading to this map. Thus he can't be ported back to the entrance. This _might_ be an exploit attempt.", GetName().c_str(), GetGUIDLow(), mapId); - RelocateToHomebind(); + TC_LOG_ERROR("entities.player", "Player %s (guid: %d) Map: %u, X: %f, Y: %f, Z: %f, O: %f. Invalid default map coordinates or instance couldn't be created.", m_name.c_str(), guid, mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); + return false; } } @@ -17435,14 +17442,21 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) m_atLoginFlags = fields[33].GetUInt16(); + if (HasAtLoginFlag(AT_LOGIN_RENAME)) + { + TC_LOG_ERROR("entities.player", "Player (GUID: %u) tried to login while forced to rename, can't load.'", GetGUIDLow()); + return false; + } + // Honor system // Update Honor kills data m_lastHonorUpdateTime = logoutTime; UpdateHonorFields(); m_deathExpireTime = time_t(fields[36].GetUInt32()); - if (m_deathExpireTime > now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP) - m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP-1; + + if (m_deathExpireTime > now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP) + m_deathExpireTime = now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP - 1; // clear channel spell data (if saved at channel spell casting) SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, 0); @@ -21674,14 +21688,14 @@ void Player::UpdatePvPState(bool onlyFFA) if (!pvpInfo.IsInNoPvPArea && !IsGameMaster() && (pvpInfo.IsInFFAPvPArea || sWorld->IsFFAPvPRealm())) { - if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + if (!IsFFAPvP()) { SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) (*itr)->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); } } - else if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + else if (IsFFAPvP()) { RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); for (ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) @@ -23757,14 +23771,18 @@ void Player::ResurectUsingRequestData() SpawnCorpseBones(); } -void Player::SetClientControl(Unit* target, uint8 allowMove) +void Player::SetClientControl(Unit* target, bool allowMove) { WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, target->GetPackGUID().size()+1); data.append(target->GetPackGUID()); - data << uint8(allowMove); + data << uint8(allowMove ? 1 : 0); GetSession()->SendPacket(&data); - if (target == this) - SetMover(this); + + if (this != target) + SetViewpoint(target, allowMove); + + if (allowMove) + SetMover(target); } void Player::SetMover(Unit* target) @@ -23829,7 +23847,7 @@ uint32 Player::GetCorpseReclaimDelay(bool pvp) const time_t now = time(NULL); // 0..2 full period // should be ceil(x)-1 but not floor(x) - uint64 count = (now < m_deathExpireTime - 1) ? (m_deathExpireTime - 1 - now)/DEATH_EXPIRE_STEP : 0; + uint64 count = (now < m_deathExpireTime - 1) ? (m_deathExpireTime - 1 - now) / DEATH_EXPIRE_STEP : 0; return copseReclaimDelay[count]; } @@ -23842,65 +23860,66 @@ void Player::UpdateCorpseReclaimDelay() return; time_t now = time(NULL); + if (now < m_deathExpireTime) { // full and partly periods 1..3 - uint64 count = (m_deathExpireTime - now)/DEATH_EXPIRE_STEP +1; + uint64 count = (m_deathExpireTime - now) / DEATH_EXPIRE_STEP + 1; + if (count < MAX_DEATH_COUNT) - m_deathExpireTime = now+(count+1)*DEATH_EXPIRE_STEP; + m_deathExpireTime = now+(count + 1) * DEATH_EXPIRE_STEP; else - m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP; + m_deathExpireTime = now + MAX_DEATH_COUNT*DEATH_EXPIRE_STEP; } else - m_deathExpireTime = now+DEATH_EXPIRE_STEP; + m_deathExpireTime = now + DEATH_EXPIRE_STEP; } -void Player::SendCorpseReclaimDelay(bool load) +int32 Player::CalculateCorpseReclaimDelay(bool load) { Corpse* corpse = GetCorpse(); + if (load && !corpse) - return; + return -1; - bool pvp; - if (corpse) - pvp = (corpse->GetType() == CORPSE_RESURRECTABLE_PVP); - else - pvp = (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH); + bool pvp = corpse ? corpse->GetType() == CORPSE_RESURRECTABLE_PVP : m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH; + + uint32 delay; - time_t delay; if (load) { if (corpse->GetGhostTime() > m_deathExpireTime) - return; + return -1; + + uint64 count = 0; - uint64 count; if ((pvp && sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP)) || (!pvp && sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE))) { - count = (m_deathExpireTime-corpse->GetGhostTime())/DEATH_EXPIRE_STEP; + count = (m_deathExpireTime - corpse->GetGhostTime()) / DEATH_EXPIRE_STEP; + if (count >= MAX_DEATH_COUNT) - count = MAX_DEATH_COUNT-1; + count = MAX_DEATH_COUNT - 1; } - else - count=0; - - time_t expected_time = corpse->GetGhostTime()+copseReclaimDelay[count]; + time_t expected_time = corpse->GetGhostTime() + copseReclaimDelay[count]; time_t now = time(NULL); + if (now >= expected_time) - return; + return -1; - delay = expected_time-now; + delay = expected_time - now; } else delay = GetCorpseReclaimDelay(pvp); - if (!delay) - return; + return delay * IN_MILLISECONDS; +} - //! corpse reclaim delay 30 * 1000ms or longer at often deaths +void Player::SendCorpseReclaimDelay(uint32 delay) +{ WorldPacket data(SMSG_CORPSE_RECLAIM_DELAY, 4); - data << uint32(delay*IN_MILLISECONDS); + data << uint32(delay); GetSession()->SendPacket(&data); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index f7658f73321..1f5f9fee7d4 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1643,6 +1643,7 @@ class Player : public Unit, public GridObject<Player> void RemoveAllSpellCooldown(); void _LoadSpellCooldowns(PreparedQueryResult result); void _SaveSpellCooldowns(SQLTransaction& trans); + uint32 GetLastPotionId() { return m_lastPotionId; } void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; } void UpdatePotionCooldown(Spell* spell = NULL); @@ -1747,14 +1748,13 @@ class Player : public Unit, public GridObject<Player> void ApplyFeralAPBonus(int32 amount, bool apply); void UpdateAttackPowerAndDamage(bool ranged = false); void UpdateShieldBlockValue(); - void UpdateDamagePhysical(WeaponAttackType attType); void ApplySpellPowerBonus(int32 amount, bool apply); void UpdateSpellDamageAndHealingBonus(); void ApplyRatingMod(CombatRating cr, int32 value, bool apply); void UpdateRating(CombatRating cr); void UpdateAllRatings(); - void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& min_damage, float& max_damage); + void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) OVERRIDE; void UpdateDefenseBonusesMod(); inline void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);} @@ -1936,7 +1936,8 @@ class Player : public Unit, public GridObject<Player> uint32 GetDeathTimer() const { return m_deathTimer; } uint32 GetCorpseReclaimDelay(bool pvp) const; void UpdateCorpseReclaimDelay(); - void SendCorpseReclaimDelay(bool load = false); + int32 CalculateCorpseReclaimDelay(bool load = false); + void SendCorpseReclaimDelay(uint32 delay); uint32 GetShieldBlockValue() const; // overwrite Unit version (virtual) bool CanParry() const { return m_canParry; } @@ -2088,7 +2089,7 @@ class Player : public Unit, public GridObject<Player> bool IsKnowHowFlyIn(uint32 mapid, uint32 zone) const; - void SetClientControl(Unit* target, uint8 allowMove); + void SetClientControl(Unit* target, bool allowMove); void SetMover(Unit* target); diff --git a/src/server/game/Entities/Totem/Totem.h b/src/server/game/Entities/Totem/Totem.h index d20a58abd01..6364157982e 100644 --- a/src/server/game/Entities/Totem/Totem.h +++ b/src/server/game/Entities/Totem/Totem.h @@ -53,7 +53,7 @@ class Totem : public Minion void UpdateMaxHealth() { } void UpdateMaxPower(Powers /*power*/) { } void UpdateAttackPowerAndDamage(bool /*ranged*/) { } - void UpdateDamagePhysical(WeaponAttackType /*attType*/) { } + void UpdateDamagePhysical(WeaponAttackType /*attType*/) OVERRIDE { } bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 3077b143bb0..3afa6b016d2 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -48,6 +48,43 @@ inline bool _ModifyUInt32(bool apply, uint32& baseValue, int32& amount) /*####################################### ######## ######## +######## UNIT STAT SYSTEM ######## +######## ######## +#######################################*/ + +void Unit::UpdateAllResistances() +{ + for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) + UpdateResistances(i); +} + +void Unit::UpdateDamagePhysical(WeaponAttackType attType) +{ + float minDamage = 0.0f; + float maxDamage = 0.0f; + + CalculateMinMaxDamage(attType, false, true, minDamage, maxDamage); + + switch (attType) + { + case BASE_ATTACK: + default: + SetStatFloatValue(UNIT_FIELD_MINDAMAGE, minDamage); + SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxDamage); + break; + case OFF_ATTACK: + SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, minDamage); + SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxDamage); + break; + case RANGED_ATTACK: + SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, minDamage); + SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxDamage); + break; + } +} + +/*####################################### +######## ######## ######## PLAYERS STAT SYSTEM ######## ######## ######## #######################################*/ @@ -178,8 +215,7 @@ bool Player::UpdateAllStats() UpdateExpertise(BASE_ATTACK); UpdateExpertise(OFF_ATTACK); RecalculateRating(CR_ARMOR_PENETRATION); - for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) - UpdateResistances(i); + UpdateAllResistances(); return true; } @@ -477,7 +513,7 @@ void Player::UpdateShieldBlockValue() SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue()); } -void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& min_damage, float& max_damage) +void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { UnitMods unitMod; @@ -495,70 +531,45 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo break; } - float att_speed = GetAPMultiplier(attType, normalized); + float attackSpeedMod = GetAPMultiplier(attType, normalized); - float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; - float base_pct = GetModifierValue(unitMod, BASE_PCT); - float total_value = GetModifierValue(unitMod, TOTAL_VALUE); - float total_pct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; + float baseValue = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * attackSpeedMod; + float basePct = GetModifierValue(unitMod, BASE_PCT); + float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); + float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; - float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); - float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); + float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE); + float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE); - if (IsInFeralForm()) //check if player is druid and in cat or bear forms + if (IsInFeralForm()) // check if player is druid and in cat or bear forms { uint8 lvl = getLevel(); if (lvl > 60) lvl = 60; - weapon_mindamage = lvl*0.85f*att_speed; - weapon_maxdamage = lvl*1.25f*att_speed; + weaponMinDamage = lvl * 0.85f * attackSpeedMod; + weaponMaxDamage = lvl * 1.25f * attackSpeedMod; } - else if (!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case) + else if (!CanUseAttackType(attType)) // check if player not in form but still can't use (disarm case) { - //cannot use ranged/off attack, set values to 0 + // cannot use ranged/off attack, set values to 0 if (attType != BASE_ATTACK) { - min_damage = 0; - max_damage = 0; + minDamage = 0; + maxDamage = 0; return; } - weapon_mindamage = BASE_MINDAMAGE; - weapon_maxdamage = BASE_MAXDAMAGE; + weaponMinDamage = BASE_MINDAMAGE; + weaponMaxDamage = BASE_MAXDAMAGE; } - else if (attType == RANGED_ATTACK) //add ammo DPS to ranged damage + else if (attType == RANGED_ATTACK) // add ammo DPS to ranged damage { - weapon_mindamage += GetAmmoDPS() * att_speed; - weapon_maxdamage += GetAmmoDPS() * att_speed; + weaponMinDamage += GetAmmoDPS() * attackSpeedMod; + weaponMaxDamage += GetAmmoDPS() * attackSpeedMod; } - min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; - max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; -} - -void Player::UpdateDamagePhysical(WeaponAttackType attType) -{ - float mindamage; - float maxdamage; - - CalculateMinMaxDamage(attType, false, true, mindamage, maxdamage); - - switch (attType) - { - case BASE_ATTACK: - default: - SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); - SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); - break; - case OFF_ATTACK: - SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, mindamage); - SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxdamage); - break; - case RANGED_ATTACK: - SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, mindamage); - SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxdamage); - break; - } + minDamage = ((weaponMinDamage + baseValue) * basePct + totalValue) * totalPct; + maxDamage = ((weaponMaxDamage + baseValue) * basePct + totalValue) * totalPct; } void Player::UpdateDefenseBonusesMod() @@ -841,9 +852,14 @@ void Player::UpdateExpertise(WeaponAttackType attack) switch (attack) { - case BASE_ATTACK: SetUInt32Value(PLAYER_EXPERTISE, expertise); break; - case OFF_ATTACK: SetUInt32Value(PLAYER_OFFHAND_EXPERTISE, expertise); break; - default: break; + case BASE_ATTACK: + SetUInt32Value(PLAYER_EXPERTISE, expertise); + break; + case OFF_ATTACK: + SetUInt32Value(PLAYER_OFFHAND_EXPERTISE, expertise); + break; + default: + break; } } @@ -950,8 +966,7 @@ bool Creature::UpdateAllStats() for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i) UpdateMaxPower(Powers(i)); - for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) - UpdateResistances(i); + UpdateAllResistances(); return true; } @@ -976,7 +991,7 @@ void Creature::UpdateArmor() void Creature::UpdateMaxHealth() { float value = GetTotalAuraModValue(UNIT_MOD_HEALTH); - SetMaxHealth((uint32)value); + SetMaxHealth(uint32(value)); } void Creature::UpdateMaxPower(Powers power) @@ -992,25 +1007,25 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; - uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; - uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; + uint16 indexMod = UNIT_FIELD_ATTACK_POWER_MODS; + uint16 indexMulti = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; - index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; - index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; + indexMod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; + indexMulti = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } - float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); - float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); - float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; + float baseAttackPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); + float attackPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); + float attackPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; - SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field - SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field - SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field + SetInt32Value(index, uint32(baseAttackPower)); // UNIT_FIELD_(RANGED)_ATTACK_POWER + SetInt32Value(indexMod, uint32(attackPowerMod)); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS + SetFloatValue(indexMulti, attackPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER - //automatically update weapon damage after attack power modification + // automatically update weapon damage after attack power modification if (ranged) UpdateDamagePhysical(RANGED_ATTACK); else @@ -1020,7 +1035,7 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) } } -void Creature::UpdateDamagePhysical(WeaponAttackType attType) +void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { UnitMods unitMod; switch (attType) @@ -1037,44 +1052,32 @@ void Creature::UpdateDamagePhysical(WeaponAttackType attType) break; } - //float att_speed = float(GetAttackTime(attType))/1000.0f; - - float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); - float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); - - /* difference in AP between current attack power and base value from DB */ - float att_pwr_change = GetTotalAttackPowerValue(attType) - GetCreatureTemplate()->attackpower; - float base_value = GetModifierValue(unitMod, BASE_VALUE) + (att_pwr_change * GetAPMultiplier(attType, false) / 14.0f); - float base_pct = GetModifierValue(unitMod, BASE_PCT); - float total_value = GetModifierValue(unitMod, TOTAL_VALUE); - float total_pct = GetModifierValue(unitMod, TOTAL_PCT); - float dmg_multiplier = GetCreatureTemplate()->dmg_multiplier; - - if (!CanUseAttackType(attType)) + if (attType == OFF_ATTACK && !haveOffhandWeapon()) { - weapon_mindamage = 0; - weapon_maxdamage = 0; + minDamage = 0.0f; + maxDamage = 0.0f; + return; } - float mindamage = ((base_value + weapon_mindamage) * dmg_multiplier * base_pct + total_value) * total_pct; - float maxdamage = ((base_value + weapon_maxdamage) * dmg_multiplier * base_pct + total_value) * total_pct; + float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE); + float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE); - switch (attType) + if (!CanUseAttackType(attType)) // disarm case { - case BASE_ATTACK: - default: - SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); - SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); - break; - case OFF_ATTACK: - SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, mindamage); - SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxdamage); - break; - case RANGED_ATTACK: - SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, mindamage); - SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxdamage); - break; + weaponMinDamage = 0.0f; + weaponMaxDamage = 0.0f; } + + float attackPower = GetTotalAttackPowerValue(attType); + float attackSpeedMulti = GetAPMultiplier(attType, normalized); + float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f); + float basePct = GetModifierValue(unitMod, BASE_PCT) * attackSpeedMulti; + float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); + float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; + float dmgMultiplier = GetCreatureTemplate()->dmg_multiplier; // = dmg_multiplier * _GetDamageMod(rank); + + minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; + maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; } /*####################################### @@ -1197,8 +1200,7 @@ bool Guardian::UpdateAllStats() for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i) UpdateMaxPower(Powers(i)); - for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i) - UpdateResistances(i); + UpdateAllResistances(); return true; } @@ -1436,6 +1438,7 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType) } } + /// @todo: remove this Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACKSPEED); for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e5fb575d8eb..e7e29fe2588 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -258,6 +258,8 @@ Unit::Unit(bool isWorldObject) : m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); _lastLiquid = NULL; + + _oldFactionId = 0; _isWalkingBeforeCharm = false; } @@ -368,10 +370,10 @@ void Unit::Update(uint32 p_time) bool Unit::haveOffhandWeapon() const { - if (GetTypeId() == TYPEID_PLAYER) - return ToPlayer()->GetWeaponForAttack(OFF_ATTACK, true); - else - return m_canDualWield; + if (Player const* player = ToPlayer()) + return player->GetWeaponForAttack(OFF_ATTACK, true); + + return CanDualWield(); } void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath, bool forceDestination) @@ -405,7 +407,7 @@ void Unit::UpdateSplinePosition() m_movesplineTimer.Reset(positionUpdateDelay); Movement::Location loc = movespline->ComputePosition(); - if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (movespline->onTransport) { Position& pos = m_movementInfo.transport.pos; pos.m_positionX = loc.x; @@ -2160,41 +2162,39 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT uint32 Unit::CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct) { - float min_damage, max_damage; + float minDamage = 0.0f; + float maxDamage = 0.0f; - if (GetTypeId() == TYPEID_PLAYER && (normalized || !addTotalPct)) - ToPlayer()->CalculateMinMaxDamage(attType, normalized, addTotalPct, min_damage, max_damage); + if (normalized || !addTotalPct) + CalculateMinMaxDamage(attType, normalized, addTotalPct, minDamage, maxDamage); else { switch (attType) { case RANGED_ATTACK: - min_damage = GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); - max_damage = GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE); + minDamage = GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); + maxDamage = GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE); break; case BASE_ATTACK: - min_damage = GetFloatValue(UNIT_FIELD_MINDAMAGE); - max_damage = GetFloatValue(UNIT_FIELD_MAXDAMAGE); + minDamage = GetFloatValue(UNIT_FIELD_MINDAMAGE); + maxDamage = GetFloatValue(UNIT_FIELD_MAXDAMAGE); break; case OFF_ATTACK: - min_damage = GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); - max_damage = GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); + minDamage = GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); + maxDamage = GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); break; - // Just for good manner default: - min_damage = 0.0f; - max_damage = 0.0f; break; } } - if (min_damage > max_damage) - std::swap(min_damage, max_damage); + if (minDamage > maxDamage) + std::swap(minDamage, maxDamage); - if (max_damage == 0.0f) - max_damage = 5.0f; + if (maxDamage == 0.0f) + maxDamage = 5.0f; - return urand((uint32)min_damage, (uint32)max_damage); + return urand(uint32(minDamage), uint32(maxDamage)); } float Unit::CalculateLevelPenalty(SpellInfo const* spellProto) const @@ -4832,7 +4832,7 @@ GameObject* Unit::GetGameObject(uint32 spellId) const void Unit::AddGameObject(GameObject* gameObj) { - if (!gameObj || !gameObj->GetOwnerGUID() == 0) + if (!gameObj || gameObj->GetOwnerGUID() != 0) return; m_gameObj.push_back(gameObj); @@ -5673,7 +5673,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere if (dummySpell->SpellFamilyFlags[1] & 0x8) { // check attack comes not from behind - if (!HasInArc(M_PI, victim)) + if (!HasInArc(M_PI, victim) || HasUnitState(UNIT_STATE_STUNNED)) return false; triggered_spell_id = 22858; @@ -9221,17 +9221,17 @@ void Unit::SetOwnerGUID(uint64 owner) Unit* Unit::GetOwner() const { - if (uint64 ownerid = GetOwnerGUID()) - { - return ObjectAccessor::GetUnit(*this, ownerid); - } + if (uint64 ownerGUID = GetOwnerGUID()) + return ObjectAccessor::GetUnit(*this, ownerGUID); + return NULL; } Unit* Unit::GetCharmer() const { - if (uint64 charmerid = GetCharmerGUID()) - return ObjectAccessor::GetUnit(*this, charmerid); + if (uint64 charmerGUID = GetCharmerGUID()) + return ObjectAccessor::GetUnit(*this, charmerGUID); + return NULL; } @@ -9567,8 +9567,8 @@ void Unit::SetCharm(Unit* charm, bool apply) } if (charm->GetTypeId() == TYPEID_PLAYER - || !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION) - || charm->GetOwnerGUID() != GetGUID()) + || !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION) + || charm->GetOwnerGUID() != GetGUID()) { m_Controlled.erase(charm); } @@ -11628,7 +11628,7 @@ bool Unit::IsServiceProvider() const void Unit::SetInCombatWith(Unit* enemy) { Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf(); - if (eOwner->IsPvP()) + if (eOwner->IsPvP() || eOwner->IsFFAPvP()) { SetInCombatState(true, enemy); return; @@ -13579,9 +13579,8 @@ CharmInfo::~CharmInfo() { } void CharmInfo::RestoreState() { - if (_unit->GetTypeId() == TYPEID_UNIT) - if (Creature* creature = _unit->ToCreature()) - creature->SetReactState(_oldReactState); + if (Creature* creature = _unit->ToCreature()) + creature->SetReactState(_oldReactState); } void CharmInfo::InitPetActionBar() @@ -15526,7 +15525,7 @@ void Unit::SetStunned(bool apply) // Creature specific if (GetTypeId() != TYPEID_PLAYER) - ToCreature()->StopMoving(); + StopMoving(); else SetStandState(UNIT_STAND_STATE_STAND); @@ -15584,7 +15583,7 @@ void Unit::SetRooted(bool apply) WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8); data.append(GetPackGUID()); SendMessageToSet(&data, true); - ToCreature()->StopMoving(); + StopMoving(); } } else @@ -15635,8 +15634,8 @@ void Unit::SetFeared(bool apply) } } - if (GetTypeId() == TYPEID_PLAYER) - ToPlayer()->SetClientControl(this, !apply); + if (Player* player = ToPlayer()) + player->SetClientControl(this, !apply); } void Unit::SetConfused(bool apply) @@ -15657,8 +15656,8 @@ void Unit::SetConfused(bool apply) } } - if (GetTypeId() == TYPEID_PLAYER) - ToPlayer()->SetClientControl(this, !apply); + if (Player* player = ToPlayer()) + player->SetClientControl(this, !apply); } bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* aurApp) @@ -15704,11 +15703,13 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au CombatStop(); /// @todo CombatStop(true) may cause crash (interrupt spells) DeleteThreatList(); + Player* playerCharmer = charmer->ToPlayer(); + // Charmer stop charming - if (charmer->GetTypeId() == TYPEID_PLAYER) + if (playerCharmer) { - charmer->ToPlayer()->StopCastingCharm(); - charmer->ToPlayer()->StopCastingBindSight(); + playerCharmer->StopCastingCharm(); + playerCharmer->StopCastingBindSight(); } // Charmed stop charming @@ -15730,11 +15731,10 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au if (aurApp && aurApp->GetRemoveMode()) return false; - // Set charmed - Map* map = GetMap(); - if (!IsVehicle() || (IsVehicle() && map && !map->IsBattleground())) - setFaction(charmer->getFaction()); + _oldFactionId = getFaction(); + setFaction(charmer->getFaction()); + // Set charmed charmer->SetCharm(this, true); if (GetTypeId() == TYPEID_UNIT) @@ -15747,7 +15747,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au Player* player = ToPlayer(); if (player->isAFK()) player->ToggleAFK(); - player->SetClientControl(this, 0); + player->SetClientControl(this, false); } // charm is set by aura, and aura effect remove handler was called during apply handler execution @@ -15765,25 +15765,21 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au GetCharmInfo()->InitCharmCreateSpells(); } - if (charmer->GetTypeId() == TYPEID_PLAYER) + if (playerCharmer) { switch (type) { case CHARM_TYPE_VEHICLE: SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); - charmer->ToPlayer()->SetClientControl(this, 1); - charmer->ToPlayer()->SetMover(this); - charmer->ToPlayer()->SetViewpoint(this, true); - charmer->ToPlayer()->VehicleSpellInitialize(); + playerCharmer->SetClientControl(this, true); + playerCharmer->VehicleSpellInitialize(); break; case CHARM_TYPE_POSSESS: AddUnitState(UNIT_STATE_POSSESSED); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - charmer->ToPlayer()->SetClientControl(this, 1); - charmer->ToPlayer()->SetMover(this); - charmer->ToPlayer()->SetViewpoint(this, true); - charmer->ToPlayer()->PossessSpellInitialize(); + playerCharmer->SetClientControl(this, true); + playerCharmer->PossessSpellInitialize(); break; case CHARM_TYPE_CHARM: if (GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK) @@ -15802,7 +15798,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped } } - charmer->ToPlayer()->CharmSpellInitialize(); + playerCharmer->CharmSpellInitialize(); break; default: case CHARM_TYPE_CONVERT: @@ -15839,16 +15835,16 @@ void Unit::RemoveCharmedBy(Unit* charmer) CombatStop(); /// @todo CombatStop(true) may cause crash (interrupt spells) getHostileRefManager().deleteReferences(); DeleteThreatList(); - Map* map = GetMap(); - if (!IsVehicle() || (IsVehicle() && map && !map->IsBattleground())) - RestoreFaction(); - GetMotionMaster()->InitDefault(); - if (type == CHARM_TYPE_POSSESS) + if (_oldFactionId) { - ClearUnitState(UNIT_STATE_POSSESSED); - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + setFaction(_oldFactionId); + _oldFactionId = 0; } + else + RestoreFaction(); + + GetMotionMaster()->InitDefault(); if (Creature* creature = ToCreature()) { @@ -15860,8 +15856,6 @@ void Unit::RemoveCharmedBy(Unit* charmer) if (type != CHARM_TYPE_VEHICLE) LastCharmerGUID = charmer->GetGUID(); } - else - ToPlayer()->SetClientControl(this, 1); // If charmer still exists if (!charmer) @@ -15872,24 +15866,23 @@ void Unit::RemoveCharmedBy(Unit* charmer) charmer->SetCharm(this, false); - if (charmer->GetTypeId() == TYPEID_PLAYER) + Player* playerCharmer = charmer->ToPlayer(); + + if (playerCharmer) { switch (type) { case CHARM_TYPE_VEHICLE: - charmer->ToPlayer()->SetClientControl(charmer, 1); - charmer->ToPlayer()->SetViewpoint(this, false); - charmer->ToPlayer()->SetClientControl(this, 0); - if (GetTypeId() == TYPEID_PLAYER) - ToPlayer()->SetMover(this); + playerCharmer->SetClientControl(this, false); + playerCharmer->SetClientControl(charmer, true); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); break; case CHARM_TYPE_POSSESS: - charmer->ToPlayer()->SetClientControl(charmer, 1); - charmer->ToPlayer()->SetViewpoint(this, false); - charmer->ToPlayer()->SetClientControl(this, 0); + playerCharmer->SetClientControl(this, false); + playerCharmer->SetClientControl(charmer, true); charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - if (GetTypeId() == TYPEID_PLAYER) - ToPlayer()->SetMover(this); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + ClearUnitState(UNIT_STATE_POSSESSED); break; case CHARM_TYPE_CHARM: if (GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK) @@ -15910,9 +15903,12 @@ void Unit::RemoveCharmedBy(Unit* charmer) } } + if (Player* player = ToPlayer()) + player->SetClientControl(this, true); + // a guardian should always have charminfo - if (charmer->GetTypeId() == TYPEID_PLAYER && this != charmer->GetFirstControlled()) - charmer->ToPlayer()->SendRemoveControlBar(); + if (playerCharmer && this != charmer->GetFirstControlled()) + playerCharmer->SendRemoveControlBar(); else if (GetTypeId() == TYPEID_PLAYER || (GetTypeId() == TYPEID_UNIT && !ToCreature()->IsGuardian())) DeleteCharmInfo(); } @@ -15969,8 +15965,7 @@ void Unit::RemoveVehicleKit() m_updateFlag &= ~UPDATEFLAG_VEHICLE; m_unitTypeMask &= ~UNIT_MASK_VEHICLE; - RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_PLAYER_VEHICLE); + RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK | UNIT_NPC_FLAG_PLAYER_VEHICLE); } bool Unit::IsOnVehicle(const Unit* vehicle) const diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index eb236666976..bae10abe85b 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -683,7 +683,8 @@ enum NPCFlags UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100% UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) - UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000 // players with mounts that have vehicle data should have it set + UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set + UNIT_NPC_FLAG_MAILBOX = 0x04000000 // }; enum MovementFlags @@ -1292,7 +1293,7 @@ class Unit : public WorldObject bool isAttackReady(WeaponAttackType type = BASE_ATTACK) const { return m_attackTimer[type] == 0; } bool haveOffhandWeapon() const; bool CanDualWield() const { return m_canDualWield; } - void SetCanDualWield(bool value) { m_canDualWield = value; } + virtual void SetCanDualWield(bool value) { m_canDualWield = value; } float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; } float GetMeleeReach() const; bool IsWithinCombatRange(const Unit* obj, float dist2compare) const; @@ -1404,6 +1405,7 @@ class Unit : public WorldObject void GetPartyMembers(std::list<Unit*> &units); bool IsContestedGuard() const; bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); } + bool IsFFAPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); } void SetPvP(bool state); uint32 GetCreatureType() const; uint32 GetCreatureTypeMask() const; @@ -1870,14 +1872,18 @@ class Unit : public WorldObject virtual bool UpdateStats(Stats stat) = 0; virtual bool UpdateAllStats() = 0; virtual void UpdateResistances(uint32 school) = 0; + virtual void UpdateAllResistances(); virtual void UpdateArmor() = 0; virtual void UpdateMaxHealth() = 0; virtual void UpdateMaxPower(Powers power) = 0; virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0; - virtual void UpdateDamagePhysical(WeaponAttackType attType) = 0; + virtual void UpdateDamagePhysical(WeaponAttackType attType); float GetTotalAttackPowerValue(WeaponAttackType attType) const; float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const; void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; } + virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) = 0; + uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct); + float GetAPMultiplier(WeaponAttackType attType, bool normalized); bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const; bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const; @@ -1935,8 +1941,6 @@ class Unit : public WorldObject void RemoveGameObject(uint32 spellid, bool del); void RemoveAllGameObjects(); - uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct); - float GetAPMultiplier(WeaponAttackType attType, bool normalized); void ModifyAuraState(AuraStateType flag, bool apply); uint32 BuildAuraStateUpdateForTarget(Unit* target) const; bool HasAuraState(AuraStateType flag, SpellInfo const* spellProto = NULL, Unit const* Caster = NULL) const; @@ -1956,7 +1960,6 @@ class Unit : public WorldObject uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = NULL); uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = NULL); - bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK); bool isBlockCritical(); bool isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const; @@ -2245,7 +2248,8 @@ class Unit : public WorldObject bool m_cleanupDone; // lock made to not add stuff after cleanup before delete bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world - bool _isWalkingBeforeCharm; // Are we walking before we were charmed? + uint32 _oldFactionId; ///< faction before charm + bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed? time_t _lastDamagedTime; // Part of Evade mechanics }; @@ -2256,31 +2260,31 @@ namespace Trinity class PowerPctOrderPred { public: - PowerPctOrderPred(Powers power, bool ascending = true) : m_power(power), m_ascending(ascending) { } - bool operator() (const Unit* a, const Unit* b) const + PowerPctOrderPred(Powers power, bool ascending = true) : _power(power), _ascending(ascending) { } + bool operator() (Unit const* a, Unit const* b) const { - float rA = a->GetMaxPower(m_power) ? float(a->GetPower(m_power)) / float(a->GetMaxPower(m_power)) : 0.0f; - float rB = b->GetMaxPower(m_power) ? float(b->GetPower(m_power)) / float(b->GetMaxPower(m_power)) : 0.0f; - return m_ascending ? rA < rB : rA > rB; + float rA = a->GetMaxPower(_power) ? float(a->GetPower(_power)) / float(a->GetMaxPower(_power)) : 0.0f; + float rB = b->GetMaxPower(_power) ? float(b->GetPower(_power)) / float(b->GetMaxPower(_power)) : 0.0f; + return _ascending ? rA < rB : rA > rB; } private: - const Powers m_power; - const bool m_ascending; + Powers const _power; + bool const _ascending; }; // Binary predicate for sorting Units based on percent value of health class HealthPctOrderPred { public: - HealthPctOrderPred(bool ascending = true) : m_ascending(ascending) { } - bool operator() (const Unit* a, const Unit* b) const + HealthPctOrderPred(bool ascending = true) : _ascending(ascending) { } + bool operator() (Unit const* a, Unit const* b) const { float rA = a->GetMaxHealth() ? float(a->GetHealth()) / float(a->GetMaxHealth()) : 0.0f; float rB = b->GetMaxHealth() ? float(b->GetHealth()) / float(b->GetMaxHealth()) : 0.0f; - return m_ascending ? rA < rB : rA > rB; + return _ascending ? rA < rB : rA > rB; } private: - const bool m_ascending; + bool const _ascending; }; } #endif diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index a48f46191ba..fae4f0c6b6a 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -521,8 +521,13 @@ Vehicle* Vehicle::RemovePassenger(Unit* unit) if (_me->IsInWorld()) { - unit->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); - unit->m_movementInfo.transport.Reset(); + if (!_me->GetTransport()) + { + unit->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + unit->m_movementInfo.transport.Reset(); + } + else + unit->m_movementInfo.transport = _me->m_movementInfo.transport; } // only for flyable vehicles diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index a84e2910e52..04f3395653d 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -638,6 +638,24 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) if (!ok2) continue; + if (cInfo->expansion > difficultyInfo->expansion) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, expansion %u) has different `expansion` in difficulty %u mode (Entry: %u, expansion %u).", + cInfo->Entry, cInfo->expansion, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->expansion); + } + + if (cInfo->faction_A != difficultyInfo->faction_A) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, faction_A %u) has different `faction_A` in difficulty %u mode (Entry: %u, faction_A %u).", + cInfo->Entry, cInfo->faction_A, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->faction_A); + } + + if (cInfo->faction_H != difficultyInfo->faction_H) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, faction_H %u) has different `faction_H` in difficulty %u mode (Entry: %u, faction_H %u).", + cInfo->Entry, cInfo->faction_H, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->faction_H); + } + if (cInfo->unit_class != difficultyInfo->unit_class) { TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, class %u) has different `unit_class` in difficulty %u mode (Entry: %u, class %u).", @@ -651,6 +669,12 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) continue; } + if (cInfo->family != difficultyInfo->family) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, family %u) has different `family` in difficulty %u mode (Entry: %u, family %u).", + cInfo->Entry, cInfo->family, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->family); + } + if (cInfo->trainer_class != difficultyInfo->trainer_class) { TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has different `trainer_class` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]); @@ -675,6 +699,24 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) continue; } + if (cInfo->type != difficultyInfo->type) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, type %u) has different `type` in difficulty %u mode (Entry: %u, type %u).", + cInfo->Entry, cInfo->type, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type); + } + + if (cInfo->type_flags != difficultyInfo->type_flags) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, type_flags %u) has different `type_flags` in difficulty %u mode (Entry: %u, type_flags %u).", + cInfo->Entry, cInfo->type_flags, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type_flags); + } + + if (!cInfo->VehicleId && difficultyInfo->VehicleId) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, VehicleId %u) has different `VehicleId` in difficulty %u mode (Entry: %u, VehicleId %u).", + cInfo->Entry, cInfo->VehicleId, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->VehicleId); + } + if (!difficultyInfo->AIName.empty()) { TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) lists difficulty %u mode entry %u with `AIName` filled in. `AIName` of difficulty 0 mode creature is always used instead.", @@ -883,7 +925,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) const_cast<CreatureTemplate*>(cInfo)->scale = 1.0f; } - if (cInfo->expansion > (MAX_CREATURE_BASE_HP - 1)) + if (cInfo->expansion > (MAX_EXPANSIONS - 1)) { TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with expansion %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion); const_cast<CreatureTemplate*>(cInfo)->expansion = 0; @@ -1772,7 +1814,7 @@ bool ObjectMgr::MoveCreData(uint32 guid, uint32 mapId, const Position& pos) // We use spawn coords to spawn if (!map->Instanceable() && map->IsGridLoaded(data.posX, data.posY)) { - Creature* creature = new Creature; + Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(guid, map)) { TC_LOG_ERROR("misc", "MoveCreData: Cannot add creature guid %u to map", guid); @@ -1824,7 +1866,7 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 /*team*/, uint32 mapId, float // We use spawn coords to spawn if (!map->Instanceable() && !map->IsRemovalGrid(x, y)) { - Creature* creature = new Creature; + Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(guid, map)) { TC_LOG_ERROR("misc", "AddCreature: Cannot add creature entry %u to map", entry); @@ -3044,8 +3086,8 @@ void ObjectMgr::LoadPetLevelInfo() { if (pInfo[level].health == 0) { - TC_LOG_ERROR("sql.sql", "Creature %u has no data for Level %i pet stats data, using data of Level %i.", itr->first, level+1, level); - pInfo[level] = pInfo[level-1]; + TC_LOG_ERROR("sql.sql", "Creature %u has no data for Level %i pet stats data, using data of Level %i.", itr->first, level + 1, level); + pInfo[level] = pInfo[level - 1]; } } } @@ -3266,7 +3308,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - TC_LOG_ERROR("server.loading", ">> Loaded 0 player create spells. DB table `%s` is empty.", sWorld->getBoolConfig(CONFIG_START_ALL_SPELLS) ? "playercreateinfo_spell_custom" : "playercreateinfo_spell"); + TC_LOG_ERROR("server.loading", ">> Loaded 0 player create spells. DB table `%s` is empty.", tableName.c_str()); } else { @@ -3281,13 +3323,13 @@ void ObjectMgr::LoadPlayerInfo() if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Wrong race mask %u in `playercreateinfo_spell` table, ignoring.", raceMask); + TC_LOG_ERROR("sql.sql", "Wrong race mask %u in `%s` table, ignoring.", raceMask, tableName.c_str()); continue; } if (classMask != 0 && !(classMask & CLASSMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Wrong class mask %u in `playercreateinfo_spell` table, ignoring.", classMask); + TC_LOG_ERROR("sql.sql", "Wrong class mask %u in `%s` table, ignoring.", classMask, tableName.c_str()); continue; } @@ -3307,7 +3349,7 @@ void ObjectMgr::LoadPlayerInfo() // We need something better here, the check is not accounting for spells used by multiple races/classes but not all of them. // Either split the masks per class, or per race, which kind of kills the point yet. // else if (raceMask != 0 && classMask != 0) - // TC_LOG_ERROR("sql.sql", "Racemask/classmask (%u/%u) combination was found containing an invalid race/class combination (%u/%u) in `playercreateinfo_spell` (Spell %u), ignoring.", raceMask, classMask, raceIndex, classIndex, spellId); + // TC_LOG_ERROR("sql.sql", "Racemask/classmask (%u/%u) combination was found containing an invalid race/class combination (%u/%u) in `%s` (Spell %u), ignoring.", raceMask, classMask, raceIndex, classIndex, tableName.c_str(), spellId); } } } @@ -3374,7 +3416,7 @@ void ObjectMgr::LoadPlayerInfo() if (!result) { - TC_LOG_ERROR("server.loading", ">> Loaded 0 level health/mana definitions. DB table `game_event_condition` is empty."); + TC_LOG_ERROR("server.loading", ">> Loaded 0 level health/mana definitions. DB table `player_classlevelstats` is empty."); exit(1); } @@ -3437,8 +3479,8 @@ void ObjectMgr::LoadPlayerInfo() { if (pClassInfo->levelInfo[level].basehealth == 0) { - TC_LOG_ERROR("sql.sql", "Class %i Level %i does not have health/mana data. Using stats data of level %i.", class_, level+1, level); - pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level-1]; + TC_LOG_ERROR("sql.sql", "Class %i Level %i does not have health/mana data. Using stats data of level %i.", class_, level + 1, level); + pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1]; } } } @@ -3498,9 +3540,9 @@ void ObjectMgr::LoadPlayerInfo() if (!info->levelInfo) info->levelInfo = new PlayerLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)]; - PlayerLevelInfo& levelInfo = info->levelInfo[current_level-1]; + PlayerLevelInfo& levelInfo = info->levelInfo[current_level - 1]; for (int i = 0; i < MAX_STATS; i++) - levelInfo.stats[i] = fields[i+3].GetUInt8(); + levelInfo.stats[i] = fields[i + 3].GetUInt8(); } ++count; @@ -3525,11 +3567,11 @@ void ObjectMgr::LoadPlayerInfo() continue; // skip expansion races if not playing with expansion - if (sWorld->getIntConfig(CONFIG_EXPANSION) < 1 && (race == RACE_BLOODELF || race == RACE_DRAENEI)) + if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_THE_BURNING_CRUSADE && (race == RACE_BLOODELF || race == RACE_DRAENEI)) continue; // skip expansion classes if not playing with expansion - if (sWorld->getIntConfig(CONFIG_EXPANSION) < 2 && class_ == CLASS_DEATH_KNIGHT) + if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_WRATH_OF_THE_LICH_KING && class_ == CLASS_DEATH_KNIGHT) continue; // fatal error if no level 1 data @@ -3544,8 +3586,8 @@ void ObjectMgr::LoadPlayerInfo() { if (info->levelInfo[level].stats[0] == 0) { - TC_LOG_ERROR("sql.sql", "Race %i Class %i Level %i does not have stats data. Using stats data of level %i.", race, class_, level+1, level); - info->levelInfo[level] = info->levelInfo[level-1]; + TC_LOG_ERROR("sql.sql", "Race %i Class %i Level %i does not have stats data. Using stats data of level %i.", race, class_, level + 1, level); + info->levelInfo[level] = info->levelInfo[level - 1]; } } } @@ -3603,8 +3645,8 @@ void ObjectMgr::LoadPlayerInfo() { if (_playerXPperLevel[level] == 0) { - TC_LOG_ERROR("sql.sql", "Level %i does not have XP for level data. Using data of level [%i] + 100.", level+1, level); - _playerXPperLevel[level] = _playerXPperLevel[level-1]+100; + TC_LOG_ERROR("sql.sql", "Level %i does not have XP for level data. Using data of level [%i] + 100.", level + 1, level); + _playerXPperLevel[level] = _playerXPperLevel[level - 1] + 100; } } @@ -7468,9 +7510,9 @@ void ObjectMgr::LoadGameObjectForQuests() { switch (itr->second.type) { - // scan GO chest with loot including quest items case GAMEOBJECT_TYPE_CHEST: { + // scan GO chest with loot including quest items uint32 loot_id = (itr->second.GetLootId()); // find quest loot for GO @@ -7486,7 +7528,7 @@ void ObjectMgr::LoadGameObjectForQuests() if (itr->second._generic.questID > 0) //quests objects { _gameObjectForQuestStore.insert(itr->second.entry); - count++; + ++count; } break; } @@ -7495,7 +7537,7 @@ void ObjectMgr::LoadGameObjectForQuests() if (itr->second.goober.questId > 0) //quests objects { _gameObjectForQuestStore.insert(itr->second.entry); - count++; + ++count; } break; } @@ -8519,13 +8561,18 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit DefaultCreatureBaseStats() { BaseArmor = 1; - for (uint8 j = 0; j < MAX_CREATURE_BASE_HP; ++j) + for (uint8 j = 0; j < MAX_EXPANSIONS; ++j) + { BaseHealth[j] = 1; + BaseDamage[j] = 0.0f; + } BaseMana = 0; + AttackPower = 0; + RangedAttackPower = 0; } }; - static const DefaultCreatureBaseStats def_stats; - return &def_stats; + static const DefaultCreatureBaseStats defStats; + return &defStats; } void ObjectMgr::LoadCreatureClassLevelStats() @@ -8545,35 +8592,38 @@ void ObjectMgr::LoadCreatureClassLevelStats() { Field* fields = result->Fetch(); - uint8 Level = fields[0].GetInt8(); - uint8 Class = fields[1].GetInt8(); - - CreatureBaseStats stats; - - for (uint8 i = 0; i < MAX_CREATURE_BASE_HP; ++i) - stats.BaseHealth[i] = fields[i + 2].GetInt16(); - - stats.BaseMana = fields[5].GetInt16(); - stats.BaseArmor = fields[6].GetInt16(); - - stats.AttackPower = fields[7].GetInt16(); - stats.RangedAttackPower = fields[8].GetInt16(); - - for (uint8 i = 0; i < MAX_CREATURE_BASE_DAMAGE; ++i) - stats.BaseDamage[i] = fields[i + 9].GetFloat(); + uint8 Level = fields[0].GetUInt8(); + uint8 Class = fields[1].GetUInt8(); if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0) TC_LOG_ERROR("sql.sql", "Creature base stats for level %u has invalid class %u", Level, Class); - for (uint8 i = 0; i < MAX_CREATURE_BASE_HP; ++i) + CreatureBaseStats stats; + + for (uint8 i = 0; i < MAX_EXPANSIONS; ++i) { - if (stats.BaseHealth[i] < 1) + stats.BaseHealth[i] = fields[2 + i].GetUInt16(); + + if (stats.BaseHealth[i] == 0) { TC_LOG_ERROR("sql.sql", "Creature base stats for class %u, level %u has invalid zero base HP[%u] - set to 1", Class, Level, i); stats.BaseHealth[i] = 1; } + + stats.BaseDamage[i] = fields[9 + i].GetFloat(); + if (stats.BaseDamage[i] < 0.0f) + { + TC_LOG_ERROR("sql.sql", "Creature base stats for class %u, level %u has invalid negative base damage[%u] - set to 0.0", Class, Level, i); + stats.BaseDamage[i] = 0.0f; + } } + stats.BaseMana = fields[5].GetUInt16(); + stats.BaseArmor = fields[6].GetUInt16(); + + stats.AttackPower = fields[7].GetUInt16(); + stats.RangedAttackPower = fields[8].GetUInt16(); + _creatureBaseStatsStore[MAKE_PAIR16(Level, Class)] = stats; ++count; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index f5138845012..319b7b589b9 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -835,26 +835,6 @@ namespace Trinity float i_range; }; - class AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck - { - public: - AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck(Unit const* funit, float range) - : i_funit(funit), i_range(range) { } - - bool operator()(const Unit* u) - { - return u->IsAlive() - && i_funit->IsWithinDistInMap(u, i_range) - && !i_funit->IsFriendlyTo(u) - && i_funit->IsValidAttackTarget(u) - && u->GetCreatureType() != CREATURE_TYPE_CRITTER - && i_funit->CanSeeOrDetect(u); - } - private: - Unit const* i_funit; - float i_range; - }; - class CreatureWithDbGUIDCheck { public: diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index c6907d125c0..354f00a9e91 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1960,7 +1960,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) if (isEmpty || method == INSTANCE_RESET_GROUP_DISBAND || method == INSTANCE_RESET_CHANGE_DIFFICULTY) { // do not reset the instance, just unbind if others are permanently bound to it - if (instanceSave->CanReset()) + if (isEmpty && instanceSave->CanReset()) instanceSave->DeleteFromDB(); else { diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 239c0b17e72..f448fbb9f19 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -701,7 +701,7 @@ bool Guild::Member::CheckStats() const return true; } -void Guild::Member::WritePacket(WorldPacket& data) const +void Guild::Member::WritePacket(WorldPacket& data, bool sendOfficerNote) const { data << uint64(m_guid) << uint8(m_flags) @@ -715,8 +715,12 @@ void Guild::Member::WritePacket(WorldPacket& data) const if (!m_flags) data << float(float(::time(NULL) - m_logoutTime) / DAY); - data << m_publicNote - << m_officerNote; + data << m_publicNote; + + if (sendOfficerNote) + data << m_officerNote; + else + data << ""; } // Decreases amount of money/slots left for today. @@ -1299,7 +1303,7 @@ bool Guild::SetName(std::string const& name) return true; } -void Guild::HandleRoster(WorldSession* session /*= NULL*/) +void Guild::HandleRoster(WorldSession* session) { // Guess size WorldPacket data(SMSG_GUILD_ROSTER, (4 + m_motd.length() + 1 + m_info.length() + 1 + 4 + _GetRanksSize() * (4 + 4 + GUILD_BANK_MAX_TABS * (4 + 4)) + m_members.size() * 50)); @@ -1312,18 +1316,10 @@ void Guild::HandleRoster(WorldSession* session /*= NULL*/) ritr->WritePacket(data); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - itr->second->WritePacket(data); + itr->second->WritePacket(data, _HasRankRight(session->GetPlayer(), GR_RIGHT_VIEWOFFNOTE)); - if (session) - { - TC_LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [%s]", session->GetPlayerInfo().c_str()); - session->SendPacket(&data); - } - else - { - TC_LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [Broadcast]"); - BroadcastPacket(&data); - } + TC_LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [%s]", session->GetPlayerInfo().c_str()); + session->SendPacket(&data); } void Guild::HandleQuery(WorldSession* session) diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index aa4c002433a..fca483e92c3 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -315,7 +315,7 @@ private: bool LoadFromDB(Field* fields); void SaveToDB(SQLTransaction& trans) const; - void WritePacket(WorldPacket& data) const; + void WritePacket(WorldPacket& data, bool sendOfficerNote) const; uint64 GetGUID() const { return m_guid; } std::string const& GetName() const { return m_name; } @@ -661,7 +661,7 @@ public: bool SetName(std::string const& name); // Handle client commands - void HandleRoster(WorldSession* session = NULL); // NULL = broadcast + void HandleRoster(WorldSession* session); void HandleQuery(WorldSession* session); void HandleSetMOTD(WorldSession* session, std::string const& motd); void HandleSetInfo(WorldSession* session, std::string const& info); diff --git a/src/server/game/Handlers/BattlefieldHandler.cpp b/src/server/game/Handlers/BattlefieldHandler.cpp index 078c2eb1084..b0580681f91 100644 --- a/src/server/game/Handlers/BattlefieldHandler.cpp +++ b/src/server/game/Handlers/BattlefieldHandler.cpp @@ -15,136 +15,173 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" +#include "Opcodes.h" +#include "Player.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Battlefield.h" #include "BattlefieldMgr.h" -#include "Opcodes.h" -#include "Player.h" -//This send to player windows for invite player to join the war -//Param1:(BattleId) the BattleId of Bf -//Param2:(ZoneId) the zone where the battle is (4197 for wg) -//Param3:(time) Time in second that the player have for accept -void WorldSession::SendBfInvitePlayerToWar(uint32 BattleId, uint32 ZoneId, uint32 p_time) +/** + * @fn void WorldSession::SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 acceptTime) + * + * @brief This send to player windows for invite player to join the war. + * + * @param battleId The BattleId of Bf + * @param zoneId The zone where the battle is (4197 for wg) + * @param acceptTime Time in second that the player have for accept + */ +void WorldSession::SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 acceptTime) { - //Send packet WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, 12); - data << uint32(BattleId); - data << uint32(ZoneId); - data << uint32((time(NULL) + p_time)); - - //Sending the packet to player + data << uint32(battleId); + data << uint32(zoneId); + data << uint32(time(NULL) + acceptTime); SendPacket(&data); } -//This send invitation to player to join the queue -//Param1:(BattleId) the BattleId of Bf -void WorldSession::SendBfInvitePlayerToQueue(uint32 BattleId) +/** + * @fn void WorldSession::SendBfInvitePlayerToQueue(uint32 battleId) + * + * @brief This send invitation to player to join the queue. + * + * @param battleId The BattleId of Bf + */ +void WorldSession::SendBfInvitePlayerToQueue(uint32 battleId) { WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, 5); - - data << uint32(BattleId); - data << uint8(1); //warmup ? used ? - - //Sending packet to player + data << uint32(battleId); + data << uint8(1); // warmup ? used ? SendPacket(&data); } -//This send packet for inform player that he join queue -//Param1:(BattleId) the BattleId of Bf -//Param2:(ZoneId) the zone where the battle is (4197 for wg) -//Param3:(CanQueue) if able to queue -//Param4:(Full) on log in is full -void WorldSession::SendBfQueueInviteResponse(uint32 BattleId, uint32 ZoneId, bool CanQueue, bool Full) +/** + * @fn void WorldSession::SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue, bool full) + * + * @brief This send packet for inform player that he join queue. + * + * @param battleId The BattleId of Bf + * @param zoneId The zone where the battle is (4197 for wg) + * @param canQueue if able to queue + * @param full on log in is full + */ +void WorldSession::SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue, bool full) { WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, 11); - data << uint32(BattleId); - data << uint32(ZoneId); - data << uint8((CanQueue ? 1 : 0)); //Accepted //0 you cannot queue wg //1 you are queued - data << uint8((Full ? 0 : 1)); //Logging In //0 wg full //1 queue for upcoming - data << uint8(1); //Warmup + data << uint32(battleId); + data << uint32(zoneId); + data << uint8(canQueue ? 1 : 0); // Accepted // 0 you cannot queue wg // 1 you are queued + data << uint8(full ? 0 : 1); // Logging In // 0 wg full // 1 queue for upcoming + data << uint8(1); // Warmup SendPacket(&data); } -//This is call when player accept to join war -//Param1:(BattleId) the BattleId of Bf -void WorldSession::SendBfEntered(uint32 BattleId) +/** + * @fn void WorldSession::SendBfEntered(uint32 battleId) + * + * @brief This is call when player accept to join war. + * + * @param battleId The BattleId of Bf + */ +void WorldSession::SendBfEntered(uint32 battleId) { -// m_PlayerInWar[player->GetTeamId()].insert(player->GetGUID()); WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERED, 7); - data << uint32(BattleId); - data << uint8(1); //unk - data << uint8(1); //unk - data << uint8(_player->isAFK() ? 1 : 0); //Clear AFK + data << uint32(battleId); + data << uint8(1); // unk + data << uint8(1); // unk + data << uint8(_player->isAFK() ? 1 : 0); // Clear AFK SendPacket(&data); } -void WorldSession::SendBfLeaveMessage(uint32 BattleId, BFLeaveReason reason) +/** + * @fn void WorldSession::SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason) + * + * @brief This is call when player leave battlefield zone. + * + * @param battleId The BattleId of Bf + * @param reason Reason why player left battlefield + */ +void WorldSession::SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason /*= BF_LEAVE_REASON_EXITED*/) { WorldPacket data(SMSG_BATTLEFIELD_MGR_EJECTED, 7); - data << uint32(BattleId); - data << uint8(reason);//byte Reason - data << uint8(2);//byte BattleStatus - data << uint8(0);//bool Relocated + data << uint32(battleId); + data << uint8(reason); // byte Reason + data << uint8(2); // byte BattleStatus + data << uint8(0); // bool Relocated SendPacket(&data); } -//Send by client when he click on accept for queue -void WorldSession::HandleBfQueueInviteResponse(WorldPacket & recvData) +/** + * @fn void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData) + * + * @brief Send by client when he click on accept for queue. + */ +void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData) { - uint32 BattleId; - uint8 Accepted; + uint32 battleId; + uint8 accepted; + + recvData >> battleId >> accepted; - recvData >> BattleId >> Accepted; - TC_LOG_DEBUG("misc", "HandleQueueInviteResponse: BattleID:%u Accepted:%u", BattleId, Accepted); - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); - if (!Bf) + TC_LOG_DEBUG("misc", "HandleBfQueueInviteResponse: BattleID:%u Accepted:%u", battleId, accepted); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId); + if (!bf) return; - if (Accepted) - { - Bf->PlayerAcceptInviteToQueue(_player); - } + if (accepted) + bf->PlayerAcceptInviteToQueue(_player); } -//Send by client on clicking in accept or refuse of invitation windows for join game -void WorldSession::HandleBfEntryInviteResponse(WorldPacket & recvData) +/** + * @fn void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData) + * + * @brief Send by client on clicking in accept or refuse of invitation windows for join game. + */ +void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData) { - uint32 BattleId; - uint8 Accepted; + uint32 battleId; + uint8 accepted; + + recvData >> battleId >> accepted; + + TC_LOG_DEBUG("misc", "HandleBfEntryInviteResponse: battleId: %u, accepted: %u", battleId, accepted); - recvData >> BattleId >> Accepted; - TC_LOG_DEBUG("misc", "HandleBattlefieldInviteResponse: BattleID:%u Accepted:%u", BattleId, Accepted); - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); - if (!Bf) + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId); + if (!bf) return; - //If player accept invitation - if (Accepted) + // If player accept invitation + if (accepted) { - Bf->PlayerAcceptInviteToWar(_player); + bf->PlayerAcceptInviteToWar(_player); } else { - if (_player->GetZoneId() == Bf->GetZoneId()) - Bf->KickPlayerFromBattlefield(_player->GetGUID()); + if (_player->GetZoneId() == bf->GetZoneId()) + bf->KickPlayerFromBattlefield(_player->GetGUID()); } } -void WorldSession::HandleBfExitRequest(WorldPacket & recvData) +/** + * @fn void WorldSession::HandleBfExitRequest(WorldPacket& recvData) + * + * @brief Send by client when exited battlefield + */ +void WorldSession::HandleBfExitRequest(WorldPacket& recvData) { - uint32 BattleId; + uint32 battleId; + + recvData >> battleId; + + TC_LOG_DEBUG("misc", "HandleBfExitRequest: battleId: %u ", battleId); - recvData >> BattleId; - TC_LOG_DEBUG("misc", "HandleBfExitRequest: BattleID:%u ", BattleId); - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); - if (!Bf) + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId); + if (!bf) return; - Bf->AskToLeaveQueue(_player); + bf->AskToLeaveQueue(_player); } diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index fba575ee84e..45d4d221d06 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -235,18 +235,20 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) recvData.ReadPackedTime(unkPackedTime); recvData >> flags; - CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId, + CalendarEvent calendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId, time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description); - if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement()) + if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement()) if (Player* creator = ObjectAccessor::FindPlayer(guid)) - calendarEvent->SetGuildId(creator->GetGuildId()); + calendarEvent.SetGuildId(creator->GetGuildId()); - if (calendarEvent->IsGuildAnnouncement()) + if (calendarEvent.IsGuildAnnouncement()) { // 946684800 is 01/01/2000 00:00:00 - default response time - CalendarInvite* invite = new CalendarInvite(0, calendarEvent->GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, ""); - sCalendarMgr->AddInvite(calendarEvent, invite); + CalendarInvite invite(0, calendarEvent.GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, ""); + // WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind + // of storage of the pointer as it will lead to memory corruption + sCalendarMgr->AddInvite(&calendarEvent, &invite); } else { @@ -262,12 +264,12 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) recvData >> status >> rank; // 946684800 is 01/01/2000 00:00:00 - default response time - CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), ""); - sCalendarMgr->AddInvite(calendarEvent, invite); + CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent.GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), ""); + sCalendarMgr->AddInvite(&calendarEvent, invite); } } - sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD); + sCalendarMgr->AddEvent(new CalendarEvent(calendarEvent, calendarEvent.GetEventId()), CALENDAR_SENDTYPE_ADD); } void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 6d790919633..4c7d1669233 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1590,9 +1590,6 @@ void WorldSession::HandleEquipmentSetDelete(WorldPacket &recvData) void WorldSession::HandleEquipmentSetUse(WorldPacket &recvData) { - if (_player->IsInCombat()) - return; - TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE"); for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) @@ -1609,6 +1606,10 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recvData) if (itemGuid == 1) continue; + // Only equip weapons in combat + if (_player->IsInCombat() && i != EQUIPMENT_SLOT_MAINHAND && i != EQUIPMENT_SLOT_OFFHAND && i != EQUIPMENT_SLOT_RANGED) + continue; + Item* item = _player->GetItemByGuid(itemGuid); uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8); @@ -1919,6 +1920,8 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) if (result) if (Guild* guild = sGuildMgr->GetGuildById((result->Fetch()[0]).GetUInt32())) guild->DeleteMember(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER), false, false, true); + + Player::LeaveAllArenaTeams(guid); } if (!HasPermission(rbac::RBAC_PERM_TWO_SIDE_ADD_FRIEND)) @@ -1931,12 +1934,8 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND); stmt->setUInt32(0, lowGuid); trans->Append(stmt); - } - // Leave Arena Teams - Player::LeaveAllArenaTeams(guid); - // Reset homebind and position stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND); stmt->setUInt32(0, lowGuid); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index b45840ab190..17b5974d1ca 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -67,6 +67,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) recvData.rfinish(); return; } + if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) @@ -242,6 +243,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: { + // Prevent cheating + if (!sender->IsAlive()) + return; + if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)); @@ -302,18 +307,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { - group = _player->GetGroup(); + group = sender->GetGroup(); if (!group || group->isBGGroup()) return; } - if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(_player->GetGUID())) + if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID())) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), _player, NULL, msg); + ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); } break; case CHAT_MSG_GUILD: @@ -354,7 +359,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), _player, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_LEADER: @@ -364,14 +369,14 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (!group) { group = GetPlayer()->GetGroup(); - if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetGUID())) + if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID())) return; } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), _player, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: @@ -384,7 +389,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) WorldPacket data; //in battleground, raid warning is sent only to players in battleground - code is ok - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), _player, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: @@ -397,7 +402,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), _player, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND_LEADER: @@ -410,74 +415,74 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), _player, NULL, msg);; + ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);; group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: { if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { - if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) + if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)); return; } } - if (ChannelMgr* cMgr = ChannelMgr::forTeam(_player->GetTeam())) + if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam())) { - if (Channel* chn = cMgr->GetChannel(channel, _player)) + if (Channel* chn = cMgr->GetChannel(channel, sender)) { - sScriptMgr->OnPlayerChat(_player, type, lang, msg, chn); - chn->Say(_player->GetGUID(), msg.c_str(), lang); + sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); + chn->Say(sender->GetGUID(), msg.c_str(), lang); } } } break; case CHAT_MSG_AFK: { - if (!_player->IsInCombat()) + if (!sender->IsInCombat()) { - if (_player->isAFK()) // Already AFK + if (sender->isAFK()) // Already AFK { if (msg.empty()) - _player->ToggleAFK(); // Remove AFK + sender->ToggleAFK(); // Remove AFK else - _player->autoReplyMsg = msg; // Update message + sender->autoReplyMsg = msg; // Update message } else // New AFK mode { - _player->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg; + sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg; - if (_player->isDND()) - _player->ToggleDND(); + if (sender->isDND()) + sender->ToggleDND(); - _player->ToggleAFK(); + sender->ToggleAFK(); } - sScriptMgr->OnPlayerChat(_player, type, lang, msg); + sScriptMgr->OnPlayerChat(sender, type, lang, msg); } break; } case CHAT_MSG_DND: { - if (_player->isDND()) // Already DND + if (sender->isDND()) // Already DND { if (msg.empty()) - _player->ToggleDND(); // Remove DND + sender->ToggleDND(); // Remove DND else - _player->autoReplyMsg = msg; // Update message + sender->autoReplyMsg = msg; // Update message } else // New DND mode { - _player->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg; + sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg; - if (_player->isAFK()) - _player->ToggleAFK(); + if (sender->isAFK()) + sender->ToggleAFK(); - _player->ToggleDND(); + sender->ToggleDND(); } - sScriptMgr->OnPlayerChat(_player, type, lang, msg); + sScriptMgr->OnPlayerChat(sender, type, lang, msg); break; } default: diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index b6b4ca84263..6404d3c8e41 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -741,7 +741,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke playerStatus |= MEMBER_STATUS_DEAD; } - if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + if (player->IsFFAPvP()) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) @@ -943,7 +943,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) playerStatus |= MEMBER_STATUS_DEAD; } - if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) + if (player->IsFFAPvP()) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 477b6ddfc77..3571410fd5c 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -991,9 +991,9 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket) void WorldSession::HandleSetAmmoOpcode(WorldPacket& recvData) { - if (!GetPlayer()->IsAlive()) + if (!_player->IsAlive()) { - GetPlayer()->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, NULL, NULL); return; } @@ -1002,10 +1002,18 @@ void WorldSession::HandleSetAmmoOpcode(WorldPacket& recvData) recvData >> item; - if (!item) - GetPlayer()->RemoveAmmo(); + if (item) + { + if (!_player->GetItemCount(item)) + { + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + return; + } + + _player->SetAmmo(item); + } else - GetPlayer()->SetAmmo(item); + _player->RemoveAmmo(); } void WorldSession::SendEnchantmentLog(uint64 target, uint64 caster, uint32 itemId, uint32 enchantId) diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 4fd912298ec..f3a1803dfca 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -223,7 +223,7 @@ void WorldSession::HandleLootOpcode(WorldPacket& recvData) recvData >> guid; // Check possible cheat - if (!_player->IsAlive()) + if (!GetPlayer()->IsAlive() || !IS_CRE_OR_VEH_GUID(guid)) return; GetPlayer()->SendLoot(guid, LOOT_CORPSE); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 5ab24f44a22..10ef7810d1d 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -29,6 +29,32 @@ #include "Item.h" #include "AccountMgr.h" +bool WorldSession::CanOpenMailBox(uint64 guid) +{ + if (guid == _player->GetGUID()) + { + if (!HasPermission(rbac::RBAC_PERM_COMMAND_MAILBOX)) + { + TC_LOG_WARN("cheat", "%s attempt open mailbox in cheating way.", _player->GetName().c_str()); + return false; + } + } + else if (IS_GAMEOBJECT_GUID(guid)) + { + if (!_player->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_MAILBOX)) + return false; + } + else if (IS_CRE_OR_VEH_OR_PET_GUID(guid)) + { + if (!_player->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_MAILBOX)) + return false; + } + else + return false; + + return true; +} + void WorldSession::HandleSendMail(WorldPacket& recvData) { uint64 mailbox, unk3; @@ -62,7 +88,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) // packet read complete, now do check - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; if (receiverName.empty()) @@ -307,7 +333,7 @@ void WorldSession::HandleMailMarkAsRead(WorldPacket& recvData) recvData >> mailbox; recvData >> mailId; - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; Player* player = _player; @@ -331,7 +357,7 @@ void WorldSession::HandleMailDelete(WorldPacket& recvData) recvData >> mailId; recvData.read_skip<uint32>(); // mailTemplateId - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; Mail* m = _player->GetMail(mailId); @@ -359,7 +385,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket& recvData) recvData >> mailId; recvData.read_skip<uint64>(); // original sender GUID for return to, not used - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; Player* player = _player; @@ -424,7 +450,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) recvData >> mailId; recvData >> itemId; // item guid low - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; Player* player = _player; @@ -518,7 +544,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket& recvData) recvData >> mailbox; recvData >> mailId; - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; Player* player = _player; @@ -555,7 +581,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData) uint64 mailbox; recvData >> mailbox; - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; Player* player = _player; @@ -678,7 +704,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData) recvData >> mailbox; recvData >> mailId; - if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) + if (!CanOpenMailBox(mailbox)) return; Player* player = _player; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 7405cbe538b..fcec4f38852 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -734,34 +734,34 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket& recvData) uint64 guid; recvData >> guid; - if (GetPlayer()->IsAlive()) + if (_player->IsAlive()) return; // do not allow corpse reclaim in arena - if (GetPlayer()->InArena()) + if (_player->InArena()) return; // body not released yet - if (!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + if (!_player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) return; - Corpse* corpse = GetPlayer()->GetCorpse(); + Corpse* corpse = _player->GetCorpse(); if (!corpse) return; // prevent resurrect before 30-sec delay after body release not finished - if (time_t(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(time(NULL))) + if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(time(NULL))) return; - if (!corpse->IsWithinDistInMap(GetPlayer(), CORPSE_RECLAIM_RADIUS, true)) + if (!corpse->IsWithinDistInMap(_player, CORPSE_RECLAIM_RADIUS, true)) return; // resurrect - GetPlayer()->ResurrectPlayer(GetPlayer()->InBattleground() ? 1.0f : 0.5f); + _player->ResurrectPlayer(_player->InBattleground() ? 1.0f : 0.5f); // spawn bones - GetPlayer()->SpawnCorpseBones(); + _player->SpawnCorpseBones(); } void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData) @@ -1721,7 +1721,7 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recvData*/) return; _player->BuildPlayerRepop(); - _player->ResurrectPlayer(100); + _player->ResurrectPlayer(1.0f); _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); } diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 08dc8602351..0c2eae849b8 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -381,6 +381,9 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) if (plrMover) // nothing is charmed, or player charmed { + if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING))) + plrMover->SetStandState(UNIT_STAND_STATE_STAND); + plrMover->UpdateFallInformationIfNeed(movementInfo, opcode); if (movementInfo.pos.GetPositionZ() < -500.0f) diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index df6703980d1..4d78064423c 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -103,6 +103,13 @@ void WorldSession::SendShowBank(uint64 guid) SendPacket(&data); } +void WorldSession::SendShowMailBox(uint64 guid) +{ + WorldPacket data(SMSG_SHOW_MAILBOX, 8); + data << guid; + SendPacket(&data); +} + void WorldSession::HandleTrainerListOpcode(WorldPacket& recvData) { uint64 guid; diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index 4487ae7b15f..34899fc23df 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -184,6 +184,14 @@ void WorldSession::HandleActivateTaxiExpressOpcode (WorldPacket& recvData) { uint32 node; recvData >> node; + + if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(node) && !GetPlayer()->isTaxiCheater()) + { + SendActivateTaxiReply(ERR_TAXINOTVISITED); + recvData.rfinish(); + return; + } + nodes.push_back(node); } @@ -290,6 +298,15 @@ void WorldSession::HandleActivateTaxiOpcode(WorldPacket& recvData) return; } + if (!GetPlayer()->isTaxiCheater()) + { + if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[1])) + { + SendActivateTaxiReply(ERR_TAXINOTVISITED); + return; + } + } + GetPlayer()->ActivateTaxiPathTo(nodes, npc); } diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index b9949ac631d..688d7e58b6c 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -49,13 +49,23 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData) // Player must not have ticket if (!ticket || ticket->IsClosed()) { - ticket = new GmTicket(GetPlayer(), recvData); - + uint32 mapId; + float x, y, z; + std::string message; + uint32 needResponse; + bool needMoreHelp; uint32 count; std::list<uint32> times; uint32 decompressedSize; std::string chatLog; + recvData >> mapId; + recvData >> x >> y >> z; + recvData >> message; + + recvData >> needResponse; + recvData >> needMoreHelp; + recvData >> count; for (uint32 i = 0; i < count; i++) @@ -77,19 +87,25 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData) if (uncompress(dest.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK) { dest >> chatLog; - ticket->SetChatLog(times, chatLog); } else { TC_LOG_ERROR("network", "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed."); recvData.rfinish(); - delete ticket; return; } recvData.rfinish(); // Will still have compressed data in buffer. } + ticket = new GmTicket(GetPlayer()); + ticket->SetPosition(mapId, x, y, z); + ticket->SetMessage(message); + ticket->SetGmAction(needResponse, needMoreHelp); + + if (!chatLog.empty()) + ticket->SetChatLog(times, chatLog); + sTicketMgr->AddTicket(ticket); sTicketMgr->UpdateLastChange(); diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index a6690a7e0b3..c46d9002604 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -161,6 +161,16 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) } } +void InstanceSaveManager::UnloadInstanceSave(uint32 InstanceId) +{ + if (InstanceSave* save = GetInstanceSave(InstanceId)) + { + save->UnloadIfEmpty(); + if (save->m_toDelete) + delete save; + } +} + InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset) : m_resetTime(resetTime), m_instanceid(InstanceId), m_mapid(MapId), m_difficulty(difficulty), m_canReset(canReset), m_toDelete(false) { } @@ -232,6 +242,11 @@ bool InstanceSave::UnloadIfEmpty() { if (m_playerList.empty() && m_groupList.empty()) { + // don't remove the save if there are still players inside the map + if (Map* map = sMapMgr->FindMap(GetMapId(), GetInstanceId())) + if (map->HavePlayers()) + return true; + if (!sInstanceSaveMgr->lock_instLists) sInstanceSaveMgr->RemoveInstanceSave(GetInstanceId()); diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index 85c9e081db5..1d753ebaa48 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -115,16 +115,16 @@ class InstanceSave but that would depend on a lot of things that can easily change in future */ Difficulty GetDifficulty() const { return m_difficulty; } + typedef std::list<Player*> PlayerListType; + typedef std::list<Group*> GroupListType; + private: + bool UnloadIfEmpty(); /* used to flag the InstanceSave as to be deleted, so the caller can delete it */ void SetToDelete(bool toDelete) { m_toDelete = toDelete; } - typedef std::list<Player*> PlayerListType; - typedef std::list<Group*> GroupListType; - private: - bool UnloadIfEmpty(); /* the only reason the instSave-object links are kept is because the object-instSave links need to be broken at reset time */ /// @todo: Check if maybe it's enough to just store the number of players/groups @@ -195,6 +195,7 @@ class InstanceSaveManager InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load = false); void RemoveInstanceSave(uint32 InstanceId); + void UnloadInstanceSave(uint32 InstanceId); static void DeleteInstanceFromDB(uint32 instanceid); InstanceSave* GetInstanceSave(uint32 InstanceId); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 39d989ef9bc..21e282cfcf4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2863,6 +2863,7 @@ void InstanceMap::RemovePlayerFromMap(Player* player, bool remove) Map::RemovePlayerFromMap(player, remove); // for normal instances schedule the reset after all players have left SetResetSchedule(true); + sInstanceSaveMgr->UnloadInstanceSave(GetInstanceId()); } void InstanceMap::CreateInstanceData(bool load) diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 6f380d42fda..3102e2c6854 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1215,6 +1215,18 @@ enum TrinityStrings LANG_AUTO_BROADCAST = 11000, LANG_INVALID_REALMID = 11001, + // Show Kick in world + LANG_COMMAND_KICKMESSAGE_WORLD = 11002, + + // Show Mute in world + LANG_COMMAND_MUTEMESSAGE_WORLD = 11003, + + // Show Ban in world + LANG_BAN_CHARACTER_YOUBANNEDMESSAGE_WORLD = 11004, + LANG_BAN_CHARACTER_YOUPERMBANNEDMESSAGE_WORLD = 11005, + LANG_BAN_ACCOUNT_YOUBANNEDMESSAGE_WORLD = 11006, + LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD = 11007, + // NOT RESERVED IDS 12000-1999999999 // `db_script_string` table index 2000000000-2000009999 (MIN_DB_SCRIPT_STRING_ID-MAX_DB_SCRIPT_STRING_ID) // For other tables maybe 2000010000-2147483647 (max index) diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 9d63e97a159..e5d3a5312de 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -44,6 +44,14 @@ enum LootModes LOOT_MODE_HARD_MODE_4 = 0x10 }; +enum Expansions +{ + EXPANSION_CLASSIC = 0, + EXPANSION_THE_BURNING_CRUSADE = 1, + EXPANSION_WRATH_OF_THE_LICH_KING = 2, + MAX_EXPANSIONS = 3 +}; + enum Gender { GENDER_MALE = 0, diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index c05d7804948..aabb117ef50 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -96,11 +96,11 @@ class MotionMaster //: private std::stack<MovementGenerator *> } void push(_Ty _Val) { ++_top; Impl[_top] = _Val; } - bool needInitTop() const - { + bool needInitTop() const + { if (empty()) return false; - return _needInit[_top]; + return _needInit[_top]; } void InitTop(); public: @@ -120,15 +120,15 @@ class MotionMaster //: private std::stack<MovementGenerator *> bool empty() const { return (_top < 0); } int size() const { return _top + 1; } - _Ty top() const - { + _Ty top() const + { ASSERT(!empty()); - return Impl[_top]; + return Impl[_top]; } - _Ty GetMotionSlot(int slot) const - { + _Ty GetMotionSlot(int slot) const + { ASSERT(slot >= 0); - return Impl[slot]; + return Impl[slot]; } void DirectDelete(_Ty curr); diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index bc2460fa709..572d65b07c7 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -25,6 +25,7 @@ #include "MoveSplineInit.h" #include "MoveSpline.h" #include "Player.h" +#include "VMapFactory.h" #define MIN_QUIET_DISTANCE 28.0f #define MAX_QUIET_DISTANCE 43.0f @@ -43,6 +44,20 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner) float x, y, z; _getPoint(owner, x, y, z); + // Add LOS check for target point + Position mypos; + owner->GetPosition(&mypos); + bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetMapId(), + mypos.m_positionX, + mypos.m_positionY, + mypos.m_positionZ + 2.0f, + x, y, z + 2.0f); + if (!isInLOS) + { + i_nextCheckTime.Reset(200); + return; + } + PathGenerator path(owner); path.SetPathLengthLimit(30.0f); bool result = path.CalculatePath(x, y, z); diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index f6ef219522c..87d8e4a0c34 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -60,23 +60,27 @@ namespace Movement { MoveSpline& move_spline = *unit->movespline; - bool transport = false; - Location real_position(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZMinusOffset(), unit->GetOrientation()); - // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID()) - { - transport = true; - real_position.x = unit->GetTransOffsetX(); - real_position.y = unit->GetTransOffsetY(); - real_position.z = unit->GetTransOffsetZ(); - real_position.orientation = unit->GetTransOffsetO(); - } - + // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes (movementInfo.transport.guid is 0 in that case) + bool transport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); + Location real_position; // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows CalculatePath spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports if (!move_spline.Finalized() && move_spline.onTransport == transport) real_position = move_spline.ComputePosition(); + else + { + Position const* pos; + if (!transport) + pos = unit; + else + pos = &unit->m_movementInfo.transport.pos; + + real_position.x = pos->GetPositionX(); + real_position.y = pos->GetPositionY(); + real_position.z = pos->GetPositionZ(); + real_position.orientation = unit->GetOrientation(); + } // should i do the things that user should do? - no. if (args.path.empty()) @@ -135,14 +139,32 @@ namespace Movement if (move_spline.Finalized()) return; - Location loc = move_spline.ComputePosition(); + bool transport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); + Location loc; + if (move_spline.onTransport == transport) + loc = move_spline.ComputePosition(); + else + { + Position const* pos; + if (!transport) + pos = unit; + else + pos = &unit->m_movementInfo.transport.pos; + + loc.x = pos->GetPositionX(); + loc.y = pos->GetPositionY(); + loc.z = pos->GetPositionZ(); + loc.orientation = unit->GetOrientation(); + } + args.flags = MoveSplineFlag::Done; unit->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE_ENABLED); + move_spline.onTransport = transport; move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data.append(unit->GetPackGUID()); - if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID()) + if (transport) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data.appendPackGUID(unit->GetTransGUID()); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index b84a9a6f093..ea02b83f2e8 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -526,7 +526,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode }, /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode}, /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleZoneUpdateOpcode }, + /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleZoneUpdateOpcode }, /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, @@ -931,7 +931,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode }, + /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode }, /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index d3586bf6e8f..904006e174d 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -275,6 +275,8 @@ class WorldSession void SendTrainerList(uint64 guid, std::string const& strTitle); void SendListInventory(uint64 guid); void SendShowBank(uint64 guid); + bool CanOpenMailBox(uint64 guid); + void SendShowMailBox(uint64 guid); void SendTabardVendorActivate(uint64 guid); void SendSpiritResurrect(); void SendBindPoint(Creature* npc); @@ -757,6 +759,16 @@ class WorldSession void HandleBattlemasterJoinArena(WorldPacket& recvData); void HandleReportPvPAFK(WorldPacket& recvData); + // Battlefield + void SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 time); + void SendBfInvitePlayerToQueue(uint32 battleId); + void SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue = true, bool full = false); + void SendBfEntered(uint32 battleId); + void SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); + void HandleBfQueueInviteResponse(WorldPacket& recvData); + void HandleBfEntryInviteResponse(WorldPacket& recvData); + void HandleBfExitRequest(WorldPacket& recvData); + void HandleWardenDataOpcode(WorldPacket& recvData); void HandleWorldTeleportOpcode(WorldPacket& recvData); void HandleMinimapPingOpcode(WorldPacket& recvData); @@ -773,16 +785,6 @@ class WorldSession void HandleHearthAndResurrect(WorldPacket& recvData); void HandleInstanceLockResponse(WorldPacket& recvPacket); - // Battlefield - void SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 time); - void SendBfInvitePlayerToQueue(uint32 battleId); - void SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue = true, bool full = false); - void SendBfEntered(uint32 battleId); - void SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); - void HandleBfQueueInviteResponse(WorldPacket& recvData); - void HandleBfEntryInviteResponse(WorldPacket& recvData); - void HandleBfExitRequest(WorldPacket& recvData); - // Looking for Dungeon/Raid void HandleLfgSetCommentOpcode(WorldPacket& recvData); void HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recvData); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index e2323198df5..e403bf34cc9 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2214,26 +2214,26 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const* aurApp, uint8 mode, WeaponAttackType attType; switch (type) { - case SPELL_AURA_MOD_DISARM: - field=UNIT_FIELD_FLAGS; - flag=UNIT_FLAG_DISARMED; - slot=EQUIPMENT_SLOT_MAINHAND; - attType=BASE_ATTACK; - break; - case SPELL_AURA_MOD_DISARM_OFFHAND: - field=UNIT_FIELD_FLAGS_2; - flag=UNIT_FLAG2_DISARM_OFFHAND; - slot=EQUIPMENT_SLOT_OFFHAND; - attType=OFF_ATTACK; - break; - case SPELL_AURA_MOD_DISARM_RANGED: - field=UNIT_FIELD_FLAGS_2; - flag=UNIT_FLAG2_DISARM_RANGED; - slot=EQUIPMENT_SLOT_RANGED; - attType=RANGED_ATTACK; - break; - default: - return; + case SPELL_AURA_MOD_DISARM: + field = UNIT_FIELD_FLAGS; + flag = UNIT_FLAG_DISARMED; + slot = EQUIPMENT_SLOT_MAINHAND; + attType = BASE_ATTACK; + break; + case SPELL_AURA_MOD_DISARM_OFFHAND: + field = UNIT_FIELD_FLAGS_2; + flag = UNIT_FLAG2_DISARM_OFFHAND; + slot = EQUIPMENT_SLOT_OFFHAND; + attType = OFF_ATTACK; + break; + case SPELL_AURA_MOD_DISARM_RANGED: + field = UNIT_FIELD_FLAGS_2; + flag = UNIT_FLAG2_DISARM_RANGED; + slot = EQUIPMENT_SLOT_RANGED; + attType = RANGED_ATTACK; + break; + default: + return; } // if disarm aura is to be removed, remove the flag first to reapply damage/aura mods @@ -4112,7 +4112,7 @@ void AuraEffect::HandleModAttackSpeed(AuraApplication const* aurApp, uint8 mode, Unit* target = aurApp->GetTarget(); - target->ApplyAttackTimePercentMod(BASE_ATTACK, (float)GetAmount(), apply); + target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply); target->UpdateDamagePhysical(BASE_ATTACK); } @@ -4123,8 +4123,8 @@ void AuraEffect::HandleModMeleeSpeedPct(AuraApplication const* aurApp, uint8 mod Unit* target = aurApp->GetTarget(); - target->ApplyAttackTimePercentMod(BASE_ATTACK, (float)GetAmount(), apply); - target->ApplyAttackTimePercentMod(OFF_ATTACK, (float)GetAmount(), apply); + target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply); + target->ApplyAttackTimePercentMod(OFF_ATTACK, float(GetAmount()), apply); } void AuraEffect::HandleAuraModRangedHaste(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -4371,9 +4371,9 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8 if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) && (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)) { - target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float (GetAmount()), apply); - target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float (GetAmount()), apply); - target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float (GetAmount()), apply); + target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetAmount()), apply); + target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply); + target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetAmount()), apply); if (target->GetTypeId() == TYPEID_PLAYER) target->ToPlayer()->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, float (GetAmount()), apply); @@ -5351,37 +5351,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) target->RemoveAurasDueToSpell(31665); break; - // Killing Spree - case 51690: - { - /// @todo this should use effect[1] of 51690 - UnitList targets; - { - // eff_radius == 0 - float radius = GetSpellInfo()->GetMaxRange(false); - - CellCoord p(Trinity::ComputeCellCoord(target->GetPositionX(), target->GetPositionY())); - Cell cell(p); - - Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck u_check(target, radius); - Trinity::UnitListSearcher<Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck> checker(target, targets, u_check); - - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); - - cell.Visit(p, grid_object_checker, *GetBase()->GetOwner()->GetMap(), *target, radius); - cell.Visit(p, world_object_checker, *GetBase()->GetOwner()->GetMap(), *target, radius); - } - - if (targets.empty()) - return; - - Unit* spellTarget = Trinity::Containers::SelectRandomContainerElement(targets); - - target->CastSpell(spellTarget, 57840, true); - target->CastSpell(spellTarget, 57841, true); - break; - } // Overkill case 58428: if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) @@ -5699,9 +5668,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) case 46284: target->CastCustomSpell(triggerSpellId, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this); return; - // Poison (Grobbulus) - case 28158: - case 54362: // Slime Pool (Dreadscale & Acidmaw) case 66882: target->CastCustomSpell(triggerSpellId, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000 * 2 / 3), NULL, true, NULL, this); @@ -6124,8 +6090,10 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const if (target != caster && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL) { uint32 funnelDamage = GetSpellInfo()->ManaPerSecond; // damage is not affected by spell power - if ((int32)funnelDamage > gain) + + if ((int32)funnelDamage > gain && gain > 0) funnelDamage = gain; + uint32 funnelAbsorb = 0; caster->DealDamageMods(caster, funnelDamage, &funnelAbsorb); caster->SendSpellNonMeleeDamageLog(caster, GetId(), funnelDamage, GetSpellInfo()->GetSchoolMask(), funnelAbsorb, 0, false, 0, false); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 4aedc1a95eb..08e0323b491 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -85,9 +85,26 @@ SpellDestination::SpellDestination(WorldObject const& wObj) _transportGUID = wObj.GetTransGUID(); _transportOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO()); _position.Relocate(wObj); - _position.SetOrientation(wObj.GetOrientation()); } +void SpellDestination::Relocate(Position const& pos) +{ + if (_transportGUID) + { + Position offset; + _position.GetPositionOffsetTo(pos, offset); + _transportOffset.RelocateOffset(offset); + } + _position.Relocate(pos); +} + +void SpellDestination::RelocateOffset(Position const& offset) +{ + if (_transportGUID) + _transportOffset.RelocateOffset(offset); + + _position.RelocateOffset(offset); +} SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget() { @@ -350,14 +367,7 @@ void SpellCastTargets::SetSrc(WorldObject const& wObj) void SpellCastTargets::ModSrc(Position const& pos) { ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION); - - if (m_src._transportGUID) - { - Position offset; - m_src._position.GetPositionOffsetTo(pos, offset); - m_src._transportOffset.RelocateOffset(offset); - } - m_src._position.Relocate(pos); + m_src.Relocate(pos); } void SpellCastTargets::RemoveSrc() @@ -393,6 +403,12 @@ void SpellCastTargets::SetDst(WorldObject const& wObj) m_targetMask |= TARGET_FLAG_DEST_LOCATION; } +void SpellCastTargets::SetDst(SpellDestination const& spellDest) +{ + m_dst = spellDest; + m_targetMask |= TARGET_FLAG_DEST_LOCATION; +} + void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets) { m_dst = spellTargets.m_dst; @@ -402,14 +418,13 @@ void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets) void SpellCastTargets::ModDst(Position const& pos) { ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION); + m_dst.Relocate(pos); +} - if (m_dst._transportGUID) - { - Position offset; - m_dst._position.GetPositionOffsetTo(pos, offset); - m_dst._transportOffset.RelocateOffset(offset); - } - m_dst._position.Relocate(pos); +void SpellCastTargets::ModDst(SpellDestination const& spellDest) +{ + ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION); + m_dst = spellDest; } void SpellCastTargets::RemoveDst() @@ -1090,24 +1105,13 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge Trinity::Containers::RandomResizeList(targets, maxTargets); } - // for compability with older code - add only unit and go targets - /// @todo remove this - std::list<Unit*> unitTargets; - std::list<GameObject*> gObjTargets; - for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) { if (Unit* unitTarget = (*itr)->ToUnit()) - unitTargets.push_back(unitTarget); + AddUnitTarget(unitTarget, effMask, false); else if (GameObject* gObjTarget = (*itr)->ToGameObject()) - gObjTargets.push_back(gObjTarget); + AddGOTarget(gObjTarget, effMask); } - - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) - AddUnitTarget(*itr, effMask, false); - - for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr) - AddGOTarget(*itr, effMask); } } } @@ -1395,31 +1399,32 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { + SpellDestination dest(*m_caster); + switch (targetType.GetTarget()) { case TARGET_DEST_CASTER: - m_targets.SetDst(*m_caster); - return; + break; case TARGET_DEST_HOME: if (Player* playerCaster = m_caster->ToPlayer()) - m_targets.SetDst(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId); - return; + dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId); + break; case TARGET_DEST_DB: if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex)) { /// @todo fix this check if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND)) - m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId); + dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId); else if (st->target_mapId == m_caster->GetMapId()) - m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation); + dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation); } else { TC_LOG_DEBUG("spells", "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id); - WorldObject* target = m_targets.GetObjectTarget(); - m_targets.SetDst(target ? *target : *m_caster); + if (WorldObject* target = m_targets.GetObjectTarget()) + dest = SpellDestination(*target); } - return; + break; case TARGET_DEST_CASTER_FISHING: { float min_dis = m_spellInfo->GetMinRange(true); @@ -1447,60 +1452,70 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici return; } - m_targets.SetDst(x, y, liquidLevel, m_caster->GetOrientation()); - return; + dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation()); + break; } default: - break; - } + { + float dist; + float angle = targetType.CalcDirectionAngle(); + float objSize = m_caster->GetObjectSize(); + if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON) + dist = PET_FOLLOW_DIST; + else + dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - float dist; - float angle = targetType.CalcDirectionAngle(); - float objSize = m_caster->GetObjectSize(); - if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON) - dist = PET_FOLLOW_DIST; - else - dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + if (dist < objSize) + dist = objSize; + else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM) + dist = objSize + (dist - objSize) * float(rand_norm()); - if (dist < objSize) - dist = objSize; - else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM) - dist = objSize + (dist - objSize) * (float)rand_norm(); + Position pos = dest._position; + if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP) + m_caster->MovePositionToFirstCollision(pos, dist, angle); + else + m_caster->MovePosition(pos, dist, angle); - Position pos; - if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP) - m_caster->GetFirstCollisionPosition(pos, dist, angle); - else - m_caster->GetNearPosition(pos, dist, angle); - m_targets.SetDst(*m_caster); - m_targets.ModDst(pos); + dest.Relocate(pos); + break; + } + } + + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.SetDst(dest); } void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { WorldObject* target = m_targets.GetObjectTarget(); + + SpellDestination dest(*target); + switch (targetType.GetTarget()) { case TARGET_DEST_TARGET_ENEMY: case TARGET_DEST_TARGET_ANY: - m_targets.SetDst(*target); - return; + break; default: + { + float angle = targetType.CalcDirectionAngle(); + float objSize = target->GetObjectSize(); + float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + if (dist < objSize) + dist = objSize; + else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM) + dist = objSize + (dist - objSize) * float(rand_norm()); + + Position pos = dest._position; + target->MovePosition(pos, dist, angle); + + dest.Relocate(pos); break; + } } - float angle = targetType.CalcDirectionAngle(); - float objSize = target->GetObjectSize(); - float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - if (dist < objSize) - dist = objSize; - else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM) - dist = objSize + (dist - objSize) * (float)rand_norm(); - - Position pos; - target->GetNearPosition(pos, dist, angle); - m_targets.SetDst(*target); - m_targets.ModDst(pos); + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.SetDst(dest); } void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) @@ -1509,8 +1524,9 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT // can only happen if previous destination target could not be set for some reason // (not found nearby target, or channel target for example // maybe we should abort the spell in such case? - if (!m_targets.HasDst()) - m_targets.SetDst(*m_caster); + CheckDst(); + + SpellDestination dest(*m_targets.GetDst()); switch (targetType.GetTarget()) { @@ -1520,20 +1536,25 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT case TARGET_DEST_DEST: return; case TARGET_DEST_TRAJ: - SelectImplicitTrajTargets(); + SelectImplicitTrajTargets(effIndex); return; default: + { + float angle = targetType.CalcDirectionAngle(); + float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); + if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM) + dist *= float(rand_norm()); + + Position pos = dest._position; + m_caster->MovePosition(pos, dist, angle); + + dest.Relocate(pos); break; + } } - float angle = targetType.CalcDirectionAngle(); - float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); - if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM) - dist *= (float)rand_norm(); - - Position pos = *m_targets.GetDstPos(); - m_caster->MovePosition(pos, dist, angle); - m_targets.ModDst(pos); + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.ModDst(dest); } void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) @@ -1624,14 +1645,9 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg // Chain primary target is added earlier CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); - // for backward compability - std::list<Unit*> unitTargets; for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) if (Unit* unitTarget = (*itr)->ToUnit()) - unitTargets.push_back(unitTarget); - - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) - AddUnitTarget(*itr, effMask, false); + AddUnitTarget(unitTarget, effMask, false); } } @@ -1649,7 +1665,7 @@ float tangent(float x) #define DEBUG_TRAJ(a) //a -void Spell::SelectImplicitTrajTargets() +void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) { if (!m_targets.HasTraj()) return; @@ -1778,7 +1794,11 @@ void Spell::SelectImplicitTrajTargets() Position trajDst; trajDst.Relocate(x, y, z, m_caster->GetOrientation()); - m_targets.ModDst(trajDst); + SpellDestination dest(*m_targets.GetDst()); + dest.Relocate(trajDst); + + CallScriptDestinationTargetSelectHandlers(dest, effIndex); + m_targets.ModDst(dest); } } @@ -4760,6 +4780,10 @@ SpellCastResult Spell::CheckCast(bool strict) else return SPELL_FAILED_NOT_READY; } + + // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat + if (m_caster->ToPlayer()->GetLastPotionId() && m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent())) + return SPELL_FAILED_NOT_READY; } if (m_spellInfo->AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL && !m_caster->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_ALLOW_CHEAT_SPELLS)) @@ -7173,6 +7197,20 @@ void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffI } } +void Spell::CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex) +{ + for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT); + std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin(); + for (; hookItr != hookItrEnd; ++hookItr) + if (hookItr->IsEffectAffected(m_spellInfo, effIndex)) + hookItr->Call(*scritr, target); + + (*scritr)->_FinishScriptCall(); + } +} + bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck) { // Skip if there are not any script diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 5653bc1194f..76be075e94d 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -87,6 +87,9 @@ struct SpellDestination SpellDestination(Position const& pos); SpellDestination(WorldObject const& wObj); + void Relocate(Position const& pos); + void RelocateOffset(Position const& offset); + WorldLocation _position; uint64 _transportGUID; Position _transportOffset; @@ -141,8 +144,10 @@ class SpellCastTargets void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID); void SetDst(Position const& pos); void SetDst(WorldObject const& wObj); + void SetDst(SpellDestination const& spellDest); void SetDst(SpellCastTargets const& spellTargets); void ModDst(Position const& pos); + void ModDst(SpellDestination const& spellDest); void RemoveDst(); bool HasSrc() const { return GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION; } @@ -301,7 +306,7 @@ class Spell void EffectKnockBack(SpellEffIndex effIndex); void EffectPullTowards(SpellEffIndex effIndex); void EffectDispelMechanic(SpellEffIndex effIndex); - void EffectSummonDeadPet(SpellEffIndex effIndex); + void EffectResurrectPet(SpellEffIndex effIndex); void EffectDestroyAllTotems(SpellEffIndex effIndex); void EffectDurabilityDamage(SpellEffIndex effIndex); void EffectSkill(SpellEffIndex effIndex); @@ -359,7 +364,7 @@ class Spell void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType); void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType); void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask); - void SelectImplicitTrajTargets(); + void SelectImplicitTrajTargets(SpellEffIndex effIndex); void SelectEffectTypeImplicitTargets(uint8 effIndex); @@ -636,6 +641,7 @@ class Spell void CallScriptAfterHitHandlers(); void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex); void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex); + void CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex); bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck); std::list<SpellScript*> m_loadedScripts; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 9a2b3815285..1369d915773 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -175,7 +175,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectSummonObject, //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 &Spell::EffectSummonObject, //107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 &Spell::EffectDispelMechanic, //108 SPELL_EFFECT_DISPEL_MECHANIC - &Spell::EffectSummonDeadPet, //109 SPELL_EFFECT_SUMMON_DEAD_PET + &Spell::EffectResurrectPet, //109 SPELL_EFFECT_RESURRECT_PET &Spell::EffectDestroyAllTotems, //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS &Spell::EffectDurabilityDamage, //111 SPELL_EFFECT_DURABILITY_DAMAGE &Spell::EffectUnused, //112 SPELL_EFFECT_112 @@ -2326,7 +2326,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION)) return; - summon->SelectLevel(summon->GetCreatureTemplate()); // some summoned creaters have different from 1 DB data for level/hp + summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp summon->SetUInt32Value(UNIT_NPC_FLAGS, summon->GetCreatureTemplate()->npcflag); summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); @@ -2538,8 +2538,6 @@ void Spell::EffectDualWield(SpellEffIndex /*effIndex*/) return; unitTarget->SetCanDualWield(true); - if (unitTarget->GetTypeId() == TYPEID_UNIT) - unitTarget->ToCreature()->UpdateDamagePhysical(OFF_ATTACK); } void Spell::EffectPull(SpellEffIndex effIndex) @@ -5051,7 +5049,7 @@ void Spell::EffectDispelMechanic(SpellEffIndex effIndex) } } -void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/) +void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; @@ -5063,9 +5061,9 @@ void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/) if (!player) return; - // Maybe player dismissed dead pet or pet despawned? bool hadPet = true; + if (!player->GetPet()) { // Position passed to SummonPet is irrelevant with current implementation, @@ -5076,11 +5074,7 @@ void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/) // TODO: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends Pet* pet = player->GetPet(); // Attempt to get current pet - if (!pet) - return; - - // TODO: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends - if (pet->IsAlive()) + if (!pet || pet->IsAlive()) return; // If player did have a pet before reviving, teleport it @@ -5819,11 +5813,11 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* { if (uint32 weapon = m_caster->GetUInt32Value(PLAYER_VISIBLE_ITEM_16_ENTRYID)) { - summon->SetDisplayId(11686); + summon->SetDisplayId(11686); // modelid2 summon->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, weapon); } else - summon->SetDisplayId(1126); + summon->SetDisplayId(1126); // modelid1 } summon->AI()->EnterEvadeMode(); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 2861ddf049f..33eb0cdf6e4 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -455,6 +455,8 @@ uint32 SpellMgr::GetSpellDifficultyId(uint32 spellId) const void SpellMgr::SetSpellDifficultyId(uint32 spellId, uint32 id) { + if (uint32 i = GetSpellDifficultyId(spellId)) + TC_LOG_ERROR("spells", "SpellMgr::SetSpellDifficultyId: Spell %u has already spellDifficultyId %u. Will override with spellDifficultyId %u.", spellId, i, id); mSpellDifficultySearcherMap[spellId] = id; } @@ -480,7 +482,7 @@ uint32 SpellMgr::GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) con SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId); if (!difficultyEntry) { - TC_LOG_DEBUG("spells", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell %u. This should never happen.", spellId); + TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell %u. This should never happen.", spellId); return spellId; //return source spell } @@ -812,7 +814,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr { if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS) { - if (!(procExtra & PROC_EX_INTERNAL_DOT)) + if (!(procExtra & PROC_EX_INTERNAL_HOT)) return false; } else if (procExtra & PROC_EX_INTERNAL_HOT) @@ -3042,6 +3044,9 @@ void SpellMgr::LoadSpellInfoCorrections() case 42730: spellInfo->Effects[EFFECT_1].TriggerSpell = 42739; break; + case 42436: // Drink! (Brewfest) + spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY); + break; case 59735: spellInfo->Effects[EFFECT_1].TriggerSpell = 59736; break; @@ -3690,6 +3695,9 @@ void SpellMgr::LoadSpellInfoCorrections() // // RUBY SANCTUM SPELLS // + case 74799: // Soul Consumption + spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS); + break; case 74769: // Twilight Cutter case 77844: // Twilight Cutter case 77845: // Twilight Cutter diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 7301e693978..c7eebb495c0 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -203,8 +203,8 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript) (spellScript->*pHitHandlerScript)(); } -SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area) - : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area) { } +SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest) + : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area), dest(_dest) { } std::string SpellScript::TargetHook::ToString() { @@ -236,8 +236,9 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff switch (targetInfo.GetObjectType()) { case TARGET_OBJECT_TYPE_SRC: // EMPTY - case TARGET_OBJECT_TYPE_DEST: // EMPTY return false; + case TARGET_OBJECT_TYPE_DEST: // DEST + return dest; default: switch (targetInfo.GetReferenceType()) { @@ -259,7 +260,7 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff } SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) - : TargetHook(_effIndex, _targetType, true) + : TargetHook(_effIndex, _targetType, true, false) { pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript; } @@ -270,7 +271,7 @@ void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript, } SpellScript::ObjectTargetSelectHandler::ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) - : TargetHook(_effIndex, _targetType, false) + : TargetHook(_effIndex, _targetType, false, false) { pObjectTargetSelectHandlerScript = _pObjectTargetSelectHandlerScript; } @@ -280,6 +281,17 @@ void SpellScript::ObjectTargetSelectHandler::Call(SpellScript* spellScript, Worl (spellScript->*pObjectTargetSelectHandlerScript)(target); } +SpellScript::DestinationTargetSelectHandler::DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) + : TargetHook(_effIndex, _targetType, false, true) +{ + DestinationTargetSelectHandlerScript = _DestinationTargetSelectHandlerScript; +} + +void SpellScript::DestinationTargetSelectHandler::Call(SpellScript* spellScript, SpellDestination& target) +{ + (spellScript->*DestinationTargetSelectHandlerScript)(target); +} + bool SpellScript::_Validate(SpellInfo const* entry) { for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr) @@ -306,6 +318,10 @@ bool SpellScript::_Validate(SpellInfo const* entry) if (!(*itr).GetAffectedEffectsMask(entry)) TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + for (std::list<DestinationTargetSelectHandler>::iterator itr = OnDestinationTargetSelect.begin(); itr != OnDestinationTargetSelect.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnDestinationTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + return _SpellScript::_Validate(entry); } diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 75cf63b495b..dfa494e38e6 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -135,6 +135,7 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_AFTER_HIT, SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT, SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT, + SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT, SPELL_SCRIPT_HOOK_CHECK_CAST, SPELL_SCRIPT_HOOK_BEFORE_CAST, SPELL_SCRIPT_HOOK_ON_CAST, @@ -158,7 +159,8 @@ class SpellScript : public _SpellScript typedef void(CLASSNAME::*SpellHitFnType)(); \ typedef void(CLASSNAME::*SpellCastFnType)(); \ typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \ - typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); + typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); \ + typedef void(CLASSNAME::*SpellDestinationTargetSelectFnType)(SpellDestination&); SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript) @@ -203,12 +205,13 @@ class SpellScript : public _SpellScript class TargetHook : public _SpellScript::EffectHook { public: - TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area); + TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest); bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex); std::string ToString(); protected: uint16 targetType; bool area; + bool dest; }; class ObjectAreaTargetSelectHandler : public TargetHook @@ -224,18 +227,28 @@ class SpellScript : public _SpellScript { public: ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); - void Call(SpellScript* spellScript, WorldObject*& targets); + void Call(SpellScript* spellScript, WorldObject*& target); private: SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript; }; + class DestinationTargetSelectHandler : public TargetHook + { + public: + DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); + void Call(SpellScript* spellScript, SpellDestination& target); + private: + SpellDestinationTargetSelectFnType DestinationTargetSelectHandlerScript; + }; + #define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ class CastHandlerFunction : public SpellScript::CastHandler { public: CastHandlerFunction(SpellCastFnType _pCastHandlerScript) : SpellScript::CastHandler((SpellScript::SpellCastFnType)_pCastHandlerScript) { } }; \ class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) { } }; \ class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) { } }; \ class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) { } }; \ class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) { } }; \ - class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; + class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; \ + class DestinationTargetSelectHandlerFunction : public SpellScript::DestinationTargetSelectHandler { public: DestinationTargetSelectHandlerFunction(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::DestinationTargetSelectHandler((SpellScript::SpellDestinationTargetSelectFnType)_DestinationTargetSelectHandlerScript, _effIndex, _targetType) { } }; #define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) public: @@ -299,11 +312,17 @@ class SpellScript : public _SpellScript HookList<ObjectTargetSelectHandler> OnObjectTargetSelect; #define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandlerFunction(&F, I, N) + // example: OnDestinationTargetSelect += SpellDestinationTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); + // where function is void function(SpellDestination& target) + HookList<DestinationTargetSelectHandler> OnDestinationTargetSelect; + #define SpellDestinationTargetSelectFn(F, I, N) DestinationTargetSelectHandlerFunction(&F, I, N) + // hooks are executed in following order, at specified event of spell: // 1. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled // 2. OnCheckCast - allows to override result of CheckCast function // 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets) // 3b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets) + // 3c. OnDestinationTargetSelect - executed just before adding selected target to final target list (for destination targets) // 4. OnCast - executed just before spell is launched (creates missile) or executed // 5. AfterCast - executed after spell missile is launched and immediate spell actions are done // 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index 83c049363d4..43c9ba80e24 100644 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -34,26 +34,13 @@ inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; } // GM ticket GmTicket::GmTicket() : _id(0), _playerGuid(0), _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(0), _lastModifiedTime(0), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), - _needResponse(false), _haveTicket(false) { } + _needResponse(false), _needMoreHelp(false) { } -GmTicket::GmTicket(Player* player, WorldPacket& recvData) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _haveTicket(false) +GmTicket::GmTicket(Player* player) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needResponse(false), _needMoreHelp(false) { _id = sTicketMgr->GenerateTicketId(); _playerName = player->GetName(); _playerGuid = player->GetGUID(); - - uint32 mapId; - recvData >> mapId; // Map is sent as UInt32! - _mapId = mapId; - - recvData >> _posX; - recvData >> _posY; - recvData >> _posZ; - recvData >> _message; - uint32 needResponse; - recvData >> needResponse; - _needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default) - recvData >> _haveTicket; // Requests further GM interaction on a ticket to which a GM has already responded. Basically means "has a new ticket" } GmTicket::~GmTicket() { } @@ -80,7 +67,7 @@ bool GmTicket::LoadFromDB(Field* fields) _completed = fields[++index].GetBool(); _escalatedStatus = GMTicketEscalationStatus(fields[++index].GetUInt8()); _viewed = fields[++index].GetBool(); - _haveTicket = fields[++index].GetBool(); + _needMoreHelp = fields[++index].GetBool(); return true; } @@ -107,7 +94,7 @@ void GmTicket::SaveToDB(SQLTransaction& trans) const stmt->setBool (++index, _completed); stmt->setUInt8 (++index, uint8(_escalatedStatus)); stmt->setBool (++index, _viewed); - stmt->setBool (++index, _haveTicket); + stmt->setBool (++index, _needMoreHelp); CharacterDatabase.ExecuteOrAppend(trans, stmt); } @@ -124,7 +111,7 @@ void GmTicket::WritePacket(WorldPacket& data) const data << uint32(GMTICKET_STATUS_HASTEXT); data << uint32(_id); data << _message; - data << uint8(_haveTicket); + data << uint8(_needMoreHelp); data << GetAge(_lastModifiedTime); if (GmTicket* ticket = sTicketMgr->GetOldestOpenTicket()) data << GetAge(ticket->GetLastModifiedTime()); @@ -220,6 +207,20 @@ void GmTicket::SetUnassigned() } } +void GmTicket::SetPosition(uint32 mapId, float x, float y, float z) +{ + _mapId = mapId; + _posX = x; + _posY = y; + _posZ = z; +} + +void GmTicket::SetGmAction(uint32 needResponse, bool needMoreHelp) +{ + _needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default) + _needMoreHelp = needMoreHelp; // Requests further GM interaction on a ticket to which a GM has already responded. Basically means "has a new ticket" +} + void GmTicket::TeleportTo(Player* player) const { player->TeleportTo(_mapId, _posX, _posY, _posZ, 0.0f, 0); diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h index 3dd048189d7..5bfe78abbba 100644 --- a/src/server/game/Tickets/TicketMgr.h +++ b/src/server/game/Tickets/TicketMgr.h @@ -82,7 +82,7 @@ class GmTicket { public: GmTicket(); - GmTicket(Player* player, WorldPacket& recvData); + GmTicket(Player* player); ~GmTicket(); bool IsClosed() const { return _closedBy; } @@ -129,6 +129,8 @@ public: void SetComment(std::string const& comment) { _comment = comment; } void SetViewed() { _viewed = true; } void SetUnassigned(); + void SetPosition(uint32 mapId, float x, float y, float z); + void SetGmAction(uint32 needResponse, bool needMoreHelp); void AppendResponse(std::string const& response) { _response += response; } @@ -164,7 +166,7 @@ private: GMTicketEscalationStatus _escalatedStatus; bool _viewed; bool _needResponse; /// @todo find out the use of this, and then store it in DB - bool _haveTicket; + bool _needMoreHelp; std::string _response; std::string _chatLog; // No need to store in db, will be refreshed every session client side }; diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index 2462fc203d2..4611a4da884 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -32,7 +32,7 @@ Warden::Warden() : _session(NULL), _inputCrypto(16), _outputCrypto(16), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), _dataSent(false), _previousTimestamp(0), _module(NULL), _initialized(false) -{ +{ memset(_inputKey, 0, sizeof(_inputKey)); memset(_outputKey, 0, sizeof(_outputKey)); memset(_seed, 0, sizeof(_seed)); diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp index b9133c9d0b1..cb332df9a41 100644 --- a/src/server/game/Weather/Weather.cpp +++ b/src/server/game/Weather/Weather.cpp @@ -194,7 +194,6 @@ bool Weather::ReGenerate() void Weather::SendWeatherUpdateToPlayer(Player* player) { WorldPacket data(SMSG_WEATHER, (4+4+4)); - data << uint32(GetWeatherState()) << (float)m_grade << uint8(0); player->GetSession()->SendPacket(&data); } @@ -202,10 +201,6 @@ void Weather::SendWeatherUpdateToPlayer(Player* player) /// Send the new weather to all players in the zone bool Weather::UpdateWeather() { - Player* player = sWorld->FindPlayerInZone(m_zone); - if (!player) - return false; - ///- Send the weather packet to all players in this zone if (m_grade >= 1) m_grade = 0.9999f; @@ -215,8 +210,13 @@ bool Weather::UpdateWeather() WeatherState state = GetWeatherState(); WorldPacket data(SMSG_WEATHER, (4+4+4)); - data << uint32(state) << (float)m_grade << uint8(0); - player->SendMessageToSet(&data, true); + data << uint32(state); + data << (float)m_grade; + data << uint8(0); + + //- Returns false if there were no players found to update + if (!sWorld->SendZoneMessage(m_zone, &data)) + return false; ///- Log the event char const* wthstr; @@ -263,8 +263,8 @@ bool Weather::UpdateWeather() wthstr = "fine"; break; } - TC_LOG_INFO("misc", "Change the weather of zone %u to %s.", m_zone, wthstr); + TC_LOG_INFO("misc", "Change the weather of zone %u to %s.", m_zone, wthstr); sScriptMgr->OnWeatherChange(this, state, m_grade); return true; } diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index e327836fa4a..886a910becc 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -145,7 +145,6 @@ void LoadWeatherData() void SendFineWeatherUpdateToPlayer(Player* player) { WorldPacket data(SMSG_WEATHER, (4+4+4)); - data << (uint32)WEATHER_STATE_FINE << (float)0.0f << uint8(0); player->GetSession()->SendPacket(&data); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index c071505e97c..3fde3ad4a11 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -169,10 +169,7 @@ Player* World::FindPlayerInZone(uint32 zone) continue; if (player->IsInWorld() && player->GetZoneId() == zone) - { - // Used by the weather system. We return the player to broadcast the change weather message to him and all players in the zone. return player; - } } return NULL; } @@ -431,27 +428,27 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_ENABLE_SINFO_LOGIN] = sConfigMgr->GetIntDefault("Server.LoginInfo", 0); ///- Read all rates from the config file - rate_values[RATE_HEALTH] = sConfigMgr->GetFloatDefault("Rate.Health", 1); + rate_values[RATE_HEALTH] = sConfigMgr->GetFloatDefault("Rate.Health", 1.0f); if (rate_values[RATE_HEALTH] < 0) { TC_LOG_ERROR("server.loading", "Rate.Health (%f) must be > 0. Using 1 instead.", rate_values[RATE_HEALTH]); rate_values[RATE_HEALTH] = 1; } - rate_values[RATE_POWER_MANA] = sConfigMgr->GetFloatDefault("Rate.Mana", 1); + rate_values[RATE_POWER_MANA] = sConfigMgr->GetFloatDefault("Rate.Mana", 1.0f); if (rate_values[RATE_POWER_MANA] < 0) { TC_LOG_ERROR("server.loading", "Rate.Mana (%f) must be > 0. Using 1 instead.", rate_values[RATE_POWER_MANA]); rate_values[RATE_POWER_MANA] = 1; } - rate_values[RATE_POWER_RAGE_INCOME] = sConfigMgr->GetFloatDefault("Rate.Rage.Income", 1); - rate_values[RATE_POWER_RAGE_LOSS] = sConfigMgr->GetFloatDefault("Rate.Rage.Loss", 1); + rate_values[RATE_POWER_RAGE_INCOME] = sConfigMgr->GetFloatDefault("Rate.Rage.Income", 1.0f); + rate_values[RATE_POWER_RAGE_LOSS] = sConfigMgr->GetFloatDefault("Rate.Rage.Loss", 1.0f); if (rate_values[RATE_POWER_RAGE_LOSS] < 0) { TC_LOG_ERROR("server.loading", "Rate.Rage.Loss (%f) must be > 0. Using 1 instead.", rate_values[RATE_POWER_RAGE_LOSS]); rate_values[RATE_POWER_RAGE_LOSS] = 1; } - rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfigMgr->GetFloatDefault("Rate.RunicPower.Income", 1); - rate_values[RATE_POWER_RUNICPOWER_LOSS] = sConfigMgr->GetFloatDefault("Rate.RunicPower.Loss", 1); + rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfigMgr->GetFloatDefault("Rate.RunicPower.Income", 1.0f); + rate_values[RATE_POWER_RUNICPOWER_LOSS] = sConfigMgr->GetFloatDefault("Rate.RunicPower.Loss", 1.0f); if (rate_values[RATE_POWER_RUNICPOWER_LOSS] < 0) { TC_LOG_ERROR("server.loading", "Rate.RunicPower.Loss (%f) must be > 0. Using 1 instead.", rate_values[RATE_POWER_RUNICPOWER_LOSS]); @@ -645,8 +642,8 @@ void World::LoadConfigSettings(bool reload) m_float_configs[CONFIG_MAX_RECRUIT_A_FRIEND_DISTANCE] = sConfigMgr->GetFloatDefault("MaxRecruitAFriendBonusDistance", 100.0f); /// @todo Add MonsterSight and GuarderSight (with meaning) in worldserver.conf or put them as define - m_float_configs[CONFIG_SIGHT_MONSTER] = sConfigMgr->GetFloatDefault("MonsterSight", 50); - m_float_configs[CONFIG_SIGHT_GUARDER] = sConfigMgr->GetFloatDefault("GuarderSight", 50); + m_float_configs[CONFIG_SIGHT_MONSTER] = sConfigMgr->GetFloatDefault("MonsterSight", 50.0f); + m_float_configs[CONFIG_SIGHT_GUARDER] = sConfigMgr->GetFloatDefault("GuarderSight", 50.0f); if (reload) { @@ -947,12 +944,12 @@ void World::LoadConfigSettings(bool reload) if (reload) { - uint32 val = sConfigMgr->GetIntDefault("Expansion", 1); + uint32 val = sConfigMgr->GetIntDefault("Expansion", 2); if (val != m_int_configs[CONFIG_EXPANSION]) TC_LOG_ERROR("server.loading", "Expansion option can't be changed at worldserver.conf reload, using current value (%u).", m_int_configs[CONFIG_EXPANSION]); } else - m_int_configs[CONFIG_EXPANSION] = sConfigMgr->GetIntDefault("Expansion", 1); + m_int_configs[CONFIG_EXPANSION] = sConfigMgr->GetIntDefault("Expansion", 2); m_int_configs[CONFIG_CHATFLOOD_MESSAGE_COUNT] = sConfigMgr->GetIntDefault("ChatFlood.MessageCount", 10); m_int_configs[CONFIG_CHATFLOOD_MESSAGE_DELAY] = sConfigMgr->GetIntDefault("ChatFlood.MessageDelay", 1); @@ -1173,6 +1170,8 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_NO_RESET_TALENT_COST] = sConfigMgr->GetBoolDefault("NoResetTalentsCost", false); m_bool_configs[CONFIG_SHOW_KICK_IN_WORLD] = sConfigMgr->GetBoolDefault("ShowKickInWorld", false); + m_bool_configs[CONFIG_SHOW_MUTE_IN_WORLD] = sConfigMgr->GetBoolDefault("ShowMuteInWorld", false); + m_bool_configs[CONFIG_SHOW_BAN_IN_WORLD] = sConfigMgr->GetBoolDefault("ShowBanInWorld", false); m_int_configs[CONFIG_INTERVAL_LOG_UPDATE] = sConfigMgr->GetIntDefault("RecordUpdateTimeDiffInterval", 60000); m_int_configs[CONFIG_MIN_LOG_UPDATE] = sConfigMgr->GetIntDefault("MinRecordUpdateTimeDiff", 100); m_int_configs[CONFIG_NUMTHREADS] = sConfigMgr->GetIntDefault("MapUpdate.Threads", 1); @@ -2276,9 +2275,11 @@ void World::SendGlobalText(const char* text, WorldSession* self) } /// Send a packet to all players (or players selected team) in the zone (except self if mentioned) -void World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self, uint32 team) +bool World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self, uint32 team) { + bool foundPlayerToSend = false; SessionMap::const_iterator itr; + for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) { if (itr->second && @@ -2289,8 +2290,11 @@ void World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self (team == 0 || itr->second->GetPlayer()->GetTeam() == team)) { itr->second->SendPacket(packet); + foundPlayerToSend = true; } } + + return foundPlayerToSend; } /// Send a System Message to all players in the zone (except self if mentioned) @@ -3167,6 +3171,10 @@ void World::UpdateCharacterNameData(uint32 guid, std::string const& name, uint8 if (race != RACE_NONE) itr->second.m_race = race; + + WorldPacket data(SMSG_INVALIDATE_PLAYER, 8); + data << MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER); + SendGlobalMessage(&data); } void World::UpdateCharacterNameDataLevel(uint32 guid, uint8 level) diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 080c9d9006b..a320933e181 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -137,6 +137,8 @@ enum WorldBoolConfigs CONFIG_PVP_TOKEN_ENABLE, CONFIG_NO_RESET_TALENT_COST, CONFIG_SHOW_KICK_IN_WORLD, + CONFIG_SHOW_MUTE_IN_WORLD, + CONFIG_SHOW_BAN_IN_WORLD, CONFIG_CHATLOG_CHANNEL, CONFIG_CHATLOG_WHISPER, CONFIG_CHATLOG_SYSCHAN, @@ -626,7 +628,7 @@ class World void SendGMText(int32 string_id, ...); void SendGlobalMessage(WorldPacket* packet, WorldSession* self = 0, uint32 team = 0); void SendGlobalGMMessage(WorldPacket* packet, WorldSession* self = 0, uint32 team = 0); - void SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = 0, uint32 team = 0); + bool SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = 0, uint32 team = 0); void SendZoneText(uint32 zone, const char *text, WorldSession* self = 0, uint32 team = 0); void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL); diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index c32a03f9bd8..aa90c21c995 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -114,9 +114,19 @@ public: case BAN_SUCCESS: { if (atoi(durationStr) > 0) - handler->PSendSysMessage(LANG_BAN_YOUBANNED, name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + { + if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) + sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + else + handler->PSendSysMessage(LANG_BAN_YOUBANNED, name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + } else - handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, name.c_str(), reasonStr); + { + if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) + sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUPERMBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), name.c_str(), reasonStr); + else + handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, name.c_str(), reasonStr); + } break; } case BAN_NOTFOUND: @@ -189,9 +199,19 @@ public: { case BAN_SUCCESS: if (atoi(durationStr) > 0) - handler->PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + { + if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) + sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + else + handler->PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + } else - handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, nameOrIP.c_str(), reasonStr); + { + if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) + sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameOrIP.c_str(), reasonStr); + else + handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, nameOrIP.c_str(), reasonStr); + } break; case BAN_SYNTAX_ERROR: return false; diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 55e22a8c99a..498ee68ba11 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -198,33 +198,34 @@ public: //Enable\Disable Invisible mode static bool HandleGMVisibleCommand(ChatHandler* handler, char const* args) { + Player* _player = handler->GetSession()->GetPlayer(); + if (!*args) { - handler->PSendSysMessage(LANG_YOU_ARE, handler->GetSession()->GetPlayer()->isGMVisible() ? handler->GetTrinityString(LANG_VISIBLE) : handler->GetTrinityString(LANG_INVISIBLE)); + handler->PSendSysMessage(LANG_YOU_ARE, _player->isGMVisible() ? handler->GetTrinityString(LANG_VISIBLE) : handler->GetTrinityString(LANG_INVISIBLE)); return true; } const uint32 VISUAL_AURA = 37800; std::string param = (char*)args; - Player* player = handler->GetSession()->GetPlayer(); if (param == "on") { - if (player->HasAura(VISUAL_AURA, 0)) - player->RemoveAurasDueToSpell(VISUAL_AURA); + if (_player->HasAura(VISUAL_AURA, 0)) + _player->RemoveAurasDueToSpell(VISUAL_AURA); - player->SetGMVisible(true); + _player->SetGMVisible(true); + _player->UpdateObjectVisibility(); handler->GetSession()->SendNotification(LANG_INVISIBLE_VISIBLE); return true; } if (param == "off") { + _player->AddAura(VISUAL_AURA, _player); + _player->SetGMVisible(false); + _player->UpdateObjectVisibility(); handler->GetSession()->SendNotification(LANG_INVISIBLE_INVISIBLE); - player->SetGMVisible(false); - - player->AddAura(VISUAL_AURA, player); - return true; } @@ -236,12 +237,11 @@ public: //Enable\Disable GM Mode static bool HandleGMCommand(ChatHandler* handler, char const* args) { + Player* _player = handler->GetSession()->GetPlayer(); + if (!*args) { - if (handler->GetSession()->GetPlayer()->IsGameMaster()) - handler->GetSession()->SendNotification(LANG_GM_ON); - else - handler->GetSession()->SendNotification(LANG_GM_OFF); + handler->GetSession()->SendNotification(_player->IsGameMaster() ? LANG_GM_ON : LANG_GM_OFF); return true; } @@ -249,9 +249,9 @@ public: if (param == "on") { - handler->GetSession()->GetPlayer()->SetGameMaster(true); + _player->SetGameMaster(true); handler->GetSession()->SendNotification(LANG_GM_ON); - handler->GetSession()->GetPlayer()->UpdateTriggerVisibility(); + _player->UpdateTriggerVisibility(); #ifdef _DEBUG_VMAPS VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager(); vMapManager->processCommand("stoplog"); @@ -261,9 +261,9 @@ public: if (param == "off") { - handler->GetSession()->GetPlayer()->SetGameMaster(false); + _player->SetGameMaster(false); handler->GetSession()->SendNotification(LANG_GM_OFF); - handler->GetSession()->GetPlayer()->UpdateTriggerVisibility(); + _player->UpdateTriggerVisibility(); #ifdef _DEBUG_VMAPS VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager(); vMapManager->processCommand("startlog"); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 796416b4031..6de8a155d01 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -94,6 +94,7 @@ public: { "unpossess", rbac::RBAC_PERM_COMMAND_UNPOSSESS, false, &HandleUnPossessCommand, "", NULL }, { "unstuck", rbac::RBAC_PERM_COMMAND_UNSTUCK, true, &HandleUnstuckCommand, "", NULL }, { "wchange", rbac::RBAC_PERM_COMMAND_WCHANGE, false, &HandleChangeWeather, "", NULL }, + { "mailbox", rbac::RBAC_PERM_COMMAND_MAILBOX, false, &HandleMailBoxCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; return commandTable; @@ -808,8 +809,13 @@ public: if (handler->HasLowerSecurity(target, 0)) return false; + char const* kickReason = strtok(NULL, "\r"); + std::string kickReasonStr = "No reason"; + if (kickReason != NULL) + kickReasonStr = kickReason; + if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) - sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); + sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), playerName.c_str(), kickReasonStr.c_str()); else handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); @@ -1333,23 +1339,20 @@ public: return false; } - std::string tNameLink = handler->GetNameLink(target); - - if (!target->GetSkillValue(skill)) - { - handler->PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, skillLine->name[handler->GetSessionDbcLocale()]); - handler->SetSentErrorMessage(true); - return false; - } + bool targetHasSkill = target->GetSkillValue(skill); - uint16 max = maxPureSkill ? atol (maxPureSkill) : target->GetPureMaxSkillValue(skill); + // If our target does not yet have the skill they are trying to add to them, the chosen level also becomes + // the max level of the new profession. + uint16 max = maxPureSkill ? atol (maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); if (level <= 0 || level > max || max <= 0) return false; - target->SetSkill(skill, target->GetSkillStep(skill), level, max); - handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], tNameLink.c_str(), level, max); - + // If the player has the skill, we get the current skill step. If they don't have the skill, we + // add the skill to the player's book with step 1 (which is the first rank, in most cases something + // like 'Apprentice <skill>'. + target->SetSkill(skill, targetHasSkill ? target->GetSkillStep(skill) : 1, level, max); + handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], handler->GetNameLink(target).c_str(), level, max); return true; } @@ -1835,7 +1838,17 @@ public: int64 muteTime = time(NULL) + notSpeakTime * MINUTE; target->GetSession()->m_muteTime = muteTime; stmt->setInt64(0, muteTime); - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); + std::string nameLink = handler->playerLink(targetName); + + if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD)) + { + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); + } + else + { + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); + } } else { @@ -1850,8 +1863,10 @@ public: LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); - handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); - + if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, handler->GetSession()->GetPlayerName().c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + else + handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); return true; } @@ -2464,6 +2479,14 @@ public: player->StopCastingBindSight(); return true; } + + static bool HandleMailBoxCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + handler->GetSession()->SendShowMailBox(player->GetGUID()); + return true; + } }; void AddSC_misc_commandscript() diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index c25002fe4f4..a5b13301403 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -744,7 +744,7 @@ public: for (uint8 i = 0; i < NPCFLAG_COUNT; i++) if (npcflags & npcFlagTexts[i].Value) - handler->PSendSysMessage(npcFlagTexts[i].Name); + handler->PSendSysMessage(npcFlagTexts[i].Name, npcFlagTexts[i].Value); handler->PSendSysMessage(LANG_NPCINFO_MECHANIC_IMMUNE, mechanicImmuneMask); for (uint8 i = 0; i < MAX_MECHANIC; ++i) diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp index 845db0cac1c..1edb1100289 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp @@ -74,7 +74,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_MOIRA) : 0)) + if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MOIRA))) { Moira->AI()->EnterEvadeMode(); Moira->setFaction(35); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp index fe38377341b..8989a8065dc 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp @@ -191,7 +191,7 @@ public: void SetData(uint32 type, uint32 data) OVERRIDE { - if (instance && type == AREATRIGGER && data == AREATRIGGER_BLACKROCK_STADIUM) + if (type == AREATRIGGER && data == AREATRIGGER_BLACKROCK_STADIUM) { if (!gythEvent) { diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp index d292e5f7701..3930656f0e1 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp @@ -183,7 +183,7 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && instance->GetBossState(BOSS_FLAMEGOR) != DONE) + if (instance->GetBossState(BOSS_FLAMEGOR) != DONE) { EnterEvadeMode(); return; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp index b8a3c157c52..8d25fe117fe 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp @@ -45,7 +45,7 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE) + if (instance->GetBossState(BOSS_BROODLORD) != DONE) { EnterEvadeMode(); return; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp index 706f376e882..cbd625e852a 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp @@ -45,7 +45,7 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE) + if (instance->GetBossState(BOSS_BROODLORD) != DONE) { EnterEvadeMode(); return; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp index e262cba1978..390bcaa3c9d 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp @@ -50,7 +50,7 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE) + if (instance->GetBossState(BOSS_BROODLORD) != DONE) { EnterEvadeMode(); return; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index 945d8b40d32..02662cd235c 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -223,16 +223,14 @@ public: void SetData(uint32 type, uint32 data) OVERRIDE { - if (instance && type == 1 && data == 1) + if ( type == 1 && data == 1) { me->StopMoving(); events.ScheduleEvent(EVENT_PATH_2, 9000); } - if (instance && type == 1 && data == 2) - { + if (type == 1 && data == 2) events.ScheduleEvent(EVENT_SUCCESS_1, 5000); - } } void UpdateAI(uint32 diff) OVERRIDE diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp index 294b662aea7..d2bd82447dc 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp @@ -96,7 +96,7 @@ class boss_majordomo : public CreatureScript void UpdateAI(uint32 diff) OVERRIDE { - if (instance && instance->GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE) + if (instance->GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE) { if (!UpdateVictim()) return; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp index 4e135ad513a..4d22ba6abb3 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp @@ -233,7 +233,7 @@ class boss_ragnaros : public CreatureScript break; case EVENT_SUBMERGE: { - if (instance && !_isBanished) + if (!_isBanished) { //Creature spawning and ragnaros becomming unattackable //is not very well supported in the core //no it really isnt diff --git a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp index d26458be82e..38a72581d66 100644 --- a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp +++ b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp @@ -113,7 +113,7 @@ public: { InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetData(TYPE_EVENT) == NOT_STARTED) + if (instance->GetData(TYPE_EVENT) == NOT_STARTED) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(GOSSIP_TEXT_EMI, creature->GetGUID()); @@ -193,15 +193,10 @@ public: instance->HandleGameObject(0, false, go); } - void SetInFace(bool bBool) + void SetInFace(bool isRight) { - if (bBool) - { - if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_RIGHT))) - me->SetFacingToObject(go); - }else - if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_LEFT))) - me->SetFacingToObject(go); + if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(isRight ? DATA_GO_CAVE_IN_RIGHT : DATA_GO_CAVE_IN_LEFT))) + me->SetFacingToObject(go); } void RestoreAll() diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp index 36bb2e32cb6..2dff776c35a 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp @@ -252,7 +252,7 @@ public: if (!UpdateVictim()) return; - if (instance && !instance->GetData(TYPE_MOROES)) + if (!instance->GetData(TYPE_MOROES)) { EnterEvadeMode(); return; @@ -371,7 +371,7 @@ struct boss_moroes_guestAI : public ScriptedAI void UpdateAI(uint32 /*diff*/) OVERRIDE { - if (instance && !instance->GetData(TYPE_MOROES)) + if (!instance->GetData(TYPE_MOROES)) EnterEvadeMode(); DoMeleeAttackIfReady(); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp index 1b9ef055b8c..ebd8762e9be 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp @@ -247,13 +247,13 @@ public: PortalPhase = false; Talk(EMOTE_PHASE_BANISH); - for (int i=0; i<3; ++i) + for (uint8 i = 0; i < 3; ++i) me->RemoveAurasDueToSpell(NetherBuff[i]); } void HandleDoors(bool open) // Massive Door switcher { - if (GameObject* Door = GameObject::GetGameObject(*me, instance ? instance->GetData64(DATA_GO_MASSIVE_DOOR) : 0)) + if (GameObject* Door = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_GO_MASSIVE_DOOR) )) Door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index b82c0099ce4..bde326a5c37 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -297,12 +297,7 @@ public: void ClearWeapons() { SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); - - //damage - const CreatureTemplate* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, cinfo->mindmg); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, cinfo->maxdmg); - me->UpdateDamagePhysical(BASE_ATTACK); + me->SetCanDualWield(false); } void EnfeebleHealthEffect() @@ -419,19 +414,8 @@ public: //models SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE, EQUIP_NO_CHANGE); - //damage - const CreatureTemplate* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, 2*cinfo->mindmg); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, 2*cinfo->maxdmg); - me->UpdateDamagePhysical(BASE_ATTACK); - - me->SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, cinfo->mindmg); - me->SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, cinfo->maxdmg); - //Sigh, updating only works on main attack, do it manually .... - me->SetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, cinfo->mindmg); - me->SetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, cinfo->maxdmg); - me->SetAttackTime(OFF_ATTACK, (me->GetAttackTime(BASE_ATTACK)*150)/100); + me->SetCanDualWield(true); } } else if (phase == 2) diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index f667394f29c..241ac85faa2 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -496,12 +496,13 @@ public: EventStarted = false; YellTimer = 0; - if (instance && instance->GetData64(DATA_IMAGE_OF_MEDIVH) == 0) + if (instance->GetData64(DATA_IMAGE_OF_MEDIVH) == 0) { instance->SetData64(DATA_IMAGE_OF_MEDIVH, me->GetGUID()); (*me).GetMotionMaster()->MovePoint(1, MedivPos[0], MedivPos[1], MedivPos[2]); Step = 0; - }else + } + else { me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); me->RemoveCorpse(); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index 6c15fdc77fa..0601c69e96d 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -515,7 +515,7 @@ public: return; } //Don't really die in all phases of Kael'Thas - if (instance && instance->GetData(DATA_KAELTHAS_EVENT) == 0) + if (instance->GetData(DATA_KAELTHAS_EVENT) == 0) { //prevent death damage = 0; diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index 8592120f94a..4bc0ee68cc3 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -376,7 +376,7 @@ struct boss_priestess_lackey_commonAI : public ScriptedAI ResetThreatTimer = urand(5000, 20000); // in case she is not alive and Reset was for some reason called, respawn her (most likely party wipe after killing her) - if (Creature* pDelrissa = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DELRISSA) : 0)) + if (Creature* pDelrissa = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_DELRISSA))) { if (!pDelrissa->IsAlive()) pDelrissa->Respawn(); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp index 0d62d47a5d6..a78dce47784 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp @@ -172,7 +172,7 @@ public: if (!UpdateVictim()) return; - if (_bHasDied && !_bHeal && instance && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL) + if (_bHasDied && !_bHeal && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL) { //On ressurection, stop fake death and heal whitemane and resume fight if (Unit* Whitemane = Unit::GetUnit(*me, instance->GetData64(DATA_WHITEMANE))) @@ -259,7 +259,7 @@ public: void AttackStart(Unit* who) OVERRIDE { - if (instance && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED) + if (instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED) return; ScriptedAI::AttackStart(who); @@ -289,11 +289,11 @@ public: if (_bCanResurrect) { //When casting resuruction make sure to delay so on rez when reinstate battle deepsleep runs out - if (instance && Wait_Timer <= diff) + if (Wait_Timer <= diff) { - if (Unit* Mograine = Unit::GetUnit(*me, instance->GetData64(DATA_MOGRAINE))) + if (Creature* mograine = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MOGRAINE))) { - DoCast(Mograine, SPELL_SCARLETRESURRECTION); + DoCast(mograine, SPELL_SCARLETRESURRECTION); Talk(SAY_WH_RESSURECT); _bCanResurrect = false; } @@ -325,7 +325,7 @@ public: if (!HealthAbovePct(75)) target = me; - if (Creature* mograine = Unit::GetCreature((*me), instance->GetData64(DATA_MOGRAINE))) + if (Creature* mograine = Unit::GetCreature(*me, instance->GetData64(DATA_MOGRAINE))) { // checking _bCanResurrectCheck prevents her healing Mograine while he is "faking death" if (_bCanResurrectCheck && mograine->IsAlive() && !mograine->HealthAbovePct(75)) diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp index eb7295f72d0..dff637fd764 100644 --- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp +++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp @@ -92,7 +92,7 @@ public: { InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetData(TYPE_FREE_NPC) != DONE && instance->GetData(TYPE_RETHILGORE) == DONE) + if (instance->GetData(TYPE_FREE_NPC) != DONE && instance->GetData(TYPE_RETHILGORE) == DONE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DOOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); diff --git a/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp b/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp index fe0e3a050c8..f4663c0f8ec 100644 --- a/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp +++ b/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp @@ -93,7 +93,7 @@ public: MortalStrike_Timer = 12000; // RaiseDead_Timer = 30000; SummonSkeletons_Timer = 34000; - if (instance && instance->GetData(TYPE_RAMSTEIN) == DONE) + if (instance->GetData(TYPE_RAMSTEIN) == DONE) instance->SetData(TYPE_BARON, NOT_STARTED); } diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp index a52ddcea3b0..9dcbed211bb 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp @@ -176,7 +176,7 @@ public: void DoIntro() { - Creature* Madrigosa = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_MADRIGOSA) : 0); + Creature* Madrigosa = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MADRIGOSA)); if (!Madrigosa) return; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 9d073cd7ef8..e8b112aa1cd 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -454,7 +454,7 @@ public: { if (uiRandomSayTimer < diff) { - if (instance && instance->GetBossState(DATA_MURU) != DONE && instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED) + if (instance->GetBossState(DATA_MURU) != DONE && instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED) Talk(SAY_KJ_OFFCOMBAT); uiRandomSayTimer = 30000; } else uiRandomSayTimer -= diff; @@ -1206,7 +1206,7 @@ public: if (uiTimer <= diff) { - if (Unit* random = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0)) + if (Unit* random = ObjectAccessor::GetPlayer(*me, instance->GetData64(DATA_PLAYER_GUID))) DoCast(random, SPELL_SHADOW_BOLT, false); uiTimer = urand(500, 1000); } else uiTimer -= diff; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp index 426771e6db6..6980dbfb9c2 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp @@ -433,10 +433,11 @@ public: { if (!SummonSentinel) { - if (InAction && instance && instance->GetBossState(DATA_MURU) == NOT_STARTED) + if (InAction && instance->GetBossState(DATA_MURU) == NOT_STARTED) Reset(); return; } + if (SummonTimer <= diff) { DoCastAOE(SPELL_SUMMON_VOID_SENTINEL, false); @@ -602,7 +603,7 @@ public: { if (SpellTimer <= diff) { - Unit* Victim = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0); + Unit* Victim = Unit::GetUnit(*me, instance->GetData64(DATA_PLAYER_GUID)); switch (NeedForAHack) { case 0: diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 646c9ddfe81..eca840dbeb2 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -228,7 +228,7 @@ class boss_akilzon : public CreatureScript case EVENT_STATIC_DISRUPTION: { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!target) + if (!target) target = me->GetVictim(); if (target) { @@ -244,7 +244,7 @@ class boss_akilzon : public CreatureScript case EVENT_GUST_OF_WIND: { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!target) + if (!target) target = me->GetVictim(); if (target) DoCast(target, SPELL_GUST_OF_WIND); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index 04e3d9f3450..d6657ac0986 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -231,7 +231,7 @@ struct boss_hexlord_addAI : public ScriptedAI void UpdateAI(uint32 /*diff*/) OVERRIDE { - if (instance && instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS) + if (instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS) { EnterEvadeMode(); return; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp index 4bf50581108..e542b3c4895 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp @@ -96,24 +96,21 @@ class boss_arlokk : public CreatureScript void Reset() OVERRIDE { + if (events.IsInPhase(PHASE_TWO)) + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack + _Reset(); _summonCountA = 0; _summonCountB = 0; - me->RemoveAllAuras(); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); - if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) - gate->SetGoState(GO_STATE_READY); me->SetWalk(false); me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0]); } void JustDied(Unit* /*killer*/) OVERRIDE { + _JustDied(); Talk(SAY_DEATH); - me->RemoveAllAuras(); - if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) - gate->SetGoState(GO_STATE_ACTIVE); - instance->SetBossState(DATA_ARLOKK, DONE); } void EnterCombat(Unit* /*who*/) OVERRIDE @@ -154,11 +151,9 @@ class boss_arlokk : public CreatureScript void EnterEvadeMode() OVERRIDE { - if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_FORCEFIELD))) - object->SetGoState(GO_STATE_ACTIVE); - if (GameObject* object = me->GetMap()->GetGameObject(instance->GetData64(GO_GONG_OF_BETHEKK))) + BossAI::EnterEvadeMode(); + if (GameObject* object = ObjectAccessor::GetGameObject(*me, instance->GetData64(GO_GONG_OF_BETHEKK))) object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - instance->SetBossState(DATA_ARLOKK, NOT_STARTED); me->DespawnOrUnsummon(4000); } @@ -194,7 +189,7 @@ class boss_arlokk : public CreatureScript case EVENT_SUMMON_PROWLERS: if (_summonCountA < MAX_PROWLERS_PER_SIDE) { - if (Unit* trigger = me->GetUnit(*me, _triggersSideAGUID[urand(0, 4)])) + if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideAGUID[urand(0, 4)])) { trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); ++_summonCountA; @@ -202,7 +197,7 @@ class boss_arlokk : public CreatureScript } if (_summonCountB < MAX_PROWLERS_PER_SIDE) { - if (Unit* trigger = me->GetUnit(*me, _triggersSideBGUID[urand(0, 4)])) + if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideBGUID[urand(0, 4)])) { trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER); ++_summonCountB; @@ -225,13 +220,15 @@ class boss_arlokk : public CreatureScript } case EVENT_TRANSFORM: { - DoCast(me, SPELL_PANTHER_TRANSFORM); + DoCast(me, SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP)); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(EQUIP_UNEQUIP)); + /* const CreatureTemplate* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35))); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35))); me->UpdateDamagePhysical(BASE_ATTACK); + */ me->AttackStop(); DoResetThreat(); me->SetReactState(REACT_PASSIVE); @@ -262,6 +259,7 @@ class boss_arlokk : public CreatureScript events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO); events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO); events.SetPhase(PHASE_TWO); + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack break; case EVENT_RAVAGE: DoCastVictim(SPELL_RAVAGE, true); @@ -269,14 +267,17 @@ class boss_arlokk : public CreatureScript break; case EVENT_TRANSFORM_BACK: { - me->RemoveAura(SPELL_PANTHER_TRANSFORM); + me->RemoveAura(SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM DoCast(me, SPELL_VANISH_VISUAL); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER)); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER)); + /* const CreatureTemplate* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg)); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg)); me->UpdateDamagePhysical(BASE_ATTACK); + */ + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE); events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE); events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE); @@ -343,9 +344,8 @@ class npc_zulian_prowler : public CreatureScript DoCast(me, SPELL_SNEAK_RANK_1_1); DoCast(me, SPELL_SNEAK_RANK_1_2); - if (_instance) - if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) - me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ()); + if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) + me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ()); _events.ScheduleEvent(EVENT_ATTACK, 6000); } @@ -364,13 +364,10 @@ class npc_zulian_prowler : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (_instance) + if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) { - if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK))) - { - if (arlokk->IsAlive()) - arlokk->GetAI()->SetData(_sideData, 0); - } + if (arlokk->IsAlive()) + arlokk->GetAI()->SetData(_sideData, 0); } me->DespawnOrUnsummon(4000); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp index e6ef90d1638..ad2d247c1e7 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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 @@ -16,13 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Jeklik -SD%Complete: 85 -SDComment: Problem in finding the right flying batriders for spawning and making them fly. -SDCategory: Zul'Gurub -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulgurub.h" @@ -44,11 +36,47 @@ enum Spells SPELL_CHAIN_MIND_FLAY = 26044, // Right ID unknown. So disabled SPELL_GREATERHEAL = 23954, SPELL_BAT_FORM = 23966, + // Batriders Spell SPELL_BOMB = 40332 // Wrong ID but Magmadars bomb is not working... }; -class boss_jeklik : public CreatureScript //jeklik +enum BatIds +{ + NPC_BLOODSEEKER_BAT = 11368, + NPC_FRENZIED_BAT = 14965 +}; + +enum Events +{ + EVENT_CHARGE_JEKLIK = 1, + EVENT_SONIC_BURST, + EVENT_SCREECH, + EVENT_SPAWN_BATS, + EVENT_SHADOW_WORD_PAIN, + EVENT_MIND_FLAY, + EVENT_CHAIN_MIND_FLAY, + EVENT_GREATER_HEAL, + EVENT_SPAWN_FLYING_BATS +}; + +enum Phase +{ + PHASE_ONE = 1, + PHASE_TWO = 2 +}; + +Position const SpawnBat[6] = +{ + { -12291.6220f, -1380.2640f, 144.8304f, 5.483f }, + { -12289.6220f, -1380.2640f, 144.8304f, 5.483f }, + { -12293.6220f, -1380.2640f, 144.8304f, 5.483f }, + { -12291.6220f, -1380.2640f, 144.8304f, 5.483f }, + { -12289.6220f, -1380.2640f, 144.8304f, 5.483f }, + { -12293.6220f, -1380.2640f, 144.8304f, 5.483f } +}; + +class boss_jeklik : public CreatureScript { public: boss_jeklik() : CreatureScript("boss_jeklik") { } @@ -56,32 +84,9 @@ class boss_jeklik : public CreatureScript //jeklik { boss_jeklikAI(Creature* creature) : BossAI(creature, DATA_JEKLIK) { } - uint32 Charge_Timer; - uint32 SonicBurst_Timer; - uint32 Screech_Timer; - uint32 SpawnBats_Timer; - uint32 ShadowWordPain_Timer; - uint32 MindFlay_Timer; - uint32 ChainMindFlay_Timer; - uint32 GreaterHeal_Timer; - uint32 SpawnFlyingBats_Timer; - - bool PhaseTwo; - void Reset() OVERRIDE { _Reset(); - Charge_Timer = 20000; - SonicBurst_Timer = 8000; - Screech_Timer = 13000; - SpawnBats_Timer = 60000; - ShadowWordPain_Timer = 6000; - MindFlay_Timer = 11000; - ChainMindFlay_Timer = 26000; - GreaterHeal_Timer = 50000; - SpawnFlyingBats_Timer = 10000; - - PhaseTwo = false; } void JustDied(Unit* /*killer*/) OVERRIDE @@ -94,156 +99,124 @@ class boss_jeklik : public CreatureScript //jeklik { _EnterCombat(); Talk(SAY_AGGRO); + events.SetPhase(PHASE_ONE); + + events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 20000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SONIC_BURST, 8000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SCREECH, 13000, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE); + + me->SetCanFly(true); DoCast(me, SPELL_BAT_FORM); } + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE + { + if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(50)) + { + me->RemoveAurasDueToSpell(SPELL_BAT_FORM); + me->SetCanFly(false); + DoResetThreat(); + events.SetPhase(PHASE_TWO); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 6000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_MIND_FLAY, 11000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 26000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_GREATER_HEAL, 50000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10000, 0, PHASE_TWO); + return; + } + } + void UpdateAI(uint32 diff) OVERRIDE { if (!UpdateVictim()) return; - if (me->GetVictim() && me->IsAlive()) + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - if (HealthAbovePct(50)) + switch (eventId) { - if (Charge_Timer <= diff) - { + case EVENT_CHARGE_JEKLIK: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { DoCast(target, SPELL_CHARGE); AttackStart(target); } - - Charge_Timer = urand(15000, 30000); - } else Charge_Timer -= diff; - - if (SonicBurst_Timer <= diff) - { + events.ScheduleEvent(EVENT_CHARGE_JEKLIK, urand(15000, 30000), 0, PHASE_ONE); + break; + case EVENT_SONIC_BURST: DoCastVictim(SPELL_SONICBURST); - SonicBurst_Timer = urand(8000, 13000); - } else SonicBurst_Timer -= diff; - - if (Screech_Timer <= diff) - { + events.ScheduleEvent(EVENT_SONIC_BURST, urand(8000, 13000), 0, PHASE_ONE); + case EVENT_SCREECH: DoCastVictim(SPELL_SCREECH); - Screech_Timer = urand(18000, 26000); - } else Screech_Timer -= diff; - - if (SpawnBats_Timer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - - Creature* Bat = NULL; - Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (target && Bat) Bat ->AI()->AttackStart(target); - - SpawnBats_Timer = 60000; - } else SpawnBats_Timer -= diff; - } - else - { - if (PhaseTwo) - { - if (ShadowWordPain_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - DoCast(target, SPELL_SHADOW_WORD_PAIN); - ShadowWordPain_Timer = urand(12000, 18000); - } - }ShadowWordPain_Timer -=diff; - - if (MindFlay_Timer <= diff) - { - DoCastVictim(SPELL_MIND_FLAY); - MindFlay_Timer = 16000; - }MindFlay_Timer -=diff; - - if (ChainMindFlay_Timer <= diff) - { - me->InterruptNonMeleeSpells(false); - DoCastVictim(SPELL_CHAIN_MIND_FLAY); - ChainMindFlay_Timer = urand(15000, 30000); - }ChainMindFlay_Timer -=diff; - - if (GreaterHeal_Timer <= diff) - { - me->InterruptNonMeleeSpells(false); - DoCast(me, SPELL_GREATERHEAL); - GreaterHeal_Timer = urand(25000, 35000); - }GreaterHeal_Timer -=diff; - - if (SpawnFlyingBats_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - if (Creature* FlyingBat = me->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) - FlyingBat->AI()->AttackStart(target); - } - - SpawnFlyingBats_Timer = urand(10000, 15000); - } else SpawnFlyingBats_Timer -=diff; - } - else - { - me->SetDisplayId(15219); - DoResetThreat(); - PhaseTwo = true; - } + events.ScheduleEvent(EVENT_SCREECH, urand(18000, 26000), 0, PHASE_ONE); + case EVENT_SPAWN_BATS: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + for (uint8 i = 0; i < 6; ++i) + if (Creature* bat = me->SummonCreature(NPC_BLOODSEEKER_BAT, SpawnBat[i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) + bat->AI()->AttackStart(target); + events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE); + break; + case EVENT_SHADOW_WORD_PAIN: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SHADOW_WORD_PAIN); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(12000, 18000), 0, PHASE_TWO); + break; + case EVENT_MIND_FLAY: + DoCastVictim(SPELL_MIND_FLAY); + events.ScheduleEvent(EVENT_MIND_FLAY, 16000, 0, PHASE_TWO); + break; + case EVENT_CHAIN_MIND_FLAY: + me->InterruptNonMeleeSpells(false); + DoCastVictim(SPELL_CHAIN_MIND_FLAY); + events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, urand(15000, 30000), 0, PHASE_TWO); + break; + case EVENT_GREATER_HEAL: + me->InterruptNonMeleeSpells(false); + DoCast(me, SPELL_GREATERHEAL); + events.ScheduleEvent(EVENT_GREATER_HEAL, urand(25000, 35000), 0, PHASE_TWO); + break; + case EVENT_SPAWN_FLYING_BATS: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + if (Creature* flyingBat = me->SummonCreature(NPC_FRENZIED_BAT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 15.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000)) + flyingBat->AI()->AttackStart(target); + events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, urand(10000, 15000), 0, PHASE_TWO); + break; + default: + break; } - - DoMeleeAttackIfReady(); } + + DoMeleeAttackIfReady(); } }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new boss_jeklikAI(creature); + return GetZulGurubAI<boss_jeklikAI>(creature); } }; -//Flying Bat +// Flying Bat class npc_batrider : public CreatureScript { public: - - npc_batrider() - : CreatureScript("npc_batrider") - { - } + npc_batrider() : CreatureScript("npc_batrider") { } struct npc_batriderAI : public ScriptedAI { - npc_batriderAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; + npc_batriderAI(Creature* creature) : ScriptedAI(creature) { } uint32 Bomb_Timer; - uint32 Check_Timer; void Reset() OVERRIDE { Bomb_Timer = 2000; - Check_Timer = 1000; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } @@ -254,7 +227,6 @@ class npc_batrider : public CreatureScript if (!UpdateVictim()) return; - //Bomb_Timer if (Bomb_Timer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) @@ -262,20 +234,9 @@ class npc_batrider : public CreatureScript DoCast(target, SPELL_BOMB); Bomb_Timer = 5000; } - } else Bomb_Timer -= diff; - - //Check_Timer - if (Check_Timer <= diff) - { - if (instance->GetBossState(DATA_JEKLIK) == DONE) - { - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); - return; - } - - Check_Timer = 1000; - } else Check_Timer -= diff; + } + else + Bomb_Timer -= diff; DoMeleeAttackIfReady(); } @@ -283,7 +244,7 @@ class npc_batrider : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return GetInstanceAI<npc_batriderAI>(creature); + return new npc_batriderAI(creature); } }; @@ -292,4 +253,3 @@ void AddSC_boss_jeklik() new boss_jeklik(); new npc_batrider(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp index 3ff18d81032..efd79d89a2b 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp @@ -64,11 +64,6 @@ enum Phases PHASE_THREE = 3 }; -enum ModelId -{ - MODEL_MARLI = 15220 -}; - class boss_marli : public CreatureScript { public: boss_marli() : CreatureScript("boss_marli") { } @@ -79,6 +74,8 @@ class boss_marli : public CreatureScript void Reset() OVERRIDE { + if (events.IsInPhase(PHASE_THREE)) + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack _Reset(); } @@ -155,11 +152,14 @@ class boss_marli : public CreatureScript case EVENT_TRANSFORM: { Talk(SAY_TRANSFORM); - DoCast(me, SPELL_SPIDER_FORM); + DoCast(me, SPELL_SPIDER_FORM); // SPELL_AURA_TRANSFORM + /* CreatureTemplate const* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35))); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35))); me->UpdateDamagePhysical(BASE_ATTACK); + */ + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack DoCastVictim(SPELL_ENVOLWINGWEB); if (DoGetThreat(me->GetVictim())) DoModifyThreatPercent(me->GetVictim(), -100); @@ -188,11 +188,14 @@ class boss_marli : public CreatureScript } case EVENT_TRANSFORM_BACK: { - me->SetDisplayId(MODEL_MARLI); + me->RemoveAura(SPELL_SPIDER_FORM); + /* CreatureTemplate const* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1))); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1))); me->UpdateDamagePhysical(BASE_ATTACK); + */ + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO); events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO); events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp index d857bff69e0..a70dd5e0a30 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp @@ -89,6 +89,8 @@ class boss_thekal : public CreatureScript void Reset() OVERRIDE { + if (events.IsInPhase(PHASE_TWO)) + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack _Reset(); Enraged = false; WasDead = false; @@ -141,15 +143,17 @@ class boss_thekal : public CreatureScript //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds. if (WasDead) { - DoCast(me, SPELL_TIGER_FORM); + DoCast(me, SPELL_TIGER_FORM); // SPELL_AURA_TRANSFORM me->SetObjectScale(2.00f); me->SetStandState(UNIT_STAND_STATE_STAND); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFullHealth(); + /* const CreatureTemplate* cinfo = me->GetCreatureTemplate(); me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40))); me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40))); me->UpdateDamagePhysical(BASE_ATTACK); + */ + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 40.0f, true); // hack DoResetThreat(); events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); // Phase 2 events.ScheduleEvent(EVENT_FORCEPUNCH, 4000, 0, PHASE_TWO); // Phase 2 diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index 673450f83d0..67d40abaea3 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -27,6 +27,12 @@ EndScriptData */ #include "InstanceScript.h" #include "zulgurub.h" +DoorData const doorData[] = +{ + { GO_FORCEFIELD, DATA_ARLOKK, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; + class instance_zulgurub : public InstanceMapScript { public: instance_zulgurub(): InstanceMapScript(ZGScriptName, 309) { } @@ -36,6 +42,7 @@ class instance_zulgurub : public InstanceMapScript instance_zulgurub_InstanceMapScript(Map* map) : InstanceScript(map) { SetBossNumber(EncounterCount); + LoadDoorData(doorData); } void Initialize() OVERRIDE @@ -46,7 +53,6 @@ class instance_zulgurub : public InstanceMapScript _jindoTheHexxerGUID = 0; _vilebranchSpeakerGUID = 0; _arlokkGUID = 0; - _goForcefieldGUID = 0; _goGongOfBethekkGUID = 0; } @@ -86,7 +92,7 @@ class instance_zulgurub : public InstanceMapScript switch (go->GetEntry()) { case GO_FORCEFIELD: - _goForcefieldGUID = go->GetGUID(); + AddDoor(go, true); break; case GO_GONG_OF_BETHEKK: _goGongOfBethekkGUID = go->GetGUID(); @@ -100,6 +106,18 @@ class instance_zulgurub : public InstanceMapScript } } + void OnGameObjectRemove(GameObject* go) OVERRIDE + { + switch (go->GetEntry()) + { + case GO_FORCEFIELD: + AddDoor(go, false); + break; + default: + break; + } + } + uint64 GetData64(uint32 uiData) const OVERRIDE { switch (uiData) @@ -119,9 +137,6 @@ class instance_zulgurub : public InstanceMapScript case NPC_ARLOKK: return _arlokkGUID; break; - case GO_FORCEFIELD: - return _goForcefieldGUID; - break; case GO_GONG_OF_BETHEKK: return _goGongOfBethekkGUID; break; @@ -181,7 +196,6 @@ class instance_zulgurub : public InstanceMapScript uint64 _jindoTheHexxerGUID; uint64 _vilebranchSpeakerGUID; uint64 _arlokkGUID; - uint64 _goForcefieldGUID; uint64 _goGongOfBethekkGUID; }; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index c92e8b8724d..a9386ff1782 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -66,13 +66,9 @@ enum GameobjectIds }; template<class AI> -CreatureAI* GetZulGurubAI(Creature* creature) +AI* GetZulGurubAI(Creature* creature) { - if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) - if (instance->GetInstanceScript()) - if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZGScriptName)) - return new AI(creature); - return NULL; + return GetInstanceAI<AI>(creature, ZGScriptName); } #endif diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp index 4bfbff50dd5..0cd1403d48a 100644 --- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp +++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp @@ -233,10 +233,7 @@ public: struct npc_lord_gregor_lescovarAI : public npc_escortAI { - npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) - { - creature->RestoreFaction(); - } + npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) { } uint32 uiTimer; uint32 uiPhase; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index a4f9a364684..c7803f23e1b 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -72,14 +72,15 @@ public: AuraTimer = 5000; InfernoTimer = 45000; - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_ANETHERONEVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS); + Talk(SAY_ONAGGRO); } @@ -91,7 +92,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 7 && instance) + if (waypointId == 7) { Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE)); if (target && target->IsAlive()) @@ -102,7 +103,7 @@ public: void JustDied(Unit* killer) OVERRIDE { hyjal_trashAI::JustDied(killer); - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_ANETHERONEVENT, DONE); Talk(SAY_ONDEATH); } @@ -225,7 +226,7 @@ public: { if (AnetheronGUID) { - Creature* boss = Unit::GetCreature((*me), AnetheronGUID); + Creature* boss = ObjectAccessor::GetCreature(*me, AnetheronGUID); if (!boss || (boss && boss->isDead())) { me->setDeathState(JUST_DIED); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp index 6d296945659..4decce7482f 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp @@ -78,14 +78,15 @@ public: EnrageTimer = 600000; enraged = false; - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_AZGALOREVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_AZGALOREVENT, IN_PROGRESS); + Talk(SAY_ONAGGRO); } @@ -107,7 +108,7 @@ public: void JustDied(Unit* killer) OVERRIDE { hyjal_trashAI::JustDied(killer); - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_AZGALOREVENT, DONE); Talk(SAY_ONDEATH); } @@ -237,7 +238,7 @@ public: { if (AzgalorGUID) { - Creature* boss = Unit::GetCreature((*me), AzgalorGUID); + Creature* boss = ObjectAccessor::GetCreature(*me, AzgalorGUID); if (!boss || (boss && boss->isDead())) { me->setDeathState(JUST_DIED); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp index 7a5870809f7..af7b0c1d899 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp @@ -74,13 +74,13 @@ public: MarkTimer = 45000; MarkTimerBase = 45000; - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_KAZROGALEVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS); Talk(SAY_ONAGGRO); } @@ -103,7 +103,7 @@ public: void JustDied(Unit* killer) OVERRIDE { hyjal_trashAI::JustDied(killer); - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_KAZROGALEVENT, DONE); DoPlaySoundToSet(me, SOUND_ONDEATH); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp index 4d6a94b6e73..691207a4682 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp @@ -69,13 +69,13 @@ public: NovaTimer = 15000; IceboltTimer = 10000; - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS); Talk(SAY_ONAGGRO); } @@ -98,7 +98,7 @@ public: void JustDied(Unit* killer) OVERRIDE { hyjal_trashAI::JustDied(killer); - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE); Talk(SAY_ONDEATH); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index 3b3cacf7d3f..c8006158ef1 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -705,7 +705,7 @@ void hyjalAI::UpdateAI(uint32 diff) switch (me->GetEntry()) { case JAINA: - if (instance && instance->GetData(DATA_ALLIANCE_RETREAT)) + if (instance->GetData(DATA_ALLIANCE_RETREAT)) { me->SetVisible(false); HideNearPos(me->GetPositionX(), me->GetPositionY()); @@ -717,7 +717,7 @@ void hyjalAI::UpdateAI(uint32 diff) else me->SetVisible(true); break; case THRALL: //thrall - if (instance && instance->GetData(DATA_HORDE_RETREAT)) + if (instance->GetData(DATA_HORDE_RETREAT)) { me->SetVisible(false); HideNearPos(me->GetPositionX(), me->GetPositionY()); @@ -781,7 +781,7 @@ void hyjalAI::UpdateAI(uint32 diff) if (Summon) { - if (instance && EnemyCount) + if (EnemyCount) { EnemyCount = instance->GetData(DATA_TRASH); if (!EnemyCount) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 2688fbbdaff..cbace6df028 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -443,7 +443,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 0 && instance && !IsOverrun) + if (waypointId == 0 && !IsOverrun) { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { @@ -559,7 +559,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 7 && instance && !IsOverrun) + if (waypointId == 7 && !IsOverrun) { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { @@ -658,7 +658,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 7 && instance && !IsOverrun) + if (waypointId == 7 && !IsOverrun) { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { @@ -769,7 +769,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 7 && instance && !IsOverrun) + if (waypointId == 7 && !IsOverrun) { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { @@ -882,7 +882,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 7 && instance && !IsOverrun) + if (waypointId == 7 && !IsOverrun) { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { @@ -978,7 +978,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 7 && instance && !IsOverrun) + if (waypointId == 7 && !IsOverrun) { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { @@ -1064,7 +1064,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 7 && instance && !IsOverrun) + if (waypointId == 7 && !IsOverrun) { if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall { @@ -1153,7 +1153,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 2 && instance && !IsOverrun) + if (waypointId == 2 && !IsOverrun) { Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->IsAlive()) @@ -1166,7 +1166,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (instance && IsEvent) + if (IsEvent) instance->SetData(DATA_TRASH, 0);//signal trash is dead float x, y, z; @@ -1181,11 +1181,13 @@ public: void UpdateAI(uint32 diff) OVERRIDE { hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) { CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); npc_escortAI::UpdateAI(diff); } + if (IsEvent) { if (!go) @@ -1197,7 +1199,9 @@ public: AddWaypoint(i, FrostWyrmWPs[i][0], FrostWyrmWPs[i][1], FrostWyrmWPs[i][2]); Start(false, true); SetDespawnAtEnd(false); - }else{//fly path FlyPathWPs + } + else + {//fly path FlyPathWPs for (uint8 i = 0; i < 3; ++i) AddWaypoint(i, FlyPathWPs[i][0]+irand(-10, 10), FlyPathWPs[i][1]+irand(-10, 10), FlyPathWPs[i][2]); Start(false, true); @@ -1205,9 +1209,12 @@ public: } } } + if (!UpdateVictim()) return; - if (!me->IsWithinDist(me->GetVictim(), 25)){ + + if (!me->IsWithinDist(me->GetVictim(), 25)) + { if (MoveTimer <= diff) { me->GetMotionMaster()->MoveChase(me->GetVictim()); @@ -1227,7 +1234,6 @@ public: } else FrostBreathTimer -= diff; } }; - }; class npc_gargoyle : public CreatureScript @@ -1246,7 +1252,8 @@ public: { instance = creature->GetInstanceScript(); go = false; - DummyTarget[0] = 0;DummyTarget[1] = 0;DummyTarget[2] = 0; + for (uint8 i = 0; i < 3; ++i) + DummyTarget[i] = 0; Reset(); } @@ -1267,7 +1274,7 @@ public: void WaypointReached(uint32 waypointId) OVERRIDE { - if (waypointId == 2 && instance && !IsOverrun) + if (waypointId == 2 && !IsOverrun) { Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL)); if (target && target->IsAlive()) @@ -1291,11 +1298,13 @@ public: void UpdateAI(uint32 diff) OVERRIDE { hyjal_trashAI::UpdateAI(diff); + if (IsEvent || IsOverrun) { CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); npc_escortAI::UpdateAI(diff); } + if (IsEvent) { if (!go) @@ -1315,6 +1324,7 @@ public: } } } + if (IsOverrun && !UpdateVictim()) { if (faction == 0)//alliance @@ -1326,8 +1336,10 @@ public: } else StrikeTimer -= diff; } } + if (!UpdateVictim()) return; + if (!me->IsWithinDist(me->GetVictim(), 20) || forcemove) { forcemove = false; @@ -1347,6 +1359,7 @@ public: MoveTimer = 2000; } else MoveTimer-=diff; } + if (StrikeTimer <= diff) { if (me->IsWithinDist(me->GetVictim(), 20)) @@ -1359,7 +1372,6 @@ public: } else StrikeTimer -= diff; } }; - }; class alliance_rifleman : public CreatureScript diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp index e4f1324d19c..7c0169cda95 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp @@ -147,7 +147,7 @@ public: return; } - if (Creature* pArthas = me->GetCreature(*me, instance ? instance->GetData64(DATA_ARTHAS) : 0)) + if (Creature* pArthas = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ARTHAS))) if (pArthas->isDead()) { EnterEvadeMode(); @@ -196,7 +196,7 @@ public: uiOutroTimer = 8000; break; case 2: - me->SetTarget(instance ? instance->GetData64(DATA_ARTHAS) : 0); + me->SetTarget(instance->GetData64(DATA_ARTHAS)); me->HandleEmoteCommand(29); Talk(SAY_ESCAPE_SPEECH_2); ++uiOutroStep; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp index 061c7fdfc62..5b1db051a56 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp @@ -99,7 +99,7 @@ public: { Talk(SAY_DEATH); - if (instance && instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) + if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) instance->SetData(TYPE_THRALL_PART1, DONE); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp index cb25d96acf3..4d75bc0545c 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp @@ -91,7 +91,7 @@ public: { Talk(SAY_DEATH); - if (instance && instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) + if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) instance->SetData(TYPE_THRALL_PART4, DONE); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 6e4ef814dbe..bf902ba403c 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -82,7 +82,7 @@ public: player->PrepareQuestMenu(creature->GetGUID()); InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS)) + if (instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS)) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); if (player->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE) @@ -92,7 +92,6 @@ public: return true; } - }; /*###### @@ -585,18 +584,14 @@ public: { player->CLOSE_GOSSIP_MENU(); - if (instance && instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) + if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS) { instance->SetData(TYPE_THRALL_PART4, IN_PROGRESS); if (instance->GetData64(DATA_EPOCH) == 0) creature->SummonCreature(ENTRY_EPOCH, 2639.13f, 698.55f, 65.43f, 4.59f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - if (uint64 ThrallGUID = instance->GetData64(DATA_THRALL)) - { - Creature* Thrall = (Unit::GetCreature((*creature), ThrallGUID)); - if (Thrall) - CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, Thrall->AI())->StartWP(); - } + if (Creature* thrall = (Unit::GetCreature(*creature, instance->GetData64(DATA_THRALL)))) + CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, thrall->AI())->StartWP(); } } return true; @@ -605,7 +600,7 @@ public: bool OnGossipHello(Player* player, Creature* creature) OVERRIDE { InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetData(TYPE_THRALL_PART3) == DONE && instance->GetData(TYPE_THRALL_PART4) == NOT_STARTED) + if (instance->GetData(TYPE_THRALL_PART3) == DONE && instance->GetData(TYPE_THRALL_PART4) == NOT_STARTED) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_EPOCH1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(GOSSIP_ID_EPOCH1, creature->GetGUID()); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp index f1406a5a008..58bda23fb36 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp @@ -138,8 +138,8 @@ public: void AttackStart(Unit* /*who*/) OVERRIDE { - //if (instance && instance->GetData(TYPE_MEDIVH) == IN_PROGRESS) - //return; + //if (instance->GetData(TYPE_MEDIVH) == IN_PROGRESS) + // return; //ScriptedAI::AttackStart(who); } @@ -297,7 +297,7 @@ public: if (!creature_entry) return; - if (instance && instance->GetData(TYPE_MEDIVH) != IN_PROGRESS) + if (instance->GetData(TYPE_MEDIVH) != IN_PROGRESS) { me->InterruptNonMeleeSpells(true); me->RemoveAllAuras(); @@ -311,7 +311,7 @@ public: pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) - if (Unit* temp = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_MEDIVH) : 0)) + if (Unit* temp = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH))) Summon->AddThreat(temp, 0.0f); } diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp index 7381594a1ce..29e08699a0f 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp @@ -340,7 +340,7 @@ public: Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15); Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check); me->VisitNearbyGridObject(30, searcher); - if (instance && Floor) + if (Floor) instance->SetData64(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID()); events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30000); break; diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp index d29831b8cde..830c3fed382 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp @@ -40,7 +40,10 @@ public: struct boss_gluttonAI : public BossAI { - boss_gluttonAI(Creature* creature) : BossAI(creature, DATA_GLUTTON) { } + boss_gluttonAI(Creature* creature) : BossAI(creature, DATA_GLUTTON) + { + hp15 = false; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp index 3b4defeca56..b9605794074 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp @@ -158,6 +158,7 @@ public: { instance = creature->GetInstanceScript(); eventInProgress = false; + spawnerCount = 0; } void Reset() OVERRIDE @@ -177,9 +178,7 @@ public: void EnterCombat(Unit* who) OVERRIDE { if (channeling) - { Talk(SAY_WATCH_OUT, who); - } else { events.ScheduleEvent(EVENT_FIREBALL, 1000); diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h index 4778677e067..a9a5a82f127 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h +++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h @@ -61,13 +61,9 @@ enum GameObjectIds }; template<class AI> -CreatureAI* GetRazorfenDownsAI(Creature* creature) +AI* GetRazorfenDownsAI(Creature* creature) { - if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) - if (instance->GetInstanceScript()) - if (instance->GetScriptId() == sObjectMgr->GetScriptId(RFDScriptName)) - return new AI(creature); - return NULL; + return GetInstanceAI<AI>(creature, RFDScriptName); } #endif diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp index c1897ff48ad..433193bd703 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp @@ -119,7 +119,7 @@ public: //Checking if Vem is dead. If yes we will enrage. if (Check_Timer <= diff) { - if (instance && instance->GetData(DATA_VEMISDEAD)) + if (instance->GetData(DATA_VEMISDEAD)) { DoCast(me, SPELL_ENRAGE); VemDead = true; diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp index 81171eef580..d84279f1e8b 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp @@ -502,8 +502,6 @@ public: //Added. Can be removed if its included in DB. me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, 0); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, 0); } void CastSpellOnBug(Creature* target) diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp index 41c0441bca5..ec28ee42625 100644 --- a/src/server/scripts/Kalimdor/zone_ashenvale.cpp +++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp @@ -198,7 +198,7 @@ public: void sQuestAccept(Player* player, Quest const* quest) { - if (quest->GetQuestId() == QUEST_TOREK_ASSULT) + if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL) { me->setFaction(FACTION_QUEST); npc_escortAI::Start(true, false, player->GetGUID()); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp index 0b281c58839..84c9181e495 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp @@ -232,7 +232,6 @@ public: npc_nadox_eggsAI(Creature* creature) : ScriptedAI(creature) { creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); - creature->UpdateAllStats(); } void Reset() OVERRIDE { } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp index 1890dfb4ff8..f599e6e7c27 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp @@ -394,7 +394,7 @@ public: void AttackStart(Unit* victim) OVERRIDE { - if ((instance && instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !victim) + if ((instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !victim) return; ScriptedAI::AttackStart(victim); @@ -403,7 +403,7 @@ public: void MoveInLineOfSight(Unit* who) OVERRIDE { - if ((instance && instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !who) + if ((instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !who) return; ScriptedAI::MoveInLineOfSight(who); @@ -432,7 +432,7 @@ public: void UpdateAI(uint32 diff) OVERRIDE { - if (instance && bCheckTimer <= diff) + if (bCheckTimer <= diff) { if (me->GetGUID() == instance->GetData64(DATA_ADD_JEDOGA_OPFER) && !bWalking) { diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index 77d3ce21d0c..efe439de440 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -17,76 +17,75 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "Player.h" #include "ahnkahet.h" enum Spells { - SPELL_BLOODTHIRST = 55968, // Trigger Spell + add aura - SPELL_CONJURE_FLAME_SPHERE = 55931, - SPELL_FLAME_SPHERE_SUMMON_1 = 55895, // 1x 30106 - H_SPELL_FLAME_SPHERE_SUMMON_1 = 59511, // 1x 31686 - H_SPELL_FLAME_SPHERE_SUMMON_2 = 59512, // 1x 31687 - SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891, - SPELL_FLAME_SPHERE_VISUAL = 55928, - SPELL_FLAME_SPHERE_PERIODIC = 55926, - SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947, - SPELL_BEAM_VISUAL = 60342, - SPELL_EMBRACE_OF_THE_VAMPYR = 55959, - SPELL_VANISH = 55964, - CREATURE_FLAME_SPHERE = 30106, - H_CREATURE_FLAME_SPHERE_1 = 31686, - H_CREATURE_FLAME_SPHERE_2 = 31687, - SPELL_HOVER_FALL = 60425 + SPELL_BLOODTHIRST = 55968, // Trigger Spell + add aura + SPELL_CONJURE_FLAME_SPHERE = 55931, + SPELL_FLAME_SPHERE_SUMMON_1 = 55895, // 1x 30106 + SPELL_FLAME_SPHERE_SUMMON_2 = 59511, // 1x 31686 + SPELL_FLAME_SPHERE_SUMMON_3 = 59512, // 1x 31687 + SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891, + SPELL_FLAME_SPHERE_VISUAL = 55928, + SPELL_FLAME_SPHERE_PERIODIC = 55926, + SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947, + SPELL_EMBRACE_OF_THE_VAMPYR = 55959, + SPELL_VANISH = 55964, + + NPC_FLAME_SPHERE_1 = 30106, + NPC_FLAME_SPHERE_2 = 31686, + NPC_FLAME_SPHERE_3 = 31687, + + SPELL_BEAM_VISUAL = 60342, + SPELL_HOVER_FALL = 60425 }; enum Misc { - DATA_EMBRACE_DMG = 20000, - H_DATA_EMBRACE_DMG = 40000, - DATA_SPHERE_DISTANCE = 15 + DATA_EMBRACE_DMG = 20000, + H_DATA_EMBRACE_DMG = 40000 }; -#define DATA_SPHERE_ANGLE_OFFSET 0.7f -#define DATA_GROUND_POSITION_Z 11.30809f +#define DATA_SPHERE_DISTANCE 25.0f +#define DATA_SPHERE_ANGLE_OFFSET M_PI / 2 +#define DATA_GROUND_POSITION_Z 11.30809f enum Yells { - SAY_1 = 0, - SAY_WARNING = 1, - SAY_AGGRO = 2, - SAY_SLAY = 3, - SAY_DEATH = 4, - SAY_FEED = 5, - SAY_VANISH = 6 + SAY_1 = 0, + SAY_WARNING = 1, + SAY_AGGRO = 2, + SAY_SLAY = 3, + SAY_DEATH = 4, + SAY_FEED = 5, + SAY_VANISH = 6 }; enum Events { - EVENT_CASTING_FLAME_SPHERES = 1, + EVENT_CONJURE_FLAME_SPHERES = 1, + EVENT_BLOODTHIRST, + EVENT_VANISH, EVENT_JUST_VANISHED, EVENT_VANISHED, EVENT_FEEDING, - EVENT_BLOODTHIRST, - EVENT_FLAME_SPHERE, - EVENT_VANISH -}; - -enum Phase -{ - PHASE_NORMAL = 1, - PHASE_SPECIAL = 2 + // Flame Sphere + EVENT_START_MOVE, + EVENT_DESPAWN }; -class boss_taldaram : public CreatureScript +class boss_prince_taldaram : public CreatureScript { public: - boss_taldaram() : CreatureScript("boss_taldaram") { } + boss_prince_taldaram() : CreatureScript("boss_prince_taldaram") { } - struct boss_taldaramAI : public BossAI + struct boss_prince_taldaramAI : public BossAI { - boss_taldaramAI(Creature* creature) : BossAI(creature, DATA_PRINCE_TALDARAM) + boss_prince_taldaramAI(Creature* creature) : BossAI(creature, DATA_PRINCE_TALDARAM) { me->SetDisableGravity(true); } @@ -94,6 +93,7 @@ class boss_taldaram : public CreatureScript void Reset() OVERRIDE { _Reset(); + _flameSphereTargetGUID = 0; _embraceTargetGUID = 0; _embraceTakenDamage = 0; } @@ -102,10 +102,24 @@ class boss_taldaram : public CreatureScript { _EnterCombat(); Talk(SAY_AGGRO); - events.SetPhase(PHASE_NORMAL); events.ScheduleEvent(EVENT_BLOODTHIRST, 10000); events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000)); - events.ScheduleEvent(EVENT_FLAME_SPHERE, 5000); + events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 5000); + } + + void JustSummoned(Creature* summon) + { + BossAI::JustSummoned(summon); + + switch (summon->GetEntry()) + { + case NPC_FLAME_SPHERE_1: + case NPC_FLAME_SPHERE_2: + case NPC_FLAME_SPHERE_3: + summon->AI()->SetGUID(_flameSphereTargetGUID); + default: + return; + } } void UpdateAI(uint32 diff) OVERRIDE @@ -122,80 +136,40 @@ class boss_taldaram : public CreatureScript { switch (eventId) { - if (events.IsInPhase(PHASE_NORMAL)) - { - case EVENT_BLOODTHIRST: - DoCast(me, SPELL_BLOODTHIRST); - events.ScheduleEvent(EVENT_BLOODTHIRST, 10000); - break; - case EVENT_FLAME_SPHERE: - DoCastVictim(SPELL_CONJURE_FLAME_SPHERE); - events.SetPhase(PHASE_SPECIAL); - events.ScheduleEvent(EVENT_CASTING_FLAME_SPHERES, 3000); - events.ScheduleEvent(EVENT_FLAME_SPHERE, 15000); - break; - case EVENT_VANISH: + case EVENT_BLOODTHIRST: + DoCast(me, SPELL_BLOODTHIRST); + events.ScheduleEvent(EVENT_BLOODTHIRST, 10000); + break; + case EVENT_CONJURE_FLAME_SPHERES: + // random target? + if (Unit* victim = me->GetVictim()) { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - uint32 targets = 0; - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - { - Player* player = i->GetSource(); - if (player && player->IsAlive()) - ++targets; - } - - if (targets > 2) - { - Talk(SAY_VANISH); - DoCast(me, SPELL_VANISH); - events.SetPhase(PHASE_SPECIAL); - events.ScheduleEvent(EVENT_JUST_VANISHED, 500); - if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - _embraceTargetGUID = embraceTarget->GetGUID(); - } - events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000)); - break; + _flameSphereTargetGUID = victim->GetGUID(); + DoCast(victim, SPELL_CONJURE_FLAME_SPHERE); } - } - case EVENT_CASTING_FLAME_SPHERES: + events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 15000); + break; + case EVENT_VANISH: { - events.SetPhase(PHASE_NORMAL); - Unit* sphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); - if (!sphereTarget) - break; - - float angle, x, y; - - //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1); - if (Creature* sphere = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS)) + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + uint32 targets = 0; + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) { - angle = sphere->GetAngle(sphereTarget); - x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle); - y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle); - sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ()); + Player* player = i->GetSource(); + if (player && player->IsAlive()) + ++targets; } - if (IsHeroic()) + if (targets > 2) { - //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1); - if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS)) - { - angle = sphere->GetAngle(sphereTarget) + DATA_SPHERE_ANGLE_OFFSET; - x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle); - y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle); - sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ()); - } - - //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2); - if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS)) - { - angle = sphere->GetAngle(sphereTarget) - DATA_SPHERE_ANGLE_OFFSET; - x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle); - y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle); - sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ()); - } + Talk(SAY_VANISH); + DoCast(me, SPELL_VANISH); + events.DelayEvents(500); + events.ScheduleEvent(EVENT_JUST_VANISHED, 500); + if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + _embraceTargetGUID = embraceTarget->GetGUID(); } + events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000)); break; } case EVENT_JUST_VANISHED: @@ -218,7 +192,6 @@ class boss_taldaram : public CreatureScript break; case EVENT_FEEDING: _embraceTargetGUID = 0; - events.SetPhase(PHASE_NORMAL); break; default: break; @@ -232,13 +205,12 @@ class boss_taldaram : public CreatureScript { Unit* embraceTarget = GetEmbraceTarget(); - if (events.IsInPhase(PHASE_SPECIAL) && embraceTarget && embraceTarget->IsAlive()) + if (embraceTarget && embraceTarget->IsAlive()) { _embraceTakenDamage += damage; if (_embraceTakenDamage > DUNGEON_MODE<uint32>(DATA_EMBRACE_DMG, H_DATA_EMBRACE_DMG)) { _embraceTargetGUID = 0; - events.SetPhase(PHASE_NORMAL); me->CastStop(); } } @@ -255,12 +227,9 @@ class boss_taldaram : public CreatureScript if (victim->GetTypeId() != TYPEID_PLAYER) return; - Unit* embraceTarget = GetEmbraceTarget(); - if (events.IsInPhase(PHASE_SPECIAL) && embraceTarget && victim == embraceTarget) - { + if (victim->GetGUID() == _embraceTargetGUID) _embraceTargetGUID = 0; - events.SetPhase(PHASE_NORMAL); - } + Talk(SAY_SLAY); } @@ -289,76 +258,120 @@ class boss_taldaram : public CreatureScript me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation()); DoCast(SPELL_HOVER_FALL); me->SetDisableGravity(false); - me->GetMotionMaster()->MovePoint(0, me->GetHomePosition()); + me->GetMotionMaster()->MoveLand(0, me->GetHomePosition()); Talk(SAY_WARNING); instance->HandleGameObject(instance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM), true); } private: + uint64 _flameSphereTargetGUID; uint64 _embraceTargetGUID; uint32 _embraceTakenDamage; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return GetAhnKahetAI<boss_taldaramAI>(creature); + return GetAhnKahetAI<boss_prince_taldaramAI>(creature); } }; -class npc_taldaram_flamesphere : public CreatureScript +// 30106, 31686, 31687 - Flame Sphere +class npc_prince_taldaram_flame_sphere : public CreatureScript { public: - npc_taldaram_flamesphere() : CreatureScript("npc_taldaram_flamesphere") { } + npc_prince_taldaram_flame_sphere() : CreatureScript("npc_prince_taldaram_flame_sphere") { } - struct npc_taldaram_flamesphereAI : public ScriptedAI + struct npc_prince_taldaram_flame_sphereAI : public ScriptedAI { - npc_taldaram_flamesphereAI(Creature* creature) : ScriptedAI(creature) + npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() OVERRIDE { + DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT, true); + DoCast(me, SPELL_FLAME_SPHERE_VISUAL, true); + + _flameSphereTargetGUID = 0; + _events.Reset(); + _events.ScheduleEvent(EVENT_START_MOVE, 3 * IN_MILLISECONDS); + _events.ScheduleEvent(EVENT_DESPAWN, 13 * IN_MILLISECONDS); } - void Reset() OVERRIDE + void SetGUID(uint64 guid, int32 /*id = 0*/) OVERRIDE { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - //! HACK: Creature's can't have MOVEMENTFLAG_FLYING - me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING); - me->setFaction(16); - me->SetObjectScale(1.0f); - DoCast(me, SPELL_FLAME_SPHERE_VISUAL); - DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT); - DoCast(me, SPELL_FLAME_SPHERE_PERIODIC); - _despawnTimer = 10 * IN_MILLISECONDS; + _flameSphereTargetGUID = guid; } void EnterCombat(Unit* /*who*/) OVERRIDE { } void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { } - void JustDied(Unit* /*killer*/) OVERRIDE - { - DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT); - } - void UpdateAI(uint32 diff) OVERRIDE { - if (_despawnTimer <= diff) - me->DisappearAndDie(); - else - _despawnTimer -= diff; + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_START_MOVE: + { + DoCast(me, SPELL_FLAME_SPHERE_PERIODIC, true); + + /// @todo: find correct values + float angleOffset = 0.0f; + float distOffset = DATA_SPHERE_DISTANCE; + + switch (me->GetEntry()) + { + case NPC_FLAME_SPHERE_1: + break; + case NPC_FLAME_SPHERE_2: + angleOffset = DATA_SPHERE_ANGLE_OFFSET; + break; + case NPC_FLAME_SPHERE_3: + angleOffset = -DATA_SPHERE_ANGLE_OFFSET; + break; + default: + return; + } + + Unit* sphereTarget = ObjectAccessor::GetUnit(*me, _flameSphereTargetGUID); + if (!sphereTarget) + return; + + float angle = me->GetAngle(sphereTarget) + angleOffset; + float x = me->GetPositionX() + distOffset * std::cos(angle); + float y = me->GetPositionY() + distOffset * std::sin(angle); + + /// @todo: correct speed + me->GetMotionMaster()->MovePoint(0, x, y, me->GetPositionZ()); + break; + } + case EVENT_DESPAWN: + DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT, true); + me->DespawnOrUnsummon(1000); + break; + default: + break; + } + } } private: - uint32 _despawnTimer; + EventMap _events; + uint64 _flameSphereTargetGUID; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new npc_taldaram_flamesphereAI(creature); + return new npc_prince_taldaram_flame_sphereAI(creature); } }; -class prince_taldaram_sphere : public GameObjectScript +// 193093, 193094 - Ancient Nerubian Device +class go_prince_taldaram_sphere : public GameObjectScript { public: - prince_taldaram_sphere() : GameObjectScript("prince_taldaram_sphere") { } + go_prince_taldaram_sphere() : GameObjectScript("go_prince_taldaram_sphere") { } bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE { @@ -369,7 +382,6 @@ class prince_taldaram_sphere : public GameObjectScript Creature* PrinceTaldaram = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_PRINCE_TALDARAM)); if (PrinceTaldaram && PrinceTaldaram->IsAlive()) { - // maybe these are hacks :( go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); go->SetGoState(GO_STATE_ACTIVE); @@ -385,15 +397,88 @@ class prince_taldaram_sphere : public GameObjectScript break; } - CAST_AI(boss_taldaram::boss_taldaramAI, PrinceTaldaram->AI())->CheckSpheres(); + CAST_AI(boss_prince_taldaram::boss_prince_taldaramAI, PrinceTaldaram->AI())->CheckSpheres(); } return true; } }; +// 55931 - Conjure Flame Sphere +class spell_prince_taldaram_conjure_flame_sphere : public SpellScriptLoader +{ + public: + spell_prince_taldaram_conjure_flame_sphere() : SpellScriptLoader("spell_prince_taldaram_conjure_flame_sphere") { } + + class spell_prince_taldaram_conjure_flame_sphere_SpellScript : public SpellScript + { + PrepareSpellScript(spell_prince_taldaram_conjure_flame_sphere_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_1) + || !sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_2) + || !sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_3)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_1, true); + + if (caster->GetMap()->IsHeroic()) + { + caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_2, true); + caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_3, true); + } + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_prince_taldaram_conjure_flame_sphere_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_prince_taldaram_conjure_flame_sphere_SpellScript(); + } +}; + +// 55895, 59511, 59512 - Flame Sphere Summon +class spell_prince_taldaram_flame_sphere_summon : public SpellScriptLoader +{ + public: + spell_prince_taldaram_flame_sphere_summon() : SpellScriptLoader("spell_prince_taldaram_flame_sphere_summon") { } + + class spell_prince_taldaram_flame_sphere_summon_SpellScript : public SpellScript + { + PrepareSpellScript(spell_prince_taldaram_flame_sphere_summon_SpellScript); + + void SetDest(SpellDestination& dest) + { + Position offset = { 0.0f, 0.0f, 5.5f, 0.0f }; + dest.RelocateOffset(offset); + } + + void Register() OVERRIDE + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_prince_taldaram_flame_sphere_summon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_prince_taldaram_flame_sphere_summon_SpellScript(); + } +}; + void AddSC_boss_taldaram() { - new boss_taldaram(); - new npc_taldaram_flamesphere(); - new prince_taldaram_sphere(); + new boss_prince_taldaram(); + new npc_prince_taldaram_flame_sphere(); + new go_prince_taldaram_sphere(); + new spell_prince_taldaram_conjure_flame_sphere(); + new spell_prince_taldaram_flame_sphere_summon(); } diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp index 7534e747ee0..a7ad7dbfb4b 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp @@ -84,7 +84,7 @@ public: uiDoorsTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS); uiCheckDistanceTimer = 2*IN_MILLISECONDS; - if (instance && (instance->GetBossState(DATA_HADRONOX) != DONE && !bFirstTime)) + if (instance->GetBossState(DATA_HADRONOX) != DONE && !bFirstTime) instance->SetBossState(DATA_HADRONOX, FAIL); bFirstTime = false; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp index 0b50375b809..045564ce570 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp @@ -467,7 +467,7 @@ public: CallDragon(DATA_TENEBRON); break; case EVENT_CALL_SHADRON: - CallDragon(DATA_SHADRON); + CallDragon(DATA_SHADRON); break; case EVENT_CALL_VESPERON: CallDragon(DATA_VESPERON); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp index dd699911786..9ae6f811e19 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp @@ -253,7 +253,7 @@ struct dummy_dragonAI : public ScriptedAI { case NPC_TENEBRON: { - if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) { for (uint32 i = 0; i < 6; ++i) me->SummonCreature(NPC_TWILIGHT_EGG, TwilightEggs[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000); @@ -267,7 +267,7 @@ struct dummy_dragonAI : public ScriptedAI } case NPC_SHADRON: { - if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000); else me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000); @@ -276,7 +276,7 @@ struct dummy_dragonAI : public ScriptedAI } case NPC_VESPERON: { - if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) + if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS) { if (Creature* acolyte = me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) { @@ -328,19 +328,19 @@ struct dummy_dragonAI : public ScriptedAI { case NPC_TENEBRON: spellId = SPELL_POWER_OF_TENEBRON; - if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) + if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) instance->SetBossState(DATA_TENEBRON, DONE); break; case NPC_SHADRON: spellId = SPELL_POWER_OF_SHADRON; - if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) + if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) instance->SetBossState(DATA_SHADRON, DONE); if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_SHADRON, 100.0f)) acolyte->Kill(acolyte); break; case NPC_VESPERON: spellId = SPELL_POWER_OF_VESPERON; - if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) + if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS) instance->SetBossState(DATA_VESPERON, DONE); if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_VESPERON, 100.0f)) acolyte->Kill(acolyte); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp index 91c1563b494..6c0acc9bba4 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp @@ -252,9 +252,8 @@ class npc_baltharus_the_warborn_clone : public CreatureScript void JustDied(Unit* killer) OVERRIDE { // This is here because DamageTaken wont trigger if the damage is deadly. - if (_instance) - if (Creature* baltharus = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_BALTHARUS_THE_WARBORN))) - killer->Kill(baltharus); + if (Creature* baltharus = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_BALTHARUS_THE_WARBORN))) + killer->Kill(baltharus); } void UpdateAI(uint32 diff) OVERRIDE @@ -262,8 +261,7 @@ class npc_baltharus_the_warborn_clone : public CreatureScript if (!UpdateVictim()) return; - if (_instance) - me->SetHealth(_instance->GetData(DATA_BALTHARUS_SHARED_HEALTH)); + me->SetHealth(_instance->GetData(DATA_BALTHARUS_SHARED_HEALTH)); _events.Update(diff); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 0f583d54a13..c35c9ba2d11 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -1697,6 +1697,7 @@ class spell_halion_twilight_phasing : public SpellScriptLoader } }; +// 74805 - Summon Exit Portals class spell_halion_summon_exit_portals : public SpellScriptLoader { public: @@ -1706,23 +1707,22 @@ class spell_halion_summon_exit_portals : public SpellScriptLoader { PrepareSpellScript(spell_halion_summon_exit_portals_SpellScript); - void OnSummon(SpellEffIndex effIndex) + void SetDest0(SpellDestination& dest) { - WorldLocation summonPos = *GetExplTargetDest(); - Position offset = {0.0f, 20.0f, 0.0f, 0.0f}; - if (effIndex == EFFECT_1) - offset.m_positionY = -20.0f; - - summonPos.RelocateOffset(offset); + Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f }; + dest.RelocateOffset(offset); + } - SetExplTargetDest(summonPos); - GetHitDest()->RelocateOffset(offset); + void SetDest1(SpellDestination& dest) + { + Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectLaunch += SpellEffectFn(spell_halion_summon_exit_portals_SpellScript::OnSummon, EFFECT_0, SPELL_EFFECT_SUMMON_OBJECT_WILD); - OnEffectLaunch += SpellEffectFn(spell_halion_summon_exit_portals_SpellScript::OnSummon, EFFECT_1, SPELL_EFFECT_SUMMON_OBJECT_WILD); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals_SpellScript::SetDest0, EFFECT_0, TARGET_DEST_CASTER); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals_SpellScript::SetDest1, EFFECT_1, TARGET_DEST_CASTER); } }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp index 3b1b5d4fd24..d2f6b8a3420 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp @@ -363,11 +363,11 @@ public: { bDone = true; - if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) + if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f); EnterEvadeMode(); @@ -496,11 +496,11 @@ public: { bDone = true; - if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) + if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f); instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS); @@ -639,11 +639,11 @@ public: { bDone = true; - if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) + if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f); instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS); @@ -783,11 +783,11 @@ public: { bDone = true; - if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) + if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f); instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS); @@ -929,11 +929,11 @@ public: { bDone = true; - if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) + if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1)) me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2)) me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f); - else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) + else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3)) me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f); instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp index ab21393fce3..a60e69d6479 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp @@ -431,7 +431,7 @@ public: void JustSummoned(Creature* summon) OVERRIDE { - if (instance && instance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED) + if (instance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED) { summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); summon->SetReactState(REACT_PASSIVE); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index 0b9b9f2543f..93d5c399725 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -470,7 +470,7 @@ class npc_swarm_scarab : public CreatureScript void UpdateAI(uint32 diff) OVERRIDE { - if (_instance && _instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS) + if (_instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS) me->DisappearAndDie(); if (!UpdateVictim()) @@ -540,7 +540,7 @@ class npc_nerubian_burrower : public CreatureScript void UpdateAI(uint32 diff) OVERRIDE { - if (_instance && _instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS) + if (_instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS) me->DisappearAndDie(); if (!UpdateVictim() && !me->HasAura(SPELL_SUBMERGE_EFFECT)) diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp index 99423a4b7ae..cb4b3cfcea3 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp @@ -239,7 +239,7 @@ class npc_legion_flame : public CreatureScript void UpdateAI(uint32 /*diff*/) OVERRIDE { UpdateVictim(); - if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) + if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) me->DespawnOrUnsummon(); } private: @@ -326,7 +326,7 @@ class npc_fel_infernal : public CreatureScript void UpdateAI(uint32 diff) OVERRIDE { - if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) + if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) { me->DespawnOrUnsummon(); return; @@ -420,8 +420,7 @@ class npc_mistress_of_pain : public CreatureScript npc_mistress_of_painAI(Creature* creature) : ScriptedAI(creature) { _instance = creature->GetInstanceScript(); - if (_instance) - _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE); + _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE); } void Reset() OVERRIDE @@ -435,13 +434,12 @@ class npc_mistress_of_pain : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (_instance) - _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE); + _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE); } void UpdateAI(uint32 diff) OVERRIDE { - if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) + if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS) { me->DespawnOrUnsummon(); return; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index a11a74250f5..ea166585bb3 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -295,8 +295,7 @@ class npc_snobold_vassal : public CreatureScript npc_snobold_vassalAI(Creature* creature) : ScriptedAI(creature) { _instance = creature->GetInstanceScript(); - if (_instance) - _instance->SetData(DATA_SNOBOLD_COUNT, INCREASE); + _instance->SetData(DATA_SNOBOLD_COUNT, INCREASE); } void Reset() OVERRIDE @@ -350,8 +349,7 @@ class npc_snobold_vassal : public CreatureScript if (Unit* target = ObjectAccessor::GetPlayer(*me, _targetGUID)) if (target->IsAlive()) target->RemoveAurasDueToSpell(SPELL_SNOBOLLED); - if (_instance) - _instance->SetData(DATA_SNOBOLD_COUNT, DECREASE); + _instance->SetData(DATA_SNOBOLD_COUNT, DECREASE); } void DoAction(int32 action) OVERRIDE @@ -378,30 +376,27 @@ class npc_snobold_vassal : public CreatureScript { if (!target->IsAlive()) { - if (_instance) + Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_GORMOK)); + if (gormok && gormok->IsAlive()) { - Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_GORMOK)); - if (gormok && gormok->IsAlive()) - { - SetCombatMovement(false); - _targetDied = true; + SetCombatMovement(false); + _targetDied = true; - // looping through Gormoks seats - for (uint8 i = 0; i < MAX_SNOBOLDS; i++) + // looping through Gormoks seats + for (uint8 i = 0; i < MAX_SNOBOLDS; i++) + { + if (!gormok->GetVehicleKit()->GetPassenger(i)) { - if (!gormok->GetVehicleKit()->GetPassenger(i)) - { - me->EnterVehicle(gormok, i); - DoAction(ACTION_ENABLE_FIRE_BOMB); - break; - } + me->EnterVehicle(gormok, i); + DoAction(ACTION_ENABLE_FIRE_BOMB); + break; } } - else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - { - _targetGUID = target2->GetGUID(); - me->GetMotionMaster()->MoveJump(target2->GetPositionX(), target2->GetPositionY(), target2->GetPositionZ(), 15.0f, 15.0f); - } + } + else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + { + _targetGUID = target2->GetGUID(); + me->GetMotionMaster()->MoveJump(target2->GetPositionX(), target2->GetPositionY(), target2->GetPositionZ(), 15.0f, 15.0f); } } } @@ -528,7 +523,7 @@ struct boss_jormungarAI : public BossAI void JustReachedHome() OVERRIDE { // prevent losing 2 attempts at once on heroics - if (instance && instance->GetData(TYPE_NORTHREND_BEASTS) != FAIL) + if (instance->GetData(TYPE_NORTHREND_BEASTS) != FAIL) instance->SetData(TYPE_NORTHREND_BEASTS, FAIL); me->DespawnOrUnsummon(); @@ -552,7 +547,7 @@ struct boss_jormungarAI : public BossAI if (!UpdateVictim()) return; - if (!Enraged && instance && instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL) + if (!Enraged && instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL) { me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index d0120e4c2de..0d7dc9062ad 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -281,7 +281,6 @@ struct boss_twin_baseAI : public BossAI { SetEquipmentSlots(false, Weapon, mode ? Weapon : int32(EQUIP_UNEQUIP), EQUIP_UNEQUIP); me->SetCanDualWield(mode); - me->UpdateDamagePhysical(mode ? OFF_ATTACK : BASE_ATTACK); } void UpdateAI(uint32 diff) OVERRIDE diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index cb0ec2acc38..fdefde10b4f 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -247,8 +247,8 @@ class boss_lich_king_toc : public CreatureScript summoned->CastSpell(summoned, 51807, false); summoned->SetDisplayId(summoned->GetCreatureTemplate()->Modelid2); } - if (_instance) - _instance->SetBossState(BOSS_LICH_KING, IN_PROGRESS); + + _instance->SetBossState(BOSS_LICH_KING, IN_PROGRESS); me->SetWalk(true); } @@ -401,12 +401,9 @@ class npc_fizzlebang_toc : public CreatureScript { case 1: me->SetWalk(false); - if (_instance) - { - _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR)); - _instance->SetData(TYPE_EVENT, 1120); - _instance->SetData(TYPE_EVENT_TIMER, 1*IN_MILLISECONDS); - } + _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR)); + _instance->SetData(TYPE_EVENT, 1120); + _instance->SetData(TYPE_EVENT_TIMER, 1*IN_MILLISECONDS); break; default: break; diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index c9247ce17f3..027a6843c87 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -664,8 +664,7 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript _events.ScheduleEvent(EVENT_INTRO_END, 5000); break; case EVENT_INTRO_END: - if (_instance) - _instance->SetData(DATA_INTRO_EVENT, DONE); + _instance->SetData(DATA_INTRO_EVENT, DONE); // Loralen or Koreln disappearAndDie() if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { @@ -1830,7 +1829,7 @@ public: _emergeTimer = 4000; _doEmerge = false; _doJump = false; - if (_instance && _instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) _instance->SetData(DATA_SUMMONS, 1); } @@ -1843,8 +1842,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (_instance) - _instance->SetData(DATA_SUMMONS, 0); + _instance->SetData(DATA_SUMMONS, 0); } void AttackStart(Unit* who) OVERRIDE @@ -1932,9 +1930,8 @@ public: _boltVolleyTimer = 15000; _curseTimer = 7000; _doEmerge = false; - if (_instance) - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) - _instance->SetData(DATA_SUMMONS, 1); + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + _instance->SetData(DATA_SUMMONS, 1); } void IsSummonedBy(Unit*) OVERRIDE @@ -1945,9 +1942,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (_instance) - _instance->SetData(DATA_SUMMONS, 0); - + _instance->SetData(DATA_SUMMONS, 0); } void AttackStart(Unit* who) OVERRIDE @@ -2049,9 +2044,8 @@ public: _doWalk = false; _vomitTimer = 15000; _strikeTimer = 6000; - if (_instance) - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) - _instance->SetData(DATA_SUMMONS, 1); + if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + _instance->SetData(DATA_SUMMONS, 1); } void IsSummonedBy(Unit*) OVERRIDE @@ -2062,9 +2056,6 @@ public: void UpdateAI(uint32 diff) OVERRIDE { - if (!_instance) - return; - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) { if (_doWalk != true) @@ -2103,8 +2094,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (_instance) - _instance->SetData(DATA_SUMMONS, 0); + _instance->SetData(DATA_SUMMONS, 0); } }; diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h index ff3192b89d5..c4776c3cfcd 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -147,9 +147,9 @@ struct boss_horAI : ScriptedAI { events.Reset(); me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); me->SetReactState(REACT_PASSIVE); - if (instance && instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED) + if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED) instance->ProcessEvent(0, EVENT_DO_WIPE); } @@ -158,7 +158,7 @@ struct boss_horAI : ScriptedAI switch (actionID) { case ACTION_ENTER_COMBAT: // called by InstanceScript when boss shall enter in combat. - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); me->SetReactState(REACT_AGGRESSIVE); if (Unit* unit = me->SelectNearestTarget()) diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp index 0859d43ee85..fe2b818b325 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp @@ -111,12 +111,13 @@ class boss_garfrost : public CreatureScript { _JustDied(); Talk(SAY_DEATH); + me->RemoveAllGameObjects(); if (Creature* tyrannus = me->GetCreature(*me, instance->GetData64(DATA_TYRANNUS))) tyrannus->AI()->Talk(SAY_TYRANNUS_DEATH); } - void DamageTaken(Unit* /*attacker*/, uint32& /*uiDamage*/) OVERRIDE + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE { if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(66)) { diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp index 5a16271d378..46912eeb898 100644 --- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp +++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp @@ -423,7 +423,7 @@ public: if (id == 1) { - if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0)) + if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS))) { colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS); if (!colossus->AI()->GetData(DATA_INTRO_DONE)) @@ -440,7 +440,7 @@ public: return; // we do this checks to see if the creature is one of the creatures that sorround the boss - if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0)) + if (Creature* colossus = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS))) { Position homePosition; me->GetHomePosition().GetPosition(&homePosition); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index 30c11ec556d..b053f0a0258 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -1492,6 +1492,7 @@ class spell_taldaram_ball_of_inferno_flame : public SpellScriptLoader } }; +// 72080 - Kinetic Bomb (Valanar) class spell_valanar_kinetic_bomb : public SpellScriptLoader { public: @@ -1501,18 +1502,15 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader { PrepareSpellScript(spell_valanar_kinetic_bomb_SpellScript); - void ChangeSummonPos(SpellEffIndex /*effIndex*/) + void SetDest(SpellDestination& dest) { - WorldLocation summonPos = *GetExplTargetDest(); - Position offset = {0.0f, 0.0f, 20.0f, 0.0f}; - summonPos.RelocateOffset(offset); - SetExplTargetDest(summonPos); - GetHitDest()->RelocateOffset(offset); + Position const offset = { 0.0f, 0.0f, 20.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectHit += SpellEffectFn(spell_valanar_kinetic_bomb_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_valanar_kinetic_bomb_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 7be766c0a0e..791f6fa2b80 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -773,7 +773,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript bool OnGossipHello(Player* player, Creature* creature) OVERRIDE { InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE) + if (instance->GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "We are ready to go, High Overlord. The Lich King must fall!", 631, -ACTION_START_EVENT); player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); @@ -921,7 +921,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript bool OnGossipHello(Player* player, Creature* creature) OVERRIDE { InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE) + if (instance->GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE) { player->ADD_GOSSIP_ITEM(0, "Let it begin...", 631, -ACTION_START_EVENT + 1); player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index f3b62cd7b24..ca2c75e502c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -2034,6 +2034,7 @@ class spell_svalna_remove_spear : public SpellScriptLoader } }; +// 72585 - Soul Missile class spell_icc_soul_missile : public SpellScriptLoader { public: @@ -2043,15 +2044,15 @@ class spell_icc_soul_missile : public SpellScriptLoader { PrepareSpellScript(spell_icc_soul_missile_SpellScript); - void RelocateDest() + void RelocateDest(SpellDestination& dest) { - static Position const offset = {0.0f, 0.0f, 200.0f, 0.0f}; - const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset); + static Position const offset = { 0.0f, 0.0f, 200.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnCast += SpellCastFn(spell_icc_soul_missile_SpellScript::RelocateDest); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_icc_soul_missile_SpellScript::RelocateDest, EFFECT_0, TARGET_DEST_CASTER); } }; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp index 3de5b6a7b2b..6769e3429fa 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp @@ -17,18 +17,19 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" #include "naxxramas.h" -#include "SpellInfo.h" enum Spells { SPELL_BOMBARD_SLIME = 28280, - SPELL_POISON_CLOUD = 28240, - SPELL_MUTATING_INJECTION = 28169, SPELL_SLIME_SPRAY = 28157, - H_SPELL_SLIME_SPRAY = 54364, - SPELL_BERSERK = 26662, - SPELL_POISON_CLOUD_ADD = 59116 + SPELL_MUTATING_INJECTION = 28169, + SPELL_MUTATING_EXPLOSION = 28206, + SPELL_POISON_CLOUD = 28240, + SPELL_POISON_CLOUD_PASSIVE = 28158, + SPELL_BERSERK = 26662 }; enum Events @@ -46,115 +47,183 @@ enum CreatureId class boss_grobbulus : public CreatureScript { -public: - boss_grobbulus() : CreatureScript("boss_grobbulus") { } + public: + boss_grobbulus() : CreatureScript("boss_grobbulus") { } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_grobbulusAI(creature); - } - - struct boss_grobbulusAI : public BossAI - { - boss_grobbulusAI(Creature* creature) : BossAI(creature, BOSS_GROBBULUS) + struct boss_grobbulusAI : public BossAI { - me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_POISON_CLOUD_ADD, true); - } + boss_grobbulusAI(Creature* creature) : BossAI(creature, BOSS_GROBBULUS) { } - void EnterCombat(Unit* /*who*/) OVERRIDE - { - _EnterCombat(); - events.ScheduleEvent(EVENT_CLOUD, 15000); - events.ScheduleEvent(EVENT_INJECT, 20000); - events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000); //not sure - events.ScheduleEvent(EVENT_BERSERK, 12*60000); - } + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.ScheduleEvent(EVENT_CLOUD, 15000); + events.ScheduleEvent(EVENT_INJECT, 20000); + events.ScheduleEvent(EVENT_SPRAY, urand(15000, 30000)); // not sure + events.ScheduleEvent(EVENT_BERSERK, 12 * 60000); + } - void SpellHitTarget(Unit* target, const SpellInfo* spell) OVERRIDE - { - if (spell->Id == uint32(SPELL_SLIME_SPRAY)) + void SpellHitTarget(Unit* target, SpellInfo const* spell) OVERRIDE { - if (TempSummon* slime = me->SummonCreature(NPC_FALLOUT_SLIME, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0)) - DoZoneInCombat(slime); + if (spell->Id == SPELL_SLIME_SPRAY) + me->SummonCreature(NPC_FALLOUT_SLIME, *target, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT); } - } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - events.Update(diff); + events.Update(diff); - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_CLOUD: - DoCastAOE(SPELL_POISON_CLOUD); - events.ScheduleEvent(EVENT_CLOUD, 15000); - return; - case EVENT_BERSERK: - DoCastAOE(SPELL_BERSERK); - return; - case EVENT_SPRAY: - DoCastAOE(SPELL_SLIME_SPRAY); - events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000); - return; - case EVENT_INJECT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) - if (!target->HasAura(SPELL_MUTATING_INJECTION)) + switch (eventId) + { + case EVENT_CLOUD: + DoCastAOE(SPELL_POISON_CLOUD); + events.ScheduleEvent(EVENT_CLOUD, 15000); + return; + case EVENT_BERSERK: + DoCastAOE(SPELL_BERSERK, true); + return; + case EVENT_SPRAY: + DoCastAOE(SPELL_SLIME_SPRAY); + events.ScheduleEvent(EVENT_SPRAY, urand(15000, 30000)); + return; + case EVENT_INJECT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_MUTATING_INJECTION)) DoCast(target, SPELL_MUTATING_INJECTION); - events.ScheduleEvent(EVENT_INJECT, 8000 + uint32(120 * me->GetHealthPct())); - return; + events.ScheduleEvent(EVENT_INJECT, 8000 + uint32(120 * me->GetHealthPct())); + return; + default: + break; + } } + + DoMeleeAttackIfReady(); } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_grobbulusAI(creature); } - }; - }; class npc_grobbulus_poison_cloud : public CreatureScript { -public: - npc_grobbulus_poison_cloud() : CreatureScript("npc_grobbulus_poison_cloud") { } + public: + npc_grobbulus_poison_cloud() : CreatureScript("npc_grobbulus_poison_cloud") { } + + struct npc_grobbulus_poison_cloudAI : public ScriptedAI + { + npc_grobbulus_poison_cloudAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + creature->SetReactState(REACT_PASSIVE); + } + + void IsSummonedBy(Unit* /*summoner*/) OVERRIDE + { + // no visual when casting in ctor or Reset() + DoCast(me, SPELL_POISON_CLOUD_PASSIVE, true); + } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_grobbulus_poison_cloudAI(creature); - } + void UpdateAI(uint32 /*diff*/) OVERRIDE { } + }; - struct npc_grobbulus_poison_cloudAI : public ScriptedAI - { - npc_grobbulus_poison_cloudAI(Creature* creature) : ScriptedAI(creature) + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - SetCombatMovement(false); + return new npc_grobbulus_poison_cloudAI(creature); } +}; + +// 28169 - Mutating Injection +class spell_grobbulus_mutating_injection : public SpellScriptLoader +{ + public: + spell_grobbulus_mutating_injection() : SpellScriptLoader("spell_grobbulus_mutating_injection") { } - uint32 Cloud_Timer; + class spell_grobbulus_mutating_injection_AuraScript : public AuraScript + { + PrepareAuraScript(spell_grobbulus_mutating_injection_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_MUTATING_EXPLOSION) + || !sSpellMgr->GetSpellInfo(SPELL_POISON_CLOUD)) + return false; + return true; + } + + void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); + if (removeMode != AURA_REMOVE_BY_ENEMY_SPELL && removeMode != AURA_REMOVE_BY_EXPIRE) + return; + + if (Unit* caster = GetCaster()) + { + caster->CastSpell(GetTarget(), SPELL_MUTATING_EXPLOSION, true); + GetTarget()->CastSpell(GetTarget(), SPELL_POISON_CLOUD, true, NULL, aurEff, GetCasterGUID()); + } + } - void Reset() OVERRIDE + void Register() OVERRIDE + { + AfterEffectRemove += AuraEffectRemoveFn(spell_grobbulus_mutating_injection_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE { - Cloud_Timer = 1000; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + return new spell_grobbulus_mutating_injection_AuraScript(); } +}; - void UpdateAI(uint32 diff) OVERRIDE +// 28158, 54362 - Poison (Grobbulus) +class spell_grobbulus_poison_cloud : public SpellScriptLoader +{ + public: + spell_grobbulus_poison_cloud() : SpellScriptLoader("spell_grobbulus_poison_cloud") { } + + class spell_grobbulus_poison_cloud_AuraScript : public AuraScript { - if (Cloud_Timer <= diff) + PrepareAuraScript(spell_grobbulus_poison_cloud_AuraScript); + + bool Validate(SpellInfo const* spellInfo) OVERRIDE { - DoCast(me, SPELL_POISON_CLOUD_ADD); - Cloud_Timer = 10000; - } else Cloud_Timer -= diff; - } - }; + if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* aurEff) + { + PreventDefaultAction(); + uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + int32 mod = int32(((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 10000 * 2 / 3); + GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_RADIUS_MOD, mod, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff); + } + + void Register() OVERRIDE + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_grobbulus_poison_cloud_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_grobbulus_poison_cloud_AuraScript(); + } }; void AddSC_boss_grobbulus() { new boss_grobbulus(); new npc_grobbulus_poison_cloud(); + new spell_grobbulus_mutating_injection(); + new spell_grobbulus_poison_cloud(); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index 41d1f53b52d..2091b82e20c 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -374,11 +374,11 @@ public: void FindGameObjects() { - PortalsGUID[0] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL01) : 0; - PortalsGUID[1] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL02) : 0; - PortalsGUID[2] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL03) : 0; - PortalsGUID[3] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL04) : 0; - KTTriggerGUID = instance ? instance->GetData64(DATA_KELTHUZAD_TRIGGER) : 0; + PortalsGUID[0] = instance->GetData64(DATA_KELTHUZAD_PORTAL01); + PortalsGUID[1] = instance->GetData64(DATA_KELTHUZAD_PORTAL02); + PortalsGUID[2] = instance->GetData64(DATA_KELTHUZAD_PORTAL03); + PortalsGUID[3] = instance->GetData64(DATA_KELTHUZAD_PORTAL04); + KTTriggerGUID = instance->GetData64(DATA_KELTHUZAD_TRIGGER); } void UpdateAI(uint32 diff) OVERRIDE @@ -757,8 +757,7 @@ class npc_kelthuzad_abomination : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (_instance) - _instance->SetData(DATA_ABOMINATION_KILLED, _instance->GetData(DATA_ABOMINATION_KILLED) + 1); + _instance->SetData(DATA_ABOMINATION_KILLED, _instance->GetData(DATA_ABOMINATION_KILLED) + 1); } private: diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 4e386afae17..7ae9ce3faa6 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -450,7 +450,7 @@ public: { case ACTION_LAND_ENCOUNTER_START: events.CancelEventGroup(1); - if (Creature* alexstraszaBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) + if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) { Position pos; pos.m_positionZ = alexstraszaBunny->GetPositionZ(); @@ -713,7 +713,8 @@ public: { _firstCyclicMovementStarted = true; me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFacingToObject(me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))); + if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) + me->SetFacingToObject(alexstraszaBunny); events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, 1*IN_MILLISECONDS, 0, PHASE_TWO); } _flyingOutOfPlatform = false; @@ -722,7 +723,8 @@ public: break; case POINT_PHASE_ONE_TO_TWO_TRANSITION: me->SetDisableGravity(true); - me->SetFacingToObject(me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))); + if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) + me->SetFacingToObject(alexstraszaBunny); SendLightOverride(LIGHT_ARCANE_RUNES, 5*IN_MILLISECONDS); events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 18*IN_MILLISECONDS, 0, PHASE_TWO); break; @@ -780,7 +782,7 @@ public: me->CastCustomSpell(SPELL_RANDOM_PORTAL, SPELLVALUE_MAX_TARGETS, 1); break; case EVENT_LAND_START_ENCOUNTER: - if (GameObject* iris = me->GetMap()->GetGameObject(instance->GetData64(DATA_FOCUSING_IRIS_GUID))) + if (GameObject* iris = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FOCUSING_IRIS_GUID))) { me->SetFacingToObject(iris); iris->Delete(); // this is not the best way. @@ -837,7 +839,7 @@ public: case EVENT_FLY_OUT_OF_PLATFORM: if (!_performingDestroyPlatform) { - if (Creature* alexstraszaBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) + if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID))) { Position randomPosOnRadius; // Hardcodded retail value, reason is Z getters can fail... (TO DO: Change to getter when height calculation works on 100%!) @@ -908,7 +910,7 @@ public: if (!_flyingOutOfPlatform) { DoCast(me, SPELL_SUMMON_ARCANE_BOMB, true); - if (Creature* lastArcaneOverloadBunny = me->GetMap()->GetCreature(_arcaneOverloadGUID)) + if (Creature* lastArcaneOverloadBunny = ObjectAccessor::GetCreature(*me, _arcaneOverloadGUID)) DoCast(lastArcaneOverloadBunny, SPELL_ARCANE_BOMB_TRIGGER, true); } events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, urand(15, 16)*IN_MILLISECONDS, 2, PHASE_TWO); @@ -993,7 +995,7 @@ public: { _JustDied(); Talk(SAY_DEATH); - if (Creature* alexstraszaGiftBoxBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_GIFT_BOX_BUNNY_GUID))) + if (Creature* alexstraszaGiftBoxBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GIFT_BOX_BUNNY_GUID))) { if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_10, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(), @@ -1087,7 +1089,7 @@ public: { if (spell->Id == SPELL_PORTAL_OPENED) { - if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) { if (malygos->AI()->GetData(DATA_PHASE) == PHASE_ONE) DoCast(me, SPELL_SUMMON_POWER_PARK, true); @@ -1101,15 +1103,12 @@ public: if (!me->HasAura(SPELL_PORTAL_VISUAL_CLOSED) && !me->HasAura(SPELL_PORTAL_OPENED)) DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true); - if (_instance) + if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) { - if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE && me->HasAura(SPELL_PORTAL_OPENED)) { - if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE && me->HasAura(SPELL_PORTAL_OPENED)) - { - me->RemoveAura(SPELL_PORTAL_OPENED); - DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true); - } + me->RemoveAura(SPELL_PORTAL_OPENED); + DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true); } } } @@ -1143,9 +1142,8 @@ public: { me->GetMotionMaster()->MoveIdle(); - if (_instance) - if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) - me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f); + if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) + me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f); } void UpdateAI(uint32 /*diff*/) OVERRIDE @@ -1153,7 +1151,7 @@ public: if (!_instance) return; - if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) { if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE || _instance->GetBossState(DATA_MALYGOS_EVENT) == FAIL) { @@ -1432,7 +1430,7 @@ class npc_nexus_lord : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS) + 1); } @@ -1499,7 +1497,7 @@ class npc_scion_of_eternity : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS) + 1); } @@ -1542,7 +1540,7 @@ public: void DoAction(int32 /*action*/) OVERRIDE { - if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS))) + if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS))) { if (malygos->AI()->GetData(DATA_PHASE) == PHASE_TWO) me->DespawnOrUnsummon(6*IN_MILLISECONDS); @@ -2047,7 +2045,7 @@ class spell_scion_of_eternity_arcane_barrage : public SpellScriptLoader Creature* caster = GetCaster()->ToCreature(); InstanceScript* instance = caster->GetInstanceScript(); - Creature* malygos = caster->GetMap()->GetCreature(instance->GetData64(DATA_MALYGOS)); + Creature* malygos = ObjectAccessor::GetCreature(*caster, instance->GetData64(DATA_MALYGOS)); // If max possible targets are more than 1 then Scions wouldn't select previosly selected target, // in longer terms this means if spell picks target X then 2nd cast of this spell will pick smth else @@ -2232,6 +2230,7 @@ class spell_alexstrasza_bunny_destroy_platform_event : public SpellScriptLoader } }; +// 56070 - Summon Red Dragon Buddy class spell_wyrmrest_skytalon_summon_red_dragon_buddy : public SpellScriptLoader { public: @@ -2246,19 +2245,16 @@ class spell_wyrmrest_skytalon_summon_red_dragon_buddy : public SpellScriptLoader return GetCaster()->GetTypeId() == TYPEID_PLAYER; } - void ChangeSummonPos(SpellEffIndex /*effIndex*/) + void SetDest(SpellDestination& dest) { // Adjust effect summon position to lower Z - WorldLocation summonPos = *GetExplTargetDest(); - Position offset = { 0.0f, 0.0f, -80.0f, 0.0f }; - summonPos.RelocateOffset(offset); - SetExplTargetDest(summonPos); - GetHitDest()->RelocateOffset(offset); + Position const offset = { 0.0f, 0.0f, -80.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectHit += SpellEffectFn(spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS); } }; diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp index 2f6a328b728..9943ad7e1b1 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp @@ -213,7 +213,7 @@ public: { InstanceScript* instance = go->GetInstanceScript(); - Creature* pKeristrasza = Unit::GetCreature(*go, instance ? instance->GetData64(DATA_KERISTRASZA) : 0); + Creature* pKeristrasza = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_KERISTRASZA)); if (pKeristrasza && pKeristrasza->IsAlive()) { // maybe these are hacks :( diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp index aa6bb11447b..93e52c4da73 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp @@ -195,8 +195,8 @@ public: struct npc_crystal_spike_triggerAI : public ScriptedAI { - npc_crystal_spike_triggerAI(Creature* creature) : ScriptedAI(creature) - { + npc_crystal_spike_triggerAI(Creature* creature) : ScriptedAI(creature) + { _count = 0; _despawntimer = 0; } diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp index 40e526219fa..506e16741fb 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp @@ -375,27 +375,16 @@ class spell_oculus_call_ruby_emerald_amber_drake : public SpellScriptLoader { PrepareSpellScript(spell_oculus_call_ruby_emerald_amber_drake_SpellScript); - void ChangeSummonPos(SpellEffIndex /*effIndex*/) + void SetDest(SpellDestination& dest) { // Adjust effect summon position - WorldLocation summonPos = *GetExplTargetDest(); - Position offset = { 0.0f, 0.0f, 12.0f, 0.0f }; - summonPos.RelocateOffset(offset); - SetExplTargetDest(summonPos); - GetHitDest()->RelocateOffset(offset); - } - - void ModDestHeight(SpellEffIndex /*effIndex*/) - { - // Used to cast visual effect at proper position - Position offset = { 0.0f, 0.0f, 12.0f, 0.0f }; - const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset); + Position const offset = { 0.0f, 0.0f, 12.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectHit += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); - OnEffectLaunch += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_FRONT); } }; diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp index c666a36741b..1788ecacd35 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp @@ -168,7 +168,7 @@ public: for (std::list<uint64>::const_iterator itr = lSparkList.begin(); itr != lSparkList.end(); ++itr) { - if (Creature* pSpark = Unit::GetCreature(*me, *itr)) + if (Creature* pSpark = ObjectAccessor::GetCreature(*me, *itr)) { if (pSpark->IsAlive()) { @@ -297,11 +297,6 @@ class npc_spark_of_ionar : public CreatureScript public: npc_spark_of_ionar() : CreatureScript("npc_spark_of_ionar") { } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return GetInstanceAI<npc_spark_of_ionarAI>(creature); - } - struct npc_spark_of_ionarAI : public ScriptedAI { npc_spark_of_ionarAI(Creature* creature) : ScriptedAI(creature) @@ -336,7 +331,7 @@ public: void UpdateAI(uint32 uiDiff) OVERRIDE { // Despawn if the encounter is not running - if (instance && instance->GetBossState(DATA_IONAR) != IN_PROGRESS) + if (instance->GetBossState(DATA_IONAR) != IN_PROGRESS) { me->DespawnOrUnsummon(); return; @@ -345,13 +340,13 @@ public: // Prevent them to follow players through the whole instance if (uiCheckTimer <= uiDiff) { - Creature* pIonar = instance->instance->GetCreature(instance->GetData64(DATA_IONAR)); - if (pIonar && pIonar->IsAlive()) + Creature* ionar = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_IONAR)); + if (ionar && ionar->IsAlive()) { - if (me->GetDistance(pIonar) > DATA_MAX_SPARK_DISTANCE) + if (me->GetDistance(ionar) > DATA_MAX_SPARK_DISTANCE) { Position pos; - pIonar->GetPosition(&pos); + ionar->GetPosition(&pos); me->SetSpeed(MOVE_RUN, 2.0f); me->GetMotionMaster()->Clear(); @@ -369,6 +364,10 @@ public: } }; + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetInstanceAI<npc_spark_of_ionarAI>(creature); + } }; void AddSC_boss_ionar() diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp index 08d12d715f9..927f4490770 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_maiden_of_grief.cpp @@ -15,146 +15,130 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* Script Data Start -SDName: Boss maiden_of_grief -SDAuthor: LordVanMartin -SD%Complete: -SDComment: -SDCategory: -Script Data End */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "halls_of_stone.h" +enum Yells +{ + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_DEATH = 2, + SAY_STUN = 3 +}; + enum Spells { - SPELL_PARTING_SORROW = 59723, - SPELL_STORM_OF_GRIEF_N = 50752, - SPELL_STORM_OF_GRIEF_H = 59772, - SPELL_SHOCK_OF_SORROW_N = 50760, - SPELL_SHOCK_OF_SORROW_H = 59726, - SPELL_PILLAR_OF_WOE_N = 50761, - SPELL_PILLAR_OF_WOE_H = 59727 + SPELL_PARTING_SORROW = 59723, + SPELL_STORM_OF_GRIEF = 50752, + SPELL_SHOCK_OF_SORROW = 50760, + SPELL_PILLAR_OF_WOE = 50761 }; -enum Yells +enum Events { - SAY_AGGRO = 0, - SAY_SLAY = 1, - SAY_DEATH = 2, - SAY_STUN = 3 + EVENT_PARTING_SORROW = 1, + EVENT_STORM_OF_GRIEF, + EVENT_SHOCK_OF_SORROW, + EVENT_PILLAR_OF_WOE }; enum Achievements { - ACHIEV_GOOD_GRIEF_START_EVENT = 20383, + ACHIEV_GOOD_GRIEF_START_EVENT = 20383, }; class boss_maiden_of_grief : public CreatureScript { -public: - boss_maiden_of_grief() : CreatureScript("boss_maiden_of_grief") { } + public: + boss_maiden_of_grief() : CreatureScript("boss_maiden_of_grief") { } - struct boss_maiden_of_griefAI : public ScriptedAI - { - boss_maiden_of_griefAI(Creature* creature) : ScriptedAI(creature) + struct boss_maiden_of_griefAI : public BossAI { - instance = me->GetInstanceScript(); - } - - InstanceScript* instance; + boss_maiden_of_griefAI(Creature* creature) : BossAI(creature, DATA_MAIDEN_OF_GRIEF) { } - uint32 PartingSorrowTimer; - uint32 StormOfGriefTimer; - uint32 ShockOfSorrowTimer; - uint32 PillarOfWoeTimer; - - void Reset() OVERRIDE - { - PartingSorrowTimer = urand(25000, 30000); - StormOfGriefTimer = 10000; - ShockOfSorrowTimer = 20000+rand()%5000; - PillarOfWoeTimer = urand(5000, 15000); - - instance->SetBossState(DATA_MAIDEN_OF_GRIEF, NOT_STARTED); - instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_GOOD_GRIEF_START_EVENT); - } - - void EnterCombat(Unit* /*who*/) OVERRIDE - { - Talk(SAY_AGGRO); + void Reset() OVERRIDE + { + _Reset(); - instance->SetBossState(DATA_MAIDEN_OF_GRIEF, IN_PROGRESS); - instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_GOOD_GRIEF_START_EVENT); - } + if (IsHeroic()) + events.ScheduleEvent(EVENT_PARTING_SORROW, urand(25000, 30000)); + events.ScheduleEvent(EVENT_STORM_OF_GRIEF, 10000); + events.ScheduleEvent(EVENT_SHOCK_OF_SORROW, urand(20000, 25000)); + events.ScheduleEvent(EVENT_PILLAR_OF_WOE, urand(5000, 15000)); - void UpdateAI(uint32 diff) OVERRIDE - { - //Return since we have no target - if (!UpdateVictim()) - return; + instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_GOOD_GRIEF_START_EVENT); + } - if (IsHeroic()) + void EnterCombat(Unit* /*who*/) OVERRIDE { - if (PartingSorrowTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_PARTING_SORROW); + _EnterCombat(); + Talk(SAY_AGGRO); - PartingSorrowTimer = urand(30000, 40000); - } else PartingSorrowTimer -= diff; + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_GOOD_GRIEF_START_EVENT); } - if (StormOfGriefTimer <= diff) + void KilledUnit(Unit* who) OVERRIDE { - DoCastVictim(SPELL_STORM_OF_GRIEF_N, true); - StormOfGriefTimer = urand(15000, 20000); - } else StormOfGriefTimer -= diff; + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - if (ShockOfSorrowTimer <= diff) + void JustDied(Unit* /*killer*/) OVERRIDE { - DoResetThreat(); - Talk(SAY_STUN); - DoCast(me, SPELL_SHOCK_OF_SORROW_N); - ShockOfSorrowTimer = urand(20000, 30000); - } else ShockOfSorrowTimer -= diff; + _JustDied(); + Talk(SAY_DEATH); + } - if (PillarOfWoeTimer <= diff) + void UpdateAI(uint32 diff) OVERRIDE { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); + if (!UpdateVictim()) + return; - if (target) - DoCast(target, SPELL_PILLAR_OF_WOE_N); - else - DoCastVictim(SPELL_PILLAR_OF_WOE_N); + events.Update(diff); - PillarOfWoeTimer = urand(5000, 25000); - } else PillarOfWoeTimer -= diff; - - DoMeleeAttackIfReady(); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); - - instance->SetBossState(DATA_MAIDEN_OF_GRIEF, DONE); - } + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_PARTING_SORROW: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_PARTING_SORROW); + events.ScheduleEvent(EVENT_PARTING_SORROW, urand(30000, 40000)); + break; + case EVENT_STORM_OF_GRIEF: + DoCastVictim(SPELL_STORM_OF_GRIEF, true); + events.ScheduleEvent(EVENT_STORM_OF_GRIEF, urand(15000, 20000)); + break; + case EVENT_SHOCK_OF_SORROW: + DoResetThreat(); + Talk(SAY_STUN); + DoCastAOE(SPELL_SHOCK_OF_SORROW); + events.ScheduleEvent(EVENT_SHOCK_OF_SORROW, urand(20000, 30000)); + break; + case EVENT_PILLAR_OF_WOE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + DoCast(target, SPELL_PILLAR_OF_WOE); + else + DoCastVictim(SPELL_PILLAR_OF_WOE); + events.ScheduleEvent(EVENT_PILLAR_OF_WOE, urand(5000, 25000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; - void KilledUnit(Unit* victim) OVERRIDE + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; - - Talk(SAY_SLAY); + return GetHallsOfStoneAI<boss_maiden_of_griefAI>(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return GetHallsOfStoneAI<boss_maiden_of_griefAI>(creature); - } }; void AddSC_boss_maiden_of_grief() diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index a8f933431c3..9599700eccb 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -1253,6 +1253,7 @@ class spell_algalon_remove_phase : public SpellScriptLoader } }; +// 62295 - Cosmic Smash class spell_algalon_cosmic_smash : public SpellScriptLoader { public: @@ -1262,16 +1263,15 @@ class spell_algalon_cosmic_smash : public SpellScriptLoader { PrepareSpellScript(spell_algalon_cosmic_smash_SpellScript); - void ModDestHeight(SpellEffIndex /*effIndex*/) + void ModDestHeight(SpellDestination& dest) { - Position offset = {0.0f, 0.0f, 65.0f, 0.0f}; - const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset); - GetHitDest()->RelocateOffset(offset); + Position const offset = { 0.0f, 0.0f, 65.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectLaunch += SpellEffectFn(spell_algalon_cosmic_smash_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_algalon_cosmic_smash_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_SUMMON); } }; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 779adf67211..dff001fee05 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -1192,7 +1192,7 @@ class npc_lorekeeper : public CreatureScript bool OnGossipHello(Player* player, Creature* creature) OVERRIDE { InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetData(BOSS_LEVIATHAN) !=DONE && player) + if (instance->GetData(BOSS_LEVIATHAN) != DONE && player) { player->PrepareGossipMenu(creature); @@ -1245,7 +1245,7 @@ public: //bool OnGossipHello(Player* player, Creature* creature) OVERRIDE //{ // InstanceScript* instance = creature->GetInstanceScript(); - // if (instance && instance->GetData(BOSS_LEVIATHAN) !=DONE) + // if (instance->GetData(BOSS_LEVIATHAN) !=DONE) // { // player->PrepareGossipMenu(creature); // diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index 480c04c3254..169a7085672 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -227,7 +227,7 @@ class npc_flash_freeze : public CreatureScript // Prevents to have Ice Block on other place than target is me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation()); if (target->GetTypeId() == TYPEID_PLAYER) - if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0)) + if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR))) Hodir->AI()->DoAction(ACTION_CHEESE_THE_FREEZE); } } @@ -279,7 +279,7 @@ class npc_ice_block : public CreatureScript { Helper->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); - if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0)) + if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR))) { if (!Hodir->IsInCombat()) { @@ -658,7 +658,7 @@ class npc_hodir_priest : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0)) + if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR))) Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } @@ -720,7 +720,7 @@ class npc_hodir_shaman : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0)) + if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR))) Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } @@ -781,7 +781,7 @@ class npc_hodir_druid : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0)) + if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR))) Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } @@ -861,7 +861,7 @@ class npc_hodir_mage : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0)) + if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR))) Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index 862ee2c786b..fee7a3ac0b7 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -312,7 +312,7 @@ class go_razorscale_harpoon : public GameObjectScript bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE { InstanceScript* instance = go->GetInstanceScript(); - if (ObjectAccessor::GetCreature(*go, instance ? instance->GetData64(BOSS_RAZORSCALE) : 0)) + if (ObjectAccessor::GetCreature(*go, instance->GetData64(BOSS_RAZORSCALE))) go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); return false; } @@ -347,14 +347,14 @@ class boss_razorscale : public CreatureScript me->SetReactState(REACT_PASSIVE); PermaGround = false; HarpoonCounter = 0; - if (Creature* commander = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_EXPEDITION_COMMANDER) : 0)) + if (Creature* commander = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EXPEDITION_COMMANDER))) commander->AI()->DoAction(ACTION_COMMANDER_RESET); } void EnterCombat(Unit* /*who*/) OVERRIDE { _EnterCombat(); - if (Creature* controller = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_RAZORSCALE_CONTROL) : 0)) + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_RAZORSCALE_CONTROL))) controller->AI()->DoAction(ACTION_HARPOON_BUILD); me->SetSpeed(MOVE_FLIGHT, 3.0f, true); me->SetReactState(REACT_PASSIVE); @@ -369,7 +369,7 @@ class boss_razorscale : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { _JustDied(); - if (Creature* controller = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_RAZORSCALE_CONTROL) : 0)) + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_RAZORSCALE_CONTROL))) controller->AI()->Reset(); } @@ -445,7 +445,7 @@ class boss_razorscale : public CreatureScript me->SetCanFly(false); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); - if (Creature* commander = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_EXPEDITION_COMMANDER) : 0)) + if (Creature* commander = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EXPEDITION_COMMANDER))) commander->AI()->DoAction(ACTION_GROUND_PHASE); events.ScheduleEvent(EVENT_BREATH, 30000, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_BUFFET, 33000, 0, PHASE_GROUND); @@ -461,7 +461,7 @@ class boss_razorscale : public CreatureScript return; case EVENT_BUFFET: DoCastAOE(SPELL_WINGBUFFET); - if (Creature* controller = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_RAZORSCALE_CONTROL) : 0)) + if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_RAZORSCALE_CONTROL))) controller->CastSpell(controller, SPELL_FLAMED, true); events.CancelEvent(EVENT_BUFFET); return; @@ -689,7 +689,7 @@ class npc_expedition_commander : public CreatureScript Phase = 5; break; case 5: - if (Creature* Razorscale = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_RAZORSCALE) : 0)) + if (Creature* Razorscale = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_RAZORSCALE))) { Razorscale->AI()->DoAction(ACTION_EVENT_START); me->SetInCombatWith(Razorscale); @@ -720,7 +720,7 @@ class npc_expedition_commander : public CreatureScript bool OnGossipHello(Player* player, Creature* creature) OVERRIDE { InstanceScript* instance = creature->GetInstanceScript(); - if (instance && instance->GetBossState(BOSS_RAZORSCALE) == NOT_STARTED) + if (instance->GetBossState(BOSS_RAZORSCALE) == NOT_STARTED) { player->PrepareGossipMenu(creature); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp index c46158b0f7a..2a24b1145c0 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp @@ -258,7 +258,7 @@ class boss_svala : public CreatureScript case EVENT_INTRO_TRANSFORM_0: { if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID)) - arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false); + arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, true); Position pos; pos.Relocate(me); pos.m_positionZ += 8.0f; diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp index 4dd3aa9916b..7377029080f 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp @@ -195,7 +195,7 @@ class npc_tempest_minion : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* emalon = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EMALON) : 0)) + if (Creature* emalon = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EMALON))) { if (emalon->IsAlive()) { @@ -210,7 +210,7 @@ class npc_tempest_minion : public CreatureScript DoZoneInCombat(); events.ScheduleEvent(EVENT_SHOCK, 20000); - if (Creature* pEmalon = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EMALON) : 0)) + if (Creature* pEmalon = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EMALON))) { if (!pEmalon->GetVictim() && pEmalon->AI()) pEmalon->AI()->AttackStart(who); diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp index ccb1b5ed7d8..bd2128a1b4c 100644 --- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp +++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp @@ -241,7 +241,7 @@ class npc_frozen_orb_stalker : public CreatureScript npc_frozen_orb_stalkerAI(Creature* creature) : ScriptedAI(creature) { creature->SetVisible(false); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); creature->SetReactState(REACT_PASSIVE); instance = creature->GetInstanceScript(); @@ -256,7 +256,7 @@ class npc_frozen_orb_stalker : public CreatureScript return; spawned = true; - Unit* toravon = me->GetCreature(*me, instance ? instance->GetData64(DATA_TORAVON) : 0); + Unit* toravon = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TORAVON)); if (!toravon) return; diff --git a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp index ec20489bfc2..e53d046b396 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp @@ -90,7 +90,7 @@ public: void UpdateAI(uint32 diff) OVERRIDE { - if (instance && instance->GetData(DATA_REMOVE_NPC) == 1) + if (instance->GetData(DATA_REMOVE_NPC) == 1) { me->DespawnOrUnsummon(); instance->SetData(DATA_REMOVE_NPC, 0); diff --git a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp index 81edfd65d03..441603dcdc8 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp @@ -79,12 +79,12 @@ public: else if (instance->GetData(DATA_WAVE_COUNT) == 12) instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED); - if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0)) + if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1))) { if (!pGuard1->IsAlive()) pGuard1->Respawn(); } - if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0)) + if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2))) { if (!pGuard2->IsAlive()) pGuard2->Respawn(); @@ -103,15 +103,15 @@ public: who->SetInCombatWith(me); DoStartMovement(who); - if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0)) + if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1))) { - pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE); + pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); if (!pGuard1->GetVictim() && pGuard1->AI()) pGuard1->AI()->AttackStart(who); } - if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0)) + if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2))) { - pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE); + pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE); if (!pGuard2->GetVictim() && pGuard2->AI()) pGuard2->AI()->AttackStart(who); } @@ -148,9 +148,9 @@ public: //spam stormstrike in hc mode if spawns are dead if (IsHeroic()) { - if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0)) + if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1))) { - if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0)) + if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2))) { if (!pGuard1->IsAlive() && !pGuard2->IsAlive()) DoCastVictim(SPELL_STORMSTRIKE); @@ -168,12 +168,12 @@ public: { if (uint64 TargetGUID = GetChainHealTargetGUID()) { - if (Creature* target = Unit::GetCreature(*me, TargetGUID)) + if (Creature* target = ObjectAccessor::GetCreature(*me, TargetGUID)) DoCast(target, SPELL_CHAIN_HEAL); //If one of the adds is dead spawn heals faster - Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0); - Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0); + Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1)); + Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2)); uiChainHealTimer = ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000) + rand()%3000; } } else uiChainHealTimer -= diff; @@ -229,11 +229,11 @@ public: if (HealthBelowPct(85)) return me->GetGUID(); - Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0); + Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1)); if (pGuard1 && pGuard1->IsAlive() && !pGuard1->HealthAbovePct(75)) return pGuard1->GetGUID(); - Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0); + Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2)); if (pGuard2 && pGuard2->IsAlive() && !pGuard2->HealthAbovePct(75)) return pGuard2->GetGUID(); diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp index 79025bb5c0f..5f79e609e01 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp @@ -446,7 +446,7 @@ public: void Reset() OVERRIDE { - if (instance && !uiBoss) + if (!uiBoss) uiBoss = instance->GetData(DATA_WAVE_COUNT) == 6 ? instance->GetData(DATA_FIRST_BOSS) : instance->GetData(DATA_SECOND_BOSS); me->SetReactState(REACT_PASSIVE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE); @@ -486,7 +486,7 @@ public: void UpdateAI(uint32 diff) OVERRIDE { - if (instance && instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS) + if (instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS) me->CastStop(); npc_escortAI::UpdateAI(diff); @@ -723,7 +723,7 @@ struct violet_hold_trashAI : public npc_escortAI void UpdateAI(uint32) OVERRIDE { - if (instance && instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS) + if (instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS) me->CastStop(); if (!bHasGotMovingPoints) diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index cbad220aed6..f840c0562b3 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -428,8 +428,8 @@ public: struct npc_jennyAI : public ScriptedAI { - npc_jennyAI(Creature* creature) : ScriptedAI(creature) - { + npc_jennyAI(Creature* creature) : ScriptedAI(creature) + { setCrateNumber = false; } @@ -1359,10 +1359,7 @@ public: struct npc_counselor_talbotAI : public ScriptedAI { - npc_counselor_talbotAI(Creature* creature) : ScriptedAI(creature) - { - creature->RestoreFaction(); - } + npc_counselor_talbotAI(Creature* creature) : ScriptedAI(creature) { } uint64 leryssaGUID; uint64 arlosGUID; diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp index f91f5d8c007..7487c3c8828 100644 --- a/src/server/scripts/Northrend/zone_dragonblight.cpp +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -150,7 +150,10 @@ class npc_commander_eligor_dawnbringer : public CreatureScript struct npc_commander_eligor_dawnbringerAI : public ScriptedAI { - npc_commander_eligor_dawnbringerAI(Creature* creature) : ScriptedAI(creature) { } + npc_commander_eligor_dawnbringerAI(Creature* creature) : ScriptedAI(creature) + { + talkWing = 0; + } void Reset() OVERRIDE { @@ -649,7 +652,10 @@ class npc_torturer_lecraft : public CreatureScript struct npc_torturer_lecraftAI : public ScriptedAI { - npc_torturer_lecraftAI(Creature* creature) : ScriptedAI(creature) { } + npc_torturer_lecraftAI(Creature* creature) : ScriptedAI(creature) + { + _playerGUID = 0; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp index bacc6de57f0..112d42441b9 100644 --- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp +++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp @@ -20,8 +20,6 @@ #include "ScriptedCreature.h" #include "ScriptedEscortAI.h" #include "Player.h" -#include "Spell.h" -#include "SpellInfo.h" #include "SpellScript.h" #include "CreatureTextMgr.h" diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 69e4e65225a..70de4d4758d 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -451,7 +451,10 @@ public: struct npc_brann_bronzebeard_keystoneAI : public ScriptedAI { - npc_brann_bronzebeard_keystoneAI(Creature* creature) : ScriptedAI(creature) { } + npc_brann_bronzebeard_keystoneAI(Creature* creature) : ScriptedAI(creature) + { + objectCounter = 0; + } void Reset() OVERRIDE { @@ -634,7 +637,10 @@ public: struct npc_king_jokkum_vehicleAI : public VehicleAI { - npc_king_jokkum_vehicleAI(Creature* creature) : VehicleAI(creature) { } + npc_king_jokkum_vehicleAI(Creature* creature) : VehicleAI(creature) + { + pathEnd = false; + } void Reset() OVERRIDE { diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp index 311b18524b2..e218741649d 100644 --- a/src/server/scripts/Northrend/zone_wintergrasp.cpp +++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp @@ -249,7 +249,10 @@ class npc_wg_queue : public CreatureScript struct npc_wg_queueAI : public ScriptedAI { - npc_wg_queueAI(Creature* creature) : ScriptedAI(creature) { } + npc_wg_queueAI(Creature* creature) : ScriptedAI(creature) + { + FrostArmor_Timer = 0; + } uint32 FrostArmor_Timer; diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 3bbd41afc89..d74aecb9b25 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -1672,7 +1672,7 @@ public: { if (Check_Timer <= diff) { - if (instance && instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE) + if (instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE) me->SetVisible(true); Check_Timer = 5000; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp index 6d632c81bca..9055bb1862d 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp @@ -139,21 +139,20 @@ public: RAdvisors[0] = instance->GetData64(DATA_SHARKKIS); RAdvisors[1] = instance->GetData64(DATA_TIDALVESS); RAdvisors[2] = instance->GetData64(DATA_CARIBDIS); - //Respawn of the 3 Advisors - Creature* pAdvisor = NULL; - for (int i=0; i<MAX_ADVISORS; ++i) + // Respawn of the 3 Advisors + for (uint8 i = 0; i < MAX_ADVISORS; ++i) if (RAdvisors[i]) { - pAdvisor = (Unit::GetCreature((*me), RAdvisors[i])); - if (pAdvisor && !pAdvisor->IsAlive()) + Creature* advisor = ObjectAccessor::GetCreature(*me, RAdvisors[i]); + if (advisor && !advisor->IsAlive()) { - pAdvisor->Respawn(); - pAdvisor->AI()->EnterEvadeMode(); - pAdvisor->GetMotionMaster()->MoveTargetedHome(); + advisor->Respawn(); + advisor->AI()->EnterEvadeMode(); + advisor->GetMotionMaster()->MoveTargetedHome(); } } - instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED); + instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED); } void EventSharkkisDeath() @@ -215,7 +214,7 @@ public: void UpdateAI(uint32 diff) OVERRIDE { //Only if not incombat check if the event is started - if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) + if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT)) { if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) { @@ -229,7 +228,7 @@ public: return; //someone evaded! - if (instance && !instance->GetData(DATA_KARATHRESSEVENT)) + if (!instance->GetData(DATA_KARATHRESSEVENT)) { EnterEvadeMode(); return; @@ -269,12 +268,11 @@ public: { BlessingOfTides = true; bool continueTriggering = false; - Creature* Advisor; for (uint8 i = 0; i < MAX_ADVISORS; ++i) if (Advisors[i]) { - Advisor = (Unit::GetCreature(*me, Advisors[i])); - if (Advisor && Advisor->IsAlive()) + Creature* advisor = ObjectAccessor::GetCreature(*me, Advisors[i]); + if (advisor && advisor->IsAlive()) { continueTriggering = true; break; @@ -333,11 +331,9 @@ public: pet = false; - Creature* Pet = Unit::GetCreature(*me, SummonedPet); + Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet); if (Pet && Pet->IsAlive()) - { Pet->DealDamage(Pet, Pet->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } SummonedPet = 0; @@ -346,7 +342,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Karathress = (Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS)))) + if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS))) CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath(); } @@ -359,7 +355,7 @@ public: void UpdateAI(uint32 diff) OVERRIDE { //Only if not incombat check if the event is started - if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) + if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT)) { if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) AttackStart(target); @@ -370,7 +366,7 @@ public: return; //someone evaded! - if (instance && !instance->GetData(DATA_KARATHRESSEVENT)) + if (!instance->GetData(DATA_KARATHRESSEVENT)) { EnterEvadeMode(); return; @@ -394,11 +390,11 @@ public: if (TheBeastWithin_Timer <= diff) { DoCast(me, SPELL_THE_BEAST_WITHIN); - Creature* Pet = Unit::GetCreature(*me, SummonedPet); + + Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet); if (Pet && Pet->IsAlive()) - { Pet->CastSpell(Pet, SPELL_PET_ENRAGE, true); - } + TheBeastWithin_Timer = 30000; } else TheBeastWithin_Timer -= diff; @@ -472,7 +468,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))) + if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS))) CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath(); } @@ -486,7 +482,7 @@ public: void UpdateAI(uint32 diff) OVERRIDE { //Only if not incombat check if the event is started - if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) + if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT)) { if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) AttackStart(target); @@ -497,7 +493,7 @@ public: return; //someone evaded! - if (instance && !instance->GetData(DATA_KARATHRESSEVENT)) + if (!instance->GetData(DATA_KARATHRESSEVENT)) { EnterEvadeMode(); return; @@ -588,7 +584,7 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { - if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))) + if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS))) CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath(); } @@ -601,7 +597,7 @@ public: void UpdateAI(uint32 diff) OVERRIDE { //Only if not incombat check if the event is started - if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT)) + if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT)) { if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER))) AttackStart(target); @@ -612,7 +608,7 @@ public: return; //someone evaded! - if (instance && !instance->GetData(DATA_KARATHRESSEVENT)) + if (!instance->GetData(DATA_KARATHRESSEVENT)) { EnterEvadeMode(); return; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index b421d9c1153..8d6eb064194 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -519,7 +519,7 @@ public: if (CheckTimer <= diff) { // Start Phase 3 - if (instance && instance->GetData(DATA_CANSTARTPHASE3)) + if (instance->GetData(DATA_CANSTARTPHASE3)) { // set life 50% me->SetHealth(me->CountPctFromMaxHealth(50)); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index a45e4ddb0a9..f9370b44c20 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -317,10 +317,10 @@ public: // and reseting equipment me->LoadEquipment(); - if (instance && instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) + if (instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) { Unit* victim = NULL; - victim = Unit::GetUnit(*me, instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)); + victim = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)); if (victim) me->getThreatManager().addThreat(victim, 1); StartEvent(); @@ -750,7 +750,7 @@ public: return; } - if (instance && !instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) + if (!instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) { EnterEvadeMode(); return; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp index a6cd426f435..718c32cd8ae 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp @@ -112,10 +112,11 @@ public: bool CheckCanStart()//check if players fished { - if (instance && instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED) + if (instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED) return false; return true; } + void Reset() OVERRIDE { me->SetSwim(true); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp index 42833fead04..3661ebc8cc3 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp @@ -224,11 +224,11 @@ public: { if (Repair_Timer <= diff) { - if (instance && instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == IN_PROGRESS) + if (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == IN_PROGRESS) { - if (Unit* pMekgineer = Unit::GetUnit(*me, instance->GetData64(DATA_MEKGINEER_STEAMRIGGER))) + if (Creature* mekgineer = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MEKGINEER_STEAMRIGGER))) { - if (me->IsWithinDistInMap(pMekgineer, MAX_REPAIR_RANGE)) + if (me->IsWithinDistInMap(mekgineer, MAX_REPAIR_RANGE)) { //are we already channeling? Doesn't work very well, find better check? if (!me->GetUInt32Value(UNIT_CHANNEL_SPELL)) diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h index 193b0be51b0..b2097c34b33 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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 @@ -16,32 +15,59 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEF_BLOOD_FURNACE_H -#define DEF_BLOOD_FURNACE_H +#ifndef BLOOD_FURNACE_H_ +#define BLOOD_FURNACE_H_ + +#define BFScriptName "instance_blood_furnace" +uint32 const EncounterCount = 3; enum DataTypes { - DATA_THE_MAKER = 1, - DATA_BROGGOK = 2, - DATA_KELIDAN_THE_MAKER = 3, - TYPE_THE_MAKER_EVENT = 4, - TYPE_BROGGOK_EVENT = 5, - TYPE_KELIDAN_THE_BREAKER_EVENT = 6, - DATA_DOOR1 = 7, - DATA_DOOR2 = 8, - DATA_DOOR3 = 9, - DATA_DOOR4 = 10, - DATA_DOOR5 = 11, - DATA_DOOR6 = 12, - DATA_PRISON_CELL1 = 13, - DATA_PRISON_CELL2 = 14, - DATA_PRISON_CELL3 = 15, - DATA_PRISON_CELL4 = 16, - DATA_PRISON_CELL5 = 17, - DATA_PRISON_CELL6 = 18, - DATA_PRISON_CELL7 = 19, - DATA_PRISON_CELL8 = 20, - DATA_BROGGOK_LEVER = 21 + // Encounter States/Boss GUIDs + DATA_THE_MAKER = 0, + DATA_BROGGOK = 1, + DATA_KELIDAN_THE_BREAKER = 2, + + // Additional Data + DATA_DOOR_4 = 3, + DATA_PRISON_CELL1 = 4, + DATA_PRISON_CELL2 = 5, + DATA_PRISON_CELL3 = 6, + DATA_PRISON_CELL4 = 7, + DATA_PRISON_CELL5 = 8, + DATA_PRISON_CELL6 = 9, + DATA_PRISON_CELL7 = 10, + DATA_PRISON_CELL8 = 11, + DATA_BROGGOK_LEVER = 12 +}; + +enum CreatureIds +{ + NPC_THE_MAKER = 17381, + NPC_BROGGOK = 17380, + NPC_KELIDAN_THE_BREAKER = 17377, + NPC_PRISONER = 17398 +}; + +enum GameObjectIds +{ + GO_PRISON_DOOR_01 = 181766, // Final Exit Door + GO_PRISON_DOOR_02 = 181811, // The Maker Front Door + GO_PRISON_DOOR_03 = 181812, // The Maker Rear Door + GO_PRISON_DOOR_04 = 181819, // Broggok Rear Door + GO_PRISON_DOOR_05 = 181822, // Broggok Front Door + GO_SUMMON_DOOR = 181823, // Kelidan Exit Door + + GO_PRISON_CELL_DOOR_1 = 181813, // The Maker Prison Cell front right + GO_PRISON_CELL_DOOR_2 = 181814, // The Maker Prison Cell back right + GO_PRISON_CELL_DOOR_3 = 181816, // The Maker Prison Cell front left + GO_PRISON_CELL_DOOR_4 = 181815, // The Maker Prison Cell back left + GO_PRISON_CELL_DOOR_5 = 181821, // Broggok Prison Cell front right + GO_PRISON_CELL_DOOR_6 = 181818, // Broggok Prison Cell back right + GO_PRISON_CELL_DOOR_7 = 181820, // Broggok Prison Cell front left + GO_PRISON_CELL_DOOR_8 = 181817, // Broggok Prison Cell back left + + GO_BROGGOK_LEVER = 181982 }; enum ActionIds @@ -51,5 +77,11 @@ enum ActionIds ACTION_PREPARE_BROGGOK = 3 }; -#endif +template<class AI> +AI* GetBloodFurnaceAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, BFScriptName); +} + +#endif // BLOOD_FURNACE_H_ diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp index 1dda4161b8c..f610d6dd7e0 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp @@ -25,39 +25,32 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" #include "blood_furnace.h" enum Yells { - SAY_AGGRO = 0 + SAY_AGGRO = 0 }; enum Spells { - SPELL_SLIME_SPRAY = 30913, - SPELL_POISON_CLOUD = 30916, - SPELL_POISON_BOLT = 30917, + SPELL_SLIME_SPRAY = 30913, + SPELL_POISON_CLOUD = 30916, + SPELL_POISON_BOLT = 30917, - SPELL_POISON = 30914 + SPELL_POISON_CLOUD_PASSIVE = 30914 }; class boss_broggok : public CreatureScript { public: - - boss_broggok() - : CreatureScript("boss_broggok") - { - } + boss_broggok() : CreatureScript("boss_broggok") { } struct boss_broggokAI : public BossAI { - boss_broggokAI(Creature* creature) : BossAI(creature, DATA_BROGGOK) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; + boss_broggokAI(Creature* creature) : BossAI(creature, DATA_BROGGOK) { } uint32 AcidSpray_Timer; uint32 PoisonSpawn_Timer; @@ -71,28 +64,22 @@ class boss_broggok : public CreatureScript PoisonSpawn_Timer = 5000; PoisonBolt_Timer = 7000; DoAction(ACTION_RESET_BROGGOK); - instance->SetData(TYPE_BROGGOK_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); Talk(SAY_AGGRO); } - void JustSummoned(Creature* summoned) OVERRIDE - { - summoned->setFaction(16); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - summoned->CastSpell(summoned, SPELL_POISON, false, 0, 0, me->GetGUID()); - } - void UpdateAI(uint32 diff) OVERRIDE { if (!UpdateVictim()) return; + if (!canAttack) return; + if (AcidSpray_Timer <= diff) { DoCastVictim(SPELL_SLIME_SPRAY); @@ -122,9 +109,7 @@ class boss_broggok : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - instance->HandleGameObject(instance->GetData64(DATA_DOOR4), true); - instance->HandleGameObject(instance->GetData64(DATA_DOOR5), true); - instance->SetData(TYPE_BROGGOK_EVENT, DONE); + _JustDied(); } void DoAction(int32 action) OVERRIDE @@ -151,7 +136,34 @@ class boss_broggok : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return GetInstanceAI<boss_broggokAI>(creature); + return GetBloodFurnaceAI<boss_broggokAI>(creature); + } +}; + +class npc_broggok_poison_cloud : public CreatureScript +{ + public: + npc_broggok_poison_cloud() : CreatureScript("npc_broggok_poison_cloud") { } + + struct npc_broggok_poison_cloudAI : public ScriptedAI + { + npc_broggok_poison_cloudAI(Creature* creature) : ScriptedAI(creature) + { + SetCombatMovement(false); + creature->SetReactState(REACT_PASSIVE); + } + + void IsSummonedBy(Unit* /*summoner*/) OVERRIDE + { + DoCast(me, SPELL_POISON_CLOUD_PASSIVE, true); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE { } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_broggok_poison_cloudAI(creature); } }; @@ -163,19 +175,60 @@ class go_broggok_lever : public GameObjectScript bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE { if (InstanceScript* instance = go->GetInstanceScript()) - if (instance->GetData(TYPE_BROGGOK_EVENT) != DONE && instance->GetData(TYPE_BROGGOK_EVENT) != IN_PROGRESS) + if (instance->GetBossState(DATA_BROGGOK) != DONE && instance->GetBossState(DATA_BROGGOK) != IN_PROGRESS) { - instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS); - if (Creature* broggok = Creature::GetCreature(*go, instance->GetData64(DATA_BROGGOK))) + instance->SetBossState(DATA_BROGGOK, IN_PROGRESS); + if (Creature* broggok = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_BROGGOK))) broggok->AI()->DoAction(ACTION_PREPARE_BROGGOK); } + go->UseDoorOrButton(); return false; } }; +// 30914, 38462 - Poison (Broggok) +class spell_broggok_poison_cloud : public SpellScriptLoader +{ + public: + spell_broggok_poison_cloud() : SpellScriptLoader("spell_broggok_poison_cloud") { } + + class spell_broggok_poison_cloud_AuraScript : public AuraScript + { + PrepareAuraScript(spell_broggok_poison_cloud_AuraScript); + + bool Validate(SpellInfo const* spellInfo) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* aurEff) + { + PreventDefaultAction(); + + uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + int32 mod = int32(((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 10000 * 2 / 3); + GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_RADIUS_MOD, mod, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff); + } + + void Register() OVERRIDE + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_broggok_poison_cloud_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_broggok_poison_cloud_AuraScript(); + } +}; + void AddSC_boss_broggok() { new boss_broggok(); + new npc_broggok_poison_cloud(); new go_broggok_lever(); + new spell_broggok_poison_cloud(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp index 78be2347656..4c04c06b091 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp @@ -16,18 +16,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Kelidan_The_Breaker -SD%Complete: 100 -SDComment: -SDCategory: Hellfire Citadel, Blood Furnace -EndScriptData */ - -/* ContentData -boss_kelidan_the_breaker -npc_shadowmoon_channeler -EndContentData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellAuras.h" @@ -71,23 +59,16 @@ const float ShadowmoonChannelers[5][4]= class boss_kelidan_the_breaker : public CreatureScript { public: + boss_kelidan_the_breaker() : CreatureScript("boss_kelidan_the_breaker") { } - boss_kelidan_the_breaker() - : CreatureScript("boss_kelidan_the_breaker") - { - } - - struct boss_kelidan_the_breakerAI : public ScriptedAI + struct boss_kelidan_the_breakerAI : public BossAI { - boss_kelidan_the_breakerAI(Creature* creature) : ScriptedAI(creature) + boss_kelidan_the_breakerAI(Creature* creature) : BossAI(creature, DATA_KELIDAN_THE_BREAKER) { - instance = creature->GetInstanceScript(); - for (uint8 i=0; i<5; ++i) + for (uint8 i = 0; i < 5; ++i) Channelers[i] = 0; } - InstanceScript* instance; - uint32 ShadowVolley_Timer; uint32 BurningNova_Timer; uint32 Firenova_Timer; @@ -99,6 +80,7 @@ class boss_kelidan_the_breaker : public CreatureScript void Reset() OVERRIDE { + _Reset(); ShadowVolley_Timer = 1000; BurningNova_Timer = 15000; Corruption_Timer = 5000; @@ -108,16 +90,15 @@ class boss_kelidan_the_breaker : public CreatureScript SummonChannelers(); me->SetReactState(REACT_PASSIVE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); - instance->SetData(TYPE_KELIDAN_THE_BREAKER_EVENT, NOT_STARTED); } void EnterCombat(Unit* who) OVERRIDE { + _EnterCombat(); Talk(SAY_WAKE); if (me->IsNonMeleeSpellCast(false)) me->InterruptNonMeleeSpells(true); DoStartMovement(who); - instance->SetData(TYPE_KELIDAN_THE_BREAKER_EVENT, IN_PROGRESS); } void KilledUnit(Unit* /*victim*/) OVERRIDE @@ -189,11 +170,8 @@ class boss_kelidan_the_breaker : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { + _JustDied(); Talk(SAY_DIE); - - instance->SetData(TYPE_KELIDAN_THE_BREAKER_EVENT, DONE); - instance->HandleGameObject(instance->GetData64(DATA_DOOR1), true); - instance->HandleGameObject(instance->GetData64(DATA_DOOR6), true); } void UpdateAI(uint32 diff) OVERRIDE @@ -270,7 +248,7 @@ class boss_kelidan_the_breaker : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return GetInstanceAI<boss_kelidan_the_breakerAI>(creature); + return GetBloodFurnaceAI<boss_kelidan_the_breakerAI>(creature); } }; @@ -368,7 +346,7 @@ class npc_shadowmoon_channeler : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return GetInstanceAI<npc_shadowmoon_channelerAI>(creature); + return GetBloodFurnaceAI<npc_shadowmoon_channelerAI>(creature); } }; diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp index 214edf4f5c2..6ab356bfa4a 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_the_maker.cpp @@ -45,20 +45,11 @@ enum Spells class boss_the_maker : public CreatureScript { public: + boss_the_maker() : CreatureScript("boss_the_maker") { } - boss_the_maker() - : CreatureScript("boss_the_maker") + struct boss_the_makerAI : public BossAI { - } - - struct boss_the_makerAI : public ScriptedAI - { - boss_the_makerAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; + boss_the_makerAI(Creature* creature) : BossAI(creature, DATA_THE_MAKER) { } uint32 AcidSpray_Timer; uint32 ExplodingBreaker_Timer; @@ -67,37 +58,30 @@ class boss_the_maker : public CreatureScript void Reset() OVERRIDE { + _Reset(); AcidSpray_Timer = 15000; ExplodingBreaker_Timer = 6000; Domination_Timer = 120000; Knockdown_Timer = 10000; - - instance->SetData(TYPE_THE_MAKER_EVENT, NOT_STARTED); - instance->HandleGameObject(instance->GetData64(DATA_DOOR2), true); } void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); Talk(SAY_AGGRO); - - instance->SetData(TYPE_THE_MAKER_EVENT, IN_PROGRESS); - instance->HandleGameObject(instance->GetData64(DATA_DOOR2), false); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* who) OVERRIDE { - Talk(SAY_KILL); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_KILL); } void JustDied(Unit* /*killer*/) OVERRIDE { + _JustDied(); Talk(SAY_DIE); - - instance->SetData(TYPE_THE_MAKER_EVENT, DONE); - instance->HandleGameObject(instance->GetData64(DATA_DOOR2), true); - instance->HandleGameObject(instance->GetData64(DATA_DOOR3), true); - - } + } void UpdateAI(uint32 diff) OVERRIDE { @@ -147,7 +131,7 @@ class boss_the_maker : public CreatureScript CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return GetInstanceAI<boss_the_makerAI>(creature); + return GetBloodFurnaceAI<boss_the_makerAI>(creature); } }; diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp index 7a9db8f4a63..bc399e4b43f 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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 @@ -16,292 +15,207 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance_Blood_Furnace -SD%Complete: 85 -SDComment: -SDCategory: Hellfire Citadel, Blood Furnace -EndScriptData */ - #include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "InstanceScript.h" #include "blood_furnace.h" -#include "CreatureAI.h" -#define ENTRY_SEWER1 181823 -#define ENTRY_SEWER2 181766 -#define MAX_ENCOUNTER 3 +DoorData const doorData[] = +{ + { GO_PRISON_DOOR_01, DATA_KELIDAN_THE_BREAKER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_PRISON_DOOR_02, DATA_THE_MAKER, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_PRISON_DOOR_03, DATA_THE_MAKER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_PRISON_DOOR_04, DATA_BROGGOK, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_PRISON_DOOR_05, DATA_BROGGOK, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_SUMMON_DOOR, DATA_KELIDAN_THE_BREAKER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; class instance_blood_furnace : public InstanceMapScript { public: - instance_blood_furnace() - : InstanceMapScript("instance_blood_furnace", 542) { } + instance_blood_furnace() : InstanceMapScript(BFScriptName, 542) { } struct instance_blood_furnace_InstanceMapScript : public InstanceScript { - instance_blood_furnace_InstanceMapScript(Map* map) : InstanceScript(map) { } - - uint64 The_MakerGUID; - uint64 BroggokGUID; - uint64 Kelidan_The_BreakerGUID; - - uint64 Door1GUID; - uint64 Door2GUID; - uint64 Door3GUID; - uint64 Door4GUID; - uint64 Door5GUID; - uint64 Door6GUID; - - uint64 PrisonCell1GUID; - uint64 PrisonCell2GUID; - uint64 PrisonCell3GUID; - uint64 PrisonCell4GUID; - uint64 PrisonCell5GUID; - uint64 PrisonCell6GUID; - uint64 PrisonCell7GUID; - uint64 PrisonCell8GUID; - - std::set<uint64> PrisonersCell5; - std::set<uint64> PrisonersCell6; - std::set<uint64> PrisonersCell7; - std::set<uint64> PrisonersCell8; - - uint8 PrisonerCounter5; - uint8 PrisonerCounter6; - uint8 PrisonerCounter7; - uint8 PrisonerCounter8; + instance_blood_furnace_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + LoadDoorData(doorData); - uint64 BroggokLeverGUID; + TheMakerGUID = 0; + BroggokGUID = 0; + KelidanTheBreakerGUID = 0; - uint32 m_auiEncounter[MAX_ENCOUNTER]; - std::string str_data; + BroggokLeverGUID = 0; + PrisonDoor4GUID = 0; - void Initialize() OVERRIDE - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - The_MakerGUID = 0; - BroggokGUID = 0; - Kelidan_The_BreakerGUID = 0; - - Door1GUID = 0; - Door2GUID = 0; - Door3GUID = 0; - Door4GUID = 0; - Door5GUID = 0; - Door6GUID = 0; - - PrisonCell1GUID = 0; - PrisonCell2GUID = 0; - PrisonCell3GUID = 0; - PrisonCell4GUID = 0; - PrisonCell5GUID = 0; - PrisonCell6GUID = 0; - PrisonCell7GUID = 0; - PrisonCell8GUID = 0; + memset(PrisonCellGUIDs, 0, 8 * sizeof(uint64)); PrisonersCell5.clear(); PrisonersCell6.clear(); PrisonersCell7.clear(); PrisonersCell8.clear(); - PrisonerCounter5 = 0; - PrisonerCounter6 = 0; - PrisonerCounter7 = 0; - PrisonerCounter8 = 0; - - BroggokLeverGUID = 0; + PrisonerCounter5 = 0; + PrisonerCounter6 = 0; + PrisonerCounter7 = 0; + PrisonerCounter8 = 0; } void OnCreatureCreate(Creature* creature) OVERRIDE { switch (creature->GetEntry()) { - case 17381: - The_MakerGUID = creature->GetGUID(); + case NPC_THE_MAKER: + TheMakerGUID = creature->GetGUID(); break; - case 17380: + case NPC_BROGGOK: BroggokGUID = creature->GetGUID(); break; - case 17377: - Kelidan_The_BreakerGUID = creature->GetGUID(); + case NPC_KELIDAN_THE_BREAKER: + KelidanTheBreakerGUID = creature->GetGUID(); break; - case 17398: + case NPC_PRISONER: StorePrisoner(creature); break; + default: + break; } } void OnUnitDeath(Unit* unit) OVERRIDE { - if (unit && unit->GetTypeId() == TYPEID_UNIT && unit->GetEntry() == 17398) + if (unit->GetTypeId() == TYPEID_UNIT && unit->GetEntry() == NPC_PRISONER) PrisonerDied(unit->GetGUID()); } void OnGameObjectCreate(GameObject* go) OVERRIDE { - if (go->GetEntry() == 181766) //Final exit door - Door1GUID = go->GetGUID(); - if (go->GetEntry() == 181811) //The Maker Front door - Door2GUID = go->GetGUID(); - if (go->GetEntry() == 181812) //The Maker Rear door - Door3GUID = go->GetGUID(); - if (go->GetEntry() == 181822) //Broggok Front door - Door4GUID = go->GetGUID(); - if (go->GetEntry() == 181819) //Broggok Rear door - Door5GUID = go->GetGUID(); - if (go->GetEntry() == 181823) //Kelidan exit door - Door6GUID = go->GetGUID(); - - if (go->GetEntry() == 181813) //The Maker prison cell front right - PrisonCell1GUID = go->GetGUID(); - if (go->GetEntry() == 181814) //The Maker prison cell back right - PrisonCell2GUID = go->GetGUID(); - if (go->GetEntry() == 181816) //The Maker prison cell front left - PrisonCell3GUID = go->GetGUID(); - if (go->GetEntry() == 181815) //The Maker prison cell back left - PrisonCell4GUID = go->GetGUID(); - if (go->GetEntry() == 181821) //Broggok prison cell front right - PrisonCell5GUID = go->GetGUID(); - if (go->GetEntry() == 181818) //Broggok prison cell back right - PrisonCell6GUID = go->GetGUID(); - if (go->GetEntry() == 181820) //Broggok prison cell front left - PrisonCell7GUID = go->GetGUID(); - if (go->GetEntry() == 181817) //Broggok prison cell back left - PrisonCell8GUID = go->GetGUID(); - - if (go->GetEntry() == 181982) - BroggokLeverGUID = go->GetGUID(); //Broggok lever - } - - uint64 GetData64(uint32 data) const OVERRIDE - { - switch (data) + switch (go->GetEntry()) { - case DATA_THE_MAKER: return The_MakerGUID; - case DATA_BROGGOK: return BroggokGUID; - case DATA_KELIDAN_THE_MAKER: return Kelidan_The_BreakerGUID; - case DATA_DOOR1: return Door1GUID; - case DATA_DOOR2: return Door2GUID; - case DATA_DOOR3: return Door3GUID; - case DATA_DOOR4: return Door4GUID; - case DATA_DOOR5: return Door5GUID; - case DATA_DOOR6: return Door6GUID; - case DATA_PRISON_CELL1: return PrisonCell1GUID; - case DATA_PRISON_CELL2: return PrisonCell2GUID; - case DATA_PRISON_CELL3: return PrisonCell3GUID; - case DATA_PRISON_CELL4: return PrisonCell4GUID; - case DATA_PRISON_CELL5: return PrisonCell5GUID; - case DATA_PRISON_CELL6: return PrisonCell6GUID; - case DATA_PRISON_CELL7: return PrisonCell7GUID; - case DATA_PRISON_CELL8: return PrisonCell8GUID; - case DATA_BROGGOK_LEVER: return BroggokLeverGUID; + case GO_PRISON_DOOR_04: + PrisonDoor4GUID = go->GetGUID(); + // no break + case GO_PRISON_DOOR_01: + case GO_PRISON_DOOR_02: + case GO_PRISON_DOOR_03: + case GO_PRISON_DOOR_05: + case GO_SUMMON_DOOR: + AddDoor(go, true); + break; + case GO_BROGGOK_LEVER: + BroggokLeverGUID = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_1: + PrisonCellGUIDs[DATA_PRISON_CELL1 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_2: + PrisonCellGUIDs[DATA_PRISON_CELL2 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_3: + PrisonCellGUIDs[DATA_PRISON_CELL3 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_4: + PrisonCellGUIDs[DATA_PRISON_CELL4 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_5: + PrisonCellGUIDs[DATA_PRISON_CELL5 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_6: + PrisonCellGUIDs[DATA_PRISON_CELL6 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_7: + PrisonCellGUIDs[DATA_PRISON_CELL7 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + case GO_PRISON_CELL_DOOR_8: + PrisonCellGUIDs[DATA_PRISON_CELL8 - DATA_PRISON_CELL1] = go->GetGUID(); + break; + default: + break; } - return 0; } - void SetData(uint32 type, uint32 data) OVERRIDE + void OnGameObjectRemove(GameObject* go) OVERRIDE { - switch (type) - { - case TYPE_THE_MAKER_EVENT: - m_auiEncounter[0] = data; - break; - case TYPE_BROGGOK_EVENT: - m_auiEncounter[1] = data; - UpdateBroggokEvent(data); - break; - case TYPE_KELIDAN_THE_BREAKER_EVENT: - m_auiEncounter[2] = data; - break; - } - - if (data == DONE) + switch (go->GetEntry()) { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2]; - - str_data = saveStream.str(); - - SaveToDB(); - OUT_SAVE_INST_DATA_COMPLETE; + case GO_PRISON_DOOR_01: + case GO_PRISON_DOOR_02: + case GO_PRISON_DOOR_03: + case GO_PRISON_DOOR_04: + case GO_PRISON_DOOR_05: + case GO_SUMMON_DOOR: + AddDoor(go, false); + break; + default: + break; } } - uint32 GetData(uint32 type) const OVERRIDE + uint64 GetData64(uint32 type) const OVERRIDE { switch (type) { - case TYPE_THE_MAKER_EVENT: return m_auiEncounter[0]; - case TYPE_BROGGOK_EVENT: return m_auiEncounter[1]; - case TYPE_KELIDAN_THE_BREAKER_EVENT: return m_auiEncounter[2]; + case DATA_THE_MAKER: + return TheMakerGUID; + case DATA_BROGGOK: + return BroggokGUID; + case DATA_KELIDAN_THE_BREAKER: + return KelidanTheBreakerGUID; + case DATA_BROGGOK_LEVER: + return BroggokLeverGUID; } - return 0; - } - const char* Save() - { - return str_data.c_str(); + return 0; } - void Load(const char* in) OVERRIDE + bool SetBossState(uint32 type, EncounterState state) OVERRIDE { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } - - OUT_LOAD_INST_DATA(in); + if (!InstanceScript::SetBossState(type, state)) + return false; - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]; - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS || m_auiEncounter[i] == FAIL) - m_auiEncounter[i] = NOT_STARTED; - - OUT_LOAD_INST_DATA_COMPLETE; - } - - void UpdateBroggokEvent(uint32 data) - { - switch (data) + switch (type) { - case IN_PROGRESS: - ActivateCell(DATA_PRISON_CELL5); - HandleGameObject(Door4GUID, false); + case DATA_BROGGOK: + switch (state) + { + case IN_PROGRESS: + ActivateCell(DATA_PRISON_CELL5); + break; + case NOT_STARTED: + ResetPrisons(); + if (GameObject* lever = instance->GetGameObject(BroggokLeverGUID)) + lever->Respawn(); + break; + default: + break; + } break; - case NOT_STARTED: - ResetPrisons(); - HandleGameObject(Door5GUID, false); - HandleGameObject(Door4GUID, true); - if (GameObject* lever = instance->GetGameObject(BroggokLeverGUID)) - lever->Respawn(); + default: break; } + + return true; } void ResetPrisons() { PrisonerCounter5 = PrisonersCell5.size(); ResetPrisoners(PrisonersCell5); - HandleGameObject(PrisonCell5GUID, false); + HandleGameObject(PrisonCellGUIDs[DATA_PRISON_CELL5 - DATA_PRISON_CELL1], false); PrisonerCounter6 = PrisonersCell6.size(); ResetPrisoners(PrisonersCell6); - HandleGameObject(PrisonCell6GUID, false); + HandleGameObject(PrisonCellGUIDs[DATA_PRISON_CELL6 - DATA_PRISON_CELL1], false); PrisonerCounter7 = PrisonersCell7.size(); ResetPrisoners(PrisonersCell7); - HandleGameObject(PrisonCell7GUID, false); + HandleGameObject(PrisonCellGUIDs[DATA_PRISON_CELL7 - DATA_PRISON_CELL1], false); PrisonerCounter8 = PrisonersCell8.size(); ResetPrisoners(PrisonersCell8); - HandleGameObject(PrisonCell8GUID, false); + HandleGameObject(PrisonCellGUIDs[DATA_PRISON_CELL8 - DATA_PRISON_CELL1], false); } void ResetPrisoners(const std::set<uint64>& prisoners) @@ -367,7 +281,7 @@ class instance_blood_furnace : public InstanceMapScript else if (PrisonersCell7.find(guid) != PrisonersCell7.end() && --PrisonerCounter7 <= 0) ActivateCell(DATA_PRISON_CELL8); else if (PrisonersCell8.find(guid) != PrisonersCell8.end() && --PrisonerCounter8 <= 0) - ActivateCell(DATA_DOOR5); + ActivateCell(DATA_DOOR_4); } void ActivateCell(uint8 id) @@ -375,30 +289,30 @@ class instance_blood_furnace : public InstanceMapScript switch (id) { case DATA_PRISON_CELL5: - HandleGameObject(PrisonCell5GUID, true); + HandleGameObject(PrisonCellGUIDs[id - DATA_PRISON_CELL1], true); ActivatePrisoners(PrisonersCell5); break; case DATA_PRISON_CELL6: - HandleGameObject(PrisonCell6GUID, true); + HandleGameObject(PrisonCellGUIDs[id - DATA_PRISON_CELL1], true); ActivatePrisoners(PrisonersCell6); break; case DATA_PRISON_CELL7: - HandleGameObject(PrisonCell7GUID, true); + HandleGameObject(PrisonCellGUIDs[id - DATA_PRISON_CELL1], true); ActivatePrisoners(PrisonersCell7); break; case DATA_PRISON_CELL8: - HandleGameObject(PrisonCell8GUID, true); + HandleGameObject(PrisonCellGUIDs[id - DATA_PRISON_CELL1], true); ActivatePrisoners(PrisonersCell8); break; - case DATA_DOOR5: - HandleGameObject(Door5GUID, true); + case DATA_DOOR_4: + HandleGameObject(PrisonDoor4GUID, true); if (Creature* broggok = instance->GetCreature(BroggokGUID)) broggok->AI()->DoAction(ACTION_ACTIVATE_BROGGOK); break; } } - void ActivatePrisoners(const std::set<uint64>& prisoners) + void ActivatePrisoners(std::set<uint64> const& prisoners) { for (std::set<uint64>::const_iterator i = prisoners.begin(); i != prisoners.end(); ++i) if (Creature* prisoner = instance->GetCreature(*i)) @@ -407,6 +321,69 @@ class instance_blood_furnace : public InstanceMapScript prisoner->SetInCombatWithZone(); } } + + std::string GetSaveData() OVERRIDE + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "B F " << GetBossSaveData(); + + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } + + void Load(char const* str) OVERRIDE + { + if (!str) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(str); + + char dataHead1, dataHead2; + + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; + + if (dataHead1 == 'B' && dataHead2 == 'F') + { + for (uint32 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + SetBossState(i, EncounterState(tmpState)); + } + } + else + OUT_LOAD_INST_DATA_FAIL; + + OUT_LOAD_INST_DATA_COMPLETE; + } + + protected: + uint64 TheMakerGUID; + uint64 BroggokGUID; + uint64 KelidanTheBreakerGUID; + + uint64 BroggokLeverGUID; + uint64 PrisonDoor4GUID; + + uint64 PrisonCellGUIDs[8]; + + std::set<uint64>PrisonersCell5; + std::set<uint64>PrisonersCell6; + std::set<uint64>PrisonersCell7; + std::set<uint64>PrisonersCell8; + + uint8 PrisonerCounter5; + uint8 PrisonerCounter6; + uint8 PrisonerCounter7; + uint8 PrisonerCounter8; }; InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index d802e48f3b0..a961800025d 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -484,7 +484,7 @@ class npc_ember_of_alar : public CreatureScript me->setDeathState(JUST_DIED); } - void DamageTaken(Unit* killer, uint32 &damage) OVERRIDE + void DamageTaken(Unit* killer, uint32& damage) OVERRIDE { if (damage >= me->GetHealth() && killer != me && !toDie) { @@ -492,7 +492,7 @@ class npc_ember_of_alar : public CreatureScript DoCast(me, SPELL_EMBER_BLAST, true); me->SetDisplayId(11686); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if (instance && instance->GetData(DATA_ALAREVENT) == 2) + if (instance->GetData(DATA_ALAREVENT) == 2) { if (Unit* Alar = Unit::GetUnit(*me, instance->GetData64(DATA_ALAR))) { diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 75b1bfe8ad1..077539b6b88 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -182,7 +182,7 @@ struct advisorbase_ai : public ScriptedAI me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); //reset encounter - if (instance && (instance->GetData(DATA_KAELTHASEVENT) == 1 || instance->GetData(DATA_KAELTHASEVENT) == 3)) + if (instance->GetData(DATA_KAELTHASEVENT) == 1 || instance->GetData(DATA_KAELTHASEVENT) == 3) if (Creature* Kaelthas = Unit::GetCreature(*me, instance->GetData64(DATA_KAELTHAS))) Kaelthas->AI()->EnterEvadeMode(); } @@ -223,14 +223,14 @@ struct advisorbase_ai : public ScriptedAI return; //Prevent glitch if in fake death - if (FakeDeath && instance && instance->GetData(DATA_KAELTHASEVENT) != 0) + if (FakeDeath && instance->GetData(DATA_KAELTHASEVENT) != 0) { damage = 0; return; } //Don't really die in phase 1 & 3, only die after that - if (instance && instance->GetData(DATA_KAELTHASEVENT) != 0) + if (instance->GetData(DATA_KAELTHASEVENT) != 0) { //prevent death damage = 0; @@ -417,7 +417,7 @@ class boss_kaelthas : public CreatureScript } else if (me->GetMap()->IsDungeon()) { - if (instance && !instance->GetData(DATA_KAELTHASEVENT) && !Phase) + if (!instance->GetData(DATA_KAELTHASEVENT) && !Phase) StartEvent(); who->SetInCombatWith(me); @@ -429,7 +429,7 @@ class boss_kaelthas : public CreatureScript void EnterCombat(Unit* /*who*/) OVERRIDE { - if (instance && !instance->GetData(DATA_KAELTHASEVENT) && !Phase) + if (!instance->GetData(DATA_KAELTHASEVENT) && !Phase) StartEvent(); } @@ -1046,7 +1046,7 @@ class boss_thaladred_the_darkener : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3) + if (instance->GetData(DATA_KAELTHASEVENT) == 3) Talk(SAY_THALADRED_DEATH); } @@ -1138,7 +1138,7 @@ class boss_lord_sanguinar : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3) + if (instance->GetData(DATA_KAELTHASEVENT) == 3) Talk(SAY_SANGUINAR_DEATH); } @@ -1203,7 +1203,7 @@ class boss_grand_astromancer_capernian : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3) + if (instance->GetData(DATA_KAELTHASEVENT) == 3) Talk(SAY_CAPERNIAN_DEATH); } @@ -1342,7 +1342,7 @@ class boss_master_engineer_telonicus : public CreatureScript void JustDied(Unit* /*killer*/) OVERRIDE { - if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3) + if (instance->GetData(DATA_KAELTHASEVENT) == 3) Talk(SAY_TELONICUS_DEATH); } diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp index a1917d6201c..1a972f65360 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp @@ -77,7 +77,7 @@ class boss_void_reaver : public CreatureScript Enraged = false; - if (instance && me->IsAlive()) + if (me->IsAlive()) instance->SetData(DATA_VOIDREAVEREVENT, NOT_STARTED); } diff --git a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp index 83b4f0440e0..3f1579c42b1 100644 --- a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp +++ b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp @@ -113,7 +113,10 @@ public: struct npc_bloodmaul_bruteAI : public ScriptedAI { - npc_bloodmaul_bruteAI(Creature* creature) : ScriptedAI(creature) { } + npc_bloodmaul_bruteAI(Creature* creature) : ScriptedAI(creature) + { + hp30 = false; + } void Reset() OVERRIDE { @@ -1125,9 +1128,10 @@ public: struct npc_oscillating_frequency_scanner_master_bunnyAI : public ScriptedAI { - npc_oscillating_frequency_scanner_master_bunnyAI(Creature* creature) : ScriptedAI(creature) + npc_oscillating_frequency_scanner_master_bunnyAI(Creature* creature) : ScriptedAI(creature) { playerGuid = 0; + timer = 500; } void Reset() OVERRIDE diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index daeb0d71720..61c3de0e6b1 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -54,7 +54,7 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript uint64 ownerGuid = me->GetOwnerGUID(); if (!ownerGuid) return; - + // Find victim of Summon Gargoyle spell std::list<Unit*> targets; Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f); diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index 0db35bf2fe6..8a0b78b5478 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -25,9 +25,9 @@ enum HunterSpells { - SPELL_HUNTER_CRIPPLING_POISON = 30981, // Viper - SPELL_HUNTER_DEADLY_POISON = 34655, // Venomous Snake - SPELL_HUNTER_MIND_NUMBING_POISON = 25810 // Viper + SPELL_HUNTER_CRIPPLING_POISON = 30981, // Viper + SPELL_HUNTER_DEADLY_POISON_PASSIVE = 34657, // Venomous Snake + SPELL_HUNTER_MIND_NUMBING_POISON = 25810 // Viper }; enum HunterCreatures @@ -57,14 +57,17 @@ class npc_pet_hunter_snake_trap : public CreatureScript me->SetMaxHealth(uint32(107 * (me->getLevel() - 40) * 0.025f)); // Add delta to make them not all hit the same time uint32 delta = (rand() % 7) * 100; - me->SetStatFloatValue(UNIT_FIELD_BASEATTACKTIME, float(Info->baseattacktime + delta)); - me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower)); + me->SetAttackTime(BASE_ATTACK, Info->baseattacktime + delta); + //me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower)); // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target if (!me->GetVictim() && me->IsSummon()) if (Unit* Owner = me->ToTempSummon()->GetSummoner()) if (Owner->getAttackerForHelper()) AttackStart(Owner->getAttackerForHelper()); + + if (!_isViper) + DoCast(me, SPELL_HUNTER_DEADLY_POISON_PASSIVE, true); } // Redefined for random target selection: @@ -99,32 +102,19 @@ class npc_pet_hunter_snake_trap : public CreatureScript return; } - if (_spellTimer <= diff) + // Viper + if (_isViper) { - if (_isViper) // Viper + if (_spellTimer <= diff) { - if (urand(0, 2) == 0) //33% chance to cast - { - uint32 spell; - if (urand(0, 1) == 0) - spell = SPELL_HUNTER_MIND_NUMBING_POISON; - else - spell = SPELL_HUNTER_CRIPPLING_POISON; - - DoCastVictim(spell); - } + if (urand(0, 2) == 0) // 33% chance to cast + DoCastVictim(RAND(SPELL_HUNTER_MIND_NUMBING_POISON, SPELL_HUNTER_CRIPPLING_POISON)); _spellTimer = 3000; } - else // Venomous Snake - { - if (urand(0, 2) == 0) // 33% chance to cast - DoCastVictim(SPELL_HUNTER_DEADLY_POISON); - _spellTimer = 1500 + (rand() % 5) * 100; - } + else + _spellTimer -= diff; } - else - _spellTimer -= diff; DoMeleeAttackIfReady(); } diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 3f5bb34015e..e1ef9ea6862 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -879,7 +879,7 @@ class spell_dk_presence : public SpellScriptLoader { Unit* target = GetTarget(); - if (GetSpellInfo()->Id == SPELL_DK_BLOOD_PRESENCE) + if (GetId() == SPELL_DK_BLOOD_PRESENCE) target->CastSpell(target, SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, true); else if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1, EFFECT_0)) if (!target->HasAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED)) @@ -890,7 +890,7 @@ class spell_dk_presence : public SpellScriptLoader { Unit* target = GetTarget(); - if (GetSpellInfo()->Id == SPELL_DK_FROST_PRESENCE) + if (GetId() == SPELL_DK_FROST_PRESENCE) target->CastSpell(target, SPELL_DK_FROST_PRESENCE_TRIGGERED, true); else if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_R1, EFFECT_0)) if (!target->HasAura(SPELL_DK_FROST_PRESENCE_TRIGGERED)) @@ -901,12 +901,12 @@ class spell_dk_presence : public SpellScriptLoader { Unit* target = GetTarget(); - if (GetSpellInfo()->Id == SPELL_DK_UNHOLY_PRESENCE) + if (GetId() == SPELL_DK_UNHOLY_PRESENCE) target->CastSpell(target, SPELL_DK_UNHOLY_PRESENCE_TRIGGERED, true); if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1, EFFECT_0)) { - if (GetSpellInfo()->Id == SPELL_DK_UNHOLY_PRESENCE) + if (GetId() == SPELL_DK_UNHOLY_PRESENCE) { // Not listed as any effect, only base points set int32 bp = impAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 419a289aed4..cdf32bd94d5 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1606,6 +1606,7 @@ class spell_q12527_zuldrak_rat : public SpellScriptLoader } }; +// 55368 - Summon Stefan class spell_q12661_q12669_q12676_q12677_q12713_summon_stefan : public SpellScriptLoader { public: @@ -1615,19 +1616,16 @@ class spell_q12661_q12669_q12676_q12677_q12713_summon_stefan : public SpellScrip { PrepareSpellScript(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript); - void ChangeSummonPos(SpellEffIndex /*effIndex*/) + void SetDest(SpellDestination& dest) { // Adjust effect summon position - WorldLocation summonPos = *GetExplTargetDest(); - Position offset = { 0.0f, 0.0f, 20.0f, 0.0f }; - summonPos.RelocateOffset(offset); - SetExplTargetDest(summonPos); - GetHitDest()->RelocateOffset(offset); + Position const offset = { 0.0f, 0.0f, 20.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectHit += SpellEffectFn(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK); } }; @@ -1723,6 +1721,7 @@ class spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy : public } }; +// 59303 - Summon Frost Wyrm class spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon : public SpellScriptLoader { public: @@ -1732,19 +1731,16 @@ class spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon : public S { PrepareSpellScript(spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon_SpellScript); - void ChangeSummonPos(SpellEffIndex /*effIndex*/) + void SetDest(SpellDestination& dest) { // Adjust effect summon position - WorldLocation summonPos = *GetExplTargetDest(); - Position offset = { 0.0f, 0.0f, 20.0f, 0.0f }; - summonPos.RelocateOffset(offset); - SetExplTargetDest(summonPos); - GetHitDest()->RelocateOffset(offset); + Position const offset = { 0.0f, 0.0f, 20.0f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectHit += SpellEffectFn(spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK); } }; @@ -1754,6 +1750,7 @@ class spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon : public S } }; +// 12601 - Second Chances: Summon Landgren's Soul Moveto Target Bunny class spell_q12847_summon_soul_moveto_bunny : public SpellScriptLoader { public: @@ -1763,19 +1760,16 @@ class spell_q12847_summon_soul_moveto_bunny : public SpellScriptLoader { PrepareSpellScript(spell_q12847_summon_soul_moveto_bunny_SpellScript); - void ChangeSummonPos(SpellEffIndex /*effIndex*/) + void SetDest(SpellDestination& dest) { // Adjust effect summon position - WorldLocation summonPos = *GetExplTargetDest(); - Position offset = { 0.0f, 0.0f, 2.5f, 0.0f }; - summonPos.RelocateOffset(offset); - SetExplTargetDest(summonPos); - GetHitDest()->RelocateOffset(offset); + Position const offset = { 0.0f, 0.0f, 2.5f, 0.0f }; + dest.RelocateOffset(offset); } void Register() OVERRIDE { - OnEffectHit += SpellEffectFn(spell_q12847_summon_soul_moveto_bunny_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q12847_summon_soul_moveto_bunny_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER); } }; @@ -2012,19 +2006,19 @@ class spell_q12308_escape_from_silverbrook_summon_worgen : public SpellScriptLoa { PrepareSpellScript(spell_q12308_escape_from_silverbrook_summon_worgen_SpellScript); - void ModDest(SpellEffIndex effIndex) + void ModDest(SpellDestination& dest) { - float dist = GetSpellInfo()->Effects[effIndex].CalcRadius(GetCaster()); - float angle = (urand(0, 1) ? -1 : 1) * (frand(0.75f, 1.0f) * M_PI); + float dist = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster()); + float angle = frand(0.75f, 1.25f) * M_PI; Position pos; GetCaster()->GetNearPosition(pos, dist, angle); - GetHitDest()->Relocate(&pos); + dest.Relocate(pos); } void Register() OVERRIDE { - OnEffectHit += SpellEffectFn(spell_q12308_escape_from_silverbrook_summon_worgen_SpellScript::ModDest, EFFECT_0, SPELL_EFFECT_SUMMON); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q12308_escape_from_silverbrook_summon_worgen_SpellScript::ModDest, EFFECT_0, TARGET_DEST_CASTER_SUMMON); } }; @@ -2241,6 +2235,47 @@ class spell_q12919_gymers_throw : public SpellScriptLoader } }; +enum Quest_The_Hunter_And_The_Prince +{ + SPELL_ILLIDAN_KILL_CREDIT = 61748 +}; + +class spell_q13400_illidan_kill_master : public SpellScriptLoader +{ + public: + spell_q13400_illidan_kill_master() : SpellScriptLoader("spell_q13400_illidan_kill_master") { } + + class spell_q13400_illidan_kill_master_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q13400_illidan_kill_master_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_ILLIDAN_KILL_CREDIT)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (caster->IsVehicle()) + if (Unit* passenger = caster->GetVehicleKit()->GetPassenger(0)) + passenger->CastSpell(passenger, SPELL_ILLIDAN_KILL_CREDIT, true); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_q13400_illidan_kill_master_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_q13400_illidan_kill_master_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -2295,4 +2330,5 @@ void AddSC_quest_spell_scripts() new spell_q12619_emblazon_runeblade_effect(); new spell_q12919_gymers_grab(); new spell_q12919_gymers_throw(); + new spell_q13400_illidan_kill_master(); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 4670117f0ea..b8b652eb314 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -25,16 +25,21 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "Containers.h" enum RogueSpells { - SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482, - SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231, - SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819, - SPELL_ROGUE_PREY_ON_THE_WEAK = 58670, - SPELL_ROGUE_SHIV_TRIGGERED = 5940, - SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, - SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, + SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482, + SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231, + SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819, + SPELL_ROGUE_KILLING_SPREE = 51690, + SPELL_ROGUE_KILLING_SPREE_TELEPORT = 57840, + SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG = 57841, + SPELL_ROGUE_KILLING_SPREE_DMG_BUFF = 61851, + SPELL_ROGUE_PREY_ON_THE_WEAK = 58670, + SPELL_ROGUE_SHIV_TRIGGERED = 5940, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, + SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, }; // 13877, 33735, (check 51211, 65956) - Blade Flurry @@ -249,6 +254,105 @@ class spell_rog_deadly_poison : public SpellScriptLoader } }; +// 51690 - Killing Spree +class spell_rog_killing_spree : public SpellScriptLoader +{ + public: + spell_rog_killing_spree() : SpellScriptLoader("spell_rog_killing_spree") { } + + class spell_rog_killing_spree_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rog_killing_spree_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty() || GetCaster()->GetVehicleBase()) + FinishCast(SPELL_FAILED_OUT_OF_RANGE); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Aura* aura = GetCaster()->GetAura(SPELL_ROGUE_KILLING_SPREE)) + { + if (spell_rog_killing_spree_AuraScript* script = dynamic_cast<spell_rog_killing_spree_AuraScript*>(aura->GetScriptByName("spell_rog_killing_spree"))) + script->AddTarget(GetHitUnit()); + } + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rog_killing_spree_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_rog_killing_spree_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_rog_killing_spree_SpellScript(); + } + + class spell_rog_killing_spree_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_killing_spree_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_KILLING_SPREE_TELEPORT) + || !sSpellMgr->GetSpellInfo(SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG) + || !sSpellMgr->GetSpellInfo(SPELL_ROGUE_KILLING_SPREE_DMG_BUFF)) + return false; + return true; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_ROGUE_KILLING_SPREE_DMG_BUFF, true); + } + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + while (!_targets.empty()) + { + uint64 guid = Trinity::Containers::SelectRandomContainerElement(_targets); + if (Unit* target = ObjectAccessor::GetUnit(*GetTarget(), guid)) + { + GetTarget()->CastSpell(target, SPELL_ROGUE_KILLING_SPREE_TELEPORT, true); + GetTarget()->CastSpell(target, SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG, true); + break; + } + else + _targets.remove(guid); + } + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_ROGUE_KILLING_SPREE_DMG_BUFF); + } + + void Register() OVERRIDE + { + AfterEffectApply += AuraEffectApplyFn(spell_rog_killing_spree_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_killing_spree_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_rog_killing_spree_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + + public: + void AddTarget(Unit* target) + { + _targets.push_back(target->GetGUID()); + } + + private: + std::list<uint64> _targets; + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_rog_killing_spree_AuraScript(); + } +}; + // -31130 - Nerves of Steel class spell_rog_nerves_of_steel : public SpellScriptLoader { @@ -594,6 +698,7 @@ void AddSC_rogue_spell_scripts() new spell_rog_blade_flurry(); new spell_rog_cheat_death(); new spell_rog_deadly_poison(); + new spell_rog_killing_spree(); new spell_rog_nerves_of_steel(); new spell_rog_preparation(); new spell_rog_prey_on_the_weak(); diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index e9a010868d8..ac30f6f1e80 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -34,7 +34,6 @@ npc_garments_of_quests 80% NPC's related to all Garments of-quests 5621, 56 npc_injured_patient 100% patients for triage-quests (6622 and 6624) npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622 and 6624 (Triage) npc_mount_vendor 100% Regular mount vendors all over the world. Display gossip if player doesn't meet the requirements to buy -npc_rogue_trainer 80% Scripted trainers, so they are able to offer item 17126 for class quest 6681 npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage @@ -1239,86 +1238,6 @@ public: } }; -/*###### -## npc_rogue_trainer -######*/ - -#define GOSSIP_HELLO_ROGUE1 "I wish to unlearn my talents" -#define GOSSIP_HELLO_ROGUE2 "<Take the letter>" -#define GOSSIP_HELLO_ROGUE3 "Purchase a Dual Talent Specialization." - -class npc_rogue_trainer : public CreatureScript -{ -public: - npc_rogue_trainer() : CreatureScript("npc_rogue_trainer") { } - - bool OnGossipHello(Player* player, Creature* creature) OVERRIDE - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->IsTrainer()) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); - - if (player->getClass() == CLASS_ROGUE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_HELLO_ROGUE1, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_UNLEARNTALENTS); - - if (player->GetSpecsCount() == 1 && player->getLevel() >= sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_HELLO_ROGUE3, GOSSIP_SENDER_MAIN, GOSSIP_OPTION_LEARNDUALSPEC); - - if (player->getClass() == CLASS_ROGUE && player->getLevel() >= 24 && !player->HasItemCount(17126) && !player->GetQuestRewardStatus(6681)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_ROGUE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(5996, creature->GetGUID()); - } else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, 21100, false); - break; - case GOSSIP_ACTION_TRAIN: - player->GetSession()->SendTrainerList(creature->GetGUID()); - break; - case GOSSIP_OPTION_UNLEARNTALENTS: - player->CLOSE_GOSSIP_MENU(); - player->SendTalentWipeConfirm(creature->GetGUID()); - break; - case GOSSIP_OPTION_LEARNDUALSPEC: - if (player->GetSpecsCount() == 1 && !(player->getLevel() < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL))) - { - if (!player->HasEnoughMoney(10000000)) - { - player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); - player->PlayerTalkClass->SendCloseGossip(); - break; - } - else - { - player->ModifyMoney(-10000000); - - // Cast spells that teach dual spec - // Both are also ImplicitTarget self and must be cast by player - player->CastSpell(player, 63680, true, NULL, NULL, player->GetGUID()); - player->CastSpell(player, 63624, true, NULL, NULL, player->GetGUID()); - - // Should show another Gossip text with "Congratulations..." - player->PlayerTalkClass->SendCloseGossip(); - } - } - break; - } - return true; - } -}; /*###### ## npc_sayge @@ -2445,7 +2364,6 @@ void AddSC_npcs_special() new npc_garments_of_quests(); new npc_guardian(); new npc_mount_vendor(); - new npc_rogue_trainer(); new npc_sayge(); new npc_steam_tonk(); new npc_tonk_mine(); diff --git a/src/server/shared/Cryptography/OpenSSLCrypto.cpp b/src/server/shared/Cryptography/OpenSSLCrypto.cpp index 10ea595640a..bd72459e9df 100644 --- a/src/server/shared/Cryptography/OpenSSLCrypto.cpp +++ b/src/server/shared/Cryptography/OpenSSLCrypto.cpp @@ -33,7 +33,12 @@ static void lockingCallback(int mode, int type, const char* /*file*/, int /*line static void threadIdCallback(CRYPTO_THREADID * id) { +/// ACE_thread_t turns out to be a struct under Mac OS. +#ifndef __APPLE__ CRYPTO_THREADID_set_numeric(id, ACE_Thread::self()); +#else + CRYPTO_THREADID_set_pointer(id, ACE_Thread::self()); +#endif } void OpenSSLCrypto::threadsSetup() diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index f4da4093dfa..fcbfa221d6a 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -62,6 +62,13 @@ WheatyExceptionReport::WheatyExceptionReport() // Constructor // Install the unhandled exception filter function m_previousFilter = SetUnhandledExceptionFilter(WheatyUnhandledExceptionFilter); m_hProcess = GetCurrentProcess(); + if (!IsDebuggerPresent()) + { + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); + } } //============ @@ -348,7 +355,7 @@ void WheatyExceptionReport::PrintSystemInfo() } //=========================================================================== -void WheatyExceptionReport::printTracesForAllThreads() +void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables) { THREADENTRY32 te32; @@ -384,7 +391,7 @@ void WheatyExceptionReport::printTracesForAllThreads() if (threadHandle) { if (GetThreadContext(threadHandle, &context)) - WriteStackDetails(&context, false, threadHandle); + WriteStackDetails(&context, bWriteVariables, threadHandle); CloseHandle(threadHandle); } } @@ -480,7 +487,7 @@ PEXCEPTION_POINTERS pExceptionInfo) CONTEXT trashableContext = *pCtx; WriteStackDetails(&trashableContext, false, NULL); - printTracesForAllThreads(); + printTracesForAllThreads(false); // #ifdef _M_IX86 // X86 Only! @@ -489,6 +496,7 @@ PEXCEPTION_POINTERS pExceptionInfo) trashableContext = *pCtx; WriteStackDetails(&trashableContext, true, NULL); + printTracesForAllThreads(true); _tprintf(_T("========================\r\n")); _tprintf(_T("Global Variables\r\n")); @@ -566,6 +574,9 @@ PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset) DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase; + if (!hMod) + return FALSE; + if (!GetModuleFileName((HMODULE)hMod, szModule, len)) return FALSE; @@ -708,7 +719,7 @@ bool bWriteVariables, HANDLE pThreadHandle) } // Get the source line for this stack frame entry - IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE) }; + IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE64) }; DWORD dwLineDisplacement; if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo)) @@ -746,15 +757,15 @@ ULONG /*SymbolSize*/, PVOID UserContext) { - char szBuffer[2048]; + char szBuffer[8192]; __try { - if (FormatSymbolValue(pSymInfo, (STACKFRAME*)UserContext, + if (FormatSymbolValue(pSymInfo, (STACKFRAME64*)UserContext, szBuffer, sizeof(szBuffer))) _tprintf(_T("\t%s\r\n"), szBuffer); } - __except(1) + __except (EXCEPTION_EXECUTE_HANDLER) { _tprintf(_T("punting on symbol %s\r\n"), pSymInfo->Name); } @@ -769,7 +780,7 @@ PVOID UserContext) ////////////////////////////////////////////////////////////////////////////// bool WheatyExceptionReport::FormatSymbolValue( PSYMBOL_INFO pSym, -STACKFRAME * sf, +STACKFRAME64 * sf, char * pszBuffer, unsigned /*cbBuffer*/) { @@ -782,7 +793,7 @@ unsigned /*cbBuffer*/) pszCurrBuffer += sprintf(pszCurrBuffer, "Local "); // If it's a function, don't do anything. - if (pSym->Tag == 5) // SymTagFunction from CVCONST.H from the DIA SDK + if (pSym->Tag == SymTagFunction) // SymTagFunction from CVCONST.H from the DIA SDK return false; DWORD_PTR pVariable = 0; // Will point to the variable's data in memory @@ -791,7 +802,11 @@ unsigned /*cbBuffer*/) { // if (pSym->Register == 8) // EBP is the value 8 (in DBGHELP 5.1) { // This may change!!! +#ifdef _M_IX86 pVariable = sf->AddrFrame.Offset; +#elif _M_X64 + pVariable = sf->AddrStack.Offset; +#endif pVariable += (DWORD_PTR)pSym->Address; } // else @@ -810,7 +825,7 @@ unsigned /*cbBuffer*/) // will return true. bool bHandled; pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, pSym->ModBase, pSym->TypeIndex, - 0, pVariable, bHandled, pSym->Name); + 0, pVariable, bHandled, pSym->Name, ""); if (!bHandled) { @@ -842,10 +857,15 @@ DWORD dwTypeIndex, unsigned nestingLevel, DWORD_PTR offset, bool & bHandled, -char* /*Name*/) +char* Name, +char* suffix) { bHandled = false; + DWORD typeTag; + if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag)) + return pszCurrBuffer; + // Get the name of the symbol. This will either be a Type name (if a UDT), // or the structure member name. WCHAR * pwszTypeName; @@ -856,10 +876,58 @@ char* /*Name*/) LocalFree(pwszTypeName); } + if (strlen(suffix) > 0) + pszCurrBuffer += sprintf(pszCurrBuffer, "%s", suffix); + + switch (typeTag) + { + case SymTagPointerType: + DWORD innerTypeID; + if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID)) + { + pszCurrBuffer += sprintf(pszCurrBuffer, " %s", Name); + BOOL isReference; + SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_IS_REFERENCE, &isReference); + + char addressStr[40]; + memset(addressStr, 0, sizeof(addressStr)); + + if (isReference) + addressStr[0] = '&'; + else + addressStr[0] = '*'; + + DWORD_PTR address = *(PDWORD_PTR)offset; + if (address == NULL) + { + pwszTypeName; + if (SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_SYMNAME, + &pwszTypeName)) + { + pszCurrBuffer += sprintf(pszCurrBuffer, " %ls", pwszTypeName); + LocalFree(pwszTypeName); + } + + pszCurrBuffer += sprintf(pszCurrBuffer, "%s = NULL", addressStr); + + bHandled = true; + return pszCurrBuffer; + } + else + { + FormatOutputValue(&addressStr[1], btVoid, sizeof(PVOID), (PVOID)offset); + pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1, + address, bHandled, "", addressStr); + } + } + break; + default: + break; + } + // Determine how many children this type has. DWORD dwChildrenCount = 0; - SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, - &dwChildrenCount); + SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &dwChildrenCount); if (!dwChildrenCount) // If no children, we're done return pszCurrBuffer; @@ -889,6 +957,12 @@ char* /*Name*/) // Iterate through each of the children for (unsigned i = 0; i < dwChildrenCount; i++) { + DWORD symTag; + SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_SYMTAG, &symTag); + + if (symTag == SymTagFunction || symTag == SymTagTypedef) + continue; + // Add appropriate indentation level (since this routine is recursive) for (unsigned j = 0; j <= nestingLevel+1; j++) pszCurrBuffer += sprintf(pszCurrBuffer, "\t"); @@ -898,18 +972,21 @@ char* /*Name*/) BasicType basicType = GetBasicType(children.ChildId[i], modBase); pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]); + // Get the offset of the child member, relative to its parent + DWORD dwMemberOffset; + SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], + TI_GET_OFFSET, &dwMemberOffset); + + // Calculate the address of the member + DWORD_PTR dwFinalOffset = offset + dwMemberOffset; + pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, children.ChildId[i], nestingLevel+1, - offset, bHandled2, ""/*Name */); + dwFinalOffset, bHandled2, ""/*Name */, ""); // If the child wasn't a UDT, format it appropriately if (!bHandled2) { - // Get the offset of the child member, relative to its parent - DWORD dwMemberOffset; - SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], - TI_GET_OFFSET, &dwMemberOffset); - // Get the real "TypeId" of the child. We need this for the // SymGetTypeInfo(TI_GET_TYPEID) call below. DWORD typeId; @@ -920,9 +997,6 @@ char* /*Name*/) ULONG64 length; SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_LENGTH, &length); - // Calculate the address of the member - DWORD_PTR dwFinalOffset = offset + dwMemberOffset; - // BasicType basicType = GetBasicType(children.ChildId[i], modBase); // // pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]); @@ -946,41 +1020,52 @@ BasicType basicType, DWORD64 length, PVOID pAddress) { - // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!) - if (length == 1) - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress); - else if (length == 2) - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress); - else if (length == 4) + __try { - if (basicType == btFloat) + // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!) + if (length == 1) + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress); + else if (length == 2) + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress); + else if (length == 4) { - pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress); + if (basicType == btFloat) + { + pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress); + } + else if (basicType == btChar) + { + if (!IsBadStringPtr(*(PSTR*)pAddress, 32)) + { + pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"", + *(PSTR*)pAddress); + } + else + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", + *(PDWORD)pAddress); + } + else + pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress); } - else if (basicType == btChar) + else if (length == 8) { - if (!IsBadStringPtr(*(PSTR*)pAddress, 32)) + if (basicType == btFloat) { - pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"", - *(PSTR*)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf", + *(double *)pAddress); } else - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", - *(PDWORD)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", + *(DWORD64*)pAddress); } - else - pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress); } - else if (length == 8) + __except (EXCEPTION_EXECUTE_HANDLER) { - if (basicType == btFloat) - { - pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf", - *(double *)pAddress); - } - else - pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", - *(DWORD64*)pAddress); +#if _WIN64 + pszCurrBuffer += sprintf(pszCurrBuffer, " <Unable to read memory> = %I64X", (DWORD64*)pAddress); +#else + pszCurrBuffer += sprintf(pszCurrBuffer, " <Unable to read memory> = %X", (PDWORD)pAddress); +#endif } return pszCurrBuffer; @@ -1017,7 +1102,7 @@ WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase) //============================================================================ int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...) { - TCHAR szBuff[1024]; + TCHAR szBuff[8192]; int retValue; DWORD cbWritten; va_list argptr; diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h index 582f1f157b8..48894a5db91 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.h +++ b/src/server/shared/Debugging/WheatyExceptionReport.h @@ -81,7 +81,7 @@ class WheatyExceptionReport static LONG WINAPI WheatyUnhandledExceptionFilter( PEXCEPTION_POINTERS pExceptionInfo); - static void printTracesForAllThreads(); + static void printTracesForAllThreads(bool); private: // where report info is extracted and generated static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo); @@ -98,9 +98,9 @@ class WheatyExceptionReport static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID); - static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer); + static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64 *, char * pszBuffer, unsigned cbBuffer); - static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, char*); + static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, char*, char*); static char * FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress); diff --git a/src/server/shared/Utilities/EventProcessor.h b/src/server/shared/Utilities/EventProcessor.h index fd8b2909165..10ae6aa954c 100644 --- a/src/server/shared/Utilities/EventProcessor.h +++ b/src/server/shared/Utilities/EventProcessor.h @@ -28,9 +28,9 @@ class BasicEvent { public: - BasicEvent() - { - to_Abort = false; + BasicEvent() + { + to_Abort = false; m_addTime = 0; m_execTime = 0; } diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 67af12660de..f4b2b542de6 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -86,8 +86,8 @@ private: uint32 _lastChange; uint32 _delaytime; public: - FreezeDetectorRunnable() - { + FreezeDetectorRunnable() + { _loops = 0; _lastChange = 0; _delaytime = 0; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 4e594fc88c0..2a47c8f989e 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -138,7 +138,7 @@ WorldServerPort = 8085 # # BindIP -# Description: Bind world server to IP/hostname +# Description: Bind world server to IP/hostname. # Default: "0.0.0.0" - (Bind to all IPs on the system) BindIP = "0.0.0.0" @@ -152,7 +152,7 @@ BindIP = "0.0.0.0" # UseProcessors # Description: Processors mask for Windows and Linux based multi-processor systems. # Example: A computer with 2 CPUs: -# 1 - 1st CPU only, 2 - 2nd CPU only, 3 - 1st and 2nd CPU, because 1 | 2 is 3 +# 1 - 1st CPU only, 2 - 2nd CPU only, 3 - 1st and 2nd CPU, because 1 | 2 is 3 # Default: 0 - (Selected by OS) # 1+ - (Bit mask value of selected processors) @@ -169,7 +169,7 @@ ProcessPriority = 0 # # Compression -# Description: Compression level for client update packages +# Description: Compression level for client update packages. # Range: 1-9 # Default: 1 - (Speed) # 9 - (Best compression) @@ -275,7 +275,7 @@ PlayerSave.Stats.SaveOnlyOnLogout = 1 # # mmap.enablePathFinding -# Description: Enable/Disable pathfinding using mmaps - experimental +# Description: Enable/Disable pathfinding using mmaps - experimental. # Default: 0 - (Disabled) # 1 - (Enabled) @@ -395,7 +395,7 @@ PersistentCharacterCleanFlags = 0 # SERVER LOGGING # # PidFile -# Description: World daemon PID file +# Description: World daemon PID file. # Example: "./world.pid" - (Enabled) # Default: "" - (Disabled) @@ -440,7 +440,6 @@ ChatLogs.SysChan = 0 # Default: 0 - (Disabled) # 1 - (Enabled) - ChatLogs.Party = 0 # @@ -449,7 +448,6 @@ ChatLogs.Party = 0 # Default: 0 - (Disabled) # 1 - (Enabled) - ChatLogs.Raid = 0 # @@ -698,6 +696,7 @@ CharacterCreating.Disabled.ClassMask = 0 # Default: 50 CharactersPerAccount = 50 + # # CharactersPerRealm # Description: Limit number of characters per account on this realm. @@ -717,7 +716,7 @@ HeroicCharactersPerRealm = 1 # # CharacterCreating.MinLevelForHeroicCharacter # Description: Limit creating heroic characters only for account with another -# character of specific level (ignored for GM accounts) +# character of specific level (ignored for GM accounts). # Default: 55 - (Enabled, Requires at least another level 55 character) # 0 - (Disabled) # 1 - (Enabled, Requires at least another level 1 character) @@ -745,7 +744,7 @@ MaxPlayerLevel = 80 # # MinDualSpecLevel -# Description: Level requirement for Dual Talent Specialization +# Description: Level requirement for Dual Talent Specialization. # Default: 40 MinDualSpecLevel = 40 @@ -913,6 +912,7 @@ Instance.UnloadDelay = 1800000 # true - (Enabled, show) InstancesResetAnnounce = false + # # Quests.LowLevelHideDiff # Description: Level difference between player and quest level at which quests are @@ -1125,7 +1125,7 @@ DBC.EnforceItemAttributes = 1 # # AccountInstancesPerHour -# Description: Controls the max amount of different instances player can enter within hour +# Description: Controls the max amount of different instances player can enter within hour. # Default: 5 AccountInstancesPerHour = 5 @@ -1813,7 +1813,7 @@ Rate.Damage.Fall = 1 # Rate.Auction.Deposit # Rate.Auction.Cut # Description: Auction rates (auction time, deposit get at auction start, -# auction cut from price at auction end) +# auction cut from price at auction end). # Default: 1 - (Rate.Auction.Time) # 1 - (Rate.Auction.Deposit) # 1 - (Rate.Auction.Cut) @@ -2018,14 +2018,14 @@ Die.Command.Mode = 1 # STATS LIMITS # # Stats.Limits.Enable -# Description: Enable or disable stats system +# Description: Enable or disable stats system. # Default: 0 - Disabled Stats.Limits.Enable = 0 # # Stats.Limit.[STAT] -# Description: Set percentage limit for dodge, parry, block and crit rating +# Description: Set percentage limit for dodge, parry, block and crit rating. # Default: 95.0 (95%) Stats.Limits.Dodge = 95.0 @@ -2142,7 +2142,7 @@ Battleground.Random.ResetHour = 6 # Battleground.RewardWinnerArenaLast # Battleground.RewardLoserHonorFirst # Battleground.RewardLoserHonorLast -# Description: Random Battlegrounds / call to the arms rewards +# Description: Random Battlegrounds / call to the arms rewards. # Default: 30 - Battleground.RewardWinnerHonorFirst # 25 - Battleground.RewardWinnerArenaFirst # 15 - Battleground.RewardWinnerHonorLast @@ -2238,7 +2238,7 @@ Arena.RatingDiscardTimer = 600000 # # Arena.RatedUpdateTimer -# Description: Time (in milliseconds) between checks for matchups in rated arena +# Description: Time (in milliseconds) between checks for matchups in rated arena. # Default: 5000 - (5 seconds) Arena.RatedUpdateTimer = 5000 @@ -2392,7 +2392,7 @@ Ra.MinLevel = 3 # # SOAP.Enable -# Description: Enable soap service +# Description: Enable soap service. # Default: 0 - (Disabled) # 1 - (Enabled) @@ -2400,7 +2400,7 @@ SOAP.Enabled = 0 # # SOAP.IP -# Description: Bind SOAP service to IP/hostname +# Description: Bind SOAP service to IP/hostname. # Default: "127.0.0.1" - (Bind to localhost) SOAP.IP = "127.0.0.1" @@ -2554,12 +2554,29 @@ Guild.AllowMultipleGuildMaster = 0 # # ShowKickInWorld # Description: Determines whether a message is broadcasted to the entire server when a -# player gets kicked +# player gets kicked. # Default: 0 - (Disabled) # 1 - (Enabled) ShowKickInWorld = 0 +# ShowMuteInWorld +# Description: Determines whether a message is broadcasted to the entire server when a +# player gets muted. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +ShowMuteInWorld = 0 + +# +# ShowBanInWorld +# Description: Determines whether a message is broadcasted to the entire server when a +# player gets banned. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +ShowBanInWorld = 0 + # # RecordUpdateTimeDiffInterval # Description: Time (in milliseconds) update time diff is written to the log file. @@ -2569,6 +2586,7 @@ ShowKickInWorld = 0 # 0 - (Disabled) RecordUpdateTimeDiffInterval = 60000 + # # MinRecordUpdateTimeDiff # Description: Only record update time diff which is greater than this value. @@ -2628,8 +2646,8 @@ PlayerDump.DisallowOverwrite = 1 # # UI.ShowQuestLevelsInDialogs # Description: Show quest levels next to quest titles in UI dialogs -# Example: [13] Westfall Stew -# Default: 0 (do not show) +# Example: [13] Westfall Stew +# Default: 0 - (Do not show) UI.ShowQuestLevelsInDialogs = 0 @@ -2641,7 +2659,7 @@ UI.ShowQuestLevelsInDialogs = 0 # # Appender config values: Given a appender "name" # Appender.name -# Description: Defines 'where to log' +# Description: Defines 'where to log'. # Format: Type,LogLevel,Flags,optional1,optional2,optional3 # # Type @@ -2789,18 +2807,18 @@ Log.Async.Enable = 0 # # PacketSpoof.Policy # Description: Determines the course of action when packet spoofing is detected. -# Default: 1 - Log + kick -# 0 - Log only ("network") -# 2 - Log + kick + ban +# Default: 1 - (Log + kick) +# 0 - (Log only 'network') +# 2 - (Log + kick + ban) PacketSpoof.Policy = 1 # # PacketSpoof.BanMode # Description: If PacketSpoof.Policy equals 2, this will determine the ban mode. -# Note: Banning by character not supported for logical reasons. -# Default: 0 - Ban Account -# 2 - Ban IP +# Note: Banning by character not supported for logical reasons. +# Default: 0 - Ban Account +# 2 - Ban IP # PacketSpoof.BanMode = 0 diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h index 227d6f2c763..5cb45d488d5 100644 --- a/src/tools/map_extractor/adt.h +++ b/src/tools/map_extractor/adt.h @@ -255,7 +255,7 @@ public: if (h->offsData2a) return *((uint64 *)((uint8*)this + 8 + h->offsData2a)); else - return 0xFFFFFFFFFFFFFFFFLL; + return 0xFFFFFFFFFFFFFFFFuLL; } }; |