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