393 lines
13 KiB
C#
393 lines
13 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
|
|
public class Inventory {
|
|
public Item[] items = new Item[20];
|
|
public Dictionary<ItemType, Item> equipped = new Dictionary<ItemType, Item>(); // Hashtable<ItemType, int>
|
|
public int inventoryMaxSize = 20;
|
|
public int money = 0;
|
|
|
|
public int[] material = { 0, 0, 0 };
|
|
|
|
public void UpdateQuests(ItemSubType itemSubType) {
|
|
HashSet<QuestID> quests = (HashSet<QuestID>)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<ItemType> stackableItems = new List<ItemType>() {
|
|
ItemType.ETC,
|
|
ItemType.USE
|
|
};
|
|
public static List<ItemType> equippableItems = new List<ItemType>() {
|
|
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);
|
|
}
|
|
} |