Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issues with the crafting functionality #275

Merged
merged 6 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion Arrowgene.Ddon.GameServer/Characters/ItemManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ public void GatherItem(DdonServer<GameClient> server, Character character, S2CIt
}
}

public List<CDataItemUpdateResult> ConsumeItemByUIdFromMultipleStorages(DdonServer<GameClient> server, Character character, List<StorageType> fromStorageTypes, string itemUId, uint consumeNum)
{
int remainingItems = (int) consumeNum;
List<CDataItemUpdateResult> results = new List<CDataItemUpdateResult>();
foreach (StorageType storageType in fromStorageTypes)
{
CDataItemUpdateResult? result = ConsumeItemByUId(server, character, storageType, itemUId, (uint) remainingItems);
if (result != null)
{
results.Add(result);
remainingItems += result.UpdateItemNum;
if (remainingItems == 0)
{
return results;
}
}
}

// TODO: Rollback transaction
throw new NotEnoughItemsException(itemUId, consumeNum, remainingItems);
}

public CDataItemUpdateResult? ConsumeItemByUId(DdonServer<GameClient> server, Character character, StorageType fromStorageType, string itemUId, uint consumeNum)
{
var foundItem = character.Storage.getStorage(fromStorageType).findItemByUId(itemUId);
Expand All @@ -113,7 +135,7 @@ public void GatherItem(DdonServer<GameClient> server, Character character, S2CIt
}
private CDataItemUpdateResult ConsumeItem(DdonServer<GameClient> server, Character character, StorageType fromStorageType, ushort slotNo, Item item, uint itemNum, uint consuneNum)
{
itemNum = Math.Max(0, itemNum - consuneNum);
itemNum = (uint) Math.Max(0, (int)itemNum - (int)consuneNum);

CDataItemUpdateResult ntcData = new CDataItemUpdateResult();
ntcData.ItemList.ItemUId = item.UId;
Expand Down Expand Up @@ -215,4 +237,19 @@ private CDataItemUpdateResult AddItem(IDatabase database, Character character, S
return result;
}
}

[Serializable]
internal class NotEnoughItemsException : Exception
{
private string itemUId;
private uint consumeNum;
private int remainingItems;

public NotEnoughItemsException(string itemUId, uint consumeNum, int remainingItems) : base($"Required {consumeNum} items of UID {itemUId}, missing {remainingItems} items")
{
this.itemUId = itemUId;
this.consumeNum = consumeNum;
this.remainingItems = remainingItems;
}
}
}
19 changes: 1 addition & 18 deletions Arrowgene.Ddon.GameServer/GameStructure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,24 +132,7 @@ public static void CDataPawnInfo(CDataPawnInfo cDataPawnInfo, Pawn pawn)
cDataPawnInfo.JewelrySlotNum = pawn.JewelrySlotNum;
// TODO: Pawn CharacterItemSlotInfoList, CraftData
cDataPawnInfo.CharacterItemSlotInfoList = new List<CDataCharacterItemSlotInfo>();
cDataPawnInfo.CraftData = new CDataPawnCraftData() {
CraftExp = 391,
CraftRank = 4,
CraftRankLimit = 8,
CraftPoint = 0,
PawnCraftSkillList = new List<CDataPawnCraftSkill>() {
new CDataPawnCraftSkill() {Type = 1, Level = 0},
new CDataPawnCraftSkill() {Type = 2, Level = 3},
new CDataPawnCraftSkill() {Type = 3, Level = 0},
new CDataPawnCraftSkill() {Type = 4, Level = 0},
new CDataPawnCraftSkill() {Type = 5, Level = 0},
new CDataPawnCraftSkill() {Type = 6, Level = 0},
new CDataPawnCraftSkill() {Type = 7, Level = 0},
new CDataPawnCraftSkill() {Type = 8, Level = 0},
new CDataPawnCraftSkill() {Type = 9, Level = 0},
new CDataPawnCraftSkill() {Type = 10, Level = 0}
}
};
cDataPawnInfo.CraftData = pawn.CraftData;
cDataPawnInfo.PawnReactionList = pawn.PawnReactionList;
cDataPawnInfo.HideEquipHead = pawn.HideEquipHead;
cDataPawnInfo.HideEquipLantern = pawn.HideEquipLantern;
Expand Down
2 changes: 1 addition & 1 deletion Arrowgene.Ddon.GameServer/Handler/BazaarProceedsHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public override void Handle(GameClient client, StructurePacket<C2SBazaarProceeds

// UPDATE CHARACTER WALLET
CDataWalletPoint wallet = client.Character.WalletPointList.Where(wp => wp.Type == WalletType.Gold).Single();
wallet.Value = (uint) Math.Max(0, wallet.Value - totalPrice);
wallet.Value = (uint) Math.Max(0, (int)wallet.Value - totalPrice);
Database.UpdateWalletPoint(client.Character.CharacterId, wallet);
updateCharacterItemNtc.UpdateWalletList.Add(new CDataUpdateWalletPoint()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public override void Handle(GameClient client, IPacket packet)
res.CraftMyPawnList = client.Character.Pawns.Select(pawn => new CDataCraftPawnList()
{
PawnId = pawn.PawnId,
CraftExp = 2500,
CraftPoint = 10,
CraftRankLimit = 10
CraftExp = pawn.CraftData.CraftExp,
CraftPoint = pawn.CraftData.CraftPoint,
CraftRankLimit = pawn.CraftData.CraftRankLimit
}).ToList();
client.Send(res);
}
Expand Down
53 changes: 25 additions & 28 deletions Arrowgene.Ddon.GameServer/Handler/CraftStartCraftHandler.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
using System.Linq;
using Arrowgene.Ddon.GameServer.Characters;
using Arrowgene.Ddon.Server;
Expand All @@ -7,13 +8,19 @@
using Arrowgene.Ddon.Shared.Network;
using Arrowgene.Logging;
using System;
using System.Collections.Generic;

namespace Arrowgene.Ddon.GameServer.Handler
{
public class CraftStartCraftHandler : GameStructurePacketHandler<C2SCraftStartCraftReq>
{
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(CraftStartCraftHandler));


private static readonly List<StorageType> STORAGE_TYPES = new List<StorageType> {
StorageType.ItemBagConsumable, StorageType.ItemBagMaterial, StorageType.ItemBagEquipment, StorageType.ItemBagJob,
StorageType.StorageBoxNormal, StorageType.StorageBoxExpansion, StorageType.StorageChest
};

private readonly ItemManager _itemManager;

public CraftStartCraftHandler(DdonGameServer server) : base(server)
Expand Down Expand Up @@ -42,33 +49,13 @@ public override void Handle(GameClient client, StructurePacket<C2SCraftStartCraf
// Remove crafting materials
foreach (var craftMaterial in packet.Structure.CraftMaterialList)
{
int consumedItems = 0;

// Take first from item bag
CDataItemUpdateResult? craftMaterialBagUpdateResult = _itemManager.ConsumeItemByUId(Server, client.Character, StorageType.ItemBagMaterial, craftMaterial.ItemUId, craftMaterial.ItemNum);
if(craftMaterialBagUpdateResult != null)
try
{
updateCharacterItemNtc.UpdateItemList.Add(craftMaterialBagUpdateResult);
consumedItems += craftMaterialBagUpdateResult.UpdateItemNum;
}

// If there weren't enough items in the item bag, take from the storage box
if (craftMaterial.ItemNum + consumedItems > 0)
{
CDataItemUpdateResult? craftMaterialStorageUpdateResult = _itemManager.ConsumeItemByUId(Server, client.Character, StorageType.StorageBoxNormal, craftMaterial.ItemUId, craftMaterial.ItemNum);
if(craftMaterialStorageUpdateResult != null)
{
updateCharacterItemNtc.UpdateItemList.Add(craftMaterialStorageUpdateResult);
consumedItems += craftMaterialStorageUpdateResult.UpdateItemNum;
}
List<CDataItemUpdateResult> updateResults = _itemManager.ConsumeItemByUIdFromMultipleStorages(Server, client.Character, STORAGE_TYPES, craftMaterial.ItemUId, craftMaterial.ItemNum);
}

// TODO: GG storage box? Other storages?

if (craftMaterial.ItemNum + consumedItems != 0)
catch (NotEnoughItemsException e)
{
// TODO: Rollback transaction
Logger.Error("Consumed "+consumedItems+" items of UID "+craftMaterial.ItemUId+" but the crafting recipe required "+craftMaterial.ItemNum);
Logger.Exception(e);
client.Send(new S2CCraftStartCraftRes()
{
Result = 1
Expand All @@ -79,19 +66,29 @@ public override void Handle(GameClient client, StructurePacket<C2SCraftStartCraf

// TODO: Refining material and all that stuff

// TODO: Calculate final craft price with the discounts from the craft pawns
uint finalCraftCost = recipe.Cost * packet.Structure.CreateCount;

// Temporary solution for craft price when setting a second pawn of rank 1
// TODO: Remove
if(packet.Structure.CraftSupportPawnIDList.Count > 0)
{
finalCraftCost = (uint)(finalCraftCost*0.95);
}

// Substract craft price
CDataWalletPoint wallet = client.Character.WalletPointList.Where(wp => wp.Type == WalletType.Gold).Single();
wallet.Value = Math.Max(0, wallet.Value - recipe.Cost);
wallet.Value = (uint)Math.Max(0, (int)wallet.Value - (int)finalCraftCost);
Database.UpdateWalletPoint(client.Character.CharacterId, wallet);
updateCharacterItemNtc.UpdateWalletList.Add(new CDataUpdateWalletPoint()
{
Type = WalletType.Gold,
AddPoint = (int) -recipe.Cost,
AddPoint = (int)-finalCraftCost,
Value = wallet.Value
});

// Add crafted items
CDataItemUpdateResult? itemUpdateResult = _itemManager.AddItem(Server, client.Character, false, recipe.ItemID, packet.Structure.CreateCount);
CDataItemUpdateResult? itemUpdateResult = _itemManager.AddItem(Server, client.Character, false, recipe.ItemID, packet.Structure.CreateCount * recipe.Num);
updateCharacterItemNtc.UpdateItemList.Add(itemUpdateResult);

client.Send(updateCharacterItemNtc);
Expand Down
2 changes: 1 addition & 1 deletion Arrowgene.Ddon.GameServer/Handler/InnStayInnHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public override void Handle(GameClient client, StructurePacket<C2SInnStayInnReq>

// Update character wallet
CDataWalletPoint wallet = client.Character.WalletPointList.Where(wp => wp.Type == priceWalletType).Single();
wallet.Value = Math.Max(0, wallet.Value - price);
wallet.Value = (uint) Math.Max(0, (int)wallet.Value - (int)price);
Database.UpdateWalletPoint(client.Character.CharacterId, wallet);

client.Send(new S2CInnStayInnRes()
Expand Down
2 changes: 1 addition & 1 deletion Arrowgene.Ddon.GameServer/Handler/InnStayPenaltyHealInn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public override void Handle(GameClient client, StructurePacket<C2SInnStayPenalty

// Update character wallet
CDataWalletPoint wallet = client.Character.WalletPointList.Where(wp => wp.Type == priceWalletType).Single();
wallet.Value = Math.Max(0, wallet.Value - price);
wallet.Value = (uint) Math.Max(0, (int)wallet.Value - (int)price);
Database.UpdateWalletPoint(client.Character.CharacterId, wallet);

client.Send(new S2CInnStayPenaltyHealInnRes()
Expand Down
4 changes: 2 additions & 2 deletions Arrowgene.Ddon.GameServer/Handler/PawnGetMyPawnListHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public override void Handle(GameClient client, StructurePacket<C2SPawnGetMypawnL
Job = pawn.Job,
Level = pawn.ActiveCharacterJobData.Lv,
// TODO: Fetch from DB
CraftRank = pcap.PawnList[0].PawnListData.CraftRank,
PawnCraftSkillList = pcap.PawnList[0].PawnListData.PawnCraftSkillList
CraftRank = pawn.CraftData.CraftRank,
PawnCraftSkillList = pawn.CraftData.PawnCraftSkillList
// TODO: CraftRank, PawnCraftSkillList, CommentSize, LatestReturnDate
}
// TODO: PawnState, ShareRange, Unk0, Unk1, Unk2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public override void Handle(GameClient client, StructurePacket<C2SShopBuyShopGoo

// UPDATE CHARACTER WALLET
CDataWalletPoint wallet = client.Character.WalletPointList.Where(wp => wp.Type == shop.WalletType).Single();
wallet.Value = Math.Max(0, wallet.Value - totalPrice);
wallet.Value = (uint) Math.Max(0, (int)wallet.Value - (int)totalPrice);
Database.UpdateWalletPoint(client.Character.CharacterId, wallet);

client.Send(new S2CItemUpdateCharacterItemNtc()
Expand Down
20 changes: 20 additions & 0 deletions Arrowgene.Ddon.Shared/Model/Pawn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ public Pawn()
OnlineStatus = OnlineStatus.None;
PawnReactionList = new List<CDataPawnReaction>();
SpSkillList = new List<CDataSpSkill>();
// TODO: Fetch from DB
CraftData = new CDataPawnCraftData() {
CraftExp = 0,
CraftRank = 0,
CraftRankLimit = 8,
CraftPoint = 0,
PawnCraftSkillList = new List<CDataPawnCraftSkill>() {
new CDataPawnCraftSkill() {Type = 1, Level = 0},
new CDataPawnCraftSkill() {Type = 2, Level = 0},
new CDataPawnCraftSkill() {Type = 3, Level = 0},
new CDataPawnCraftSkill() {Type = 4, Level = 0},
new CDataPawnCraftSkill() {Type = 5, Level = 0},
new CDataPawnCraftSkill() {Type = 6, Level = 0},
new CDataPawnCraftSkill() {Type = 7, Level = 0},
new CDataPawnCraftSkill() {Type = 8, Level = 0},
new CDataPawnCraftSkill() {Type = 9, Level = 0},
new CDataPawnCraftSkill() {Type = 10, Level = 0}
}
};
}

public Pawn(uint ownerCharacterId):this()
Expand All @@ -35,5 +54,6 @@ public Pawn(uint ownerCharacterId):this()

public List<CDataPawnReaction> PawnReactionList { get; set; }
public List<CDataSpSkill> SpSkillList { get; set; }
public CDataPawnCraftData CraftData { get; set; }
}
}
4 changes: 2 additions & 2 deletions Arrowgene.Ddon.Shared/Model/Storages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ public enum StorageType : byte
ItemBagJob = 0x4,
Unk5 = 0x5,
StorageBoxNormal = 0x6,
Unk7 = 0x7,
Unk8 = 0x8,
StorageBoxExpansion = 0x7,
StorageChest = 0x8, // The one in the Arisen Room
Unk9 = 0x9,
Unk10 = 0xA,
Unk11 = 0xB,
Expand Down
Loading