diff --git a/Maple2.Database/Storage/Metadata/TableMetadataStorage.cs b/Maple2.Database/Storage/Metadata/TableMetadataStorage.cs index 8caf0f403..86cafefee 100644 --- a/Maple2.Database/Storage/Metadata/TableMetadataStorage.cs +++ b/Maple2.Database/Storage/Metadata/TableMetadataStorage.cs @@ -14,6 +14,7 @@ public class TableMetadataStorage { private readonly Lazy magicPathTable; private readonly Lazy masteryRecipeTable; private readonly Lazy masteryRewardTable; + private readonly Lazy masteryDifferentialFactorTable; private readonly Lazy fishingRodTable; private readonly Lazy instrumentTable; private readonly Lazy interactObjectTable; @@ -80,6 +81,7 @@ public class TableMetadataStorage { public MagicPathTable MagicPathTable => magicPathTable.Value; public MasteryRecipeTable MasteryRecipeTable => masteryRecipeTable.Value; public MasteryRewardTable MasteryRewardTable => masteryRewardTable.Value; + public MasteryDifferentialFactorTable MasteryDifferentialFactorTable => masteryDifferentialFactorTable.Value; public FishingRodTable FishingRodTable => fishingRodTable.Value; public InstrumentTable InstrumentTable => instrumentTable.Value; public InteractObjectTable InteractObjectTable => interactObjectTable.Value; @@ -147,6 +149,7 @@ public TableMetadataStorage(MetadataContext context) { magicPathTable = Retrieve(context, TableNames.MAGIC_PATH); masteryRecipeTable = Retrieve(context, TableNames.MASTERY_RECIPE); masteryRewardTable = Retrieve(context, TableNames.MASTERY); + masteryDifferentialFactorTable = Retrieve(context, TableNames.MASTERYT_DIFFERENTIAL_FACTOR); fishingRodTable = Retrieve(context, TableNames.FISHING_ROD); instrumentTable = Retrieve(context, TableNames.INSTRUMENT_CATEGORY_INFO); interactObjectTable = Retrieve(context, TableNames.INTERACT_OBJECT); diff --git a/Maple2.File.Ingest/Mapper/TableMapper.cs b/Maple2.File.Ingest/Mapper/TableMapper.cs index 05826a4cf..e3288db07 100644 --- a/Maple2.File.Ingest/Mapper/TableMapper.cs +++ b/Maple2.File.Ingest/Mapper/TableMapper.cs @@ -59,6 +59,7 @@ protected override IEnumerable Map() { yield return new TableMetadata { Name = TableNames.ITEM_SOCKET, Table = ParseItemSocketTable() }; yield return new TableMetadata { Name = TableNames.MASTERY_RECIPE, Table = ParseMasteryRecipe() }; yield return new TableMetadata { Name = TableNames.MASTERY, Table = ParseMasteryReward() }; + yield return new TableMetadata { Name = TableNames.MASTERYT_DIFFERENTIAL_FACTOR, Table = ParseMasteryDifferentialFactor() }; yield return new TableMetadata { Name = TableNames.GUILD, Table = ParseGuildTable() }; yield return new TableMetadata { Name = TableNames.VIP, Table = ParsePremiumClubTable() }; yield return new TableMetadata { Name = TableNames.INDIVIDUAL_ITEM_DROP, Table = ParseIndividualItemDropTable() }; @@ -776,6 +777,16 @@ private MasteryRewardTable ParseMasteryReward() { return new MasteryRewardTable(results); } + private MasteryDifferentialFactorTable ParseMasteryDifferentialFactor() { + var results = new Dictionary(); + foreach ((int id, MasteryDifferentialFactor factor) in parser.ParseMasteryDifferentialFactor()) { + results.Add(id, new MasteryDifferentialFactorTable.Entry( + Differential: factor.differential, + Factor: factor.factor)); + } + return new MasteryDifferentialFactorTable(results); + } + private GuildTable ParseGuildTable() { // Dictionary expTable = parser.ParseGuildExp() // .ToDictionary(entry => (short) entry.Id, entry => entry.Item.value); diff --git a/Maple2.Model/Common/TableNames.cs b/Maple2.Model/Common/TableNames.cs index 6df45fdaf..100fef6c1 100644 --- a/Maple2.Model/Common/TableNames.cs +++ b/Maple2.Model/Common/TableNames.cs @@ -15,6 +15,7 @@ public static class TableNames { public const string ITEM_SOCKET = "itemsocket.xml"; public const string MASTERY_RECIPE = "masteryreceipe.xml"; public const string MASTERY = "mastery.xml"; + public const string MASTERYT_DIFFERENTIAL_FACTOR = "masterydifferentialfactor.xml"; public const string GUILD = "guild*.xml"; public const string VIP = "vip*.xml"; public const string INDIVIDUAL_ITEM_DROP = "individualitemdrop*.xml"; diff --git a/Maple2.Model/Metadata/Table/MasteryDifferentialFactorTable.cs b/Maple2.Model/Metadata/Table/MasteryDifferentialFactorTable.cs new file mode 100644 index 000000000..2bdba1a16 --- /dev/null +++ b/Maple2.Model/Metadata/Table/MasteryDifferentialFactorTable.cs @@ -0,0 +1,9 @@ +namespace Maple2.Model.Metadata; + +public record MasteryDifferentialFactorTable(IReadOnlyDictionary Entries) : Table { + public record Entry( + int Differential, + int Factor); +} + + diff --git a/Maple2.Model/Metadata/TableMetadata.cs b/Maple2.Model/Metadata/TableMetadata.cs index 044a8fafc..e16d9266c 100644 --- a/Maple2.Model/Metadata/TableMetadata.cs +++ b/Maple2.Model/Metadata/TableMetadata.cs @@ -47,6 +47,7 @@ public override int GetHashCode() { [JsonDerivedType(typeof(ChatStickerTable), typeDiscriminator: "chatsticker")] [JsonDerivedType(typeof(MasteryRecipeTable), typeDiscriminator: "masteryrecipe")] [JsonDerivedType(typeof(MasteryRewardTable), typeDiscriminator: "masteryreward")] +[JsonDerivedType(typeof(MasteryDifferentialFactorTable), typeDiscriminator: "masterydifferentialfactor")] [JsonDerivedType(typeof(FishingRodTable), typeDiscriminator: "fishingrod")] [JsonDerivedType(typeof(GuildTable), typeDiscriminator: "guild")] [JsonDerivedType(typeof(PremiumClubTable), typeDiscriminator: "vip")] diff --git a/Maple2.Server.Game/Manager/MasteryManager.cs b/Maple2.Server.Game/Manager/MasteryManager.cs index 9be8ceb43..7c772bb4d 100644 --- a/Maple2.Server.Game/Manager/MasteryManager.cs +++ b/Maple2.Server.Game/Manager/MasteryManager.cs @@ -134,10 +134,25 @@ private bool GatherCommon(int recipeId, Vector3 position, Vector3 rotation) { } Gather(recipeMetadata, position, rotation); - this[recipeMetadata.Type] += recipeMetadata.RewardMastery; if (!recipeMetadata.NoRewardExp) { session.Exp.AddExp(ExpType.gathering); } + switch (recipeMetadata.Type) { + case MasteryType.Farming: + case MasteryType.Mining: + case MasteryType.Gathering: + case MasteryType.Breeding: + short playerLevel = GetLevel(recipeMetadata.Type); + // no mastery given - recipe level is more than 3 levels below player's mastery level + int masteryFactorCount = session.TableMetadata.MasteryDifferentialFactorTable.Entries.Values.Count(m => m.Factor > 0); + if (playerLevel - recipeMetadata.RewardMastery >= masteryFactorCount) { + return true; + } + break; + default: + break; + } + this[recipeMetadata.Type] += recipeMetadata.RewardMastery; return true; }