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();