diff options
author | Shauren <shauren.trinity@gmail.com> | 2018-12-02 17:39:41 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2018-12-02 17:39:41 +0100 |
commit | 1b67a2626b77cf4bf04006cfcb09fdf46e6436fc (patch) | |
tree | 33bb8ba53c6d9c3ec222d7c0a682664518a03d44 /src | |
parent | 947771e6bdbeaa8788c373e0659cd8ca95cd96f2 (diff) |
Core/Players: Update profession rank handling with new split skill values for each expansion
Diffstat (limited to 'src')
-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 |
7 files changed, 95 insertions, 71 deletions
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*/) |