diff options
author | Meji <alvaro.megias@outlook.com> | 2023-03-12 11:07:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-12 11:07:34 +0100 |
commit | bb6773171154a80275791bd57a00624e0107fac5 (patch) | |
tree | d0cc45c21e931d89d30665bd7edb12cef1532f57 | |
parent | 09568736134372ec1a79b936a248eec30f071c8d (diff) |
Core/Fishing: Update correct fishing skill according to area expansion (#28838)
Closes #26676
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 41 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 44 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 35 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 8 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 3 |
6 files changed, 101 insertions, 33 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 43707fa07ce..3d182cf6604 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2525,34 +2525,37 @@ void GameObject::Use(Unit* user) SendUpdateToPlayer(player); - uint32 zone, subzone; - GetZoneAndAreaId(zone, subzone); + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(GetAreaId()); + if (!areaEntry) + { + TC_LOG_ERROR("entities.gameobject", "Gameobject '{}' ({}) spawned in unknown area (x: {} y: {} z: {} map: {})", + GetEntry(), GetGUID().ToString(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId()); + break; + } + + // Update the correct fishing skill according to the area's ContentTuning + ContentTuningEntry const* areaContentTuning = sObjectMgr->GetContentTuningForArea(areaEntry); + if (!areaContentTuning) + break; - int32 zone_skill = sObjectMgr->GetFishingBaseSkillLevel(subzone); - if (!zone_skill) - zone_skill = sObjectMgr->GetFishingBaseSkillLevel(zone); + player->UpdateFishingSkill(areaContentTuning->ExpansionID); - //provide error, no fishable zone or area should be 0 - if (!zone_skill) - TC_LOG_ERROR("sql.sql", "Fishable areaId {} are not properly defined in `skill_fishing_base_level`.", subzone); + // Send loot + int32 areaFishingLevel = sObjectMgr->GetFishingBaseSkillLevel(areaEntry); - int32 skill = player->GetSkillValue(SKILL_FISHING); + uint32 playerFishingSkill = player->GetProfessionSkillForExp(SKILL_FISHING, areaContentTuning->ExpansionID); + int32 playerFishingLevel = player->GetSkillValue(playerFishingSkill); - int32 chance; - if (skill < zone_skill) + int32 roll = irand(1, 100); + int32 chance = 100; + if (playerFishingLevel < areaFishingLevel) { - chance = int32(pow((double)skill/zone_skill, 2) * 100); + chance = int32(pow((double)playerFishingLevel / areaFishingLevel, 2) * 100); if (chance < 1) chance = 1; } - else - chance = 100; - - int32 roll = irand(1, 100); - - TC_LOG_DEBUG("misc", "Fishing check (skill: {} zone min skill: {} chance {} roll: {}", skill, zone_skill, chance, roll); - player->UpdateFishingSkill(); + TC_LOG_DEBUG("misc", "Fishing check (skill {} level: {} area skill level: {} chance {} roll: {}", playerFishingSkill, playerFishingLevel, areaFishingLevel, chance, roll); /// @todo find reasonable value for fishing hole search GameObject* fishingPool = LookupFishingHoleAround(20.0f + CONTACT_DISTANCE); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d760b938264..ea568ce1535 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5626,24 +5626,28 @@ uint8 GetFishingStepsNeededToLevelUp(uint32 SkillValue) return SkillValue / 31; } -bool Player::UpdateFishingSkill() +bool Player::UpdateFishingSkill(int32 expansion) { - TC_LOG_DEBUG("entities.player.skills", "Player::UpdateFishingSkill: Player '{}' ({})", GetName(), GetGUID().ToString()); + TC_LOG_DEBUG("entities.player.skills", "Player::UpdateFishingSkill: Player '{}' ({}) Expansion: {}", GetName(), GetGUID().ToString(), expansion); - uint32 SkillValue = GetPureSkillValue(SKILL_FISHING); + uint32 fishingSkill = GetProfessionSkillForExp(SKILL_FISHING, expansion); + if (!fishingSkill || !HasSkill(fishingSkill)) + return false; + + uint32 skillValue = GetPureSkillValue(fishingSkill); - if (SkillValue >= GetMaxSkillValue(SKILL_FISHING)) + if (skillValue >= GetMaxSkillValue(fishingSkill)) return false; - uint8 stepsNeededToLevelUp = GetFishingStepsNeededToLevelUp(SkillValue); + uint8 stepsNeededToLevelUp = GetFishingStepsNeededToLevelUp(skillValue); ++m_fishingSteps; if (m_fishingSteps >= stepsNeededToLevelUp) { m_fishingSteps = 0; - uint32 gathering_skill_gain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_GATHERING); - return UpdateSkillPro(SKILL_FISHING, 100*10, gathering_skill_gain); + uint32 gatheringSkillGain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_GATHERING); + return UpdateSkillPro(fishingSkill, 100*10, gatheringSkillGain); } return false; @@ -5983,6 +5987,32 @@ void Player::SetSkill(uint32 id, uint16 step, uint16 newVal, uint16 maxVal) } } +uint32 Player::GetProfessionSkillForExp(uint32 skill, int32 expansion) const +{ + SkillLineEntry const* skillEntry = sSkillLineStore.LookupEntry(skill); + if (!skillEntry) + return 0; + + if (skillEntry->ParentSkillLineID || (skillEntry->CategoryID != SKILL_CATEGORY_PROFESSION && skillEntry->CategoryID != SKILL_CATEGORY_SECONDARY)) + return 0; + + // The value -3 from ContentTuning refers to the current expansion + if (expansion < 0) + expansion = CURRENT_EXPANSION; + + if (std::vector<SkillLineEntry const*> const* childSkillLines = sDB2Manager.GetSkillLinesForParentSkill(skillEntry->ID)) + for (SkillLineEntry const* childSkillLine : *childSkillLines) + { + // Values of ParentTierIndex in SkillLine.db2 start at 4 (Classic) and increase by one for each expansion skillLine + // Subtract 4 (BASE_PARENT_TIER_INDEX) from this value to obtain the expansion of the skillLine + int32 skillLineExpansion = childSkillLine->ParentTierIndex - BASE_PARENT_TIER_INDEX; + if (expansion == skillLineExpansion) + return childSkillLine->ID; + } + + return 0; +} + bool Player::HasSkill(uint32 skill) const { if (!skill) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7cff3ee493e..854bc120939 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2025,7 +2025,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step); bool UpdateCraftSkill(SpellInfo const* spellInfo); bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1, WorldObject const* object = nullptr); - bool UpdateFishingSkill(); + bool UpdateFishingSkill(int32 expansion); float GetHealthBonusFromStamina() const; Stats GetPrimaryStat() const; @@ -2204,6 +2204,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> int16 GetSkillPermBonusValue(uint32 skill) const; int16 GetSkillTempBonusValue(uint32 skill) const; uint16 GetSkillStep(uint32 skill) const; // 0...6 + uint32 GetProfessionSkillForExp(uint32 skill, int32 expansion) const; bool HasSkill(uint32 skill) const; void LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue, Races race); int32 GetProfessionSlotFor(uint32 skillId) const; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 86d1bfafbf2..91f81825f14 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8090,6 +8090,41 @@ uint32 ObjectMgr::GetXPForLevel(uint8 level) const return 0; } +int32 ObjectMgr::GetFishingBaseSkillLevel(AreaTableEntry const* areaEntry) const +{ + if (!areaEntry) + return 0; + + // Get level for the area + FishingBaseSkillContainer::const_iterator itr = _fishingBaseForAreaStore.find(areaEntry->ID); + if (itr != _fishingBaseForAreaStore.end()) + return itr->second; + + // If there is no data for the current area and it has a parent area, get data from the last (recursive) + if (AreaTableEntry const* parentAreaEntry = sAreaTableStore.LookupEntry(areaEntry->ParentAreaID)) + return GetFishingBaseSkillLevel(parentAreaEntry); + + TC_LOG_ERROR("sql.sql", "Fishable areaId {} is not properly defined in `skill_fishing_base_level`.", areaEntry->ID); + + return 0; +} + +ContentTuningEntry const* ObjectMgr::GetContentTuningForArea(AreaTableEntry const* areaEntry) const +{ + if (!areaEntry) + return nullptr; + + // Get ContentTuning for the area + if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(areaEntry->ContentTuningID)) + return contentTuning; + + // If there is no data for the current area and it has a parent area, get data from the last (recursive) + if (AreaTableEntry const* parentAreaEntry = sAreaTableStore.LookupEntry(areaEntry->ParentAreaID)) + return GetContentTuningForArea(parentAreaEntry); + + return nullptr; +} + void ObjectMgr::LoadPetNames() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 7c791592350..fee3d6e3e5c 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1429,11 +1429,9 @@ class TC_GAME_API ObjectMgr uint32 GetBaseXP(uint8 level); uint32 GetXPForLevel(uint8 level) const; - int32 GetFishingBaseSkillLevel(uint32 entry) const - { - FishingBaseSkillContainer::const_iterator itr = _fishingBaseForAreaStore.find(entry); - return itr != _fishingBaseForAreaStore.end() ? itr->second : 0; - } + int32 GetFishingBaseSkillLevel(AreaTableEntry const* areaEntry) const; + + ContentTuningEntry const* GetContentTuningForArea(AreaTableEntry const* areaEntry) const; SkillTiersEntry const* GetSkillTier(uint32 skillTierId) const { diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index c7849a3cffc..4e707a2262e 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -6472,7 +6472,8 @@ enum TaxiNodeStatus enum ProfessionUI { MAX_PRIMARY_PROFESSIONS = 2, - MAX_SECONDARY_SKILLS = 5 + MAX_SECONDARY_SKILLS = 5, + BASE_PARENT_TIER_INDEX = 4 }; enum DuelCompleteType : uint8 |