Skip to content

Commit

Permalink
[Core][Inventory] Initial implementation of the inventory system. #1
Browse files Browse the repository at this point in the history
  • Loading branch information
Rawaho committed Jul 31, 2017
1 parent b3ce405 commit 7a47c26
Show file tree
Hide file tree
Showing 49 changed files with 1,257 additions and 43 deletions.
17 changes: 9 additions & 8 deletions source/Shared/Database/Datacentre/CharacterAppearanceInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
using System.Data;
using System.Linq;
using Newtonsoft.Json.Linq;
using Shared.Game.Enum;

namespace Shared.Database.Datacentre
{
public struct CharacterAppearanceInfo
{
public byte Race
public Race Race
{
get => Data[0];
private set => Data[0] = value;
get => (Race)Data[0];
private set => Data[0] = (byte)value;
}

public byte Sex
public Sex Sex
{
get => Data[1];
private set => Data[1] = value;
get => (Sex)Data[1];
private set => Data[1] = (byte)value;
}

public byte Height
Expand Down Expand Up @@ -162,8 +163,8 @@ public CharacterAppearanceInfo(JArray array)
public CharacterAppearanceInfo(DataRow row)
{
Data = new byte[26];
Race = row.Read<byte>("race");
Sex = row.Read<byte>("sex");
Race = row.Read<Race>("race");
Sex = row.Read<Sex>("sex");
Height = row.Read<byte>("height");
Clan = row.Read<byte>("clan");
Face = row.Read<byte>("face");
Expand Down
8 changes: 8 additions & 0 deletions source/Shared/Game/Enum/Sex.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Shared.Game.Enum
{
public enum Sex : byte
{
Male,
Female
}
}
20 changes: 18 additions & 2 deletions source/Shared/Game/QueuedCounter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,25 @@ public class QueuedCounter<T> where T : IConvertible
{
private T counter;
private readonly Queue<T> queuedValues = new Queue<T>();
private readonly object mutex;

public QueuedCounter(T counter)
public QueuedCounter(T counter, bool concurrent = false)
{
this.counter = counter;
if (concurrent)
mutex = new object();
}

public T DequeueValue()
{
if (mutex == null)
return _DequeueValue();

lock (mutex)
return _DequeueValue();
}

private T _DequeueValue()
{
if (queuedValues.Count > 0)
return queuedValues.Dequeue();
Expand All @@ -24,7 +36,11 @@ public T DequeueValue()

public void EnqueueValue(T value)
{
queuedValues.Enqueue(value);
if (mutex != null)
lock (mutex)
queuedValues.Enqueue(value);
else
queuedValues.Enqueue(value);
}
}
}
9 changes: 8 additions & 1 deletion source/Shared/Network/SubPacketOpcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public enum SubPacketOpcode : ushort
ClientGmCommandInt = 0x010C,
ClientGmCommandString = 0x010D,
ClientPlayerMove = 0x010F,

ClientInventoryAction = 0x0116,

// server->client
ServerError = 0x0002,
ServerServiceAccountList = 0x000C,
Expand All @@ -32,6 +33,12 @@ public enum SubPacketOpcode : ushort
ServerPlayerSetup = 0x011E,
ServerPlayerStateFlags = 0x0121,
ServerClassSetup = 0x0123,
ServerActorAppearanceUpdate = 0x0124,
ServerItemSetup = 0x0139,
ServerContainerSetup = 0x013A,
ServerInventoryUpdateFinish = 0x013B,
ServerInventoryUpdate = 0x013C,
ServerItemUpdate = 0x0140,
// all 3 invoke the same client function just with different parameters
ServerActorAction1 = 0x0142,
ServerActorAction2 = 0x0143,
Expand Down
3 changes: 3 additions & 0 deletions source/Shared/Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
<Compile Include="Game\Enum\ClassJob.cs" />
<Compile Include="Game\Enum\Expansion.cs" />
<Compile Include="Game\Enum\Race.cs" />
<Compile Include="Game\Enum\Sex.cs" />
<Compile Include="Game\QueuedCounter.cs" />
<Compile Include="Game\SecurityLevel.cs" />
<Compile Include="Game\WorldPosition.cs" />
Expand Down Expand Up @@ -125,7 +126,9 @@
<Compile Include="SqPack\Exh.cs" />
<Compile Include="SqPack\GameTableManager.cs" />
<Compile Include="SqPack\GameTable\ClassJobEntry.cs" />
<Compile Include="SqPack\GameTable\EquipSlotCategoryEntry.cs" />
<Compile Include="SqPack\GameTable\ItemEntry.cs" />
<Compile Include="SqPack\GameTable\ItemUiCategoryEntry.cs" />
<Compile Include="SqPack\GameTable\PlaceNameEntry.cs" />
<Compile Include="SqPack\GameTable\RaceEntry.cs" />
<Compile Include="SqPack\GameTable\TerritoryTypeEntry.cs" />
Expand Down
7 changes: 7 additions & 0 deletions source/Shared/SqPack/BinaryReaderBigEndian.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ public uint ReadUInt32Be()
return BitConverter.ToUInt32(data, 0);
}

public ulong ReadUInt64Be()
{
byte[] data = ReadBytes(8);
Array.Reverse(data);
return BitConverter.ToUInt64(data, 0);
}

public string ReadExdString()
{
var sb = new StringBuilder();
Expand Down
5 changes: 2 additions & 3 deletions source/Shared/SqPack/Exd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ public class Entry
case ExdDataType.UInt:
entry.Data[i] = reader.ReadUInt32Be();
break;
case ExdDataType.Packed:
reader.ReadUInt32Be();
reader.ReadUInt32Be();
case ExdDataType.ULong:
entry.Data[i] = reader.ReadUInt64Be();
break;
default:
Debug.Assert(false, $"Unhandled EXD data type {header.Columns[i].Type}");
Expand Down
2 changes: 1 addition & 1 deletion source/Shared/SqPack/ExdDataType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ public enum ExdDataType
Int = 6,
UInt = 7,
Float = 9,
Packed = 11
ULong = 11
}
}
2 changes: 2 additions & 0 deletions source/Shared/SqPack/ExdTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Shared.SqPack
{
public class ExdTable<T> where T : Exd.Entry, new()
{
public int Count => entries.FirstOrDefault().Value.Count;

private readonly Dictionary<ExdLanguage, Dictionary<uint, T>> entries = new Dictionary<ExdLanguage, Dictionary<uint, T>>();

public ExdTable(Exh header)
Expand Down
1 change: 1 addition & 0 deletions source/Shared/SqPack/GameTable/ClassJobEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public class ClassJobEntry : Exd.Entry
public string Name => (string)Data[0];
public string Abbreviation => (string)Data[1];
public sbyte ClassId => (sbyte)Data[4];
public int WeaponItemId => (int)Data[28];
public byte CityState => (byte)Data[31];
}
}
14 changes: 14 additions & 0 deletions source/Shared/SqPack/GameTable/EquipSlotCategoryEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Collections.Generic;

namespace Shared.SqPack.GameTable
{
public class EquipSlotCategoryEntry : Exd.Entry
{
public IEnumerable<ushort> GetEquipSlots()
{
for (ushort i = 0; i < Data.Length; i++)
if ((sbyte)Data[i] == 1)
yield return i;
}
}
}
10 changes: 9 additions & 1 deletion source/Shared/SqPack/GameTable/ItemEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
{
public class ItemEntry : Exd.Entry
{

public string Name => (string)Data[0];
public string NamePlural => (string)Data[2];
public string Description => (string)Data[8];
public string ToolTipName => (string)Data[9];
public byte UiCategoryId => (byte)Data[15];
public byte EquipSlotCategoryId => (byte)Data[17];
public uint MaxStackCount => (uint)Data[19];
public ulong ModelPrimary => (ulong)Data[45];
public ulong ModelSecondary => (ulong)Data[46];
}
}
7 changes: 7 additions & 0 deletions source/Shared/SqPack/GameTable/ItemUiCategoryEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Shared.SqPack.GameTable
{
public class ItemUiCategoryEntry : Exd.Entry
{
public string Name => (string)Data[0];
}
}
17 changes: 12 additions & 5 deletions source/Shared/SqPack/GameTableManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@ namespace Shared.SqPack
public static class GameTableManager
{
public static ExdTable<ClassJobEntry> ClassJobs { get; private set; }
public static ExdTable<EquipSlotCategoryEntry> EquipSlotCategories { get; private set; }
public static ExdTable<ItemEntry> Items { get; private set; }
public static ExdTable<ItemUiCategoryEntry> ItemUiCategories { get; private set; }
public static ExdTable<PlaceNameEntry> PlaceNames { get; private set; }
public static ExdTable<RaceEntry> Races { get; private set; }
public static ExdTable<TerritoryTypeEntry> TerritoryTypes { get; private set; }

public static void Initialise()
{
ClassJobs = ExdTable<ClassJobEntry>.Load(@"data\\exd\\classjob.exh");
PlaceNames = ExdTable<PlaceNameEntry>.Load(@"data\\exd\\placename.exh");
Races = ExdTable<RaceEntry>.Load(@"data\\exd\\race.exh");
TerritoryTypes = ExdTable<TerritoryTypeEntry>.Load(@"data\\exd\\territorytype.exh");
string path = @"data\\exd\\";
ClassJobs = ExdTable<ClassJobEntry>.Load($"{path}classjob.exh");
EquipSlotCategories = ExdTable<EquipSlotCategoryEntry>.Load($"{path}equipslotcategory.exh");
Items = ExdTable<ItemEntry>.Load($"{path}item.exh");
ItemUiCategories = ExdTable<ItemUiCategoryEntry>.Load($"{path}itemuicategory.exh");
PlaceNames = ExdTable<PlaceNameEntry>.Load($"{path}placename.exh");
Races = ExdTable<RaceEntry>.Load($"{path}race.exh");
TerritoryTypes = ExdTable<TerritoryTypeEntry>.Load($"{path}territorytype.exh");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using WorldServer.Game.Map;
using WorldServer.Network.Message;

namespace WorldServer.Game
namespace WorldServer.Game.Entity
{
public abstract class Actor
{
Expand Down
91 changes: 91 additions & 0 deletions source/WorldServer/Game/Entity/Container.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace WorldServer.Game.Entity
{
public class Container
{
public ContainerType ContainerType { get; }
public ushort Count => (ushort)items.Count(i => i != null);

private readonly List<Item> items;

public Container(ContainerType containerType, ushort capacity)
{
ContainerType = containerType;
items = new List<Item>(new Item[capacity]);
}

/// <summary>
/// Find all item instances and their current slot by item id.
/// </summary>
public IEnumerable<(ushort Slot, Item Item)> GetItems(uint itemId)
{
for (ushort i = 0; i < items.Count; i++)
if (items[i]?.Template.Index == itemId)
yield return (i, items[i]);
}

/// <summary>
/// Find a single item instance by Guid.
/// </summary>
public Item GetItem(ulong guid)
{
return items.SingleOrDefault(i => i != null && i.Guid == guid);
}

/// <summary>
/// Find a single item instance by container slot.
/// </summary>
public Item GetItem(ushort slot)
{
if (slot >= items.Count)
throw new ArgumentException($"Invalid slot {slot}!");
return items[slot];
}

public ushort GetFirstAvailableSlot()
{
for (ushort i = 0; i < items.Count; i++)
if (items[i] == null)
return i;

return ushort.MaxValue;
}

public void AddItem(Item item, ushort slot, bool update = false)
{
Debug.Assert(item != null);
Debug.Assert(slot < items.Count);
items[slot] = item;

#if DEBUG
Console.WriteLine($"Adding item {item.Template.Index} to container: {ContainerType}, slot: {slot}");
#endif

item.UpdatePosition(ContainerType, slot, update);
}

public void RemoveItem(Item item)
{
Debug.Assert(item != null);
items[item.Slot] = null;

#if DEBUG
Console.WriteLine($"Removing item {item.Template.Index} from container: {ContainerType}, slot: {item.Slot}");
#endif

item.UpdatePosition(ContainerType.None, ushort.MaxValue);
}

/// <summary>
/// Send container item instance information to client, only sent on login.
/// </summary>
public void SendItemSetup(uint index)
{
items.ForEach(i => i?.SendSetup(index));
}
}
}
20 changes: 20 additions & 0 deletions source/WorldServer/Game/Entity/ContainerEquippedSlot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace WorldServer.Game.Entity
{
public enum ContainerEquippedSlot : byte
{
MainHand,
OffHand,
Head,
Body,
Hands,
Waist,
Legs,
Feet,
Ears,
Neck,
Wrists,
RightRing,
LeftRing,
SoulCrystal
}
}
Loading

0 comments on commit 7a47c26

Please sign in to comment.