From a98dc65a3b7af09a3c882718cc3185529e8c4f2f Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 14 Mar 2023 04:12:47 -0400 Subject: [PATCH] Core/Fishing: Update correct fishing skill according to area expansion Port From (https://github.com/TrinityCore/TrinityCore/commit/bb6773171154a80275791bd57a00624e0107fac5) --- Source/Framework/Logging/Log.cs | 1 + Source/Game/Entities/GameObject/GameObject.cs | 48 +++++++------ Source/Game/Entities/Player/Player.Spells.cs | 71 ++++++++++++++++--- Source/Game/Globals/ObjectManager.cs | 48 +++++++++++-- 4 files changed, 132 insertions(+), 36 deletions(-) diff --git a/Source/Framework/Logging/Log.cs b/Source/Framework/Logging/Log.cs index 64e172844..5bd394da1 100644 --- a/Source/Framework/Logging/Log.cs +++ b/Source/Framework/Logging/Log.cs @@ -400,6 +400,7 @@ public enum LogFilter CommandsRA, Condition, Conversation, + GameObject, Garrison, Gameevent, Guild, diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs index 8247c1651..09375c2f6 100644 --- a/Source/Game/Entities/GameObject/GameObject.cs +++ b/Source/Game/Entities/GameObject/GameObject.cs @@ -1999,34 +1999,36 @@ namespace Game.Entities SendUpdateToPlayer(player); - uint zone, subzone; - GetZoneAndAreaId(out zone, out subzone); - - int zone_skill = Global.ObjectMgr.GetFishingBaseSkillLevel(subzone); - if (zone_skill == 0) - zone_skill = Global.ObjectMgr.GetFishingBaseSkillLevel(zone); - - //provide error, no fishable zone or area should be 0 - if (zone_skill == 0) - Log.outError(LogFilter.Sql, "Fishable areaId {0} are not properly defined in `skill_fishing_base_level`.", subzone); - - int skill = player.GetSkillValue(SkillType.Fishing); - - int chance; - if (skill < zone_skill) + AreaTableRecord areaEntry = CliDB.AreaTableStorage.LookupByKey(GetAreaId()); + if (areaEntry == null) { - chance = (int)(Math.Pow((double)skill / zone_skill, 2) * 100); + Log.outError(LogFilter.GameObject, $"Gameobject '{GetEntry()}' ({GetGUID()}) spawned in unknown area (x: {GetPositionX()} y: {GetPositionY()} z: {GetPositionZ()} map: {GetMapId()})"); + break; + } + + // Update the correct fishing skill according to the area's ContentTuning + ContentTuningRecord areaContentTuning = Global.ObjectMgr.GetContentTuningForArea(areaEntry); + if (areaContentTuning == null) + break; + + player.UpdateFishingSkill(areaContentTuning.ExpansionID); + + // Send loot + int areaFishingLevel = Global.ObjectMgr.GetFishingBaseSkillLevel(areaEntry); + + uint playerFishingSkill = player.GetProfessionSkillForExp(SkillType.Fishing, areaContentTuning.ExpansionID); + int playerFishingLevel = player.GetSkillValue(playerFishingSkill); + + int roll = RandomHelper.IRand(1, 100); + int chance = 100; + if (playerFishingLevel < areaFishingLevel) + { + chance = (int)Math.Pow((double)playerFishingLevel / areaFishingLevel, 2) * 100; if (chance < 1) chance = 1; } - else - chance = 100; - int roll = RandomHelper.IRand(1, 100); - - Log.outDebug(LogFilter.Server, "Fishing check (skill: {0} zone min skill: {1} chance {2} roll: {3}", skill, zone_skill, chance, roll); - - player.UpdateFishingSkill(); + Log.outDebug(LogFilter.Misc, $"Fishing check (skill {playerFishingSkill} level: {playerFishingLevel} area skill level: {areaFishingLevel} chance {chance} roll: {roll}"); // @todo find reasonable value for fishing hole search GameObject fishingPool = LookupFishingHoleAround(20.0f + SharedConst.ContactDistance); diff --git a/Source/Game/Entities/Player/Player.Spells.cs b/Source/Game/Entities/Player/Player.Spells.cs index 47f71834a..ef2fa1279 100644 --- a/Source/Game/Entities/Player/Player.Spells.cs +++ b/Source/Game/Entities/Player/Player.Spells.cs @@ -46,6 +46,11 @@ namespace Game.Entities } public ushort GetSkillValue(SkillType skill) + { + return GetSkillValue((uint)skill); + } + + public ushort GetSkillValue(uint skill) { if (skill == 0) return 0; @@ -63,6 +68,11 @@ namespace Game.Entities } ushort GetMaxSkillValue(SkillType skill) + { + return GetMaxSkillValue((uint)skill); + } + + ushort GetMaxSkillValue(uint skill) { if (skill == 0) return 0; @@ -80,13 +90,18 @@ namespace Game.Entities } public ushort GetPureSkillValue(SkillType skill) + { + return GetPureSkillValue((uint)skill); + } + + public ushort GetPureSkillValue(uint skill) { if (skill == 0) return 0; SkillInfo skillInfo = m_activePlayerData.Skill; - var skillStatusData = mSkillStatus.LookupByKey((uint)skill); + var skillStatusData = mSkillStatus.LookupByKey(skill); if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0) return 0; @@ -1374,29 +1389,67 @@ namespace Game.Entities return (byte)(SkillValue / 31); } - public bool UpdateFishingSkill() + public bool UpdateFishingSkill(int expansion) { - Log.outDebug(LogFilter.Player, "UpdateFishingSkill"); + Log.outDebug(LogFilter.Player, $"Player::UpdateFishingSkill: Player '{GetName()}' ({GetGUID()}) Expansion: {expansion}"); - uint SkillValue = GetPureSkillValue(SkillType.Fishing); - - if (SkillValue >= GetMaxSkillValue(SkillType.Fishing)) + uint fishingSkill = GetProfessionSkillForExp(SkillType.Fishing, expansion); + if (fishingSkill == 0 || !HasSkill(fishingSkill)) return false; - byte stepsNeededToLevelUp = GetFishingStepsNeededToLevelUp(SkillValue); + uint skillValue = GetPureSkillValue(fishingSkill); + + if (skillValue >= GetMaxSkillValue(fishingSkill)) + return false; + + byte stepsNeededToLevelUp = GetFishingStepsNeededToLevelUp(skillValue); ++m_fishingSteps; if (m_fishingSteps >= stepsNeededToLevelUp) { m_fishingSteps = 0; - uint gathering_skill_gain = WorldConfig.GetUIntValue(WorldCfg.SkillGainGathering); - return UpdateSkillPro(SkillType.Fishing, 100 * 10, gathering_skill_gain); + uint gatheringSkillGain = WorldConfig.GetUIntValue(WorldCfg.SkillGainGathering); + return UpdateSkillPro(fishingSkill, 100 * 10, gatheringSkillGain); } return false; } + public uint GetProfessionSkillForExp(SkillType skill, int expansion) + { + return GetProfessionSkillForExp((uint)skill, expansion); + } + + public uint GetProfessionSkillForExp(uint skill, int expansion) + { + SkillLineRecord skillEntry = CliDB.SkillLineStorage.LookupByKey(skill); + if (skillEntry == null) + return 0; + + if (skillEntry.ParentSkillLineID != 0 || (skillEntry.CategoryID != SkillCategory.Profession && skillEntry.CategoryID != SkillCategory.Secondary)) + return 0; + + // The value -3 from ContentTuning refers to the current expansion + if (expansion < 0) + expansion = (int)PlayerConst.CurrentExpansion; + + var childSkillLines = Global.DB2Mgr.GetSkillLinesForParentSkill(skillEntry.Id); + if (childSkillLines != null) + { + foreach (var childSkillLine in 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 + int skillLineExpansion = childSkillLine.ParentTierIndex - 4; + if (expansion == skillLineExpansion) + return childSkillLine.Id; + } + } + + return 0; + } + int SkillGainChance(uint SkillValue, uint GrayLevel, uint GreenLevel, uint YellowLevel) { if (SkillValue >= GrayLevel) diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index cc2c6d305..be9b8b02e 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -8703,10 +8703,6 @@ namespace Game { return _spellClickInfoStorage.LookupByKey(creature_id); } - public int GetFishingBaseSkillLevel(uint entry) - { - return _fishingBaseForAreaStorage.LookupByKey(entry); - } public SkillTiersEntry GetSkillTier(uint skillTierId) { return _skillTiers.LookupByKey(skillTierId); @@ -10453,12 +10449,52 @@ namespace Game { return _baseXPTable.ContainsKey(level) ? _baseXPTable[level] : 0; } + public uint GetXPForLevel(uint level) { if (level < _playerXPperLevel.Length) return _playerXPperLevel[level]; return 0; } + + public int GetFishingBaseSkillLevel(AreaTableRecord areaEntry) + { + if (areaEntry == null) + return 0; + + // Get level for the area + var level = _fishingBaseForAreaStorage.LookupByKey(areaEntry.Id); + if (level != 0) + return level; + + // If there is no data for the current area and it has a parent area, get data from the last (recursive) + var parentAreaEntry = CliDB.AreaTableStorage.LookupByKey(areaEntry.ParentAreaID); + if (parentAreaEntry != null) + return GetFishingBaseSkillLevel(parentAreaEntry); + + Log.outError(LogFilter.Sql, $"Fishable areaId {areaEntry.Id} is not properly defined in `skill_fishing_base_level`."); + + return 0; + } + + public ContentTuningRecord GetContentTuningForArea(AreaTableRecord areaEntry) + { + if (areaEntry == null) + return null; + + // Get ContentTuning for the area + var contentTuning = CliDB.ContentTuningStorage.LookupByKey(areaEntry.ContentTuningID); + if (contentTuning != null) + return contentTuning; + + // If there is no data for the current area and it has a parent area, get data from the last (recursive) + var parentAreaEntry = CliDB.AreaTableStorage.LookupByKey(areaEntry.ParentAreaID); + if (parentAreaEntry != null) + return GetContentTuningForArea(parentAreaEntry); + + return null; + } + public uint GetMaxLevelForExpansion(Expansion expansion) { switch (expansion) @@ -10488,6 +10524,7 @@ namespace Game } return 0; } + CellObjectGuids CreateCellObjectGuids(uint mapid, Difficulty difficulty, uint cellid) { var key = (mapid, difficulty); @@ -10500,6 +10537,7 @@ namespace Game return mapObjectGuidsStore[key][cellid]; } + public CellObjectGuids GetCellObjectGuids(uint mapid, Difficulty difficulty, uint cellid) { var key = (mapid, difficulty); @@ -10509,11 +10547,13 @@ namespace Game return null; } + public Dictionary GetMapObjectGuids(uint mapid, Difficulty difficulty) { var key = (mapid, difficulty); return mapObjectGuidsStore.LookupByKey(key); } + public PageText GetPageText(uint pageEntry) { return _pageTextStorage.LookupByKey(pageEntry);