diff options
| author | Shauren <shauren.trinity@gmail.com> | 2012-07-05 14:16:44 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2012-07-05 14:16:44 +0200 |
| commit | 32ba32c4ebe56ba931c8638460c24cd57ae29a75 (patch) | |
| tree | 2f757648b85ec8989a7dfc573b954b9b4d718650 /src/server/game | |
| parent | c95905ddbb22e2b5b5362b790aa851ef10d4e27e (diff) | |
| parent | ed6f3e2deff55f913f9646db5f540b7704088478 (diff) | |
Merge branch '4.x' of github.com:TrinityCore/TrinityCore into 4.3.4
Diffstat (limited to 'src/server/game')
114 files changed, 2034 insertions, 4099 deletions
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h index f4555649210..fbc8675cc47 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.h +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -53,7 +53,8 @@ class GameObjectAI virtual uint64 GetData64(uint32 /*id*/) { return 0; } virtual void SetData(uint32 /*id*/, uint32 /*value*/) {} virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) {} - virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) { } + virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) {} + virtual void EventInform(uint32 /*eventId*/) {} }; class NullGameObjectAI : public GameObjectAI diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 160b406a6ea..97ae0581a18 100755 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -532,3 +532,19 @@ bool PetAI::CanAttack(Unit* target) // default, though we shouldn't ever get here return false; } + +void PetAI::ReceiveEmote(Player* player, uint32 emote) +{ + if (me->GetOwnerGUID() && me->GetOwnerGUID() == player->GetGUID()) + switch (emote) + { + case TEXT_EMOTE_COWER: + if (me->isPet() && me->ToPet()->IsPetGhoul()) + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + break; + case TEXT_EMOTE_ANGRY: + if (me->isPet() && me->ToPet()->IsPetGhoul()) + me->HandleEmoteCommand(EMOTE_ONESHOT_COWER); + break; + } +} diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h index ed3e2305556..8e5311fa000 100755 --- a/src/server/game/AI/CoreAI/PetAI.h +++ b/src/server/game/AI/CoreAI/PetAI.h @@ -42,6 +42,7 @@ class PetAI : public CreatureAI void MovementInform(uint32 moveType, uint32 data); void OwnerDamagedBy(Unit* attacker); void OwnerAttacked(Unit* target); + void ReceiveEmote(Player* player, uint32 textEmote); private: bool _isVisible(Unit*) const; diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 94ac452b9f3..68752b82e7f 100755 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -128,8 +128,6 @@ class CreatureAI : public UnitAI void OnCharmed(bool apply); - //virtual void SpellClick(Player* player) {} - // Called at reaching home after evade virtual void JustReachedHome() {} @@ -171,6 +169,8 @@ class CreatureAI : public UnitAI virtual void PassengerBoarded(Unit* /*passenger*/, int8 /*seatId*/, bool /*apply*/) {} + virtual void OnSpellClick(Unit* /*clicker*/) { } + virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; } protected: virtual void MoveInLineOfSight(Unit* /*who*/); diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp index 517e55af457..a863f2f89cf 100755 --- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp @@ -204,12 +204,17 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() temp.raw.param3 = fields[8].GetInt32(); temp.raw.param4 = fields[9].GetInt32(); + CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id); //Creature does not exist in database - if (!sObjectMgr->GetCreatureTemplate(temp.creature_id)) + if (!cInfo) { - sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id); + sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, creature_id); continue; } + + // Only on the first script + if (cInfo->AIName != "EventAI" && m_CreatureEventAI_Event_Map[creature_id].empty()) + sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI' - possible AI-mismatch?", temp.creature_id); //No chance of this event occuring if (temp.event_chance == 0) @@ -735,18 +740,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() } while (result->NextRow()); - for (CreatureEventAI_Event_Map::const_iterator itr = m_CreatureEventAI_Event_Map.begin(); itr != m_CreatureEventAI_Event_Map.end(); ++itr) - { - if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(itr->first)) - { - if (cInfo->AIName != "EventAI") - { - sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI', changing to EventAI", itr->first); - const_cast<CreatureTemplate*>(cInfo)->AIName = "EventAI"; - } - } - } - sLog->outString(">> Loaded %u CreatureEventAI scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index 4fac8b3cba5..ba0a94d2590 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -191,7 +191,7 @@ struct ScriptedAI : public CreatureAI //Generally used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims void SetCombatMovement(bool allowMovement); - bool IsCombatMovementAllowed() { return _isCombatMovementAllowed; } + bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; } bool EnterEvadeIfOutOfCombatArea(uint32 const diff); @@ -200,16 +200,16 @@ struct ScriptedAI : public CreatureAI // - for raid in mode 10-Heroic // - for raid in mode 25-heroic // DO NOT USE to check raid in mode 25-normal. - bool IsHeroic() { return _isHeroic; } + bool IsHeroic() const { return _isHeroic; } // return the dungeon or raid difficulty - Difficulty GetDifficulty() { return _difficulty; } + Difficulty GetDifficulty() const { return _difficulty; } // return true for 25 man or 25 man heroic mode - bool Is25ManRaid() { return _difficulty & RAID_DIFFICULTY_MASK_25MAN; } + bool Is25ManRaid() const { return _difficulty & RAID_DIFFICULTY_MASK_25MAN; } template<class T> inline - const T& DUNGEON_MODE(const T& normal5, const T& heroic10) + const T& DUNGEON_MODE(const T& normal5, const T& heroic10) const { switch (_difficulty) { @@ -225,7 +225,7 @@ struct ScriptedAI : public CreatureAI } template<class T> inline - const T& RAID_MODE(const T& normal10, const T& normal25) + const T& RAID_MODE(const T& normal10, const T& normal25) const { switch (_difficulty) { @@ -241,7 +241,7 @@ struct ScriptedAI : public CreatureAI } template<class T> inline - const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25) + const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25) const { switch (_difficulty) { diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index 13bbbe2c338..987af82e496 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -327,7 +327,6 @@ Player* FollowerAI::GetLeaderForFollower() sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI GetLeader changed and returned new leader."); m_uiLeaderGUID = member->GetGUID(); return member; - break; } } } diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 08f1b18ffad..96fc43e0572 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -696,8 +696,9 @@ void SmartAI::OnCharmed(bool apply) GetScript()->ProcessEventsFor(SMART_EVENT_CHARMED, NULL, 0, 0, apply); } -void SmartAI::DoAction(const int32 /*param*/) +void SmartAI::DoAction(const int32 param) { + GetScript()->ProcessEventsFor(SMART_EVENT_ACTION_DONE, NULL, param); } uint32 SmartAI::GetData(uint32 /*id*/) @@ -825,27 +826,10 @@ void SmartAI::sOnGameEvent(bool start, uint16 eventId) GetScript()->ProcessEventsFor(start ? SMART_EVENT_GAME_EVENT_START : SMART_EVENT_GAME_EVENT_END, NULL, eventId); } -/* -SMART_EVENT_UPDATE_OOC -SMART_EVENT_SPELLHIT -SMART_EVENT_RANGE -SMART_EVENT_RESPAWN -SMART_EVENT_SUMMONED_UNIT -SMART_EVENT_ACCEPTED_QUEST -SMART_EVENT_REWARD_QUEST -SMART_EVENT_TARGET_BUFFED -SMART_EVENT_SUMMON_DESPAWNED -SMART_EVENT_AI_INIT -SMART_EVENT_DATA_SET -SMART_EVENT_TEXT_OVER -SMART_EVENT_TIMED_EVENT_TRIGGERED -SMART_EVENT_UPDATE -SMART_EVENT_LINK -SMART_EVENT_GOSSIP_SELECT -SMART_EVENT_JUST_CREATED -SMART_EVENT_GOSSIP_HELLO -SMART_EVENT_DEATH -*/ +void SmartAI::OnSpellClick(Unit* clicker) +{ + GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELLCLICK, clicker); +} int SmartGameObjectAI::Permissible(const GameObject* g) { @@ -937,6 +921,11 @@ void SmartGameObjectAI::OnStateChanged(uint32 state, Unit* unit) GetScript()->ProcessEventsFor(SMART_EVENT_GO_STATE_CHANGED, unit, state); } +void SmartGameObjectAI::EventInform(uint32 eventId) +{ + GetScript()->ProcessEventsFor(SMART_EVENT_GO_EVENT_INFORM, NULL, eventId); +} + class SmartTrigger : public AreaTriggerScript { public: diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 435aa176d4d..79cef0c3b37 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -198,6 +198,8 @@ class SmartAI : public CreatureAI void RemoveAuras(); + void OnSpellClick(Unit* clicker); + private: uint32 mFollowCreditType; uint32 mFollowArrivedTimer; @@ -235,30 +237,31 @@ class SmartAI : public CreatureAI class SmartGameObjectAI : public GameObjectAI { -public: - SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {} - ~SmartGameObjectAI() {} - - void UpdateAI(uint32 diff); - void InitializeAI(); - void Reset(); - SmartScript* GetScript() { return &mScript; } - static int Permissible(const GameObject* g); - - bool GossipHello(Player* player); - bool GossipSelect(Player* player, uint32 sender, uint32 action); - 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); - void OnGameEvent(bool start, uint16 eventId); - void OnStateChanged(uint32 state, Unit* unit); - -protected: - GameObject* const go; - SmartScript mScript; + public: + SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {} + ~SmartGameObjectAI() {} + + void UpdateAI(uint32 diff); + void InitializeAI(); + void Reset(); + SmartScript* GetScript() { return &mScript; } + static int Permissible(const GameObject* g); + + bool GossipHello(Player* player); + bool GossipSelect(Player* player, uint32 sender, uint32 action); + 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); + void OnGameEvent(bool start, uint16 eventId); + void OnStateChanged(uint32 state, Unit* unit); + void EventInform(uint32 eventId); + + protected: + GameObject* const go; + SmartScript mScript; }; #endif diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 01a9b777358..103cde80f43 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -160,9 +160,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { case SMART_ACTION_TALK: { - if (!me) - break; - ObjectList* targets = GetTargets(e, unit); Creature* talker = me; Player* targetPlayer = NULL; @@ -185,6 +182,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u delete targets; } + if (!talker) + break; + mTalkerEntry = talker->GetEntry(); mLastTextID = e.action.talk.textGroupID; mTextTimer = e.action.talk.duration; @@ -789,7 +789,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsUnit((*itr))) continue; - (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell); + if (e.action.removeAura.spell == 0) + (*itr)->ToUnit()->RemoveAllAuras(); + else + (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell); + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u", (*itr)->GetGUIDLow(), e.action.removeAura.spell); } @@ -1539,8 +1543,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsSmart()) break; - float attackDistance = (float)e.action.setRangedMovement.distance; - float attackAngle = e.action.setRangedMovement.angle / 180.0f * M_PI; + float attackDistance = float(e.action.setRangedMovement.distance); + float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * M_PI; ObjectList* targets = GetTargets(e, unit); if (targets) @@ -2016,16 +2020,16 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e) if (!go) return; //store hostage as id1 - AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0); + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0); //store invoker as id2 - AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); //signal hostage - AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0); + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0); //when hostage raeched end point, give credit to invoker if (e.action.installTtemplate.param2) AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); else - AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); break; } case SMARTAI_TEMPLATE_BASIC: @@ -2119,12 +2123,20 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* case SMART_TARGET_INVOKER_PARTY: if (trigger) { - l->push_back(trigger); if (Player* player = trigger->ToPlayer()) + { if (Group* group = player->GetGroup()) + { for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) if (Player* member = groupRef->getSource()) l->push_back(member); + } + // We still add the player to the list if there is no group. If we do + // this even if there is a group (thus the else-check), it will add the + // same player to the list twice. We don't want that to happen. + else + l->push_back(trigger); + } } break; case SMART_TARGET_CREATURE_RANGE: @@ -2522,6 +2534,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui case SMART_EVENT_JUST_CREATED: case SMART_EVENT_GOSSIP_HELLO: case SMART_EVENT_FOLLOW_COMPLETED: + case SMART_EVENT_ON_SPELLCLICK: ProcessAction(e, unit, var0, var1, bvar, spell, gob); break; case SMART_EVENT_IS_BEHIND_TARGET: @@ -2759,6 +2772,20 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui ProcessAction(e, unit, var0, var1); break; } + case SMART_EVENT_GO_EVENT_INFORM: + { + if (e.event.eventInform.eventId != var0) + return; + ProcessAction(e, NULL, var0); + break; + } + case SMART_EVENT_ACTION_DONE: + { + if (e.event.doAction.eventId != var0) + return; + ProcessAction(e, unit, var0); + break; + } default: sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType()); break; @@ -2875,23 +2902,6 @@ void SmartScript::InstallEvents() } } -bool SmartScript::ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3) -{ - if (c == 0) - return true; - - if (!u || !u->ToPlayer()) - return false; - - Condition cond; - cond.ConditionType = ConditionTypes(uint32(c)); - cond.ConditionValue1 = uint32(v1); - cond.ConditionValue1 = uint32(v2); - cond.ConditionValue1 = uint32(v3); - ConditionSourceInfo srcInfo = ConditionSourceInfo(u->ToPlayer()); - return cond.Meets(srcInfo); -} - void SmartScript::OnUpdate(uint32 const diff) { if ((mScriptType == SMART_SCRIPT_TYPE_CREATURE || mScriptType == SMART_SCRIPT_TYPE_GAMEOBJECT) && !GetBaseObject()) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 5fb691c87f2..03d533e69e5 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -83,8 +83,6 @@ class SmartScript return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT; } - bool ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3); - void OnUpdate(const uint32 diff); void OnMoveInLineOfSight(Unit* who); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index a7149f37480..de766d2a7e1 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -475,64 +475,78 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; } case SMART_EVENT_TRANSPORT_ADDCREATURE: - { - if (e.event.transportAddCreature.creature && !IsCreatureValid(e, e.event.transportAddCreature.creature)) - return false; - break; - } + { + if (e.event.transportAddCreature.creature && !IsCreatureValid(e, e.event.transportAddCreature.creature)) + return false; + break; + } case SMART_EVENT_MOVEMENTINFORM: + { + if (e.event.movementInform.type > NULL_MOTION_TYPE) { - if (e.event.movementInform.type > NULL_MOTION_TYPE) - { - sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.movementInform.type); - return false; - } - break; + sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.movementInform.type); + return false; } + break; + } case SMART_EVENT_DATA_SET: - { - if (!IsMinMaxValid(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax)) - return false; - break; - } + { + if (!IsMinMaxValid(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax)) + return false; + break; + } case SMART_EVENT_AREATRIGGER_ONTRIGGER: - { - if (e.event.areatrigger.id && !IsAreaTriggerValid(e, e.event.areatrigger.id)) - return false; - break; - } + { + if (e.event.areatrigger.id && !IsAreaTriggerValid(e, e.event.areatrigger.id)) + return false; + break; + } case SMART_EVENT_TEXT_OVER: //if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group! break; case SMART_EVENT_LINK: + { + if (e.link && e.link == e.event_id) { - if (e.link && e.link == e.event_id) - { - sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); - return false; - } - break; + sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); + return false; } + break; + } case SMART_EVENT_DUMMY_EFFECT: + { if (!IsSpellValid(e, e.event.dummy.spell)) return false; if (e.event.dummy.effIndex > EFFECT_2) return false; break; + } case SMART_EVENT_IS_BEHIND_TARGET: + { if (!IsMinMaxValid(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax)) return false; break; + } case SMART_EVENT_GAME_EVENT_START: case SMART_EVENT_GAME_EVENT_END: + { + GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap(); + if (e.event.gameEvent.gameEventId >= events.size() || !events[e.event.gameEvent.gameEventId].isValid()) + return false; + break; + } + case SMART_EVENT_ACTION_DONE: + { + if (e.event.doAction.eventId > EVENT_CHARGE) { - GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap(); - if (e.event.gameEvent.gameEventId >= events.size() || !events[e.event.gameEvent.gameEventId].isValid()) - return false; - break; + sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid event id %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.doAction.eventId); + return false; } + break; + } case SMART_EVENT_GO_STATE_CHANGED: + case SMART_EVENT_GO_EVENT_INFORM: case SMART_EVENT_TIMED_EVENT_TRIGGERED: case SMART_EVENT_INSTANCE_PLAYER_ENTER: case SMART_EVENT_TRANSPORT_RELOCATE: @@ -563,6 +577,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_GOSSIP_HELLO: case SMART_EVENT_JUST_CREATED: case SMART_EVENT_FOLLOW_COMPLETED: + case SMART_EVENT_ON_SPELLCLICK: break; default: sLog->outErrorDb("SmartAIMgr: Not handled event_type(%u), Entry %d SourceType %u Event %u Action %u, skipped.", e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -709,7 +724,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; break; case SMART_ACTION_REMOVEAURASFROMSPELL: - if (!IsSpellValid(e, e.action.removeAura.spell)) + if (e.action.removeAura.spell != 0 && !IsSpellValid(e, e.action.removeAura.spell)) return false; break; case SMART_ACTION_RANDOM_PHASE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index e6c5eb727d7..155f27d0fe7 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -22,7 +22,6 @@ #include "Creature.h" #include "CreatureAI.h" #include "Unit.h" -#include "ConditionMgr.h" #include "Spell.h" #include "DB2Stores.h" @@ -83,80 +82,82 @@ const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] = enum SMART_EVENT { - SMART_EVENT_UPDATE_IC = 0, //1 // InitialMin, InitialMax, RepeatMin, RepeatMax - SMART_EVENT_UPDATE_OOC = 1, //1 // InitialMin, InitialMax, RepeatMin, RepeatMax - SMART_EVENT_HEALT_PCT = 2, //1 // HPMin%, HPMax%, RepeatMin, RepeatMax - SMART_EVENT_MANA_PCT = 3, //1 // ManaMin%, ManaMax%, RepeatMin, RepeatMax - SMART_EVENT_AGGRO = 4, //1 // NONE - SMART_EVENT_KILL = 5, //1 // CooldownMin0, CooldownMax1, playerOnly2, else creature entry3 - SMART_EVENT_DEATH = 6, //1 // NONE - SMART_EVENT_EVADE = 7, //1 // NONE - SMART_EVENT_SPELLHIT = 8, //1 // SpellID, School, CooldownMin, CooldownMax - SMART_EVENT_RANGE = 9, //1 // MinDist, MaxDist, RepeatMin, RepeatMax - SMART_EVENT_OOC_LOS = 10, //1 // NoHostile, MaxRnage, CooldownMin, CooldownMax - SMART_EVENT_RESPAWN = 11, //1 // type, MapId, ZoneId - SMART_EVENT_TARGET_HEALTH_PCT = 12, //1 // HPMin%, HPMax%, RepeatMin, RepeatMax - SMART_EVENT_TARGET_CASTING = 13, //1 // RepeatMin, RepeatMax - SMART_EVENT_FRIENDLY_HEALTH = 14, //1 // HPDeficit, Radius, RepeatMin, RepeatMax - SMART_EVENT_FRIENDLY_IS_CC = 15, //1 // Radius, RepeatMin, RepeatMax - SMART_EVENT_FRIENDLY_MISSING_BUFF = 16, //1 // SpellId, Radius, RepeatMin, RepeatMax - SMART_EVENT_SUMMONED_UNIT = 17, //1 // CreatureId(0 all), CooldownMin, CooldownMax - SMART_EVENT_TARGET_MANA_PCT = 18, //1 // ManaMin%, ManaMax%, RepeatMin, RepeatMax - SMART_EVENT_ACCEPTED_QUEST = 19, //1 // QuestID(0any) - SMART_EVENT_REWARD_QUEST = 20, //1 // QuestID(0any) - SMART_EVENT_REACHED_HOME = 21, //1 // NONE - SMART_EVENT_RECEIVE_EMOTE = 22, //1 // EmoteId, CooldownMin, CooldownMax, condition, val1, val2, val3 - SMART_EVENT_HAS_AURA = 23, //1 // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax - SMART_EVENT_TARGET_BUFFED = 24, //1 // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax - SMART_EVENT_RESET = 25, //1 // Called after combat, when the creature respawn and spawn. - - SMART_EVENT_IC_LOS = 26, //1 // NoHostile, MaxRnage, CooldownMin, CooldownMax - SMART_EVENT_PASSENGER_BOARDED = 27, //1 // CooldownMin, CooldownMax - SMART_EVENT_PASSENGER_REMOVED = 28, //1 // CooldownMin, CooldownMax - SMART_EVENT_CHARMED = 29, //1 // NONE - SMART_EVENT_CHARMED_TARGET = 30, //1 // NONE - SMART_EVENT_SPELLHIT_TARGET = 31, //1 // SpellID, School, CooldownMin, CooldownMax - SMART_EVENT_DAMAGED = 32, //1 // MinDmg, MaxDmg, CooldownMin, CooldownMax - SMART_EVENT_DAMAGED_TARGET = 33, //1 // MinDmg, MaxDmg, CooldownMin, CooldownMax - SMART_EVENT_MOVEMENTINFORM = 34, //1 // MovementType(any), PointID - SMART_EVENT_SUMMON_DESPAWNED = 35, //1 // Entry, CooldownMin, CooldownMax - SMART_EVENT_CORPSE_REMOVED = 36, //1 // NONE - SMART_EVENT_AI_INIT = 37, //1 // NONE - SMART_EVENT_DATA_SET = 38, //1 // Id, Value, CooldownMin, CooldownMax - SMART_EVENT_WAYPOINT_START = 39, //1 // PointId(0any), pathID(0any) - SMART_EVENT_WAYPOINT_REACHED = 40, //1 // PointId(0any), pathID(0any) - SMART_EVENT_TRANSPORT_ADDPLAYER = 41, //1 // NONE - SMART_EVENT_TRANSPORT_ADDCREATURE = 42, //1 // Entry (0 any) - SMART_EVENT_TRANSPORT_REMOVE_PLAYER = 43, //1 // NONE - SMART_EVENT_TRANSPORT_RELOCATE = 44, //1 // PointId - SMART_EVENT_INSTANCE_PLAYER_ENTER = 45, //1 // Team (0 any), CooldownMin, CooldownMax - SMART_EVENT_AREATRIGGER_ONTRIGGER = 46, //1 // TriggerId(0 any) - SMART_EVENT_QUEST_ACCEPTED = 47, //1 // none - SMART_EVENT_QUEST_OBJ_COPLETETION = 48, //1 // none - SMART_EVENT_QUEST_COMPLETION = 49, //1 // none - SMART_EVENT_QUEST_REWARDED = 50, //1 // none - SMART_EVENT_QUEST_FAIL = 51, //1 // none - SMART_EVENT_TEXT_OVER = 52, //1 // GroupId from creature_text, creature entry who talks (0 any) - SMART_EVENT_RECEIVE_HEAL = 53, //1 // MinHeal, MaxHeal, CooldownMin, CooldownMax - SMART_EVENT_JUST_SUMMONED = 54, //1 // none - SMART_EVENT_WAYPOINT_PAUSED = 55, //1 // PointId(0any), pathID(0any) - SMART_EVENT_WAYPOINT_RESUMED = 56, //1 // PointId(0any), pathID(0any) - SMART_EVENT_WAYPOINT_STOPPED = 57, //1 // PointId(0any), pathID(0any) - SMART_EVENT_WAYPOINT_ENDED = 58, //1 // PointId(0any), pathID(0any) - SMART_EVENT_TIMED_EVENT_TRIGGERED = 59, //1 // id - SMART_EVENT_UPDATE = 60, //1 // InitialMin, InitialMax, RepeatMin, RepeatMax - SMART_EVENT_LINK = 61, //1 // INTERNAL USAGE, no params, used to link together multiple events, does not use any extra resources to iterate event lists needlessly - SMART_EVENT_GOSSIP_SELECT = 62, //1 // menuID, actionID - SMART_EVENT_JUST_CREATED = 63, //1 // none - SMART_EVENT_GOSSIP_HELLO = 64, //1 // none - SMART_EVENT_FOLLOW_COMPLETED = 65, //1 // none - SMART_EVENT_DUMMY_EFFECT = 66, //1 // spellId, effectIndex - SMART_EVENT_IS_BEHIND_TARGET = 67, //1 // cooldownMin, CooldownMax - SMART_EVENT_GAME_EVENT_START = 68, //1 // game_event.Entry - SMART_EVENT_GAME_EVENT_END = 69, //1 // game_event.Entry - SMART_EVENT_GO_STATE_CHANGED = 70, // go state - - SMART_EVENT_END = 71, + SMART_EVENT_UPDATE_IC = 0, // InitialMin, InitialMax, RepeatMin, RepeatMax + SMART_EVENT_UPDATE_OOC = 1, // InitialMin, InitialMax, RepeatMin, RepeatMax + SMART_EVENT_HEALT_PCT = 2, // HPMin%, HPMax%, RepeatMin, RepeatMax + SMART_EVENT_MANA_PCT = 3, // ManaMin%, ManaMax%, RepeatMin, RepeatMax + SMART_EVENT_AGGRO = 4, // NONE + SMART_EVENT_KILL = 5, // CooldownMin0, CooldownMax1, playerOnly2, else creature entry3 + SMART_EVENT_DEATH = 6, // NONE + SMART_EVENT_EVADE = 7, // NONE + SMART_EVENT_SPELLHIT = 8, // SpellID, School, CooldownMin, CooldownMax + SMART_EVENT_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax + SMART_EVENT_OOC_LOS = 10, // NoHostile, MaxRnage, CooldownMin, CooldownMax + SMART_EVENT_RESPAWN = 11, // type, MapId, ZoneId + SMART_EVENT_TARGET_HEALTH_PCT = 12, // HPMin%, HPMax%, RepeatMin, RepeatMax + SMART_EVENT_TARGET_CASTING = 13, // RepeatMin, RepeatMax + SMART_EVENT_FRIENDLY_HEALTH = 14, // HPDeficit, Radius, RepeatMin, RepeatMax + SMART_EVENT_FRIENDLY_IS_CC = 15, // Radius, RepeatMin, RepeatMax + SMART_EVENT_FRIENDLY_MISSING_BUFF = 16, // SpellId, Radius, RepeatMin, RepeatMax + SMART_EVENT_SUMMONED_UNIT = 17, // CreatureId(0 all), CooldownMin, CooldownMax + SMART_EVENT_TARGET_MANA_PCT = 18, // ManaMin%, ManaMax%, RepeatMin, RepeatMax + SMART_EVENT_ACCEPTED_QUEST = 19, // QuestID(0any) + SMART_EVENT_REWARD_QUEST = 20, // QuestID(0any) + SMART_EVENT_REACHED_HOME = 21, // NONE + SMART_EVENT_RECEIVE_EMOTE = 22, // EmoteId, CooldownMin, CooldownMax, condition, val1, val2, val3 + SMART_EVENT_HAS_AURA = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax + SMART_EVENT_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax + SMART_EVENT_RESET = 25, // Called after combat, when the creature respawn and spawn. + SMART_EVENT_IC_LOS = 26, // NoHostile, MaxRnage, CooldownMin, CooldownMax + SMART_EVENT_PASSENGER_BOARDED = 27, // CooldownMin, CooldownMax + SMART_EVENT_PASSENGER_REMOVED = 28, // CooldownMin, CooldownMax + SMART_EVENT_CHARMED = 29, // NONE + SMART_EVENT_CHARMED_TARGET = 30, // NONE + SMART_EVENT_SPELLHIT_TARGET = 31, // SpellID, School, CooldownMin, CooldownMax + SMART_EVENT_DAMAGED = 32, // MinDmg, MaxDmg, CooldownMin, CooldownMax + SMART_EVENT_DAMAGED_TARGET = 33, // MinDmg, MaxDmg, CooldownMin, CooldownMax + SMART_EVENT_MOVEMENTINFORM = 34, // MovementType(any), PointID + SMART_EVENT_SUMMON_DESPAWNED = 35, // Entry, CooldownMin, CooldownMax + SMART_EVENT_CORPSE_REMOVED = 36, // NONE + SMART_EVENT_AI_INIT = 37, // NONE + SMART_EVENT_DATA_SET = 38, // Id, Value, CooldownMin, CooldownMax + SMART_EVENT_WAYPOINT_START = 39, // PointId(0any), pathID(0any) + SMART_EVENT_WAYPOINT_REACHED = 40, // PointId(0any), pathID(0any) + SMART_EVENT_TRANSPORT_ADDPLAYER = 41, // NONE + SMART_EVENT_TRANSPORT_ADDCREATURE = 42, // Entry (0 any) + SMART_EVENT_TRANSPORT_REMOVE_PLAYER = 43, // NONE + SMART_EVENT_TRANSPORT_RELOCATE = 44, // PointId + SMART_EVENT_INSTANCE_PLAYER_ENTER = 45, // Team (0 any), CooldownMin, CooldownMax + SMART_EVENT_AREATRIGGER_ONTRIGGER = 46, // TriggerId(0 any) + SMART_EVENT_QUEST_ACCEPTED = 47, // none + SMART_EVENT_QUEST_OBJ_COPLETETION = 48, // none + SMART_EVENT_QUEST_COMPLETION = 49, // none + SMART_EVENT_QUEST_REWARDED = 50, // none + SMART_EVENT_QUEST_FAIL = 51, // none + SMART_EVENT_TEXT_OVER = 52, // GroupId from creature_text, creature entry who talks (0 any) + SMART_EVENT_RECEIVE_HEAL = 53, // MinHeal, MaxHeal, CooldownMin, CooldownMax + SMART_EVENT_JUST_SUMMONED = 54, // none + SMART_EVENT_WAYPOINT_PAUSED = 55, // PointId(0any), pathID(0any) + SMART_EVENT_WAYPOINT_RESUMED = 56, // PointId(0any), pathID(0any) + SMART_EVENT_WAYPOINT_STOPPED = 57, // PointId(0any), pathID(0any) + SMART_EVENT_WAYPOINT_ENDED = 58, // PointId(0any), pathID(0any) + SMART_EVENT_TIMED_EVENT_TRIGGERED = 59, // id + SMART_EVENT_UPDATE = 60, // InitialMin, InitialMax, RepeatMin, RepeatMax + SMART_EVENT_LINK = 61, // INTERNAL USAGE, no params, used to link together multiple events, does not use any extra resources to iterate event lists needlessly + SMART_EVENT_GOSSIP_SELECT = 62, // menuID, actionID + SMART_EVENT_JUST_CREATED = 63, // none + SMART_EVENT_GOSSIP_HELLO = 64, // none + SMART_EVENT_FOLLOW_COMPLETED = 65, // none + SMART_EVENT_DUMMY_EFFECT = 66, // spellId, effectIndex + SMART_EVENT_IS_BEHIND_TARGET = 67, // cooldownMin, CooldownMax + SMART_EVENT_GAME_EVENT_START = 68, // game_event.Entry + SMART_EVENT_GAME_EVENT_END = 69, // game_event.Entry + SMART_EVENT_GO_STATE_CHANGED = 70, // go state + SMART_EVENT_GO_EVENT_INFORM = 71, // eventId + SMART_EVENT_ACTION_DONE = 72, // eventId (SharedDefines.EventId) + SMART_EVENT_ON_SPELLCLICK = 73, // clicker (unit) + + SMART_EVENT_END = 74, }; struct SmartEvent @@ -353,6 +354,16 @@ struct SmartEvent struct { + uint32 eventId; + } eventInform; + + struct + { + uint32 eventId; + } doAction; + + struct + { uint32 param1; uint32 param2; uint32 param3; @@ -399,7 +410,7 @@ enum SMART_ACTION SMART_ACTION_FLEE_FOR_ASSIST = 25, // With Emote SMART_ACTION_CALL_GROUPEVENTHAPPENS = 26, // QuestID SMART_ACTION_CALL_CASTEDCREATUREORGO = 27, // CreatureId, SpellId - SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid + SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid, 0 removes all auras SMART_ACTION_FOLLOW = 29, // Distance (0 = default), Angle (0 = default), EndCreatureEntry, credit, creditType (0monsterkill, 1event) SMART_ACTION_RANDOM_PHASE = 30, // PhaseId1, PhaseId2, PhaseId3... SMART_ACTION_RANDOM_PHASE_RANGE = 31, // PhaseMin, PhaseMax @@ -847,9 +858,9 @@ struct SmartAction struct { - bool withDelayed; + uint32 withDelayed; uint32 spell_id; - bool withInstant; + uint32 withInstant; } interruptSpellCasting; struct @@ -875,7 +886,7 @@ struct SmartAction struct { - uint8 pointId; + uint32 pointId; } MoveToPos; struct @@ -896,10 +907,13 @@ struct SmartAction struct { - float distance; - float angle; + uint32 distance; + uint32 angle; } setRangedMovement; + //! Note for any new future actions + //! All parameters must have type uint32 + struct { uint32 param1; @@ -1167,7 +1181,9 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] = {SMART_EVENT_GAME_EVENT_START, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GAME_EVENT_END, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GO_STATE_CHANGED, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, - + {SMART_EVENT_GO_EVENT_INFORM, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, + {SMART_EVENT_ACTION_DONE, SMART_SCRIPT_TYPE_MASK_CREATURE }, + {SMART_EVENT_ON_SPELLCLICK, SMART_SCRIPT_TYPE_MASK_CREATURE }, }; enum SmartEventFlags @@ -1380,26 +1396,6 @@ class SmartAIMgr } return true; } - /*inline bool IsConditionValid(SmartScriptHolder e, int32 t, int32 v1, int32 v2, int32 v3) - { - bool error = false; - if (t > 0 && v1 >= 0 && v2 >= 0 && v3 >= 0) - { - Condition cond; - cond.mConditionType = ConditionType(t); - cond.mConditionValue1 = uint32(v1); - cond.mConditionValue2 = uint32(v2); - cond.mConditionValue3 = uint32(v3); - if (!sConditionMgr->isConditionTypeValid(&cond)) - error = true; - } - if (error) - { - sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Condition, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); - return false; - } - return true; - }*/ bool IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry) { diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 21a2a75b470..252e120f0c9 100755 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -2207,7 +2207,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList() for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId) { - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); if (!criteria) continue; @@ -2238,7 +2237,6 @@ void AchievementGlobalMgr::LoadAchievementReferenceList() for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId) { - AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId); if (!achievement || !achievement->refAchievement) continue; @@ -2247,6 +2245,10 @@ void AchievementGlobalMgr::LoadAchievementReferenceList() ++count; } + // Once Bitten, Twice Shy (10 player) - Icecrown Citadel + if (AchievementEntry const* achievement = sAchievementStore.LookupEntry(4539)) + const_cast<AchievementEntry*>(achievement)->mapID = 631; // Correct map requirement (currently has Ulduar) + sLog->outString(">> Loaded %u achievement references in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); } diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index c964f47f495..1b666859749 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -151,11 +151,11 @@ void ArenaTeamMgr::DistributeArenaPoints() if (ArenaTeam* at = teamItr->second) at->UpdateArenaPointsHelper(PlayerPoints); + /* SQLTransaction trans = CharacterDatabase.BeginTransaction(); // Cycle that gives points to all players - /* - PreparedStatement* stmt; + PreparedStatement* stmt; for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr) { @@ -170,9 +170,9 @@ void ArenaTeamMgr::DistributeArenaPoints() trans->Append(stmt); } } - */ CharacterDatabase.CommitTransaction(trans); + */ PlayerPoints.clear(); diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 54c84f2e6d4..ebcf5495a55 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -850,12 +850,8 @@ void Battleground::EndBattleground(uint32 winner) if (team == winner) { // update achievement BEFORE personal rating update - if (ArenaTeamMember* member = winner_arena_team->GetMember(player->GetGUID())) - { - uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot()); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, - rating ? rating : 1); - } + uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot()); + player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change); } @@ -1776,15 +1772,19 @@ void Battleground::HandleTriggerBuff(uint64 go_guid) SpawnBGObject(index, BUFF_RESPAWN_TIME); } -void Battleground::HandleKillPlayer(Player* player, Player* killer) +void Battleground::HandleKillPlayer(Player* victim, Player* killer) { // Keep in mind that for arena this will have to be changed a bit // Add +1 deaths - UpdatePlayerScore(player, SCORE_DEATHS, 1); + UpdatePlayerScore(victim, SCORE_DEATHS, 1); // Add +1 kills to group and +1 killing_blows to killer if (killer) { + // Don't reward credit for killing ourselves, like fall damage of hellfire (warlock) + if (killer == victim) + return; + UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1); UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1); @@ -1794,7 +1794,7 @@ void Battleground::HandleKillPlayer(Player* player, Player* killer) if (!creditedPlayer || creditedPlayer == killer) continue; - if (creditedPlayer->GetTeam() == killer->GetTeam() && creditedPlayer->IsAtGroupRewardDistance(player)) + if (creditedPlayer->GetTeam() == killer->GetTeam() && creditedPlayer->IsAtGroupRewardDistance(victim)) UpdatePlayerScore(creditedPlayer, SCORE_HONORABLE_KILLS, 1); } } @@ -1802,8 +1802,8 @@ void Battleground::HandleKillPlayer(Player* player, Player* killer) if (!isArena()) { // To be able to remove insignia -- ONLY IN Battlegrounds - player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - RewardXPAtKill(killer, player); + victim->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + RewardXPAtKill(killer, victim); } } diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index b7079fb00e0..0d4fc458faa 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -55,7 +55,7 @@ BattlegroundMgr::BattlegroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTe { for (uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++) m_Battlegrounds[i].clear(); - m_NextRatingDiscardUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); + m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER); m_Testing=false; } @@ -143,10 +143,10 @@ void BattlegroundMgr::Update(uint32 diff) } // if rating difference counts, maybe force-update queues - if (sWorld->getIntConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER)) + if (sWorld->getIntConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER)) { // it's time to force update - if (m_NextRatingDiscardUpdate < diff) + if (m_NextRatedArenaUpdate < diff) { // forced update for rated arenas (scan all, but skipped non rated) sLog->outDebug(LOG_FILTER_BATTLEGROUND, "BattlegroundMgr: UPDATING ARENA QUEUES"); @@ -156,10 +156,10 @@ void BattlegroundMgr::Update(uint32 diff) BATTLEGROUND_AA, BattlegroundBracketId(bracket), BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId(qtype)), true, 0); - m_NextRatingDiscardUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); + m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER); } else - m_NextRatingDiscardUpdate -= diff; + m_NextRatedArenaUpdate -= diff; } if (sWorld->getBoolConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS)) { @@ -771,8 +771,9 @@ void BattlegroundMgr::CreateInitialBattlegrounds() continue; } - selectionWeight = fields[10].GetUInt8(); data.StartMaxDist = fields[9].GetFloat(); + + selectionWeight = fields[10].GetUInt8(); data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString()); //data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()]; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index dd502409178..4edad4da742 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -141,7 +141,7 @@ class BattlegroundMgr BattlegroundSelectionWeightMap m_BGSelectionWeights; std::vector<uint64> m_QueueUpdateScheduler; std::set<uint32> m_ClientBattlegroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_BRACKETS]; //the instanceids just visible for the client - uint32 m_NextRatingDiscardUpdate; + uint32 m_NextRatedArenaUpdate; time_t m_NextAutoDistributionTime; uint32 m_AutoDistributionTimeChecker; bool m_ArenaTesting; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 39c6e00946a..bda1bdfa8d3 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -56,6 +56,8 @@ void BattlegroundSA::Reset() GateStatus[i] = BG_SA_GATE_OK; ShipsStarted = false; gateDestroyed = false; + _notEvenAScratch[BG_TEAM_ALLIANCE] = true; + _notEvenAScratch[BG_TEAM_HORDE] = true; Status = BG_SA_WARMUP; } @@ -553,13 +555,13 @@ void BattlegroundSA::EventPlayerDamagedGO(Player* /*player*/, GameObject* go, ui SendWarningToAll(LANG_BG_SA_IS_UNDER_ATTACK, go->GetGOInfo()->name.c_str()); } -void BattlegroundSA::HandleKillUnit(Creature* unit, Player* killer) +void BattlegroundSA::HandleKillUnit(Creature* creature, Player* killer) { - if (!unit) - return; - - if (unit->GetEntry() == NPC_DEMOLISHER_SA) + if (creature->GetEntry() == NPC_DEMOLISHER_SA) + { UpdatePlayerScore(killer, SCORE_DESTROYED_DEMOLISHER, 1); + _notEvenAScratch[Attackers] = false; + } } /* diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index c18806490f2..fd11cb2c5ea 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -456,7 +456,7 @@ class BattlegroundSA : public Battleground /// Called when a player deal damage to building (door) virtual void EventPlayerDamagedGO(Player* player, GameObject* go, uint32 eventType); /// Called when a player kill a unit in bg - virtual void HandleKillUnit(Creature* unit, Player* killer); + virtual void HandleKillUnit(Creature* creature, Player* killer); /// Return the nearest graveyard where player can respawn virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); /// Called when a player click on flag (graveyard flag) @@ -531,9 +531,12 @@ class BattlegroundSA : public Battleground /// Update score board void UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor = true); - // Achievement Defense of the Ancients + // Achievement: Defense of the Ancients bool gateDestroyed; + // Achievement: Not Even a Scratch + bool notEvenAScratch(uint32 team) const { return _notEvenAScratch[GetTeamIndexByTeamId(team)]; } + /// Id of attacker team TeamId Attackers; @@ -615,5 +618,7 @@ class BattlegroundSA : public Battleground bool InitSecondRound; std::map<uint32/*id*/, uint32/*timer*/> DemoliserRespawnList; + // Achievement: Not Even a Scratch + bool _notEvenAScratch[BG_TEAMS_COUNT]; }; #endif diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index cc64a8e22dd..7a146e89505 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -92,40 +92,6 @@ ChatCommand* ChatHandler::getCommandTable() { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand castCommandTable[] = - { - { "back", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastBackCommand>, "", NULL }, - { "dist", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastDistCommand>, "", NULL }, - { "self", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastSelfCommand>, "", NULL }, - { "target", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastTargetCommand>, "", NULL }, - { "dest", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastDestCommand>, "", NULL }, - { "", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand characterDeletedCommandTable[] = - { - { "delete", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleCharacterDeletedDeleteCommand>, "", NULL }, - { "list", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleCharacterDeletedListCommand>, "", NULL }, - { "restore", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleCharacterDeletedRestoreCommand>, "", NULL }, - { "old", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleCharacterDeletedOldCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand characterCommandTable[] = - { - { "customize", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterCustomizeCommand>, "", NULL }, - { "changefaction", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterChangeFactionCommand>, "", NULL }, - { "changerace", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterChangeRaceCommand>, "", NULL }, - { "deleted", SEC_GAMEMASTER, true, NULL, "", characterDeletedCommandTable}, - { "erase", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleCharacterEraseCommand>, "", NULL }, - { "level", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleCharacterLevelCommand>, "", NULL }, - { "rename", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterRenameCommand>, "", NULL }, - { "reputation", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterReputationCommand>, "", NULL }, - { "titles", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterTitlesCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand channelSetCommandTable[] = { { "ownership", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleChannelSetOwnership>, "", NULL }, @@ -156,24 +122,6 @@ ChatCommand* ChatHandler::getCommandTable() { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand instanceCommandTable[] = - { - { "listbinds", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleInstanceListBindsCommand>, "", NULL }, - { "unbind", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleInstanceUnbindCommand>, "", NULL }, - { "stats", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleInstanceStatsCommand>, "", NULL }, - { "savedata", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleInstanceSaveDataCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand listCommandTable[] = - { - { "creature", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleListCreatureCommand>, "", NULL }, - { "item", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleListItemCommand>, "", NULL }, - { "object", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleListObjectCommand>, "", NULL }, - { "auras", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleListAurasCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand lookupPlayerCommandTable[] = { { "ip", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleLookupPlayerIpCommand>, "", NULL }, @@ -217,18 +165,6 @@ ChatCommand* ChatHandler::getCommandTable() { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand resetCommandTable[] = - { - { "achievements", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetAchievementsCommand>, "", NULL }, - { "honor", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetHonorCommand>, "", NULL }, - { "level", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetLevelCommand>, "", NULL }, - { "spells", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetSpellsCommand>, "", NULL }, - { "stats", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetStatsCommand>, "", NULL }, - { "talents", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetTalentsCommand>, "", NULL }, - { "all", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetAllCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand sendCommandTable[] = { { "items", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleSendItemsCommand>, "", NULL }, @@ -238,60 +174,6 @@ ChatCommand* ChatHandler::getCommandTable() { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand serverIdleRestartCommandTable[] = - { - { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, - { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerIdleRestartCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand serverIdleShutdownCommandTable[] = - { - { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, - { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerIdleShutDownCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand serverRestartCommandTable[] = - { - { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, - { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerRestartCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand serverShutdownCommandTable[] = - { - { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL }, - { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand serverSetCommandTable[] = - { - { "difftime", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerSetDiffTimeCommand>, "", NULL }, - { "loglevel", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerSetLogLevelCommand>, "", NULL }, - { "logfilelevel", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerSetLogFileLevelCommand>, "", NULL }, - { "motd", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerSetMotdCommand>, "", NULL }, - { "closed", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerSetClosedCommand>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - - static ChatCommand serverCommandTable[] = - { - { "corpses", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleServerCorpsesCommand>, "", NULL }, - { "exit", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerExitCommand>, "", NULL }, - { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable }, - { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverIdleShutdownCommandTable }, - { "info", SEC_PLAYER, true, OldHandler<&ChatHandler::HandleServerInfoCommand>, "", NULL }, - { "motd", SEC_PLAYER, true, OldHandler<&ChatHandler::HandleServerMotdCommand>, "", NULL }, - { "plimit", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerPLimitCommand>, "", NULL }, - { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable }, - { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable }, - { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable }, - { "togglequerylog", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerToggleQueryLogging>, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand unbanCommandTable[] = { { "account", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleUnBanAccountCommand>, "", NULL }, @@ -331,16 +213,10 @@ ChatCommand* ChatHandler::getCommandTable() static ChatCommand commandTable[] = { - { "character", SEC_GAMEMASTER, true, NULL, "", characterCommandTable}, - { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable }, { "lookup", SEC_ADMINISTRATOR, true, NULL, "", lookupCommandTable }, { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable }, { "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable }, { "group", SEC_ADMINISTRATOR, false, NULL, "", groupCommandTable }, - { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable }, - { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable }, - { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable }, - { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable }, { "channel", SEC_ADMINISTRATOR, true, NULL, "", channelCommandTable }, diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index e88914a2daf..bbe138b923d 100755 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -119,10 +119,13 @@ class ChatHandler GameObject* GetNearbyGameObject(); GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid, uint32 entry); - bool HasSentErrorMessage() const { return sentErrorMessage;} - void SetSentErrorMessage(bool val){ sentErrorMessage = val;}; - static bool LoadCommandTable() { return load_command_table;} - static void SetLoadCommandTable(bool val){ load_command_table = val;}; + bool HasSentErrorMessage() const { return sentErrorMessage; } + void SetSentErrorMessage(bool val){ sentErrorMessage = val; } + static bool LoadCommandTable() { return load_command_table; } + static void SetLoadCommandTable(bool val) { load_command_table = val; } + + // cs_character + void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel); protected: explicit ChatHandler() : m_session(NULL) {} // for CLI subclass @@ -147,26 +150,6 @@ class ChatHandler bool HandleBanListCharacterCommand(const char* args); bool HandleBanListIPCommand(const char* args); - bool HandleCastCommand(const char *args); - bool HandleCastBackCommand(const char *args); - bool HandleCastDistCommand(const char *args); - bool HandleCastSelfCommand(const char *args); - bool HandleCastTargetCommand(const char *args); - bool HandleCastDestCommand(const char *args); - - bool HandleCharacterCustomizeCommand(const char* args); - bool HandleCharacterChangeFactionCommand(const char* args); - bool HandleCharacterChangeRaceCommand(const char * args); - bool HandleCharacterDeletedDeleteCommand(const char* args); - bool HandleCharacterDeletedListCommand(const char* args); - bool HandleCharacterDeletedRestoreCommand(const char* args); - bool HandleCharacterDeletedOldCommand(const char* args); - bool HandleCharacterEraseCommand(const char* args); - bool HandleCharacterLevelCommand(const char* args); - bool HandleCharacterRenameCommand(const char* args); - bool HandleCharacterReputationCommand(const char* args); - bool HandleCharacterTitlesCommand(const char* args); - bool HandleChannelSetOwnership(const char *args); bool HandlePossessCommand(const char* args); @@ -180,16 +163,6 @@ class ChatHandler bool HandleGuildRankCommand(const char* args); bool HandleGuildDeleteCommand(const char* args); - bool HandleInstanceListBindsCommand(const char* args); - bool HandleInstanceUnbindCommand(const char* args); - bool HandleInstanceStatsCommand(const char* args); - bool HandleInstanceSaveDataCommand(const char * args); - - bool HandleListAurasCommand(const char * args); - bool HandleListCreatureCommand(const char* args); - bool HandleListItemCommand(const char* args); - bool HandleListObjectCommand(const char* args); - bool HandleLookupAreaCommand(const char* args); bool HandleLookupCreatureCommand(const char* args); bool HandleLookupEventCommand(const char* args); @@ -211,37 +184,11 @@ class ChatHandler bool HandlePDumpLoadCommand(const char *args); bool HandlePDumpWriteCommand(const char *args); - bool HandleResetAchievementsCommand(const char * args); - bool HandleResetAllCommand(const char * args); - bool HandleResetHonorCommand(const char * args); - bool HandleResetLevelCommand(const char * args); - bool HandleResetSpellsCommand(const char* args); - bool HandleResetStatsCommand(const char * args); - bool HandleResetTalentsCommand(const char* args); - bool HandleSendItemsCommand(const char* args); bool HandleSendMailCommand(const char* args); bool HandleSendMessageCommand(const char * args); bool HandleSendMoneyCommand(const char* args); - bool HandleServerCorpsesCommand(const char* args); - bool HandleServerExitCommand(const char* args); - bool HandleServerIdleRestartCommand(const char* args); - bool HandleServerIdleShutDownCommand(const char* args); - bool HandleServerInfoCommand(const char* args); - bool HandleServerMotdCommand(const char* args); - bool HandleServerPLimitCommand(const char* args); - bool HandleServerRestartCommand(const char* args); - bool HandleServerSetLogLevelCommand(const char* args); - bool HandleServerSetMotdCommand(const char* args); - bool HandleServerShutDownCommand(const char* args); - bool HandleServerShutDownCancelCommand(const char* args); - bool HandleServerSetClosedCommand(const char* args); - bool HandleServerToggleQueryLogging(const char* args); - - bool HandleServerSetLogFileLevelCommand(const char* args); - bool HandleServerSetDiffTimeCommand(const char* args); - bool HandleUnBanAccountCommand(const char* args); bool HandleUnBanAccountByCharCommand(const char* args); bool HandleUnBanCharacterCommand(const char* args); @@ -354,25 +301,8 @@ class ChatHandler bool HandleBanHelper(BanMode mode, char const* args); bool HandleBanInfoHelper(uint32 accountid, char const* accountname); bool HandleUnBanHelper(BanMode mode, char const* args); - void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel); void HandleLearnSkillRecipesHelper(Player* player, uint32 skill_id); - // Stores informations about a deleted character - struct DeletedInfo - { - uint32 lowguid; ///< the low GUID from the character - std::string name; ///< the character name - uint32 accountId; ///< the account id - std::string accountName; ///< the account name - time_t deleteDate; ///< the date at which the character has been deleted - }; - - typedef std::list<DeletedInfo> DeletedInfoList; - bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString = ""); - std::string GenerateDeletedCharacterGUIDsWhereStr(DeletedInfoList::const_iterator& itr, DeletedInfoList::const_iterator const& itr_end); - void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList); - void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo); - private: bool _HandleGMTicketResponseAppendCommand(const char* args, bool newLine); diff --git a/src/server/game/Chat/Commands/Level0.cpp b/src/server/game/Chat/Commands/Level0.cpp index b2ac090c313..b05ba9b4194 100755 --- a/src/server/game/Chat/Commands/Level0.cpp +++ b/src/server/game/Chat/Commands/Level0.cpp @@ -80,29 +80,6 @@ bool ChatHandler::HandleStartCommand(const char* /*args*/) return true; } -bool ChatHandler::HandleServerInfoCommand(const char* /*args*/) -{ - uint32 playersNum = sWorld->GetPlayerCount(); - uint32 maxPlayersNum = sWorld->GetMaxPlayerCount(); - uint32 activeClientsNum = sWorld->GetActiveSessionCount(); - uint32 queuedClientsNum = sWorld->GetQueuedSessionCount(); - uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount(); - uint32 maxQueuedClientsNum = sWorld->GetMaxQueuedSessionCount(); - std::string uptime = secsToTimeString(sWorld->GetUptime()); - uint32 updateTime = sWorld->GetUpdateTime(); - - SendSysMessage(_FULLVERSION); - PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum); - PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); - PSendSysMessage(LANG_UPTIME, uptime.c_str()); - PSendSysMessage(LANG_UPDATE_DIFF, updateTime); - //! Can't use sWorld->ShutdownMsg here in case of console command - if (sWorld->IsShuttingDown()) - PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str()); - - return true; -} - bool ChatHandler::HandleDismountCommand(const char* /*args*/) { Player* player = m_session->GetPlayer(); @@ -150,10 +127,3 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/) return true; } -/// Display the 'Message of the day' for the realm -bool ChatHandler::HandleServerMotdCommand(const char* /*args*/) -{ - PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd()); - return true; -} - diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp index 4359c5ff20c..b1e13b7d92d 100755 --- a/src/server/game/Chat/Commands/Level2.cpp +++ b/src/server/game/Chat/Commands/Level2.cpp @@ -458,190 +458,6 @@ bool ChatHandler::HandlePInfoCommand(const char* args) return true; } -//rename characters -bool ChatHandler::HandleCharacterRenameCommand(const char* args) -{ - Player* target; - uint64 targetGuid; - std::string targetName; - if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - if (target) - { - // check online security - if (HasLowerSecurity(target, 0)) - return false; - - PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str()); - target->SetAtLoginFlag(AT_LOGIN_RENAME); - } - else - { - // check offline security - if (HasLowerSecurity(NULL, targetGuid)) - return false; - - std::string oldNameLink = playerLink(targetName); - - PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - - stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); - stmt->setUInt32(1, GUID_LOPART(targetGuid)); - - CharacterDatabase.Execute(stmt); - } - - return true; -} - -// customize characters -bool ChatHandler::HandleCharacterCustomizeCommand(const char* args) -{ - Player* target; - uint64 targetGuid; - std::string targetName; - if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - - stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE)); - - if (target) - { - PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); - target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); - - stmt->setUInt32(1, target->GetGUIDLow()); - } - else - { - std::string oldNameLink = playerLink(targetName); - - stmt->setUInt32(1, GUID_LOPART(targetGuid)); - - PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); - } - - CharacterDatabase.Execute(stmt); - - return true; -} - -bool ChatHandler::HandleCharacterChangeFactionCommand(const char* args) -{ - Player* target; - uint64 targetGuid; - std::string targetName; - - if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - - stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION)); - - if (target) - { - PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); - target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION); - - stmt->setUInt32(1, target->GetGUIDLow()); - } - else - { - std::string oldNameLink = playerLink(targetName); - - PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); - - stmt->setUInt32(1, GUID_LOPART(targetGuid)); - } - - CharacterDatabase.Execute(stmt); - - return true; -} - -bool ChatHandler::HandleCharacterChangeRaceCommand(const char * args) -{ - Player* target; - uint64 targetGuid; - std::string targetName; - if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - - stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE)); - - if (target) - { - // TODO : add text into database - PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str()); - target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE); - - stmt->setUInt32(1, target->GetGUIDLow()); - } - else - { - std::string oldNameLink = playerLink(targetName); - - // TODO : add text into database - PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid)); - - stmt->setUInt32(1, GUID_LOPART(targetGuid)); - } - - CharacterDatabase.Execute(stmt); - - return true; -} - -bool ChatHandler::HandleCharacterReputationCommand(const char* args) -{ - Player* target; - if (!extractPlayerTarget((char*)args, &target)) - return false; - - LocaleConstant loc = GetSessionDbcLocale(); - - FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList(); - for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr) - { - const FactionState& faction = itr->second; - FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); - char const* factionName = factionEntry ? factionEntry->name : "#Not found#"; - ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); - std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]); - std::ostringstream ss; - if (m_session) - ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r"; - else - ss << faction.ID << " - " << factionName << ' ' << localeNames[loc]; - - ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; - - if (faction.Flags & FACTION_FLAG_VISIBLE) - ss << GetTrinityString(LANG_FACTION_VISIBLE); - if (faction.Flags & FACTION_FLAG_AT_WAR) - ss << GetTrinityString(LANG_FACTION_ATWAR); - if (faction.Flags & FACTION_FLAG_PEACE_FORCED) - ss << GetTrinityString(LANG_FACTION_PEACE_FORCED); - if (faction.Flags & FACTION_FLAG_HIDDEN) - ss << GetTrinityString(LANG_FACTION_HIDDEN); - if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED) - ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); - if (faction.Flags & FACTION_FLAG_INACTIVE) - ss << GetTrinityString(LANG_FACTION_INACTIVE); - - SendSysMessage(ss.str().c_str()); - } - return true; -} - bool ChatHandler::HandleLookupEventCommand(const char* args) { if (!*args) @@ -848,13 +664,6 @@ bool ChatHandler::LookupPlayerSearchCommand(PreparedQueryResult result, int32 li return true; } -/// Triggering corpses expire check in world -bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/) -{ - sObjectAccessor->RemoveOldCorpses(); - return true; -} - bool ChatHandler::HandleRepairitemsCommand(const char* args) { Player* target; @@ -1130,43 +939,3 @@ bool ChatHandler::HandleLookupTitleCommand(const char* args) SendSysMessage(LANG_COMMAND_NOTITLEFOUND); return true; } - -bool ChatHandler::HandleCharacterTitlesCommand(const char* args) -{ - if (!*args) - return false; - - Player* target; - if (!extractPlayerTarget((char*)args, &target)) - return false; - - LocaleConstant loc = GetSessionDbcLocale(); - char const* targetName = target->GetName(); - char const* knownStr = GetTrinityString(LANG_KNOWN); - - // Search in CharTitles.dbc - for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++) - { - CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); - if (titleInfo && target->HasTitle(titleInfo)) - { - std::string name = titleInfo->name; - if (name.empty()) - continue; - - char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index - ? GetTrinityString(LANG_ACTIVE) - : ""; - - char titleNameStr[80]; - snprintf(titleNameStr, 80, name.c_str(), targetName); - - // send title in "id (idx:idx) - [namedlink locale]" format - if (m_session) - PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr); - else - PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr); - } - } - return true; -} diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp index 2ae7e73b828..0386b8786b6 100755 --- a/src/server/game/Chat/Commands/Level3.cpp +++ b/src/server/game/Chat/Commands/Level3.cpp @@ -385,365 +385,6 @@ bool ChatHandler::HandleAddItemSetCommand(const char *args) return true; } -bool ChatHandler::HandleListItemCommand(const char *args) -{ - if (!*args) - return false; - - char* cId = extractKeyFromLink((char*)args, "Hitem"); - if (!cId) - return false; - - uint32 item_id = atol(cId); - if (!item_id) - { - PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); - SetSentErrorMessage(true); - return false; - } - - ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id); - if (!itemProto) - { - PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id); - SetSentErrorMessage(true); - return false; - } - - char* c_count = strtok(NULL, " "); - int _count = c_count ? atol(c_count) : 10; - - if (_count < 0) - return false; - uint32 count = uint32(_count); - - PreparedQueryResult result; - - // inventory case - uint32 inv_count = 0; - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM); - stmt->setUInt32(0, item_id); - result = CharacterDatabase.Query(stmt); - - if (result) - inv_count = (*result)[0].GetUInt64(); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY); - stmt->setUInt32(0, item_id); - stmt->setUInt32(1, count); - result = CharacterDatabase.Query(stmt); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 item_bag = fields[1].GetUInt32(); - uint8 item_slot = fields[2].GetUInt8(); - uint32 owner_guid = fields[3].GetUInt32(); - uint32 owner_acc = fields[4].GetUInt32(); - std::string owner_name = fields[5].GetString(); - - char const* item_pos = 0; - if (Player::IsEquipmentPos(item_bag, item_slot)) - item_pos = "[equipped]"; - else if (Player::IsInventoryPos(item_bag, item_slot)) - item_pos = "[in inventory]"; - else if (Player::IsBankPos(item_bag, item_slot)) - item_pos = "[in bank]"; - else - item_pos = ""; - - PSendSysMessage(LANG_ITEMLIST_SLOT, item_guid, owner_name.c_str(), owner_guid, owner_acc, item_pos); - } - while (result->NextRow()); - - uint32 res_count = uint32(result->GetRowCount()); - - if (count > res_count) - count -= res_count; - else if (count) - count = 0; - } - - // mail case - uint32 mail_count = 0; - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM); - stmt->setUInt32(0, item_id); - result = CharacterDatabase.Query(stmt); - - if (result) - mail_count = (*result)[0].GetUInt64(); - - if (count > 0) - { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY); - stmt->setUInt32(0, item_id); - stmt->setUInt32(1, count); - result = CharacterDatabase.Query(stmt); - } - else - result = PreparedQueryResult(NULL); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 item_s = fields[1].GetUInt32(); - uint32 item_r = fields[2].GetUInt32(); - uint32 item_s_acc = fields[3].GetUInt32(); - std::string item_s_name = fields[4].GetString(); - uint32 item_r_acc = fields[5].GetUInt32(); - std::string item_r_name = fields[6].GetString(); - - char const* item_pos = "[in mail]"; - - PSendSysMessage(LANG_ITEMLIST_MAIL, item_guid, item_s_name.c_str(), item_s, item_s_acc, item_r_name.c_str(), item_r, item_r_acc, item_pos); - } - while (result->NextRow()); - - uint32 res_count = uint32(result->GetRowCount()); - - if (count > res_count) - count -= res_count; - else if (count) - count = 0; - } - - // auction case - uint32 auc_count = 0; - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM); - stmt->setUInt32(0, item_id); - result = CharacterDatabase.Query(stmt); - - if (result) - auc_count = (*result)[0].GetUInt64(); - - if (count > 0) - { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY); - stmt->setUInt32(0, item_id); - stmt->setUInt32(1, count); - result = CharacterDatabase.Query(stmt); - } - else - result = PreparedQueryResult(NULL); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 owner = fields[1].GetUInt32(); - uint32 owner_acc = fields[2].GetUInt32(); - std::string owner_name = fields[3].GetString(); - - char const* item_pos = "[in auction]"; - - PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc, item_pos); - } - while (result->NextRow()); - } - - // guild bank case - uint32 guild_count = 0; - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM); - stmt->setUInt32(0, item_id); - result = CharacterDatabase.Query(stmt); - - if (result) - guild_count = (*result)[0].GetUInt64(); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY); - stmt->setUInt32(0, item_id); - stmt->setUInt32(1, count); - result = CharacterDatabase.Query(stmt); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 item_guid = fields[0].GetUInt32(); - uint32 guild_guid = fields[1].GetUInt32(); - std::string guild_name = fields[2].GetString(); - - char const* item_pos = "[in guild bank]"; - - PSendSysMessage(LANG_ITEMLIST_GUILD, item_guid, guild_name.c_str(), guild_guid, item_pos); - } - while (result->NextRow()); - - uint32 res_count = uint32(result->GetRowCount()); - - if (count > res_count) - count -= res_count; - else if (count) - count = 0; - } - - if (inv_count + mail_count + auc_count + guild_count == 0) - { - SendSysMessage(LANG_COMMAND_NOITEMFOUND); - SetSentErrorMessage(true); - return false; - } - - PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, item_id, inv_count + mail_count + auc_count + guild_count, inv_count, mail_count, auc_count, guild_count); - return true; -} - -bool ChatHandler::HandleListObjectCommand(const char *args) -{ - if (!*args) - return false; - - // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args, "Hgameobject_entry"); - if (!cId) - return false; - - uint32 go_id = atol(cId); - if (!go_id) - { - PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); - SetSentErrorMessage(true); - return false; - } - - GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(go_id); - if (!gInfo) - { - PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id); - SetSentErrorMessage(true); - return false; - } - - char* c_count = strtok(NULL, " "); - int count = c_count ? atol(c_count) : 10; - - if (count < 0) - return false; - - QueryResult result; - - uint32 obj_count = 0; - result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", go_id); - if (result) - obj_count = (*result)[0].GetUInt64(); - - if (m_session) - { - Player* player = m_session->GetPlayer(); - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", - player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), go_id, uint32(count)); - } - else - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u", - go_id, uint32(count)); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); - float x = fields[1].GetFloat(); - float y = fields[2].GetFloat(); - float z = fields[3].GetFloat(); - int mapid = fields[4].GetUInt16(); - uint32 entry = fields[5].GetUInt32(); - - if (m_session) - PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapid); - else - PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapid); - } while (result->NextRow()); - } - - PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, go_id, obj_count); - return true; -} - -bool ChatHandler::HandleListCreatureCommand(const char *args) -{ - if (!*args) - return false; - - // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r - char* cId = extractKeyFromLink((char*)args, "Hcreature_entry"); - if (!cId) - return false; - - uint32 cr_id = atol(cId); - if (!cr_id) - { - PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); - SetSentErrorMessage(true); - return false; - } - - CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(cr_id); - if (!cInfo) - { - PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id); - SetSentErrorMessage(true); - return false; - } - - char* c_count = strtok(NULL, " "); - int count = c_count ? atol(c_count) : 10; - - if (count < 0) - return false; - - QueryResult result; - - uint32 cr_count = 0; - result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", cr_id); - if (result) - cr_count = (*result)[0].GetUInt64(); - - if (m_session) - { - Player* player = m_session->GetPlayer(); - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u", - player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), cr_id, uint32(count)); - } - else - result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u", - cr_id, uint32(count)); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); - float x = fields[1].GetFloat(); - float y = fields[2].GetFloat(); - float z = fields[3].GetFloat(); - int mapid = fields[4].GetUInt16(); - - if (m_session) - PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapid); - else - PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapid); - } while (result->NextRow()); - } - - PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, cr_id, cr_count); - return true; -} - bool ChatHandler::HandleLookupItemCommand(const char *args) { if (!*args) @@ -1144,15 +785,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args) { QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); - if (status == QUEST_STATUS_COMPLETE) + switch (status) { - if (target->GetQuestRewardStatus(qinfo->GetQuestId())) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); - else + case QUEST_STATUS_COMPLETE: statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); + break; + case QUEST_STATUS_INCOMPLETE: + statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); + break; + case QUEST_STATUS_REWARDED: + statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); + break; + default: + break; } - else if (status == QUEST_STATUS_INCOMPLETE) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); } if (m_session) @@ -1187,15 +833,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args) { QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId()); - if (status == QUEST_STATUS_COMPLETE) + switch (status) { - if (target->GetQuestRewardStatus(qinfo->GetQuestId())) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); - else + case QUEST_STATUS_COMPLETE: statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE); + break; + case QUEST_STATUS_INCOMPLETE: + statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); + break; + case QUEST_STATUS_REWARDED: + statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED); + break; + default: + break; } - else if (status == QUEST_STATUS_INCOMPLETE) - statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE); } if (m_session) @@ -1730,7 +1381,7 @@ bool ChatHandler::HandleGuildUninviteCommand(const char *args) if (!extractPlayerTarget((char*)args, &target, &target_guid)) return false; - uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromGuid(target_guid); + uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid); if (!glId) return false; @@ -1756,7 +1407,7 @@ bool ChatHandler::HandleGuildRankCommand(const char *args) if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) return false; - uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromGuid(target_guid); + uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid); if (!glId) return false; @@ -2188,47 +1839,6 @@ void ChatHandler::HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 } } -bool ChatHandler::HandleCharacterLevelCommand(const char *args) -{ - char* nameStr; - char* levelStr; - extractOptFirstArg((char*)args, &nameStr, &levelStr); - if (!levelStr) - return false; - - // exception opt second arg: .character level $name - if (isalpha(levelStr[0])) - { - nameStr = levelStr; - levelStr = NULL; // current level will used - } - - Player* target; - uint64 target_guid; - std::string target_name; - if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) - return false; - - int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid); - int32 newlevel = levelStr ? atoi(levelStr) : oldlevel; - - if (newlevel < 1) - return false; // invalid level - - if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level - newlevel = STRONG_MAX_LEVEL; - - HandleCharacterLevel(target, target_guid, oldlevel, newlevel); - - if (!m_session || m_session->GetPlayer() != target) // including player == NULL - { - std::string nameLink = playerLink(target_name); - PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel); - } - - return true; -} - bool ChatHandler::HandleLevelUpCommand(const char *args) { char* nameStr; @@ -2380,457 +1990,6 @@ bool ChatHandler::HandleChangeWeather(const char *args) return true; } -bool ChatHandler::HandleListAurasCommand (const char * /*args*/) -{ - Unit* unit = getSelectedUnit(); - if (!unit) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - char const* talentStr = GetTrinityString(LANG_TALENT); - char const* passiveStr = GetTrinityString(LANG_PASSIVE); - - Unit::AuraApplicationMap const& uAuras = unit->GetAppliedAuras(); - PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size()); - for (Unit::AuraApplicationMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) - { - bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0; - - AuraApplication const* aurApp = itr->second; - Aura const* aura = aurApp->GetBase(); - char const* name = aura->GetSpellInfo()->SpellName; - - std::ostringstream ss_name; - ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r"; - - PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (m_session ? ss_name.str().c_str() : name), - aurApp->GetEffectMask(), aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(), - aura->GetDuration(), aura->GetMaxDuration(), (aura->IsPassive() ? passiveStr : ""), - (talent ? talentStr : ""), IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature", - GUID_LOPART(aura->GetCasterGUID())); - } - for (uint16 i = 0; i < TOTAL_AURAS; ++i) - { - Unit::AuraEffectList const& uAuraList = unit->GetAuraEffectsByType(AuraType(i)); - if (uAuraList.empty()) - continue; - - PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i); - for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr) - { - PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), - (*itr)->GetAmount()); - } - } - return true; -} - -bool ChatHandler::HandleResetAchievementsCommand (const char * args) -{ - Player* target; - uint64 target_guid; - if (!extractPlayerTarget((char*)args, &target, &target_guid)) - return false; - - if (target) - target->GetAchievementMgr().Reset(); - else - AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid)); - - return true; -} - -bool ChatHandler::HandleResetHonorCommand (const char * args) -{ - Player* target; - if (!extractPlayerTarget((char*)args, &target)) - return false; - - target->SetCurrency(CURRENCY_TYPE_HONOR_POINTS, 0); - target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); - target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); - target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); - - return true; -} - -static bool HandleResetStatsOrLevelHelper(Player* player) -{ - ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass()); - if (!cEntry) - { - sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass()); - return false; - } - - uint8 powertype = cEntry->powerType; - - // reset m_form if no aura - if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) - player->SetShapeshiftForm(FORM_NONE); - - player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); - player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH); - - player->setFactionForRace(player->getRace()); - - player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powertype << 24))); - - // reset only if player not in some form; - if (player->GetShapeshiftForm() == FORM_NONE) - player->InitDisplayIds(); - - player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - - player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - - //-1 is default value - player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); - - //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000); - return true; -} - -bool ChatHandler::HandleResetLevelCommand(const char * args) -{ - Player* target; - if (!extractPlayerTarget((char*)args, &target)) - return false; - - if (!HandleResetStatsOrLevelHelper(target)) - return false; - - uint8 oldLevel = target->getLevel(); - - // set starting level - uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT - ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL) - : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - - target->_ApplyAllLevelScaleItemMods(false); - target->SetLevel(start_level); - target->InitRunes(); - target->InitStatsForLevel(true); - target->InitTaxiNodesForLevel(); - target->InitGlyphsForLevel(); - target->InitTalentForLevel(); - target->SetUInt32Value(PLAYER_XP, 0); - - target->_ApplyAllLevelScaleItemMods(true); - - // reset level for pet - if (Pet* pet = target->GetPet()) - pet->SynchronizeLevelWithOwner(); - - sScriptMgr->OnPlayerLevelChanged(target, oldLevel); - - return true; -} - -bool ChatHandler::HandleResetStatsCommand(const char * args) -{ - Player* target; - if (!extractPlayerTarget((char*)args, &target)) - return false; - - if (!HandleResetStatsOrLevelHelper(target)) - return false; - - target->InitRunes(); - target->InitStatsForLevel(true); - target->InitTaxiNodesForLevel(); - target->InitGlyphsForLevel(); - target->InitTalentForLevel(); - - return true; -} - -bool ChatHandler::HandleResetSpellsCommand(const char* args) -{ - Player* target; - uint64 targetGuid; - std::string targetName; - if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - if (target) - { - target->resetSpells(/* bool myClassOnly */); - - ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS); - if (!m_session || m_session->GetPlayer() != target) - PSendSysMessage(LANG_RESET_SPELLS_ONLINE, GetNameLink(target).c_str()); - } - else - { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - - stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS)); - stmt->setUInt32(1, GUID_LOPART(targetGuid)); - - CharacterDatabase.Execute(stmt); - - PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str()); - } - - return true; -} - -bool ChatHandler::HandleResetTalentsCommand(const char* args) -{ - Player* target; - uint64 targetGuid; - std::string targetName; - if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - { - // Try reset talents as Hunter Pet - Creature* creature = getSelectedCreature(); - if (!*args && creature && creature->isPet()) - { - Unit* owner = creature->GetOwner(); - if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer())) - { - creature->ToPet()->resetTalents(); - owner->ToPlayer()->SendTalentsInfoData(true); - - ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS); - if (!m_session || m_session->GetPlayer() != owner->ToPlayer()) - PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, GetNameLink(owner->ToPlayer()).c_str()); - } - return true; - } - - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if (target) - { - target->ResetTalents(true); - target->SendTalentsInfoData(false); - ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); - if (!m_session || m_session->GetPlayer() != target) - PSendSysMessage(LANG_RESET_TALENTS_ONLINE, GetNameLink(target).c_str()); - - Pet* pet = target->GetPet(); - Pet::resetTalentsForAllPetsOf(target, pet); - if (pet) - target->SendTalentsInfoData(true); - return true; - } - else if (targetGuid) - { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); - - stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS)); - stmt->setUInt32(1, GUID_LOPART(targetGuid)); - - CharacterDatabase.Execute(stmt); - - std::string nameLink = playerLink(targetName); - PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str()); - return true; - } - - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; -} - -bool ChatHandler::HandleResetAllCommand(const char * args) -{ - if (!*args) - return false; - - std::string casename = args; - - AtLoginFlags atLogin; - - // Command specially created as single command to prevent using short case names - if (casename == "spells") - { - atLogin = AT_LOGIN_RESET_SPELLS; - sWorld->SendWorldText(LANG_RESETALL_SPELLS); - if (!m_session) - SendSysMessage(LANG_RESETALL_SPELLS); - } - else if (casename == "talents") - { - atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS); - sWorld->SendWorldText(LANG_RESETALL_TALENTS); - if (!m_session) - SendSysMessage(LANG_RESETALL_TALENTS); - } - else - { - PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args); - SetSentErrorMessage(true); - return false; - } - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS); - - stmt->setUInt16(0, uint16(atLogin)); - - CharacterDatabase.Execute(stmt); - - TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock()); - HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers(); - for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) - itr->second->SetAtLoginFlag(atLogin); - - return true; -} - -bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/) -{ - sWorld->ShutdownCancel(); - return true; -} - -bool ChatHandler::HandleServerShutDownCommand(const char *args) -{ - if (!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld->ShutdownServ(time, 0, exitcode); - } - else - sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE); - return true; -} - -bool ChatHandler::HandleServerRestartCommand(const char *args) -{ - if (!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitcode); - } - else - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); - return true; -} - -bool ChatHandler::HandleServerIdleRestartCommand(const char *args) -{ - if (!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode); - } - else - sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE); - return true; -} - -bool ChatHandler::HandleServerIdleShutDownCommand(const char *args) -{ - if (!*args) - return false; - - char* time_str = strtok ((char*) args, " "); - char* exitcode_str = strtok (NULL, ""); - - int32 time = atoi (time_str); - - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0) - return false; - - if (exitcode_str) - { - int32 exitcode = atoi (exitcode_str); - - // Handle atoi() errors - if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) - return false; - - // Exit code should be in range of 0-125, 126-255 is used - // in many shells for their own return codes and code > 255 - // is not supported in many others - if (exitcode < 0 || exitcode > 125) - return false; - - sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitcode); - } - else - sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE); - return true; -} bool ChatHandler::HandleBanAccountCommand(const char *args) { @@ -3752,277 +2911,6 @@ bool ChatHandler::HandleMovegensCommand(const char* /*args*/) return true; } -bool ChatHandler::HandleServerPLimitCommand(const char *args) -{ - if (*args) - { - char* param = strtok((char*)args, " "); - if (!param) - return false; - - int l = strlen(param); - - if (strncmp(param, "player", l) == 0) - sWorld->SetPlayerSecurityLimit(SEC_PLAYER); - else if (strncmp(param, "moderator", l) == 0) - sWorld->SetPlayerSecurityLimit(SEC_MODERATOR); - else if (strncmp(param, "gamemaster", l) == 0) - sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER); - else if (strncmp(param, "administrator", l) == 0) - sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR); - else if (strncmp(param, "reset", l) == 0) - { - sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100)); - sWorld->LoadDBAllowedSecurityLevel(); - } - else - { - int val = atoi(param); - if (val < 0) - sWorld->SetPlayerSecurityLimit(AccountTypes(uint32(-val))); - else - sWorld->SetPlayerAmountLimit(uint32(val)); - } - } - - uint32 pLimit = sWorld->GetPlayerAmountLimit(); - AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); - char const* secName = ""; - switch (allowedAccountType) - { - case SEC_PLAYER: secName = "Player"; break; - case SEC_MODERATOR: secName = "Moderator"; break; - case SEC_GAMEMASTER: secName = "Gamemaster"; break; - case SEC_ADMINISTRATOR: secName = "Administrator"; break; - default: secName = "<unknown>"; break; - } - - PSendSysMessage("Player limits: amount %u, min. security level %s.", pLimit, secName); - - return true; -} - -bool ChatHandler::HandleCastCommand(const char *args) -{ - if (!*args) - return false; - - Unit* target = getSelectedUnit(); - - if (!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if (!spell) - return false; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); - if (!spellInfo) - { - PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); - SetSentErrorMessage(true); - return false; - } - - if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); - SetSentErrorMessage(true); - return false; - } - - char* trig_str = strtok(NULL, " "); - if (trig_str) - { - int l = strlen(trig_str); - if (strncmp(trig_str, "triggered", l) != 0) - return false; - } - - bool triggered = (trig_str != NULL); - - m_session->GetPlayer()->CastSpell(target, spell, triggered); - - return true; -} - -bool ChatHandler::HandleCastBackCommand(const char *args) -{ - Creature* caster = getSelectedCreature(); - - if (!caster) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if (!spell || !sSpellMgr->GetSpellInfo(spell)) - { - PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); - SetSentErrorMessage(true); - return false; - } - - char* trig_str = strtok(NULL, " "); - if (trig_str) - { - int l = strlen(trig_str); - if (strncmp(trig_str, "triggered", l) != 0) - return false; - } - - bool triggered = (trig_str != NULL); - - caster->CastSpell(m_session->GetPlayer(), spell, triggered); - - return true; -} - -bool ChatHandler::HandleCastDistCommand(const char *args) -{ - if (!*args) - return false; - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if (!spell) - return false; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); - if (!spellInfo) - { - PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); - SetSentErrorMessage(true); - return false; - } - - if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); - SetSentErrorMessage(true); - return false; - } - - char *distStr = strtok(NULL, " "); - - float dist = 0; - - if (distStr) - sscanf(distStr, "%f", &dist); - - char* trig_str = strtok(NULL, " "); - if (trig_str) - { - int l = strlen(trig_str); - if (strncmp(trig_str, "triggered", l) != 0) - return false; - } - - bool triggered = (trig_str != NULL); - - float x, y, z; - m_session->GetPlayer()->GetClosePoint(x, y, z, dist); - - m_session->GetPlayer()->CastSpell(x, y, z, spell, triggered); - return true; -} - -bool ChatHandler::HandleCastTargetCommand(const char *args) -{ - Creature* caster = getSelectedCreature(); - - if (!caster) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - if (!caster->getVictim()) - { - SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if (!spell || !sSpellMgr->GetSpellInfo(spell)) - { - PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); - SetSentErrorMessage(true); - return false; - } - - char* trig_str = strtok(NULL, " "); - if (trig_str) - { - int l = strlen(trig_str); - if (strncmp(trig_str, "triggered", l) != 0) - return false; - } - - bool triggered = (trig_str != NULL); - - caster->CastSpell(caster->getVictim(), spell, triggered); - - return true; -} - -bool ChatHandler::HandleCastDestCommand(const char *args) -{ - Unit* caster = getSelectedUnit(); - if (!caster) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if (!spell || !sSpellMgr->GetSpellInfo(spell)) - { - PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); - SetSentErrorMessage(true); - return false; - } - - char* px = strtok(NULL, " "); - char* py = strtok(NULL, " "); - char* pz = strtok(NULL, " "); - - if (!px || !py || !pz) - return false; - - float x = (float)atof(px); - float y = (float)atof(py); - float z = (float)atof(pz); - - char* trig_str = strtok(NULL, " "); - if (trig_str) - { - int l = strlen(trig_str); - if (strncmp(trig_str, "triggered", l) != 0) - return false; - } - - bool triggered = (trig_str != NULL); - - caster->CastSpell(x, y, z, spell, triggered); - - return true; -} - /* ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator Without this function 3rd party scripting library will get linking errors (unresolved external) @@ -4049,196 +2937,6 @@ bool ChatHandler::HandleComeToMeCommand(const char *args) return true; } -bool ChatHandler::HandleCastSelfCommand(const char *args) -{ - if (!*args) - return false; - - Unit* target = getSelectedUnit(); - - if (!target) - { - SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spell = extractSpellIdFromLink((char*)args); - if (!spell) - return false; - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); - if (!spellInfo) - return false; - - if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer())) - { - PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell); - SetSentErrorMessage(true); - return false; - } - - target->CastSpell(target, spell, false); - - return true; -} - -std::string GetTimeString(uint64 time) -{ - uint64 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE; - std::ostringstream ss; - if (days) ss << days << "d "; - if (hours) ss << hours << "h "; - ss << minute << 'm'; - return ss.str(); -} - -bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/) -{ - Player* player = getSelectedPlayer(); - if (!player) player = m_session->GetPlayer(); - uint32 counter = 0; - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - { - Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); - for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) - { - InstanceSave* save = itr->second.save; - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); - counter++; - } - } - PSendSysMessage("player binds: %d", counter); - counter = 0; - Group* group = player->GetGroup(); - if (group) - { - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - { - Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i)); - for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) - { - InstanceSave* save = itr->second.save; - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); - counter++; - } - } - } - PSendSysMessage("group binds: %d", counter); - - return true; -} - -bool ChatHandler::HandleInstanceUnbindCommand(const char *args) -{ - if (!*args) - return false; - - Player* player = getSelectedPlayer(); - if (!player) - player = m_session->GetPlayer(); - - char* map = strtok((char*)args, " "); - char* pDiff = strtok(NULL, " "); - int8 diff = -1; - if (pDiff) - diff = atoi(pDiff); - uint16 counter = 0; - uint16 MapId = 0; - - if (strcmp(map, "all")) - { - MapId = uint16(atoi(map)); - if (!MapId) - return false; - } - - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - { - Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); - for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) - { - InstanceSave* save = itr->second.save; - if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty())) - { - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str()); - player->UnbindInstance(itr, Difficulty(i)); - counter++; - } - else - ++itr; - } - } - PSendSysMessage("instances unbound: %d", counter); - return true; -} - -bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/) -{ - PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances()); - PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances()); - PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves()); - PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal()); - PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal()); - return true; -} - -bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/) -{ - Player* player = m_session->GetPlayer(); - - Map* map = player->GetMap(); - if (!map->IsDungeon()) - { - PSendSysMessage("Map is not a dungeon."); - SetSentErrorMessage(true); - return false; - } - - if (!((InstanceMap*)map)->GetInstanceScript()) - { - PSendSysMessage("Map has no instance data."); - SetSentErrorMessage(true); - return false; - } - - ((InstanceMap*)map)->GetInstanceScript()->SaveToDB(); - return true; -} - -/// Define the 'Message of the day' for the realm -bool ChatHandler::HandleServerSetMotdCommand(const char *args) -{ - sWorld->SetMotd(args); - PSendSysMessage(LANG_MOTD_NEW, args); - return true; -} - -/// Set whether we accept new clients -bool ChatHandler::HandleServerSetClosedCommand(const char *args) -{ - if (strncmp(args, "on", 3) == 0) - { - SendSysMessage(LANG_WORLD_CLOSED); - sWorld->SetClosed(true); - return true; - } - else if (strncmp(args, "off", 4) == 0) - { - SendSysMessage(LANG_WORLD_OPENED); - sWorld->SetClosed(false); - return true; - } - - SendSysMessage(LANG_USE_BOL); - SetSentErrorMessage(true); - return false; -} - //Send items by mail bool ChatHandler::HandleSendItemsCommand(const char *args) { diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 9737d4584ea..0c43c9ece0e 100755 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -354,7 +354,9 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileR // list sorted and and we check current target, then this is best case if (currentVictim == currentRef || currentRef->getThreat() <= 1.1f * currentVictim->getThreat()) { - currentRef = currentVictim; // for second case + if (currentVictim != currentRef && attacker->canCreatureAttack(currentVictim->getTarget())) + currentRef = currentVictim; // for second case, if currentvictim is attackable + found = true; break; } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 4176d9f605b..9f534ab697d 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -441,7 +441,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition() uint32 Condition::GetMaxAvailableConditionTargets() { // returns number of targets which are available for given source type - switch(SourceType) + switch (SourceType) { case CONDITION_SOURCE_TYPE_SPELL: case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET: diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index dcd189a05cb..e032335c3bc 100755 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -527,16 +527,27 @@ enum SummonPropFlags enum VehicleSeatFlags { + VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_ENTER = 0x00000001, + VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_RIDE = 0x00000002, + VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIM_ON_VOLUNTARY_EXIT = 0x00000008, VEHICLE_SEAT_FLAG_HIDE_PASSENGER = 0x00000200, // Passenger is hidden - VEHICLE_SEAT_FLAG_UNK1 = 0x00000400, // needed for CGCamera__SyncFreeLookFacing + VEHICLE_SEAT_FLAG_ALLOW_TURNING = 0x00000400, // needed for CGCamera__SyncFreeLookFacing VEHICLE_SEAT_FLAG_CAN_CONTROL = 0x00000800, // Lua_UnitInVehicleControlSeat VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL = 0x00001000, // Can cast spells with SPELL_AURA_MOUNTED from seat (possibly 4.x only, 0 seats on 3.3.5a) VEHICLE_SEAT_FLAG_UNCONTROLLED = 0x00002000, // can override !& VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT VEHICLE_SEAT_FLAG_CAN_ATTACK = 0x00004000, // Can attack, cast spells and use items from vehicle + VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIMN_ON_FORCED_EXIT = 0x00008000, + VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_VOLUNTARY_EXIT = 0x00040000, + VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_FORCED_EXIT = 0x00080000, + VEHICLE_SEAT_FLAG_REC_HAS_VEHICLE_ENTER_ANIM = 0x00400000, + VEHICLE_SEAT_FLAG_ENABLE_VEHICLE_ZOOM = 0x01000000, VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT = 0x02000000, // Lua_CanExitVehicle - can enter and exit at free will VEHICLE_SEAT_FLAG_CAN_SWITCH = 0x04000000, // Lua_CanSwitchVehicleSeats + VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_ENTER = 0x08000000, + VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_EXIT = 0x10000000, VEHICLE_SEAT_FLAG_CAN_CAST = 0x20000000, // Lua_UnitHasVehicleUI VEHICLE_SEAT_FLAG_UNK2 = 0x40000000, // checked in conjunction with 0x800 in CastSpell2 + VEHICLE_SEAT_FLAG_ALLOWS_INTERACTION = 0x80000000, }; enum VehicleSeatFlagsB @@ -548,6 +559,7 @@ enum VehicleSeatFlagsB VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 = 0x00000040, VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100, VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4 = 0x02000000, + VEHICLE_SEAT_FLAG_B_CAN_SWITCH = 0x04000000, VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000 }; diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 973421bc2e3..80f62d9cedb 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -635,7 +635,7 @@ void LoadDBCStores(const std::string& dataPath) // include existed nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; - for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) + for (uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i) if (SpellEffectEntry const* sInfo = sSpellEffectStore.LookupEntry (i)) if (sInfo->Effect == SPELL_EFFECT_SEND_TAXI) spellPaths.insert(sInfo->EffectMiscValue); @@ -1166,11 +1166,3 @@ uint32 ScalingStatValuesEntry::GetDPSAndDamageMultiplier(uint32 subClass, bool i return 0; } -// script support functions -DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; } -DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() { return &sSpellRangeStore; } -DBCStorage <FactionEntry> const* GetFactionStore() { return &sFactionStore; } -DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore() { return &sCreatureDisplayInfoStore; } -DBCStorage <EmotesEntry> const* GetEmotesStore() { return &sEmotesStore; } -DBCStorage <EmotesTextEntry> const* GetEmotesTextStore() { return &sEmotesTextStore; } -DBCStorage <AchievementEntry> const* GetAchievementStore() { return &sAchievementStore; } diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index c22f2ccd625..d94b60c1384 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -214,13 +214,4 @@ extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore; void LoadDBCStores(const std::string& dataPath); -// script support functions - DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore(); - DBCStorage <SpellRangeEntry> const* GetSpellRangeStore(); - DBCStorage <FactionEntry> const* GetFactionStore(); -// DBCStorage <ItemEntry> const* GetItemDisplayStore(); - DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore(); - DBCStorage <EmotesEntry> const* GetEmotesStore(); - DBCStorage <EmotesTextEntry> const* GetEmotesTextStore(); - DBCStorage <AchievementEntry> const* GetAchievementStore(); #endif diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 47c298d7467..91f9104b0b1 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -433,8 +433,8 @@ void LFGMgr::InitializeLockedDungeons(Player* player) locktype = LFG_LOCKSTATUS_RAID_LOCKED; else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty))) { - if (!player->GetGroup() || !player->GetGroup()->isLFGGroup() || GetDungeon(player->GetGroup()->GetGUID(), true) != dungeon->ID || GetState(player->GetGroup()->GetGUID()) != LFG_STATE_DUNGEON) - locktype = LFG_LOCKSTATUS_RAID_LOCKED; + //if (!player->GetGroup() || !player->GetGroup()->isLFGGroup() || GetDungeon(player->GetGroup()->GetGUID(), true) != dungeon->ID || GetState(player->GetGroup()->GetGUID()) != LFG_STATE_DUNGEON) + locktype = LFG_LOCKSTATUS_RAID_LOCKED; } else if (dungeon->minlevel > level) locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL; @@ -791,7 +791,7 @@ LfgProposal* LFGMgr::FindNewGroups(LfgGuidList& check, LfgGuidList& all) sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FindNewGroup: (%s) - all(%s)", ConcatenateGuids(check).c_str(), ConcatenateGuids(all).c_str()); LfgProposal* pProposal = NULL; - if (!check.size() || check.size() > MAXGROUPSIZE || !CheckCompatibility(check, pProposal)) + if (check.empty() || check.size() > MAXGROUPSIZE || !CheckCompatibility(check, pProposal)) return NULL; // Try to match with queued groups @@ -1417,6 +1417,10 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) waitTimesMap[(*it)->GetGUID()] = int32(joinTime - itQueue->second->joinTime); } + // Set the dungeon difficulty + LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId); + ASSERT(dungeon); + // Create a new group (if needed) LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND); Group* grp = pProposal->groupLowGuid ? sGroupMgr->GetGroupByGUID(pProposal->groupLowGuid) : NULL; @@ -1427,6 +1431,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) Group* group = player->GetGroup(); if (sendUpdate) player->GetSession()->SendLfgUpdateProposal(proposalId, pProposal); + if (group) { player->GetSession()->SendLfgUpdateParty(updateData); @@ -1478,14 +1483,16 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept) break; } } + m_teleport.push_back(pguid); grp->SetLfgRoles(pguid, pProposal->players[pguid]->role); SetState(pguid, LFG_STATE_DUNGEON); + + // Add the cooldown spell if queued for a random dungeon + if (dungeon->type == LFG_TYPE_RANDOM) + player->CastSpell(player, LFG_SPELL_DUNGEON_COOLDOWN, false); } - // Set the dungeon difficulty - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId); - ASSERT(dungeon); grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty)); uint64 gguid = grp->GetGUID(); SetDungeon(gguid, dungeon->Entry()); @@ -1626,6 +1633,7 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas { if (!grp) return; + uint64 gguid = grp->GetGUID(); SetState(gguid, LFG_STATE_BOOT); @@ -1635,7 +1643,6 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas pBoot->reason = reason; pBoot->victim = victim; pBoot->votedNeeded = GetVotesNeeded(gguid); - PlayerSet players; // Set votes for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) @@ -1651,15 +1658,11 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas else { pBoot->votes[guid] = LFG_ANSWER_PENDING; // Other members need to vote - players.insert(plrg); + plrg->GetSession()->SendLfgBootPlayer(pBoot); } } } - // Notify players - for (PlayerSet::const_iterator it = players.begin(); it != players.end(); ++it) - (*it)->GetSession()->SendLfgBootPlayer(pBoot); - m_Boots[grp->GetLowGUID()] = pBoot; } @@ -1748,14 +1751,7 @@ void LFGMgr::UpdateBoot(Player* player, bool accept) void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/) { sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::TeleportPlayer: [" UI64FMTD "] is being teleported %s", player->GetGUID(), out ? "out" : "in"); - if (out) - { - player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); - player->TeleportToBGEntryPoint(); - return; - } - // TODO Add support for LFG_TELEPORTERROR_FATIGUE LfgTeleportError error = LFG_TELEPORTERROR_OK; Group* grp = player->GetGroup(); @@ -1765,10 +1761,25 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* error = LFG_TELEPORTERROR_PLAYER_DEAD; else if (player->IsFalling() || player->HasUnitState(UNIT_STATE_JUMPING)) error = LFG_TELEPORTERROR_FALLING; + else if (player->IsMirrorTimerActive(FATIGUE_TIMER)) + error = LFG_TELEPORTERROR_FATIGUE; else { - uint64 gguid = grp->GetGUID(); - LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(gguid)); + LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(grp->GetGUID())); + + if (out) + { + // Player needs to be inside the LFG dungeon to be able to teleport out + if (dungeon && player->GetMapId() == uint32(dungeon->map)) + { + player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); + player->TeleportToBGEntryPoint(); + } + else + player->GetSession()->SendLfgTeleportError(LFG_TELEPORTERROR_DONT_REPORT); // Not sure which error message to send + + return; + } if (!dungeon) error = LFG_TELEPORTERROR_INVALID_LOCATION; @@ -1817,7 +1828,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* if (error == LFG_TELEPORTERROR_OK) { - if (!player->GetMap()->IsDungeon() && !player->GetMap()->IsRaid()) + if (!player->GetMap()->IsDungeon()) player->SetBattlegroundEntryPoint(); if (player->isInFlight()) diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index d10902b9553..f21818deb64 100755 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -68,6 +68,7 @@ enum LfgTeleportError LFG_TELEPORTERROR_OK = 0, // Internal use LFG_TELEPORTERROR_PLAYER_DEAD = 1, LFG_TELEPORTERROR_FALLING = 2, + LFG_TELEPORTERROR_DONT_REPORT = 3, LFG_TELEPORTERROR_FATIGUE = 4, LFG_TELEPORTERROR_INVALID_LOCATION = 6 }; diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 6175addfae2..1fa7fe0ca9f 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -117,13 +117,14 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth return; } + uint32 state = sLFGMgr->GetState(gguid); sLFGMgr->ClearState(guid); sLFGMgr->SetState(guid, LFG_STATE_NONE); if (Player* player = ObjectAccessor::FindPlayer(guid)) { + if (method == GROUP_REMOVEMETHOD_LEAVE && state != LFG_STATE_FINISHED_DUNGEON && player->HasAura(LFG_SPELL_DUNGEON_COOLDOWN)) + player->CastSpell(player, LFG_SPELL_DUNGEON_DESERTER, false); /* - if (method == GROUP_REMOVEMETHOD_LEAVE) - // Add deserter flag else if (group->isLfgKickActive()) // Update internal kick cooldown of kicked */ @@ -134,7 +135,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth sLFGMgr->TeleportPlayer(player, true); } - if (sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon + if (state != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon sLFGMgr->OfferContinue(group); } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index bbce6cf56c1..c7758bf5e55 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -486,7 +486,7 @@ void Creature::Update(uint32 diff) break; uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_UNIT); - time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId()); + time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid); if (!linkedRespawntime) // Can respawn Respawn(); else // the master is dead @@ -1303,7 +1303,7 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap) m_respawnDelay = data->spawntimesecs; m_deathState = ALIVE; - m_respawnTime = sObjectMgr->GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId()); + m_respawnTime = GetMap()->GetCreatureRespawnTime(m_DBTableGuid); if (m_respawnTime) // respawn on Update { m_deathState = DEAD; @@ -1398,7 +1398,7 @@ void Creature::DeleteFromDB() return; } - sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId()); + GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid); sObjectMgr->DeleteCreatureData(m_DBTableGuid); SQLTransaction trans = WorldDatabase.BeginTransaction(); @@ -1598,7 +1598,7 @@ void Creature::Respawn(bool force) if (getDeathState() == DEAD) { if (m_DBTableGuid) - sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId()); + GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid); sLog->outStaticDebug("Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName(), GetGUIDLow(), GetGUID(), GetEntry()); m_respawnTime = 0; @@ -1676,11 +1676,15 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) // the check of mechanic immunity on DB (tested) because GetCreatureTemplate()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data. bool immunedToAllEffects = true; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (!spellInfo->Effects[i].IsEffect()) + continue; if (!IsImmunedToSpellEffect(spellInfo, i)) { immunedToAllEffects = false; break; } + } if (immunedToAllEffects) return true; @@ -1727,6 +1731,8 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim) break; } } + if (bcontinue) + continue; if (bcontinue) continue; @@ -2014,7 +2020,7 @@ void Creature::SaveRespawnTime() if (isSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData)) return; - sObjectMgr->SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime); + GetMap()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime); } // this should not be called by petAI or @@ -2458,7 +2464,7 @@ bool Creature::SetWalk(bool enable) if (!Unit::SetWalk(enable)) return false; - WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_WALK_MODE : SMSG_MOVE_SPLINE_SET_RUN_MODE, 9); + WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9); data.append(GetPackGUID()); SendMessageToSet(&data, false); return true; @@ -2474,7 +2480,7 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/) if (!movespline->Initialized()) return true; - WorldPacket data(disable ? SMSG_MOVE_SPLINE_DISABLE_GRAVITY : SMSG_MOVE_SPLINE_ENABLE_GRAVITY, 9); + WorldPacket data(disable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9); data.append(GetPackGUID()); SendMessageToSet(&data, false); return true; @@ -2495,7 +2501,7 @@ bool Creature::SetHover(bool enable) return true; //! Not always a packet is sent - WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_HOVER : SMSG_MOVE_SPLINE_UNSET_HOVER, 9); + WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9); data.append(GetPackGUID()); SendMessageToSet(&data, false); return true; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 906dc827d3f..1824e2c1b44 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -679,6 +679,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); } Position GetHomePosition() { return m_homePosition; } + void SetTransportHomePosition(float x, float y, float z, float o) { m_transportHomePosition.Relocate(x, y, z, o); } + void SetTransportHomePosition(const Position &pos) { m_transportHomePosition.Relocate(pos); } + void GetTransportHomePosition(float &x, float &y, float &z, float &ori) { m_transportHomePosition.GetPosition(x, y, z, ori); } + Position GetTransportHomePosition() { return m_transportHomePosition; } + uint32 GetWaypointPath(){return m_path_id;} void LoadPath(uint32 pathid) { m_path_id = pathid; } @@ -752,6 +757,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature uint32 m_originalEntry; Position m_homePosition; + Position m_transportHomePosition; bool DisableReputationGain; diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 829eb73bf80..537bbd9c099 100755 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -36,6 +36,7 @@ class TempSummon : public Creature Unit* GetSummoner() const; uint64 GetSummonerGUID() { return m_summonerGUID; } TempSummonType const& GetSummonType() { return m_type; } + uint32 GetTimer() { return m_timer; } const SummonPropertiesEntry* const m_Properties; private: diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 7591359230a..2a74d262daf 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -338,7 +338,7 @@ void GameObject::Update(uint32 diff) if (m_respawnTime <= now) // timer expired { uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_GAMEOBJECT); - time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId()); + time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid); if (linkedRespawntime) // Can't respawn, the master is dead { uint64 targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid); @@ -761,13 +761,13 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap) else { m_respawnDelayTime = data->spawntimesecs; - m_respawnTime = sObjectMgr->GetGORespawnTime(m_DBTableGuid, map->GetInstanceId()); + m_respawnTime = GetMap()->GetGORespawnTime(m_DBTableGuid); // ready to respawn if (m_respawnTime && m_respawnTime <= time(NULL)) { m_respawnTime = 0; - sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId()); + GetMap()->RemoveGORespawnTime(m_DBTableGuid); } } } @@ -788,7 +788,7 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap) void GameObject::DeleteFromDB() { - sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId()); + GetMap()->RemoveGORespawnTime(m_DBTableGuid); sObjectMgr->DeleteGOData(m_DBTableGuid); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); @@ -863,7 +863,7 @@ Unit* GameObject::GetOwner() const void GameObject::SaveRespawnTime() { if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault) - sObjectMgr->SaveGORespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime); + GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime); } bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const @@ -908,7 +908,7 @@ void GameObject::Respawn() if (m_spawnedByDefault && m_respawnTime > 0) { m_respawnTime = time(NULL); - sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId()); + GetMap()->RemoveGORespawnTime(m_DBTableGuid); } } @@ -1711,7 +1711,13 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const void GameObject::EventInform(uint32 eventId) { - if (eventId && m_zoneScript) + if (!eventId) + return; + + if (AI()) + AI()->EventInform(eventId); + + if (m_zoneScript) m_zoneScript->ProcessEvent(this, eventId); } diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index d973c3ba4f8..248b080bfdd 100755 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -274,7 +274,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, itemProto->Spells[i].SpellCharges); - SetUInt32Value(ITEM_FIELD_DURATION, abs(itemProto->Duration)); + SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration); SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0); return true; } @@ -420,7 +420,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { - SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration)); + SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration); need_save = true; } diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 54570e9b708..d38e8c32e30 100755 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -242,6 +242,7 @@ class Item : public Object bool IsLocked() const { return !HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED); } bool IsBag() const { return GetTemplate()->InventoryType == INVTYPE_BAG; } + bool IsCurrencyToken() const { return GetTemplate()->IsCurrencyToken(); } bool IsNotEmptyBag() const; bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; } bool CanBeTraded(bool mail = false, bool trade = false) const; diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 048da0b231c..2da0e721a20 100755 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -202,6 +202,12 @@ enum ItemFlagsExtra ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND = 0x00020000, }; +enum ItemFlagsCustom +{ + ITEM_FLAGS_CU_DURATION_REAL_TIME = 0x0001, // Item duration will tick even if player is offline + ITEM_FLAGS_CU_IGNORE_QUEST_STATUS = 0x0002, // No quest status will be checked when this item drops +}; + enum BAG_FAMILY_MASK { BAG_FAMILY_MASK_NONE = 0x00000000, @@ -641,7 +647,7 @@ struct ItemTemplate uint32 socketBonus; // id from SpellItemEnchantment.dbc uint32 GemProperties; // id from GemProperties.dbc float ArmorDamageModifier; - int32 Duration; // negative = realtime, positive = ingame time + uint32 Duration; uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc uint32 HolidayId; // id from Holidays.dbc float StatScalingFactor; @@ -661,6 +667,7 @@ struct ItemTemplate uint32 FoodType; uint32 MinMoneyLoot; uint32 MaxMoneyLoot; + uint32 FlagsCu; // helpers bool CanChangeEquipStateInCombat() const @@ -683,6 +690,8 @@ struct ItemTemplate return false; } + bool IsCurrencyToken() const { return BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS; } + uint32 GetMaxStackSize() const { return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 0d18a47885f..1a04f7b3053 100755 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -34,11 +34,11 @@ #define CONTACT_DISTANCE 0.5f #define INTERACTION_DISTANCE 5.0f #define ATTACK_DISTANCE 5.0f -#define MAX_VISIBILITY_DISTANCE 500.0f // max distance for visible objects +#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects #define SIGHT_RANGE_UNIT 50.0f -#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents -#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards -#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards +#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents +#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards +#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards #define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects #define DEFAULT_COMBAT_REACH 1.5f @@ -500,13 +500,13 @@ struct MovementInfo t_seat = -1; } - uint32 GetMovementFlags() { return flags; } + uint32 GetMovementFlags() const { return flags; } void SetMovementFlags(uint32 flag) { flags = flag; } void AddMovementFlag(uint32 flag) { flags |= flag; } void RemoveMovementFlag(uint32 flag) { flags &= ~flag; } bool HasMovementFlag(uint32 flag) const { return flags & flag; } - uint16 GetExtraMovementFlags() { return flags2; } + uint16 GetExtraMovementFlags() const { return flags2; } void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; } bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 6e988a79c29..5759a58a575 100755 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -153,6 +153,7 @@ class Pet : public Guardian bool HaveInDiet(ItemTemplate const* item) const; uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel); void SetDuration(int32 dur) { m_duration = dur; } + int32 GetDuration() { return m_duration; } /* bool UpdateStats(Stats stat); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e8d89110f82..ba7ca524521 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3403,7 +3403,7 @@ void Player::SendInitialSpells() uint16 spellCooldowns = m_spellCooldowns.size(); data << uint16(spellCooldowns); - for (SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr) + for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr) { SpellInfo const* sEntry = sSpellMgr->GetSpellInfo(itr->first); if (!sEntry) @@ -4828,7 +4828,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC // bones will be deleted by corpse/bones deleting thread shortly sObjectAccessor->ConvertCorpseForPlayer(playerguid); - if (uint32 guildId = GetGuildIdFromGuid(playerguid)) + if (uint32 guildId = GetGuildIdFromDB(playerguid)) if (Guild* guild = sGuildMgr->GetGuildById(guildId)) guild->DeleteMember(guid); @@ -5176,8 +5176,8 @@ void Player::SetMovement(PlayerMovementType pType) { case MOVE_ROOT: data.Initialize(SMSG_MOVE_ROOT, GetPackGUID().size()+4); break; case MOVE_UNROOT: data.Initialize(SMSG_MOVE_UNROOT, GetPackGUID().size()+4); break; - case MOVE_WATER_WALK: data.Initialize(SMSG_MOVE_SPLINE_SET_WATER_WALK, GetPackGUID().size()+4); break; - case MOVE_LAND_WALK: data.Initialize(SMSG_MOVE_SPLINE_SET_LAND_WALK, GetPackGUID().size()+4); break; + case MOVE_WATER_WALK: data.Initialize(SMSG_SPLINE_MOVE_SET_WATER_WALK, GetPackGUID().size()+4); break; + case MOVE_LAND_WALK: data.Initialize(SMSG_SPLINE_MOVE_SET_LAND_WALK, GetPackGUID().size()+4); break; default: sLog->outError("Player::SetMovement: Unsupported move type (%d), data not sent to client.", pType); return; @@ -7270,7 +7270,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto uint8 k_level = getLevel(); uint8 k_grey = Trinity::XP::GetGrayLevel(k_level); - uint8 v_level = plrVictim->getLevel(); + uint8 v_level = victim->getLevel(); if (v_level <= k_grey) return false; @@ -7281,7 +7281,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto // [15..28] Horde honor titles and player name // [29..38] Other title and player name // [39+] Nothing - uint32 victim_title = plrVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE); + uint32 victim_title = victim->GetUInt32Value(PLAYER_CHOSEN_TITLE); // Get Killer titles, CharTitlesEntry::bit_index // Ranks: // title[1..14] -> rank[5..18] @@ -7303,10 +7303,10 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto // and those in a lifetime ApplyModUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 1, true); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, plrVictim->getClass()); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, plrVictim->getRace()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, victim->getClass()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId()); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, plrVictim); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim); } else { @@ -7548,7 +7548,7 @@ uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const return cap; } -uint32 Player::GetGuildIdFromGuid(uint64 guid) +uint32 Player::GetGuildIdFromDB(uint64 guid) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUILD_ID); stmt->setUInt64(0, guid); @@ -8227,7 +8227,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (CanUseAttackType(attType)) _ApplyWeaponDamage(slot, proto, ssv, apply); - } void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply) @@ -9157,7 +9156,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type) loot->loot_type = loot_type; WorldPacket data(SMSG_LOOT_RESPONSE, 8 + 1 + 50 + 1 + 1); // we guess size - data << uint64(guid); data << uint8(loot_type); data << LootView(*loot, this, permission); @@ -10734,7 +10732,7 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; // currencytoken case - if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)) + if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->IsCurrencyToken())) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; // prevent cheating @@ -11087,7 +11085,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } } - else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) + else if (pProto->IsCurrencyToken()) { res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot); if (res != EQUIP_ERR_OK) @@ -11254,7 +11252,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } } - else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) + else if (pProto->IsCurrencyToken()) { res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot); if (res != EQUIP_ERR_OK) @@ -11503,7 +11501,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const if (b_found) continue; - if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) + if (pProto->IsCurrencyToken()) { for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) { @@ -12755,7 +12753,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ { ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount); pItem->SetCount(pItem->GetCount() - count + remcount); - if (IsInWorld() & update) + if (IsInWorld() && update) pItem->SendUpdateToPlayer(this); pItem->SetState(ITEM_CHANGED, this); return; @@ -12783,7 +12781,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ { ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount); pItem->SetCount(pItem->GetCount() - count + remcount); - if (IsInWorld() & update) + if (IsInWorld() && update) pItem->SendUpdateToPlayer(this); pItem->SetState(ITEM_CHANGED, this); return; @@ -12849,7 +12847,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ { ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount); pItem->SetCount(pItem->GetCount() - count + remcount); - if (IsInWorld() & update) + if (IsInWorld() && update) pItem->SendUpdateToPlayer(this); pItem->SetState(ITEM_CHANGED, this); return; @@ -12924,6 +12922,11 @@ Item* Player::GetItemByEntry(uint32 entry) const if (pItem->GetEntry() == entry) return pItem; + for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) + if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (pItem->GetEntry() == entry) + return pItem; + for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); ++j) @@ -12957,7 +12960,7 @@ void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update) ItemRemovedQuestCheck(pItem->GetEntry(), count); pItem->SetCount(pItem->GetCount() - count); count = 0; - if (IsInWorld() & update) + if (IsInWorld() && update) pItem->SendUpdateToPlayer(this); pItem->SetState(ITEM_CHANGED, this); } @@ -13545,9 +13548,9 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint } case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: // no idea about this one... { - data << uint64(0); - data << uint32(0); - data << uint64(0); + data << uint64(0); // item guid + data << uint32(0); // slot + data << uint64(0); // container break; } case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED: @@ -13653,7 +13656,7 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly) Item* item = *itr; ++itr; // current element can be erased in UpdateDuration - if ((realtimeonly && item->GetTemplate()->Duration < 0) || !realtimeonly) + if (!realtimeonly || item->GetTemplate()->FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME) item->UpdateDuration(this, time); } } @@ -14226,7 +14229,7 @@ void Player::SendNewItem(Item* item, uint32 count, bool received, bool created, data << uint64(GetGUID()); // player GUID data << uint32(received); // 0=looted, 1=from npc data << uint32(created); // 0=received, 1=created - data << uint32(1); // always 0x01 (probably meant to be count of listed items) + data << uint32(1); // bool print error to chat data << uint8(item->GetBagSlot()); // bagslot // item slot, but when added to stack: 0xFFFFFFFF data << uint32((item->GetCount() == count) ? item->GetSlot() : -1); @@ -20160,8 +20163,10 @@ void Player::PetSpellInitialize() WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*MAX_UNIT_ACTION_BAR_INDEX+1+1); data << uint64(pet->GetGUID()); data << uint16(pet->GetCreatureTemplate()->family); // creature family (required for pet talents) - data << uint32(0); - data << uint8(pet->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); + data << uint32(pet->GetDuration()); + data << uint8(pet->GetReactState()); + data << uint8(charmInfo->GetCommandState()); + data << uint16(0); // Flags, mostly unknown // action bar loop charmInfo->BuildActionBar(&data); @@ -20194,22 +20199,33 @@ void Player::PetSpellInitialize() for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr) { - time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0; - - data << uint32(itr->first); // spellid - data << uint16(0); // spell category? - data << uint32(cooldown); // cooldown - data << uint32(0); // category cooldown - } + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); + if (!spellInfo) + { + data << uint32(0); + data << uint16(0); + data << uint32(0); + data << uint32(0); + continue; + } - for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr) - { time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0; + data << uint32(itr->first); // spell ID - data << uint32(itr->first); // spellid - data << uint16(0); // spell category? - data << uint32(0); // cooldown - data << uint32(cooldown); // category cooldown + CreatureSpellCooldowns::const_iterator categoryitr = pet->m_CreatureCategoryCooldowns.find(spellInfo->Category); + if (categoryitr != pet->m_CreatureCategoryCooldowns.end()) + { + time_t categoryCooldown = (categoryitr->second > curTime) ? (categoryitr->second - curTime) * IN_MILLISECONDS : 0; + data << uint16(spellInfo->Category); // spell category + data << uint32(cooldown); // spell cooldown + data << uint32(categoryCooldown); // category cooldown + } + else + { + data << uint16(0); + data << uint32(cooldown); + data << uint32(0); + } } GetSession()->SendPacket(&data); @@ -20245,24 +20261,24 @@ void Player::PossessSpellInitialize() void Player::VehicleSpellInitialize() { - Creature* veh = GetVehicleCreatureBase(); - if (!veh) + Creature* vehicle = GetVehicleCreatureBase(); + if (!vehicle) return; - uint8 cooldownCount = veh->m_CreatureSpellCooldowns.size() + veh->m_CreatureCategoryCooldowns.size(); + uint8 cooldownCount = vehicle->m_CreatureSpellCooldowns.size(); WorldPacket data(SMSG_PET_SPELLS, 8 + 2 + 4 + 4 + 4 * 10 + 1 + 1 + cooldownCount * (4 + 2 + 4 + 4)); - data << uint64(veh->GetGUID()); - data << uint16(veh->GetCreatureTemplate()->family); - data << uint32(0); - // The following three segments are read as one uint32 - data << uint8(veh->GetReactState()); - data << uint8(0); // CommandState? - data << uint16(0); // unk + data << uint64(vehicle->GetGUID()); // Guid + data << uint16(0); // Pet Family (0 for all vehicles) + data << uint32(vehicle->isSummon() ? vehicle->ToTempSummon()->GetTimer() : 0); // Duration + // The following three segments are read by the client as one uint32 + data << uint8(vehicle->GetReactState()); // React State + data << uint8(0); // Command State + data << uint16(0x800); // DisableActions (set for all vehicles) for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { - uint32 spellId = veh->m_spells[i]; + uint32 spellId = vehicle->m_spells[i]; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { @@ -20270,54 +20286,59 @@ void Player::VehicleSpellInitialize() continue; } - ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(veh->GetEntry(), spellId); - if (!sConditionMgr->IsObjectMeetToConditions(this, veh, conditions)) + ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(vehicle->GetEntry(), spellId); + if (!sConditionMgr->IsObjectMeetToConditions(this, vehicle, conditions)) { - sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", veh->ToCreature()->GetEntry(), spellId); + sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", vehicle->ToCreature()->GetEntry(), spellId); data << uint16(0) << uint8(0) << uint8(i+8); continue; } if (spellInfo->IsPassive()) - { - veh->CastSpell(veh, spellId, true); - data << uint16(0) << uint8(0) << uint8(i+8); - } - else - data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8)); + vehicle->CastSpell(vehicle, spellId, true); + + data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8)); } for (uint32 i = CREATURE_MAX_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i) - data << uint16(0) << uint8(0) << uint8(i+8); + data << uint32(0); - data << uint8(0); - /*if (v23 > 0) - { - for (uint32 i = 0; i < v23; ++i) - data << uint32(v16); // Some spellid? - }*/ + data << uint8(0); // Auras? // Cooldowns - data << cooldownCount; + data << uint8(cooldownCount); time_t now = sWorld->GetGameTime(); - CreatureSpellCooldowns::const_iterator itr; - for (itr = veh->m_CreatureSpellCooldowns.begin(); itr != veh->m_CreatureSpellCooldowns.end(); ++itr) - { - time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0; - data << uint32(itr->first); // SpellId - data << uint16(0); // unk - data << uint32(cooldown); // spell cooldown - data << uint32(0); // category cooldown - } - for (itr = veh->m_CreatureCategoryCooldowns.begin(); itr != veh->m_CreatureCategoryCooldowns.end(); ++itr) + for (CreatureSpellCooldowns::const_iterator itr = vehicle->m_CreatureSpellCooldowns.begin(); itr != vehicle->m_CreatureSpellCooldowns.end(); ++itr) { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); + if (!spellInfo) + { + data << uint32(0); + data << uint16(0); + data << uint32(0); + data << uint32(0); + continue; + } + time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0; - data << uint32(itr->first); // SpellId - data << uint16(0); // unk - data << uint32(0); // spell cooldown - data << uint32(cooldown); // category cooldown + data << uint32(itr->first); // spell ID + + CreatureSpellCooldowns::const_iterator categoryitr = vehicle->m_CreatureCategoryCooldowns.find(spellInfo->Category); + if (categoryitr != vehicle->m_CreatureCategoryCooldowns.end()) + { + time_t categoryCooldown = (categoryitr->second > now) ? (categoryitr->second - now) * IN_MILLISECONDS : 0; + data << uint16(spellInfo->Category); // spell category + data << uint32(cooldown); // spell cooldown + data << uint32(categoryCooldown); // category cooldown + } + else + { + data << uint16(0); + data << uint32(cooldown); + data << uint32(0); + } } GetSession()->SendPacket(&data); @@ -20356,7 +20377,7 @@ void Player::CharmSpellInitialize() if (charm->GetTypeId() != TYPEID_PLAYER) data << uint8(charm->ToCreature()->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); else - data << uint8(0) << uint8(0) << uint16(0); + data << uint32(0); charmInfo->BuildActionBar(&data); @@ -20581,7 +20602,7 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type) else { stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE); - stmt->setUInt8(0, uint8(type)); + stmt->setUInt8(1, uint8(type)); } stmt->setUInt32(0, GUID_LOPART(guid)); @@ -22319,8 +22340,8 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3 data << uint32(time); if (type == RAID_INSTANCE_WELCOME) { - data << uint8(0); // is your (1) - data << uint8(0); // is extended (1), ignored if prev field is 0 + data << uint8(0); // is locked + data << uint8(0); // is extended, ignored if prev field is 0 } GetSession()->SendPacket(&data); } @@ -23366,7 +23387,7 @@ Player* Player::GetNextRandomRaidMember(float radius) PartyResult Player::CanUninviteFromGroup() const { - const Group* grp = GetGroup(); + Group const* grp = GetGroup(); if (!grp) return ERR_NOT_IN_GROUP; @@ -23389,8 +23410,12 @@ PartyResult Player::CanUninviteFromGroup() const if (grp->isRollLootActive()) return ERR_PARTY_LFG_BOOT_LOOT_ROLLS; + // TODO: Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer. + for (GroupReference const* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + if (itr->getSource() && itr->getSource()->isInCombat()) + return ERR_PARTY_LFG_BOOT_IN_COMBAT; + /* Missing support for these types - return ERR_PARTY_LFG_BOOT_IN_COMBAT; // also have a cooldown (some secs after combat finish return ERR_PARTY_LFG_BOOT_COOLDOWN_S; return ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S; */ @@ -25639,8 +25664,8 @@ void Player::SendMovementSetCanFly(bool apply) void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply) { WorldPacket data(apply ? - SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY : - SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY, 12); + SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY : + SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, 12); data.append(GetPackGUID()); data << uint32(0); //! movement counter SendDirectMessage(&data); @@ -25648,7 +25673,7 @@ void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply) void Player::SendMovementSetHover(bool apply) { - WorldPacket data(apply ? SMSG_MOVE_SET_HOVERING : SMSG_MOVE_SPLINE_UNSET_HOVER, 12); + WorldPacket data(apply ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12); data.append(GetPackGUID()); data << uint32(0); //! movement counter SendDirectMessage(&data); @@ -25656,7 +25681,7 @@ void Player::SendMovementSetHover(bool apply) void Player::SendMovementSetWaterWalking(bool apply) { - WorldPacket data(apply ? SMSG_MOVE_SET_WATER_WALK : SMSG_MOVE_SET_LAND_WALK, 12); + WorldPacket data(apply ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12); data.append(GetPackGUID()); data << uint32(0); //! movement counter SendDirectMessage(&data); @@ -25664,7 +25689,7 @@ void Player::SendMovementSetWaterWalking(bool apply) void Player::SendMovementSetFeatherFall(bool apply) { - WorldPacket data(apply ? SMSG_MOVE_SET_FEATHER_FALL : SMSG_MOVE_SET_NORMAL_FALL, 12); + WorldPacket data(apply ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12); data.append(GetPackGUID()); data << uint32(0); //! movement counter SendDirectMessage(&data); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 24a1c35b8e2..dbe9cd94a21 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1888,7 +1888,7 @@ class Player : public Unit, public GridObject<Player> m_guildId = GuildId; } uint32 GetGuildId() { return m_guildId; } - static uint32 GetGuildIdFromGuid(uint64 guid); + static uint32 GetGuildIdFromDB(uint64 guid); void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); } uint8 GetRank() { return uint8(GetUInt32Value(PLAYER_GUILDRANK)); } @@ -2049,6 +2049,7 @@ class Player : public Unit, public GridObject<Player> StopMirrorTimer(BREATH_TIMER); StopMirrorTimer(FIRE_TIMER); } + bool IsMirrorTimerActive(MirrorTimerType type) { return m_MirrorTimer[type] == getMaxTimer(type); } void SetMovement(PlayerMovementType pType); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index a00fcae1e09..ef3e1331a4c 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -656,6 +656,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, o + GetOrientation()); creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); + creature->SetTransportHomePosition(creature->m_movementInfo.t_pos); if (!creature->IsPositionValid()) { @@ -698,11 +699,33 @@ void Transport::UpdateNPCPositions() Creature* npc = *itr; float x, y, z, o; - o = GetOrientation() + npc->m_movementInfo.t_pos.m_orientation; - x = GetPositionX() + (npc->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI)); - y = GetPositionY() + (npc->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionX * sin(GetOrientation())); - z = GetPositionZ() + npc->m_movementInfo.t_pos.m_positionZ; - npc->SetHomePosition(x, y, z, o); + npc->m_movementInfo.t_pos.GetPosition(x, y, z, o); + CalculatePassengerPosition(x, y, z, o); GetMap()->CreatureRelocation(npc, x, y, z, o, false); + npc->GetTransportHomePosition(x, y, z, o); + CalculatePassengerPosition(x, y, z, o); + npc->SetHomePosition(x, y, z, o); } } + +//! This method transforms supplied transport offsets into global coordinates +void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float& o) +{ + float inx = x, iny = y, inz = z, ino = o; + o = GetOrientation() + ino; + x = GetPositionX() + (inx * cos(GetOrientation()) + iny * sin(GetOrientation() + M_PI)); + y = GetPositionY() + (iny * cos(GetOrientation()) + inx * sin(GetOrientation())); + z = GetPositionZ() + inz; +} + +//! This method transforms supplied global coordinates into local offsets +void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o) +{ + o -= GetOrientation(); + z -= GetPositionZ(); + y -= GetPositionY(); // y = searchedY * cos(o) + searchedX * sin(o) + x -= GetPositionX(); // x = searchedX * cos(o) + searchedY * sin(o + pi) + float inx = x, iny = y; + y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) - sin(GetOrientation() + M_PI) * tan(GetOrientation())); + x = (inx - iny * sin(GetOrientation() + M_PI) / cos(GetOrientation())) / (cos(GetOrientation()) - tan(GetOrientation()) * sin(GetOrientation() + M_PI)); +} diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 518dcf6359d..4b0c42c9071 100755 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -47,6 +47,8 @@ class Transport : public GameObject uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0); void UpdatePosition(MovementInfo* mi); void UpdateNPCPositions(); + void CalculatePassengerPosition(float& x, float& y, float& z, float& o); + void CalculatePassengerOffset(float& x, float& y, float& z, float& o); void BuildStartMovePacket(Map const* targetMap); void BuildStopMovePacket(Map const* targetMap); uint32 GetScriptId() const { return ScriptId; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 347a51a67d9..5fe8f0bf657 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -396,10 +396,25 @@ void Unit::UpdateSplineMovement(uint32 t_diff) m_movesplineTimer.Reset(POSITION_UPDATE_DELAY); Movement::Location loc = movespline->ComputePosition(); - if (GetTypeId() == TYPEID_PLAYER) - ((Player*)this)->UpdatePosition(loc.x,loc.y,loc.z,loc.orientation); - else - GetMap()->CreatureRelocation((Creature*)this,loc.x,loc.y,loc.z,loc.orientation); + if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + { + Position& pos = m_movementInfo.t_pos; + pos.m_positionX = loc.x; + pos.m_positionY = loc.y; + pos.m_positionZ = loc.z; + pos.m_orientation = loc.orientation; + if (Unit* vehicle = GetVehicleBase()) + { + loc.x += vehicle->GetPositionX(); + loc.y += vehicle->GetPositionY(); + loc.z += vehicle->GetPositionZMinusOffset(); + loc.orientation = vehicle->GetOrientation(); + } + else if (Transport* trans = GetTransport()) + trans->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation); + } + + UpdatePosition(loc.x, loc.y, loc.z, loc.orientation); } } @@ -409,50 +424,6 @@ void Unit::DisableSpline() movespline->_Interrupt(); } -void Unit::SendMonsterMoveExitVehicle(Position const* newPos) -{ - WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size()); - data.append(GetPackGUID()); - - data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // new in 3.1, bool - data << GetPositionX() << GetPositionY() << GetPositionZ(); - data << getMSTime(); - - data << uint8(SPLINETYPE_FACING_ANGLE); - data << float(GetOrientation()); // guess - data << uint32(SPLINEFLAG_EXIT_VEHICLE); - data << uint32(0); // Time in between points - data << uint32(1); // 1 single waypoint - data << newPos->GetPositionX(); - data << newPos->GetPositionY(); - data << newPos->GetPositionZ(); - - SendMessageToSet(&data, true); -} - -void Unit::SendMonsterMoveTransport(Unit* vehicleOwner) -{ - // TODO: Turn into BuildMonsterMoveTransport packet and allow certain variables (for npc movement aboard vehicles) - WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicleOwner->GetPackGUID().size() + 47); - data.append(GetPackGUID()); - data.append(vehicleOwner->GetPackGUID()); - data << int8(GetTransSeat()); - data << uint8(0); - data << GetPositionX() - vehicleOwner->GetPositionX(); - data << GetPositionY() - vehicleOwner->GetPositionY(); - data << GetPositionZ() - vehicleOwner->GetPositionZ(); - data << uint32(getMSTime()); // should be an increasing constant that indicates movement packet count - data << uint8(SPLINETYPE_FACING_ANGLE); - data << GetTransOffsetO(); // facing angle? - data << uint32(SPLINEFLAG_TRANSPORT); - data << uint32(GetTransTime()); // move time - data << uint32(1); // amount of waypoints - data << uint32(0); // waypoint X - data << uint32(0); // waypoint Y - data << uint32(0); // waypoint Z - SendMessageToSet(&data, true); -} - void Unit::resetAttackTimer(WeaponAttackType type) { m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); @@ -556,13 +527,7 @@ void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb) if (absorb) *absorb += damage; damage = 0; - return; } - - uint32 originalDamage = damage; - - if (absorb && originalDamage > damage) - *absorb += (originalDamage - damage); } uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss) @@ -839,11 +804,6 @@ void Unit::CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo return; } - // TODO: this is a workaround and needs removal - if (!originalCaster && GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem() && IsControlledByPlayer()) - if (Unit* owner = GetOwner()) - originalCaster=owner->GetGUID(); - // TODO: this is a workaround - not needed anymore, but required for some scripts :( if (!originalCaster && triggeredByAura) originalCaster = triggeredByAura->GetCasterGUID(); @@ -2503,12 +2463,12 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell) // Chance resist debuff if (!spell->IsPositive()) { - bool bNegativeAura = false; + bool bNegativeAura = true; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (spell->Effects[i].ApplyAuraName != 0) + if (spell->Effects[i].ApplyAuraName == 0) { - bNegativeAura = true; + bNegativeAura = false; break; } } @@ -2931,9 +2891,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell) InterruptSpell(CURRENT_AUTOREPEAT_SPELL); m_AutoRepeatFirstCast = true; } - AddUnitState(UNIT_STATE_CASTING); - } break; + if (pSpell->m_spellInfo->CalcCastTime(this) > 0) + AddUnitState(UNIT_STATE_CASTING); + break; + } case CURRENT_CHANNELED_SPELL: { // channel spells always break generic non-delayed and any channeled spells @@ -2945,8 +2907,9 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell) m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75) InterruptSpell(CURRENT_AUTOREPEAT_SPELL); AddUnitState(UNIT_STATE_CASTING); - } break; + break; + } case CURRENT_AUTOREPEAT_SPELL: { // only Auto Shoot does not break anything @@ -2958,12 +2921,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell) } // special action: set first cast flag m_AutoRepeatFirstCast = true; - } break; + break; + } default: - { - // other spell types don't break anything now - } break; + break; // other spell types don't break anything now } // current spell (if it is still here) may be safely deleted now @@ -3638,87 +3600,6 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId // Call AfterDispel hook on AuraScript aura->CallScriptAfterDispel(&dispelInfo); - switch (aura->GetSpellInfo()->SpellFamilyName) - { - case SPELLFAMILY_WARLOCK: - { - // Unstable Affliction (crash if before removeaura?) - if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x0100) - { - Unit* caster = aura->GetCaster(); - if (!caster) - break; - if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_0)) - { - int32 damage = aurEff->GetAmount() * 9; - // backfire damage and silence - caster->CastCustomSpell(dispeller, 31117, &damage, NULL, NULL, true, NULL, aurEff); - } - } - break; - } - case SPELLFAMILY_DRUID: - { - // Lifebloom - if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x10) - { - if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_1)) - { - // final heal - int32 healAmount = aurEff->GetAmount(); - if (Unit* caster = aura->GetCaster()) - { - healAmount = caster->SpellHealingBonusDone(this, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges()); - healAmount = this->SpellHealingBonusTaken(caster, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges()); - } - CastCustomSpell(this, 33778, &healAmount, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID()); - - // mana - if (Unit* caster = aura->GetCaster()) - { - int32 mana = CalculatePctU(caster->GetCreateMana(), aura->GetSpellInfo()->ManaCostPercentage) * chargesRemoved / 2; - caster->CastCustomSpell(caster, 64372, &mana, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID()); - } - } - } - break; - } - case SPELLFAMILY_SHAMAN: - { - // Flame Shock - if (aura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10000000) - { - if (Unit* caster = aura->GetCaster()) - { - uint32 triggeredSpellId = 0; - // Lava Flows - if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 3087, 0)) - { - switch (aurEff->GetId()) - { - case 51482: // Rank 3 - triggeredSpellId = 65264; - break; - case 51481: // Rank 2 - triggeredSpellId = 65263; - break; - case 51480: // Rank 1 - triggeredSpellId = 64694; - break; - default: - sLog->outError("Unit::RemoveAurasDueToSpellByDispel: Unknown rank of Lava Flows (%d) found", aurEff->GetId()); - } - } - - if (triggeredSpellId) - caster->CastSpell(caster, triggeredSpellId, true); - } - } - break; - } - default: - break; - } return; } else @@ -8328,6 +8209,14 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg CastSpell(victim, 27526, true, castItem, triggeredByAura); return true; } + // Evasive Maneuvers + case 50240: + { + // Remove a Evasive Charge + Aura* charge = GetAura(50241); + if (charge->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL)) + RemoveAurasDueToSpell(50240); + } } break; case SPELLFAMILY_MAGE: @@ -8982,12 +8871,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg CastSpell(this, 70721, true); break; } - // Bloodthirst (($m/100)% of max health) - case 23880: - { - basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); - break; - } // Shamanistic Rage triggered spell case 30824: { @@ -10159,7 +10042,7 @@ Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo) Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET); for (Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr) { - if (Unit* magnet = (*itr)->GetBase()->GetUnitOwner()) + if (Unit* magnet = (*itr)->GetBase()->GetCaster()) if (spellInfo->CheckExplicitTarget(this, magnet) == SPELL_CAST_OK && spellInfo->CheckTarget(this, magnet, false) == SPELL_CAST_OK && _IsValidAttackTarget(magnet, spellInfo) @@ -10801,6 +10684,15 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui int32 TakenTotal = 0; float TakenTotalMod = 1.0f; + float TakenTotalCasterMod = 0.0f; + + // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) + AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); + for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i) + { + if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) + TakenTotalCasterMod += (float((*i)->GetAmount())/100); + } // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) @@ -10865,7 +10757,22 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod); } - float tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod; + float tmpDamage = 0.0f; + + if (TakenTotalCasterMod) + { + if (TakenTotal < 0) + { + if (TakenTotalMod < 1) + tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod)); + else + tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod); + } + else if (TakenTotalMod < 1) + tmpDamage = ((CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod)); + } + if (!tmpDamage) + tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod; return uint32(std::max(tmpDamage, 0.0f)); } @@ -11575,6 +11482,8 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) { // State/effect immunities applied by aura expect full spell immunity // Ignore effects with mechanic, they are supposed to be checked separately + if (!spellInfo->Effects[i].IsEffect()) + continue; if (!IsImmunedToSpellEffect(spellInfo, i)) { immuneToAllEffects = false; @@ -11820,6 +11729,16 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT return 0; int32 TakenFlatBenefit = 0; + float TakenTotalCasterMod = 0.0f; + + // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) + SpellSchoolMask attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL; + AuraEffectList const& IgnoreResistAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); + for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i) + { + if ((*i)->GetMiscValue() & attackSchoolMask) + TakenTotalCasterMod += (float((*i)->GetAmount())/100); + } // ..taken AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN); @@ -11904,7 +11823,22 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT AddPctN(TakenTotalMod, (*i)->GetAmount()); } - float tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod; + float tmpDamage = 0.0f; + + if (TakenTotalCasterMod) + { + if (TakenFlatBenefit < 0) + { + if (TakenTotalMod < 1) + tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod)); + else + tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod); + } + else if (TakenTotalMod < 1) + tmpDamage = ((CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod)); + } + if (!tmpDamage) + tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod; // bonus result can be negative return uint32(std::max(tmpDamage, 0.0f)); @@ -12730,7 +12664,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) { // Set creature speed rate from CreatureInfo if (GetTypeId() == TYPEID_UNIT) - speed *= ToCreature()->GetCreatureTemplate()->speed_walk; + speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need // TODO: possible affect only on MOVE_RUN @@ -12795,10 +12729,10 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) switch (mtype) { case MOVE_WALK: - data.Initialize(SMSG_MOVE_SPLINE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4); break; case MOVE_RUN: - data.Initialize(SMSG_MOVE_SPLINE_SET_RUN_SPEED, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_SPEED, 1 + 8 + 4); data.WriteByteMask(bytes[7]); data.WriteByteMask(bytes[2]); data.WriteByteMask(bytes[1]); @@ -12820,7 +12754,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) data << float(GetSpeed(mtype)); break; case MOVE_RUN_BACK: - data.Initialize(SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, 1 + 8 + 4); data.WriteByteMask(bytes[4]); data.WriteByteMask(bytes[0]); data.WriteByteMask(bytes[6]); @@ -12842,7 +12776,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) data << float(GetSpeed(mtype)); break; case MOVE_SWIM: - data.Initialize(SMSG_MOVE_SPLINE_SET_SWIM_SPEED, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, 1 + 8 + 4); data.WriteByteMask(bytes[3]); data.WriteByteMask(bytes[5]); data.WriteByteMask(bytes[7]); @@ -12863,7 +12797,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) data.WriteByteSeq(bytes[5]); break; case MOVE_SWIM_BACK: - data.Initialize(SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, 1 + 8 + 4); data.WriteByteMask(bytes[3]); data.WriteByteMask(bytes[5]); data.WriteByteMask(bytes[4]); @@ -12884,7 +12818,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) data.WriteByteSeq(bytes[5]); break; case MOVE_TURN_RATE: - data.Initialize(SMSG_MOVE_SPLINE_SET_TURN_RATE, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_TURN_RATE, 1 + 8 + 4); data.WriteByteMask(bytes[0]); data.WriteByteMask(bytes[4]); data.WriteByteMask(bytes[5]); @@ -12905,7 +12839,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) data.WriteByteSeq(bytes[3]); break; case MOVE_FLIGHT: - data.Initialize(SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, 1 + 8 + 4); data.WriteByteMask(bytes[2]); data.WriteByteMask(bytes[3]); data.WriteByteMask(bytes[5]); @@ -12927,7 +12861,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) data.WriteByteSeq(bytes[4]); break; case MOVE_FLIGHT_BACK: - data.Initialize(SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4); data.WriteByteMask(bytes[1]); data.WriteByteMask(bytes[6]); data.WriteByteMask(bytes[0]); @@ -12948,7 +12882,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) data.WriteByteSeq(bytes[3]); break; case MOVE_PITCH_RATE: - data.Initialize(SMSG_MOVE_SPLINE_SET_PITCH_RATE, 1 + 8 + 4); + data.Initialize(SMSG_SPLINE_MOVE_SET_PITCH_RATE, 1 + 8 + 4); data.WriteByteMask(bytes[7]); data.WriteByteMask(bytes[2]); data.WriteByteMask(bytes[3]); @@ -13379,8 +13313,7 @@ void Unit::TauntFadeOut(Unit* taunter) return; } - //m_ThreatManager.tauntFadeOut(taunter); - target = m_ThreatManager.getHostilTarget(); + target = creature->SelectVictim(); // might have more taunt auras remaining if (target && target != taunter) { @@ -13464,7 +13397,7 @@ Unit* Creature::SelectVictim() else return NULL; - if (target && _IsTargetAcceptable(target)) + if (target && _IsTargetAcceptable(target) && canCreatureAttack(target)) { SetInFront(target); return target; @@ -13490,7 +13423,7 @@ Unit* Creature::SelectVictim() { target = SelectNearestTargetInAttackDistance(m_CombatDistance ? m_CombatDistance : ATTACK_DISTANCE); - if (target && _IsTargetAcceptable(target)) + if (target && _IsTargetAcceptable(target) && canCreatureAttack(target)) return target; } @@ -13672,7 +13605,7 @@ void Unit::ModSpellCastTime(SpellInfo const* spellProto, int32 & castTime, Spell if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime, spell); - if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && spellProto->SpellFamilyName) + if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && ((GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName) || GetTypeId() == TYPEID_UNIT)) castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED)); else if (spellProto->Attributes & SPELL_ATTR0_REQ_AMMO && !(spellProto->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG)) castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]); @@ -15007,6 +14940,11 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check takeCharges = true; break; + case SPELL_AURA_SPELL_MAGNET: + // Skip Melee hits and targets with magnet aura + if (procSpell && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit())) // Magnet + takeCharges = true; + break; case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: case SPELL_AURA_MOD_POWER_COST_SCHOOL: // Skip melee hits and spells ws wrong school or zero cost @@ -15235,6 +15173,7 @@ void Unit::StopMoving() return; Movement::MoveSplineInit init(*this); + init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); init.SetFacing(GetOrientation()); init.Launch(); } @@ -16347,7 +16286,7 @@ void Unit::SetRooted(bool apply) } else { - WorldPacket data(SMSG_MOVE_SPLINE_ROOT, 8); + WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8); data.append(GetPackGUID()); SendMessageToSet(&data, true); ToCreature()->StopMoving(); @@ -16366,7 +16305,7 @@ void Unit::SetRooted(bool apply) } else { - WorldPacket data(SMSG_MOVE_SPLINE_UNROOT, 8); + WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); data.append(GetPackGUID()); SendMessageToSet(&data, true); } @@ -16747,7 +16686,7 @@ Creature* Unit::GetVehicleCreatureBase() const uint64 Unit::GetTransGUID() const { if (GetVehicle()) - return GetVehicle()->GetBase()->GetGUID(); + return GetVehicleBase()->GetGUID(); if (GetTransport()) return GetTransport()->GetGUID(); @@ -17529,7 +17468,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) Creature* creature = ToCreature(); if (creature && creature->IsAIEnabled) - creature->AI()->DoAction(EVENT_SPELLCLICK); + creature->AI()->OnSpellClick(clicker); return true; } @@ -17649,11 +17588,12 @@ void Unit::_ExitVehicle(Position const* exitPosition) Vehicle* vehicle = m_vehicle; m_vehicle = NULL; - SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT + SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT Position pos; - if (!exitPosition) // Exit position not specified - vehicle->GetBase()->GetPosition(&pos); + if (!exitPosition) // Exit position not specified + vehicle->GetBase()->GetPosition(&pos); // This should use passenger's current position, leaving it as it is now + // because we calculate positions incorrect (sometimes under map) else pos = *exitPosition; @@ -17663,19 +17603,22 @@ void Unit::_ExitVehicle(Position const* exitPosition) ToPlayer()->SetFallInformation(0, GetPositionZ()); else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT)) { - WorldPacket data(SMSG_MOVE_SPLINE_UNROOT, 8); + WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); data.append(GetPackGUID()); SendMessageToSet(&data, false); } - SendMonsterMoveExitVehicle(&pos); - Relocate(&pos); + Movement::MoveSplineInit init(*this); + init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + init.SetFacing(GetOrientation()); + init.SetTransportExit(); + init.Launch(); + + //GetMotionMaster()->MoveFall(); // Enable this once passenger positions are calculater properly (see above) if (Player* player = ToPlayer()) player->ResummonPetTemporaryUnSummonedIfAny(); - SendMovementFlagUpdate(); - if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION)) if (((Minion*)vehicle->GetBase())->GetOwner() == this) vehicle->Dismiss(); @@ -17693,24 +17636,13 @@ void Unit::_ExitVehicle(Position const* exitPosition) void Unit::BuildMovementPacket(ByteBuffer *data) const { - switch (GetTypeId()) - { - case TYPEID_UNIT: - if (CanFly()) - const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); - break; - case TYPEID_PLAYER: - // remove unknown, unused etc flags for now - const_cast<Unit*>(this)->RemoveUnitMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED); - if (isInFlight()) - { - WPAssert(const_cast<Unit*>(this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE); - const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE_ENABLED); - } - break; - default: - break; - } + *data << uint32(GetUnitMovementFlags()); // movement flags + *data << uint16(GetExtraUnitMovementFlags()); // 2.3.0 + *data << uint32(getMSTime()); // time / counter + *data << GetPositionX(); + *data << GetPositionY(); + *data << GetPositionZMinusOffset(); + *data << GetOrientation(); bool onTransport = GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT; bool hasInterpolatedMovement = m_movementInfo.flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT; @@ -18116,6 +18048,7 @@ void Unit::SetInFront(Unit const* target) void Unit::SetFacingTo(float ori) { Movement::MoveSplineInit init(*this); + init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); init.SetFacing(ori); init.Launch(); } @@ -18187,7 +18120,7 @@ void Unit::SendMovementHover() if (GetTypeId() == TYPEID_PLAYER) ToPlayer()->SendMovementSetHover(HasUnitMovementFlag(MOVEMENTFLAG_HOVER)); - WorldPacket data(MSG_MOVE_HOVER, 64); // SMSG_MOVE_SET_HOVERING? + WorldPacket data(MSG_MOVE_HOVER, 64); data.append(GetPackGUID()); BuildMovementPacket(&data); SendMessageToSet(&data, false); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 9d6c22ab8b5..6d188fe3593 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -735,19 +735,6 @@ enum MovementFlags2 MOVEMENTFLAG2_UNK16 = 0x00008000, }; -enum SplineFlags -{ - SPLINEFLAG_WALKMODE = 0x00001000, - SPLINEFLAG_FLYING = 0x00002000, - SPLINEFLAG_TRANSPORT = 0x00800000, - SPLINEFLAG_EXIT_VEHICLE = 0x01000000, -}; - -enum SplineType -{ - SPLINETYPE_FACING_ANGLE = 4, -}; - enum UnitTypeMask { UNIT_MASK_NONE = 0x00000000, @@ -806,8 +793,8 @@ public: m_dispeller(_dispeller), m_dispellerSpellId(_dispellerSpellId), m_chargesRemoved(_chargesRemoved) {} Unit* GetDispeller() { return m_dispeller; } - uint32 GetDispellerSpellId() { return m_dispellerSpellId; } - uint8 GetRemovedCharges() { return m_chargesRemoved; } + uint32 GetDispellerSpellId() const { return m_dispellerSpellId; } + uint8 GetRemovedCharges() const { return m_chargesRemoved; } void SetRemovedCharges(uint8 amount) { m_chargesRemoved = amount; @@ -1350,10 +1337,10 @@ class Unit : public WorldObject uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); } bool IsFullHealth() const { return GetHealth() == GetMaxHealth(); } - bool HealthBelowPct(int32 pct) const { return GetHealth() * uint64(100) < GetMaxHealth() * uint64(pct); } - bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return (int32(GetHealth()) - damage) * int64(100) < GetMaxHealth() * int64(pct); } - bool HealthAbovePct(int32 pct) const { return GetHealth() * uint64(100) > GetMaxHealth() * uint64(pct); } - bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return (GetHealth() + heal) * uint64(100) > GetMaxHealth() * uint64(pct); } + bool HealthBelowPct(int32 pct) const { return GetHealth() < CountPctFromMaxHealth(pct); } + bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return int64(GetHealth()) - int64(damage) < int64(CountPctFromMaxHealth(pct)); } + bool HealthAbovePct(int32 pct) const { return GetHealth() > CountPctFromMaxHealth(pct); } + bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return uint64(GetHealth()) + uint64(heal) > CountPctFromMaxHealth(pct); } float GetHealthPct() const { return GetMaxHealth() ? 100.f * GetHealth() / GetMaxHealth() : 0.0f; } uint32 CountPctFromMaxHealth(int32 pct) const { return CalculatePctN(GetMaxHealth(), pct); } uint32 CountPctFromCurHealth(int32 pct) const { return CalculatePctN(GetHealth(), pct); } @@ -1632,9 +1619,7 @@ class Unit : public WorldObject void MonsterMoveWithSpeed(float x, float y, float z, float speed); //void SetFacing(float ori, WorldObject* obj = NULL); - void SendMonsterMoveExitVehicle(Position const* newPos); //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); - void SendMonsterMoveTransport(Unit* vehicleOwner); void SendMovementFlagUpdate(); /*! These methods send the same packet to the client in apply and unapply case. diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 090a1db382a..eb50f3fe229 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -28,6 +28,7 @@ #include "ZoneScript.h" #include "SpellMgr.h" #include "SpellInfo.h" +#include "MoveSplineInit.h" Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry) { @@ -338,7 +339,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) } } - if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK1)) + if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING)) unit->AddUnitState(UNIT_STATE_ONVEHICLE); unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); @@ -364,7 +365,12 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) unit->SendClearTarget(); // SMSG_BREAK_TARGET unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT - unit->SendMonsterMoveTransport(_me); // SMSG_MONSTER_MOVE_TRANSPORT + Movement::MoveSplineInit init(*unit); + init.DisableTransportPathTransformations(); + init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ); + init.SetFacing(0.0f); + init.SetTransportEnter(); + init.Launch(); if (_me->GetTypeId() == TYPEID_UNIT) { @@ -372,7 +378,8 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) _me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true); // update all passenger's positions - RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation()); + //Passenger's spline OR vehicle movement will update positions + //RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation()); } } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 43381267545..71ce341185e 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -461,7 +461,7 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.SkinLootId = fields[48].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[50 + i -1].GetInt16(); + creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); @@ -1884,71 +1884,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data } } -void ObjectMgr::LoadCreatureRespawnTimes() -{ - uint32 oldMSTime = getMSTime(); - - uint32 count = 0; - - PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS)); - if (!result) - { - sLog->outString(">> Loaded 0 creature respawn time."); - sLog->outString(); - return; - } - - do - { - Field* fields = result->Fetch(); - - uint32 loguid = fields[0].GetUInt32(); - uint32 respawn_time = fields[1].GetUInt32(); - uint32 instance = fields[2].GetUInt32(); - - _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time); - - ++count; - } while (result->NextRow()); - - sLog->outString(">> Loaded %lu creature respawn times in %u ms", (unsigned long)_creatureRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime)); - sLog->outString(); -} - -void ObjectMgr::LoadGameobjectRespawnTimes() -{ - uint32 oldMSTime = getMSTime(); - - // Remove outdated data - CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawnTime <= UNIX_TIMESTAMP(NOW())"); - - uint32 count = 0; - - PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS)); - if (!result) - { - sLog->outString(">> Loaded 0 gameobject respawn times. DB table `gameobject_respawn` is empty!"); - sLog->outString(); - return; - } - - do - { - Field* fields = result->Fetch(); - - uint32 loguid = fields[0].GetUInt32(); - uint32 respawn_time = fields[1].GetUInt32(); - uint32 instance = fields[2].GetUInt32(); - - _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time); - - ++count; - } while (result->NextRow()); - - sLog->outString(); - sLog->outString(">> Loaded %lu gameobject respawn times in %u ms", (unsigned long)_goRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime)); -} - Player* ObjectMgr::GetPlayerByLowGUID(uint32 lowguid) const { uint64 guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER); @@ -2613,7 +2548,7 @@ void ObjectMgr::LoadItemTemplateAddon() uint32 oldMSTime = getMSTime(); uint32 count = 0; - QueryResult result = WorldDatabase.Query("SELECT Id, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon"); + QueryResult result = WorldDatabase.Query("SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon"); if (result) { do @@ -2626,16 +2561,8 @@ void ObjectMgr::LoadItemTemplateAddon() continue; } - uint8 buyCount = fields[1].GetUInt8(); - if (!buyCount) - { - sLog->outErrorDb("Item %u has BuyCount set to 0, corrected to 1.", itemId); - buyCount = 1; - } - - uint8 foodType = fields[1].GetUInt8(); - uint32 minMoneyLoot = fields[2].GetUInt32(); - uint32 maxMoneyLoot = fields[3].GetUInt32(); + uint32 minMoneyLoot = fields[3].GetUInt32(); + uint32 maxMoneyLoot = fields[4].GetUInt32(); if (minMoneyLoot > maxMoneyLoot) { sLog->outErrorDb("Minimum money loot specified in `item_template_addon` for item %u was greater than maximum amount, swapping.", itemId); @@ -2643,10 +2570,11 @@ void ObjectMgr::LoadItemTemplateAddon() } ItemTemplate& itemTemplate = _itemTemplateStore[itemId]; - itemTemplate.FoodType = foodType; + itemTemplate.FlagsCu = fields[1].GetUInt32(); + itemTemplate.FoodType = fields[2].GetUInt8(); itemTemplate.MinMoneyLoot = minMoneyLoot; itemTemplate.MaxMoneyLoot = maxMoneyLoot; - itemTemplate.SpellPPMRate = fields[4].GetFloat(); + itemTemplate.SpellPPMRate = fields[5].GetFloat(); ++count; } while (result->NextRow()); } @@ -2739,6 +2667,7 @@ void ObjectMgr::LoadItemSetNames() } // 0 1 2 + // 0 1 2 QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`"); if (!result) @@ -5043,11 +4972,11 @@ void ObjectMgr::LoadSpellScriptNames() Field* fields = result->Fetch(); - int32 spellId = fields[0].GetInt32(); + int32 spellId = fields[0].GetInt32(); const char *scriptName = fields[1].GetCString(); bool allRanks = false; - if (spellId <=0) + if (spellId <= 0) { allRanks = true; spellId = -spellId; @@ -6783,7 +6712,7 @@ uint32 ObjectMgr::GetBaseXP(uint8 level) return _baseXPTable[level] ? _baseXPTable[level] : 0; } -uint32 ObjectMgr::GetXPForLevel(uint8 level) +uint32 ObjectMgr::GetXPForLevel(uint8 level) const { if (level < _playerXPperLevel.size()) return _playerXPperLevel[level]; @@ -7340,44 +7269,6 @@ void ObjectMgr::LoadNPCSpellClickSpells() sLog->outString(); } -void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t) -{ - if (!t) - { - // Delete only - RemoveCreatureRespawnTime(loguid, instance); - return; - } - - // This function can be called from various map threads concurrently - { - _creatureRespawnTimesMutex.acquire(); - _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = t; - _creatureRespawnTimesMutex.release(); - } - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN); - stmt->setUInt32(0, loguid); - stmt->setUInt32(1, uint32(t)); - stmt->setUInt32(2, instance); - CharacterDatabase.Execute(stmt); -} - -void ObjectMgr::RemoveCreatureRespawnTime(uint32 loguid, uint32 instance) -{ - // This function can be called from various map threads concurrently - { - _creatureRespawnTimesMutex.acquire(); - _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0; - _creatureRespawnTimesMutex.release(); - } - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); - stmt->setUInt32(0, loguid); - stmt->setUInt32(1, instance); - CharacterDatabase.Execute(stmt); -} - void ObjectMgr::DeleteCreatureData(uint32 guid) { // remove mapid*cellid -> guid_set map @@ -7388,81 +7279,6 @@ void ObjectMgr::DeleteCreatureData(uint32 guid) _creatureDataStore.erase(guid); } -void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t) -{ - if (!t) - { - // Delete only - RemoveGORespawnTime(loguid, instance); - return; - } - - // This function can be called from different map threads concurrently - { - _goRespawnTimesMutex.acquire(); - _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = t; - _goRespawnTimesMutex.release(); - } - - PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN); - stmt->setUInt32(0, loguid); - stmt->setUInt64(1, uint64(t)); - stmt->setUInt32(2, instance); - CharacterDatabase.Execute(stmt); -} - -void ObjectMgr::RemoveGORespawnTime(uint32 loguid, uint32 instance) -{ - // This function can be called from different map threads concurrently - { - _goRespawnTimesMutex.acquire(); - _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0; - _goRespawnTimesMutex.release(); - } - - PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN); - stmt->setUInt32(0, loguid); - stmt->setUInt32(1, instance); - CharacterDatabase.Execute(stmt); -} - -void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance) -{ - // This function can be called from different map threads concurrently - RespawnTimes::iterator next; - - { - _goRespawnTimesMutex.acquire(); - for (RespawnTimes::iterator itr = _goRespawnTimes.begin(); itr != _goRespawnTimes.end(); itr = next) - { - next = itr; - ++next; - - if (GUID_HIPART(itr->first) == instance) - _goRespawnTimes.erase(itr); - } - _goRespawnTimesMutex.release(); - } - { - _creatureRespawnTimesMutex.acquire(); - for (RespawnTimes::iterator itr = _creatureRespawnTimes.begin(); itr != _creatureRespawnTimes.end(); itr = next) - { - next = itr; - ++next; - - if (GUID_HIPART(itr->first) == instance) - _creatureRespawnTimes.erase(itr); - } - _creatureRespawnTimesMutex.release(); - } - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE); - stmt->setUInt32(0, instance); - CharacterDatabase.Execute(stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE); - stmt->setUInt32(0, instance); - CharacterDatabase.Execute(stmt); -} - void ObjectMgr::DeleteGOData(uint32 guid) { // remove mapid*cellid -> guid_set map diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 9ab7898573f..742259aa536 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -367,8 +367,6 @@ struct CellObjectGuids typedef UNORDERED_MAP<uint32/*cell_id*/, CellObjectGuids> CellObjectGuidsMap; typedef UNORDERED_MAP<uint32/*(mapid, spawnMode) pair*/, CellObjectGuidsMap> MapObjectGuids; -typedef UNORDERED_MAP<uint64/*(instance, guid) pair*/, time_t> RespawnTimes; - // Trinity string ranges #define MIN_TRINITY_STRING_ID 1 // 'trinity_string' #define MAX_TRINITY_STRING_ID 2000000000 @@ -624,14 +622,14 @@ class ObjectMgr Player* GetPlayerByLowGUID(uint32 lowguid) const; GameObjectTemplate const* GetGameObjectTemplate(uint32 entry); - GameObjectTemplateContainer const* GetGameObjectTemplates() { return &_gameObjectTemplateStore; } + GameObjectTemplateContainer const* GetGameObjectTemplates() const { return &_gameObjectTemplateStore; } int LoadReferenceVendor(int32 vendor, int32 item_id, std::set<uint32> *skip_vendors); void LoadGameObjectTemplate(); void AddGameobjectInfo(GameObjectTemplate* goinfo); CreatureTemplate const* GetCreatureTemplate(uint32 entry); - CreatureTemplateContainer const* GetCreatureTemplates() { return &_creatureTemplateStore; } + CreatureTemplateContainer const* GetCreatureTemplates() const { return &_creatureTemplateStore; } CreatureModelInfo const* GetCreatureModelInfo(uint32 modelId); CreatureModelInfo const* GetCreatureModelRandomGender(uint32* displayID); static uint32 ChooseDisplayId(uint32 team, const CreatureTemplate* cinfo, const CreatureData* data = NULL); @@ -640,7 +638,7 @@ class ObjectMgr CreatureAddon const* GetCreatureAddon(uint32 lowguid); CreatureAddon const* GetCreatureTemplateAddon(uint32 entry); ItemTemplate const* GetItemTemplate(uint32 entry); - ItemTemplateContainer const* GetItemTemplateStore() { return &_itemTemplateStore; } + ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; } ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId) { @@ -863,13 +861,11 @@ class ObjectMgr void LoadCreatures(); void LoadLinkedRespawn(); bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid); - void LoadCreatureRespawnTimes(); void LoadCreatureAddons(); void LoadCreatureModelInfo(); void LoadEquipmentTemplates(); void LoadGameObjectLocales(); void LoadGameobjects(); - void LoadGameobjectRespawnTimes(); void LoadItemTemplates(); void LoadItemTemplateAddon(); void LoadItemScriptNames(); @@ -927,7 +923,7 @@ class ObjectMgr std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint8 level); - uint32 GetXPForLevel(uint8 level); + uint32 GetXPForLevel(uint8 level) const; int32 GetFishingBaseSkillLevel(uint32 entry) const { @@ -1059,36 +1055,6 @@ class ObjectMgr void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance); void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid); - time_t GetLinkedRespawnTime(uint64 guid, uint32 instance) - { - uint64 linkedGuid = GetLinkedRespawnGuid(guid); - switch (GUID_HIPART(linkedGuid)) - { - case HIGHGUID_UNIT: - return GetCreatureRespawnTime(GUID_LOPART(linkedGuid), instance); - case HIGHGUID_GAMEOBJECT: - return GetGORespawnTime(GUID_LOPART(linkedGuid), instance); - default: - return 0; - } - } - - time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance) - { - TRINITY_GUARD(ACE_Thread_Mutex, _creatureRespawnTimesMutex); - return _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)]; - } - void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t); - void RemoveCreatureRespawnTime(uint32 loguid, uint32 instance); - time_t GetGORespawnTime(uint32 loguid, uint32 instance) - { - TRINITY_GUARD(ACE_Thread_Mutex, _goRespawnTimesMutex); - return _goRespawnTimes[MAKE_PAIR64(loguid, instance)]; - } - void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t); - void RemoveGORespawnTime(uint32 loguid, uint32 instance); - void DeleteRespawnTimeForInstance(uint32 instance); - // grid objects void AddCreatureToGrid(uint32 guid, CreatureData const* data); void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data); @@ -1143,7 +1109,7 @@ class ObjectMgr void LoadScriptNames(); ScriptNameContainer &GetScriptNames() { return _scriptNamesStore; } - const char * GetScriptName(uint32 id) { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; } + const char * GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; } uint32 GetScriptId(const char *name); SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const @@ -1321,10 +1287,6 @@ class ObjectMgr TrinityStringLocaleContainer _trinityStringLocaleStore; GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore; PointOfInterestLocaleContainer _pointOfInterestLocaleStore; - RespawnTimes _creatureRespawnTimes; - ACE_Thread_Mutex _creatureRespawnTimesMutex; - RespawnTimes _goRespawnTimes; - ACE_Thread_Mutex _goRespawnTimesMutex; CacheVendorItemContainer _cacheVendorItemStore; CacheTrainerSpellContainer _cacheTrainerSpellStore; @@ -1339,7 +1301,6 @@ class ObjectMgr GO_TO_GO, GO_TO_CREATURE, // GO is dependant on creature }; - HotfixData _hotfixData; }; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 54bc1206e18..75df3e67c5a 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1325,11 +1325,16 @@ namespace Trinity { public: UnitAuraCheck(bool present, uint32 spellId, uint64 casterGUID = 0) : _present(present), _spellId(spellId), _casterGUID(casterGUID) {} - bool operator()(Unit* unit) + bool operator()(Unit* unit) const { return unit->HasAura(_spellId, _casterGUID) == _present; } + bool operator()(WorldObject* object) const + { + return object->ToUnit() && object->ToUnit()->HasAura(_spellId, _casterGUID) == _present; + } + private: bool _present; uint32 _spellId; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 4c6b6249887..743d56886f0 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -556,7 +556,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV roll->playerVote.erase(itr2); - CountRollVote(guid, roll->itemGUID, GetMembersCount()-1, MAX_ROLL_TYPE); + CountRollVote(guid, roll->itemGUID, MAX_ROLL_TYPE); } // Update subgroups @@ -763,7 +763,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r) WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1)); data << uint64(r.itemGUID); // guid of rolled item data << uint32(mapid); // 3.3.3 mapid - data << uint32(r.itemSlot); // slot + data << uint32(r.itemSlot); // itemslot data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for data << uint32(r.itemRandomSuffix); // randomSuffix data << uint32(r.itemRandomPropId); // item random property ID @@ -791,7 +791,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1)); data << uint64(r.itemGUID); // guid of rolled item data << uint32(mapId); // 3.3.3 mapid - data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it??? + data << uint32(r.itemSlot); // itemslot data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for data << uint32(r.itemRandomSuffix); // randomSuffix data << uint32(r.itemRandomPropId); // item random property ID @@ -805,20 +805,20 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, p->GetSession()->SendPacket(&data); } -void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) +void Group::SendLootRoll(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll) { WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1)); - data << uint64(SourceGuid); // guid of the item rolled - data << uint32(0); // unknown, maybe amount of players - data << uint64(TargetGuid); - data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for - data << uint32(r.itemRandomSuffix); // randomSuffix - data << uint32(r.itemRandomPropId); // Item random property ID - data << uint8(RollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number - data << uint8(RollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll - data << uint8(0); // auto pass on NeedBeforeGreed loot because player cannot use the object + data << uint64(sourceGuid); // guid of the item rolled + data << uint32(roll.itemSlot); // slot + data << uint64(targetGuid); + data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for + data << uint32(roll.itemRandomSuffix); // randomSuffix + data << uint32(roll.itemRandomPropId); // Item random property ID + data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number + data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll + data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed - for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr) + for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) { Player* p = ObjectAccessor::FindPlayer(itr->first); if (!p || !p->GetSession()) @@ -829,19 +829,19 @@ void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, } } -void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r) +void Group::SendLootRollWon(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll) { WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1)); - data << uint64(SourceGuid); // guid of the item rolled - data << uint32(0); // unknown, maybe amount of players - data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for - data << uint32(r.itemRandomSuffix); // randomSuffix - data << uint32(r.itemRandomPropId); // Item random property - data << uint64(TargetGuid); // guid of the player who won. - data << uint8(RollNumber); // rollnumber realted to SMSG_LOOT_ROLL - data << uint8(RollType); // Rolltype related to SMSG_LOOT_ROLL + data << uint64(sourceGuid); // guid of the item rolled + data << uint32(roll.itemSlot); // slot + data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for + data << uint32(roll.itemRandomSuffix); // randomSuffix + data << uint32(roll.itemRandomPropId); // Item random property + data << uint64(targetGuid); // guid of the player who won. + data << uint8(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL + data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL - for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr) + for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) { Player* p = ObjectAccessor::FindPlayer(itr->first); if (!p || !p->GetSession()) @@ -852,11 +852,11 @@ void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumb } } -void Group::SendLootAllPassed(uint32 numberOfPlayers, Roll const& roll) +void Group::SendLootAllPassed(Roll const& roll) { WorldPacket data(SMSG_LOOT_ALL_PASSED, (8+4+4+4+4)); data << uint64(roll.itemGUID); // Guid of the item rolled - data << uint32(numberOfPlayers); // The number of players rolling for it + data << uint32(roll.itemSlot); // Item loot slot data << uint32(roll.itemid); // The itemEntryId for the item that shall be rolled for data << uint32(roll.itemRandomPropId); // Item random property ID data << uint32(roll.itemRandomSuffix); // Item random suffix ID @@ -1099,7 +1099,7 @@ void Group::MasterLoot(Loot* /*loot*/, WorldObject* pLootedObject) } } -void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choice) +void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choice) { Rolls::iterator rollI = GetRoll(Guid); if (rollI == RollId.end()) @@ -1140,7 +1140,7 @@ void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers } if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling) - CountTheRoll(rollI, NumberOfPlayers); + CountTheRoll(rollI); } //called when roll timer expires @@ -1149,7 +1149,7 @@ void Group::EndRoll(Loot* pLoot) for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();) { if ((*itr)->getLoot() == pLoot) { - CountTheRoll(itr, GetMembersCount()); //i don't have to edit player votes, who didn't vote ... he will pass + CountTheRoll(itr); //i don't have to edit player votes, who didn't vote ... he will pass itr = RollId.begin(); } else @@ -1157,7 +1157,7 @@ void Group::EndRoll(Loot* pLoot) } } -void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers) +void Group::CountTheRoll(Rolls::iterator rollI) { Roll* roll = *rollI; if (!roll->isValid()) // is loot already deleted ? @@ -1280,7 +1280,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers) } else { - SendLootAllPassed(NumberOfPlayers, *roll); + SendLootAllPassed(*roll); // remove is_blocked so that the item is lootable by all players LootItem* item = &(roll->getLoot()->items[roll->itemSlot]); @@ -2107,20 +2107,6 @@ bool Group::HasFreeSlotSubGroup(uint8 subgroup) const return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE); } -Group::MemberSlotList const& Group::GetMemberSlots() const -{ - return m_memberSlots; -} - -GroupReference* Group::GetFirstMember() -{ - return m_memberMgr.getFirst(); -} - -uint32 Group::GetMembersCount() const -{ - return m_memberSlots.size(); -} uint8 Group::GetMemberGroup(uint64 guid) const { diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 08246614627..f909b755829 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -232,9 +232,11 @@ class Group bool SameSubGroup(Player const* member1, Player const* member2) const; bool HasFreeSlotSubGroup(uint8 subgroup) const; - MemberSlotList const& GetMemberSlots() const; - GroupReference* GetFirstMember(); - uint32 GetMembersCount() const; + MemberSlotList const& GetMemberSlots() const { return m_memberSlots; } + GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); } + GroupReference const* GetFirstMember() const { return m_memberMgr.getFirst(); } + uint32 GetMembersCount() const { return m_memberSlots.size(); } + uint8 GetMemberGroup(uint64 guid) const; void ConvertToLFG(); @@ -279,14 +281,14 @@ class Group void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r); void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); - void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r); + void SendLootAllPassed(Roll const& roll); void SendLooter(Creature* creature, Player* pLooter); void GroupLoot(Loot* loot, WorldObject* pLootedObject); void NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject); void MasterLoot(Loot* loot, WorldObject* pLootedObject); Rolls::iterator GetRoll(uint64 Guid); - void CountTheRoll(Rolls::iterator roll, uint32 NumberOfPlayers); - void CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise); + void CountTheRoll(Rolls::iterator roll); + void CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choise); void EndRoll(Loot* loot); // related to disenchant rolls diff --git a/src/server/game/Groups/GroupRefManager.h b/src/server/game/Groups/GroupRefManager.h index 9bcc05f8724..d9fef8611de 100755 --- a/src/server/game/Groups/GroupRefManager.h +++ b/src/server/game/Groups/GroupRefManager.h @@ -28,7 +28,8 @@ class GroupReference; class GroupRefManager : public RefManager<Group, Player> { public: - GroupReference* getFirst() { return ((GroupReference*) RefManager<Group, Player>::getFirst()); } + GroupReference* getFirst() { return ((GroupReference*)RefManager<Group, Player>::getFirst()); } + GroupReference const* getFirst() const { return ((GroupReference const*)RefManager<Group, Player>::getFirst()); } }; #endif diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h index 2048fd9cb0d..7960dd21035 100755 --- a/src/server/game/Groups/GroupReference.h +++ b/src/server/game/Groups/GroupReference.h @@ -35,6 +35,7 @@ class GroupReference : public Reference<Group, Player> GroupReference() : Reference<Group, Player>(), iSubGroup(0) {} ~GroupReference() { unlink(); } GroupReference* next() { return (GroupReference*)Reference<Group, Player>::next(); } + GroupReference const* next() const { return (GroupReference const*)Reference<Group, Player>::next(); } uint8 getSubGroup() const { return iSubGroup; } void setSubGroup(uint8 pSubGroup) { iSubGroup = pSubGroup; } }; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index dfeb3f7cad9..b57e9970dab 100755 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2093,7 +2093,7 @@ bool Guild::AddMember(uint64 guid, uint8 rankId) if (player->GetGuildId() != 0) return false; } - else if (Player::GetGuildIdFromGuid(guid) != 0) + else if (Player::GetGuildIdFromDB(guid) != 0) return false; // Remove all player signs from another petitions diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 27eb559fb68..95204dfa353 100755 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -161,7 +161,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) etime *= MINUTE; - switch(etime) + switch (etime) { case 1*MIN_AUCTION_TIME: case 2*MIN_AUCTION_TIME: diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 887bebe5656..1c79b20ce81 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1868,9 +1868,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) case RACE_NIGHTELF: stmt->setUInt16(1, 113); break; - case RACE_WORGEN: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 791, 300, 300)", lowGuid); - break; + case RACE_WORGEN: + stmt->setUInt16(1, 791); + break; case RACE_UNDEAD_PLAYER: stmt->setUInt16(1, 673); break; @@ -1883,9 +1883,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) case RACE_BLOODELF: stmt->setUInt16(1, 137); break; - case RACE_GOBLIN: - trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 792, 300, 300)", lowGuid); - break; + case RACE_GOBLIN: + stmt->setUInt16(1, 792); + break; } trans->Append(stmt); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index d725419ac84..eadc0958518 100755 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -458,24 +458,20 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket & recv_data) group->SendUpdate(); } -void WorldSession::HandleLootRoll(WorldPacket &recv_data) +void WorldSession::HandleLootRoll(WorldPacket& recvData) { + uint64 guid; + uint32 itemSlot; + uint8 rollType; + recvData >> guid; // guid of the item rolled + recvData >> itemSlot; + recvData >> rollType; // 0: pass, 1: need, 2: greed + Group* group = GetPlayer()->GetGroup(); if (!group) - { - recv_data.rfinish(); return; - } - uint64 Guid; - uint32 NumberOfPlayers; - uint8 rollType; - recv_data >> Guid; //guid of the item rolled - recv_data >> NumberOfPlayers; - recv_data >> rollType; //0: pass, 1: need, 2: greed - - // everything's fine, do it - group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, rollType); + group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType); switch (rollType) { diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 2d85a4cb689..5baa54a2779 100755 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1369,6 +1369,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item) + _player->RemoveTradeableItem(itemTarget); itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 82afdfb9044..9c66ca44383 100755 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -529,7 +529,7 @@ void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot) } sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s", guid, uint8(pBoot->inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), pBoot->victim, votesNum, agreeNum, secsleft, pBoot->votedNeeded, pBoot->reason.c_str()); - WorldPacket data(SMSG_LFG_BOOT_PLAYER, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length()); + WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length()); data << uint8(pBoot->inProgress); // Vote in progress data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 8e4b41a9be4..339c7a44d9f 100755 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -220,16 +220,18 @@ void WorldSession::HandleLootOpcode(WorldPacket & recv_data) GetPlayer()->InterruptNonMeleeSpells(false); } -void WorldSession::HandleLootReleaseOpcode(WorldPacket & recv_data) +void WorldSession::HandleLootReleaseOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_RELEASE"); // cheaters can modify lguid to prevent correct apply loot release code and re-loot // use internal stored guid - recv_data.read_skip<uint64>(); // guid; + uint64 guid; + recvData >> guid; if (uint64 lguid = GetPlayer()->GetLootGUID()) - DoLootRelease(lguid); + if (lguid == guid) + DoLootRelease(lguid); } void WorldSession::DoLootRelease(uint64 lguid) diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 988857558c9..ce056d2729c 100755 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -107,7 +107,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) uint32 reqmoney = cost + money; - if (!player->HasEnoughMoney(reqmoney)) + if (!player->HasEnoughMoney(reqmoney) && !player->isGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 247db1975a4..46e40e16c08 100755 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -494,7 +494,7 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recv_data) uint32 newZone; recv_data >> newZone; - sLog->outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd ZONE_UPDATE: %u", newZone); // use server size data uint32 newzone, newarea; @@ -737,7 +737,7 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data) void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data) { - sLog->outDetail("WORLD: Received CMSG_RECLAIM_CORPSE"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RECLAIM_CORPSE"); uint64 guid; recv_data >> guid; @@ -774,7 +774,7 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data) void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data) { - sLog->outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RESURRECT_RESPONSE"); uint64 guid; uint8 status; @@ -945,7 +945,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) { - sLog->outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); uint32 type, timestamp, decompressedSize; recv_data >> type >> timestamp >> decompressedSize; @@ -1000,7 +1000,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) { - sLog->outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); uint32 type; recv_data >> type; @@ -1079,12 +1079,12 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) void WorldSession::HandleCompleteCinematic(WorldPacket & /*recv_data*/) { - sLog->outStaticDebug("WORLD: Player is watching cinema"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC"); } void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recv_data*/) { - sLog->outStaticDebug("WORLD: Which movie to play"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA"); } void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data) @@ -1127,7 +1127,7 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data) void WorldSession::HandleFeatherFallAck(WorldPacket &recv_data) { - sLog->outStaticDebug("WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); // no used recv_data.rfinish(); // prevent warnings spam @@ -1215,13 +1215,17 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data) { uint64 guid; recv_data >> guid; - sLog->outStaticDebug("Inspected guid is " UI64FMTD, guid); + + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT"); _player->SetSelection(guid); Player* player = ObjectAccessor::FindPlayer(guid); - if (!player) // wrong player + if (!player) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_INSPECT: No player found from GUID: " UI64FMTD, guid); return; + } uint32 talent_points = 41; WorldPacket data(SMSG_INSPECT_TALENT, 8 + 4 + 1 + 1 + talent_points + 8 + 4 + 8 + 4); @@ -1256,7 +1260,7 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data) if (!player) { - sLog->outError("InspectHonorStats: WTF, player not found..."); + sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid); return; } @@ -1270,10 +1274,6 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data) void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) { - // write in client console: worldport 469 452 6454 2536 180 or /console worldport 469 452 6454 2536 180 - // Received opcode CMSG_WORLD_TELEPORT - // Time is ***, map=469, x=452.000000, y=6454.000000, z=2536.000000, orient=3.141593 - uint32 time; uint32 mapid; float PositionX; @@ -1288,20 +1288,20 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) recv_data >> PositionZ; recv_data >> Orientation; // o (3.141593 = 180 degrees) - //sLog->outDebug("Received opcode CMSG_WORLD_TELEPORT"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_WORLD_TELEPORT"); + if (GetPlayer()->isInFlight()) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Player '%s' (GUID: %u) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); return; } - sLog->outStaticDebug("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation); if (AccountMgr::IsAdminAccount(GetSecurity())) GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation); else SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); - sLog->outDebug(LOG_FILTER_NETWORKIO, "Received worldport command from player %s", GetPlayer()->GetName()); } void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 40d63235af3..598dafb200a 100755 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -193,7 +193,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_MOVE_TELEPORT_ACK"); BitStream mask = recv_data.ReadBitStream(8); - + uint32 flags, time; recv_data >> flags >> time; @@ -264,6 +264,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plrMover && plrMover->IsBeingTeleported()) { + recvData.rfinish(); // prevent warnings spam return; } @@ -302,16 +303,42 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) } // if we boarded a transport, add us to it - if (plrMover && !plrMover->GetTransport()) + if (plrMover) { - // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list - for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) + if (!plrMover->GetTransport()) { - if ((*iter)->GetGUID() == movementInfo.t_guid) + // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list + for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { - plrMover->m_transport = (*iter); - (*iter)->AddPassenger(plrMover); - break; + if ((*iter)->GetGUID() == movementInfo.t_guid) + { + plrMover->m_transport = *iter; + (*iter)->AddPassenger(plrMover); + break; + } + } + } + else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid) + { + bool foundNewTransport = false; + plrMover->m_transport->RemovePassenger(plrMover); + for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) + { + if ((*iter)->GetGUID() == movementInfo.t_guid) + { + foundNewTransport = true; + plrMover->m_transport = *iter; + (*iter)->AddPassenger(plrMover); + break; + } + } + + if (!foundNewTransport) + { + plrMover->m_transport = NULL; + movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); + movementInfo.t_time = 0; + movementInfo.t_seat = -1; } } } @@ -971,4 +998,4 @@ void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi) WPError(false, "Incorrect sequence element detected at ReadMovementInfo"); } } -}
\ No newline at end of file +} diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 5f7e4ce04a8..3660bfbfcc7 100755 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -344,9 +344,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid if (unit_target2->GetTypeId() == TYPEID_PLAYER) pet->SendUpdateToPlayer((Player*)unit_target2); } + if (Unit* powner = pet->GetCharmerOrOwner()) if (powner->GetTypeId() == TYPEID_PLAYER) - pet->SendUpdateToPlayer(powner->ToPlayer()); + pet->SendUpdateToPlayer(powner->ToPlayer()); + result = SPELL_CAST_OK; } @@ -738,7 +740,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) { - sLog->outDetail("WORLD: CMSG_PET_CAST_SPELL"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL"); uint64 guid; uint8 castCount; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index f0e681b535c..c22fc309770 100755 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -113,7 +113,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data) ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName); } } - sLog->outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); // guess size WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); data << uint32(entry); // creature entry @@ -184,7 +184,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data) ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption); } } - sLog->outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry); WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150); data << uint32(entry); data << uint32(info->type); @@ -215,7 +215,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data) void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) { - sLog->outDetail("WORLD: Received MSG_CORPSE_QUERY"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_CORPSE_QUERY"); Corpse* corpse = GetPlayer()->GetCorpse(); @@ -270,7 +270,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data) uint64 guid; recv_data >> textID; - sLog->outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); recv_data >> guid; GetPlayer()->SetSelection(guid); @@ -350,7 +350,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data) /// Only _static_ data is sent in this packet !!! void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data) { - sLog->outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PAGE_TEXT_QUERY"); uint32 pageID; recv_data >> pageID; diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index ccd2e178f88..2998b8a1c75 100755 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -324,7 +324,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data) // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { - if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true)) + if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) { _player->AddQuest(nextQuest, object); if (_player->CanCompleteQuest(nextQuest->GetQuestId())) @@ -343,7 +343,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data) // Send next quest if (Quest const* nextQuest = _player->GetNextQuest(guid, quest)) { - if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true)) + if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true)) { _player->AddQuest(nextQuest, object); if (_player->CanCompleteQuest(nextQuest->GetQuestId())) @@ -496,10 +496,9 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data) if (!_player->CanInteractWithQuestGiver(object)) return; - Quest const* quest = sObjectMgr->GetQuestTemplate(questId); - if (quest) + if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { - if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId)==QUEST_STATUS_NONE) + if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) { sLog->outError("Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] without being in possession of the questId!", _player->GetName(), _player->GetGUIDLow(), questId); diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index c56d86d11db..5823a38fb42 100755 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -100,7 +100,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) return; } - sLog->outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size()); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size()); ItemTemplate const* proto = pItem->GetTemplate(); if (!proto) @@ -176,7 +176,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) { - sLog->outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size()); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size()); Player* pUser = _player; @@ -669,13 +669,16 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket) recvPacket >> z; Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid); - Spell* spell = caster ? caster->FindCurrentSpellBySpellId(spellId) : NULL; - if (spell && spell->m_targets.HasDst()) - { - Position pos = *spell->m_targets.GetDstPos(); - pos.Relocate(x, y, z); - spell->m_targets.ModDst(pos); - } + if (!caster) + return; + + Spell* spell = caster->FindCurrentSpellBySpellId(spellId); + if (!spell || !spell->m_targets.HasDst()) + return; + + Position pos = *spell->m_targets.GetDstPos(); + pos.Relocate(x, y, z); + spell->m_targets.ModDst(pos); WorldPacket data(SMSG_SET_PROJECTILE_POSITION, 21); data << uint64(casterGuid); @@ -683,5 +686,5 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket) data << float(x); data << float(y); data << float(z); - SendPacket(&data); + caster->SendMessageToSet(&data, true); } diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index 8078a91d082..59bb86cb68e 100755 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -543,7 +543,10 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId) if (iMap && iMap->IsDungeon()) ((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY); - sObjectMgr->DeleteRespawnTimeForInstance(instanceId); // even if map is not loaded + if (iMap) + iMap->DeleteRespawnTimes(); + else + Map::DeleteRespawnTimesInDB(mapid, instanceId); // Free up the instance id and allow it to be reused sMapMgr->FreeInstanceId(instanceId); diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 2100eb26346..24338d5f0ad 100755 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -356,18 +356,14 @@ bool LootItem::AllowedForPlayer(Player const* player) const if ((pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && player->GetTeam() != ALLIANCE) return false; - if (needs_quest) - { - // Checking quests for quest-only drop (check only quests requirements in this case) - if (!player->HasQuestForItem(itemid)) - return false; - } - else - { - // Not quest only drop (check quest starting items for already accepted non-repeatable quests) - if (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid)) - return false; - } + // check quest requirements + if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid))) + if (Group const* group = player->GetGroup()) + { + if (pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT || ((pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT) == 0 && (group->GetLootMethod() != MASTER_LOOT || group->GetLooterGuid() != player->GetGUID()))) + return false; + } + else return false; return true; } @@ -483,7 +479,7 @@ void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting) if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player)) if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid)) - if (proto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) + if (proto->IsCurrencyToken()) player->StoreLootItem(i, this); } } @@ -899,6 +895,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) } LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; + LootSlotType partySlotType = lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : (lv.permission == GROUP_PERMISSION ? LOOT_SLOT_TYPE_ROLL_ONGOING : slotType); QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems(); QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow()); if (q_itr != lootPlayerQuestItems.end()) @@ -911,7 +908,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) { b << uint8(l.items.size() + (qi - q_list->begin())); b << item; - b << uint8(slotType); + if (!item.freeforall) + b << uint8(partySlotType); + else + b << uint8(slotType); ++itemsShown; } } @@ -929,7 +929,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) { b << uint8(fi->index); b << item; - b << uint8(slotType); + if (!item.freeforall) + b << uint8(partySlotType); + else + b << uint8(slotType); ++itemsShown; } } @@ -947,7 +950,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) { b << uint8(ci->index); b << item; - b << uint8(slotType); + if (!item.freeforall) + b << uint8(partySlotType); + else + b << uint8(slotType); ++itemsShown; } } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 073ceae5b62..8df8feb6cac 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1230,7 +1230,7 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/) return true; } -uint16 GridMap::getArea(float x, float y) +uint16 GridMap::getArea(float x, float y) const { if (!_areaMap) return _gridArea; @@ -1463,7 +1463,7 @@ float GridMap::getHeightFromUint16(float x, float y) const return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight; } -float GridMap::getLiquidLevel(float x, float y) +float GridMap::getLiquidLevel(float x, float y) const { if (!_liquidMap) return _liquidLevel; @@ -1483,7 +1483,7 @@ float GridMap::getLiquidLevel(float x, float y) } // Why does this return LIQUID data? -uint8 GridMap::getTerrainType(float x, float y) +uint8 GridMap::getTerrainType(float x, float y) const { if (!_liquidFlags) return 0; @@ -2633,7 +2633,7 @@ void InstanceMap::UnloadAll() ASSERT(!HavePlayers()); if (m_resetAfterUnload == true) - sObjectMgr->DeleteRespawnTimeForInstance(GetInstanceId()); + DeleteRespawnTimes(); Map::UnloadAll(); } @@ -2782,3 +2782,134 @@ void Map::UpdateIteratorBack(Player* player) if (m_mapRefIter == player->GetMapRef()) m_mapRefIter = m_mapRefIter->nocheck_prev(); } + +void Map::SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime) +{ + if (!respawnTime) + { + // Delete only + RemoveCreatureRespawnTime(dbGuid); + return; + } + + _creatureRespawnTimes[dbGuid] = respawnTime; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN); + stmt->setUInt32(0, dbGuid); + stmt->setUInt32(1, uint32(respawnTime)); + stmt->setUInt16(2, GetId()); + stmt->setUInt32(3, GetInstanceId()); + CharacterDatabase.Execute(stmt); +} + +void Map::RemoveCreatureRespawnTime(uint32 dbGuid) +{ + _creatureRespawnTimes.erase(dbGuid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); + stmt->setUInt32(0, dbGuid); + stmt->setUInt16(1, GetId()); + stmt->setUInt32(2, GetInstanceId()); + CharacterDatabase.Execute(stmt); +} + +void Map::SaveGORespawnTime(uint32 dbGuid, time_t respawnTime) +{ + if (!respawnTime) + { + // Delete only + RemoveGORespawnTime(dbGuid); + return; + } + + _goRespawnTimes[dbGuid] = respawnTime; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN); + stmt->setUInt32(0, dbGuid); + stmt->setUInt32(1, uint32(respawnTime)); + stmt->setUInt16(2, GetId()); + stmt->setUInt32(3, GetInstanceId()); + CharacterDatabase.Execute(stmt); +} + +void Map::RemoveGORespawnTime(uint32 dbGuid) +{ + _goRespawnTimes.erase(dbGuid); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN); + stmt->setUInt32(0, dbGuid); + stmt->setUInt16(1, GetId()); + stmt->setUInt32(2, GetInstanceId()); + CharacterDatabase.Execute(stmt); +} + +void Map::LoadRespawnTimes() +{ + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS); + stmt->setUInt16(0, GetId()); + stmt->setUInt32(1, GetInstanceId()); + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + { + do + { + Field* fields = result->Fetch(); + uint32 loguid = fields[0].GetUInt32(); + uint32 respawnTime = fields[1].GetUInt32(); + + _creatureRespawnTimes[loguid] = time_t(respawnTime); + } while (result->NextRow()); + } + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS); + stmt->setUInt16(0, GetId()); + stmt->setUInt32(1, GetInstanceId()); + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + { + do + { + Field* fields = result->Fetch(); + uint32 loguid = fields[0].GetUInt32(); + uint32 respawnTime = fields[1].GetUInt32(); + + _goRespawnTimes[loguid] = time_t(respawnTime); + } while (result->NextRow()); + } +} + +void Map::DeleteRespawnTimes() +{ + _creatureRespawnTimes.clear(); + _goRespawnTimes.clear(); + + DeleteRespawnTimesInDB(GetId(), GetInstanceId()); +} + +void Map::DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId) +{ + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE); + stmt->setUInt16(0, mapId); + stmt->setUInt32(1, instanceId); + CharacterDatabase.Execute(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE); + stmt->setUInt16(0, mapId); + stmt->setUInt32(1, instanceId); + CharacterDatabase.Execute(stmt); +} + +time_t Map::GetLinkedRespawnTime(uint64 guid) const +{ + uint64 linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid); + switch (GUID_HIPART(linkedGuid)) + { + case HIGHGUID_UNIT: + return GetCreatureRespawnTime(GUID_LOPART(linkedGuid)); + case HIGHGUID_GAMEOBJECT: + return GetGORespawnTime(GUID_LOPART(linkedGuid)); + default: + break; + } + + return time_t(0); +} + diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 6ba08646f25..6d526f23a94 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -193,10 +193,10 @@ public: bool loadData(char* filaname); void unloadData(); - uint16 getArea(float x, float y); - inline float getHeight(float x, float y) {return (this->*_gridGetHeight)(x, y);} - float getLiquidLevel(float x, float y); - uint8 getTerrainType(float x, float y); + uint16 getArea(float x, float y) const; + inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);} + float getLiquidLevel(float x, float y) const; + uint8 getTerrainType(float x, float y) const; ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0); }; @@ -443,6 +443,38 @@ class Map : public GridRefManager<NGridType> void Insert(const GameObjectModel& mdl) { _dynamicTree.insert(mdl); } bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);} bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist); + + /* + RESPAWN TIMES + */ + time_t GetLinkedRespawnTime(uint64 guid) const; + time_t GetCreatureRespawnTime(uint32 dbGuid) const + { + UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _creatureRespawnTimes.find(dbGuid); + if (itr != _creatureRespawnTimes.end()) + return itr->second; + + return time_t(0); + } + + time_t GetGORespawnTime(uint32 dbGuid) const + { + UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _goRespawnTimes.find(dbGuid); + if (itr != _goRespawnTimes.end()) + return itr->second; + + return time_t(0); + } + + void SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime); + void RemoveCreatureRespawnTime(uint32 dbGuid); + void SaveGORespawnTime(uint32 dbGuid, time_t respawnTime); + void RemoveGORespawnTime(uint32 dbGuid); + void LoadRespawnTimes(); + void DeleteRespawnTimes(); + + static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId); + private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -488,6 +520,7 @@ class Map : public GridRefManager<NGridType> void ScriptsProcess(); void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff); + protected: void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } @@ -570,6 +603,9 @@ class Map : public GridRefManager<NGridType> else m_activeNonPlayers.erase(obj); } + + UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _creatureRespawnTimes; + UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _goRespawnTimes; }; enum InstanceResetMethod diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 5543251e115..2c1bdb00834 100755 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -211,6 +211,8 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, InstanceMap* map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this); ASSERT(map->IsDungeon()); + map->LoadRespawnTimes(); + bool load_data = save != NULL; map->CreateInstanceData(load_data); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index ce93fe5af1a..8736c8b3782 100755 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -110,6 +110,7 @@ Map* MapManager::CreateBaseMap(uint32 id) else { map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); + map->LoadRespawnTimes(); } i_maps[id] = map; } diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 1049325237a..aa07eef2204 100755 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -71,7 +71,7 @@ class MapManager void SetMapUpdateInterval(uint32 t) { - if (t > MIN_MAP_UPDATE_DELAY) + if (t < MIN_MAP_UPDATE_DELAY) t = MIN_MAP_UPDATE_DELAY; i_timer.SetInterval(t); @@ -143,7 +143,7 @@ class MapManager void RegisterInstanceId(uint32 instanceId); void FreeInstanceId(uint32 instanceId); - uint32 GetNextInstanceId() { return _nextInstanceId; }; + uint32 GetNextInstanceId() const { return _nextInstanceId; }; void SetNextInstanceId(uint32 nextInstanceId) { _nextInstanceId = nextInstanceId; }; MapUpdater * GetMapUpdater() { return &m_updater; } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 7b77ecaa17e..7d12f94d155 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -3279,8 +3279,6 @@ enum SummonType enum EventId { - EVENT_SPELLCLICK = 1001, - EVENT_FALL_GROUND = 1002, EVENT_CHARGE = 1003, }; diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index c0e1eb842ae..bc0570bb73b 100755 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -298,7 +298,7 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z) } } -void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed) +void MotionMaster::MoveLand(uint32 id, Position const& pos) { float x, y, z; pos.GetPosition(x, y, z); @@ -307,13 +307,12 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed) Movement::MoveSplineInit init(*_owner); init.MoveTo(x,y,z); - init.SetVelocity(speed); init.SetAnimation(Movement::ToGround); init.Launch(); Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); } -void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed) +void MotionMaster::MoveTakeoff(uint32 id, Position const& pos) { float x, y, z; pos.GetPosition(x, y, z); @@ -322,7 +321,6 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed) Movement::MoveSplineInit init(*_owner); init.MoveTo(x,y,z); - init.SetVelocity(speed); init.SetAnimation(Movement::ToFly); init.Launch(); Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index d6144bfcc3a..727f626cdea 100755 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -157,8 +157,8 @@ class MotionMaster //: private std::stack<MovementGenerator *> void MovePoint(uint32 id, float x, float y, float z); // These two movement types should only be used with creatures having landing/takeoff animations - void MoveLand(uint32 id, Position const& pos, float speed); - void MoveTakeoff(uint32 id, Position const& pos, float speed); + void MoveLand(uint32 id, Position const& pos); + void MoveTakeoff(uint32 id, Position const& pos); void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index a922c937b5f..07a5761517e 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -33,6 +33,7 @@ void PointMovementGenerator<T>::Initialize(T &unit) unit.StopMoving(); unit.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE); + i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); init.MoveTo(i_x, i_y, i_z); if (speed > 0.0f) @@ -53,6 +54,17 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 & /*diff*/) } unit.AddUnitState(UNIT_STATE_ROAMING_MOVE); + + if (i_recalculateSpeed && !unit.movespline->Finalized()) + { + i_recalculateSpeed = false; + Movement::MoveSplineInit init(unit); + init.MoveTo(i_x, i_y, i_z); + if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit + init.SetVelocity(speed); + init.Launch(); + } + return !unit.movespline->Finalized(); } @@ -81,11 +93,6 @@ void PointMovementGenerator<T>::MovementInform(T & /*unit*/) template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit) { - //if (id == EVENT_FALL_GROUND) - //{ - // unit.setDeathState(JUST_DIED); - // unit.SetFlying(true); - //} if (unit.AI()) unit.AI()->MovementInform(POINT_MOTION_TYPE, id); } diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 13be9fee77b..d2833a5ee10 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -36,6 +36,8 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG void MovementInform(T &); + void unitSpeedChanged() { i_recalculateSpeed = true; } + MovementGeneratorType GetMovementGeneratorType() { return POINT_MOTION_TYPE; } bool GetDestination(float& x, float& y, float& z) const { x=i_x; y=i_y; z=i_z; return true; } @@ -43,6 +45,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG uint32 id; float i_x, i_y, i_z; float speed; + bool i_recalculateSpeed; }; class AssistanceMovementGenerator : public PointMovementGenerator<Creature> diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 91b4ff08250..b1c25aedfd7 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -203,7 +203,7 @@ bool MoveSplineInitArgs::Validate() const return false;\ } CHECK(path.size() > 1); - CHECK(velocity > 0.f); + CHECK(velocity > 0.1f); CHECK(time_perc >= 0.f && time_perc <= 1.f); //CHECK(_checkPathBounds()); return true; diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index 33973064e09..cfc2fdee450 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -34,43 +34,43 @@ namespace Movement { public: enum eFlags{ - None = 0x00000000, - // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag - Done = 0x00000100, - Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag - No_Spline = 0x00000400, - Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag - Walkmode = 0x00001000, - Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation - OrientationFixed = 0x00004000, // Model orientation fixed - Final_Point = 0x00008000, - Final_Target = 0x00010000, - Final_Angle = 0x00020000, - Catmullrom = 0x00040000, // Used Catmullrom interpolation mode - Cyclic = 0x00080000, // Movement by cycled spline - Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done - Animation = 0x00200000, // Plays animation after some time passed - Frozen = 0x00400000, // Will never arrive - Unknown5 = 0x00800000, - Unknown6 = 0x01000000, - Unknown7 = 0x02000000, - Unknown8 = 0x04000000, + None = 0x00000000, + // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag + Done = 0x00000100, + Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag + No_Spline = 0x00000400, + Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag + Walkmode = 0x00001000, + Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation + OrientationFixed = 0x00004000, // Model orientation fixed + Final_Point = 0x00008000, + Final_Target = 0x00010000, + Final_Angle = 0x00020000, + Catmullrom = 0x00040000, // Used Catmullrom interpolation mode + Cyclic = 0x00080000, // Movement by cycled spline + Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done + Animation = 0x00200000, // Plays animation after some time passed + Frozen = 0x00400000, // Will never arrive + TransportEnter = 0x00800000, + TransportExit = 0x01000000, + Unknown7 = 0x02000000, + Unknown8 = 0x04000000, OrientationInversed = 0x08000000, - Unknown10 = 0x10000000, - Unknown11 = 0x20000000, - Unknown12 = 0x40000000, - Unknown13 = 0x80000000, + Unknown10 = 0x10000000, + Unknown11 = 0x20000000, + Unknown12 = 0x40000000, + Unknown13 = 0x80000000, // Masks - Mask_Final_Facing = Final_Point | Final_Target | Final_Angle, + Mask_Final_Facing = Final_Point | Final_Target | Final_Angle, // animation ids stored here, see AnimType enum, used with Animation flag - Mask_Animations = 0xFF, + Mask_Animations = 0xFF, // flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done, // CatmullRom interpolation mode used - Mask_CatmullRom = Flying | Catmullrom, + Mask_CatmullRom = Flying | Catmullrom, // Unused, not suported flags - Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown5|Unknown6|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13, + Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13, }; inline uint32& raw() { return (uint32&)*this;} @@ -98,14 +98,16 @@ namespace Movement void operator &= (uint32 f) { raw() &= f;} void operator |= (uint32 f) { raw() |= f;} - void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations|Falling|Parabolic)) | Animation|anim;} - void EnableParabolic() { raw() = (raw() & ~(Mask_Animations|Falling|Animation)) | Parabolic;} - void EnableFalling() { raw() = (raw() & ~(Mask_Animations|Parabolic|Animation)) | Falling;} + void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic)) | Animation | anim; } + void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Parabolic; } + void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling; } void EnableFlying() { raw() = (raw() & ~Catmullrom) | Flying; } void EnableCatmullRom() { raw() = (raw() & ~Flying) | Catmullrom; } - void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point;} - void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle;} - void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target;} + void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; } + void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; } + void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target; } + void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; } + void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; } uint8 animId : 8; bool done : 1; @@ -123,8 +125,8 @@ namespace Movement bool enter_cycle : 1; bool animation : 1; bool frozen : 1; - bool unknown5 : 1; - bool unknown6 : 1; + bool transportEnter: 1; + bool transportExit : 1; bool unknown7 : 1; bool unknown8 : 1; bool orientationInversed : 1; diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index e586cb4f4f9..c539dd3cc39 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -20,6 +20,8 @@ #include "MoveSpline.h" #include "MovementPacketBuilder.h" #include "Unit.h" +#include "Transport.h" +#include "Vehicle.h" namespace Movement { @@ -58,17 +60,26 @@ namespace Movement { MoveSpline& move_spline = *unit.movespline; - Location real_position(unit.GetPositionX(),unit.GetPositionY(),unit.GetPositionZMinusOffset(),unit.GetOrientation()); - // there is a big chane that current position is unknown if current state is not finalized, need compute it + 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(); + } + + // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized()) real_position = move_spline.ComputePosition(); + // should i do the things that user should do? - no. if (args.path.empty()) - { - // should i do the things that user should do? - MoveTo(real_position); - } + return; // corrent first vertex args.path[0] = real_position; @@ -82,7 +93,7 @@ namespace Movement moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD); - if (args.velocity == 0.f) + if (!args.HasVelocity) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate()) @@ -94,14 +105,22 @@ namespace Movement unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); - WorldPacket data(SMSG_MONSTER_MOVE, 64); + WorldPacket data(!transport ? SMSG_MONSTER_MOVE : SMSG_MONSTER_MOVE_TRANSPORT, 64); data.append(unit.GetPackGUID()); + if (transport) + { + data.appendPackGUID(unit.GetTransGUID()); + data << int8(unit.GetTransSeat()); + } + PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data,true); } MoveSplineInit::MoveSplineInit(Unit& m) : unit(m) { + // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes + args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID(); // mix existing state into new args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY|MOVEMENTFLAG_DISABLE_GRAVITY)); @@ -110,13 +129,48 @@ namespace Movement void MoveSplineInit::SetFacing(const Unit * target) { args.flags.EnableFacingTarget(); - //args.facing.target = target->GetObjectGuid().GetRawValue(); - args.facing.target = target->GetUInt64Value(OBJECT_FIELD_GUID); + args.facing.target = target->GetGUID(); } void MoveSplineInit::SetFacing(float angle) { + if (args.TransformForTransport) + { + if (Unit* vehicle = unit.GetVehicleBase()) + angle -= vehicle->GetOrientation(); + else if (Transport* transport = unit.GetTransport()) + angle -= transport->GetOrientation(); + } + args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi()); args.flags.EnableFacingAngle(); } + + void MoveSplineInit::MoveTo(Vector3 const& dest) + { + args.path_Idx_offset = 0; + args.path.resize(2); + TransportPathTransform transform(unit, args.TransformForTransport); + args.path[1] = transform(dest); + } + + Vector3 TransportPathTransform::operator()(Vector3 input) + { + if (_transformForTransport) + { + if (Unit* vehicle = _owner.GetVehicleBase()) + { + input.x -= vehicle->GetPositionX(); + input.y -= vehicle->GetPositionY(); + input.z -= vehicle->GetPositionZMinusOffset(); + } + else if (Transport* transport = _owner.GetTransport()) + { + float unused = 0.0f; + transport->CalculatePassengerOffset(input.x, input.y, input.z, unused); + } + } + + return input; + } } diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 7ef6cd7a120..ef847809ac8 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -33,6 +33,19 @@ namespace Movement FlyToGround = 3, // 463 = FlyToGround }; + // Transforms coordinates from global to transport offsets + class TransportPathTransform + { + public: + TransportPathTransform(Unit& owner, bool transformForTransport) + : _owner(owner), _transformForTransport(transformForTransport) { } + Vector3 operator()(Vector3 input); + + private: + Unit& _owner; + bool _transformForTransport; + }; + /* Initializes and launches spline movement */ class MoveSplineInit @@ -96,6 +109,12 @@ namespace Movement /* Enables falling mode. Disabled by default */ void SetFall(); + /* Enters transport. Disabled by default + */ + void SetTransportEnter(); + /* Exits transport. Disabled by default + */ + void SetTransportExit(); /* Inverses unit model orientation. Disabled by default */ void SetOrientationInversed(); @@ -112,40 +131,39 @@ namespace Movement PointsArray& Path() { return args.path; } + /* Disables transport coordinate transformations for cases where raw offsets are available + */ + void DisableTransportPathTransformations(); protected: MoveSplineInitArgs args; Unit& unit; }; - inline void MoveSplineInit::SetFly() { args.flags.EnableFlying();} + inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); } inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable;} inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom();} inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true;} inline void MoveSplineInit::SetFall() { args.flags.EnableFalling();} - inline void MoveSplineInit::SetVelocity(float vel){ args.velocity = vel;} + inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; } inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;} + inline void MoveSplineInit::SetTransportEnter() { args.flags.EnableTransportEnter(); } + inline void MoveSplineInit::SetTransportExit() { args.flags.EnableTransportExit(); } inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable;} inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset) { args.path_Idx_offset = path_offset; - args.path.assign(controls.begin(),controls.end()); + args.path.resize(controls.size()); + std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport)); } inline void MoveSplineInit::MoveTo(float x, float y, float z) { - Vector3 v(x,y,z); + Vector3 v(x, y, z); MoveTo(v); } - inline void MoveSplineInit::MoveTo(const Vector3& dest) - { - args.path_Idx_offset = 0; - args.path.resize(2); - args.path[1] = dest; - } - inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift) { args.time_perc = time_shift; @@ -161,10 +179,14 @@ namespace Movement inline void MoveSplineInit::SetFacing(Vector3 const& spot) { - args.facing.f.x = spot.x; - args.facing.f.y = spot.y; - args.facing.f.z = spot.z; + TransportPathTransform transform(unit, args.TransformForTransport); + Vector3 finalSpot = transform(spot); + args.facing.f.x = finalSpot.x; + args.facing.f.y = finalSpot.y; + args.facing.f.z = finalSpot.z; args.flags.EnableFacingPoint(); } + + inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; } } #endif // TRINITYSERVER_MOVESPLINEINIT_H diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h index 26fbbdd0fcc..de02b35d0a0 100644 --- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h +++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h @@ -42,7 +42,8 @@ namespace Movement struct MoveSplineInitArgs { MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0), - velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f) + velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), + HasVelocity(false), TransformForTransport(true) { path.reserve(path_capacity); } @@ -56,6 +57,8 @@ namespace Movement float time_perc; uint32 splineId; float initialOrientation; + bool HasVelocity; + bool TransformForTransport; /** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */ bool Validate() const; diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 0260767dbe2..8aef671d2d1 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -44,24 +44,12 @@ namespace Movement void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data) { MoveSplineFlag splineflags = move_spline.splineflags; - /*if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) - { - data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); - if (unit->GetVehicle()) - data << unit->GetVehicle()->GetBase()->GetPackGUID(); - else if (unit->GetTransport()) - data << unit->GetTransport()->GetPackGUID(); - else - data << uint64(0); - - data << int8(unit->GetTransSeat()); - }*/ - data << uint8(0); + data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) data << move_spline.spline.getPoint(move_spline.spline.first()); data << move_spline.GetId(); - switch(splineflags & MoveSplineFlag::Mask_Final_Facing) + switch (splineflags & MoveSplineFlag::Mask_Final_Facing) { case MoveSplineFlag::Final_Target: data << uint8(MonsterMoveFacingTarget); diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 465fca75030..dfdd4fc4ffc 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -166,8 +166,10 @@ bool OPvPCapturePoint::DelCreature(uint32 type) //if (Map* map = sMapMgr->FindMap(cr->GetMapId())) // map->Remove(cr, false); // delete respawn time for this creature - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_GUID); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); stmt->setUInt32(0, guid); + stmt->setUInt16(1, cr->GetMapId()); + stmt->setUInt32(2, 0); // instance id, always 0 for world maps CharacterDatabase.Execute(stmt); cr->AddObjectToRemoveList(); diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 26f4ad71cda..ff351f90f74 100755 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -132,16 +132,16 @@ Quest::Quest(Field* questRecord) ObjectiveText[i] = questRecord[128+i].GetString(); for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) - RewardCurrencyId[i] = questRecord[132+i].GetUInt32(); + RewardCurrencyId[i] = questRecord[132+i].GetUInt16(); for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) - RewardCurrencyCount[i] = questRecord[136+i].GetUInt32(); + RewardCurrencyCount[i] = questRecord[136+i].GetUInt8(); for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) - RequiredCurrencyId[i] = questRecord[140+i].GetUInt32(); + RequiredCurrencyId[i] = questRecord[140+i].GetUInt16(); for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) - RequiredCurrencyCount[i] = questRecord[144+i].GetUInt32(); + RequiredCurrencyCount[i] = questRecord[144+i].GetUInt8(); QuestGiverTextWindow = questRecord[148].GetString(); QuestGiverTargetName = questRecord[149].GetString(); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index f64d0953e86..58b9c55cdd1 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -46,21 +46,27 @@ void AddSC_SmartSCripts(); //Commands void AddSC_account_commandscript(); void AddSC_achievement_commandscript(); +void AddSC_cast_commandscript(); void AddSC_debug_commandscript(); void AddSC_event_commandscript(); void AddSC_gm_commandscript(); void AddSC_go_commandscript(); void AddSC_gobject_commandscript(); void AddSC_honor_commandscript(); +void AddSC_instance_commandscript(); void AddSC_learn_commandscript(); +void AddSC_list_commandscript(); void AddSC_misc_commandscript(); void AddSC_modify_commandscript(); void AddSC_npc_commandscript(); void AddSC_quest_commandscript(); void AddSC_reload_commandscript(); +void AddSC_reset_commandscript(); void AddSC_tele_commandscript(); +void AddSC_server_commandscript(); void AddSC_titles_commandscript(); void AddSC_wp_commandscript(); +void AddSC_character_commandscript(); #ifdef SCRIPTS //world @@ -648,21 +654,27 @@ void AddCommandScripts() { AddSC_account_commandscript(); AddSC_achievement_commandscript(); + AddSC_cast_commandscript(); AddSC_debug_commandscript(); AddSC_event_commandscript(); AddSC_gm_commandscript(); AddSC_go_commandscript(); AddSC_gobject_commandscript(); AddSC_honor_commandscript(); + AddSC_instance_commandscript(); AddSC_learn_commandscript(); + AddSC_list_commandscript(); AddSC_misc_commandscript(); AddSC_modify_commandscript(); AddSC_npc_commandscript(); AddSC_quest_commandscript(); AddSC_reload_commandscript(); + AddSC_reset_commandscript(); AddSC_tele_commandscript(); + AddSC_server_commandscript(); AddSC_titles_commandscript(); AddSC_wp_commandscript(); + AddSC_character_commandscript(); } void AddWorldScripts() diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index bf701d41ec2..195dd9391bd 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1041,7 +1041,6 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_LEARNED_DANCE_MOVES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_LEVELUP_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PROPOSAL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_LFG_DISABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_LFG_JOIN_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1102,9 +1101,9 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVERING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1112,30 +1111,12 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_RUN_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1297,16 +1278,32 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_SPELL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 14f9687cdcd..4f6cda222e9 100755 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -792,7 +792,7 @@ enum Opcodes SMSG_LEARNED_DANCE_MOVES = 0x0E05, SMSG_LEARNED_SPELL = 0x58A2, SMSG_LEVELUP_INFO = 0x0000, - SMSG_LFG_BOOT_PLAYER = 0x0000, + SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x0000, SMSG_LFG_DISABLED = 0x0000, SMSG_LFG_JOIN_RESULT = 0x0000, SMSG_LFG_OFFER_CONTINUE = 0x0000, @@ -844,22 +844,21 @@ enum Opcodes SMSG_MOUNTSPECIAL_ANIM = 0x0000, SMSG_MOVE_DISABLE_COLLISION = 0x0000, SMSG_MOVE_DISABLE_GRAVITY = 0x0000, - SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000, SMSG_MOVE_ENABLE_COLLISION = 0x0000, SMSG_MOVE_ENABLE_GRAVITY = 0x0000, - SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000, + SMSG_MOVE_FEATHER_FALL = 0x0000, SMSG_MOVE_KNOCK_BACK = 0x0000, + SMSG_MOVE_LAND_WALK = 0x0000, + SMSG_MOVE_NORMAL_FALL = 0x0000, SMSG_MOVE_ROOT = 0x0000, SMSG_MOVE_SET_ACTIVE_MOVER = 0x0000, SMSG_MOVE_SET_CAN_FLY = 0x0000, + SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000, SMSG_MOVE_SET_COLLISION_HEIGHT = 0x0000, SMSG_MOVE_SET_COMPOUND_STATE = 0x0000, - SMSG_MOVE_SET_FEATHER_FALL = 0x0000, SMSG_MOVE_SET_FLIGHT_BACK_SPEED = 0x0000, SMSG_MOVE_SET_FLIGHT_SPEED = 0x0000, - SMSG_MOVE_SET_HOVERING = 0x0000, - SMSG_MOVE_SET_LAND_WALK = 0x0000, - SMSG_MOVE_SET_NORMAL_FALL = 0x0000, + SMSG_MOVE_SET_HOVER = 0x0000, SMSG_MOVE_SET_PITCH_RATE = 0x0000, SMSG_MOVE_SET_RUN_BACK_SPEED = 0x0000, SMSG_MOVE_SET_RUN_SPEED = 0x0000, @@ -869,42 +868,16 @@ enum Opcodes SMSG_MOVE_SET_VEHICLE_REC_ID = 0x0000, SMSG_MOVE_SET_WALK_IN_AIR = 0x0000, SMSG_MOVE_SET_WALK_SPEED = 0x0000, - SMSG_MOVE_SET_WATER_WALK = 0x0000, SMSG_MOVE_SKIP_TIME = 0x0000, - SMSG_MOVE_SPLINE_DISABLE_COLLISION = 0x0000, - SMSG_MOVE_SPLINE_DISABLE_GRAVITY = 0x0000, - SMSG_MOVE_SPLINE_ENABLE_COLLISION = 0x0000, - SMSG_MOVE_SPLINE_ENABLE_GRAVITY = 0x0000, - SMSG_MOVE_SPLINE_ROOT = 0x0000, - SMSG_MOVE_SPLINE_SET_FEATHER_FALL = 0x0000, - SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED = 0x0000, - SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED = 0x0000, - SMSG_MOVE_SPLINE_SET_FLYING = 0x0000, - SMSG_MOVE_SPLINE_SET_HOVER = 0x0000, - SMSG_MOVE_SPLINE_SET_LAND_WALK = 0x0000, - SMSG_MOVE_SPLINE_SET_NORMAL_FALL = 0x0000, - SMSG_MOVE_SPLINE_SET_PITCH_RATE = 0x0000, - SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED = 0x0000, - SMSG_MOVE_SPLINE_SET_RUN_MODE = 0x0000, - SMSG_MOVE_SPLINE_SET_RUN_SPEED = 0x0000, - SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED = 0x0000, - SMSG_MOVE_SPLINE_SET_SWIM_SPEED = 0x0000, - SMSG_MOVE_SPLINE_SET_TURN_RATE = 0x0000, - SMSG_MOVE_SPLINE_SET_WALK_MODE = 0x0000, - SMSG_MOVE_SPLINE_SET_WALK_SPEED = 0x0000, - SMSG_MOVE_SPLINE_SET_WATER_WALK = 0x0000, - SMSG_MOVE_SPLINE_START_SWIM = 0x0000, - SMSG_MOVE_SPLINE_STOP_SWIM = 0x0000, - SMSG_MOVE_SPLINE_UNROOT = 0x0000, - SMSG_MOVE_SPLINE_UNSET_FLYING = 0x0000, - SMSG_MOVE_SPLINE_UNSET_HOVER = 0x0000, SMSG_MOVE_TELEPORT = 0x0000, SMSG_MOVE_UNROOT = 0x0000, SMSG_MOVE_UNSET_CAN_FLY = 0x0000, - SMSG_MOVE_UNSET_HOVERING = 0x0000, + SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000, + SMSG_MOVE_UNSET_HOVER = 0x0000, SMSG_MOVE_UNSET_WALK_IN_AIR = 0x0000, SMSG_MOVE_UPDATE_KNOCK_BACK = 0x0000, SMSG_MOVE_UPDATE_TELEPORT = 0x0000, + SMSG_MOVE_WATER_WALK = 0x0000, SMSG_MULTIPLE_PACKETS = 0x0000, SMSG_NAME_QUERY_RESPONSE = 0x6E04, SMSG_NEW_TAXI_PATH = 0x0000, @@ -1046,6 +1019,33 @@ enum Opcodes SMSG_SPELL_START = 0x6415, SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x0000, SMSG_SPIRIT_HEALER_CONFIRM = 0x0000, + SMSG_SPLINE_MOVE_COLLISION_DISABLE = 0x0000, + SMSG_SPLINE_MOVE_COLLISION_ENABLE = 0x0000, + SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0x0000, + SMSG_SPLINE_MOVE_GRAVITY_ENABLE = 0x0000, + SMSG_SPLINE_MOVE_ROOT = 0x0000, + SMSG_SPLINE_MOVE_SET_FEATHER_FALL = 0x0000, + SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED = 0x0000, + SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED = 0x0000, + SMSG_SPLINE_MOVE_SET_FLYING = 0x0000, + SMSG_SPLINE_MOVE_SET_HOVER = 0x0000, + SMSG_SPLINE_MOVE_SET_LAND_WALK = 0x0000, + SMSG_SPLINE_MOVE_SET_NORMAL_FALL = 0x0000, + SMSG_SPLINE_MOVE_SET_PITCH_RATE = 0x0000, + SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED = 0x0000, + SMSG_SPLINE_MOVE_SET_RUN_MODE = 0x0000, + SMSG_SPLINE_MOVE_SET_RUN_SPEED = 0x0000, + SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED = 0x0000, + SMSG_SPLINE_MOVE_SET_SWIM_SPEED = 0x0000, + SMSG_SPLINE_MOVE_SET_TURN_RATE = 0x0000, + SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x0000, + SMSG_SPLINE_MOVE_SET_WALK_SPEED = 0x0000, + SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x0000, + SMSG_SPLINE_MOVE_START_SWIM = 0x0000, + SMSG_SPLINE_MOVE_STOP_SWIM = 0x0000, + SMSG_SPLINE_MOVE_UNROOT = 0x0000, + SMSG_SPLINE_MOVE_UNSET_FLYING = 0x0000, + SMSG_SPLINE_MOVE_UNSET_HOVER = 0x0000, SMSG_STABLE_RESULT = 0x0000, SMSG_STANDSTATE_UPDATE = 0x6F04, SMSG_START_MIRROR_TIMER = 0x0000, @@ -1112,7 +1112,7 @@ enum SessionStatus STATUS_AUTHED = 0, // Player authenticated (_player == NULL, m_playerRecentlyLogout = false or will be reset before handler call, m_GUID have garbage) STATUS_LOGGEDIN, // Player in game (_player != NULL, m_GUID == _player->GetGUID(), inWorld()) STATUS_TRANSFER, // Player transferring to another map (_player != NULL, m_GUID == _player->GetGUID(), !inWorld()) - STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, // _player!= NULL or _player == NULL && m_playerRecentlyLogout, m_GUID store last _player guid) + STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, // _player != NULL or _player == NULL && m_playerRecentlyLogout && m_playerLogout, m_GUID store last _player guid) STATUS_NEVER, // Opcode not accepted from client (deprecated or server side only) STATUS_UNHANDLED, // Opcode not handled yet }; diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp new file mode 100644 index 00000000000..cb6dcdbdb9e --- /dev/null +++ b/src/server/game/Server/Protocol/PacketLog.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "PacketLog.h" +#include "Config.h" +#include "ByteBuffer.h" +#include "WorldPacket.h" + +PacketLog::PacketLog() : _file(NULL) +{ + Initialize(); +} + +PacketLog::~PacketLog() +{ + if (_file) + fclose(_file); + + _file = NULL; +} + +void PacketLog::Initialize() +{ + std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", ""); + + if (!logsDir.empty()) + if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\')) + logsDir.push_back('/'); + + std::string logname = ConfigMgr::GetStringDefault("PacketLogFile", ""); + if (!logname.empty()) + _file = fopen((logsDir + logname).c_str(), "wb"); +} + +void PacketLog::LogPacket(WorldPacket const& packet, Direction direction) +{ + ByteBuffer data(4+4+4+1+packet.size()); + data << int32(packet.GetOpcode()); + data << int32(packet.size()); + data << uint32(time(NULL)); + data << uint8(direction); + + for (uint32 i = 0; i < packet.size(); i++) + data << const_cast<WorldPacket&>(packet)[i]; + + fwrite(data.contents(), 1, data.size(), _file); + fflush(_file); +} diff --git a/src/server/game/Server/Protocol/WorldLog.h b/src/server/game/Server/Protocol/PacketLog.h index fb344f195de..b899daae198 100755..100644 --- a/src/server/game/Server/Protocol/WorldLog.h +++ b/src/server/game/Server/Protocol/PacketLog.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * * 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,46 +15,36 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/// \addtogroup u2w -/// @{ -/// \file - -#ifndef TRINITY_WORLDLOG_H -#define TRINITY_WORLDLOG_H +#ifndef TRINITY_PACKETLOG_H +#define TRINITY_PACKETLOG_H #include "Common.h" #include <ace/Singleton.h> -#include "Errors.h" -#include <stdarg.h> +enum Direction +{ + CLIENT_TO_SERVER, + SERVER_TO_CLIENT +}; + +class WorldPacket; -/// %Log packets to a file -class WorldLog +class PacketLog { - friend class ACE_Singleton<WorldLog, ACE_Thread_Mutex>; + friend class ACE_Singleton<PacketLog, ACE_Thread_Mutex>; private: - WorldLog(); - ~WorldLog(); - WorldLog(const WorldLog &); - WorldLog& operator=(const WorldLog &); - ACE_Thread_Mutex Lock; + PacketLog(); + ~PacketLog(); public: void Initialize(); - /// Is the world logger active? - bool LogWorld(void) const { return (i_file != NULL); } - /// %Log to the file - void outLog(char const* fmt, ...); - void outTimestampLog(char const* fmt, ...); + bool CanLogPacket() const { return (_file != NULL); } + void LogPacket(WorldPacket const& packet, Direction direction); private: - FILE* i_file; - - bool m_dbWorld; + FILE* _file; }; -#define sWorldLog ACE_Singleton<WorldLog, ACE_Thread_Mutex>::instance() +#define sPacketLog ACE_Singleton<PacketLog, ACE_Thread_Mutex>::instance() #endif -/// @} - diff --git a/src/server/game/Server/Protocol/WorldLog.cpp b/src/server/game/Server/Protocol/WorldLog.cpp deleted file mode 100755 index 38b13dff095..00000000000 --- a/src/server/game/Server/Protocol/WorldLog.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** \file - \ingroup u2w -*/ - -#include "WorldLog.h" -#include "Config.h" -#include "Log.h" -#include "DatabaseWorkerPool.h" - -WorldLog::WorldLog() : i_file(NULL) -{ - Initialize(); -} - -WorldLog::~WorldLog() -{ - if (i_file != NULL) - fclose(i_file); - - i_file = NULL; -} - -/// Open the log file (if specified so in the configuration file) -void WorldLog::Initialize() -{ - std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", ""); - - if (!logsDir.empty()) - { - if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\')) - logsDir.push_back('/'); - } - - std::string logname = ConfigMgr::GetStringDefault("WorldLogFile", ""); - if (!logname.empty()) - { - i_file = fopen((logsDir+logname).c_str(), "w"); - } - - m_dbWorld = ConfigMgr::GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled -} - -void WorldLog::outTimestampLog(char const* fmt, ...) -{ - if (LogWorld()) - { - TRINITY_GUARD(ACE_Thread_Mutex, Lock); - ASSERT(i_file); - - Log::outTimestamp(i_file); - va_list args; - va_start(args, fmt); - vfprintf(i_file, fmt, args); - //fprintf(i_file, "\n"); - va_end(args); - - fflush(i_file); - } - - if (sLog->GetLogDB() && m_dbWorld) - { - va_list ap2; - va_start(ap2, fmt); - char nnew_str[MAX_QUERY_LEN]; - vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2); - sLog->outDB(LOG_TYPE_WORLD, nnew_str); - va_end(ap2); - } -} - -void WorldLog::outLog(char const* fmt, ...) -{ - if (LogWorld()) - { - TRINITY_GUARD(ACE_Thread_Mutex, Lock); - ASSERT(i_file); - - va_list args; - va_start(args, fmt); - vfprintf(i_file, fmt, args); - //fprintf(i_file, "\n"); - va_end(args); - - fflush(i_file); - } - - if (sLog->GetLogDB() && m_dbWorld) - { - va_list ap2; - va_start(ap2, fmt); - char nnew_str[MAX_QUERY_LEN]; - vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2); - sLog->outDB(LOG_TYPE_WORLD, nnew_str); - va_end(ap2); - } -} diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 0f41ea1ca37..9b6eaaea6c3 100755 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -218,7 +218,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet) /// Logging helper for unexpected opcodes void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason) { - sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s", + sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s", GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), status, reason); } @@ -226,7 +226,7 @@ void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, /// Logging helper for unexpected opcodes void WorldSession::LogUnprocessedTail(WorldPacket* packet) { - sLog->outError("SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)", + sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), uint32(packet->rpos()), uint32(packet->wpos())); packet->print_storage(); } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index c7c19eeeacd..c1d1cb5d53c 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -333,7 +333,7 @@ class WorldSession void LoadTutorialsData(); void SendTutorialsData(); void SaveTutorialsData(SQLTransaction& trans); - uint32 GetTutorialInt(uint8 index) { return m_Tutorials[index]; } + uint32 GetTutorialInt(uint8 index) const { return m_Tutorials[index]; } void SetTutorialInt(uint8 index, uint32 value) { if (m_Tutorials[index] != value) @@ -400,8 +400,8 @@ class WorldSession } // Recruit-A-Friend Handling - uint32 GetRecruiterId() { return recruiterId; } - bool IsARecruiter() { return isRecruiter; } + uint32 GetRecruiterId() const { return recruiterId; } + bool IsARecruiter() const { return isRecruiter; } public: // opcodes handlers diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 5f55ddbc254..c2a02d6f12c 100755 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -42,7 +42,7 @@ #include "WorldSession.h" #include "WorldSocketMgr.h" #include "Log.h" -#include "WorldLog.h" +#include "PacketLog.h" #include "ScriptMgr.h" #include "AccountMgr.h" @@ -78,7 +78,7 @@ struct ServerPktHeader return 2+(isLargePacket()?3:2); } - bool isLargePacket() + bool isLargePacket() const { return size > 0x7FFF; } @@ -152,7 +152,7 @@ const std::string& WorldSocket::GetRemoteAddress (void) const return m_Address; } -int WorldSocket::SendPacket(const WorldPacket& pct) +int WorldSocket::SendPacket(WorldPacket const& pct) { ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1); @@ -160,24 +160,8 @@ int WorldSocket::SendPacket(const WorldPacket& pct) return -1; // Dump outgoing packet. - if (sWorldLog->LogWorld()) - { - sWorldLog->outTimestampLog ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n", - (uint32) get_handle(), - pct.size(), - LookupOpcodeName (pct.GetOpcode()), - pct.GetOpcode()); - - uint32 p = 0; - while (p < pct.size()) - { - for (uint32 j = 0; j < 16 && p < pct.size(); j++) - sWorldLog->outLog("%.2X ", const_cast<WorldPacket&>(pct)[p++]); - - sWorldLog->outLog("\n"); - } - sWorldLog->outLog("\n"); - } + if (sPacketLog->CanLogPacket()) + sPacketLog->LogPacket(pct, SERVER_TO_CLIENT); sLog->outOpCode(uint32(pct.GetOpcode()), LookupOpcodeName(pct.GetOpcode()), true); @@ -668,7 +652,7 @@ int WorldSocket::schedule_wakeup_output (GuardType& g) return 0; } -int WorldSocket::ProcessIncoming (WorldPacket* new_pct) +int WorldSocket::ProcessIncoming(WorldPacket* new_pct) { ACE_ASSERT (new_pct); @@ -681,24 +665,8 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct) return -1; // Dump received packet. - if (sWorldLog->LogWorld()) - { - sWorldLog->outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n", - (uint32) get_handle(), - new_pct->size(), - LookupOpcodeName (new_pct->GetOpcode()), - new_pct->GetOpcode()); - - uint32 p = 0; - while (p < new_pct->size()) - { - for (uint32 j = 0; j < 16 && p < new_pct->size(); j++) - sWorldLog->outLog ("%.2X ", (*new_pct)[p++]); - - sWorldLog->outLog ("\n"); - } - sWorldLog->outLog ("\n"); - } + if (sPacketLog->CanLogPacket()) + sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER); sLog->outOpCode(uint32(Opcodes(opcode)), LookupOpcodeName(Opcodes(opcode)), false); @@ -808,7 +776,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) LocaleConstant locale; std::string account; SHA1Hash sha; - BigNumber v, s, g, N, k; + BigNumber k; WorldPacket addonsData; recvPacket.read_skip<uint32>(); @@ -891,21 +859,9 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) if (expansion > world_expansion) expansion = world_expansion; - N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); - g.SetDword(7); - - v.SetHexStr(fields[4].GetCString()); - s.SetHexStr(fields[5].GetCString()); - - const char* sStr = s.AsHexStr(); //Must be freed by OPENSSL_free() - const char* vStr = v.AsHexStr(); //Must be freed by OPENSSL_free() - sLog->outStaticDebug("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", - sStr, - vStr); - - OPENSSL_free((void*) sStr); - OPENSSL_free((void*) vStr); + fields[5].GetCString(), + fields[4].GetCString()); ///- Re-check ip locking (same check as in realmd). if (fields[3].GetUInt8() == 1) // if ip is locked diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 7cff80cf6a0..7817e5e0d4d 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -831,33 +831,18 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load) m_amplitude = 1 * IN_MILLISECONDS; case SPELL_AURA_PERIODIC_DAMAGE: case SPELL_AURA_PERIODIC_HEAL: - case SPELL_AURA_PERIODIC_ENERGIZE: case SPELL_AURA_OBS_MOD_HEALTH: + case SPELL_AURA_PERIODIC_TRIGGER_SPELL: + case SPELL_AURA_PERIODIC_ENERGIZE: case SPELL_AURA_PERIODIC_LEECH: case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: case SPELL_AURA_PERIODIC_MANA_LEECH: case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: case SPELL_AURA_POWER_BURN: - m_isPeriodic = true; - break; - case SPELL_AURA_PERIODIC_TRIGGER_SPELL: - if (GetId() == 51912) - m_amplitude = 3000; - m_isPeriodic = true; - break; - case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE: case SPELL_AURA_PERIODIC_DUMMY: + case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE: m_isPeriodic = true; break; - case SPELL_AURA_DUMMY: - // Haunting Spirits - perdiodic trigger demon - if (GetId() == 7057) - { - m_isPeriodic = true; - m_amplitude = irand (0, 60) + 30; - m_amplitude *= IN_MILLISECONDS; - } - break; default: break; } @@ -1153,14 +1138,6 @@ void AuraEffect::UpdatePeriodic(Unit* caster) { switch (GetAuraType()) { - case SPELL_AURA_DUMMY: - // Haunting Spirits - if (GetId() == 7057) - { - m_amplitude = irand (0, 60) + 30; - m_amplitude *= IN_MILLISECONDS; - } - break; case SPELL_AURA_PERIODIC_DUMMY: switch (GetSpellInfo()->SpellFamilyName) { @@ -1362,11 +1339,6 @@ void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const case SPELL_AURA_POWER_BURN: HandlePeriodicPowerBurnAuraTick(target, caster); break; - case SPELL_AURA_DUMMY: - // Haunting Spirits - if (GetId() == 7057) - target->CastSpell((Unit*)NULL, GetAmount(), true); - break; default: break; } @@ -3352,9 +3324,11 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp, { target->SetCanFly(apply); if (!apply) + { target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING); target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING); target->m_movementInfo.SetFallTime(0); + } Player* player = target->ToPlayer(); if (!player) @@ -3431,41 +3405,244 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const* aurApp, uint8 return; Unit* target = aurApp->GetTarget(); + std::list <AuraType> aura_immunity_list; + uint32 mechanic_immunity_list = 0; + int32 miscVal = GetMiscValue(); - std::list <AuraType> immunity_list; - if (GetMiscValue() & (1<<10)) - immunity_list.push_back(SPELL_AURA_MOD_STUN); - if (GetMiscValue() & (1<<1)) - immunity_list.push_back(SPELL_AURA_TRANSFORM); + switch (miscVal) + { + case 96: + case 1615: + { + if (GetAmount()) + { + mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) + | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) + | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) + | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) + | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) + | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); + aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); + aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); + aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); + aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); + } + break; + } + case 679: + { + if (GetId() == 57742) + { + mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) + | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) + | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) + | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) + | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) + | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); + aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); + aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); + aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); + aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); + } + break; + } + case 1557: + { + if (GetId() == 64187) + { + mechanic_immunity_list = (1 << MECHANIC_STUN); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + } + else + { + mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) + | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) + | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) + | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) + | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) + | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); + aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); + aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); + aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); + aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); + } + break; + } + case 1614: + case 1694: + { + target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT); + break; + } + case 1630: + { + if (!GetAmount()) + { + target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT); + } + else + { + mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) + | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) + | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) + | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) + | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) + | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); + aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); + aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); + aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); + aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); + } + break; + } + case 477: + case 1733: + { + if (!GetAmount()) + { + mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT) + | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN) + | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM) + | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR) + | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED) + | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN); + + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); + aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); + aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); + aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); + aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); + } + break; + } + case 878: + { + if (GetAmount() == 1) + { + mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_STUN) + | (1 << MECHANIC_DISORIENTED) | (1 << MECHANIC_FREEZE); + + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply); + target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply); + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); + } + break; + } + default: + break; + } - // These flag can be recognized wrong: - if (GetMiscValue() & (1<<6)) - immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); - if (GetMiscValue() & (1<<0)) - immunity_list.push_back(SPELL_AURA_MOD_ROOT); - if (GetMiscValue() & (1<<2)) - immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); - if (GetMiscValue() & (1<<9)) - immunity_list.push_back(SPELL_AURA_MOD_FEAR); + if (aura_immunity_list.empty()) + { + if (miscVal & (1<<10)) + aura_immunity_list.push_back(SPELL_AURA_MOD_STUN); + if (miscVal & (1<<1)) + aura_immunity_list.push_back(SPELL_AURA_TRANSFORM); - // an exception for Bladestorm - if ((GetMiscValue() & (1<<7)) && (GetId() != 46924)) - immunity_list.push_back(SPELL_AURA_MOD_DISARM); + // These flag can be recognized wrong: + if (miscVal & (1<<6)) + aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED); + if (miscVal & (1<<0)) + aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT); + if (miscVal & (1<<2)) + aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE); + if (miscVal & (1<<9)) + aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR); + if (miscVal & (1<<7)) + aura_immunity_list.push_back(SPELL_AURA_MOD_DISARM); + } // apply immunities - for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter) + for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter) target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply); - // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated. - if (apply && GetId() == 46924) - { - target->RemoveAurasByType(SPELL_AURA_MOD_ROOT); - target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); - } - if (apply && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY) - for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter) + { + target->RemoveAurasWithMechanic(mechanic_immunity_list, AURA_REMOVE_BY_DEFAULT, GetId()); + for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter) target->RemoveAurasByType(*iter); + } } void AuraEffect::HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -4861,38 +5038,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (Unit* spellTarget = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget())) target->CastSpell(spellTarget, 51699, true); break; - case 28832: // Mark of Korth'azz - case 28833: // Mark of Blaumeux - case 28834: // Mark of Rivendare - case 28835: // Mark of Zeliek - if (caster) // actually we can also use cast(this, originalcasterguid) - { - int32 damage; - switch (GetBase()->GetStackAmount()) - { - case 1: damage = 0; break; - case 2: damage = 500; break; - case 3: damage = 1000; break; - case 4: damage = 1500; break; - case 5: damage = 4000; break; - case 6: damage = 12000; break; - default:damage = 20000 + 1000 * (GetBase()->GetStackAmount() - 7); break; - } - if (damage) - caster->CastCustomSpell(28836, SPELLVALUE_BASE_POINT0, damage, target); - } - break; - case 63322: // Saronite Vapors - { - if (caster) - { - int32 mana = int32(GetAmount() * pow(2.0f, GetBase()->GetStackAmount())); // mana restore - bp * 2^stackamount - int32 damage = mana * 2; // damage - caster->CastCustomSpell(target, 63337, &mana, NULL, NULL, true); - caster->CastCustomSpell(target, 63338, &damage, NULL, NULL, true); - } - break; - } case 71563: if (Aura* newAura = target->AddAura(71564, target)) newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount); @@ -4986,57 +5131,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool break; } break; - case SPELLFAMILY_MAGE: - // Living Bomb - if (m_spellInfo->SpellFamilyFlags[1] & 0x20000) - { - AuraRemoveMode removeMode = aurApp->GetRemoveMode(); - if (caster && (removeMode == AURA_REMOVE_BY_ENEMY_SPELL || removeMode == AURA_REMOVE_BY_EXPIRE)) - caster->CastSpell(target, GetAmount(), true); - } - break; - case SPELLFAMILY_PRIEST: - // Vampiric Touch - if (m_spellInfo->SpellFamilyFlags[1] & 0x0400 && aurApp->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && GetEffIndex() == 0) - if (AuraEffect const* aurEff = GetBase()->GetEffect(1)) - { - int32 damage = aurEff->GetAmount() * 8; - // backfire damage - target->CastCustomSpell(target, 64085, &damage, NULL, NULL, true, NULL, NULL, GetCasterGUID()); - } - break; - case SPELLFAMILY_WARLOCK: - // Haunt - if (m_spellInfo->SpellFamilyFlags[1] & 0x40000) - if (caster) - target->CastCustomSpell(caster, 48210, &m_amount, 0, 0, true, NULL, this, GetCasterGUID()); - break; - case SPELLFAMILY_DRUID: - // Lifebloom - if (GetSpellInfo()->SpellFamilyFlags[1] & 0x10) - { - // Final heal only on duration end - if (aurApp->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; - - // final heal - int32 stack = GetBase()->GetStackAmount(); - int32 heal = m_amount; - if (caster) - { - heal = caster->SpellHealingBonusDone(target, GetSpellInfo(), heal, HEAL, stack); - heal = target->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, HEAL, stack); - } - target->CastCustomSpell(target, 33778, &heal, &stack, NULL, true, NULL, this, GetCasterGUID()); - - // restore mana - if (caster) - { - int32 returnmana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2; - caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, this, GetCasterGUID()); - } - } - break; case SPELLFAMILY_DEATHKNIGHT: // Summon Gargoyle (Dismiss Gargoyle at remove) if (GetId() == 61777) @@ -5044,7 +5138,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool break; case SPELLFAMILY_ROGUE: // Tricks of the trade - switch(GetId()) + switch (GetId()) { case 59628: //Tricks of the trade buff on rogue (6sec duration) target->SetReducedThreatPercent(0,0); @@ -5112,48 +5206,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool target->SetEntry(apply ? 17654 : 17326); break; } - //Summon Fire Elemental - case 40133: - { - if (!caster) - break; - - Unit* owner = caster->GetOwner(); - if (owner && owner->GetTypeId() == TYPEID_PLAYER) - { - if (apply) - owner->CastSpell(owner, 8985, true); - else - owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); - } - break; - } - //Summon Earth Elemental - case 40132 : - { - if (!caster) - break; - - Unit* owner = caster->GetOwner(); - if (owner && owner->GetTypeId() == TYPEID_PLAYER) - { - if (apply) - owner->CastSpell(owner, 19704, true); - else - owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); - } - break; - } - case 57723: // Exhaustion - case 57724: // Sated - { - switch (GetId()) - { - case 57723: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 32182, apply); break; // Heroism - case 57724: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 2825, apply); break; // Bloodlust - } - break; - } case 57819: // Argent Champion case 57820: // Ebon Champion case 57821: // Champion of the Kirin Tor @@ -5246,69 +5298,14 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool } case SPELLFAMILY_DRUID: { - if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)) - break; - switch (GetId()) - { - case 52610: // Savage Roar - { - uint32 spellId = 62071; - if (apply) - { - if (target->GetShapeshiftForm() != FORM_CAT) - break; - - target->CastSpell(target, spellId, true, NULL, NULL, GetCasterGUID()); - break; - } - target->RemoveAurasDueToSpell(spellId); - break; - } - case 61336: // Survival Instincts - { - if (!(mode & AURA_EFFECT_HANDLE_REAL)) - break; - - if (apply) - { - if (!target->IsInFeralForm()) - break; - - int32 bp0 = int32(target->CountPctFromMaxHealth(GetAmount())); - target->CastCustomSpell(target, 50322, &bp0, NULL, NULL, true); - } - else - target->RemoveAurasDueToSpell(50322); - break; - } - } - // Predatory Strikes - if (target->GetTypeId() == TYPEID_PLAYER && GetSpellInfo()->SpellIconID == 1563) - { - target->ToPlayer()->UpdateAttackPowerAndDamage(); - } + //if (!(mode & AURA_EFFECT_HANDLE_REAL)) + //break; break; } case SPELLFAMILY_SHAMAN: { - if (!(mode & AURA_EFFECT_HANDLE_REAL)) - break; - // Sentry Totem - if (GetId() == 6495 && caster && caster->GetTypeId() == TYPEID_PLAYER) - { - if (apply) - { - if (uint64 guid = caster->m_SummonSlot[4]) - { - if (Creature* totem = caster->GetMap()->GetCreature(guid)) - if (totem->isTotem()) - caster->ToPlayer()->CastSpell(totem, 6277, true); - } - } - else - caster->ToPlayer()->StopCastingBindSight(); - return; - } + //if (!(mode & AURA_EFFECT_HANDLE_REAL)) + //break; break; } case SPELLFAMILY_PALADIN: @@ -5941,14 +5938,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) if (caster) caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, int32(target->CountPctFromMaxHealth(21)), target, true, NULL, this); return; - // Detonate Mana - case 27819: - if (int32 mana = (int32)(target->GetMaxPower(POWER_MANA) / 10)) - { - mana = target->ModifyPower(POWER_MANA, -mana); - target->CastCustomSpell(27820, SPELLVALUE_BASE_POINT0, -mana*10, target, true, NULL, this); - } - return; // Inoculate Nestlewood Owlkin case 29528: if (target->GetTypeId() != TYPEID_UNIT) // prevent error reports in case ignored player target @@ -6613,33 +6602,6 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con target->AddThreat(caster, float(gainedAmount) * 0.5f, GetSpellInfo()->GetSchoolMask(), GetSpellInfo()); } - // spell-specific code - switch (GetId()) - { - case 31447: // Mark of Kaz'rogal - if (target->GetPower(powerType) == 0) - { - target->CastSpell(target, 31463, true, 0, this); - // Remove aura - GetBase()->SetDuration(0); - } - break; - case 32960: // Mark of Kazzak - { - int32 modifier = int32(target->GetPower(powerType) * 0.05f); - target->ModifyPower(powerType, -modifier); - - if (target->GetPower(powerType) == 0) - { - target->CastSpell(target, 32961, true, 0, this); - // Remove aura - GetBase()->SetDuration(0); - } - break; - } - default: - break; - } // Drain Mana if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[0] & 0x00000010) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 58c8ce5c558..6a8ac5d4eef 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1236,19 +1236,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b caster->CastCustomSpell(caster, 75999, &heal, NULL, NULL, true, NULL, GetEffect(0)); } } - // Renew - else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00000040 && GetEffect(0)) - { - // Empowered Renew - if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3021, 1)) - { - uint32 damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), HEAL); - damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, HEAL); - - int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100; - caster->CastCustomSpell(target, 63544, &basepoints0, NULL, NULL, true, NULL, GetEffect(0)); - } - } // Power Word: Shield else if (m_spellInfo->SpellFamilyFlags[0] & 0x1 && m_spellInfo->SpellFamilyFlags[2] & 0x400 && GetEffect(0)) { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d833782bc76..54b3ae310e2 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -828,7 +828,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar break; } - switch(targetType.GetSelectionCategory()) + switch (targetType.GetSelectionCategory()) { case TARGET_SELECT_CATEGORY_CHANNEL: SelectImplicitChannelTargets(effIndex, targetType); @@ -846,7 +846,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar switch (targetType.GetObjectType()) { case TARGET_OBJECT_TYPE_SRC: - switch(targetType.GetReferenceType()) + switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_CASTER: m_targets.SetSrc(*m_caster); @@ -857,7 +857,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar } break; case TARGET_OBJECT_TYPE_DEST: - switch(targetType.GetReferenceType()) + switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_CASTER: SelectImplicitCasterDestTargets(effIndex, targetType); @@ -874,7 +874,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar } break; default: - switch(targetType.GetReferenceType()) + switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_CASTER: SelectImplicitCasterObjectTargets(effIndex, targetType); @@ -915,17 +915,25 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa switch (targetType.GetTarget()) { case TARGET_UNIT_CHANNEL_TARGET: + { + WorldObject* target = ObjectAccessor::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID()); + CallScriptObjectTargetSelectHandlers(target, effIndex); // unit target may be no longer avalible - teleported out of map for example - if (Unit* target = Unit::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID())) - AddUnitTarget(target, 1 << effIndex); + if (target && target->ToUnit()) + AddUnitTarget(target->ToUnit(), 1 << effIndex); else sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, effIndex); break; + } case TARGET_DEST_CHANNEL_TARGET: if (channeledSpell->m_targets.HasDst()) m_targets.SetDst(channeledSpell->m_targets); else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, channeledSpell->m_targets.GetObjectTargetGUID())) - m_targets.SetDst(*target); + { + CallScriptObjectTargetSelectHandlers(target, effIndex); + if (target) + m_targets.SetDst(*target); + } else sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, effIndex); break; @@ -1003,6 +1011,8 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar return; } + CallScriptObjectTargetSelectHandlers(target, effIndex); + switch (targetType.GetObjectType()) { case TARGET_OBJECT_TYPE_UNIT: @@ -1042,7 +1052,9 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge { Trinity::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList); Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask); - SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, radius); + SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius); + + CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); if (!targets.empty()) { @@ -1070,8 +1082,6 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge gObjTargets.push_back(gObjTarget); } - CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) AddUnitTarget(*itr, effMask, false); @@ -1206,6 +1216,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge default: break; } + + CallScriptObjectAreaTargetSelectHandlers(targets, effIndex); + std::list<Unit*> unitTargets; std::list<GameObject*> gObjTargets; // for compability with older code - add only unit and go targets @@ -1287,18 +1300,6 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth power = POWER_HEALTH; } - else if (m_spellInfo->SpellFamilyFlags[2] == 0x0100) // Starfall - { - // Remove targets not in LoS or in stealth - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end();) - { - if ((*itr)->HasStealthAura() || (*itr)->HasInvisibilityAura() || !(*itr)->IsWithinLOSInMap(m_caster)) - itr = unitTargets.erase(itr); - else - ++itr; - } - break; - } else break; @@ -1339,6 +1340,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge } } + // todo: move to scripts, but we must call it before resize list by MaxAffectedTargets + // Intimidating Shout + if (m_spellInfo->Id == 5246 && effIndex != EFFECT_0) + unitTargets.remove(m_targets.GetUnitTarget()); + // Other special target selection goes here if (uint32 maxTargets = m_spellValue->MaxAffectedTargets) { @@ -1347,13 +1353,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge if ((*j)->IsAffectingSpell(m_spellInfo)) maxTargets += (*j)->GetAmount(); - if (m_spellInfo->Id == 5246) //Intimidating Shout - unitTargets.remove(m_targets.GetUnitTarget()); Trinity::Containers::RandomResizeList(unitTargets, maxTargets); } - CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) AddUnitTarget(*itr, effMask, false); } @@ -1369,6 +1371,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge Trinity::Containers::RandomResizeList(gObjTargets, maxTargets); } + for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr) AddGOTarget(*itr, effMask); } @@ -1376,7 +1379,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { - switch(targetType.GetTarget()) + switch (targetType.GetTarget()) { case TARGET_DEST_CASTER: m_targets.SetDst(*m_caster); @@ -1441,7 +1444,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { WorldObject* target = m_targets.GetObjectTarget(); - switch(targetType.GetTarget()) + switch (targetType.GetTarget()) { case TARGET_DEST_TARGET_ENEMY: case TARGET_DEST_TARGET_ANY: @@ -1474,7 +1477,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT if (!m_targets.HasDst()) m_targets.SetDst(*m_caster); - switch(targetType.GetTarget()) + switch (targetType.GetTarget()) { case TARGET_DEST_DYNOBJ_ENEMY: case TARGET_DEST_DYNOBJ_ALLY: @@ -1500,27 +1503,27 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { - switch(targetType.GetTarget()) + WorldObject* target = NULL; + bool checkIfValid = true; + + switch (targetType.GetTarget()) { case TARGET_UNIT_CASTER: - AddUnitTarget(m_caster, 1 << effIndex, false); + target = m_caster; + checkIfValid = false; break; case TARGET_UNIT_MASTER: - if (Unit* owner = m_caster->GetCharmerOrOwner()) - AddUnitTarget(owner, 1 << effIndex); + target = m_caster->GetCharmerOrOwner(); break; case TARGET_UNIT_PET: - if (Guardian* pet = m_caster->GetGuardianPet()) - AddUnitTarget(pet, 1 << effIndex); + target = m_caster->GetGuardianPet(); break; case TARGET_UNIT_SUMMONER: if (m_caster->isSummon()) - if (Unit* unit = m_caster->ToTempSummon()->GetSummoner()) - AddUnitTarget(unit, 1 << effIndex); + target = m_caster->ToTempSummon()->GetSummoner(); break; case TARGET_UNIT_VEHICLE: - if (Unit *vehicle = m_caster->GetVehicleBase()) - AddUnitTarget(vehicle, 1 << effIndex); + target = m_caster->GetVehicleBase(); break; case TARGET_UNIT_PASSENGER_0: case TARGET_UNIT_PASSENGER_1: @@ -1531,26 +1534,38 @@ void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImpli case TARGET_UNIT_PASSENGER_6: case TARGET_UNIT_PASSENGER_7: if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsVehicle()) - if (Unit *unit = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0)) - AddUnitTarget(unit, 1 << effIndex); + target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0); break; default: break; } + + CallScriptObjectTargetSelectHandlers(target, effIndex); + + if (target && target->ToUnit()) + AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid); } void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!"); - if (Unit* unit = m_targets.GetUnitTarget()) - AddUnitTarget(unit, 1 << effIndex, true, false); - else if (GameObject* gobj = m_targets.GetGOTarget()) - AddGOTarget(gobj, 1 << effIndex); - else - AddItemTarget(m_targets.GetItemTarget(), 1 << effIndex); - if (WorldObject* target = m_targets.GetObjectTarget()) + WorldObject* target = m_targets.GetObjectTarget(); + + CallScriptObjectTargetSelectHandlers(target, effIndex); + + if (target) + { + if (Unit* unit = target->ToUnit()) + AddUnitTarget(unit, 1 << effIndex, true, false); + else if (GameObject* gobj = target->ToGameObject()) + AddGOTarget(gobj, 1 << effIndex); + SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex); + } + // Script hook can remove object target and we would wrongly land here + else if (Item* item = m_targets.GetItemTarget()) + AddItemTarget(item, 1 << effIndex); } void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask) @@ -1571,14 +1586,15 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType() , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY); + // 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); - CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex); - for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr) AddUnitTarget(*itr, effMask, false); } @@ -1741,9 +1757,12 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) case SPELL_EFFECT_SUMMON_PLAYER: if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection()) { - Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); - if (target) - AddUnitTarget(target, 1 << effIndex, false); + WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); + + CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex)); + + if (target && target->ToPlayer()) + AddUnitTarget(target->ToUnit(), 1 << effIndex, false); } return; default: @@ -1759,6 +1778,8 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) if (!targetMask) return; + WorldObject* target = NULL; + switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType()) { // add explicit object target or self to the target map @@ -1767,40 +1788,46 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)) { if (Unit* unitTarget = m_targets.GetUnitTarget()) - AddUnitTarget(unitTarget, 1 << effIndex, false); + target = unitTarget; else if (targetMask & TARGET_FLAG_CORPSE_MASK) { if (Corpse* corpseTarget = m_targets.GetCorpseTarget()) { // TODO: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID())) - AddUnitTarget(owner, 1 << effIndex, false); + target = owner; } } else //if (targetMask & TARGET_FLAG_UNIT_MASK) - { - AddUnitTarget(m_caster, 1 << effIndex, false); - } + target = m_caster; } if (targetMask & TARGET_FLAG_ITEM_MASK) { if (Item* itemTarget = m_targets.GetItemTarget()) AddItemTarget(itemTarget, 1 << effIndex); + return; } if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK) - { - if (GameObject* gObjTarget = m_targets.GetGOTarget()) - AddGOTarget(gObjTarget, 1 << effIndex); - } + target = m_targets.GetGOTarget(); break; // add self to the target map case EFFECT_IMPLICIT_TARGET_CASTER: if (targetMask & TARGET_FLAG_UNIT_MASK) - AddUnitTarget(m_caster, 1 << effIndex, false); + target = m_caster; break; default: break; } + + CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex)); + + if (target) + { + if (target->ToUnit()) + AddUnitTarget(target->ToUnit(), 1 << effIndex, false); + else if (target->ToGameObject()) + AddGOTarget(target->ToGameObject(), 1 << effIndex); + } } uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList) @@ -2474,12 +2501,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx); } - // Haunt - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[1] & 0x40000 && m_spellAura && m_spellAura->GetEffect(1)) - { - AuraEffect* aurEff = m_spellAura->GetEffect(1); - aurEff->SetAmount(CalculatePctU(aurEff->GetAmount(), damageInfo.damage)); - } + m_damage = damageInfo.damage; @@ -2548,12 +2570,31 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA return SPELL_MISS_EVADE; // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case + if (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo))) + return SPELL_MISS_IMMUNE; + // disable effects to which unit is immune + SpellMissInfo returnVal = SPELL_MISS_IMMUNE; for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) - if (effectMask & (1 << effectNumber) && unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) - effectMask &= ~(1 << effectNumber); - if (!effectMask || (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))) - return SPELL_MISS_IMMUNE; + { + if (effectMask & (1 << effectNumber)) + if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber)) + effectMask &= ~(1 << effectNumber); + else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber)) + { + int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel)); + debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel)); + + if (debuff_resist_chance > 0) + if (irand(0,10000) <= (debuff_resist_chance * 100)) + { + effectMask &= ~(1 << effectNumber); + returnVal = SPELL_MISS_RESIST; + } + } + } + if (!effectMask) + return returnVal; PrepareScriptHitHandlers(); CallScriptBeforeHitHandlers(); @@ -3855,7 +3896,7 @@ void Spell::SendSpellStart() data << uint8(0); // unkByte // if (unkByte == 2) // data.append(0); - + } m_caster->SendMessageToSet(&data, true); @@ -3876,6 +3917,7 @@ void Spell::SendSpellGo() castFlags |= CAST_FLAG_PENDING; + if ((m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet())) && m_spellInfo->PowerType != POWER_HEALTH) @@ -4804,19 +4846,9 @@ SpellCastResult Spell::CheckCast(bool strict) if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target)) return SPELL_FAILED_LINE_OF_SIGHT; } - else - { - if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster - { - // Lay on Hands - cannot be self-cast on paladin with Forbearance or after using Avenging Wrath - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags[0] & 0x0008000) - if (target->HasAura(61988)) // Immunity shield marker - return SPELL_FAILED_TARGET_AURASTATE; - } - } } - //Check for line of sight for spells with dest + // Check for line of sight for spells with dest if (m_targets.HasDst()) { float x, y, z; @@ -4915,7 +4947,9 @@ SpellCastResult Spell::CheckCast(bool strict) bool hasDispellableAura = false; bool hasNonDispelEffect = false; - for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + uint32 dispelMask = 0; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL) { if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->AttributesEx & SPELL_ATTR1_MELEE_COMBAT_START) @@ -4923,28 +4957,28 @@ SpellCastResult Spell::CheckCast(bool strict) hasDispellableAura = true; break; } - if (Unit* target = m_targets.GetUnitTarget()) - { - DispelChargesList dispelList; - uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue)); - target->GetDispellableAuraList(m_caster, dispelMask, dispelList); - if (!dispelList.empty()) - { - hasDispellableAura = true; - break; - } - } + + dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue)); } else if (m_spellInfo->Effects[i].IsEffect()) { hasNonDispelEffect = true; break; } + } - if (!hasNonDispelEffect && !hasDispellableAura && m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL) && !IsTriggered()) - return SPELL_FAILED_NOTHING_TO_DISPEL; + if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered()) + { + if (Unit* target = m_targets.GetUnitTarget()) + { + DispelChargesList dispelList; + target->GetDispellableAuraList(m_caster, dispelMask, dispelList); + if (dispelList.empty()) + return SPELL_FAILED_NOTHING_TO_DISPEL; + } + } - for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { // for effects of spells that have only one target switch (m_spellInfo->Effects[i].Effect) @@ -5285,10 +5319,6 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_LEAP_BACK: { - // Spell 781 (Disengage) requires player to be in combat - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->Id == 781 && !m_caster->isInCombat()) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; - if (m_caster->HasUnitState(UNIT_STATE_ROOT)) { if (m_caster->GetTypeId() == TYPEID_PLAYER) @@ -5310,66 +5340,10 @@ SpellCastResult Spell::CheckCast(bool strict) } } - for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { switch (m_spellInfo->Effects[i].ApplyAuraName) { - case SPELL_AURA_DUMMY: - { - //custom check - switch (m_spellInfo->Id) - { - // Tag Murloc - case 30877: - { - Unit* target = m_targets.GetUnitTarget(); - if (!target || target->GetEntry() != 17326) - return SPELL_FAILED_BAD_TARGETS; - break; - } - case 61336: - if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_caster->ToPlayer()->IsInFeralForm()) - return SPELL_FAILED_ONLY_SHAPESHIFT; - break; - case 1515: - { - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return SPELL_FAILED_BAD_TARGETS; - - if (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget()->GetTypeId() == TYPEID_PLAYER) - return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - - Creature* target = m_targets.GetUnitTarget()->ToCreature(); - - if (target->getLevel() > m_caster->getLevel()) - return SPELL_FAILED_HIGHLEVEL; - - // use SMSG_PET_TAME_FAILURE? - if (!target->GetCreatureTemplate()->isTameable (m_caster->ToPlayer()->CanTameExoticPets())) - return SPELL_FAILED_BAD_TARGETS; - - if (m_caster->GetPetGUID()) - return SPELL_FAILED_ALREADY_HAVE_SUMMON; - - if (m_caster->GetCharmGUID()) - return SPELL_FAILED_ALREADY_HAVE_CHARM; - - break; - } - case 44795: // Parachute - { - float x, y, z; - m_caster->GetPosition(x, y, z); - float ground_Z = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z); - if (fabs(ground_Z - z) < 0.1f) - return SPELL_FAILED_DONT_REPORT; - break; - } - default: - break; - } - break; - } case SPELL_AURA_MOD_POSSESS_PET: { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -7047,15 +7021,29 @@ void Spell::CallScriptAfterHitHandlers() } } -void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex) +void Spell::CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex) { for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) { - (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT); - std::list<SpellScript::UnitTargetHandler>::iterator hookItrEnd = (*scritr)->OnUnitTargetSelect.end(), hookItr = (*scritr)->OnUnitTargetSelect.begin(); + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT); + std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin(); for (; hookItr != hookItrEnd; ++hookItr) if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex)) - (*hookItr).Call(*scritr, unitTargets); + (*hookItr).Call(*scritr, targets); + + (*scritr)->_FinishScriptCall(); + } +} + +void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex) +{ + for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT); + std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin(); + for (; hookItr != hookItrEnd; ++hookItr) + if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex)) + (*hookItr).Call(*scritr, target); (*scritr)->_FinishScriptCall(); } @@ -7089,12 +7077,6 @@ void Spell::PrepareTriggersExecutedOnHit() // todo: move this to scripts switch (m_spellInfo->SpellFamilyName) { - case SPELLFAMILY_GENERIC: - { - if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages - m_preCastSpell = 11196; // Recently Bandaged - break; - } case SPELLFAMILY_MAGE: { // Permafrost diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 777d151440c..50510397056 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -629,7 +629,8 @@ class Spell void CallScriptBeforeHitHandlers(); void CallScriptOnHitHandlers(); void CallScriptAfterHitHandlers(); - void CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex); + void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex); + void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex); std::list<SpellScript*> m_loadedScripts; struct HitTriggerSpell diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index ca3c4197fc3..aba486b0df9 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -366,43 +366,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) return; break; } - case 33671: // gruul's shatter - case 50811: // krystallus shatter ( Normal ) - case 61547: // krystallus shatter ( Heroic ) - { - // don't damage self and only players - if (unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - float radius = m_spellInfo->Effects[EFFECT_0].CalcRadius(m_caster); - if (!radius) - return; - float distance = m_caster->GetDistance2d(unitTarget); - damage = (distance > radius) ? 0 : int32(m_spellInfo->Effects[EFFECT_0].CalcValue(m_caster) * ((radius - distance)/radius)); - break; - } - // Loken Pulsing Shockwave - case 59837: - case 52942: - { - // don't damage self and only players - if (unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - float radius = m_spellInfo->Effects[EFFECT_0].CalcRadius(m_caster); - if (!radius) - return; - float distance = m_caster->GetDistance2d(unitTarget); - damage = (distance > radius) ? 0 : int32(m_spellInfo->Effects[EFFECT_0].CalcValue(m_caster) * distance); - break; - } - // TODO: add spell specific target requirement hook for spells - // Shadowbolts only affects targets with Shadow Mark (Gothik) - case 27831: - case 55638: - if (!unitTarget->HasAura(27825)) - return; - break; // Gargoyle Strike case 51963: { @@ -415,11 +378,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) } case SPELLFAMILY_WARRIOR: { - // Bloodthirst - if (m_spellInfo->SpellFamilyFlags[1] & 0x400) - ApplyPctF(damage, m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); // Shield Slam - else if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->Category == 1209) + if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->Category == 1209) { uint8 level = m_caster->getLevel(); uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f), uint32(float(level) * 34.5f)); @@ -2863,6 +2823,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex) // add new enchanting if equipped item_owner->ApplyEnchantment(itemTarget, PERM_ENCHANTMENT_SLOT, true); + item_owner->RemoveTradeableItem(itemTarget); itemTarget->ClearSoulboundTradeable(item_owner); } } @@ -2927,6 +2888,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex) // add new enchanting if equipped item_owner->ApplyEnchantment(itemTarget, PRISMATIC_ENCHANTMENT_SLOT, true); + item_owner->RemoveTradeableItem(itemTarget); itemTarget->ClearSoulboundTradeable(item_owner); } @@ -3275,6 +3237,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(2, unitTarget); } } + if (m_spellInfo->SpellFamilyFlags[0] & 0x8000000) // Mocking Blow + { + if (unitTarget->IsImmunedToSpellEffect(m_spellInfo,EFFECT_1) || unitTarget->GetTypeId() == TYPEID_PLAYER) + { + m_damage = 0; + return; + } + } break; } case SPELLFAMILY_ROGUE: @@ -3375,7 +3345,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Blood Strike if (m_spellInfo->SpellFamilyFlags[0] & 0x400000) { - AddPctF(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f); + float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f; + // Death Knight T8 Melee 4P Bonus + if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) + AddPctF(bonusPct, aurEff->GetAmount()); + AddPctF(totalDamagePercentMod, bonusPct); // Glyph of Blood Strike if (m_caster->GetAuraEffect(59332, EFFECT_0)) @@ -3402,7 +3376,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) if (roll_chance_i(aurEff->GetAmount())) consumeDiseases = false; - AddPctF(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f); + float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f; + // Death Knight T8 Melee 4P Bonus + if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) + AddPctF(bonusPct, aurEff->GetAmount()); + AddPctF(totalDamagePercentMod, bonusPct); break; } // Blood-Caked Strike - Blood-Caked Blade @@ -3414,7 +3392,12 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Heart Strike if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000) { - AddPctN(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID())); + float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()); + // Death Knight T8 Melee 4P Bonus + if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0)) + AddPctF(bonusPct, aurEff->GetAmount()); + + AddPctF(totalDamagePercentMod, bonusPct); break; } break; @@ -3524,15 +3507,6 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/) return; int32 addhealth = 0; - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN) // Lay on Hands - { - if (m_caster->GetGUID() == unitTarget->GetGUID()) - { - m_caster->CastSpell(m_caster, 25771, true); // Forbearance - m_caster->CastSpell(m_caster, 61988, true); // Immune shield marker (serverside) - m_caster->CastSpell(m_caster, 61987, true); // Avenging Wrath marker - } - } // damage == 0 - heal for caster max health if (damage == 0) @@ -3763,12 +3737,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) if (!itemTarget && m_caster->GetTypeId() != TYPEID_PLAYER) return; - uint32 spell_id = 0; - switch (urand(1, 5)) - { - case 1: spell_id = 8854; break; - default: spell_id = 8855; break; - } + uint32 spell_id = roll_chance_i(20) ? 8854 : 8855; m_caster->CastSpell(m_caster, spell_id, true, NULL); return; @@ -3815,10 +3784,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); return; } - // Escape artist - case 20589: - m_caster->RemoveMovementImpairingAuras(); - return; // Decimate case 28374: case 54426: @@ -3849,15 +3814,8 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) DoCreateItem(effIndex, item); break; } - // Improved Sprint - case 30918: - { - // Removes snares and roots. - unitTarget->RemoveMovementImpairingAuras(); - break; - } - // Spirit Walk - case 58876: + case 20589: // Escape artist + case 30918: // Improved Sprint { // Removes snares and roots. unitTarget->RemoveMovementImpairingAuras(); @@ -3875,96 +3833,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) } } break; - case 48025: // Headless Horseman's Mount - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts and client crashes upon dismounting - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill and zone - bool canFly = true; - uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); - if (v_map != 530 && v_map != 571) - canFly = false; - - if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) - canFly = false; - - float x, y, z; - unitTarget->GetPosition(x, y, z); - uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); - AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); - if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) - canFly = false; - - switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) - { - case 75: unitTarget->CastSpell(unitTarget, 51621, true); break; - case 150: unitTarget->CastSpell(unitTarget, 48024, true); break; - case 225: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 51617, true); - else - unitTarget->CastSpell(unitTarget, 48024, true); - }break; - case 300: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 48023, true); - else - unitTarget->CastSpell(unitTarget, 48024, true); - }break; - } - return; - } - case 47977: // Magic Broom - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts and client crashes upon dismounting - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill and zone - bool canFly = true; - uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); - if (v_map != 530 && v_map != 571) - canFly = false; - - if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) - canFly = false; - - float x, y, z; - unitTarget->GetPosition(x, y, z); - uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); - AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); - if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) - canFly = false; - - switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) - { - case 75: unitTarget->CastSpell(unitTarget, 42680, true); break; - case 150: unitTarget->CastSpell(unitTarget, 42683, true); break; - case 225: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 42667, true); - else - unitTarget->CastSpell(unitTarget, 42683, true); - }break; - case 300: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 42668, true); - else - unitTarget->CastSpell(unitTarget, 42683, true); - }break; - } - return; - } // Mug Transformation case 41931: { @@ -4156,25 +4024,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) if (unitTarget) unitTarget->CastSpell(m_caster, damage, true); return; - // Winged Steed of the Ebon Blade - case 54729: - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts and client crashes upon dismounting - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill - if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING)) - { - if (skillval >= 300) - unitTarget->CastSpell(unitTarget, 54727, true); - else - unitTarget->CastSpell(unitTarget, 54726, true); - } - return; - } case 57347: // Retrieving (Wintergrasp RP-GG pickup spell) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || m_caster->GetTypeId() != TYPEID_PLAYER) @@ -4257,188 +4106,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) m_caster->CastSpell(m_caster, 63919, true); return; } - case 71342: // Big Love Rocket - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts and client crashes upon dismounting - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill and zone - bool canFly = true; - uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); - if (v_map != 530 && v_map != 571) - canFly = false; - - if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) - canFly = false; - - float x, y, z; - unitTarget->GetPosition(x, y, z); - uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); - AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); - if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) - canFly = false; - - switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) - { - case 0: unitTarget->CastSpell(unitTarget, 71343, true); break; - case 75: unitTarget->CastSpell(unitTarget, 71344, true); break; - case 150: unitTarget->CastSpell(unitTarget, 71345, true); break; - case 225: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 71346, true); - else - unitTarget->CastSpell(unitTarget, 71345, true); - }break; - case 300: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 71347, true); - else - unitTarget->CastSpell(unitTarget, 71345, true); - }break; - } - return; - } - case 72286: // Invincible - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts and client crashes upon dismounting - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill and zone - bool canFly = true; - uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); - if (v_map != 530 && v_map != 571) - canFly = false; - - if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) - canFly = false; - - float x, y, z; - unitTarget->GetPosition(x, y, z); - uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); - AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); - if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) - canFly = false; - - switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) - { - case 75: unitTarget->CastSpell(unitTarget, 72281, true); break; - case 150: unitTarget->CastSpell(unitTarget, 72282, true); break; - case 225: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 72283, true); - else - unitTarget->CastSpell(unitTarget, 72282, true); - }break; - case 300: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 72284, true); - else - unitTarget->CastSpell(unitTarget, 72282, true); - }break; - } - return; - } - case 74856: // Blazing Hippogryph - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts and client crashes upon dismounting - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill - if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING)) - { - if (skillval >= 300) - unitTarget->CastSpell(unitTarget, 74855, true); - else - unitTarget->CastSpell(unitTarget, 74854, true); - } - return; - } - case 75614: // Celestial Steed - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts and client crashes upon dismounting - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill and zone - bool canFly = true; - uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId()); - if (v_map != 530 && v_map != 571) - canFly = false; - - if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197)) - canFly = false; - - float x, y, z; - unitTarget->GetPosition(x, y, z); - uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z); - AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag); - if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE))) - canFly = false; - - switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING)) - { - case 75: unitTarget->CastSpell(unitTarget, 75619, true); break; - case 150: unitTarget->CastSpell(unitTarget, 75620, true); break; - case 225: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 75617, true); - else - unitTarget->CastSpell(unitTarget, 75620, true); - } - break; - case 300: - { - if (canFly) - unitTarget->CastSpell(unitTarget, 75618, true); - else - unitTarget->CastSpell(unitTarget, 75620, true); - } - break; - case 375: - if (canFly) - unitTarget->CastSpell(unitTarget, 76153, true); - else - unitTarget->CastSpell(unitTarget, 75620, true); - break; - } - return; - } - case 75973: // X-53 Touring Rocket - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // Prevent stacking of mounts - unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); - - // Triggered spell id dependent on riding skill - if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING)) - { - if (skillval >= 375) - unitTarget->CastSpell(unitTarget, 76154, true); - else if (skillval >= 300) - unitTarget->CastSpell(unitTarget, 75972, true); - else - unitTarget->CastSpell(unitTarget, 75957, true); - } - return; - } case 59317: // Teleporting if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5058,16 +4725,14 @@ void Spell::EffectDisEnchant(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - Player* p_caster = (Player*)m_caster; if (!itemTarget || !itemTarget->GetTemplate()->DisenchantID) return; - p_caster->UpdateCraftSkill(m_spellInfo->Id); - - m_caster->ToPlayer()->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING); + if (Player* caster = m_caster->ToPlayer()) + { + caster->UpdateCraftSkill(m_spellInfo->Id); + caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING); + } // item will be removed at disenchanting end } diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 183ca747b37..bb4815d5fc1 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -452,6 +452,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const if (!basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) && Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE && Effect != SPELL_EFFECT_KNOCK_BACK && + Effect != SPELL_EFFECT_ADD_EXTRA_ATTACKS && ApplyAuraName != SPELL_AURA_MOD_SPEED_ALWAYS && ApplyAuraName != SPELL_AURA_MOD_SPEED_NOT_STACK && ApplyAuraName != SPELL_AURA_MOD_INCREASE_SPEED && @@ -1810,6 +1811,7 @@ AuraStateType SpellInfo::GetAuraState() const switch (Id) { case 71465: // Divine Surge + case 50241: // Evasive Charges return AURA_STATE_UNKNOWN22; default: break; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 117953f2bc0..439b0c91324 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2960,8 +2960,10 @@ void SpellMgr::LoadDbcDataCorrections() switch (spellInfo->Id) { - case 40244: case 40245: // Simon Game Visual - case 40246: case 40247: // Simon Game Visual + case 40244: // Simon Game Visual + case 40245: // Simon Game Visual + case 40246: // Simon Game Visual + case 40247: // Simon Game Visual case 42835: // Spout, remove damage effect, only anim is needed spellInfo->Effect[0] = 0; break; @@ -2973,7 +2975,6 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectImplicitTargetB[0] = 0; break; case 63665: // Charge (Argent Tournament emote on riders) - case 31447: // Mark of Kaz'rogal (needs target selection script) case 31298: // Sleep (needs target selection script) case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed) case 2895: // Wrath of Air Totem rank 1 (Aura) @@ -3045,6 +3046,9 @@ void SpellMgr::LoadDbcDataCorrections() case 48246: // Ball of Flame spellInfo->MaxAffectedTargets = 1; break; + case 36384: // Skartax Purple Beam + spellInfo->MaxAffectedTargets = 2; + break; case 41376: // Spite case 39992: // Needle Spine case 29576: // Multi-Shot @@ -3084,7 +3088,7 @@ void SpellMgr::LoadDbcDataCorrections() case 50312: // Unholy Frenzy spellInfo->MaxAffectedTargets = 15; break; - case 33711: //Murmur's Touch + case 33711: // Murmur's Touch case 38794: spellInfo->MaxAffectedTargets = 1; spellInfo->EffectTriggerSpell[0] = 33760; @@ -3125,6 +3129,9 @@ void SpellMgr::LoadDbcDataCorrections() case 51852: // The Eye of Acherus (no spawn in phase 2 in db) spellInfo->EffectMiscValue[0] |= 1; break; + case 51912: // Crafty's Ultra-Advanced Proto-Typical Shortening Blaster + spellInfo->EffectAmplitude[0] = 3000; + break; case 29809: // Desecration Arm - 36 instead of 37 - typo? :/ spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_7_YARDS; break; @@ -3238,6 +3245,9 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1 spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0) break; + case 45602: // Ride Carpet + spellInfo->EffectBasePoints[EFFECT_0] = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)" + break; case 64745: // Item - Death Knight T8 Tank 4P Bonus case 64936: // Item - Warrior T8 Protection 4P Bonus spellInfo->EffectBasePoints[0] = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit) @@ -3252,9 +3262,16 @@ void SpellMgr::LoadDbcDataCorrections() case 53313: // Entangling Roots (Rank 8) -- Nature's Grasp Proc spellInfo->CastingTimeIndex = 1; break; + case 59414: // Pulsing Shockwave Aura (Loken) + // this flag breaks movement, remove it + spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1; + break; case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE; break; + case 70650: // Death Knight T10 Tank 2P Bonus + spellInfo->EffectApplyAuraName[0] = SPELL_AURA_ADD_PCT_MODIFIER; + break; // ULDUAR SPELLS // case 62374: // Pursued (Flame Leviathan) @@ -3293,11 +3310,6 @@ void SpellMgr::LoadDbcDataCorrections() // that will be clear if we get more spells with problem like this spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY; break; - case 62584: // Lifebinder's Gift - case 64185: // Lifebinder's Gift - spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_NEARBY_ENTRY; - spellInfo->EffectImplicitTargetB[2] = TARGET_UNIT_NEARBY_ENTRY; - break; case 62301: // Cosmic Smash (Algalon the Observer) spellInfo->MaxAffectedTargets = 1; break; @@ -3429,7 +3441,7 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_200_YARDS; // 200yd break; case 70598: // Sindragosa's Fury - spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER; + spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST; break; case 69846: // Frost Bomb spellInfo->speed = 0.0f; // This spell's summon happens instantly @@ -3539,11 +3551,6 @@ void SpellMgr::LoadDbcDataCorrections() switch (spellInfo->SpellFamilyName) { - case SPELLFAMILY_DRUID: - // Starfall Target Selection - if (spellInfo->SpellFamilyFlags[2] & 0x100) - spellInfo->MaxAffectedTargets = 2; - break; case SPELLFAMILY_PALADIN: // Seals of the Pure should affect Seal of Righteousness if (spellInfo->SpellIconID == 25 && spellInfo->Attributes & SPELL_ATTR0_PASSIVE) diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index e6ce80c20f0..d0ae6fe3098 100755 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -203,52 +203,106 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript) (spellScript->*pHitHandlerScript)(); } -SpellScript::UnitTargetHandler::UnitTargetHandler(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType) - : _SpellScript::EffectHook(_effIndex), targetType(_targetType) +SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area) + : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area) { - pUnitTargetHandlerScript = _pUnitTargetHandlerScript; } -std::string SpellScript::UnitTargetHandler::ToString() +std::string SpellScript::TargetHook::ToString() { std::ostringstream oss; oss << "Index: " << EffIndexToString() << " Target: " << targetType; return oss.str(); } -bool SpellScript::UnitTargetHandler::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) +bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) { if (!targetType) return false; - return (effIndex == EFFECT_ALL) || (spellEntry->Effects[effIndex].TargetA.GetTarget() == targetType || spellEntry->Effects[effIndex].TargetB.GetTarget() == targetType); + + if (spellEntry->Effects[effIndex].TargetA.GetTarget() != targetType && + spellEntry->Effects[effIndex].TargetB.GetTarget() != targetType) + return false; + + SpellImplicitTargetInfo targetInfo(targetType); + switch (targetInfo.GetSelectionCategory()) + { + case TARGET_SELECT_CATEGORY_CHANNEL: // SINGLE + return !area; + case TARGET_SELECT_CATEGORY_NEARBY: // BOTH + return true; + case TARGET_SELECT_CATEGORY_CONE: // AREA + case TARGET_SELECT_CATEGORY_AREA: // AREA + return area; + case TARGET_SELECT_CATEGORY_DEFAULT: + switch (targetInfo.GetObjectType()) + { + case TARGET_OBJECT_TYPE_SRC: // EMPTY + case TARGET_OBJECT_TYPE_DEST: // EMPTY + return false; + default: + switch (targetInfo.GetReferenceType()) + { + case TARGET_REFERENCE_TYPE_CASTER: // SINGLE + return !area; + case TARGET_REFERENCE_TYPE_TARGET: // BOTH + return true; + } + break; + } + break; + } + + return false; +} + +SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) + : TargetHook(_effIndex, _targetType, true) +{ + pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript; +} + +void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript, std::list<WorldObject*>& targets) +{ + (spellScript->*pObjectAreaTargetSelectHandlerScript)(targets); } -void SpellScript::UnitTargetHandler::Call(SpellScript* spellScript, std::list<Unit*>& unitTargets) +SpellScript::ObjectTargetSelectHandler::ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) + : TargetHook(_effIndex, _targetType, false) { - (spellScript->*pUnitTargetHandlerScript)(unitTargets); + pObjectTargetSelectHandlerScript = _pObjectTargetSelectHandlerScript; +} + +void SpellScript::ObjectTargetSelectHandler::Call(SpellScript* spellScript, WorldObject*& target) +{ + (spellScript->*pObjectTargetSelectHandlerScript)(target); } bool SpellScript::_Validate(SpellInfo const* entry) { - for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr) + for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunch` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); - for (std::list<EffectHandler>::iterator itr = OnEffectLaunchTarget.begin(); itr != OnEffectLaunchTarget.end(); ++itr) + for (std::list<EffectHandler>::iterator itr = OnEffectLaunchTarget.begin(); itr != OnEffectLaunchTarget.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunchTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); - for (std::list<EffectHandler>::iterator itr = OnEffectHit.begin(); itr != OnEffectHit.end(); ++itr) + for (std::list<EffectHandler>::iterator itr = OnEffectHit.begin(); itr != OnEffectHit.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHit` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); - for (std::list<EffectHandler>::iterator itr = OnEffectHitTarget.begin(); itr != OnEffectHitTarget.end(); ++itr) + for (std::list<EffectHandler>::iterator itr = OnEffectHitTarget.begin(); itr != OnEffectHitTarget.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHitTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); - for (std::list<UnitTargetHandler>::iterator itr = OnUnitTargetSelect.begin(); itr != OnUnitTargetSelect.end(); ++itr) + for (std::list<ObjectAreaTargetSelectHandler>::iterator itr = OnObjectAreaTargetSelect.begin(); itr != OnObjectAreaTargetSelect.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectAreaTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + + for (std::list<ObjectTargetSelectHandler>::iterator itr = OnObjectTargetSelect.begin(); itr != OnObjectTargetSelect.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) - sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnUnitTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + sLog->outError("TSCR: 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()); return _SpellScript::_Validate(entry); } diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 7b194b7827f..376e7f18edc 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -131,7 +131,8 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_BEFORE_HIT, SPELL_SCRIPT_HOOK_HIT, SPELL_SCRIPT_HOOK_AFTER_HIT, - SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT, + SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT, + SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT, SPELL_SCRIPT_HOOK_CHECK_CAST, SPELL_SCRIPT_HOOK_BEFORE_CAST, SPELL_SCRIPT_HOOK_ON_CAST, @@ -154,7 +155,8 @@ class SpellScript : public _SpellScript typedef void(CLASSNAME::*SpellEffectFnType)(SpellEffIndex); \ typedef void(CLASSNAME::*SpellHitFnType)(); \ typedef void(CLASSNAME::*SpellCastFnType)(); \ - typedef void(CLASSNAME::*SpellUnitTargetFnType)(std::list<Unit*>&); \ + typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \ + typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript) @@ -196,16 +198,33 @@ class SpellScript : public _SpellScript SpellHitFnType pHitHandlerScript; }; - class UnitTargetHandler : public _SpellScript::EffectHook + class TargetHook : public _SpellScript::EffectHook { public: - UnitTargetHandler(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType); + TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area); + bool CheckEffect(SpellInfo const* spellEntry, uint8 effIndex); std::string ToString(); - bool CheckEffect(SpellInfo const* spellEntry, uint8 targetType); - void Call(SpellScript* spellScript, std::list<Unit*>& unitTargets); - private: - SpellUnitTargetFnType pUnitTargetHandlerScript; + protected: uint16 targetType; + bool area; + }; + + class ObjectAreaTargetSelectHandler : public TargetHook + { + public: + ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); + void Call(SpellScript* spellScript, std::list<WorldObject*>& targets); + private: + SpellObjectAreaTargetSelectFnType pObjectAreaTargetSelectHandlerScript; + }; + + class ObjectTargetSelectHandler : public TargetHook + { + public: + ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType); + void Call(SpellScript* spellScript, WorldObject*& targets); + private: + SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript; }; #define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ @@ -213,7 +232,8 @@ class SpellScript : public _SpellScript 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 UnitTargetHandlerFunction : public SpellScript::UnitTargetHandler { public: UnitTargetHandlerFunction(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::UnitTargetHandler((SpellScript::SpellUnitTargetFnType)_pUnitTargetHandlerScript, _effIndex, _targetType) {} }; \ + 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) {} }; #define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) public: @@ -267,15 +287,21 @@ class SpellScript : public _SpellScript // where function is: void function() #define SpellHitFn(F) HitHandlerFunction(&F) - // example: OnUnitTargetSelect += SpellUnitTargetFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); - // where function is void function(std::list<Unit*>& targetList) - HookList<UnitTargetHandler> OnUnitTargetSelect; - #define SpellUnitTargetFn(F, I, N) UnitTargetHandlerFunction(&F, I, N) + // example: OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); + // where function is void function(std::list<WorldObject*>& targets) + HookList<ObjectAreaTargetSelectHandler> OnObjectAreaTargetSelect; + #define SpellObjectAreaTargetSelectFn(F, I, N) ObjectAreaTargetSelectHandlerFunction(&F, I, N) + + // example: OnObjectTargetSelect += SpellObjectTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier); + // where function is void function(WorldObject*& target) + HookList<ObjectTargetSelectHandler> OnObjectTargetSelect; + #define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandlerFunction(&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 - // 3. OnUnitTargetSelect - executed just before adding selected targets to final target list + // 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) // 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 @@ -302,7 +328,7 @@ class SpellScript : public _SpellScript // -shadowstep - explicit target is the unit you want to go behind of // -chain heal - explicit target is the unit to be healed first // -holy nova/arcane explosion - explicit target = NULL because target you are selecting doesn't affect how spell targets are selected - // you can determine if spell requires explicit targets by dbc columns: + // you can determine if spell requires explicit targets by dbc columns: // - Targets - mask of explicit target types // - ImplicitTargetXX set to TARGET_XXX_TARGET_YYY, _TARGET_ here means that explicit target is used by the effect, so spell needs one too diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index 0734e0a0f63..54e56174b1a 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -188,11 +188,14 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/) std::string accountName; AccountMgr::GetName(_session->GetAccountId(), accountName); std::stringstream banReason; - banReason << "Warden Anticheat Violation: " << check->Comment << " (CheckId: " << check->CheckId << ")"; + banReason << "Warden Anticheat Violation"; + // Check can be NULL, for example if the client sent a wrong signature in the warden packet (CHECKSUM FAIL) + if (check) + banReason << ": " << check->Comment << " (CheckId: " << check->CheckId << ")"; + sWorld->BanAccount(BAN_ACCOUNT, accountName, duration.str(), banReason.str(),"Server"); return "Ban"; - break; } default: break; @@ -208,7 +211,7 @@ void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData) sLog->outDebug(LOG_FILTER_WARDEN, "Got packet, opcode %02X, size %u", opcode, uint32(recvData.size())); recvData.hexlike(); - switch(opcode) + switch (opcode) { case WARDEN_CMSG_MODULE_MISSING: _warden->SendModuleToClient(); diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp index f4c7a5069cf..abd7ff8f87d 100644 --- a/src/server/game/Warden/WardenCheckMgr.cpp +++ b/src/server/game/Warden/WardenCheckMgr.cpp @@ -121,7 +121,7 @@ void WardenCheckMgr::LoadWardenChecks() if (checkType == MPQ_CHECK || checkType == MEM_CHECK) { - WardenCheckResult *wr = new WardenCheckResult(); + WardenCheckResult* wr = new WardenCheckResult(); wr->Result.SetHexStr(checkResult.c_str()); int len = checkResult.size() / 2; if (wr->Result.GetNumBytes() < len) diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index a60ae765013..3cc95b9f3f7 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -43,8 +43,8 @@ void WardenMac::Init(WorldSession *pClient, BigNumber *K) _session = pClient; // Generate Warden Key SHA1Randx WK(K->AsByteArray(), K->GetNumBytes()); - WK.generate(_inputKey, 16); - WK.generate(_outputKey, 16); + WK.Generate(_inputKey, 16); + WK.Generate(_outputKey, 16); /* Seed: 4D808D2C77D905C41A6380EC08586AFE (0x05 packet) Hash: <?> (0x04 packet) @@ -222,7 +222,7 @@ void WardenMac::HandleData(ByteBuffer &buff) // return; //} - bool found = false; + //bool found = false; std::string str = "Test string!"; @@ -238,7 +238,7 @@ void WardenMac::HandleData(ByteBuffer &buff) if (memcmp(sha1Hash, sha1.GetDigest(), 20)) { sLog->outDebug(LOG_FILTER_WARDEN, "Handle data failed: SHA1 hash is wrong!"); - found = true; + //found = true; } MD5_CTX ctx; @@ -253,7 +253,7 @@ void WardenMac::HandleData(ByteBuffer &buff) if (memcmp(ourMD5Hash, theirsMD5Hash, 16)) { sLog->outDebug(LOG_FILTER_WARDEN, "Handle data failed: MD5 hash is wrong!"); - found = true; + //found = true; } _session->KickPlayer(); diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index a7485d7da51..9aa439ec8c0 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -47,8 +47,8 @@ void WardenWin::Init(WorldSession* session, BigNumber *k) _session = session; // Generate Warden Key SHA1Randx WK(k->AsByteArray(), k->GetNumBytes()); - WK.generate(_inputKey, 16); - WK.generate(_outputKey, 16); + WK.Generate(_inputKey, 16); + WK.Generate(_outputKey, 16); memcpy(_seed, Module.Seed, 16); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a3b9054bd68..fc46d8d2d60 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1023,6 +1023,7 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_BG_XP_FOR_KILL] = ConfigMgr::GetBoolDefault("Battleground.GiveXPForKills", false); m_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = ConfigMgr::GetIntDefault ("Arena.MaxRatingDifference", 150); m_int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = ConfigMgr::GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS); + m_int_configs[CONFIG_ARENA_RATED_UPDATE_TIMER] = ConfigMgr::GetIntDefault ("Arena.RatedUpdateTimer", 5 * IN_MILLISECONDS); m_bool_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = ConfigMgr::GetBoolDefault("Arena.AutoDistributePoints", false); m_int_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = ConfigMgr::GetIntDefault ("Arena.AutoDistributeInterval", 7); m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = ConfigMgr::GetBoolDefault("Arena.QueueAnnouncer.Enable", false); @@ -1413,15 +1414,9 @@ void World::SetInitialWorldSettings() sLog->outString("Loading Creature Addon Data..."); sObjectMgr->LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures() - sLog->outString("Loading Creature Respawn Data..."); // must be after PackInstances() - sObjectMgr->LoadCreatureRespawnTimes(); - sLog->outString("Loading Gameobject Data..."); sObjectMgr->LoadGameobjects(); - sLog->outString("Loading Gameobject Respawn Data..."); // must be after PackInstances() - sObjectMgr->LoadGameobjectRespawnTimes(); - sLog->outString("Loading Creature Linked Respawn..."); sObjectMgr->LoadLinkedRespawn(); // must be after LoadCreatures(), LoadGameObjects() diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 51f384770da..450183226fc 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -289,6 +289,7 @@ enum WorldIntConfigs CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH, CONFIG_ARENA_MAX_RATING_DIFFERENCE, CONFIG_ARENA_RATING_DISCARD_TIMER, + CONFIG_ARENA_RATED_UPDATE_TIMER, CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS, CONFIG_ARENA_SEASON_ID, CONFIG_ARENA_START_RATING, |
