diff options
-rw-r--r-- | sql/base/characters_database.sql | 3 | ||||
-rw-r--r-- | sql/updates/characters/master/2018_12_02_00_characters.sql | 135 | ||||
-rw-r--r-- | sql/updates/world/master/2018_12_02_00_world.sql | 8 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 9 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 141 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SystemPackets.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SystemPackets.h | 4 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 4 |
10 files changed, 240 insertions, 72 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 17bf37bc811..248f489fc5a 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -3570,7 +3570,8 @@ INSERT INTO `updates` VALUES ('2018_07_28_00_characters.sql','31F66AE7831251A8915625EC7F10FA138AB8B654','RELEASED','2018-07-28 18:30:19',0), ('2018_07_31_00_characters.sql','7DA8D4A4534520B23E6F5BBD5B8EE205B799C798','RELEASED','2018-07-31 20:54:39',0), ('2018_09_18_00_characters.sql','7FE9641C93ED762597C08F1E9B6649C9EC2F0E47','RELEASED','2018-09-18 23:34:29',0), -('2018_10_10_00_characters.sql','C80B936AAD94C58A0F33382CED08CFB4E0B6AC34','RELEASED','2018-10-10 22:05:28',0); +('2018_10_10_00_characters.sql','C80B936AAD94C58A0F33382CED08CFB4E0B6AC34','RELEASED','2018-10-10 22:05:28',0), +('2018_12_02_00_characters.sql','DBBA0C06985CE8AC4E6E7E94BD6B2673E9ADFAE2','RELEASED','2018-12-02 17:32:31',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/master/2018_12_02_00_characters.sql b/sql/updates/characters/master/2018_12_02_00_characters.sql new file mode 100644 index 00000000000..6c95b00778d --- /dev/null +++ b/sql/updates/characters/master/2018_12_02_00_characters.sql @@ -0,0 +1,135 @@ +-- +-- Table structure for table `profession_skill_migration_data` +-- +DROP TABLE IF EXISTS `profession_skill_migration_data`; +CREATE TABLE `profession_skill_migration_data` ( + `SkillID` int(10) unsigned, + `ParentSkillLineID` int(10) unsigned, + `MaxValue` int(10) unsigned, + `NewMaxValue` int(10) unsigned, + `SpellID_A` int(10) unsigned, + `SpellID_H` int(10) unsigned, + PRIMARY KEY (`SkillID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- +-- Dumping data for table `profession_skill_migration_data` +-- +INSERT INTO `profession_skill_migration_data` VALUES +(2437,164,900,150,264448,265803), +(2454,164,800,100,264446,264446), +(2472,164,700,100,264444,264444), +(2473,164,600,75,264442,264442), +(2474,164,525,75,264440,264440), +(2475,164,450,75,264438,264438), +(2476,164,375,75,264436,264436), +(2477,164,300,300,264434,264434), +(2478,171,900,150,264255,265787), +(2479,171,800,100,264250,264250), +(2480,171,700,100,264247,264247), +(2481,171,600,75,264245,264245), +(2482,171,525,75,264243,264243), +(2483,171,450,75,264220,264220), +(2484,171,375,75,264213,264213), +(2485,171,300,300,264211,264211), +(2486,333,900,150,264473,265805), +(2487,333,800,100,264471,264471), +(2488,333,700,100,264469,264469), +(2489,333,600,75,264467,264467), +(2491,333,525,75,264464,264464), +(2492,333,450,75,264462,264462), +(2493,333,375,75,264460,264460), +(2494,333,300,300,264455,264455), +(2499,202,900,150,264492,265807), +(2500,202,800,100,264490,264490), +(2501,202,700,100,264487,264487), +(2502,202,600,75,264485,264485), +(2503,202,525,75,264483,264483), +(2504,202,450,75,264481,264481), +(2505,202,375,75,264479,264479), +(2506,202,300,300,264475,264475), +(2507,773,900,150,264508,265809), +(2508,773,800,100,264506,264506), +(2509,773,700,100,264504,264504), +(2510,773,600,75,264502,264502), +(2511,773,525,75,264500,264500), +(2512,773,450,75,264498,264498), +(2513,773,375,75,264496,264496), +(2514,773,300,300,264494,264494), +(2517,755,900,150,264548,265811), +(2518,755,800,100,264546,264546), +(2519,755,700,100,264544,264544), +(2520,755,600,75,264542,264542), +(2521,755,525,75,264539,264539), +(2522,755,450,75,264537,264537), +(2523,755,375,75,264534,264534), +(2524,755,300,300,264532,264532), +(2525,165,900,150,264592,265813), +(2526,165,800,100,264590,264590), +(2527,165,700,100,264588,264588), +(2528,165,600,75,264585,264585), +(2529,165,525,75,264583,264583), +(2530,165,450,75,264581,264581), +(2531,165,375,75,264579,264579), +(2532,165,300,300,264577,264577), +(2533,197,900,150,264630,265815), +(2534,197,800,100,264628,264628), +(2535,197,700,100,264626,264626), +(2536,197,600,75,264624,264624), +(2537,197,525,75,264622,264622), +(2538,197,450,75,264620,264620), +(2539,197,375,75,264618,264618), +(2540,197,300,300,264616,264616), +(2541,185,825,150,264646,265817), +(2542,185,750,100,264644,264644), +(2543,185,700,100,264642,264642), +(2544,185,600,75,264640,264640), +(2545,185,525,75,264638,264638), +(2546,185,450,75,264636,264636), +(2547,185,375,75,264634,264634), +(2548,185,300,300,264632,264632), +(2549,182,900,150,265831,265835), +(2550,182,800,100,265834,265834), +(2551,182,700,100,265829,265829), +(2552,182,600,75,265827,265827), +(2553,182,525,75,265825,265825), +(2554,182,450,75,265823,265823), +(2555,182,375,75,265821,265821), +(2556,182,300,300,265819,265819), +(2557,393,900,150,265869,265871), +(2558,393,800,100,265867,265867), +(2559,393,700,100,265865,265865), +(2560,393,600,75,265863,265863), +(2561,393,525,75,265861,265861), +(2562,393,450,75,265859,265859), +(2563,393,375,75,265857,265857), +(2564,393,300,300,265855,265855), +(2565,186,900,150,265851,265853), +(2566,186,800,100,265849,265849), +(2567,186,700,100,265847,265847), +(2568,186,600,75,265845,265845), +(2569,186,525,75,265843,265843), +(2570,186,450,75,265841,265841), +(2571,186,375,75,265839,265839), +(2572,186,300,300,265837,265837), +(2585,356,825,150,271675,271677), +(2586,356,750,100,271672,271672), +(2587,356,700,100,271664,271664), +(2588,356,600,75,271662,271662), +(2589,356,525,75,271660,271660), +(2590,356,450,75,271658,271658), +(2591,356,375,75,271656,271656), +(2592,356,300,300,271616,271616); + +INSERT IGNORE INTO `character_spell` +SELECT cs.`guid`, IF(c.`race` IN (1,3,4,7,11,22,25,29,30,34), psmd.`SpellID_A`, psmd.`SpellID_H`), 1, 0 +FROM `profession_skill_migration_data` psmd +INNER JOIN `character_skills` cs ON psmd.`ParentSkillLineID` = cs.`skill` AND psmd.`MaxValue` <= cs.`max` +INNER JOIN `characters` c ON cs.`guid` = c.`guid`; + +INSERT IGNORE INTO `character_skills` +SELECT cs.`guid`, psmd.`SkillID`, CASE WHEN psmd.`MaxValue` < cs.`value` THEN psmd.`NewMaxValue` WHEN psmd.`MaxValue` - cs.`value` < psmd.`NewMaxValue` THEN psmd.`NewMaxValue` + cs.`value` - psmd.`MaxValue` ELSE 1 END, psmd.`NewMaxValue` +FROM `profession_skill_migration_data` psmd +INNER JOIN `character_skills` cs ON psmd.`ParentSkillLineID` = cs.`skill` AND psmd.`MaxValue` <= cs.`max`; + +DROP TABLE IF EXISTS `profession_skill_migration_data`; diff --git a/sql/updates/world/master/2018_12_02_00_world.sql b/sql/updates/world/master/2018_12_02_00_world.sql new file mode 100644 index 00000000000..9228a56d2b8 --- /dev/null +++ b/sql/updates/world/master/2018_12_02_00_world.sql @@ -0,0 +1,8 @@ +DELETE FROM `skill_tiers` WHERE `ID` IN (333,335,336,338); +INSERT INTO `skill_tiers` (`ID`,`Value1`,`Value2`,`Value3`,`Value4`,`Value5`,`Value6`,`Value7`,`Value8`,`Value9`,`Value10`,`Value11`,`Value12`,`Value13`,`Value14`,`Value15`,`Value16`) VALUES +(333,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(335,75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(336,300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(338,150,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); + +UPDATE `skill_tiers` SET `Value10`=800,`Value11`=950 WHERE `ID`=224; diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 03e2e872c65..a2639077eb4 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -392,6 +392,7 @@ namespace std::unordered_map<uint32, std::vector<RewardPackXCurrencyTypeEntry const*>> _rewardPackCurrencyTypes; std::unordered_map<uint32, std::vector<RewardPackXItemEntry const*>> _rewardPackItems; RulesetItemUpgradeContainer _rulesetItemUpgrade; + std::unordered_map<uint32, std::vector<SkillLineAbilityEntry const*>> _skillLineAbilitiesBySkillupSkill; SkillRaceClassInfoContainer _skillRaceClassInfoBySkill; SpecializationSpellsContainer _specializationSpellsBySpec; std::unordered_set<uint8> _spellFamilyNames; @@ -1023,6 +1024,9 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale) for (RulesetItemUpgradeEntry const* rulesetItemUpgrade : sRulesetItemUpgradeStore) _rulesetItemUpgrade[rulesetItemUpgrade->ItemID] = rulesetItemUpgrade->ItemUpgradeID; + for (SkillLineAbilityEntry const* skillLineAbility : sSkillLineAbilityStore) + _skillLineAbilitiesBySkillupSkill[skillLineAbility->SkillupSkillLineID ? skillLineAbility->SkillupSkillLineID : skillLineAbility->SkillLine].push_back(skillLineAbility); + for (SkillRaceClassInfoEntry const* entry : sSkillRaceClassInfoStore) if (sSkillLineStore.LookupEntry(entry->SkillID)) _skillRaceClassInfoBySkill.insert(SkillRaceClassInfoContainer::value_type(entry->SkillID, entry)); @@ -2278,6 +2282,11 @@ uint32 DB2Manager::GetRulesetItemUpgrade(uint32 itemId) const return 0; } +std::vector<SkillLineAbilityEntry const*> const* DB2Manager::GetSkillLineAbilitiesBySkill(uint32 skillId) const +{ + return Trinity::Containers::MapGetValuePtr(_skillLineAbilitiesBySkillupSkill, skillId); +} + SkillRaceClassInfoEntry const* DB2Manager::GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_) { auto bounds = _skillRaceClassInfoBySkill.equal_range(skill); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 06f8635c908..389a19e952e 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -323,6 +323,7 @@ public: std::vector<RewardPackXCurrencyTypeEntry const*> const* GetRewardPackCurrencyTypesByRewardID(uint32 rewardPackID) const; std::vector<RewardPackXItemEntry const*> const* GetRewardPackItemsByRewardID(uint32 rewardPackID) const; uint32 GetRulesetItemUpgrade(uint32 itemId) const; + std::vector<SkillLineAbilityEntry const*> const* GetSkillLineAbilitiesBySkill(uint32 skillId) const; SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_); std::vector<SpecializationSpellsEntry const*> const* GetSpecializationSpells(uint32 specId) const; static bool IsValidSpellFamiliyName(SpellFamilyNames family); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 51db53c9c61..b3e8bd33097 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5172,43 +5172,6 @@ void Player::SetRegularAttackTime() } } -//skill+step, checking for max value -bool Player::UpdateSkill(uint32 skill_id, uint32 step) -{ - if (!skill_id) - return false; - - SkillStatusMap::iterator itr = mSkillStatus.find(skill_id); - if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) - return false; - - uint16 field = itr->second.pos / 2; - uint8 offset = itr->second.pos & 1; // itr->second.pos % 2 - - uint16 value = GetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_RANK_OFFSET + field, offset); - uint16 max = GetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_MAX_RANK_OFFSET + field, offset); - - if (!max || !value || value >= max) - return false; - - if (value < max) - { - uint32 new_value = value + step; - if (new_value > max) - new_value = max; - - SetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_RANK_OFFSET + field, offset, new_value); - if (itr->second.uState != SKILL_NEW) - itr->second.uState = SKILL_CHANGED; - - UpdateSkillEnchantments(skill_id, value, new_value); - UpdateCriteria(CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id); - return true; - } - - return false; -} - inline int SkillGainChance(uint32 SkillValue, uint32 GrayLevel, uint32 GreenLevel, uint32 YellowLevel) { if (SkillValue >= GrayLevel) @@ -5229,21 +5192,21 @@ bool Player::UpdateCraftSkill(uint32 spellid) for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) { - if (_spell_idx->second->SkillLine) + if (_spell_idx->second->SkillupSkillLineID) { - uint32 SkillValue = GetPureSkillValue(_spell_idx->second->SkillLine); + uint32 SkillValue = GetPureSkillValue(_spell_idx->second->SkillupSkillLineID); // Alchemy Discoveries here SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spellid); if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY) { - if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->SkillLine, spellid, this)) + if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->SkillupSkillLineID, spellid, this)) LearnSpell(discoveredSpell, false); } uint32 craft_skill_gain = _spell_idx->second->NumSkillUps * sWorld->getIntConfig(CONFIG_SKILL_GAIN_CRAFTING); - return UpdateSkillPro(_spell_idx->second->SkillLine, SkillGainChance(SkillValue, + return UpdateSkillPro(_spell_idx->second->SkillupSkillLineID, SkillGainChance(SkillValue, _spell_idx->second->TrivialSkillLineRankHigh, (_spell_idx->second->TrivialSkillLineRankHigh + _spell_idx->second->TrivialSkillLineRankLow)/2, _spell_idx->second->TrivialSkillLineRankLow), @@ -5321,8 +5284,7 @@ bool Player::UpdateSkillPro(uint16 skillId, int32 chance, uint32 step) // levels sync. with spell requirement for skill levels to learn // bonus abilities in sSkillLineAbilityStore // Used only to avoid scan DBC at each skill grow - static uint32 bonusSkillLevels[] = { 75, 150, 225, 300, 375, 450, 525 }; - static const size_t bonusSkillLevelsSize = sizeof(bonusSkillLevels) / sizeof(uint32); + uint32 const bonusSkillLevels[] = { 75, 150, 225, 300, 375, 450, 525, 600, 700, 850 }; TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro: Player '%s' (%s), SkillID: %u, Chance: %3.1f%%)", GetName().c_str(), GetGUID().ToString().c_str(), skillId, chance / 10.0f); @@ -5364,9 +5326,8 @@ bool Player::UpdateSkillPro(uint16 skillId, int32 chance, uint32 step) if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; - for (size_t i = 0; i < bonusSkillLevelsSize; ++i) + for (uint32 bsl : bonusSkillLevels) { - uint32 bsl = bonusSkillLevels[i]; if (value < bsl && new_value >= bsl) { LearnSkillRewardedSpells(skillId, new_value); @@ -5525,10 +5486,13 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) mSkillStatus.erase(itr); // remove all spells that related to this skill - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) - if (SkillLineAbilityEntry const* pAbility = sSkillLineAbilityStore.LookupEntry(j)) - if (pAbility->SkillLine == id) - RemoveSpell(sSpellMgr->GetFirstSpellInChain(pAbility->Spell)); + if (std::vector<SkillLineAbilityEntry const*> const* skillLineAbilities = sDB2Manager.GetSkillLineAbilitiesBySkill(id)) + for (SkillLineAbilityEntry const* skillLineAbility : *skillLineAbilities) + RemoveSpell(sSpellMgr->GetFirstSpellInChain(skillLineAbility->Spell)); + + for (SkillLineEntry const* childSkillLine : sSkillLineStore) + if (childSkillLine->ParentSkillLineID == id) + SetSkill(childSkillLine->ID, 0, 0, 0); // Clear profession lines if (GetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE) == id) @@ -5555,15 +5519,27 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) return; } - SetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_ID_OFFSET + field, offset, id); - if (skillEntry->CategoryID == SKILL_CATEGORY_PROFESSION) + if (skillEntry->ParentSkillLineID && skillEntry->ParentTierIndex > 0) { - if (!GetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE)) - SetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE, id); - else if (!GetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE + 1)) - SetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE + 1, id); + if (SkillRaceClassInfoEntry const* rcEntry = sDB2Manager.GetSkillRaceClassInfo(skillEntry->ParentSkillLineID, getRace(), getClass())) + { + if (SkillTiersEntry const* tier = sObjectMgr->GetSkillTier(rcEntry->SkillTierID)) + { + uint16 skillval = GetPureSkillValue(skillEntry->ParentSkillLineID); + SetSkill(skillEntry->ParentSkillLineID, skillEntry->ParentTierIndex, std::max<uint16>(skillval, 1), tier->Value[skillEntry->ParentTierIndex - 1]); + } + } + + if (skillEntry->CategoryID == SKILL_CATEGORY_PROFESSION) + { + int32 freeProfessionSlot = FindProfessionSlotFor(id); + if (freeProfessionSlot != -1) + SetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE + freeProfessionSlot, id); + } } + SetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_ID_OFFSET + field, offset, id); + SetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_STEP_OFFSET + field, offset, step); SetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_RANK_OFFSET + field, offset, newVal); SetUInt16Value(ACTIVE_PLAYER_FIELD_SKILL_LINEID + SKILL_MAX_RANK_OFFSET + field, offset, maxVal); @@ -24119,12 +24095,12 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue) { uint64 raceMask = getRaceMask(); uint32 classMask = getClassMask(); - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) - { - SkillLineAbilityEntry const* ability = sSkillLineAbilityStore.LookupEntry(j); - if (!ability || ability->SkillLine != int32(skillId)) - continue; + std::vector<SkillLineAbilityEntry const*> const* skillLineAbilities = sDB2Manager.GetSkillLineAbilitiesBySkill(skillId); + if (!skillLineAbilities) + return; + for (SkillLineAbilityEntry const* ability : *skillLineAbilities) + { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(ability->Spell); if (!spellInfo) continue; @@ -24159,6 +24135,42 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue) } } +int32 Player::FindProfessionSlotFor(uint32 skillId) const +{ + SkillLineEntry const* skillEntry = sSkillLineStore.LookupEntry(skillId); + if (!skillEntry) + return -1; + + uint32 constexpr professionSlots = 2; + uint32 const* professionsBegin = &m_uint32Values[ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE]; + uint32 const* professionsEnd = professionsBegin + professionSlots; + + // both free, return first slot + if (std::none_of(professionsBegin, professionsEnd, [](uint32 slot) { return slot != 0; })) + return 0; + + // when any slot is filled we need to check both - one of them might be earlier step of the same profession + auto sameProfessionSlot = std::find_if(professionsBegin, professionsEnd, [&](uint32 slot) + { + if (SkillLineEntry const* slotProfession = sSkillLineStore.LookupEntry(slot)) + if (slotProfession->ParentSkillLineID == skillEntry->ParentSkillLineID) + return true; + return false; + }); + + if (sameProfessionSlot != professionsEnd) + { + if (sSkillLineStore.AssertEntry(*sameProfessionSlot)->ParentTierIndex < skillEntry->ParentTierIndex) + return std::distance(professionsBegin, sameProfessionSlot); + + return -1; + } + + // if there is no same profession, find any free slot + auto freeSlot = std::find(professionsBegin, professionsEnd, 0u); + return freeSlot != professionsEnd ? std::distance(professionsBegin, freeSlot) : -1; +} + void Player::SendAurasForTarget(Unit* target) const { if (!target || target->GetVisibleAuras().empty()) // speedup things @@ -25792,7 +25804,6 @@ void Player::_LoadSkills(PreparedQueryResult result) // SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", GUID_LOPART(m_guid)); uint32 count = 0; - uint8 professionCount = 0; std::unordered_map<uint32, uint32> loadedSkillValues; if (result) { @@ -25859,8 +25870,12 @@ void Player::_LoadSkills(PreparedQueryResult result) { step = max / 75; - if (professionCount < 2) - SetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE + professionCount++, skill); + if (skillLine->ParentSkillLineID && skillLine->ParentTierIndex) + { + int32 professionSlot = FindProfessionSlotFor(skill); + if (professionSlot != -1) + SetUInt32Value(ACTIVE_PLAYER_FIELD_PROFESSION_SKILL_LINE + professionSlot, skill); + } } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index e3092f0279c..d53dbf33db0 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1786,9 +1786,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> static Difficulty CheckLoadedLegacyRaidDifficultyID(Difficulty difficulty); void SendRaidGroupOnlyMessage(RaidGroupReason reason, int32 delay) const; - bool UpdateSkill(uint32 skill_id, uint32 step); bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step); - bool UpdateCraftSkill(uint32 spellid); bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1); bool UpdateFishingSkill(); @@ -1928,6 +1926,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint16 GetSkillStep(uint16 skill) const; // 0...6 bool HasSkill(uint32 skill) const; void LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue); + int32 FindProfessionSlotFor(uint32 skillId) const; WorldLocation& GetTeleportDest() { return m_teleport_dest; } bool IsBeingTeleported() const { return mSemaphoreTeleport_Near || mSemaphoreTeleport_Far; } diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp index 71dbce750e7..853e35fce5c 100644 --- a/src/server/game/Server/Packets/SystemPackets.cpp +++ b/src/server/game/Server/Packets/SystemPackets.cpp @@ -112,8 +112,8 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write() { _worldPacket.WriteBit(VoiceChatManagerSettings.Enabled); - _worldPacket << VoiceChatManagerSettings.Unused_801_1; - _worldPacket << VoiceChatManagerSettings.Unused_801_2; + _worldPacket << VoiceChatManagerSettings.BnetAccountGuid; + _worldPacket << VoiceChatManagerSettings.GuildGuid; } if (EuropaTicketSystemStatus) diff --git a/src/server/game/Server/Packets/SystemPackets.h b/src/server/game/Server/Packets/SystemPackets.h index 8fe1f515590..4d0812e7e67 100644 --- a/src/server/game/Server/Packets/SystemPackets.h +++ b/src/server/game/Server/Packets/SystemPackets.h @@ -83,8 +83,8 @@ namespace WorldPackets struct VoiceChatProxySettings { bool Enabled = false; - ObjectGuid Unused_801_1; - ObjectGuid Unused_801_2; + ObjectGuid BnetAccountGuid; + ObjectGuid GuildGuid; }; FeatureSystemStatus() : ServerPacket(SMSG_FEATURE_SYSTEM_STATUS, 48) { } diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 6cfb2764f08..4a1061b6425 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2366,7 +2366,7 @@ void Spell::EffectLearnSkill(SpellEffIndex /*effIndex*/) if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; - if (damage < 0) + if (damage < 1) return; uint32 skillid = effectInfo->MiscValue; @@ -2379,7 +2379,7 @@ void Spell::EffectLearnSkill(SpellEffIndex /*effIndex*/) return; uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid); - unitTarget->ToPlayer()->SetSkill(skillid, effectInfo->CalcValue(), std::max<uint16>(skillval, 1), tier->Value[damage - 1]); + unitTarget->ToPlayer()->SetSkill(skillid, damage, std::max<uint16>(skillval, 1), tier->Value[damage - 1]); } void Spell::EffectPlayMovie(SpellEffIndex /*effIndex*/) |