diff --git a/sql/updates/world/3.3.5/2024_09_11_00_world.sql b/sql/updates/world/3.3.5/2024_09_11_00_world.sql new file mode 100644 index 0000000000..501f0bdaf1 --- /dev/null +++ b/sql/updates/world/3.3.5/2024_09_11_00_world.sql @@ -0,0 +1,2 @@ +-- Steelbreaker: Fix wrong itemId for Belt of the Crystal Tree +UPDATE creature_loot_template SET `Item`=45455 WHERE `entry`=32867 AND `Item`=25455; diff --git a/sql/updates/world/3.3.5/2024_09_14_00_world.sql b/sql/updates/world/3.3.5/2024_09_14_00_world.sql new file mode 100644 index 0000000000..d56ef87534 --- /dev/null +++ b/sql/updates/world/3.3.5/2024_09_14_00_world.sql @@ -0,0 +1,46 @@ +-- Shard of a Felhound +UPDATE `quest_details` SET `Emote2`=1,`Emote3`=1 WHERE `ID`=4962; + +-- The Binding +DELETE FROM `quest_details` WHERE `ID`=1795; +INSERT INTO `quest_details` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`VerifiedBuild`) VALUES +(1795,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1,`EmoteOncomplete`=1 WHERE `ID`=1795; +UPDATE `quest_offer_reward` SET `Emote1`=1,`Emote2`=2 WHERE `ID`=1795; + +-- The Orb of Soran'ruk +DELETE FROM `quest_details` WHERE `ID`=1740; +INSERT INTO `quest_details` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`VerifiedBuild`) VALUES +(1740,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1,`EmoteOncomplete`=1 WHERE `ID`=1740; +UPDATE `quest_offer_reward` SET `Emote1`=1,`Emote2`=1 WHERE `ID`=1740; + +-- The Affray +UPDATE `quest_details` SET `Emote3`=25 WHERE `ID`=1719; + +-- Tome of the Cabal +DELETE FROM `quest_details` WHERE `ID`=1758; +INSERT INTO `quest_details` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`VerifiedBuild`) VALUES +(1758,1,1,0,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=6 WHERE `ID`=1758; + +-- A Host of Evil +DELETE FROM `quest_details` WHERE `ID`=6626; +INSERT INTO `quest_details` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`VerifiedBuild`) VALUES +(6626,1,1,0,0,0,0,0,0,0); +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=1 WHERE `ID`=6626; +UPDATE `quest_offer_reward` SET `Emote1`=1,`Emote2`=1 WHERE `ID`=6626; + +-- Blueleaf Tubers +UPDATE `quest_request_items` SET `EmoteOnIncomplete`=6,`EmoteOncomplete`=6 WHERE `ID`=1221; + +-- Passage to Booty Bay +DELETE FROM `quest_details` WHERE `ID`=1040; +INSERT INTO `quest_details` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`VerifiedBuild`) VALUES +(1040,1,1,1,0,0,0,0,0,0); +UPDATE `quest_offer_reward` SET `Emote1`=1,`Emote2`=1 WHERE `ID`=1040; + +-- Mission: Possible But Not Probable +DELETE FROM `quest_details` WHERE `ID`=2478; +INSERT INTO `quest_details` (`ID`,`Emote1`,`Emote2`,`Emote3`,`Emote4`,`EmoteDelay1`,`EmoteDelay2`,`EmoteDelay3`,`EmoteDelay4`,`VerifiedBuild`) VALUES +(2478,1,1,1,1,0,0,0,0,0); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp index 6cd32cd475..7ef37f3e89 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp @@ -182,7 +182,7 @@ bool AuctionBotSeller::Initialize() allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_ALLOW_ZERO); break; case ITEM_CLASS_KEY: allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_ALLOW_ZERO); break; - case ITEM_CLASS_MISC: + case ITEM_CLASS_MISCELLANEOUS: allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_ALLOW_ZERO); break; case ITEM_CLASS_GLYPH: allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_ALLOW_ZERO); break; @@ -273,7 +273,7 @@ bool AuctionBotSeller::Initialize() continue; break; } - case ITEM_CLASS_MISC: + case ITEM_CLASS_MISCELLANEOUS: if (prototype->SubClass == ITEM_SUBCLASS_JUNK_MOUNT) { if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL)) @@ -399,7 +399,7 @@ void AuctionBotSeller::LoadItemsQuantity(SellerConfiguration& config) config.SetRandomStackRatioPerClass(ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUIVER)); config.SetRandomStackRatioPerClass(ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUEST)); config.SetRandomStackRatioPerClass(ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY)); - config.SetRandomStackRatioPerClass(ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC)); + config.SetRandomStackRatioPerClass(ITEM_CLASS_MISCELLANEOUS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC)); config.SetRandomStackRatioPerClass(ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH)); // Set the best value to get nearest amount of items wanted @@ -434,7 +434,7 @@ void AuctionBotSeller::LoadItemsQuantity(SellerConfiguration& config) index = CONFIG_AHBOT_CLASS_QUEST_PRIORITY; break; case ITEM_CLASS_KEY: index = CONFIG_AHBOT_CLASS_KEY_PRIORITY; break; - case ITEM_CLASS_MISC: + case ITEM_CLASS_MISCELLANEOUS: index = CONFIG_AHBOT_CLASS_MISC_PRIORITY; break; case ITEM_CLASS_GLYPH: index = CONFIG_AHBOT_CLASS_GLYPH_PRIORITY; break; @@ -512,7 +512,7 @@ void AuctionBotSeller::LoadSellerValues(SellerConfiguration& config) config.SetPriceRatioPerClass(ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_PRICE_RATIO)); config.SetPriceRatioPerClass(ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_PRICE_RATIO)); config.SetPriceRatioPerClass(ITEM_CLASS_PERMANENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PERMANENT_PRICE_RATIO)); - config.SetPriceRatioPerClass(ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_MISCELLANEOUS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO)); config.SetPriceRatioPerClass(ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_PRICE_RATIO)); //load min and max auction times @@ -691,7 +691,7 @@ uint32 AuctionBotSeller::GetBuyModifier(ItemTemplate const* prototype) case ITEM_SUBCLASS_WEAPON_AXE: case ITEM_SUBCLASS_WEAPON_MACE: case ITEM_SUBCLASS_WEAPON_SWORD: - case ITEM_SUBCLASS_WEAPON_FIST: + case ITEM_SUBCLASS_WEAPON_FIST_WEAPON: case ITEM_SUBCLASS_WEAPON_DAGGER: return 1200; case ITEM_SUBCLASS_WEAPON_AXE2: @@ -710,7 +710,7 @@ uint32 AuctionBotSeller::GetBuyModifier(ItemTemplate const* prototype) { switch (prototype->SubClass) { - case ITEM_SUBCLASS_ARMOR_MISC: + case ITEM_SUBCLASS_ARMOR_MISCELLANEOUS: case ITEM_SUBCLASS_ARMOR_CLOTH: return 500; case ITEM_SUBCLASS_ARMOR_LEATHER: diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 23e5d83d00..6787e04080 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -308,7 +308,7 @@ enum ItemClass : uint8 ITEM_CLASS_QUEST = 12, ITEM_CLASS_KEY = 13, ITEM_CLASS_PERMANENT = 14, - ITEM_CLASS_MISC = 15, + ITEM_CLASS_MISCELLANEOUS = 15, ITEM_CLASS_GLYPH = 16 }; @@ -321,7 +321,7 @@ enum ItemSubclassConsumable ITEM_SUBCLASS_ELIXIR = 2, ITEM_SUBCLASS_FLASK = 3, ITEM_SUBCLASS_SCROLL = 4, - ITEM_SUBCLASS_FOOD = 5, + ITEM_SUBCLASS_FOOD_DRINK = 5, ITEM_SUBCLASS_ITEM_ENHANCEMENT = 6, ITEM_SUBCLASS_BANDAGE = 7, ITEM_SUBCLASS_CONSUMABLE_OTHER = 8 @@ -359,8 +359,8 @@ enum ItemSubclassWeapon ITEM_SUBCLASS_WEAPON_STAFF = 10, ITEM_SUBCLASS_WEAPON_EXOTIC = 11, ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12, - ITEM_SUBCLASS_WEAPON_FIST = 13, - ITEM_SUBCLASS_WEAPON_MISC = 14, + ITEM_SUBCLASS_WEAPON_FIST_WEAPON = 13, + ITEM_SUBCLASS_WEAPON_MISCELLANEOUS = 14, ITEM_SUBCLASS_WEAPON_DAGGER = 15, ITEM_SUBCLASS_WEAPON_THROWN = 16, ITEM_SUBCLASS_WEAPON_SPEAR = 17, @@ -392,7 +392,7 @@ enum ItemSubclassGem enum ItemSubclassArmor { - ITEM_SUBCLASS_ARMOR_MISC = 0, + ITEM_SUBCLASS_ARMOR_MISCELLANEOUS = 0, ITEM_SUBCLASS_ARMOR_CLOTH = 1, ITEM_SUBCLASS_ARMOR_LEATHER = 2, ITEM_SUBCLASS_ARMOR_MAIL = 3, @@ -466,10 +466,11 @@ enum ItemSubclassRecipe ITEM_SUBCLASS_FIRST_AID_MANUAL = 7, ITEM_SUBCLASS_ENCHANTING_FORMULA = 8, ITEM_SUBCLASS_FISHING_MANUAL = 9, - ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10 + ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10, + ITEM_SUBCLASS_INSCRIPTION_TECHNIQUE = 11 }; -#define MAX_ITEM_SUBCLASS_RECIPE 11 +#define MAX_ITEM_SUBCLASS_RECIPE 12 enum ItemSubclassMoney { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 26f956e32c..7d1c1a75bb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -197,9 +197,6 @@ Player::Player(WorldSession* session): Unit(true) if (!GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS)) SetAcceptWhispers(true); - m_usedTalentCount = 0; - m_questRewardTalentCount = 0; - m_regenTimer = 0; m_regenTimerCount = 0; m_foodEmoteTimerCount = 0; @@ -305,8 +302,6 @@ Player::Player(WorldSession* session): Unit(true) unReadMails = 0; m_nextMailDelivereTime = 0; - m_resetTalentsCost = 0; - m_resetTalentsTime = 0; m_itemUpdateQueueBlocked = false; /////////////////// Instance System ///////////////////// @@ -319,16 +314,7 @@ Player::Player(WorldSession* session): Unit(true) m_lastPotionId = 0; - m_activeSpec = 0; - m_specsCount = 1; - - for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) - { - for (uint8 g = 0; g < MAX_GLYPH_SLOT_INDEX; ++g) - m_Glyphs[i][g] = 0; - - m_talents[i] = new PlayerTalentMap(); - } + _talentMgr = new PlayerTalentInfo(); for (uint8 i = 0; i < BASEMOD_END; ++i) { @@ -415,12 +401,7 @@ Player::~Player() for (uint8 i = 0; i < PLAYER_SLOTS_COUNT; ++i) delete m_items[i]; - for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) - { - for (PlayerTalentMap::const_iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end(); ++itr) - delete itr->second; - delete m_talents[i]; - } + delete _talentMgr; //all mailed items should be deleted, also all mail should be deallocated for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr) @@ -613,7 +594,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo uint32 count = iProto->BuyCount; // special amount for food/drink - if (iProto->Class == ITEM_CLASS_CONSUMABLE && iProto->SubClass == ITEM_SUBCLASS_FOOD) + if (iProto->Class == ITEM_CLASS_CONSUMABLE && iProto->SubClass == ITEM_SUBCLASS_FOOD_DRINK) { switch (iProto->Spells[0].SpellCategory) { @@ -2615,7 +2596,7 @@ void Player::InitTalentForLevel() if (level < 10) { // Remove all talent points - if (m_usedTalentCount > 0) // Free any used talents + if (GetUsedTalentCount() > 0) // Free any used talents { ResetTalents(true); SetFreeTalentPoints(0); @@ -2623,16 +2604,16 @@ void Player::InitTalentForLevel() } else { - if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || m_specsCount == 0) + if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || GetSpecsCount() == 0) { - m_specsCount = 1; - m_activeSpec = 0; + SetSpecsCount(1); + SetActiveSpec(0); } uint32 talentPointsForLevel = CalculateTalentsPoints(); // if used more that have then reset - if (m_usedTalentCount > talentPointsForLevel) + if (GetUsedTalentCount() > talentPointsForLevel) { if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED)) ResetTalents(true); @@ -2641,7 +2622,7 @@ void Player::InitTalentForLevel() } // else update amount of free points else - SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount); + SetFreeTalentPoints(talentPointsForLevel - GetUsedTalentCount()); } if (!GetSession()->PlayerLoading()) @@ -2837,7 +2818,7 @@ void Player::SendInitialSpells() data << uint32(itr->first); data << uint16(0); // it's not slot id - spellCount +=1; + ++spellCount; } data.put(countPos, spellCount); // write real count value @@ -3013,8 +2994,8 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) return false; } - PlayerTalentMap::iterator itr = m_talents[spec]->find(spellId); - if (itr != m_talents[spec]->end()) + PlayerTalentMap::iterator itr = GetTalentMap(spec)->find(spellId); + if (itr != GetTalentMap(spec)->end()) itr->second->state = PLAYERSPELL_UNCHANGED; else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId)) { @@ -3027,8 +3008,8 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) if (!rankSpellId || rankSpellId == spellId) continue; - itr = m_talents[spec]->find(rankSpellId); - if (itr != m_talents[spec]->end()) + itr = GetTalentMap(spec)->find(rankSpellId); + if (itr != GetTalentMap(spec)->end()) itr->second->state = PLAYERSPELL_REMOVED; } } @@ -3038,7 +3019,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) newtalent->state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED; newtalent->spec = spec; - (*m_talents[spec])[spellId] = newtalent; + (*GetTalentMap(spec))[spellId] = newtalent; return true; } return false; @@ -3331,7 +3312,7 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent } // update used talent points count - m_usedTalentCount += talentCost; + SetUsedTalentCount(GetUsedTalentCount() + talentCost); // update free primary prof.points (if any, can be none in case GM .learn prof. learning) if (uint32 freeProfs = GetFreePrimaryProfessionPoints()) @@ -3569,10 +3550,10 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank) uint32 talentCosts = GetTalentSpellCost(spell_id); if (talentCosts > 0 && giveTalentPoints) { - if (talentCosts < m_usedTalentCount) - m_usedTalentCount -= talentCosts; + if (talentCosts < GetUsedTalentCount()) + SetUsedTalentCount(GetUsedTalentCount() - talentCosts); else - m_usedTalentCount = 0; + SetUsedTalentCount(0); } // update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning) @@ -3789,28 +3770,28 @@ uint32 Player::ResetTalentsCost() const return 0; // The first time reset costs 1 gold - if (m_resetTalentsCost < 1*GOLD) + if (GetTalentResetCost() < 1*GOLD) return 1*GOLD; // then 5 gold - else if (m_resetTalentsCost < 5*GOLD) + else if (GetTalentResetCost() < 5*GOLD) return 5*GOLD; // After that it increases in increments of 5 gold - else if (m_resetTalentsCost < 10*GOLD) + else if (GetTalentResetCost() < 10*GOLD) return 10*GOLD; else { - uint64 months = (GameTime::GetGameTime() - m_resetTalentsTime)/MONTH; + uint64 months = (GameTime::GetGameTime() - GetTalentResetTime())/MONTH; if (months > 0) { // This cost will be reduced by a rate of 5 gold per month - int32 new_cost = int32(m_resetTalentsCost - 5*GOLD*months); + int32 new_cost = int32(GetTalentResetCost() - 5*GOLD*months); // to a minimum of 10 gold. return (new_cost < 10*GOLD ? 10*GOLD : new_cost); } else { // After that it increases in increments of 5 gold - int32 new_cost = m_resetTalentsCost + 5*GOLD; + int32 new_cost = GetTalentResetCost() + 5*GOLD; // until it hits a cap of 50 gold. if (new_cost > 50*GOLD) new_cost = 50*GOLD; @@ -3822,9 +3803,9 @@ uint32 Player::ResetTalentsCost() const void Player::IncreaseResetTalentsCostAndCounters(uint32 lastResetTalentsCost) { if (lastResetTalentsCost > 0) // We don't want to reset the accumulated talent reset cost if we decide to temporarily enable CONFIG_NO_RESET_TALENT_COST - m_resetTalentsCost = lastResetTalentsCost; + _talentMgr->ResetTalentsCost = lastResetTalentsCost; - m_resetTalentsTime = GameTime::GetGameTime(); + _talentMgr->ResetTalentsTime = GameTime::GetGameTime(); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, lastResetTalentsCost); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1); @@ -3840,7 +3821,7 @@ bool Player::ResetTalents(bool involuntarily /*= false*/) uint32 talentPointsForLevel = CalculateTalentsPoints(); - if (m_usedTalentCount == 0) + if (!GetUsedTalentCount()) { SetFreeTalentPoints(talentPointsForLevel); return false; @@ -3880,8 +3861,8 @@ bool Player::ResetTalents(bool involuntarily /*= false*/) if (spellEffectInfo.IsEffect(SPELL_EFFECT_LEARN_SPELL) && spellEffectInfo.TriggerSpell > 0) RemoveSpell(spellEffectInfo.TriggerSpell, true); // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted - PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->SpellRank[rank]); - if (plrTalent != m_talents[m_activeSpec]->end()) + PlayerTalentMap::iterator plrTalent = GetTalentMap(GetActiveSpec())->find(talentInfo->SpellRank[rank]); + if (plrTalent != GetTalentMap(GetActiveSpec())->end()) plrTalent->second->state = PLAYERSPELL_REMOVED; } } @@ -3985,8 +3966,8 @@ bool Player::HasSpell(uint32 spell) const bool Player::HasTalent(uint32 spell, uint8 spec) const { - PlayerTalentMap::const_iterator itr = m_talents[spec]->find(spell); - return (itr != m_talents[spec]->end() && itr->second->state != PLAYERSPELL_REMOVED); + PlayerTalentMap::const_iterator itr = GetTalentMap(spec)->find(spell); + return (itr != GetTalentMap(spec)->end() && itr->second->state != PLAYERSPELL_REMOVED); } bool Player::HasActiveSpell(uint32 spell) const @@ -4411,24 +4392,6 @@ void Player::DeleteOldCharacters(uint32 keepDays) } } -void Player::SetMovement(PlayerMovementType pType) -{ - WorldPacket data; - switch (pType) - { - case MOVE_ROOT: data.Initialize(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size()+4); break; - case MOVE_UNROOT: data.Initialize(SMSG_FORCE_MOVE_UNROOT, GetPackGUID().size()+4); break; - case MOVE_WATER_WALK: data.Initialize(SMSG_MOVE_WATER_WALK, GetPackGUID().size()+4); break; - case MOVE_LAND_WALK: data.Initialize(SMSG_MOVE_LAND_WALK, GetPackGUID().size()+4); break; - default: - TC_LOG_ERROR("entities.player", "Player::SetMovement: Unsupported move type ({}), data not sent to client.", pType); - return; - } - data << GetPackGUID(); - data << uint32(0); - SendDirectMessage(&data); -} - /* Preconditions: - a resurrectable corpse must not be loaded for the player (only bones) - the player must be in world @@ -4466,9 +4429,9 @@ void Player::BuildPlayerRepop() setDeathState(DEAD); SetHealth(1); - SetMovement(MOVE_WATER_WALK); + SetWaterWalking(true); if (!GetSession()->isLogingOut()) - SetMovement(MOVE_UNROOT); + SetRooted(false); // BG - remove insignia related RemoveUnitFlag(UNIT_FLAG_SKINNABLE); @@ -4507,8 +4470,10 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) setDeathState(ALIVE); - SetMovement(MOVE_LAND_WALK); - SetMovement(MOVE_UNROOT); + // add the flag to make sure opcode is always sent + AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING); + SetWaterWalking(false); + SetRooted(false); m_deathTimer = 0; @@ -4581,7 +4546,7 @@ void Player::KillPlayer() if (IsFlying() && !GetTransport()) GetMotionMaster()->MoveFall(); - SetMovement(MOVE_ROOT); + SetRooted(true); StopMirrorTimers(); //disable timers(bars) @@ -5787,7 +5752,7 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType) { case ITEM_SUBCLASS_WEAPON_FISHING_POLE: break; - case ITEM_SUBCLASS_WEAPON_FIST: + case ITEM_SUBCLASS_WEAPON_FIST_WEAPON: UpdateSkill(SKILL_UNARMED, weapon_skill_gain); [[fallthrough]]; default: @@ -9604,7 +9569,7 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c if (playerClass == CLASS_SHAMAN) slots[0] = EQUIPMENT_SLOT_RANGED; break; - case ITEM_SUBCLASS_ARMOR_MISC: + case ITEM_SUBCLASS_ARMOR_MISCELLANEOUS: if (playerClass == CLASS_WARLOCK) slots[0] = EQUIPMENT_SLOT_RANGED; break; @@ -11795,7 +11760,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje if (proto->Class == ITEM_CLASS_WEAPON && GetSkillValue(item_weapon_skills[proto->SubClass]) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISC && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK) + if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISCELLANEOUS && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK) { if (_class == CLASS_WARRIOR || _class == CLASS_PALADIN || _class == CLASS_DEATH_KNIGHT) { @@ -15219,9 +15184,9 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, SetTitle(titleEntry); } - if (quest->GetBonusTalents()) + if (uint32 talents = quest->GetBonusTalents()) { - m_questRewardTalentCount += quest->GetBonusTalents(); + AddQuestRewardedTalentCount(talents); InitTalentForLevel(); } @@ -16806,10 +16771,10 @@ void Player::SendQuestComplete(uint32 quest_id) const void Player::SendQuestReward(Quest const* quest, uint32 XP) const { - uint32 questid = quest->GetQuestId(); - sGameEventMgr->HandleQuestComplete(questid); + uint32 questId = quest->GetQuestId(); + sGameEventMgr->HandleQuestComplete(questId); WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4)); - data << uint32(questid); + data << uint32(questId); if (!IsMaxLevel()) data << uint32(XP); @@ -17651,8 +17616,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol m_Played_time[PLAYED_TIME_TOTAL] = fields[24].GetUInt32(); m_Played_time[PLAYED_TIME_LEVEL] = fields[25].GetUInt32(); - m_resetTalentsCost = fields[29].GetUInt32(); - m_resetTalentsTime = time_t(fields[30].GetUInt32()); + SetTalentResetCost(fields[29].GetUInt32()); + SetTalentResetTime(time_t(fields[30].GetUInt32())); if (!m_taxi.LoadTaxiMask(fields[22].GetString())) // must be before InitTaxiNodesForLevel TC_LOG_WARN("entities.player.loading", "Player::LoadFromDB: Player ({}) has invalid taximask ({}) in DB. Forced partial load.", GetGUID().ToString(), fields[22].GetString()); @@ -17735,15 +17700,15 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol //mails are loaded only when needed ;-) - when player in game click on mailbox. //_LoadMail(); - m_specsCount = fields[64].GetUInt8(); - m_activeSpec = fields[65].GetUInt8(); + SetSpecsCount(fields[64].GetUInt8()); + SetActiveSpec(fields[65].GetUInt8()); // sanity check - if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC || m_specsCount < MIN_TALENT_SPECS) + if (GetSpecsCount() > MAX_TALENT_SPECS || GetActiveSpec() > MAX_TALENT_SPEC || GetSpecsCount() < MIN_TALENT_SPECS) { TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player {} ({}) has invalid SpecCount = {} and/or invalid ActiveSpec = {}.", - GetName(), GetGUID().ToString(), uint32(m_specsCount), uint32(m_activeSpec)); - m_activeSpec = 0; + GetName(), GetGUID().ToString(), uint32(GetSpecsCount()), uint32(GetActiveSpec())); + SetActiveSpec(0); } UpdateDisplayPower(); @@ -18064,7 +18029,7 @@ void Player::_LoadGlyphAuras() { for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) { - if (uint32 glyph = GetGlyph(i)) + if (uint32 glyph = GetGlyph(GetActiveSpec(), i)) { if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph)) { @@ -18601,8 +18566,8 @@ void Player::_LoadQuestStatusRewarded(PreparedQueryResult result) SetTitle(titleEntry); } - if (quest->GetBonusTalents()) - m_questRewardTalentCount += quest->GetBonusTalents(); + if (uint32 talents = quest->GetBonusTalents()) + AddQuestRewardedTalentCount(talents); if (quest->CanIncreaseRewardedQuestCounters()) m_RewardedQuests.insert(quest_id); @@ -19362,8 +19327,8 @@ void Player::SaveToDB(CharacterDatabaseTransaction trans, bool create /* = false stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0)); //save, far from tavern/city //save, but in tavern/city - stmt->setUInt32(index++, m_resetTalentsCost); - stmt->setUInt32(index++, uint32(m_resetTalentsTime)); + stmt->setUInt32(index++, GetTalentResetCost()); + stmt->setUInt32(index++, uint32(GetTalentResetTime())); stmt->setUInt16(index++, (uint16)m_ExtraFlags); stmt->setUInt8(index++, m_petStable ? m_petStable->MaxStabledPets : 0); stmt->setUInt16(index++, (uint16)m_atLoginFlags); @@ -19392,8 +19357,8 @@ void Player::SaveToDB(CharacterDatabaseTransaction trans, bool create /* = false stmt->setUInt32(index++, GetSession()->GetLatency()); - stmt->setUInt8(index++, m_specsCount); - stmt->setUInt8(index++, m_activeSpec); + stmt->setUInt8(index++, GetSpecsCount()); + stmt->setUInt8(index++, GetActiveSpec()); ss.str(""); for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) @@ -19487,8 +19452,8 @@ void Player::SaveToDB(CharacterDatabaseTransaction trans, bool create /* = false stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0)); //save, far from tavern/city //save, but in tavern/city - stmt->setUInt32(index++, m_resetTalentsCost); - stmt->setUInt32(index++, uint32(m_resetTalentsTime)); + stmt->setUInt32(index++, GetTalentResetCost()); + stmt->setUInt32(index++, uint32(GetTalentResetTime())); stmt->setUInt16(index++, (uint16)m_ExtraFlags); stmt->setUInt8(index++, m_petStable ? m_petStable->MaxStabledPets : 0); stmt->setUInt16(index++, (uint16)m_atLoginFlags); @@ -19517,8 +19482,8 @@ void Player::SaveToDB(CharacterDatabaseTransaction trans, bool create /* = false stmt->setUInt32(index++, GetSession()->GetLatency()); - stmt->setUInt8(index++, m_specsCount); - stmt->setUInt8(index++, m_activeSpec); + stmt->setUInt8(index++, GetSpecsCount()); + stmt->setUInt8(index++, GetActiveSpec()); ss.str(""); for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) @@ -19626,7 +19591,7 @@ void Player::_SaveActions(CharacterDatabaseTransaction trans) case ACTIONBUTTON_NEW: stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACTION); stmt->setUInt32(0, GetGUID().GetCounter()); - stmt->setUInt8(1, m_activeSpec); + stmt->setUInt8(1, GetActiveSpec()); stmt->setUInt8(2, itr->first); stmt->setUInt32(3, itr->second.GetAction()); stmt->setUInt8(4, uint8(itr->second.GetType())); @@ -19641,7 +19606,7 @@ void Player::_SaveActions(CharacterDatabaseTransaction trans) stmt->setUInt8(1, uint8(itr->second.GetType())); stmt->setUInt32(2, GetGUID().GetCounter()); stmt->setUInt8(3, itr->first); - stmt->setUInt8(4, m_activeSpec); + stmt->setUInt8(4, GetActiveSpec()); trans->Append(stmt); itr->second.uState = ACTIONBUTTON_UNCHANGED; @@ -19651,7 +19616,7 @@ void Player::_SaveActions(CharacterDatabaseTransaction trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC); stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt8(1, itr->first); - stmt->setUInt8(2, m_activeSpec); + stmt->setUInt8(2, GetActiveSpec()); trans->Append(stmt); m_actionButtons.erase(itr++); @@ -21175,7 +21140,7 @@ template TC_GAME_API void Player::ApplySpellMod(uint32 spellId, SpellModOp op, f void Player::AddSpellMod(SpellModifier* mod, bool apply) { TC_LOG_DEBUG("spells", "Player::AddSpellMod: Player '{}' ({}), SpellID: {}", GetName(), GetGUID().ToString(), mod->spellId); - uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; + uint16 opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; flag96 modMask; for (uint8 i = 0; i < 3; ++i) @@ -21192,7 +21157,7 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) val += spellMod->value; } val += apply ? mod->value : -(mod->value); - WorldPacket data(Opcode, (1 + 1 + 4)); + WorldPacket data(opcode, (1 + 1 + 4)); data << uint8(eff + 32 * i); data << uint8(mod->op); data << int32(val); @@ -22769,7 +22734,7 @@ void Player::SendInitialPacketsAfterAddToMap() } if (HasAuraType(SPELL_AURA_MOD_STUN)) - SetMovement(MOVE_ROOT); + SetRooted(true); WorldPacket setCompoundState(SMSG_MULTIPLE_MOVES, 100); setCompoundState << uint32(0); // size placeholder @@ -24556,7 +24521,7 @@ void Player::InitGlyphsForLevel() void Player::SetGlyph(uint8 slot, uint32 glyph) { - m_Glyphs[m_activeSpec][slot] = glyph; + _talentMgr->SpecInfo[GetActiveSpec()].Glyphs[slot] = glyph; SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); } @@ -24925,16 +24890,16 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) uint32 Player::CalculateTalentsPoints() const { - uint32 base_talent = GetLevel() < 10 ? 0 : GetLevel()-9; + uint32 baseForLevel = GetLevel() < 10 ? 0 : GetLevel() - 9; if (GetClass() != CLASS_DEATH_KNIGHT || GetMapId() != 609) - return uint32(base_talent * sWorld->getRate(RATE_TALENT)); + return uint32(baseForLevel * sWorld->getRate(RATE_TALENT)); uint32 talentPointsForLevel = GetLevel() < 56 ? 0 : GetLevel() - 55; - talentPointsForLevel += m_questRewardTalentCount; + talentPointsForLevel += GetQuestRewardedTalentCount(); - if (talentPointsForLevel > base_talent) - talentPointsForLevel = base_talent; + if (talentPointsForLevel > baseForLevel) + talentPointsForLevel = baseForLevel; return uint32(talentPointsForLevel * sWorld->getRate(RATE_TALENT)); } @@ -25236,29 +25201,29 @@ void Player::CompletedAchievement(AchievementEntry const* entry) m_achievementMgr->CompletedAchievement(entry); } -void Player::LearnTalent(uint32 talentId, uint32 talentRank) +bool Player::LearnTalent(uint32 talentId, uint32 talentRank) { uint32 CurTalentPoints = GetFreeTalentPoints(); if (CurTalentPoints == 0) - return; + return false; if (talentRank >= MAX_TALENT_RANK) - return; + return false; TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId); if (!talentInfo) - return; + return false; TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TabID); if (!talentTabInfo) - return; + return false; // prevent learn talent for different class (cheating) if ((GetClassMask() & talentTabInfo->ClassMask) == 0) - return; + return false; // find current max talent rank (0~5) uint8 curtalent_maxrank = 0; // 0 = not learned any rank @@ -25273,11 +25238,11 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) // we already have same or higher talent rank learned if (curtalent_maxrank >= (talentRank + 1)) - return; + return false; // check if we have enough talent points if (CurTalentPoints < (talentRank - curtalent_maxrank + 1)) - return; + return false; // Check if it requires another talent if (talentInfo->PrereqTalent > 0) @@ -25292,7 +25257,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) hasEnoughRank = true; } if (!hasEnoughRank) - return; + return false; } } @@ -25301,8 +25266,8 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) uint32 tTab = talentInfo->TabID; if (talentInfo->TierID > 0) - for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) // Loop through all talents. - if (TalentEntry const* tmpTalent = sTalentStore.LookupEntry(i)) // the way talents are tracked + for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) // Loop through all talents. + if (TalentEntry const* tmpTalent = sTalentStore.LookupEntry(i)) // Someday, someone needs to revamp the way talents are tracked if (tmpTalent->TabID == tTab) for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++) if (tmpTalent->SpellRank[rank] != 0) @@ -25311,33 +25276,34 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) // not have required min points spent in talent tree if (spentPoints < (talentInfo->TierID * MAX_TALENT_RANK)) - return; + return false; // spell not set in talent.dbc uint32 spellid = talentInfo->SpellRank[talentRank]; if (spellid == 0) { TC_LOG_ERROR("entities.player", "Player::LearnTalent: Talent.dbc has no spellInfo for talent: {} (spell id = 0)", talentId); - return; + return false; } // already known if (HasSpell(spellid)) - return; + return false; // learn! (other talent ranks will unlearned at learning) LearnSpell(spellid, false); - AddTalent(spellid, m_activeSpec, true); + AddTalent(spellid, GetActiveSpec(), true); - TC_LOG_DEBUG("misc", "Player::LearnTalent: TalentID: {} Spell: {} Group: {}\n", talentId, spellid, uint32(m_activeSpec)); + TC_LOG_DEBUG("misc", "Player::LearnTalent: TalentID: {} Spell: {} Group: {}\n", talentId, spellid, uint32(GetActiveSpec())); // update free talent points SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1)); - #ifdef ELUNA if (Eluna* e = GetEluna()) e->OnLearnTalents(this, talentId, talentRank, spellid); #endif + + return true; } void Player::LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank) @@ -25550,16 +25516,16 @@ bool Player::CanSeeSpellClickOn(Creature const* c) const void Player::BuildPlayerTalentsInfoData(WorldPacket* data) { *data << uint32(GetFreeTalentPoints()); // unspentTalentPoints - *data << uint8(m_specsCount); // talent group count (0, 1 or 2) - *data << uint8(m_activeSpec); // talent group index (0 or 1) + *data << uint8(GetSpecsCount()); // talent group count (0, 1 or 2) + *data << uint8(GetActiveSpec()); // talent group index (0 or 1) - if (m_specsCount) + if (GetSpecsCount()) { - if (m_specsCount > MAX_TALENT_SPECS) - m_specsCount = MAX_TALENT_SPECS; + if (GetSpecsCount() > MAX_TALENT_SPECS) + SetSpecsCount(MAX_TALENT_SPECS); // loop through all specs (only 1 for now) - for (uint32 specIdx = 0; specIdx < m_specsCount; ++specIdx) + for (uint32 specIdx = 0; specIdx < GetSpecsCount(); ++specIdx) { uint8 talentIdCount = 0; size_t pos = data->wpos(); @@ -25609,7 +25575,7 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket* data) *data << uint8(MAX_GLYPH_SLOT_INDEX); // glyphs count for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) - *data << uint16(m_Glyphs[specIdx][i]); // GlyphProperties.dbc + *data << uint16(GetGlyph(specIdx, i)); // GlyphProperties.dbc } } } @@ -25935,15 +25901,11 @@ void Player::_LoadGlyphs(PreparedQueryResult result) Field* fields = result->Fetch(); uint8 spec = fields[0].GetUInt8(); - if (spec >= m_specsCount) + if (spec >= GetSpecsCount()) continue; - m_Glyphs[spec][0] = fields[1].GetUInt16(); - m_Glyphs[spec][1] = fields[2].GetUInt16(); - m_Glyphs[spec][2] = fields[3].GetUInt16(); - m_Glyphs[spec][3] = fields[4].GetUInt16(); - m_Glyphs[spec][4] = fields[5].GetUInt16(); - m_Glyphs[spec][5] = fields[6].GetUInt16(); + for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) + _talentMgr->SpecInfo[spec].Glyphs[i] = fields[i + 1].GetUInt16(); } while (result->NextRow()); } @@ -25954,7 +25916,7 @@ void Player::_SaveGlyphs(CharacterDatabaseTransaction trans) const stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); - for (uint8 spec = 0; spec < m_specsCount; ++spec) + for (uint8 spec = 0; spec < GetSpecsCount(); ++spec) { uint8 index = 0; @@ -25964,7 +25926,7 @@ void Player::_SaveGlyphs(CharacterDatabaseTransaction trans) const stmt->setUInt8(index++, spec); for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) - stmt->setUInt16(index++, uint16(m_Glyphs[spec][i])); + stmt->setUInt16(index++, uint16(GetGlyph(spec, i))); trans->Append(stmt); } @@ -25987,7 +25949,7 @@ void Player::_SaveTalents(CharacterDatabaseTransaction trans) for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) { - for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();) + for (PlayerTalentMap::iterator itr = GetTalentMap(i)->begin(); itr != GetTalentMap(i)->end();) { if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) { @@ -26010,7 +25972,7 @@ void Player::_SaveTalents(CharacterDatabaseTransaction trans) if (itr->second->state == PLAYERSPELL_REMOVED) { delete itr->second; - m_talents[i]->erase(itr++); + GetTalentMap(i)->erase(itr++); } else { @@ -26027,7 +25989,7 @@ void Player::UpdateSpecCount(uint8 count) if (curCount == count) return; - if (m_activeSpec >= count) + if (GetActiveSpec() >= count) ActivateSpec(0); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); @@ -26054,11 +26016,11 @@ void Player::UpdateSpecCount(uint8 count) _SaveActions(trans); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC); - stmt->setUInt8(0, m_activeSpec); + stmt->setUInt8(0, GetActiveSpec()); stmt->setUInt32(1, GetGUID().GetCounter()); trans->Append(stmt); - m_activeSpec = 0; + SetActiveSpec(0); } CharacterDatabase.CommitTransaction(trans); @@ -26153,7 +26115,7 @@ void Player::ActivateSpec(uint8 spec) // set glyphs for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot) // remove secondary glyph - if (uint32 oldglyph = m_Glyphs[m_activeSpec][slot]) + if (uint32 oldglyph = GetGlyph(GetActiveSpec(), slot)) if (GlyphPropertiesEntry const* old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph)) RemoveAurasDueToSpell(old_gp->SpellID); @@ -26183,7 +26145,7 @@ void Player::ActivateSpec(uint8 spec) if (talentInfo->SpellRank[rank] == 0) continue; // if the talent can be found in the newly activated PlayerTalentMap - if (HasTalent(talentInfo->SpellRank[rank], m_activeSpec)) + if (HasTalent(talentInfo->SpellRank[rank], GetActiveSpec())) { LearnSpell(talentInfo->SpellRank[rank], false); // add the talent to the PlayerSpellMap spentTalents += (rank + 1); // increment the spentTalents count @@ -26194,7 +26156,7 @@ void Player::ActivateSpec(uint8 spec) // set glyphs for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot) { - uint32 glyph = m_Glyphs[m_activeSpec][slot]; + uint32 glyph = GetGlyph(GetActiveSpec(), slot); // apply primary glyph if (glyph) @@ -26204,14 +26166,14 @@ void Player::ActivateSpec(uint8 spec) SetGlyph(slot, glyph); } - m_usedTalentCount = spentTalents; + SetUsedTalentCount(spentTalents); InitTalentForLevel(); // load them asynchronously { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC); stmt->setUInt32(0, GetGUID().GetCounter()); - stmt->setUInt8(1, m_activeSpec); + stmt->setUInt8(1, GetActiveSpec()); WorldSession* mySess = GetSession(); mySess->GetQueryProcessor().AddCallback(CharacterDatabase.AsyncQuery(stmt) @@ -26671,6 +26633,15 @@ bool Player::SetFeatherFall(bool apply, bool packetOnly /*= false*/) return true; } +void Player::SendMovementSetCollisionHeight(float height) +{ + WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); + data << GetPackGUID(); + data << uint32(GetMovementCounterAndInc()); + data << height; + SendDirectMessage(&data); +} + std::string Player::GetMapAreaAndZoneString() const { uint32 areaId = GetAreaId(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 8b8ebde8fe..6a0e544d31 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -83,7 +83,7 @@ enum LootType : uint8; typedef std::deque PlayerMails; -#define PLAYER_MAX_SKILLS 127 +#define PLAYER_MAX_SKILLS 128 #define PLAYER_MAX_DAILY_QUESTS 25 #define PLAYER_EXPLORED_ZONES_SIZE 128 @@ -306,14 +306,6 @@ struct EnchantDuration typedef std::list EnchantDurationList; typedef std::list ItemDurationList; -enum PlayerMovementType -{ - MOVE_ROOT = 1, - MOVE_UNROOT = 2, - MOVE_WATER_WALK = 3, - MOVE_LAND_WALK = 4 -}; - enum DrunkenState { DRUNKEN_SOBER = 0, @@ -426,7 +418,7 @@ enum MirrorTimerType { FATIGUE_TIMER = 0, BREATH_TIMER = 1, - FIRE_TIMER = 2 + FIRE_TIMER = 2 // feign death }; #define MAX_TIMERS 3 #define DISABLED_MIRROR_TIMER -1 @@ -610,22 +602,22 @@ typedef std::vector ItemPosCountVec; enum TransferAbortReason { - TRANSFER_ABORT_NONE = 0x00, - TRANSFER_ABORT_ERROR = 0x01, - TRANSFER_ABORT_MAX_PLAYERS = 0x02, // Transfer Aborted: instance is full - TRANSFER_ABORT_NOT_FOUND = 0x03, // Transfer Aborted: instance not found - TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x04, // You have entered too many instances recently. - TRANSFER_ABORT_ZONE_IN_COMBAT = 0x06, // Unable to zone in while an encounter is in progress. - TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x07, // You must have expansion installed to access this area. - TRANSFER_ABORT_DIFFICULTY = 0x08, // difficulty mode is not available for %s. - TRANSFER_ABORT_UNIQUE_MESSAGE = 0x09, // Until you've escaped TLK's grasp, you cannot leave this place! - TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x0A, // Additional instances cannot be launched, please try again later. - TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1 - TRANSFER_ABORT_NOT_FOUND1 = 0x0C, // 3.1 - TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1 - TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2 - TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm. - TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10 // Map can't be entered at this time. + TRANSFER_ABORT_NONE = 0x00, + TRANSFER_ABORT_ERROR = 0x01, + TRANSFER_ABORT_MAX_PLAYERS = 0x02, // Transfer Aborted: instance is full + TRANSFER_ABORT_NOT_FOUND = 0x03, // Transfer Aborted: instance not found + TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x04, // You have entered too many instances recently. + TRANSFER_ABORT_ZONE_IN_COMBAT = 0x06, // Unable to zone in while an encounter is in progress. + TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x07, // You must have expansion installed to access this area. + TRANSFER_ABORT_DIFFICULTY = 0x08, // difficulty mode is not available for %s. + TRANSFER_ABORT_UNIQUE_MESSAGE = 0x09, // Until you've escaped TLK's grasp, you cannot leave this place! + TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x0A, // Additional instances cannot be launched, please try again later. + TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1 + TRANSFER_ABORT_NOT_FOUND1 = 0x0C, // 3.1 + TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1 + TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2 + TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm. + TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10 // Map can't be entered at this time. }; enum InstanceResetWarningType @@ -877,6 +869,47 @@ struct ResurrectionData #define SPELL_DK_RAISE_ALLY 46619 +struct PlayerTalentInfo +{ + PlayerTalentInfo() : + UsedTalentCount(0), QuestRewardedTalentCount(0), + ResetTalentsCost(0), ResetTalentsTime(0), + ActiveSpec(0), SpecsCount(1) + { + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + { + SpecInfo[i].Talents = new PlayerTalentMap(); + memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32)); + } + } + + ~PlayerTalentInfo() + { + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + { + for (PlayerTalentMap::const_iterator itr = SpecInfo[i].Talents->begin(); itr != SpecInfo[i].Talents->end(); ++itr) + delete itr->second; + delete SpecInfo[i].Talents; + } + } + + struct TalentSpecInfo + { + PlayerTalentMap* Talents; + uint32 Glyphs[MAX_GLYPH_SLOT_INDEX]; + } SpecInfo[MAX_TALENT_SPECS]; + + uint32 UsedTalentCount; + uint32 QuestRewardedTalentCount; + uint32 ResetTalentsCost; + time_t ResetTalentsTime; + uint8 ActiveSpec; + uint8 SpecsCount; + +private: + PlayerTalentInfo(PlayerTalentInfo const&); +}; + class TC_GAME_API Player : public Unit, public GridObject { friend class WorldSession; @@ -1439,8 +1472,23 @@ class TC_GAME_API Player : public Unit, public GridObject void SetReputation(uint32 factionentry, uint32 value); uint32 GetReputation(uint32 factionentry) const; std::string const& GetGuildName() const; + + // Talents uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); } void SetFreeTalentPoints(uint32 points); + uint32 GetUsedTalentCount() const { return _talentMgr->UsedTalentCount; } + void SetUsedTalentCount(uint32 talents) { _talentMgr->UsedTalentCount = talents; } + uint32 GetQuestRewardedTalentCount() const { return _talentMgr->QuestRewardedTalentCount; } + void AddQuestRewardedTalentCount(uint32 points) { _talentMgr->QuestRewardedTalentCount += points; } + uint32 GetTalentResetCost() const { return _talentMgr->ResetTalentsCost; } + void SetTalentResetCost(uint32 cost) { _talentMgr->ResetTalentsCost = cost; } + time_t GetTalentResetTime() const { return _talentMgr->ResetTalentsTime; } + void SetTalentResetTime(time_t time_) { _talentMgr->ResetTalentsTime = time_; } + uint8 GetActiveSpec() const { return _talentMgr->ActiveSpec; } + void SetActiveSpec(uint8 spec){ _talentMgr->ActiveSpec = spec; } + uint8 GetSpecsCount() const { return _talentMgr->SpecsCount; } + void SetSpecsCount(uint8 count) { _talentMgr->SpecsCount = count; } + bool ResetTalents(bool involuntarily = false); uint32 ResetTalentsCost() const; void IncreaseResetTalentsCostAndCounters(uint32 lastResetTalentsCost); @@ -1448,29 +1496,27 @@ class TC_GAME_API Player : public Unit, public GridObject void BuildPlayerTalentsInfoData(WorldPacket* data); void BuildPetTalentsInfoData(WorldPacket* data); void SendTalentsInfoData(bool pet); - void LearnTalent(uint32 talentId, uint32 talentRank); + bool LearnTalent(uint32 talentId, uint32 talentRank); void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank); void SendTameFailure(uint8 result); - bool AddTalent(uint32 spellId, uint8 spec, bool learning); bool HasTalent(uint32 spell_id, uint8 spec) const; - uint32 CalculateTalentsPoints() const; // Dual Spec void UpdateSpecCount(uint8 count); - uint32 GetActiveSpec() const { return m_activeSpec; } - void SetActiveSpec(uint8 spec){ m_activeSpec = spec; } - uint8 GetSpecsCount() const { return m_specsCount; } - void SetSpecsCount(uint8 count) { m_specsCount = count; } void ActivateSpec(uint8 spec); void LoadActions(PreparedQueryResult result); void InitGlyphsForLevel(); void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); } - uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); } + uint32 GetGlyphSlot(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); } void SetGlyph(uint8 slot, uint32 glyph); - uint32 GetGlyph(uint8 slot) { return m_Glyphs[m_activeSpec][slot]; } + uint32 GetGlyph(uint8 spec, uint8 slot) const { return _talentMgr->SpecInfo[spec].Glyphs[slot]; } + + PlayerTalentMap const* GetTalentMap(uint8 spec) const { return _talentMgr->SpecInfo[spec].Talents; } + PlayerTalentMap* GetTalentMap(uint8 spec) { return _talentMgr->SpecInfo[spec].Talents; } + ActionButtonList const& GetActionButtons() const { return m_actionButtons; } uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); } void SetFreePrimaryProfessions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2, profs); } @@ -1719,8 +1765,6 @@ class TC_GAME_API Player : public Unit, public GridObject void StopMirrorTimers(); bool IsMirrorTimerActive(MirrorTimerType type) const; - void SetMovement(PlayerMovementType pType); - bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone) const; void JoinedChannel(Channel* c); @@ -2184,6 +2228,7 @@ class TC_GAME_API Player : public Unit, public GridObject bool SetWaterWalking(bool apply, bool packetOnly = false) override; bool SetFeatherFall(bool apply, bool packetOnly = false) override; bool SetHover(bool enable, bool packetOnly = false, bool updateAnimTier = true) override; + void SendMovementSetCollisionHeight(float height); bool CanFly() const override { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); } bool CanEnterWater() const override { return true; } @@ -2334,13 +2379,9 @@ class TC_GAME_API Player : public Unit, public GridObject PlayerMails m_mail; PlayerSpellMap m_spells; - PlayerTalentMap* m_talents[MAX_TALENT_SPECS]; uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use - uint8 m_activeSpec; - uint8 m_specsCount; - - uint32 m_Glyphs[MAX_TALENT_SPECS][MAX_GLYPH_SLOT_INDEX]; + PlayerTalentInfo* _talentMgr; ActionButtonList m_actionButtons; @@ -2403,10 +2444,6 @@ class TC_GAME_API Player : public Unit, public GridObject float m_rest_bonus; uint32 _restFlagMask; ////////////////////Rest System///////////////////// - uint32 m_resetTalentsCost; - time_t m_resetTalentsTime; - uint32 m_usedTalentCount; - uint32 m_questRewardTalentCount; // Social PlayerSocial* m_social; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 28c3bb16e1..dea17a6119 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -8220,11 +8220,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) if (charm->GetTypeId() == TYPEID_UNIT) charm->SetUnitFlag(UNIT_FLAG_STUNNED); - WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); - data << GetPackGUID(); - data << uint32(GameTime::GetGameTime()); // Packet counter - data << player->GetCollisionHeight(); - player->SendDirectMessage(&data); + player->SendMovementSetCollisionHeight(player->GetCollisionHeight()); } RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT); @@ -8239,13 +8235,7 @@ void Unit::Dismount() RemoveUnitFlag(UNIT_FLAG_MOUNT); if (Player* thisPlayer = ToPlayer()) - { - WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); - data << GetPackGUID(); - data << uint32(GameTime::GetGameTime()); // Packet counter - data << thisPlayer->GetCollisionHeight(); - thisPlayer->SendDirectMessage(&data); - } + thisPlayer->SendMovementSetCollisionHeight(thisPlayer->GetCollisionHeight()); WorldPacket data(SMSG_DISMOUNT, 8); data << GetPackGUID(); @@ -10836,7 +10826,7 @@ float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized) const case ITEM_SUBCLASS_WEAPON_SWORD: case ITEM_SUBCLASS_WEAPON_EXOTIC: case ITEM_SUBCLASS_WEAPON_EXOTIC2: - case ITEM_SUBCLASS_WEAPON_FIST: + case ITEM_SUBCLASS_WEAPON_FIST_WEAPON: return 2.4f; case ITEM_SUBCLASS_WEAPON_DAGGER: return 1.7f; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index a969ee0214..42e94a53e2 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1932,9 +1932,8 @@ class TC_GAME_API Unit : public WorldObject void SetStunned(bool apply); void SetRooted(bool apply); - uint32 m_rootTimes; - private: + uint32 m_rootTimes; uint32 m_state; // Even derived shouldn't modify uint32 m_lastManaUse; // msecs diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 9cf9079676..a469181095 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3138,7 +3138,7 @@ void ObjectMgr::LoadItemTemplates() if (itemTemplate.Class >= MAX_ITEM_CLASS) { TC_LOG_ERROR("sql.sql", "Item (Entry: {}) has wrong Class value ({})", entry, itemTemplate.Class); - itemTemplate.Class = ITEM_CLASS_MISC; + itemTemplate.Class = ITEM_CLASS_MISCELLANEOUS; } if (itemTemplate.SubClass >= MaxItemSubclassValues[itemTemplate.Class]) diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 18fed0e33c..d548d226bf 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2344,6 +2344,11 @@ bool Guild::ChangeMemberRank(CharacterDatabaseTransaction trans, ObjectGuid guid return false; } +bool Guild::IsMember(ObjectGuid guid) const +{ + return m_members.find(guid.GetCounter()) != m_members.end(); +} + uint64 Guild::GetMemberAvailableMoneyForRepairItems(ObjectGuid guid) const { Member const* member = GetMember(guid); diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 45e75a985e..c83b223340 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -717,6 +717,7 @@ class TC_GAME_API Guild bool AddMember(CharacterDatabaseTransaction trans, ObjectGuid guid, uint8 rankId = GUILD_RANK_NONE); bool DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bool isDisbanding = false, bool isKicked = false); bool ChangeMemberRank(CharacterDatabaseTransaction trans, ObjectGuid guid, uint8 newRank); + bool IsMember(ObjectGuid guid) const; uint64 GetMemberAvailableMoneyForRepairItems(ObjectGuid guid) const; // Bank diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index b1e16e02f3..fd6bd6da09 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -423,7 +423,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } } -//this function is called when client bids or buys out auction +// this function is called when client bids or buys out auction void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_PLACE_BID"); @@ -435,7 +435,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) recvData >> auctionId >> price; if (!auctionId || !price) - return; //check for cheaters + return; // check for cheaters Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) @@ -580,7 +580,6 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) uint32 auctionId; recvData >> auctioneer; recvData >> auctionId; - //TC_LOG_DEBUG("Cancel AUCTION AuctionID: {}", auctionId); Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) @@ -621,7 +620,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) } else { - TC_LOG_ERROR("network", "Auction id: {} has non-existed item (item guid : {})!!!", auction->Id, auction->itemGUIDLow); + TC_LOG_ERROR("network", "Auction id: {} got non existing item (item guid : {})!!!", auction->Id, auction->itemGUIDLow); SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR); return; } @@ -630,7 +629,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) { SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR); //this code isn't possible ... maybe there should be assert - TC_LOG_ERROR("entities.player.cheat", "CHEATER : {} tried to cancel auction (id: {}) of another player, or auction is NULL", player->GetGUID().ToString(), auctionId); + TC_LOG_ERROR("entities.player.cheat", "CHEATER : {} tried to cancel auction (id: {}) of another player or auction is NULL", player->GetGUID().ToString(), auctionId); return; } @@ -681,7 +680,7 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket& recvData) WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4)); Player* player = GetPlayer(); - data << (uint32) 0; //add 0 as count + data << uint32(0); //add 0 as count uint32 count = 0; uint32 totalcount = 0; while (outbiddedCount > 0) //add all data, which client requires @@ -700,7 +699,7 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket& recvData) auctionHouse->BuildListBidderItems(data, player, count, totalcount); data.put(0, count); // add count to placeholder data << totalcount; - data << (uint32)sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY); + data << uint32(sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY)); SendPacket(&data); } @@ -729,15 +728,15 @@ void WorldSession::HandleAuctionListOwnerItems(WorldPacket& recvData) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction()); WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4)); - data << (uint32) 0; // amount place holder + data << uint32(0); // amount place holder uint32 count = 0; uint32 totalcount = 0; auctionHouse->BuildListOwnerItems(data, _player, count, totalcount); data.put(0, count); - data << (uint32) totalcount; - data << (uint32) sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY); + data << uint32(totalcount); + data << uint32(sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY)); SendPacket(&data); } @@ -804,8 +803,8 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData) count, totalcount, (getAll != 0 && sWorld->getIntConfig(CONFIG_AUCTION_GETALL_DELAY) != 0)); data.put(0, count); - data << (uint32) totalcount; - data << (uint32) sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY); + data << uint32(totalcount); + data << uint32(sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY)); SendPacket(&data); } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 98c7d24973..dd0093226c 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -839,15 +839,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder) pCurrChar->SendInitialPacketsAfterAddToMap(); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ONLINE); - stmt->setUInt32(0, pCurrChar->GetGUID().GetCounter()); - CharacterDatabase.Execute(stmt); LoginDatabasePreparedStatement* loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_ONLINE); - loginStmt->setUInt32(0, GetAccountId()); - LoginDatabase.Execute(loginStmt); pCurrChar->SetInGameTime(GameTime::GetGameTimeMS()); @@ -870,7 +866,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder const& holder) // setting Ghost+speed if dead if (pCurrChar->m_deathState == DEAD) - pCurrChar->SetMovement(MOVE_WATER_WALK); + pCurrChar->SetWaterWalking(true); pCurrChar->ContinueTaxiFlight(); @@ -1346,7 +1342,7 @@ void WorldSession::HandleRemoveGlyph(WorldPacket& recvData) return; } - if (uint32 glyph = _player->GetGlyph(slot)) + if (uint32 glyph = _player->GetGlyph(_player->GetActiveSpec(), slot)) { if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph)) { diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index caee630fbe..ba108275c0 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -576,10 +576,9 @@ void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket & /*recvData*/) if (_player->InBattleground()) return; - /** error handling **/ + // error handling if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2) return; - /********************/ // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code) SendPartyResult(PARTY_OP_INVITE, "", ERR_PARTY_RESULT_OK); diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 0a022b8e93..ec546fcbf9 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -334,12 +334,9 @@ void WorldSession::HandleItemQuerySingleOpcode(WorldPackets::Query::QueryItemSin void WorldSession::HandleReadItem(WorldPacket& recvData) { - //TC_LOG_DEBUG("network", "WORLD: CMSG_READ_ITEM"); - uint8 bag, slot; recvData >> bag >> slot; - //TC_LOG_INFO("network", "STORAGE: Read bag = {}, slot = {}", bag, slot); Item* pItem = _player->GetItemByPos(bag, slot); if (pItem && pItem->GetTemplate()->PageText) @@ -349,7 +346,7 @@ void WorldSession::HandleReadItem(WorldPacket& recvData) InventoryResult msg = _player->CanUseItem(pItem); if (msg == EQUIP_ERR_OK) { - data.Initialize (SMSG_READ_ITEM_OK, 8); + data.Initialize(SMSG_READ_ITEM_OK, 8); TC_LOG_INFO("network", "STORAGE: Item page sent"); } else @@ -1141,15 +1138,15 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT"); - uint32 eslot; + uint32 slot; - recvData >> eslot; + recvData >> slot; // apply only to equipped item - if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, eslot)) + if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, slot)) return; - Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, eslot); + Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); if (!item) return; diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 382a6206a1..8064c73d62 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -41,7 +41,7 @@ #include #include -void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recvPacket*/) { TC_LOG_DEBUG("network", "WORLD: got MSG_MOVE_WORLDPORT_ACK."); HandleMoveWorldportAck(); @@ -210,21 +210,21 @@ void WorldSession::HandleMoveWorldportAck() player->ProcessDelayedOperations(); } -void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData) +void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) { TC_LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK"); ObjectGuid guid; - recvData >> guid.ReadAsPacked(); + recvPacket >> guid.ReadAsPacked(); if (!IsRightUnitBeingMoved(guid)) { - recvData.rfinish(); // prevent warnings spam + recvPacket.rfinish(); // prevent warnings spam return; } uint32 sequenceIndex, time; - recvData >> sequenceIndex >> time; + recvPacket >> sequenceIndex >> time; GameClient* client = GetGameClient(); Unit* mover = client->GetActivelyMovedUnit(); @@ -265,16 +265,16 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData) GetPlayer()->ProcessDelayedOperations(); } -void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) +void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket) { - uint16 opcode = recvData.GetOpcode(); + uint16 opcode = recvPacket.GetOpcode(); ObjectGuid guid; - recvData >> guid.ReadAsPacked(); + recvPacket >> guid.ReadAsPacked(); if (!IsRightUnitBeingMoved(guid)) { - recvData.rfinish(); // prevent warnings spam + recvPacket.rfinish(); // prevent warnings spam return; } @@ -285,7 +285,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plrMover && plrMover->IsBeingTeleported()) { - recvData.rfinish(); // prevent warnings spam + recvPacket.rfinish(); // prevent warnings spam return; } @@ -293,9 +293,9 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) MovementInfo movementInfo; movementInfo.guid = guid; - ReadMovementInfo(recvData, &movementInfo); + ReadMovementInfo(recvPacket, &movementInfo); - recvData.rfinish(); // prevent warnings spam + recvPacket.rfinish(); // prevent warnings spam if (!movementInfo.pos.IsPositionValid()) return; @@ -359,7 +359,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // Parachutes /* process position-change */ - WorldPacket data(opcode, recvData.size()); + WorldPacket data(opcode, recvPacket.size()); int64 movementTime = (int64) movementInfo.time + _timeSyncClockDelta; if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF) { @@ -891,9 +891,9 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData) if (!_player->IsAlive() || _player->IsInCombat()) return; - ObjectGuid summoner_guid; + ObjectGuid summonerGuid; bool agree; - recvData >> summoner_guid; + recvData >> summonerGuid; recvData >> agree; _player->SummonIfPossible(agree); diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 3f0027fb59..47640072db 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -321,7 +321,7 @@ void WorldSession::SendPetitionQueryOpcode(ObjectGuid petitionguid) void WorldSession::HandlePetitionRenameGuild(WorldPacket& recvData) { - TC_LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); // ok + TC_LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); ObjectGuid petitionGuid; std::string newName; diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index 178237924e..8911b36fdc 100644 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -27,11 +27,11 @@ void WorldSession::HandleLearnTalentOpcode(WorldPacket& recvData) { - uint32 talent_id, requested_rank; - recvData >> talent_id >> requested_rank; + uint32 talentId, requestedRank; + recvData >> talentId >> requestedRank; - _player->LearnTalent(talent_id, requested_rank); - _player->SendTalentsInfoData(false); + if (_player->LearnTalent(talentId, requestedRank)) + _player->SendTalentsInfoData(false); } void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket) @@ -50,7 +50,11 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket) { recvPacket >> talentId >> talentRank; - _player->LearnTalent(talentId, talentRank); + if (!_player->LearnTalent(talentId, talentRank)) + { + recvPacket.rfinish(); + break; + } } _player->SendTalentsInfoData(false); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 3eba144a4a..0423dc2eca 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -57,14 +57,14 @@ enum EncounterCreditType : uint8; enum EncounterFrameType { - ENCOUNTER_FRAME_ENGAGE = 0, - ENCOUNTER_FRAME_DISENGAGE = 1, - ENCOUNTER_FRAME_UPDATE_PRIORITY = 2, - ENCOUNTER_FRAME_ADD_TIMER = 3, - ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 4, - ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 5, - ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 6, - ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED = 7 + ENCOUNTER_FRAME_ENGAGE = 0, + ENCOUNTER_FRAME_DISENGAGE = 1, + ENCOUNTER_FRAME_UPDATE_PRIORITY = 2, + ENCOUNTER_FRAME_ADD_TIMER = 3, + ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 4, + ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 5, + ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 6, + ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED = 7 }; // EnumUtils: DESCRIBE THIS diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index ea55ba434d..a822566b10 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1171,7 +1171,9 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const if (target->GetTypeId() == TYPEID_PLAYER) { - PlayerSpellMap const& sp_list = target->ToPlayer()->GetSpellMap(); + Player* plrTarget = target->ToPlayer(); + + PlayerSpellMap const& sp_list = plrTarget->GetSpellMap(); for (auto itr = sp_list.begin(); itr != sp_list.end(); ++itr) { if (itr->second.state == PLAYERSPELL_REMOVED || itr->second.disabled) @@ -1191,7 +1193,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const // Also do it for Glyphs for (uint32 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) { - if (uint32 glyphId = target->ToPlayer()->GetGlyph(i)) + if (uint32 glyphId = plrTarget->GetGlyph(plrTarget->GetActiveSpec(), i)) { if (GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId)) { @@ -1206,19 +1208,21 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const } // Leader of the Pack - if (target->ToPlayer()->HasSpell(17007)) + if (plrTarget->HasSpell(17007)) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24932); if (spellInfo && spellInfo->Stances & (UI64LIT(1) << (GetMiscValue() - 1))) target->CastSpell(target, 24932, this); } + // Improved Barkskin - apply/remove armor bonus due to shapeshift - if (target->ToPlayer()->HasSpell(63410) || target->ToPlayer()->HasSpell(63411)) + if (plrTarget->HasSpell(63410) || plrTarget->HasSpell(63411)) { target->RemoveAurasDueToSpell(66530); if (GetMiscValue() == FORM_TRAVEL || GetMiscValue() == FORM_NONE) // "while in Travel Form or while not shapeshifted" target->CastSpell(target, 66530, true); } + // Heart of the Wild if (HotWSpellId) { // hacky, but the only way as spell family is not SPELLFAMILY_DRUID @@ -2581,17 +2585,17 @@ void AuraEffect::HandleAuraModSkill(AuraApplication const* aurApp, uint8 mode, b { if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SKILL))) return; - Unit* target = aurApp->GetTarget(); - if (target->GetTypeId() != TYPEID_PLAYER) + Player* target = aurApp->GetTarget()->ToPlayer(); + if (!target) return; uint32 prot = GetMiscValue(); int32 points = GetAmount(); - target->ToPlayer()->ModifySkillBonus(prot, ((apply) ? points: -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT); + target->ModifySkillBonus(prot, ((apply) ? points: -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT); if (prot == SKILL_DEFENSE) - target->ToPlayer()->UpdateDefenseBonusesMod(); + target->UpdateDefenseBonusesMod(); } /****************************/ diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 8d91704ea0..44daca909e 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3828,7 +3828,7 @@ void Spell::EffectApplyGlyph() } // remove old glyph - if (uint32 oldglyph = player->GetGlyph(m_glyphIndex)) + if (uint32 oldglyph = player->GetGlyph(player->GetActiveSpec(), m_glyphIndex)) { if (GlyphPropertiesEntry const* old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph)) { diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 053b19cc0b..c6a53d5e09 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -47,11 +47,11 @@ struct Realm; // ServerMessages.dbc enum ServerMessageType { - SERVER_MSG_SHUTDOWN_TIME = 1, - SERVER_MSG_RESTART_TIME = 2, - SERVER_MSG_STRING = 3, - SERVER_MSG_SHUTDOWN_CANCELLED = 4, - SERVER_MSG_RESTART_CANCELLED = 5 + SERVER_MSG_SHUTDOWN_TIME = 1, + SERVER_MSG_RESTART_TIME = 2, + SERVER_MSG_STRING = 3, + SERVER_MSG_SHUTDOWN_CANCELLED = 4, + SERVER_MSG_RESTART_CANCELLED = 5 }; enum ShutdownMask : uint32 diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp index ca0066457b..a112169d90 100644 --- a/src/server/scripts/Commands/cs_cheat.cpp +++ b/src/server/scripts/Commands/cs_cheat.cpp @@ -165,13 +165,13 @@ class cheat_commandscript : public CommandScript if (enable) { handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK); - handler->GetSession()->GetPlayer()->SetMovement(MOVE_WATER_WALK); // ON + handler->GetSession()->GetPlayer()->SetWaterWalking(true); // ON handler->SendSysMessage("Waterwalking is ON. You can walk on water."); } else { handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK); - handler->GetSession()->GetPlayer()->SetMovement(MOVE_LAND_WALK); // OFF + handler->GetSession()->GetPlayer()->SetWaterWalking(false); // OFF handler->SendSysMessage("Waterwalking is OFF. You can't walk on water."); } diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 6b64aa8b12..bd78a177d5 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -302,7 +302,11 @@ class wp_commandscript : public CommandScript if (show == "add") { - if (Optional id = Trinity::StringTo(arg_id)) + Optional id; + if (arg_id) + id = Trinity::StringTo(arg_id); + + if (id) { stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID); stmt->setUInt32(0, *id); @@ -344,9 +348,8 @@ class wp_commandscript : public CommandScript uint32 id = Trinity::StringTo(arg_id).value_or(0); - uint32 a2, a3, a4, a5, a6; + uint32 a2, a3, a4, a5, a6, a7; float a8, a9, a10, a11; - char const* a7; stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID); stmt->setUInt32(0, id); @@ -368,13 +371,13 @@ class wp_commandscript : public CommandScript a4 = fields[2].GetUInt32(); a5 = fields[3].GetUInt32(); a6 = fields[4].GetUInt32(); - a7 = fields[5].GetCString(); + a7 = fields[5].GetUInt32(); a8 = fields[6].GetFloat(); a9 = fields[7].GetFloat(); a10 = fields[8].GetFloat(); a11 = fields[9].GetFloat(); - handler->PSendSysMessage("|cffff33ffid:|r|cff00ffff %u|r|cff00ff00, guid: |r|cff00ffff%u|r|cff00ff00, delay: |r|cff00ffff%u|r|cff00ff00, command: |r|cff00ffff%u|r|cff00ff00, datalong: |r|cff00ffff%u|r|cff00ff00, datalong2: |r|cff00ffff%u|r|cff00ff00, datatext: |r|cff00ffff%s|r|cff00ff00, posx: |r|cff00ffff%f|r|cff00ff00, posy: |r|cff00ffff%f|r|cff00ff00, posz: |r|cff00ffff%f|r|cff00ff00, orientation: |r|cff00ffff%f|r", id, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + handler->PSendSysMessage("|cffff33ffid:|r|cff00ffff %u|r|cff00ff00, guid: |r|cff00ffff%u|r|cff00ff00, delay: |r|cff00ffff%u|r|cff00ff00, command: |r|cff00ffff%u|r|cff00ff00, datalong: |r|cff00ffff%u|r|cff00ff00, datalong2: |r|cff00ffff%u|r|cff00ff00, dataint: |r|cff00ffff%u|r|cff00ff00, posx: |r|cff00ffff%f|r|cff00ff00, posy: |r|cff00ffff%f|r|cff00ff00, posz: |r|cff00ffff%f|r|cff00ff00, orientation: |r|cff00ffff%f|r", id, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); } while (result->NextRow()); } diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 7c2001f8f6..2ae3043b79 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -3224,14 +3224,14 @@ enum ChatLinkColors : uint32 // Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.PetFoodMask enum PetDiet { - PET_DIET_MEAT = 1, - PET_DIET_FISH = 2, - PET_DIET_CHEESE = 3, - PET_DIET_BREAD = 4, - PET_DIET_FUNGAS = 5, - PET_DIET_FRUIT = 6, - PET_DIET_RAW_MEAT = 7, - PET_DIET_RAW_FISH = 8 + PET_DIET_MEAT = 1, + PET_DIET_FISH = 2, + PET_DIET_CHEESE = 3, + PET_DIET_BREAD = 4, + PET_DIET_FUNGAS = 5, + PET_DIET_FRUIT = 6, + PET_DIET_RAW_MEAT = 7, + PET_DIET_RAW_FISH = 8 }; #define MAX_PET_DIET 9 diff --git a/tests/DummyData.cpp b/tests/DummyData.cpp index 09a2faa0f9..5e4fd18083 100644 --- a/tests/DummyData.cpp +++ b/tests/DummyData.cpp @@ -29,7 +29,7 @@ ItemTemplate& t = sObjectMgr->_itemTemplateStore[itemId]; t = {}; t.ItemId = itemId; - t.Class = ItemClass::ITEM_CLASS_MISC; + t.Class = ItemClass::ITEM_CLASS_MISCELLANEOUS; t.SoundOverrideSubclass = -1; t.Name1 = name; t.Quality = ItemQualities::ITEM_QUALITY_ARTIFACT;