diff --git a/GameServer/GameServer.csproj b/GameServer/GameServer.csproj
index b95dc8907..6e9e3e1f4 100644
--- a/GameServer/GameServer.csproj
+++ b/GameServer/GameServer.csproj
@@ -98,8 +98,7 @@
-
-
+
diff --git a/GameServer/Logic/ChampionFactory.cs b/GameServer/Logic/ChampionFactory.cs
index 9ab7161f0..573330f34 100644
--- a/GameServer/Logic/ChampionFactory.cs
+++ b/GameServer/Logic/ChampionFactory.cs
@@ -1,4 +1,5 @@
-using LeagueSandbox.GameServer.Logic.GameObjects;
+using LeagueSandbox.GameServer.Core.Logic;
+using LeagueSandbox.GameServer.Logic.GameObjects;
using LeagueSandbox.GameServer.Logic.Maps;
using System;
using System.Collections.Generic;
@@ -10,9 +11,9 @@ namespace LeagueSandbox.GameServer.Logic
{
class ChampionFactory
{
- public static Champion getChampionFromType(string type, Map map, uint id, uint playerId)
+ public static Champion getChampionFromType(Game game, string type, Map map, uint id, uint playerId)
{
- return new Champion(type, map, id, playerId);
+ return new Champion(game, type, map, id, playerId);
}
}
}
diff --git a/GameServer/Logic/Content/ItemCollection.cs b/GameServer/Logic/Content/ItemCollection.cs
index a06c69b63..ba90c6771 100644
--- a/GameServer/Logic/Content/ItemCollection.cs
+++ b/GameServer/Logic/Content/ItemCollection.cs
@@ -1,4 +1,5 @@
-using Newtonsoft.Json;
+using LeagueSandbox.GameServer.Core.Logic;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
@@ -8,43 +9,79 @@
namespace LeagueSandbox.GameServer.Logic.Content
{
- public class ContentCollection
+ public class ContentCollectionEntry
{
- public class ContentCollectionEntry
+ public Dictionary> Values { get; set; }
+ public Dictionary MetaData { get; set; }
+
+ public int ContentFormatVersion { get { return Convert.ToInt32(MetaData["ContentFormatVersion"]); } }
+
+ public T GetValue(string section, string name)
{
- public Dictionary> Values { get; set; }
- public Dictionary MetaData { get; set; }
+ return (T)Convert.ChangeType(Values[section][name], typeof(T));
+ }
- public int ContentFormatVersion { get { return Convert.ToInt32(MetaData["ContentFormatVersion"]); } }
+ public T SafeGetValue(string section, string name, T defaultValue)
+ {
+ if (!Values.ContainsKey(section)) return defaultValue;
+ if (!Values[section].ContainsKey(name)) return defaultValue;
+ return GetValue(section, name);
+ }
- public T GetValue(string section, string name)
- {
- return (T)Convert.ChangeType(Values[section][name], typeof(T));
- }
+ public float SafeGetFloat(string section, string name, float defaultValue)
+ {
+ return SafeGetValue(section, name, defaultValue);
+ }
- public T SafeGetValue(string section, string name, T defaultValue)
- {
- if (!Values.ContainsKey(section)) return LogSkipAndReturn(section, name, defaultValue);
- if (!Values[section].ContainsKey(name)) return LogSkipAndReturn(section, name, defaultValue);
- return GetValue(section, name);
- }
+ public float SafeGetFloat(string section, string name)
+ {
+ return SafeGetFloat(section, name, 0f);
+ }
- private T LogSkipAndReturn(string section, string name, T value)
- {
- return value;
- }
+ public int SafeGetInt(string section, string name, int defaultValue)
+ {
+ return SafeGetValue(section, name, defaultValue);
}
- }
- public class ItemCollection : ContentCollection
- {
- public class ItemCollectionEntry : ContentCollectionEntry
+ public int SafeGetInt(string section, string name)
+ {
+ return SafeGetInt(section, name, 0);
+ }
+
+ public string SafeGetString(string section, string name, string defaultValue)
+ {
+ return SafeGetValue(section, name, defaultValue);
+ }
+
+ public string SafeGetString(string section, string name)
{
- public string ItemFileName { get { return Convert.ToString(MetaData["ItemFileName"]); } }
- public string ItemName { get { return Convert.ToString(MetaData["ItemName"]); } }
- public int ItemId { get { return Convert.ToInt32(MetaData["ItemId"]); } }
+ return SafeGetString(section, name, "");
}
+ public bool SafeGetBool(string section, string name, bool defaultValue)
+ {
+ return SafeGetValue(section, name, defaultValue);
+ }
+
+ public bool SafeGetBool(string section, string name)
+ {
+ return SafeGetBool(section, name, false);
+ }
+ }
+
+ public class ContentCollection
+ {
+ }
+
+ public class ItemCollectionEntry : ContentCollectionEntry
+ {
+ public string ItemFileName { get { return Convert.ToString(MetaData["ItemFileName"]); } }
+ public string ItemName { get { return Convert.ToString(MetaData["ItemName"]); } }
+ public int ItemId { get { return Convert.ToInt32(MetaData["ItemId"]); } }
+ }
+
+ public class ItemCollection : ContentCollection
+ {
private Dictionary _items;
public Dictionary.Enumerator GetEnumerator() { return _items.GetEnumerator(); }
diff --git a/GameServer/Logic/Content/ItemManager.cs b/GameServer/Logic/Content/ItemManager.cs
new file mode 100644
index 000000000..dc3df782c
--- /dev/null
+++ b/GameServer/Logic/Content/ItemManager.cs
@@ -0,0 +1,249 @@
+using LeagueSandbox.GameServer.Core.Logic;
+using LeagueSandbox.GameServer.Logic.GameObjects;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using LeagueSandbox.GameServer.Logic.Items;
+using LeagueSandbox.GameServer.Core.Logic.PacketHandlers;
+
+namespace LeagueSandbox.GameServer.Logic.Content
+{
+ public class ItemManager
+ {
+ private Game _owner;
+ private Dictionary _itemTypes;
+
+ private ItemManager(Game owner)
+ {
+ _owner = owner;
+ _itemTypes = new Dictionary();
+ }
+
+ public ItemType GetItemType(int itemId)
+ {
+ return _itemTypes[itemId];
+ }
+
+ public ItemType SafeGetItemType(int itemId, ItemType defaultValue)
+ {
+ if (!_itemTypes.ContainsKey(itemId)) return defaultValue;
+ return _itemTypes[itemId];
+ }
+
+ public ItemType SafeGetItemType(int itemId)
+ {
+ return SafeGetItemType(itemId, null);
+ }
+
+ public static ItemManager LoadItems(Game game)
+ {
+ var result = new ItemManager(game);
+ var itemCollection = ItemCollection.LoadItemsFrom("Content/Data/LeagueSandbox-Default/Items");
+ foreach(var entry in itemCollection)
+ {
+ var itemType = ItemType.Load(game, result, entry.Value);
+ result._itemTypes.Add(entry.Key, itemType);
+ }
+ return result;
+ }
+ }
+
+ public class ItemType
+ {
+ private Game _game;
+ private ItemManager _owner;
+ private ItemCollectionEntry _itemInfo;
+ private StatMod[] _statMods;
+ private int _totalPrice;
+
+ // Meta
+ public int ItemId { get; private set; }
+ public string Name { get; private set; }
+
+ // General
+ public int MaxStack { get; private set; }
+ public int Price { get; private set; }
+ public string ItemGroup { get; private set; }
+ public float SellBackModifier { get; private set; }
+
+ // Stats
+ public float FlatPhysicalDamageMod { get; private set; }
+ public float PercentPhysicalDamageMod { get; private set; }
+ public float FlatMagicDamageMod { get; private set; }
+ public float FlatHPRegenMod { get; private set; }
+ public float FlatCritChanceMod { get; private set; }
+ public float FlatArmorMod { get; private set; }
+ public float FlatSpellBlockMod { get; private set; }
+ public float PercentAttackSpeedMod { get; private set; }
+ public float PercentLifeStealMod { get; private set; }
+ public float FlatHPPoolMod { get; private set; }
+ public float FlatMPPoolMod { get; private set; }
+ public float FlatMovementSpeedMod { get; private set; }
+
+ // Recipes
+ public int RecipeItem1 { get; private set; }
+ public int RecipeItem2 { get; private set; }
+ public int RecipeItem3 { get; private set; }
+ public int RecipeItem4 { get; private set; }
+
+ // Not from data
+ public ItemRecipe Recipe { get; private set; }
+ public int TotalPrice { get { return Recipe.TotalPrice; } }
+ public List StatMods { get { if (_statMods == null) CreateStatMods(); return _statMods.ToList(); } }
+
+ private ItemType(Game game, ItemManager owner, ItemCollectionEntry itemInfo)
+ {
+ _game = game;
+ _owner = owner;
+ _itemInfo = itemInfo;
+ _totalPrice = -1;
+ }
+
+ public void CreateStatMods()
+ {
+ _statMods = new StatMod[]
+ {
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Bonus_Ad_Flat, FlatPhysicalDamageMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Bonus_Ad_Pct, PercentPhysicalDamageMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Bonus_Ap_Flat, FlatMagicDamageMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Hp5, FlatHPRegenMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Crit_Chance, FlatCritChanceMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Armor, FlatArmorMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Magic_Armor, FlatSpellBlockMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_Atks_multiplier, PercentAttackSpeedMod),
+ StatMod.FromValues(MasterMask.MM_Two, FieldMask.FM2_LifeSteal, PercentLifeStealMod),
+ StatMod.FromValues(MasterMask.MM_Four, FieldMask.FM4_MaxHp, FlatHPPoolMod),
+ StatMod.FromValues(MasterMask.MM_Four, FieldMask.FM4_MaxMp, FlatMPPoolMod),
+ StatMod.FromValues(MasterMask.MM_Four, FieldMask.FM4_Speed, FlatMovementSpeedMod)
+ };
+ }
+
+ private void CreateRecipe()
+ {
+ Recipe = ItemRecipe.FromItemType(_game, this);
+ }
+
+ public static ItemType Load(Game game, ItemManager owner, ItemCollectionEntry itemInfo)
+ {
+ // Because IntelliSense is nice to have
+ var result = new ItemType(game, owner, itemInfo)
+ {
+ ItemId = itemInfo.ItemId,
+ Name = itemInfo.ItemName,
+ MaxStack = itemInfo.SafeGetInt("Data", "MaxStack"),
+ Price = itemInfo.SafeGetInt("Data", "Price"),
+ ItemGroup = itemInfo.SafeGetString("Data", "ItemGroup"),
+ SellBackModifier = itemInfo.SafeGetFloat("Data", "SellBackModifier", 0.7f),
+ FlatPhysicalDamageMod = itemInfo.SafeGetFloat("Data", "FlatPhysicalDamageMod"),
+ PercentPhysicalDamageMod = itemInfo.SafeGetFloat("Data", "PercentPhysicalDamageMod"),
+ FlatMagicDamageMod = itemInfo.SafeGetFloat("Data", "FlatMagicDamageMod"),
+ FlatHPRegenMod = itemInfo.SafeGetFloat("Data", "FlatHPRegenMod"),
+ FlatCritChanceMod = itemInfo.SafeGetFloat("Data", "FlatCritChanceMod"),
+ FlatArmorMod = itemInfo.SafeGetFloat("Data", "FlatArmorMod"),
+ FlatSpellBlockMod = itemInfo.SafeGetFloat("Data", "FlatSpellBlockMod"),
+ PercentAttackSpeedMod = itemInfo.SafeGetFloat("Data", "PercentAttackSpeedMod"),
+ PercentLifeStealMod = itemInfo.SafeGetFloat("Data", "PercentLifeStealMod"),
+ FlatHPPoolMod = itemInfo.SafeGetFloat("Data", "FlatHPPoolMod"),
+ FlatMPPoolMod = itemInfo.SafeGetFloat("Data", "FlatMPPoolMod"),
+ FlatMovementSpeedMod = itemInfo.SafeGetFloat("Data", "FlatMovementSpeedMod"),
+ RecipeItem1 = itemInfo.SafeGetInt("Data", "RecipeItem1", -1),
+ RecipeItem2 = itemInfo.SafeGetInt("Data", "RecipeItem2", -1),
+ RecipeItem3 = itemInfo.SafeGetInt("Data", "RecipeItem3", -1),
+ RecipeItem4 = itemInfo.SafeGetInt("Data", "RecipeItem4", -1)
+ };
+ result.CreateRecipe();
+ return result;
+ }
+
+ public bool GetIsTrinket()
+ {
+ return ItemGroup.ToLower() == "relicbase";
+ }
+ }
+
+ public class ItemRecipe
+ {
+ private Game _game;
+ private ItemType _owner;
+ private ItemType[] _items;
+ private int _totalPrice;
+
+ public List Items { get { if (_items == null) FindRecipeItems(); return _items.ToList(); } }
+ public int TotalPrice { get { if (_totalPrice < -1) FindPrice(); return _totalPrice; } }
+
+ private ItemRecipe(Game game, ItemType owner)
+ {
+ _game = game;
+ _owner = owner;
+ _totalPrice = -1;
+ }
+
+ private void FindRecipeItems()
+ {
+ _items = new ItemType[]
+ {
+ _game.ItemManager.SafeGetItemType(_owner.RecipeItem1),
+ _game.ItemManager.SafeGetItemType(_owner.RecipeItem2),
+ _game.ItemManager.SafeGetItemType(_owner.RecipeItem3),
+ _game.ItemManager.SafeGetItemType(_owner.RecipeItem4)
+ };
+ }
+
+ private void FindPrice()
+ {
+ _totalPrice = 0;
+ foreach (var item in Items)
+ {
+ _totalPrice += item.TotalPrice;
+ }
+ _totalPrice += _owner.Price;;
+ }
+
+ public static ItemRecipe FromItemType(Game game, ItemType type)
+ {
+ return new ItemRecipe(game, type);
+ }
+ }
+
+ public class Item
+ {
+ public byte Slot { get; private set; }
+ public byte StackSize { get; private set; }
+ public int TotalPrice { get; private set; }
+ public ItemType ItemType { get; private set; }
+
+ private Game _game;
+ private Inventory _owner;
+
+ private Item(Game game, Inventory owner, ItemType type, byte slot)
+ {
+ _game = game;
+ _owner = owner;
+ ItemType = type;
+ StackSize = 1;
+ Slot = slot;
+ }
+
+ public bool IncrementStackSize()
+ {
+ if (StackSize >= ItemType.MaxStack) return false;
+ StackSize++;
+ return true;
+ }
+
+ public bool DecrementStackSize()
+ {
+ if (StackSize <= 1) return false;
+ StackSize--;
+ return true;
+ }
+
+ internal static Item CreateFromType(Game _game, Inventory inventory, ItemType item, byte slot)
+ {
+ return new Item(_game, inventory, item, slot);
+ }
+ }
+}
diff --git a/GameServer/Logic/Game.cs b/GameServer/Logic/Game.cs
index dc55fc2a6..0b82474b3 100644
--- a/GameServer/Logic/Game.cs
+++ b/GameServer/Logic/Game.cs
@@ -16,6 +16,7 @@
using BlowFishCS;
using static ENet.Native;
using System.Threading;
+using LeagueSandbox.GameServer.Logic.Content;
namespace LeagueSandbox.GameServer.Core.Logic
{
@@ -37,8 +38,12 @@ public unsafe class Game
private const PacketFlags UNRELIABLE = PacketFlags.None;
private const double REFRESH_RATE = 16.666; // 60 fps
+ // Object managers
+ public ItemManager ItemManager { get; protected set; }
+
public bool initialize(ENetAddress address, string baseKey)
{
+ ItemManager = ItemManager.LoadItems(this);
if (enet_initialize() < 0)
return false;
@@ -76,7 +81,7 @@ public bool initialize(ENetAddress address, string baseKey)
player.setSummoners(strToId(p.Value.summoner1), strToId(p.Value.summoner2));
- Champion c = ChampionFactory.getChampionFromType(p.Value.champion, map, GetNewNetID(), (uint)player.userId);
+ Champion c = ChampionFactory.getChampionFromType(this, p.Value.champion, map, GetNewNetID(), (uint)player.userId);
var pos = c.getRespawnPosition();
c.setPosition(pos.Item1, pos.Item2);
diff --git a/GameServer/Logic/GameObjects/Champion.cs b/GameServer/Logic/GameObjects/Champion.cs
index 1d11024e6..de0d74c54 100644
--- a/GameServer/Logic/GameObjects/Champion.cs
+++ b/GameServer/Logic/GameObjects/Champion.cs
@@ -31,12 +31,12 @@ public Spell getSpell(int index)
{
return spells[index];
}
- public Champion(string type, Map map, uint id, uint playerId) : base(map, id, type, new Stats(), 30, 0, 0, 1200)
+ public Champion(Game game, string type, Map map, uint id, uint playerId) : base(map, id, type, new Stats(), 30, 0, 0, 1200)
{
this.type = type;
this.playerId = playerId;
- Inventory = InventoryManager.CreateInventory(this);
+ Inventory = InventoryManager.CreateInventory(game, this);
Shop = Shop.CreateShop(this);
stats.setGold(475.0f);
diff --git a/GameServer/Logic/GameObjects/Stats.cs b/GameServer/Logic/GameObjects/Stats.cs
index 24a63d99d..01198491c 100644
--- a/GameServer/Logic/GameObjects/Stats.cs
+++ b/GameServer/Logic/GameObjects/Stats.cs
@@ -53,9 +53,19 @@ public enum FieldMask : uint
public class StatMod
{
- public MasterMask blockId;
- public FieldMask mask;
- public float value;
+ public MasterMask BlockId { get; set; }
+ public FieldMask Mask { get; set; }
+ public float Value { get; set; }
+
+ public static StatMod FromValues(MasterMask blockId, FieldMask mask, float value)
+ {
+ return new StatMod()
+ {
+ BlockId = blockId,
+ Mask = mask,
+ Value = value
+ };
+ }
}
public class Stats
@@ -249,24 +259,24 @@ public void levelUp()
setMp5(getMana5() + mp5RegenPerLevel);
}
- public void applyStatMods(List statMods)
+ public void applyStatMods(IEnumerable statMods)
{
foreach (var stat in statMods)
{
- if (stat.value == 0)
+ if (stat.Value == 0)
continue;
- setStat(stat.blockId, stat.mask, getStat(stat.blockId, stat.mask) + stat.value);
+ setStat(stat.BlockId, stat.Mask, getStat(stat.BlockId, stat.Mask) + stat.Value);
}
}
public void unapplyStatMods(List statMods)
{
foreach (var stat in statMods)
{
- if (stat.value == 0)
+ if (stat.Value == 0)
continue;
- setStat(stat.blockId, stat.mask, getStat(stat.blockId, stat.mask) - stat.value);
+ setStat(stat.BlockId, stat.Mask, getStat(stat.BlockId, stat.Mask) - stat.Value);
}
}
diff --git a/GameServer/Logic/Items/Inventory.cs b/GameServer/Logic/Items/Inventory.cs
index 73329bd02..aba2df571 100644
--- a/GameServer/Logic/Items/Inventory.cs
+++ b/GameServer/Logic/Items/Inventory.cs
@@ -1,4 +1,6 @@
-using LeagueSandbox.GameServer.Logic.GameObjects;
+using LeagueSandbox.GameServer.Core.Logic;
+using LeagueSandbox.GameServer.Logic.Content;
+using LeagueSandbox.GameServer.Logic.GameObjects;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -10,28 +12,34 @@ namespace LeagueSandbox.GameServer.Logic.Items
public class Inventory
{
private const int TRINKET_SLOT = 6;
- private ItemInstance[] _items;
+ private Item[] _items;
+ private InventoryManager _owner;
+ private Game _game;
- public Inventory()
+ public Item[] Items { get { return _items; } }
+
+ public Inventory(Game game, InventoryManager owner)
{
- _items = new ItemInstance[7];
+ _game = game;
+ _owner = owner;
+ _items = new Item[7];
}
- public ItemInstance AddItem(ItemInstance item)
+ public Item AddItem(ItemType item)
{
- if(item.IsTrinket) return AddTrinketItem(item);
- if (item.MaximumStackSize > 1) return AddStackingItem(item);
+ if(item.GetIsTrinket()) return AddTrinketItem(item);
+ if (item.MaxStack > 1) return AddStackingItem(item);
return AddNewItem(item);
}
- public ItemInstance SetItem(int slot, ItemInstance item)
+ public Item SetItem(byte slot, ItemType item)
{
if (slot > _items.Length) return null;
- _items[slot] = item;
- return item;
+ _items[slot] = Item.CreateFromType(_game, this, item, slot);
+ return _items[slot];
}
- public ItemInstance GetItem(int slot)
+ public Item GetItem(int slot)
{
return _items[slot];
}
@@ -48,163 +56,33 @@ public void SwapItems(int slot1, int slot2)
_items[slot2] = buffer;
}
- private ItemInstance AddTrinketItem(ItemInstance item)
+ private Item AddTrinketItem(ItemType item)
{
if (_items[TRINKET_SLOT] != null) return null;
return SetItem(TRINKET_SLOT, item);
}
- private ItemInstance AddStackingItem(ItemInstance item)
+ private Item AddStackingItem(ItemType item)
{
for(var i = 0; i < _items.Length; i++)
{
if (_items[i] == null) continue;
- if (item.Id != _items[i].Id) continue;
- return _items[i].IncrementCount();
+ if (item.ItemId != _items[i].ItemType.ItemId) continue;
+ if (_items[i].IncrementStackSize()) return _items[i];
+ return null;
}
return AddNewItem(item);
}
- private ItemInstance AddNewItem(ItemInstance item)
+ private Item AddNewItem(ItemType item)
{
for(var i = 0; i < _items.Length; i++)
{
if (i == TRINKET_SLOT) continue;
if (_items[i] != null) continue;
- return SetItem(i, item);
+ return SetItem((byte)i, item);
}
return null;
}
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Shitty methods pasted for compatibility //
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
- private List _getAvailableRecipeParts(ItemTemplate recipe)
- {
- var toReturn = new List();
-
- foreach (var i in _items)
- {
- if (i == null)
- continue;
-
- if (i.getTemplate().getId() == recipe.getId() && !i.getRecipeSearchFlag())
- {
- toReturn.Add(i);
- i.setRecipeSearchFlag(true);
- return toReturn;
- }
- }
-
- foreach (var itemId in recipe.getRecipeParts())
- {
- var parts = _getAvailableRecipeParts(ItemManager.getInstance().getItemTemplateById(itemId));
- toReturn.AddRange(parts);
- }
-
- return toReturn;
- }
- public List getAvailableRecipeParts(ItemTemplate recipe)
- {
- var toReturn = new List();
-
- foreach (var itemId in recipe.getRecipeParts())
- {
- var item = ItemManager.getInstance().getItemTemplateById(itemId);
- if (item == null)
- continue;
-
- var parts = _getAvailableRecipeParts(item);
- toReturn.AddRange(parts);
- }
-
- foreach (var i in _items)
- if (i != null)
- i.setRecipeSearchFlag(false);
-
- return toReturn;
- }
- public ItemInstance addItem(ItemTemplate itemTemplate)
- {
- var slot = -1;
-
- if (itemTemplate.isTrinket())
- {
- if (_items[6] == null)
- {
- _items[6] = new ItemInstance(itemTemplate, 6, 1);
- return _items[6];
- }
- return null;
- }
-
- if (itemTemplate.getMaxStack() > 1)
- {
- for (slot = 0; slot < 6; ++slot)
- {
- if (_items[slot] == null)
- continue;
-
- if (_items[slot].getTemplate() == itemTemplate)
- {
- if (_items[slot].getStacks() < itemTemplate.getMaxStack())
- {
- _items[slot].incrementStacks();
- return _items[slot];
- }
- else if (_items[slot].getStacks() == itemTemplate.getMaxStack())
- {
- return null;
- }
- }
- }
- }
-
- for (slot = 0; slot < 6; ++slot)
- {
- if (_items[slot] == null)
- break;
- }
-
- if (slot == 6)
- { // Inventory full
- return null;
- }
-
- _items[slot] = new ItemInstance(itemTemplate, (byte)slot, 1);
-
- return _items[slot];
- }
}
-
- //public class Item
- //{
- // public bool IsTrinket { get; private set; }
- // public int MaximumStackSize { get; private set; }
- // public int StackSize { get; private set; }
- // public int Id { get; private set; }
- // public int TotalPrice { get; private set; }
-
- // private Item()
- // {
- // var inventory = new Inventory();
- // }
-
- // public Item IncrementCount()
- // {
- // if (StackSize >= MaximumStackSize) return null;
- // StackSize++;
- // return this;
- // }
-
- // public StatMod[] GetStatMods()
- // {
- // throw new Exception("Gtfo");
- // }
-
- // public static Item Instantiate(int id)
- // {
- // return new Item();
- // }
- //}
}
diff --git a/GameServer/Logic/Items/InventoryManager.cs b/GameServer/Logic/Items/InventoryManager.cs
index bf634503e..8cc1adf03 100644
--- a/GameServer/Logic/Items/InventoryManager.cs
+++ b/GameServer/Logic/Items/InventoryManager.cs
@@ -1,4 +1,6 @@
-using LeagueSandbox.GameServer.Logic.GameObjects;
+using LeagueSandbox.GameServer.Core.Logic;
+using LeagueSandbox.GameServer.Logic.Content;
+using LeagueSandbox.GameServer.Logic.GameObjects;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -12,18 +14,18 @@ public class InventoryManager
private Inventory _inventory;
private Champion _owner;
- private InventoryManager(Champion owner)
+ private InventoryManager(Game game, Champion owner)
{
_owner = owner;
- _inventory = new Inventory();
+ _inventory = new Inventory(game, this);
}
- public ItemInstance AddItem(ItemTemplate item)
+ public Item AddItem(ItemType item)
{
- return _inventory.addItem(item);
+ return _inventory.AddItem(item);
}
- public ItemInstance GetItem(int slot)
+ public Item GetItem(int slot)
{
return _inventory.GetItem(slot);
}
@@ -38,14 +40,22 @@ public void SwapItems(int slot1, int slot2)
_inventory.SwapItems(slot1, slot2);
}
- public ItemInstance[] GetAvailableRecipeParts(ItemTemplate item)
+ public List- GetAvailableItems(ItemRecipe recipe)
{
- return _inventory.getAvailableRecipeParts(item).ToArray();
+ var result = new List
- ();
+ foreach(var item in _inventory.Items)
+ {
+ if (item == null) continue;
+ if (!recipe.Items.Contains(item.ItemType)) continue;
+ if (result.Contains(item)) continue;
+ result.Add(item);
+ }
+ return result;
}
- public static InventoryManager CreateInventory(Champion owner)
+ public static InventoryManager CreateInventory(Game game, Champion owner)
{
- return new InventoryManager(owner);
+ return new InventoryManager(game, owner);
}
}
}
diff --git a/GameServer/Logic/Items/Item.cs b/GameServer/Logic/Items/Item.cs
deleted file mode 100644
index e1ca7996f..000000000
--- a/GameServer/Logic/Items/Item.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-using LeagueSandbox.GameServer.Logic.GameObjects;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LeagueSandbox.GameServer.Logic.Items
-{
- public class ItemTemplate
- {
- private int id;
- private int maxStack;
- private int price;
- private bool trinket;
- private float sellBackModifier;
- private List statMods;
-
- /**
- * Necessary item ids to create this one.
- */
- private List recipes;
-
- public ItemTemplate(int id, int maxStack, int price, float sellBackModifier, bool trinket, List statMods, List recipes)
- {
- this.id = id;
- this.maxStack = maxStack;
- this.price = price;
- this.sellBackModifier = sellBackModifier;
- this.trinket = trinket;
- this.statMods = statMods;
- this.recipes = recipes;
- }
-
- public int getId()
- {
- return id;
- }
- public int getMaxStack()
- {
- return maxStack;
- }
- public int getPrice()
- {
- return price;
- }
-
- /**
- * Returns the total price of an item. This will change for recipes, as they include their parts fees
- */
- public int getTotalPrice()
- {
- var toReturn = price;
-
- foreach (var itemId in recipes)
- {
- var item = ItemManager.getInstance().getItemTemplateById(itemId);
- if (item == null)
- continue;
- toReturn += item.getTotalPrice();
- }
- return toReturn;
- }
-
- public bool isTrinket()
- {
- return trinket;
- }
- public float getSellBackModifier()
- {
- return sellBackModifier;
- }
- public List getStatMods()
- {
- return statMods;
- }
-
- public bool isRecipe()
- {
- return recipes.Count > 0;
- }
-
- public List getRecipeParts()
- {
- return recipes;
- }
- }
-
- public class ItemInstance
- {
-
- private ItemTemplate itemTemplate;
- private byte slot, stacks;
- private float cooldown;
- private bool recipeSearchFlag;
-
- // Methods to make old code compatible with already refactored code
- public int Id { get { return itemTemplate.getId(); } }
- public bool IsTrinket { get { return itemTemplate.isTrinket(); } }
- public int MaximumStackSize { get { return itemTemplate.getMaxStack(); } }
- public ItemInstance IncrementCount()
- {
- incrementStacks();
- if (stacks >= itemTemplate.getMaxStack())
- {
- decrementStacks();
- return null;
- }
- return this;
- }
- // End compatibility methods
-
- public ItemInstance(ItemTemplate itemTemplate, byte slot = 0, byte stacks = 1)
- {
- this.itemTemplate = itemTemplate;
- this.cooldown = 0;
- this.slot = slot;
- this.stacks = stacks;
- this.recipeSearchFlag = false;
- }
-
- public ItemTemplate getTemplate()
- {
- return itemTemplate;
- }
-
- public byte getSlot()
- {
- return slot;
- }
-
- public byte getStacks()
- {
- return stacks;
- }
-
- public void incrementStacks()
- {
- ++stacks;
- }
-
- public void decrementStacks()
- {
- --stacks;
- }
-
- public bool getRecipeSearchFlag()
- {
- return recipeSearchFlag;
- }
-
- public void setRecipeSearchFlag(bool flag)
- {
- recipeSearchFlag = flag;
- }
- }
-}
diff --git a/GameServer/Logic/Items/ItemManager.cs b/GameServer/Logic/Items/ItemManager.cs
deleted file mode 100644
index 6e5ba750f..000000000
--- a/GameServer/Logic/Items/ItemManager.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using InibinSharp;
-using LeagueSandbox.GameServer.Core.Logic;
-using LeagueSandbox.GameServer.Core.Logic.PacketHandlers;
-using LeagueSandbox.GameServer.Core.Logic.RAF;
-using LeagueSandbox.GameServer.Logic.Content;
-using LeagueSandbox.GameServer.Logic.GameObjects;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LeagueSandbox.GameServer.Logic.Items
-{
- class ItemManager
- {
- private static ItemManager _instance;
-
- private Dictionary itemTemplates;
-
- public int GetItemPrice(int itemId)
- {
- throw new NotImplementedException("Fuck yo");
- }
-
- public void init()
- {
- itemTemplates = new Dictionary();
- var itemCollection = ItemCollection.LoadItemsFrom("Content/Data/LeagueSandbox-Default/Items");
- foreach(var itemEntry in itemCollection)
- {
- var itemData = itemEntry.Value;
-
-
- var maxStack = itemData.SafeGetValue("Data", "MaxStack", 0);
- var price = itemData.SafeGetValue("Data", "Price", 0);
-
- var itemGroup = itemData.SafeGetValue("Data", "ItemGroup", "");
- bool trinket = itemGroup.ToLower() == "relicbase";
-
- float sellBack = itemData.SafeGetValue("Data", "SellBackModifier", 0.7f);
-
- var statMods = new List();
-
- // "Another part that's just completely ass" - Mythic, 14th April 2016
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Bonus_Ad_Flat, value = itemData.SafeGetValue("Data", "FlatPhysicalDamageMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Bonus_Ad_Pct, value = itemData.SafeGetValue("Data", "PercentPhysicalDamageMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Bonus_Ap_Flat, value = itemData.SafeGetValue("Data", "FlatMagicDamageMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Hp5, value = itemData.SafeGetValue("Data", "FlatHPRegenMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Crit_Chance, value = itemData.SafeGetValue("Data", "FlatCritChanceMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Armor, value = itemData.SafeGetValue("Data", "FlatArmorMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Magic_Armor, value = itemData.SafeGetValue("Data", "FlatSpellBlockMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_Atks_multiplier, value = itemData.SafeGetValue("Data", "PercentAttackSpeedMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Two, mask = FieldMask.FM2_LifeSteal, value = itemData.SafeGetValue("Data", "PercentLifeStealMod", 0f) });
-
- statMods.Add(new StatMod { blockId = MasterMask.MM_Four, mask = FieldMask.FM4_MaxHp, value = itemData.SafeGetValue("Data", "FlatHPPoolMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Four, mask = FieldMask.FM4_MaxMp, value = itemData.SafeGetValue("Data", "FlatMPPoolMod", 0f) });
- statMods.Add(new StatMod { blockId = MasterMask.MM_Four, mask = FieldMask.FM4_Speed, value = itemData.SafeGetValue("Data", "FlatMovementSpeedMod", 0f) });
-
- var recipes = new List();
-
- var index = 1;
- var componentId = itemData.SafeGetValue("Data", string.Format("RecipeItem{0}", index), -1);
- while (componentId > -1)
- {
- recipes.Add(componentId);
- index++;
- componentId = itemData.SafeGetValue("Data", string.Format("RecipeItem{0}", index), -1);
- }
-
- var itemTemplate = new ItemTemplate(
- itemData.ItemId,
- maxStack,
- price,
- sellBack,
- trinket,
- statMods,
- recipes
- );
- itemTemplates.Add(itemData.ItemId, itemTemplate);
- Logger.LogCoreInfo("Loaded Item: {0}", itemData.ItemName);
- }
-
- Logger.LogCoreInfo("Loaded " + itemTemplates.Count + " items");
- }
-
- public ItemTemplate getItemTemplateById(int id)
- {
- if (!itemTemplates.ContainsKey(id))
- return null;
-
- return itemTemplates[id];
- }
-
- public static ItemManager getInstance()
- {
- if (_instance == null)
- _instance = new ItemManager();
- return _instance;
- }
- }
-}
diff --git a/GameServer/Logic/Logger.cs b/GameServer/Logic/Logger.cs
index 579efd2be..59d3fdf4f 100644
--- a/GameServer/Logic/Logger.cs
+++ b/GameServer/Logic/Logger.cs
@@ -35,7 +35,7 @@ public static void LogCoreInfo(string line)
public static void LogCoreInfo(string format, params object[] args)
{
- Log(string.Format(format, args), "CORE_INFO");
+ LogCoreInfo(string.Format(format, args));
}
public static void LogCoreWarning(string line)
@@ -43,6 +43,11 @@ public static void LogCoreWarning(string line)
Log(line, "CORE_WARNING");
}
+ public static void LogCoreWarning(string format, params object[] args)
+ {
+ LogCoreWarning(string.Format(format, args));
+ }
+
public static void LogCoreError(string line)
{
Log(line, "CORE_ERROR");
@@ -50,7 +55,7 @@ public static void LogCoreError(string line)
public static void LogCoreError(string format, params object[] args)
{
- Log(string.Format(format, args), "CORE_ERROR");
+ LogCoreError(string.Format(format, args));
}
}
diff --git a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleBuyItem.cs b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleBuyItem.cs
index 3e598c17e..832d5fda1 100644
--- a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleBuyItem.cs
+++ b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleBuyItem.cs
@@ -7,6 +7,7 @@
using static ENet.Native;
using LeagueSandbox.GameServer.Logic.Packets;
using LeagueSandbox.GameServer.Logic.Items;
+using LeagueSandbox.GameServer.Logic.Content;
namespace LeagueSandbox.GameServer.Core.Logic.PacketHandlers.Packets
{
@@ -16,15 +17,15 @@ public unsafe bool HandlePacket(ENetPeer* peer, byte[] data, Game game)
{
var request = new BuyItemReq(data);
- var itemTemplate = ItemManager.getInstance().getItemTemplateById(request.id);
+ var itemTemplate = game.ItemManager.SafeGetItemType(request.id);
if (itemTemplate == null)
return false;
- var recipeParts = game.getPeerInfo(peer).getChampion().getInventory().GetAvailableRecipeParts(itemTemplate);
- var price = itemTemplate.getTotalPrice();
- ItemInstance i;
+ var recipeParts = game.getPeerInfo(peer).getChampion().getInventory().GetAvailableItems(itemTemplate.Recipe);
+ var price = itemTemplate.TotalPrice;
+ Item i;
- if (recipeParts.Length == 0)
+ if (recipeParts.Count == 0)
{
if (game.getPeerInfo(peer).getChampion().getStats().getGold() < price)
{
@@ -41,7 +42,7 @@ public unsafe bool HandlePacket(ENetPeer* peer, byte[] data, Game game)
else
{
foreach (var instance in recipeParts)
- price -= instance.getTemplate().getTotalPrice();
+ price -= instance.TotalPrice;
if (game.getPeerInfo(peer).getChampion().getStats().getGold() < price)
return false;
@@ -49,16 +50,16 @@ public unsafe bool HandlePacket(ENetPeer* peer, byte[] data, Game game)
foreach (var instance in recipeParts)
{
- game.getPeerInfo(peer).getChampion().getStats().unapplyStatMods(instance.getTemplate().getStatMods());
- PacketNotifier.notifyRemoveItem(game.getPeerInfo(peer).getChampion(), instance.getSlot(), 0);
- game.getPeerInfo(peer).getChampion().getInventory().RemoveItem(instance.getSlot());
+ game.getPeerInfo(peer).getChampion().getStats().unapplyStatMods(instance.ItemType.StatMods);
+ PacketNotifier.notifyRemoveItem(game.getPeerInfo(peer).getChampion(), instance.Slot, 0);
+ game.getPeerInfo(peer).getChampion().getInventory().RemoveItem(instance.Slot);
}
i = game.getPeerInfo(peer).getChampion().getInventory().AddItem(itemTemplate);
}
game.getPeerInfo(peer).getChampion().getStats().setGold(game.getPeerInfo(peer).getChampion().getStats().getGold() - price);
- game.getPeerInfo(peer).getChampion().getStats().applyStatMods(itemTemplate.getStatMods());
+ game.getPeerInfo(peer).getChampion().getStats().applyStatMods(itemTemplate.StatMods);
PacketNotifier.notifyItemBought(game.getPeerInfo(peer).getChampion(), i);
return true;
diff --git a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleChatBoxMessage.cs b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleChatBoxMessage.cs
index 787382c31..409544abe 100644
--- a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleChatBoxMessage.cs
+++ b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleChatBoxMessage.cs
@@ -176,7 +176,7 @@ public unsafe bool HandlePacket(ENetPeer* peer, byte[] data, Game game)
return true;
new System.Threading.Thread(new System.Threading.ThreadStart(() =>
{
- var c = new Champion(split[1], game.getMap(), game.getPeerInfo(peer).getChampion().getNetId(), (uint)game.getPeerInfo(peer).userId);
+ var c = new Champion(game, split[1], game.getMap(), game.getPeerInfo(peer).getChampion().getNetId(), (uint)game.getPeerInfo(peer).userId);
c.setPosition(game.getPeerInfo(peer).getChampion().getX(), game.getPeerInfo(peer).getChampion().getY());
c.setModel(split[1]); // trigger the "modelUpdate" proc
c.setTeam(game.getPeerInfo(peer).getChampion().getTeam());
diff --git a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSellItem.cs b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSellItem.cs
index 887927976..ebaef7caa 100644
--- a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSellItem.cs
+++ b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSellItem.cs
@@ -21,15 +21,15 @@ public unsafe bool HandlePacket(ENetPeer* peer, byte[] data, Game game)
if (i == null)
return false;
- float sellPrice = i.getTemplate().getTotalPrice() * i.getTemplate().getSellBackModifier();
+ float sellPrice = i.ItemType.TotalPrice * i.ItemType.TotalPrice;
client.getChampion().getStats().setGold(client.getChampion().getStats().getGold() + sellPrice);
- if (i.getTemplate().getMaxStack() > 1)
+ if (i.ItemType.MaxStack > 1)
{
- i.decrementStacks();
- PacketNotifier.notifyRemoveItem(client.getChampion(), sell.slotId, i.getStacks());
+ i.DecrementStackSize();
+ PacketNotifier.notifyRemoveItem(client.getChampion(), sell.slotId, i.StackSize);
- if (i.getStacks() == 0)
+ if (i.StackSize == 0)
client.getChampion().getInventory().RemoveItem(sell.slotId);
}
else
diff --git a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSpawn.cs b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSpawn.cs
index bf6fe1eac..7b0a661e6 100644
--- a/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSpawn.cs
+++ b/GameServer/Logic/Packets/PacketHandlers/Handlers/HandleSpawn.cs
@@ -9,6 +9,7 @@
using LeagueSandbox.GameServer.Logic.Enet;
using LeagueSandbox.GameServer.Logic.GameObjects;
using LeagueSandbox.GameServer.Logic.Items;
+using LeagueSandbox.GameServer.Logic.Content;
namespace LeagueSandbox.GameServer.Core.Logic.PacketHandlers.Packets
{
@@ -36,8 +37,8 @@ public unsafe bool HandlePacket(ENetPeer* peer, byte[] data, Game game)
}
var peerInfo = game.getPeerInfo(peer);
- var bluePill = ItemManager.getInstance().getItemTemplateById(game.getMap().getBluePillId());
- var itemInstance = new ItemInstance(bluePill, 7);
+ var bluePill = game.ItemManager.GetItemType(game.getMap().getBluePillId());
+ var itemInstance = Item.CreateFromType(game, null, bluePill, 7);
var buyItem = new BuyItemAns(peerInfo.getChampion(), itemInstance);
PacketHandlerManager.getInstace().sendPacket(peer, buyItem, Channel.CHL_S2C);
diff --git a/GameServer/Logic/Packets/PacketNotifier.cs b/GameServer/Logic/Packets/PacketNotifier.cs
index d4da0d3e4..a191693c7 100644
--- a/GameServer/Logic/Packets/PacketNotifier.cs
+++ b/GameServer/Logic/Packets/PacketNotifier.cs
@@ -1,5 +1,6 @@
using LeagueSandbox.GameServer.Core.Logic;
using LeagueSandbox.GameServer.Core.Logic.PacketHandlers;
+using LeagueSandbox.GameServer.Logic.Content;
using LeagueSandbox.GameServer.Logic.Enet;
using LeagueSandbox.GameServer.Logic.GameObjects;
using LeagueSandbox.GameServer.Logic.Items;
@@ -146,7 +147,7 @@ public static void notifyModelUpdate(Unit obj)
PacketHandlerManager.getInstace().broadcastPacket(mp, Channel.CHL_S2C);
}
- public static void notifyItemBought(Champion c, ItemInstance i)
+ public static void notifyItemBought(Champion c, Item i)
{
var response = new BuyItemAns(c, i);
PacketHandlerManager.getInstace().broadcastPacketVision(c, response, Channel.CHL_S2C);
diff --git a/GameServer/Logic/Packets/Packets.cs b/GameServer/Logic/Packets/Packets.cs
index 480fe59b3..1c98a95bc 100644
--- a/GameServer/Logic/Packets/Packets.cs
+++ b/GameServer/Logic/Packets/Packets.cs
@@ -15,6 +15,7 @@
using LeagueSandbox.GameServer.Logic.Items;
using LeagueSandbox.GameServer.Logic.Maps;
using LeagueSandbox.GameServer.Core.Logic.PacketHandlers.Packets;
+using LeagueSandbox.GameServer.Logic.Content;
namespace LeagueSandbox.GameServer.Logic.Packets
{
@@ -1084,11 +1085,11 @@ public BuyItemReq(byte[] data)
public class BuyItemAns : BasePacket
{
- public BuyItemAns(Champion actor, ItemInstance item) : base(PacketCmdS2C.PKT_S2C_BuyItemAns, actor.getNetId())
+ public BuyItemAns(Champion actor, Item item) : base(PacketCmdS2C.PKT_S2C_BuyItemAns, actor.getNetId())
{
- buffer.Write((int)item.getTemplate().getId());
- buffer.Write((byte)item.getSlot());
- buffer.Write((byte)item.getStacks());
+ buffer.Write((int)item.ItemType.ItemId);
+ buffer.Write((byte)item.Slot);
+ buffer.Write((byte)item.StackSize);
buffer.Write((byte)0); //unk or stacks => short
buffer.Write((byte)0x40); //unk
}
diff --git a/GameServer/Program.cs b/GameServer/Program.cs
index ab5ac464b..60a5bfacf 100644
--- a/GameServer/Program.cs
+++ b/GameServer/Program.cs
@@ -48,8 +48,6 @@ static void Main(string[] args)
return;
}
- ItemManager.getInstance().init();
-
Logger.LogCoreInfo("Game started");
Game g = new Game();