diff options
28 files changed, 342 insertions, 178 deletions
diff --git a/sql/updates/auth/2015_09_15_00_auth.sql b/sql/updates/auth/2015_09_15_00_auth.sql new file mode 100644 index 00000000000..0e84db63361 --- /dev/null +++ b/sql/updates/auth/2015_09_15_00_auth.sql @@ -0,0 +1,4 @@ +UPDATE `battlenet_components` SET `Build`=20490 WHERE `Program`='WoW' AND `Platform`='base' AND `Build`=20444; +UPDATE `battlenet_components` SET `Build`=20490 WHERE `Program`='WoW' AND `Platform` IN ('Mc64','Win','Wn64') AND `Build`=20444; + +UPDATE `realmlist` SET `gamebuild`=20490 WHERE `gamebuild`=20444; diff --git a/sql/updates/hotfixes/2015_09_16_00_hotfixes.sql b/sql/updates/hotfixes/2015_09_16_00_hotfixes.sql new file mode 100644 index 00000000000..4e516360224 --- /dev/null +++ b/sql/updates/hotfixes/2015_09_16_00_hotfixes.sql @@ -0,0 +1 @@ +ALTER TABLE `battle_pet_breed_quality` CHANGE COLUMN `Modifier` `Modifier` float NOT NULL DEFAULT '0'; diff --git a/src/server/game/BattlePets/BattlePetMgr.h b/src/server/game/BattlePets/BattlePetMgr.h index 97b1b34c13c..09823ccc2a7 100644 --- a/src/server/game/BattlePets/BattlePetMgr.h +++ b/src/server/game/BattlePets/BattlePetMgr.h @@ -29,7 +29,7 @@ enum BattlePetMisc DEFAULT_SUMMON_BATTLE_PET_SPELL = 118301 }; -// TODO: fix values in this enum +// TODO: fix undefined values in this enum enum BattlePetError { BATTLEPETRESULT_CANT_HAVE_MORE_PETS_OF_THAT_TYPE = 9, @@ -67,7 +67,9 @@ enum BattlePetState STATE_COSMETIC_TREASURE_GOBLIN = 176, // these are not in BattlePetState.db2 but are used in BattlePetSpeciesState.db2 STATE_START_WITH_BUFF = 183, - STATE_START_WITH_BUFF_2 = 184 + STATE_START_WITH_BUFF_2 = 184, + // + STATE_COSMETIC_SPECTRAL_BLUE = 196 }; enum BattlePetSaveInfo diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index ac2ab48c242..486cf79f5cf 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -36,7 +36,7 @@ #include "Transport.h" GameObject::GameObject() : WorldObject(false), MapObject(), - m_model(NULL), m_goValue(), m_AI(NULL) + m_model(NULL), m_goValue(), m_AI(NULL), _animKitId(0) { m_objectType |= TYPEMASK_GAMEOBJECT; m_objectTypeId = TYPEID_GAMEOBJECT; @@ -2426,6 +2426,26 @@ void GameObject::UpdateModelPosition() } } +void GameObject::SetAnimKitId(uint16 animKitId, bool oneshot) +{ + if (_animKitId == animKitId) + return; + + if (animKitId && !sAnimKitStore.LookupEntry(animKitId)) + return; + + if (!oneshot) + _animKitId = animKitId; + else + _animKitId = 0; + + WorldPackets::GameObject::GameObjectActivateAnimKit activateAnimKit; + activateAnimKit.ObjectGUID = GetGUID(); + activateAnimKit.AnimKitID = animKitId; + activateAnimKit.Maintain = !oneshot; + SendMessageToSet(activateAnimKit.Write(), true); +} + class GameObjectModelOwnerImpl : public GameObjectModelOwnerBase { public: diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 53c52f9ec5b..e81b3fe424d 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -1083,6 +1083,9 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map void UpdateModelPosition(); + uint16 GetAIAnimKitId() const override { return _animKitId; } + void SetAnimKitId(uint16 animKitId, bool oneshot); + protected: bool AIM_Initialize(); GameObjectModel* CreateModel(); @@ -1127,5 +1130,6 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map } GameObjectAI* m_AI; + uint16 _animKitId; }; #endif diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 95a2485bc7a..9e6ceda9f66 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1442,9 +1442,7 @@ void MovementInfo::OutDebug() WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0), m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL), m_transport(NULL), m_currMap(NULL), m_InstanceId(0), -m_phaseMask(PHASEMASK_NORMAL), _dbPhase(0), m_notifyflags(0), m_executed_notifies(0), -m_aiAnimKitId(0), m_movementAnimKitId(0), m_meleeAnimKitId(0) - +m_phaseMask(PHASEMASK_NORMAL), _dbPhase(0), m_notifyflags(0), m_executed_notifies(0) { m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST); m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); @@ -3108,54 +3106,6 @@ ObjectGuid WorldObject::GetTransGUID() const return ObjectGuid::Empty; } -void WorldObject::SetAIAnimKitId(uint16 animKitId) -{ - if (m_aiAnimKitId == animKitId) - return; - - if (animKitId && !sAnimKitStore.LookupEntry(animKitId)) - return; - - m_aiAnimKitId = animKitId; - - WorldPackets::Misc::SetAIAnimKit data; - data.Unit = GetGUID(); - data.AnimKitID = animKitId; - SendMessageToSet(data.Write(), true); -} - -void WorldObject::SetMovementAnimKitId(uint16 animKitId) -{ - if (m_movementAnimKitId == animKitId) - return; - - if (animKitId && !sAnimKitStore.LookupEntry(animKitId)) - return; - - m_movementAnimKitId = animKitId; - - WorldPacket data(SMSG_SET_MOVEMENT_ANIM_KIT, 8 + 2); - data << GetPackGUID(); - data << uint16(animKitId); - SendMessageToSet(&data, true); -} - -void WorldObject::SetMeleeAnimKitId(uint16 animKitId) -{ - if (m_meleeAnimKitId == animKitId) - return; - - if (animKitId && !sAnimKitStore.LookupEntry(animKitId)) - return; - - m_meleeAnimKitId = animKitId; - - WorldPacket data(SMSG_SET_MELEE_ANIM_KIT, 8 + 2); - data << GetPackGUID(); - data << uint16(animKitId); - SendMessageToSet(&data, true); -} - void WorldObject::RebuildTerrainSwaps() { // Clear all terrain swaps, will be rebuilt below diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index a466de3f62e..54b6677f714 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -616,12 +616,9 @@ class WorldObject : public Object, public WorldLocation virtual float GetStationaryZ() const { return GetPositionZ(); } virtual float GetStationaryO() const { return GetOrientation(); } - uint16 GetAIAnimKitId() const { return m_aiAnimKitId; } - void SetAIAnimKitId(uint16 animKitId); - uint16 GetMovementAnimKitId() const { return m_movementAnimKitId; } - void SetMovementAnimKitId(uint16 animKitId); - uint16 GetMeleeAnimKitId() const { return m_meleeAnimKitId; } - void SetMeleeAnimKitId(uint16 animKitId); + virtual uint16 GetAIAnimKitId() const { return 0; } + virtual uint16 GetMovementAnimKitId() const { return 0; } + virtual uint16 GetMeleeAnimKitId() const { return 0; } protected: std::string m_name; @@ -663,10 +660,6 @@ class WorldObject : public Object, public WorldLocation bool CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert = false) const; bool CanDetectInvisibilityOf(WorldObject const* obj) const; bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const; - - uint16 m_aiAnimKitId; - uint16 m_movementAnimKitId; - uint16 m_meleeAnimKitId; }; namespace Trinity diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp new file mode 100644 index 00000000000..34e19fabc1a --- /dev/null +++ b/src/server/game/Entities/Player/CollectionMgr.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008-2015 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 "CollectionMgr.h" +#include "Player.h" + +void CollectionMgr::LoadToys() +{ + for (auto const& t : _toys) + _owner->GetPlayer()->AddDynamicValue(PLAYER_DYNAMIC_FIELD_TOYS, t.first); +} + +bool CollectionMgr::AddToy(uint32 itemId, bool isFavourite /*= false*/) +{ + if (UpdateAccountToys(itemId, isFavourite)) + { + _owner->GetPlayer()->AddDynamicValue(PLAYER_DYNAMIC_FIELD_TOYS, itemId); + return true; + } + + return false; +} + +void CollectionMgr::LoadAccountToys(PreparedQueryResult result) +{ + if (!result) + return; + + do + { + Field* fields = result->Fetch(); + uint32 itemId = fields[0].GetUInt32(); + bool isFavourite = fields[1].GetBool(); + + _toys[itemId] = isFavourite; + } while (result->NextRow()); +} + +void CollectionMgr::SaveAccountToys(SQLTransaction& trans) +{ + PreparedStatement* stmt = NULL; + for (ToyBoxContainer::const_iterator itr = _toys.begin(); itr != _toys.end(); ++itr) + { + stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_ACCOUNT_TOYS); + stmt->setUInt32(0, _owner->GetBattlenetAccountId()); + stmt->setUInt32(1, itr->first); + stmt->setBool(2, itr->second); + trans->Append(stmt); + } +} + +bool CollectionMgr::UpdateAccountToys(uint32 itemId, bool isFavourite /*= false*/) +{ + return _toys.insert(ToyBoxContainer::value_type(itemId, isFavourite)).second; +} + +void CollectionMgr::ToySetFavorite(uint32 itemId, bool favorite) +{ + ToyBoxContainer::iterator itr = _toys.find(itemId); + if (itr == _toys.end()) + return; + + itr->second = favorite; +} diff --git a/src/server/game/Entities/Player/CollectionMgr.h b/src/server/game/Entities/Player/CollectionMgr.h new file mode 100644 index 00000000000..1920447be9c --- /dev/null +++ b/src/server/game/Entities/Player/CollectionMgr.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-2015 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/>. + */ + +#ifndef CollectionMgr_h__ +#define CollectionMgr_h__ + +#include "WorldSession.h" + +typedef std::map<uint32, bool> ToyBoxContainer; + +class CollectionMgr +{ +public: + explicit CollectionMgr(WorldSession* owner) : _owner(owner) { } + + WorldSession* GetOwner() const { return _owner; } + + // Account-wide toys + void LoadToys(); + void LoadAccountToys(PreparedQueryResult result); + void SaveAccountToys(SQLTransaction& trans); + void ToySetFavorite(uint32 itemId, bool favorite); + + bool AddToy(uint32 itemId, bool isFavourite /*= false*/); + bool UpdateAccountToys(uint32 itemId, bool isFavourite /*= false*/); + + ToyBoxContainer const& GetAccountToys() const { return _toys; } + + // Account-wide heirlooms + // Account-wide mounts + +private: + WorldSession* _owner; + + ToyBoxContainer _toys; +}; + +#endif // CollectionMgr_h__ diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 8d9d9426596..6af50b89b43 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17092,7 +17092,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) _LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS)); _LoadSpells(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS)); - _LoadToys(GetSession()->GetAccountToys()); + GetSession()->GetCollectionMgr()->LoadToys(); LearnSpecializationSpells(); @@ -18233,23 +18233,6 @@ void Player::_LoadSpells(PreparedQueryResult result) } } -void Player::_LoadToys(ToyBoxContainer const& toys) -{ - for (auto const& t : toys) - AddDynamicValue(PLAYER_DYNAMIC_FIELD_TOYS, t.first); -} - -bool Player::AddToy(uint32 itemId, bool isFavourite /*= false*/) -{ - if (GetSession()->UpdateAccountToys(itemId, isFavourite)) - { - AddDynamicValue(PLAYER_DYNAMIC_FIELD_TOYS, itemId); - return true; - } - - return false; -} - void Player::_LoadGroup(PreparedQueryResult result) { //QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM group_member WHERE memberGuid=%u", GetGUIDLow()); @@ -19052,7 +19035,7 @@ void Player::SaveToDB(bool create /*=false*/) // TODO: Move this out trans = LoginDatabase.BeginTransaction(); - GetSession()->SaveAccountToys(trans); + GetSession()->GetCollectionMgr()->SaveAccountToys(trans); GetSession()->GetBattlePetMgr()->SaveToDB(trans); LoginDatabase.CommitTransaction(trans); @@ -22506,7 +22489,7 @@ void Player::SendInitialPacketsBeforeAddToMap() // SMSG_ACCOUNT_TOYS_UPDATE WorldPackets::Toy::AccountToysUpdate toysUpdate; toysUpdate.IsFullUpdate = true; - toysUpdate.Toys = &GetSession()->GetAccountToys(); + toysUpdate.Toys = &GetSession()->GetCollectionMgr()->GetAccountToys(); SendDirectMessage(toysUpdate.Write()); WorldPackets::Character::InitialSetup initialSetup; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 51316b21c1a..d16fc7a1fc1 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2574,8 +2574,6 @@ class Player : public Unit, public GridObject<Player> VoidStorageItem* GetVoidStorageItem(uint8 slot) const; VoidStorageItem* GetVoidStorageItem(uint64 id, uint8& slot) const; - bool AddToy(uint32 itemId, bool isFavourite /*= false*/); - void OnCombatExit(); void CreateGarrison(uint32 garrSiteId); @@ -2653,7 +2651,6 @@ class Player : public Unit, public GridObject<Player> void _LoadGroup(PreparedQueryResult result); void _LoadSkills(PreparedQueryResult result); void _LoadSpells(PreparedQueryResult result); - void _LoadToys(ToyBoxContainer const& toys); void _LoadFriendList(PreparedQueryResult result); bool _LoadHomeBind(PreparedQueryResult result); void _LoadDeclinedNames(PreparedQueryResult result); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f5b13122ecf..1b9c2f02e61 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -201,7 +201,9 @@ Unit::Unit(bool isWorldObject) : i_AI(NULL), i_disabledAI(NULL), m_AutoRepeatFirstCast(false), m_procDeep(0), m_removedAurasCount(0), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this), m_vehicle(NULL), m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), - m_HostileRefManager(this), _lastDamagedTime(0), _spellHistory(new SpellHistory(this)) + m_HostileRefManager(this), _lastDamagedTime(0), + _aiAnimKitId(0), _movementAnimKitId(0), _meleeAnimKitId(0), + _spellHistory(new SpellHistory(this)) { m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; @@ -13422,6 +13424,54 @@ void Unit::SendDurabilityLoss(Player* receiver, uint32 percent) receiver->GetSession()->SendPacket(packet.Write()); } +void Unit::SetAIAnimKitId(uint16 animKitId) +{ + if (_aiAnimKitId == animKitId) + return; + + if (animKitId && !sAnimKitStore.LookupEntry(animKitId)) + return; + + _aiAnimKitId = animKitId; + + WorldPackets::Misc::SetAIAnimKit data; + data.Unit = GetGUID(); + data.AnimKitID = animKitId; + SendMessageToSet(data.Write(), true); +} + +void Unit::SetMovementAnimKitId(uint16 animKitId) +{ + if (_movementAnimKitId == animKitId) + return; + + if (animKitId && !sAnimKitStore.LookupEntry(animKitId)) + return; + + _movementAnimKitId = animKitId; + + WorldPackets::Misc::SetMovementAnimKit data; + data.Unit = GetGUID(); + data.AnimKitID = animKitId; + SendMessageToSet(data.Write(), true); +} + +void Unit::SetMeleeAnimKitId(uint16 animKitId) +{ + if (_meleeAnimKitId == animKitId) + return; + + if (animKitId && !sAnimKitStore.LookupEntry(animKitId)) + return; + + _meleeAnimKitId = animKitId; + + WorldPackets::Misc::SetMeleeAnimKit data; + data.Unit = GetGUID(); + data.AnimKitID = animKitId; + SendMessageToSet(data.Write(), true); +} + void Unit::PlayOneShotAnimKit(uint16 animKitId) { WorldPacket data(SMSG_PLAY_ONE_SHOT_ANIM_KIT, 7+2); @@ -15512,7 +15562,7 @@ void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference) { WorldPackets::Combat::ThreatInfo info; info.UnitGUID = (*itr)->getUnitGuid(); - info.Threat = int32((*itr)->getThreat()); + info.Threat = int32((*itr)->getThreat() * 100); packet.ThreatList.push_back(info); } SendMessageToSet(packet.Write(), false); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index de38e50c378..e13c8354d2a 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1490,6 +1490,12 @@ class Unit : public WorldObject MountCapabilityEntry const* GetMountCapability(uint32 mountType) const; void SendDurabilityLoss(Player* receiver, uint32 percent); + void SetAIAnimKitId(uint16 animKitId); + uint16 GetAIAnimKitId() const override { return _aiAnimKitId; } + void SetMovementAnimKitId(uint16 animKitId); + uint16 GetMovementAnimKitId() const override { return _movementAnimKitId; } + void SetMeleeAnimKitId(uint16 animKitId); + uint16 GetMeleeAnimKitId() const override { return _meleeAnimKitId; } void PlayOneShotAnimKit(uint16 animKitId); uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } @@ -1908,6 +1914,10 @@ class Unit : public WorldObject int32 GetCurrentSpellCastTime(uint32 spell_id) const; virtual SpellInfo const* GetCastSpellInfo(SpellInfo const* spellInfo) const; + uint16 _aiAnimKitId; + uint16 _movementAnimKitId; + uint16 _meleeAnimKitId; + SpellHistory* GetSpellHistory() { return _spellHistory; } SpellHistory const* GetSpellHistory() const { return _spellHistory; } diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp index b52ebdd9808..9126252ee60 100644 --- a/src/server/game/Garrison/Garrison.cpp +++ b/src/server/game/Garrison/Garrison.cpp @@ -734,7 +734,7 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact finalizer->SetRespawnTime(0); if (uint16 animKit = finalizeInfo->FactionInfo[faction].AnimKitId) - finalizer->SetAIAnimKitId(animKit); + finalizer->SetAnimKitId(animKit, false); map->AddToMap(finalizer); } diff --git a/src/server/game/Handlers/ToyHandler.cpp b/src/server/game/Handlers/ToyHandler.cpp index 89ed9426c0f..a68c2ca5064 100644 --- a/src/server/game/Handlers/ToyHandler.cpp +++ b/src/server/game/Handlers/ToyHandler.cpp @@ -41,7 +41,7 @@ void WorldSession::HandleAddToy(WorldPackets::Toy::AddToy& packet) return; } - if (_player->AddToy(item->GetEntry(), false)) + if (_collectionMgr->AddToy(item->GetEntry(), false)) _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); } @@ -74,9 +74,5 @@ void WorldSession::HandleUseToy(WorldPackets::Toy::UseToy& packet) void WorldSession::HandleToySetFavorite(WorldPackets::Toy::ToySetFavorite& packet) { - ToyBoxContainer::iterator itr = _toys.find(packet.ItemID); - if (itr == _toys.end()) - return; - - itr->second = packet.Favorite; + _collectionMgr->ToySetFavorite(packet.ItemID, packet.Favorite); } diff --git a/src/server/game/Server/Packets/BattlePetPackets.cpp b/src/server/game/Server/Packets/BattlePetPackets.cpp index 435b9f54338..43e08e75eea 100644 --- a/src/server/game/Server/Packets/BattlePetPackets.cpp +++ b/src/server/game/Server/Packets/BattlePetPackets.cpp @@ -21,8 +21,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePetSlot const& slot) { data << (slot.Pet.Guid.IsEmpty() ? ObjectGuid::Create<HighGuid::BattlePet>(0) : slot.Pet.Guid); - data << slot.CollarID; - data << slot.Index; + data << uint32(slot.CollarID); + data << uint8(slot.Index); data.WriteBit(slot.Locked); data.FlushBits(); @@ -32,18 +32,18 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePetSlot ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePet const& pet) { data << pet.Guid; - data << pet.Species; - data << pet.CreatureID; - data << pet.CollarID; - data << pet.Breed; - data << pet.Level; - data << pet.Exp; - data << pet.Flags; - data << pet.Power; - data << pet.Health; - data << pet.MaxHealth; - data << pet.Speed; - data << pet.Quality; + data << uint32(pet.Species); + data << uint32(pet.CreatureID); + data << uint32(pet.CollarID); + data << uint16(pet.Breed); + data << uint16(pet.Level); + data << uint16(pet.Exp); + data << uint16(pet.Flags); + data << uint32(pet.Power); + data << uint32(pet.Health); + data << uint32(pet.MaxHealth); + data << uint32(pet.Speed); + data << uint8(pet.Quality); data.WriteBits(pet.Name.size(), 7); data.WriteBit(!pet.Owner.IsEmpty()); // HasOwnerInfo data.WriteBit(pet.Name.empty()); // NoRename @@ -52,8 +52,8 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePet cons if (!pet.Owner.IsEmpty()) { data << pet.Owner; - data << GetVirtualRealmAddress(); // Virtual - data << GetVirtualRealmAddress(); // Native + data << uint32(GetVirtualRealmAddress()); // Virtual + data << uint32(GetVirtualRealmAddress()); // Native } data.WriteString(pet.Name); @@ -63,9 +63,9 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePet cons WorldPacket const* WorldPackets::BattlePet::BattlePetJournal::Write() { - _worldPacket << Trap; - _worldPacket << Slots.size(); - _worldPacket << Pets.size(); + _worldPacket << uint16(Trap); + _worldPacket << uint32(Slots.size()); + _worldPacket << uint32(Pets.size()); for (auto const& slot : Slots) _worldPacket << slot; @@ -73,7 +73,7 @@ WorldPacket const* WorldPackets::BattlePet::BattlePetJournal::Write() for (auto const& pet : Pets) _worldPacket << pet; - _worldPacket.WriteBit(1); // HasJournalLock + _worldPacket.WriteBit(HasJournalLock); _worldPacket.FlushBits(); return &_worldPacket; @@ -160,7 +160,7 @@ WorldPacket const* WorldPackets::BattlePet::BattlePetError::Write() { _worldPacket.WriteBits(Result, 4); _worldPacket.FlushBits(); - _worldPacket << CreatureID; + _worldPacket << uint32(CreatureID); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/BattlePetPackets.h b/src/server/game/Server/Packets/BattlePetPackets.h index 98112f23d5d..85edc748184 100644 --- a/src/server/game/Server/Packets/BattlePetPackets.h +++ b/src/server/game/Server/Packets/BattlePetPackets.h @@ -63,6 +63,7 @@ namespace WorldPackets uint16 Trap = 0; std::vector<BattlePetSlot> Slots; std::vector<BattlePet> Pets; + bool HasJournalLock = true; }; class BattlePetJournalLockAcquired final : public ServerPacket diff --git a/src/server/game/Server/Packets/GameObjectPackets.cpp b/src/server/game/Server/Packets/GameObjectPackets.cpp index c52a1974635..56498e44690 100644 --- a/src/server/game/Server/Packets/GameObjectPackets.cpp +++ b/src/server/game/Server/Packets/GameObjectPackets.cpp @@ -38,3 +38,13 @@ WorldPacket const* WorldPackets::GameObject::PageText::Write() _worldPacket << GameObjectGUID; return &_worldPacket; } + +WorldPacket const* WorldPackets::GameObject::GameObjectActivateAnimKit::Write() +{ + _worldPacket << ObjectGUID; + _worldPacket << uint32(AnimKitID); + _worldPacket.WriteBit(Maintain); + _worldPacket.FlushBits(); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/GameObjectPackets.h b/src/server/game/Server/Packets/GameObjectPackets.h index 6478293a9b7..5e0207190df 100644 --- a/src/server/game/Server/Packets/GameObjectPackets.h +++ b/src/server/game/Server/Packets/GameObjectPackets.h @@ -66,6 +66,18 @@ namespace WorldPackets ObjectGuid GameObjectGUID; }; + + class GameObjectActivateAnimKit final : public ServerPacket + { + public: + GameObjectActivateAnimKit() : ServerPacket(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, 16 + 4 + 1) { } + + WorldPacket const* Write() override; + + ObjectGuid ObjectGUID; + int32 AnimKitID = 0; + bool Maintain = false; + }; } } #endif // GOPackets_h__ diff --git a/src/server/game/Server/Packets/GarrisonPackets.h b/src/server/game/Server/Packets/GarrisonPackets.h index 7f5c4da424b..c678d89aaeb 100644 --- a/src/server/game/Server/Packets/GarrisonPackets.h +++ b/src/server/game/Server/Packets/GarrisonPackets.h @@ -87,7 +87,7 @@ namespace WorldPackets uint32 CurrentBuildingID = 0; uint32 CurrentMissionID = 0; std::list<GarrAbilityEntry const*> AbilityID; - uint32 FollowerStatus; + uint32 FollowerStatus = 0; std::string CustomName; }; @@ -105,8 +105,8 @@ namespace WorldPackets struct GarrisonMissionAreaBonus { - uint32 GarrMssnBonusAbilityID; - time_t StartTime; + uint32 GarrMssnBonusAbilityID = 0; + time_t StartTime = time_t(0); }; class GetGarrisonInfoResult final : public ServerPacket diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index b1799a1aa64..8617e56a841 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -532,6 +532,22 @@ WorldPacket const* WorldPackets::Misc::SetAIAnimKit::Write() return &_worldPacket; } +WorldPacket const* WorldPackets::Misc::SetMovementAnimKit::Write() +{ + _worldPacket << Unit; + _worldPacket << uint16(AnimKitID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Misc::SetMeleeAnimKit::Write() +{ + _worldPacket << Unit; + _worldPacket << uint16(AnimKitID); + + return &_worldPacket; +} + WorldPacket const* WorldPackets::Misc::SetPlayHoverAnim::Write() { _worldPacket << UnitGUID; diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index 749b9516e82..423a6ccbc8d 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -676,6 +676,28 @@ namespace WorldPackets uint16 AnimKitID = 0; }; + class SetMovementAnimKit final : public ServerPacket + { + public: + SetMovementAnimKit() : ServerPacket(SMSG_SET_MOVEMENT_ANIM_KIT, 16 + 2) { } + + WorldPacket const* Write() override; + + ObjectGuid Unit; + uint16 AnimKitID = 0; + }; + + class SetMeleeAnimKit final : public ServerPacket + { + public: + SetMeleeAnimKit() : ServerPacket(SMSG_SET_MELEE_ANIM_KIT, 16 + 2) { } + + WorldPacket const* Write() override; + + ObjectGuid Unit; + uint16 AnimKitID = 0; + }; + class SetPlayHoverAnim final : public ServerPacket { public: diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 367b0763e5a..5b6b9803b4a 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -395,15 +395,15 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS if (!splineFlags.cyclic) { uint32 count = spline.getPointCount() - 3; - for (uint32 i = 2; i < count; ++i) - movementSpline.Points.push_back(array[i]); + for (uint32 i = 0; i < count; ++i) + movementSpline.Points.push_back(array[i + 2]); } else { uint32 count = spline.getPointCount() - 3; movementSpline.Points.push_back(array[1]); - for (uint32 i = 1; i < count; ++i) - movementSpline.Points.push_back(array[i]); + for (uint32 i = 0; i < count; ++i) + movementSpline.Points.push_back(array[i + 1]); } } else @@ -422,8 +422,6 @@ void WorldPackets::Movement::MonsterMove::InitializeSplineData(::Movement::MoveS movementSpline.PackedDeltas.push_back(middle - realPath[i]); } } - - movementSpline.Mode = spline.mode(); } WorldPacket const* WorldPackets::Movement::MonsterMove::Write() diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index 7ce4abb3726..66261564989 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -78,8 +78,8 @@ namespace WorldPackets uint32 MoveTime = 0; float JumpGravity = 0.0f; uint32 SpecialTime = 0; - std::vector<G3D::Vector3> Points; // Spline path - uint8 Mode = 0; + std::vector<G3D::Vector3> Points; // Spline path + uint8 Mode = 0; // Spline mode - actually always 0 in this packet - Catmullrom mode appears only in SMSG_UPDATE_OBJECT. In this packet it is determined by flags uint8 VehicleExitVoluntary = 0; ObjectGuid TransportGUID; uint8 VehicleSeat = 255; diff --git a/src/server/game/Server/Packets/ToyPackets.h b/src/server/game/Server/Packets/ToyPackets.h index 11b0f47ddda..1fb0b7ddaf0 100644 --- a/src/server/game/Server/Packets/ToyPackets.h +++ b/src/server/game/Server/Packets/ToyPackets.h @@ -21,6 +21,7 @@ #include "Packet.h" #include "ObjectGuid.h" #include "SpellPackets.h" +#include "CollectionMgr.h" namespace WorldPackets { diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 67cbd08369e..fbbfb8cef53 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1101,7 +1101,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_OBJECT_RELINK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_CUSTOM_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_DESPAWN, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1603,7 +1603,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_RESEARCH_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_AI_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_AI_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ALL_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ANIM_TIER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1618,12 +1618,12 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ITEM_PURCHASE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_LOOT_METHOD_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MAX_WEEKLY_QUANTITY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MELEE_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MOVEMENT_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MELEE_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MOVEMENT_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PET_SPECIALIZATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TASK_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 4e60c366a66..79d1eb4ea12 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -50,6 +50,7 @@ #include "ChatPackets.h" #include "BattlePetMgr.h" #include "PacketUtilities.h" +#include "CollectionMgr.h" #include <zlib.h> @@ -132,7 +133,8 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun expireTime(60000), // 1 min after socket loss, session is deleted forceExit(false), m_currentBankerGUID(), - _battlePetMgr(Trinity::make_unique<BattlePetMgr>(this)) + _battlePetMgr(Trinity::make_unique<BattlePetMgr>(this)), + _collectionMgr(Trinity::make_unique<CollectionMgr>(this)) { memset(_tutorials, 0, sizeof(_tutorials)); @@ -750,40 +752,6 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask) while (result->NextRow()); } -void WorldSession::LoadAccountToys(PreparedQueryResult result) -{ - if (!result) - return; - - do - { - Field* fields = result->Fetch(); - uint32 itemId = fields[0].GetUInt32(); - bool isFavourite = fields[1].GetBool(); - - _toys[itemId] = isFavourite; - } - while (result->NextRow()); -} - -void WorldSession::SaveAccountToys(SQLTransaction& trans) -{ - PreparedStatement* stmt = NULL; - for (ToyBoxContainer::const_iterator itr = _toys.begin(); itr != _toys.end(); ++itr) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_ACCOUNT_TOYS); - stmt->setUInt32(0, GetBattlenetAccountId()); - stmt->setUInt32(1, itr->first); - stmt->setBool(2, itr->second); - trans->Append(stmt); - } -} - -bool WorldSession::UpdateAccountToys(uint32 itemId, bool isFavourite /*= false*/) -{ - return _toys.insert(ToyBoxContainer::value_type(itemId, isFavourite)).second; -} - void WorldSession::SetAccountData(AccountDataType type, uint32 time, std::string const& data) { if ((1 << type) & GLOBAL_CACHE_MASK) @@ -1248,7 +1216,7 @@ void WorldSession::InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQue { LoadAccountData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK); LoadTutorialsData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS)); - LoadAccountToys(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_TOYS)); + _collectionMgr->LoadAccountToys(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_TOYS)); if (!m_inQueue) SendAuthResponse(AUTH_OK, false); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index e30f5d030b8..79e50046d9a 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -35,6 +35,7 @@ class BattlePetMgr; class Channel; +class CollectionMgr; class Creature; class GameObject; class InstanceSave; @@ -694,8 +695,6 @@ enum Tutorials #define MAX_ACCOUNT_TUTORIAL_VALUES 8 -typedef std::map<uint32, bool> ToyBoxContainer; - struct AccountData { time_t Time = 0; @@ -919,12 +918,6 @@ class WorldSession void SetAccountData(AccountDataType type, uint32 time, std::string const& data); void LoadAccountData(PreparedQueryResult result, uint32 mask); - // Account Toys - void LoadAccountToys(PreparedQueryResult result); - void SaveAccountToys(SQLTransaction& trans); - bool UpdateAccountToys(uint32 itemId, bool isFavourite /*= false*/); - ToyBoxContainer const& GetAccountToys() const { return _toys; } - void LoadTutorialsData(PreparedQueryResult result); void SendTutorialsData(); void SaveTutorialsData(SQLTransaction& trans); @@ -1014,6 +1007,8 @@ class WorldSession // Battle Pets BattlePetMgr* GetBattlePetMgr() const { return _battlePetMgr.get(); } + CollectionMgr* GetCollectionMgr() const { return _collectionMgr.get(); } + public: // opcodes handlers void Handle_NULL(WorldPackets::Null& null); // not used @@ -1730,10 +1725,11 @@ class WorldSession uint32 expireTime; bool forceExit; ObjectGuid m_currentBankerGUID; - ToyBoxContainer _toys; std::unique_ptr<BattlePetMgr> _battlePetMgr; + std::unique_ptr<CollectionMgr> _collectionMgr; + WorldSession(WorldSession const& right) = delete; WorldSession& operator=(WorldSession const& right) = delete; }; |