diff --git a/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs b/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs index 2a0808ffe..56e80c62d 100644 --- a/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs @@ -899,11 +899,16 @@ private double CalculateTargetLvMultiplier(GameMode gameMode, PartyGroup party, return multiplier; } + private double ModifierBasedOnSource(RewardSource source) + { + return source == RewardSource.Enemy ? _GameSettings.EnemyExpModifier : _GameSettings.QuestExpModifier; + } + public uint GetAdjustedExp(GameMode gameMode, RewardSource source, PartyGroup party, uint baseExpAmount, uint targetLv) { if (_Server.GpCourseManager.DisablePartyExpAdjustment()) { - return (uint)(baseExpAmount * _GameSettings.ExpModifier); + return (uint)(baseExpAmount * ModifierBasedOnSource(source)); } double multiplier = 1.0; @@ -913,8 +918,12 @@ public uint GetAdjustedExp(GameMode gameMode, RewardSource source, PartyGroup pa var partyRangeMultiplier = CalculatePartyRangeMultipler(gameMode, party); multiplier = Math.Min(partyRangeMultiplier, targetMultiplier); } - - return (uint)(multiplier * baseExpAmount * _GameSettings.ExpModifier); + else if (source == RewardSource.Quest) + { + // Currently no adjustments + } + + return (uint)(multiplier * baseExpAmount * ModifierBasedOnSource(source)); } private uint GetMaxAllowedPartyRange() @@ -996,13 +1005,13 @@ public uint GetAdjustedPawnExp(GameMode gameMode, RewardSource source, PartyGrou { if (!_GameSettings.EnablePawnCatchup || gameMode == GameMode.BitterblackMaze) { - return (uint)(baseExpAmount * _GameSettings.ExpModifier); + return (uint)(baseExpAmount * ModifierBasedOnSource(source)); } var targetMultiplier = CalculatePawnCatchupTargetLvMultiplier(gameMode, pawn, targetLv); var multiplier = _GameSettings.PawnCatchupMultiplier * targetMultiplier; - return (uint)(multiplier * baseExpAmount * _GameSettings.ExpModifier); + return (uint)(multiplier * baseExpAmount * ModifierBasedOnSource(source)); } } } diff --git a/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs b/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs index c85a713c9..080e6ecbc 100644 --- a/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs +++ b/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs @@ -1,3 +1,4 @@ +using Arrowgene.Ddon.Database.Model; using Arrowgene.Ddon.GameServer.Characters; using Arrowgene.Ddon.GameServer.Party; using Arrowgene.Ddon.Server; @@ -10,6 +11,7 @@ using System; using System.Collections.Generic; using System.Data.Common; +using System.Drawing; using System.Linq; namespace Arrowgene.Ddon.GameServer.Quests @@ -557,6 +559,27 @@ public QuestProcessState GetProcessState(uint questScheduleId, ushort processNo) public abstract PacketQueue DistributeQuestRewards(uint questScheduleId, DbConnection? connectionIn = null); public abstract PacketQueue UpdatePriorityQuestList(GameClient requestingClient, DbConnection? connectionIn = null); + private uint CalculateTotalPointAmount(DdonGameServer server, GameClient client, CDataQuestExp point) + { + uint amount = point.Reward; + double modifier = 1.0; + switch (point.Type) + { + case ExpType.ExperiencePoints: + amount = server.ExpManager.GetAdjustedExp(client.GameMode, RewardSource.Quest, null, point.Reward, 0); + break; + case ExpType.JobPoints: + modifier = (uint)(amount * server.Setting.GameLogicSetting.JpModifier); + break; + case ExpType.PlayPoints: + amount = (uint)(amount * server.Setting.GameLogicSetting.PpModifier); + break; + default: + break; + } + return amount; + } + protected PacketQueue SendWalletRewards(DdonGameServer server, GameClient client, Quest quest, DbConnection? connectionIn = null) { PacketQueue packets = new(); @@ -581,40 +604,47 @@ protected PacketQueue SendWalletRewards(DdonGameServer server, GameClient client client.Enqueue(updateCharacterItemNtc, packets); } - foreach (var expPoint in quest.ExpRewards) + foreach (var point in quest.ExpRewards) { - uint amount = expPoint.Reward; - double modifier = 1.0; - switch (expPoint.Type) + uint amount = CalculateTotalPointAmount(server, client, point); + if (amount == 0) + { + continue; + } + + switch (point.Type) { case ExpType.ExperiencePoints: - modifier = server.Setting.GameLogicSetting.ExpModifier; + packets.AddRange(server.ExpManager.AddExp(client, client.Character, amount, RewardSource.Quest, quest.QuestType, connectionIn)); + if (server.Setting.GameLogicSetting.EnableMainPartyPawnsQuestRewards) + { + foreach (PartyMember member in client.Party.Members) + { + if (member is PawnPartyMember pawnMember && client.Character.Pawns.Contains(pawnMember.Pawn)) + { + packets.AddRange(server.ExpManager.AddExp(client, pawnMember.Pawn, amount, RewardSource.Quest, quest.QuestType, connectionIn)); + } + } + } break; case ExpType.JobPoints: - modifier = server.Setting.GameLogicSetting.JpModifier; + packets.AddRange(server.ExpManager.AddJp(client, client.Character, amount, RewardSource.Quest, quest.QuestType, connectionIn)); + if (server.Setting.GameLogicSetting.EnableMainPartyPawnsQuestRewards) + { + foreach (PartyMember member in client.Party.Members) + { + if (member is PawnPartyMember pawnMember && client.Character.Pawns.Contains(pawnMember.Pawn)) + { + packets.AddRange(server.ExpManager.AddJp(client, pawnMember.Pawn, amount, RewardSource.Quest, quest.QuestType, connectionIn)); + } + } + } break; case ExpType.PlayPoints: - modifier = server.Setting.GameLogicSetting.PpModifier; + var ntc = server.PPManager.AddPlayPoint(client, amount, type: 1, connectionIn: connectionIn); + client.Enqueue(ntc, packets); break; } - - amount = (uint)(amount * modifier); - - if (expPoint.Type == ExpType.ExperiencePoints) - { - var ntcs = server.ExpManager.AddExp(client, client.Character, amount, RewardSource.Quest, quest.QuestType, connectionIn); - packets.AddRange(ntcs); - } - else if (expPoint.Type == ExpType.JobPoints) - { - var ntcs = server.ExpManager.AddJp(client, client.Character, amount, RewardSource.Quest, quest.QuestType, connectionIn); - packets.AddRange(ntcs); - } - else if (expPoint.Type == ExpType.PlayPoints) - { - var ntc = server.PPManager.AddPlayPoint(client, amount, type: 1, connectionIn: connectionIn); - client.Enqueue(ntc, packets); - } } if (QuestManager.IsClanQuest(quest) && client.Character.ClanId != 0) @@ -630,7 +660,6 @@ protected PacketQueue SendWalletRewards(DdonGameServer server, GameClient client packets.AddRange(completeNtcs); } - return packets; } diff --git a/Arrowgene.Ddon.Server/GameLogicSetting.cs b/Arrowgene.Ddon.Server/GameLogicSetting.cs index 7d40a933b..815acf64a 100644 --- a/Arrowgene.Ddon.Server/GameLogicSetting.cs +++ b/Arrowgene.Ddon.Server/GameLogicSetting.cs @@ -169,43 +169,53 @@ public class GameLogicSetting /// /// Global modifier for exp calculations to scale up or down. /// - [DataMember(Order = 26)] public double ExpModifier { get; set; } + [DataMember(Order = 27)] public double EnemyExpModifier { get; set; } + + /// + /// Global modifier for quest exp calculations to scale up or down. + /// + [DataMember(Order = 28)] public double QuestExpModifier { get; set; } /// /// Global modifier for pp calculations to scale up or down. /// - [DataMember(Order = 26)] public double PpModifier { get; set; } + [DataMember(Order = 29)] public double PpModifier { get; set; } /// /// Global modifier for BO calculations to scale up or down. /// - [DataMember(Order = 26)] public double BoModifier { get; set; } + [DataMember(Order = 30)] public double BoModifier { get; set; } /// /// Global modifier for HO calculations to scale up or down. /// - [DataMember(Order = 26)] public double HoModifier { get; set; } + [DataMember(Order = 31)] public double HoModifier { get; set; } /// /// Global modifier for JP calculations to scale up or down. /// - [DataMember(Order = 26)] public double JpModifier { get; set; } + [DataMember(Order = 32)] public double JpModifier { get; set; } /// /// Configures the maximum amount of reward box slots. /// - [DataMember(Order = 27)] public byte RewardBoxMax { get; set; } + [DataMember(Order = 33)] public byte RewardBoxMax { get; set; } /// /// Configures the maximum amount of quests that can be ordered at one time. /// - [DataMember(Order = 27)] public byte QuestOrderMax { get; set; } + [DataMember(Order = 34)] public byte QuestOrderMax { get; set; } /// /// Configures if epitaph rewards are limited once per weekly reset. /// - [DataMember(Order = 28)] public bool EnableEpitaphWeeklyRewards { get; set; } + [DataMember(Order = 35)] public bool EnableEpitaphWeeklyRewards { get; set; } + /// Enables main pawns in party to gain EXP and JP from quests + /// Original game apparantly did not have pawns share quest reward, so will set to false for default, + /// change as needed + /// + [DataMember(Order = 36)] public bool EnableMainPartyPawnsQuestRewards { get; set; } /// /// Various URLs used by the client. @@ -290,7 +300,8 @@ public GameLogicSetting() DefaultMaxBazaarExhibits = 5; DefaultWarpFavorites = 3; - ExpModifier = 1.0; + EnemyExpModifier = 1.0; + QuestExpModifier = 1.0; PpModifier = 1.0; BoModifier = 1.0; HoModifier = 1.0; @@ -299,6 +310,7 @@ public GameLogicSetting() QuestOrderMax = 20; EnableEpitaphWeeklyRewards = false; + EnableMainPartyPawnsQuestRewards = false; string urlDomain = $"http://localhost:{52099}"; UrlManual = $"{urlDomain}/manual_nfb/"; @@ -352,7 +364,8 @@ public GameLogicSetting(GameLogicSetting setting) DefaultMaxBazaarExhibits = setting.DefaultMaxBazaarExhibits; DefaultWarpFavorites = setting.DefaultWarpFavorites; - ExpModifier = setting.ExpModifier; + EnemyExpModifier = setting.EnemyExpModifier; + QuestExpModifier = setting.QuestExpModifier; PpModifier = setting.PpModifier; BoModifier = setting.BoModifier; HoModifier = setting.HoModifier; @@ -361,6 +374,7 @@ public GameLogicSetting(GameLogicSetting setting) QuestOrderMax = setting.QuestOrderMax; EnableEpitaphWeeklyRewards = setting.EnableEpitaphWeeklyRewards; + EnableMainPartyPawnsQuestRewards = setting.EnableMainPartyPawnsQuestRewards; UrlManual = setting.UrlManual; UrlShopDetail = setting.UrlShopDetail; @@ -436,9 +450,13 @@ void OnDeserialized(StreamingContext context) { PawnCatchupMultiplier = 1.0; } - if (ExpModifier < 0) + if (EnemyExpModifier < 0) + { + EnemyExpModifier = 1.0; + } + if (QuestExpModifier < 0) { - ExpModifier = 1.0; + QuestExpModifier = 1.0; } if (PpModifier < 0) { diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50101020.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50101020.json index d13e5259e..84ed40f9b 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50101020.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50101020.json @@ -24,6 +24,10 @@ { "item_id": 9456, "num": 3 + }, + { + "item_id": 7795, + "num": 200 } ] }, @@ -290,7 +294,6 @@ "named_enemy_params_id": 631, "level": 58, "exp": 0, - "blood_orbs": 200, "is_boss": true }, { @@ -490,4 +493,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50102020.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50102020.json index 125a23ca5..7cdafc55d 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50102020.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50102020.json @@ -24,6 +24,10 @@ { "item_id": 9457, "num": 3 + }, + { + "item_id": 7795, + "num": 200 } ] }, @@ -204,7 +208,6 @@ "index": 0, "level": 60, "exp": 0, - "blood_orbs": 200, "named_enemy_params_id": 682, "is_boss": true } @@ -304,4 +307,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50103020.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50103020.json index d0e881b56..3012011f5 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50103020.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50103020.json @@ -24,6 +24,10 @@ { "item_id": 9788, "num": 3 + }, + { + "item_id": 7795, + "num": 200 } ] }, @@ -185,7 +189,6 @@ "enemy_id": "0x015711", "level": 60, "exp": 0, - "blood_orbs": 100, "is_boss": true }, { @@ -193,7 +196,6 @@ "enemy_id": "0x015840", "level": 60, "exp": 0, - "blood_orbs": 100, "is_boss": true } ] @@ -308,4 +310,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50104000.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50104000.json index 000358bd1..6d8114839 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50104000.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50104000.json @@ -24,6 +24,10 @@ { "item_id": 9789, "num": 3 + }, + { + "item_id": 7795, + "num": 1000 } ] }, @@ -49,7 +53,6 @@ "enemy_id": "0x021002", "level": 60, "exp": 0, - "blood_orbs": 1000, "named_enemy_params_id": 440, "is_boss": true } @@ -259,4 +262,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50201000.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50201000.json index 6ff97e119..83e7cfdba 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50201000.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50201000.json @@ -24,6 +24,10 @@ { "item_id": 11780, "num": 3 + }, + { + "item_id": 7795, + "num": 500 } ] }, @@ -50,7 +54,6 @@ "level": 65, "exp": 0, "is_boss": true, - "blood_orbs": 500, "named_enemy_params_id": 1674 } ] diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50202000.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50202000.json index 32b8cf284..20f83a46d 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50202000.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50202000.json @@ -24,6 +24,10 @@ { "item_id": 11810, "num": 3 + }, + { + "item_id": 7795, + "num": 650 } ] }, @@ -49,7 +53,6 @@ "enemy_id": "0x021003", "level": 70, "exp": 0, - "blood_orbs": 650, "named_enemy_params_id": 942, "is_boss": true } @@ -304,4 +307,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50203000.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50203000.json index b2bde7b6c..8b10b0294 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50203000.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50203000.json @@ -24,6 +24,10 @@ { "item_id": 15940, "num": 3 + }, + { + "item_id": 7795, + "num": 750 } ] }, @@ -49,7 +53,6 @@ "enemy_id": "0x080600", "level": 75, "exp": 0, - "blood_orbs": 750, "is_boss": true } ] @@ -221,4 +224,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204001.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204001.json index 5e69fbb1c..0a2fc040a 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204001.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204001.json @@ -24,6 +24,10 @@ { "item_id": 41, "num": 1 + }, + { + "item_id": 7795, + "num": 2000 } ] }, @@ -74,7 +78,6 @@ "enemy_id": "0x080502", "level": 80, "exp": 0, - "blood_orbs": 2000, "is_boss": true } ] @@ -193,4 +196,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204002.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204002.json index 235e90902..d0b03e4dd 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204002.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50204002.json @@ -24,6 +24,10 @@ { "item_id": 15997, "num": 3 + }, + { + "item_id": 7795, + "num": 1000 } ] }, @@ -49,7 +53,6 @@ "enemy_id": "0x080501", "level": 80, "exp": 0, - "blood_orbs": 1000, "is_boss": true } ] @@ -80,4 +83,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300001.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300001.json index 02e5d6379..ca01f2dcf 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300001.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300001.json @@ -20,11 +20,15 @@ "rewards": [ { "type": "fixed", - "comment": "Green Dye", + "comment": "Green Dye, Blood Orb", "loot_pool": [ { "item_id": 8136, "num": 1 + }, + { + "item_id": 7795, + "num": 200 } ] }, @@ -159,7 +163,6 @@ "enemy_id": "0x080200", "level": 45, "exp": 0, - "blood_orbs": 200, "is_boss": true } ] @@ -197,4 +200,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300003.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300003.json index dc4f85440..1434fc211 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300003.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300003.json @@ -20,11 +20,15 @@ "rewards": [ { "type": "fixed", - "comment": "Pink Dye", + "comment": "Pink Dye, Blood Orb", "loot_pool": [ { "item_id": 8139, "num": 1 + }, + { + "item_id": 7795, + "num": 500 } ] }, @@ -159,8 +163,7 @@ "enemy_id": "0x080300", "level": 55, "exp": 0, - "is_boss": true, - "blood_orbs": 500 + "is_boss": true } ] } @@ -189,4 +192,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300006.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300006.json index 3c89ecad0..1e17ddaba 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300006.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300006.json @@ -20,11 +20,15 @@ "rewards": [ { "type": "fixed", - "comment": "Yellow Dye", + "comment": "Yellow Dye, Blood Orb", "loot_pool": [ { "item_id": 8138, "num": 1 + }, + { + "item_id": 7795, + "num": 1000 } ] }, @@ -159,7 +163,6 @@ "enemy_id": "0x080100", "level": 60, "exp": 0, - "blood_orbs": 1000, "is_boss": true } ] @@ -189,4 +192,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300010.json b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300010.json index 68e64200b..a57320390 100644 --- a/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300010.json +++ b/Arrowgene.Ddon.Shared/Files/Assets/quests/q50300010.json @@ -18,6 +18,16 @@ }, "order_conditions": [], "rewards": [ + { + "type": "fixed", + "comment": "Blood Orb", + "loot_pool": [ + { + "item_id": 7795, + "num": 1500 + } + ] + }, { "type": "random", "loot_pool": [ @@ -136,7 +146,6 @@ "level": 80, "exp": 0, "is_boss": true, - "blood_orbs": 1500, "named_enemy_params_id": 1564 } ] @@ -486,4 +495,4 @@ ] } ] -} +} \ No newline at end of file