mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Players: Update profession rank handling with new split skill values for each expansion
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
135
sql/updates/characters/master/2018_12_02_00_characters.sql
Normal file
135
sql/updates/characters/master/2018_12_02_00_characters.sql
Normal file
@@ -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`;
|
||||
8
sql/updates/world/master/2018_12_02_00_world.sql
Normal file
8
sql/updates/world/master/2018_12_02_00_world.sql
Normal file
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) { }
|
||||
|
||||
@@ -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*/)
|
||||
|
||||
Reference in New Issue
Block a user