using UnityEngine; using System.Collections; using System.Collections.Generic; using System; public class Inventory { public Item[] items = new Item[20]; public Dictionary equipped = new Dictionary(); // Hashtable public int inventoryMaxSize = 20; public int money = 0; public int[] material = { 0, 0, 0 }; public void UpdateQuests(ItemSubType itemSubType) { HashSet quests = (HashSet)State.state.quests.itemToQuestID[itemSubType]; if (quests != null) { foreach (QuestID questID in quests) { ((QuestProgress)State.state.quests.allQuestProgress[questID]).RefreshItemProgress(); } } } public bool CraftItem(Item newItem, Hashtable craftingRequirements) { // Check for sufficient open slots. int numOpenSlots = 0; foreach (Item i in State.state.inventory.items) { if (i == null || i.count == 0) { numOpenSlots++; } } if (numOpenSlots == 0) { Debug.Log("You're missing a slot for crafting."); return false; } // Cache inventory. Item[] inventoryCache = new Item[State.state.inventory.items.Length]; Array.Copy(State.state.inventory.items, inventoryCache, inventoryCache.Length); // Disburse item. Debug.Log("Disbursing " + newItem.subType.ToString()); // Items remaining from what was gained >0 means that the gain failed. if (State.state.inventory.GainItem(newItem, false) > 0) { Debug.LogError("Failed to gain item " + newItem.data.name + "! Reverting to inventory cache."); Array.Copy(inventoryCache, State.state.inventory.items, inventoryCache.Length); return false; } // Take what the quest wants (items). Debug.Log("Here you go!"); Hashtable requiredItems = (Hashtable)craftingRequirements.Clone(); for (int i = 0; i < State.state.inventory.items.Length; i++) { Item item = State.state.inventory.items[i]; if (item != null && requiredItems.ContainsKey(item.subType)) { // Drop (destroy) Item droppedItem = State.state.inventory.DropItem(i, Mathf.Min((int)requiredItems[item.subType], item.count), false); requiredItems[item.subType] = (int)requiredItems[item.subType] - droppedItem.count; if ((int)requiredItems[item.subType] == 0) { requiredItems.Remove(item.subType); } } } // Having required items remaining means something went wrong destroying the items. if (requiredItems.Count > 0) { string remaining = ""; foreach (DictionaryEntry KV in requiredItems) { remaining += ((ItemData)ItemData.itemData[KV.Key]).name + ", "; } Debug.LogError("Failed to delete required items: " + remaining); Array.Copy(inventoryCache, State.state.inventory.items, inventoryCache.Length); return false; } // Update state. State.state.stats.updateCache(); State.state.inventory.UpdateQuests(newItem.subType); State.state.quests.RefreshAvailableQuests(); return true; } // Returns the stack size remaining for the item. Zero if full pickup. public int GainItem(Item item, bool shouldUpdateQuests = true) { switch(item.subType) { case ItemSubType.ENHANCE: material[0] += item.count; return 0; case ItemSubType.ENHANCE2: material[1] += item.count; return 0; case ItemSubType.ENHANCE3: material[2] += item.count; return 0; } bool stackable = Item.stackableItems.Contains(item.data.itemType); bool success = false; for (int i = 0; i < items.Length; i++) { if (items[i] == null) { items[i] = new Item(item.data, item.subType, item.count); item.count -= items[i].count; success = true; } else if (stackable && item.subType == items[i].subType) { int increase = Mathf.Min(item.count, item.data.maxStack - items[i].count); items[i].count += increase; item.count -= increase; success = true; } if (item.count == 0) { if (shouldUpdateQuests) { UpdateQuests(item.subType); } return 0; } } if (shouldUpdateQuests && success) { UpdateQuests(item.subType); } return item.count; } public Item DropItem(int index, int dropCount, bool shouldUpdateQuests = true) { if (index < 0 || index > items.Length || items[index] == null || items[index].count < dropCount) { return null; } Item toDrop = new Item(items[index].data, items[index].subType, dropCount); items[index].count -= dropCount; if (items[index].count == 0) { items[index] = null; } if (shouldUpdateQuests) { UpdateQuests(toDrop.subType); } return toDrop; } public bool EquipItem(int index) { if (index < 0 || index > items.Length || items[index] == null || !Item.equippableItems.Contains(items[index].data.itemType)) { return false; } Item item = items[index].DeepCopy(); if (equipped.ContainsKey(item.data.itemType) && equipped[item.data.itemType] != null) { Item dequippedItem = equipped[item.data.itemType].DeepCopy(); items[index] = dequippedItem; } else { items[index] = null; } equipped[item.data.itemType] = item; Debug.Log(item.data.name); State.state.stats.updateCache(); UpdateQuests(item.subType); return true; } public bool DequipItem(ItemType type) { Debug.Log("Trying to dequip " + type.ToString()); if (!equipped.ContainsKey(type) || equipped[type] == null) { return false; } // If Gain leaves >0 items (i.e. the Gain fails) int left = GainItem((Item)equipped[type]); Debug.Log(left); if (left > 0) { return false; } equipped[type] = null; State.state.stats.updateCache(); return true; } public bool UseItem(int index) { if (index < 0 || index > items.Length || items[index] == null || items[index].data.itemType != ItemType.USE) { return false; } Item item = items[index]; State.state.stats.hp = Mathf.Min(State.state.stats.maxHP, State.state.stats.hp + item.data.useStats.hp); State.state.stats.hp = Mathf.Min(State.state.stats.maxHP, State.state.stats.hp + (int)(item.data.useStats.hpPercentage * State.state.stats.maxHP)); State.state.stats.gainExp((int)(item.data.useStats.expPercentage * State.state.stats.maxExp)); State.state.stats.gainExp(item.data.useStats.exp); State.state.stats.availableStatPoints += item.data.useStats.availableStatPoints; State.state.stats.updateCache(); item.count -= 1; if (item.count < 1) { items[index] = null; } UpdateQuests(item.subType); return true; } } public class Item { public static List stackableItems = new List() { ItemType.ETC, ItemType.USE }; public static List equippableItems = new List() { ItemType.EQUIP_BOW, ItemType.EQUIP_HAT, ItemType.EQUIP_GLOVES, ItemType.EQUIP_OVERALL, ItemType.EQUIP_SHOES }; public ItemData data; public ItemSubType subType; public int count = 1; public Item(ItemData data, ItemSubType subType, int count = 1) { if (data != null) { this.data = data.DeepCopy(); } else { data = null; } this.subType = subType; this.count = count; } public Item DeepCopy() { Item newItem = new Item(data.DeepCopy(), subType, count); return newItem; } // Attempt to enhance an equip. Returns true iff the enhancement succeeded. // Enhancement stat amounts are fixed per item. public bool Enhance() { if (!equippableItems.Contains(data.itemType)) { return false; } if (data.equipStats.remainingEnhancements > 0) { for (int i = 0; i < 3; i++) { if (data.enhancementStats.tier == i && State.state.inventory.material[i] >= data.enhancementStats.requiredMaterial) { State.state.inventory.material[i] -= data.enhancementStats.requiredMaterial; data.equipStats.remainingEnhancements -= 1; data.equipStats.numEnhancements += 1; data.equipStats.attack += data.enhancementStats.attack; data.equipStats.pwr += data.enhancementStats.pwr; data.equipStats.dex += data.enhancementStats.dex; data.equipStats.stb += data.enhancementStats.stb; data.equipStats.def += data.enhancementStats.def; data.equipStats.maxHP += data.enhancementStats.maxHP; return true; } } } return false; } } public class EquipStats { public int attack; public int pwr; public int dex; public int stb; public int def; public int maxHP; public int pwrPercentage; public int dexPercentage; public int stbPercentage; public int defPercentage; public int maxHPPercentage; public int attackPercentage; public int numEnhancements; public int remainingEnhancements; public int requiredLevel; public EquipStats(int requiredLevel, int numEnhancements, int remainingEnhancements, int attack, int pwr, int dex, int stb, int def = 0, int maxHP = 0, int pwrPercentage = 0, int dexPercentage = 0, int stbPercentage = 0, int defPercentage = 0, int maxHPPercentage = 0, int attackPercentage = 0) { this.requiredLevel = requiredLevel; this.numEnhancements = numEnhancements; this.remainingEnhancements = remainingEnhancements; this.attack = attack; this.pwr = pwr; this.dex = dex; this.stb = stb; this.def = def; this.maxHP = maxHP; this.pwrPercentage = pwrPercentage; this.dexPercentage = dexPercentage; this.stbPercentage = stbPercentage; this.defPercentage = defPercentage; this.maxHPPercentage = maxHPPercentage; this.attackPercentage = attackPercentage; } public EquipStats DeepCopy() { return new EquipStats( requiredLevel, numEnhancements, remainingEnhancements, attack, pwr, dex, stb, def, maxHP, pwrPercentage, dexPercentage, stbPercentage, defPercentage, maxHPPercentage, attackPercentage); } } // Amount of stats gained per enhancement. public class EnhancementStats { public int tier; public int requiredMaterial; public int attack; public int pwr; public int dex; public int stb; public int def; public int maxHP; public EnhancementStats(int _tier = 1, int _requiredMaterial = 1, int _attack = 0, int _pwr = 0, int _dex = 0, int _stb = 0, int _def = 0, int _maxHP = 0) { this.tier = _tier; this.requiredMaterial = _requiredMaterial; this.attack = _attack; this.pwr = _pwr; this.dex = _dex; this.stb = _stb; this.def = _def; this.maxHP = _maxHP; } public EnhancementStats DeepCopy() { return new EnhancementStats( tier, requiredMaterial, attack, pwr, dex, stb, def, maxHP); } } public class UseStats { public int hp; public int exp; public int availableStatPoints; public float hpPercentage; public float expPercentage; // Percentage of maxExp public UseStats(int hp = 0, int exp = 0, int availableStatPoints = 0, float hpPercentage = 0, float expPercentage = 0) { this.hp = hp; this.exp = exp; this.availableStatPoints = availableStatPoints; this.hpPercentage = hpPercentage; this.expPercentage = expPercentage; } public UseStats DeepCopy() { return new UseStats( hp, exp, availableStatPoints, hpPercentage, expPercentage); } }