/// <summary> /// returns the first item instance associated with 'id' (if any). /// if 'id' is zero or lower, returns the first item of 'itemType'. /// this method uses a temporary dictionary to speed things up. /// if the item can't be found in the dictionary, tries to add it /// to the dictionary from the serialized list. returns null if /// 'itemType' is null or no matching item can be found /// </summary> public vp_ItemInstance GetItem(vp_ItemType itemType, int id) { //Debug.Log("GetItem @ " + Time.frameCount); // TIP: turn the comments in this method into debug output for // a very detailed look at the code flow at runtime if (itemType == null) { Debug.LogError("Error (" + vp_Utility.GetErrorLocation(1, true) + ") Sent a null itemType to 'GetItem'."); return(null); } if (id < 1) { //Debug.Log("no ID was specified: returning the first item of matching type"); return(GetItem(itemType)); } if (m_ItemDictionaryDirty) { //Debug.Log("resetting the dictionary"); m_ItemDictionary.Clear(); m_ItemDictionaryDirty = false; } //Debug.Log("we have an ID (" + id + "): try to fetch an associated instance from the dictionary"); if (!m_ItemDictionary.TryGetValue(id, out m_GetItemResult)) { //Debug.Log("DID NOT find item in the dictionary: trying to find it in the list"); m_GetItemResult = GetItemFromList(itemType, id); if ((m_GetItemResult != null) && (id > 0)) { //Debug.Log("found id '"+id+"' in the list! adding it to dictionary"); m_ItemDictionary.Add(id, m_GetItemResult); } } else if (m_GetItemResult != null) { //Debug.Log("DID find a quick-match by ID ("+id+") in the dictionary: verifying the item type"); if (m_GetItemResult.Type != itemType) { //Debug.Log("type (" + m_GetItemResult.Type + ") was wrong (expected " + itemType + ") trying to get item from the list"); Debug.LogWarning("Warning: (vp_Inventory) Player has vp_FPWeapons with identical, non-zero vp_ItemIdentifier IDs! This is much slower than using zero or differing IDs."); m_GetItemResult = GetItemFromList(itemType, id); } } else { //Debug.Log("we found item in the dictionary but it was null"); m_ItemDictionary.Remove(id); GetItem(itemType, id); } //if (m_GetItemResult != null) Debug.Log("found item: " + m_GetItemResult + ", Type: " + m_GetItemResult.Type + ", ID: " + m_GetItemResult.ID); //else Debug.Log("found no matching item"); return(m_GetItemResult); }
/// <summary> /// tries to award an item to a recipient by transform, item type /// and amount /// </summary> public static bool TryGiveItem(Transform recipient, vp_ItemType itemType, int amount) { if (recipient == null) { Debug.LogError("Error (" + Instance + ") Recipient was null."); return false; } vp_Inventory inventory; if (!m_RecipientInventories.TryGetValue(recipient, out inventory)) { inventory = vp_TargetEventReturn<vp_Inventory>.SendUpwards(recipient, "GetInventory"); m_RecipientInventories.Add(recipient, inventory); } if (inventory == null) { Debug.LogError("Error (" + Instance + ") Failed to find an enabled inventory on '" + recipient + "'."); return false; } if (TryMatchExistingItem(inventory, recipient, itemType, amount)) return true; return TryGiveItemAsNew(recipient, itemType, amount); }
/// <summary> /// tries to award an item to a recipient by transform, item type /// and amount /// </summary> public static bool TryGiveItem(Transform recipient, vp_ItemType itemType, int amount) { if (recipient == null) { Debug.LogError("Error (" + Instance + ") Recipient was null."); return(false); } vp_Inventory inventory; if (!m_RecipientInventories.TryGetValue(recipient, out inventory)) { inventory = vp_TargetEventReturn <vp_Inventory> .SendUpwards(recipient, "GetInventory"); m_RecipientInventories.Add(recipient, inventory); } if (inventory == null) { Debug.LogError("Error (" + Instance + ") Failed to find an enabled inventory on '" + recipient + "'."); return(false); } if (TryMatchExistingItem(inventory, recipient, itemType, amount)) { return(true); } return(TryGiveItemAsNew(recipient, itemType, amount)); }
/// <summary> /// upon success, unwields the current weapon of the player and waits /// for a little bit before tossing the weapon /// </summary> public virtual void TryDropCurrentWeapon(float pauseForUnwield = 0.3f) { if (WeaponHandler == null) { return; } if (WeaponHandler.CurrentWeapon == null) { return; } vp_ItemIdentifier identifier = WeaponHandler.CurrentWeapon.GetComponent <vp_ItemIdentifier>(); if (identifier == null) { return; } vp_ItemType itemType = identifier.GetItemType(); if (itemType == null) { return; } int units = Inventory.GetAmmoInCurrentWeapon(); Player.Unwield.Send(); vp_Timer.In(Mathf.Max(pauseForUnwield, 0.0f), () => { TryDropWeapon(itemType, units); }); }
/// <summary> /// returns a pickup prefab of the passed 'itemType', if available /// </summary> protected virtual GameObject GetPickupPrefab(vp_ItemType itemType, int units = 0) { if (itemType == null) { return(null); } GameObject o = null; if (itemType is vp_UnitType) // ammo { m_SceneDroppables.TryGetValue(itemType.name + "," + units, out o); } else // weapons and other items { m_SceneDroppables.TryGetValue(itemType.name, out o); } if (o == null) { return(null); } return(o); }
/// <summary> /// /// </summary> public virtual int GetItemCount(vp_ItemType type) { vp_UnitType unitType = type as vp_UnitType; if (unitType != null) { return(GetUnitCount(unitType)); } int count = 0; for (int v = 0; v < ItemInstances.Count; v++) { if (ItemInstances[v].Type == type) { count++; } } for (int v = 0; v < m_UnitBankInstances.Count; v++) { if (m_UnitBankInstances[v].Type == type) { count++; } } return(count); }
/// <summary> /// upon success, drops all the player's weapons /// </summary> protected virtual void TryDropAllWeapons() { if (WeaponHandler == null) { return; } foreach (KeyValuePair <vp_Weapon, vp_ItemIdentifier> w in Inventory.WeaponIdentifiers) { vp_Weapon weapon = w.Key; vp_ItemIdentifier weaponIdentifier = w.Value; // skip if weapon identifier has no item type vp_ItemType itemType = weaponIdentifier.GetItemType(); if (itemType == null) { continue; } // for unitbank weapons, try and set the weapon pickup's ammo // to the amount of ammo in the dropped weapon int units = 0; vp_UnitBankInstance unitBank = Inventory.GetUnitBankInstanceOfWeapon(weapon); if (unitBank != null) { units = unitBank.Count; } // drop the weapon TryDropWeapon(itemType, units, weaponIdentifier.ID); } }
/// <summary> /// if id is set: looks for a specific item, if not: /// returns the first item found /// </summary> protected virtual vp_ItemInstance GetItemFromList(vp_ItemType itemType, int id = UNIDENTIFIED) { for (int v = 0; v < m_UnitBankInstances.Count; v++) { if (m_UnitBankInstances[v].Type != itemType) { continue; } if ((id == UNIDENTIFIED) || m_UnitBankInstances[v].ID == id) { return(m_UnitBankInstances[v]); } } for (int v = 0; v < ItemInstances.Count; v++) { if (ItemInstances[v].Type != itemType) { continue; } if ((id == UNIDENTIFIED) || ItemInstances[v].ID == id) { return(ItemInstances[v]); } } return(null); }
/// <summary> /// sets item count to higher or lower than current, regardless /// of item cap. this can be used for game designs allowing /// for a one-time addition of excess items. NOTE: if caps /// should be imposed, instead use 'TryGiveItem. /// </summary> public virtual void SetItemCount(vp_ItemType type, int amount) { if (type is vp_UnitType) { SetUnitCount((vp_UnitType)type, amount); return; } // if we are to ignore item caps and inventory space, temporarily disable them bool capsEnabledBak = CapsEnabled; bool spaceEnabledBak = SpaceEnabled; CapsEnabled = false; SpaceEnabled = false; // either give or remove items to reach target amount int amountToGive = amount - GetItemCount(type); if (amountToGive > 0) { TryGiveItems(type, amount); } else if (amountToGive < 0) { TryRemoveItems(type, -amount); } CapsEnabled = capsEnabledBak; SpaceEnabled = spaceEnabledBak; }
/// <summary> /// /// </summary> protected virtual void DrawUnitBank(Rect pos, SerializedProperty prop) { vp_PropertyDrawerUtility.AddObjectBoxBG(pos, pos.width - 50); pos.width -= 22; pos.x += 6; pos.y += 2; vp_ItemType item = (vp_UnitBankType)prop.objectReferenceValue; string name = item.ToString(); if (vp_PropertyDrawerUtility.ItemCard(pos, ((item == null) ? null : item.Icon), name, ((item == null) ? null : item), ref vp_ItemAmountDrawer.ItemAmountValue, "Units", null, ref vp_ItemIDDrawer.ItemIDValue, "ID", null, delegate() { prop.objectReferenceValue = null; vp_ItemAmountDrawer.ItemAmountValue = 0; vp_ItemIDDrawer.ItemIDValue = 0; }, 0)) { vp_ItemAmountDrawer.ItemAmountTargetObject = prop.serializedObject; vp_ItemIDDrawer.ItemIDTargetObject = prop.serializedObject; } }
/// <summary> /// /// </summary> protected virtual void DrawInternalUnitBank(Rect pos, SerializedProperty prop) { vp_PropertyDrawerUtility.AddObjectBoxBG(pos, pos.width - 50); //int NOVALUE = -1; // uncomment to hide ID field pos.width -= 22; pos.x += 6; pos.y += 2; vp_ItemType item = (vp_ItemType)prop.objectReferenceValue; string name = item.ToString(); //if(prop.serializedObject.targetObject.GetType() == typeof(vp_ItemPickup)) // this can be done to identify the type of host component if (vp_PropertyDrawerUtility.ItemCard(pos, ((item == null) ? null : item.Icon), name, ((item == null) ? null : item), ref vp_ItemAmountDrawer.ItemAmountValue, "Units", null, ref vp_ItemIDDrawer.ItemIDValue, // set to 'NOVALUE' to hide ID field "ID", // set to "" to hide ID field null, delegate() { prop.objectReferenceValue = null; vp_ItemAmountDrawer.ItemAmountValue = 0; vp_ItemIDDrawer.ItemIDValue = 0; }, 0)) { vp_ItemAmountDrawer.ItemAmountTargetObject = prop.serializedObject; } }
/// <summary> /// returns true if we managed to add new items of 'itemType', /// false if not /// </summary> protected static bool TryGiveItemAsNew(Transform recipient, vp_ItemType itemType, int amount) { System.Type type = itemType.GetType(); if (type == typeof(vp_ItemType)) { return(vp_TargetEventReturn <vp_ItemType, int, bool> .SendUpwards(recipient, "TryGiveItem", itemType, 0)); } else if (type == typeof(vp_UnitBankType)) { return(vp_TargetEventReturn <vp_UnitBankType, int, int, bool> .SendUpwards(recipient, "TryGiveUnitBank", (itemType as vp_UnitBankType), amount, 0)); } else if (type == typeof(vp_UnitType)) { return(vp_TargetEventReturn <vp_UnitType, int, bool> .SendUpwards(recipient, "TryGiveUnits", (itemType as vp_UnitType), amount)); } else if (type.BaseType == typeof(vp_ItemType)) { return(vp_TargetEventReturn <vp_ItemType, int, bool> .SendUpwards(recipient, "TryGiveItem", itemType, 0)); } else if (type.BaseType == typeof(vp_UnitBankType)) { return(vp_TargetEventReturn <vp_UnitBankType, int, int, bool> .SendUpwards(recipient, "TryGiveUnitBank", (itemType as vp_UnitBankType), amount, 0)); } else if (type.BaseType == typeof(vp_UnitType)) { return(vp_TargetEventReturn <vp_UnitType, int, bool> .SendUpwards(recipient, "TryGiveUnits", (itemType as vp_UnitType), amount)); } return(false); }
/// <summary> /// /// </summary> public virtual bool HaveItem(vp_ItemType itemType, int id = UNIDENTIFIED) { if (itemType == null) { return(false); } return(GetItem(itemType, id) != null); }
/// <summary> /// /// </summary> protected override void DoAddItem(vp_ItemType type, int id) { bool alreadyHaveIt = vp_Gameplay.isMultiplayer ? HaveItem(type) : HaveItem(type, id); // NOTE: id not supported in UFPS multiplayer add-on base.DoAddItem(type, id); TryWieldNewItem(type, alreadyHaveIt); }
/// <summary> /// tries to drop the currenlty loaded throwing weapon unit in the form /// of an ammo unit (rather than in the form of a weapon) /// </summary> protected virtual void TryDropLoadedThrowingUnit(vp_UnitType unitType) { vp_UnitBankType unitBankType = Inventory.GetThrowingWeaponUnitBankType(unitType); if (unitBankType == null) { return; } for (int v = (WeaponHandler.Weapons.Count - 1); v > -1; v--) { if (WeaponHandler.Weapons[v] == null) { continue; } vp_ItemIdentifier identifier = WeaponHandler.Weapons[v].GetComponent <vp_ItemIdentifier>(); if (identifier == null) { continue; } vp_ItemType iType = identifier.GetItemType(); if (iType == null) { continue; } if (iType != unitBankType) { continue; } for (int u = (Inventory.UnitBankInstances.Count - 1); u > -1; u--) { //Debug.Log("unittype: " + Inventory.UnitBankInstances[u].Type + ", count: " + Inventory.UnitBankInstances[u].Count); if (Inventory.UnitBankInstances[u].UnitType == unitBankType.Unit) { // if the throwing weapon is currently loaded with one unit (likely), move that unit // from the throwing weapon to the internal unitbank and drop it as an ammo clip if (Inventory.UnitBankInstances[u].Count == 1) { // move unit to internal unitbank Inventory.UnitBankInstances[u].DoRemoveUnits(1); vp_UnitBankInstance internalUnitBank = Inventory.GetInternalUnitBank(Inventory.UnitBankInstances[u].UnitType); internalUnitBank.DoAddUnits(1); // drop the moved unit if (TryDropAmmoClip(Inventory.UnitBankInstances[u].UnitType.name, 1)) { //Debug.Log("Dropped: " + Inventory.UnitBankInstances[v].UnitType.name + ",1"); } continue; } } } } }
public static void CreateItemTypeVpItemType() { vp_ItemType asset = (vp_ItemType)vp_EditorUtility.CreateAsset("UFPS/Base/Content/ItemTypes", typeof(vp_ItemType)); if (asset != null) { asset.DisplayName = "thing"; } }
/// <summary> /// /// </summary> protected override void DoAddItem(vp_ItemType type, int id) { bool hadItBefore = HaveItem(type, id); base.DoAddItem(type, id); if (!hadItBefore) { TryWield(GetItem(type, id)); } }
/// <summary> /// /// </summary> protected virtual void DoAddItem(vp_ItemType type, int id) { ItemInstances.Add(new vp_ItemInstance(type, id)); m_FirstItemsDirty = true; if (SpaceEnabled) { m_UsedSpace += type.Space; } SetDirty(); }
/// <summary> /// /// </summary> protected virtual vp_ItemInstance GetItem(vp_ItemType itemType) { // TIP: turn the comments in this method into debug output for // a very detailed look at the code flow at runtime // recreate the dictionary if needed (items may have been added, removed) if (m_FirstItemsDirty) { //Debug.Log("recreating the 'm_FirstItemsOfType' dictionary"); m_FirstItemsOfType.Clear(); foreach (vp_ItemInstance itemInstance in ItemInstances) { if (itemInstance == null) { continue; } if (!m_FirstItemsOfType.ContainsKey(itemInstance.Type)) { m_FirstItemsOfType.Add(itemInstance.Type, itemInstance); } } foreach (vp_UnitBankInstance itemInstance in UnitBankInstances) { if (itemInstance == null) { continue; } if (!m_FirstItemsOfType.ContainsKey(itemInstance.Type)) { m_FirstItemsOfType.Add(itemInstance.Type, itemInstance); } } m_FirstItemsDirty = false; } //Debug.Log("trying to fetch an instance of the target item type"); if (!m_FirstItemsOfType.TryGetValue(itemType, out m_GetFirstItemInstanceResult)) { //Debug.Log("no match: returning null"); return(null); } //Debug.Log("an instance of the target item type was found: perform a null check"); if (m_GetFirstItemInstanceResult == null) { //Debug.Log("the instance was null: so refresh dictionary and run the method all over again"); m_FirstItemsDirty = true; return(GetItem(itemType)); } //Debug.Log("item was found"); return(m_GetFirstItemInstanceResult); }
/// <summary> /// /// </summary> protected virtual void DoAddItem(vp_ItemType type, int id) { //Debug.Log("DoAddItem"); ItemInstances.Add(new vp_ItemInstance(type, id)); if (SpaceEnabled) { m_UsedSpace += type.Space; } m_FirstItemsDirty = true; m_ItemDictionaryDirty = true; SetDirty(); }
/// <summary> /// tries to remove a number of items by type and amount, /// regardless of their IDs /// </summary> public virtual bool TryRemoveItems(vp_ItemType type, int amount) { bool result = false; while (amount > 0) { if (TryRemoveItem(type, UNIDENTIFIED)) { result = true; } amount--; } return(result); }
/// <summary> /// tries to remove an amount of items to the item count. /// NOTE: this event should be passed an object array where /// the first object is of type 'vp_ItemType', and the second /// (optional) object is of type 'int', representing the amount /// of items to remove /// </summary> protected virtual bool OnAttempt_RemoveItem(object args) { object[] arr = (object[])args; // fail if item type is unknown vp_ItemType type = arr[0] as vp_ItemType; if (type == null) { return(false); } int amount = (arr.Length == 2) ? (int)arr[1] : 1; return(TryRemoveItems(type, amount)); }
/// <summary> /// tries to remove an item record or unit from the player inventory /// </summary> protected virtual bool TryRemoveItem(vp_ItemType itemType, int units = 1, int id = 0) { //Debug.Log("TryRemoveItem: " + itemType.name + ", " + amount); if (Inventory == null) { Debug.LogError("Error (" + this + ") Tried to remove an item but there is no vp_Inventory!"); return(false); } vp_ItemInstance i = null; if (id != 0) { i = Inventory.GetItem(itemType, id); } else { i = Inventory.GetItem(itemType.name); } if (i == null) { return(false); } id = i.ID; if (itemType is vp_UnitType) { if (!Inventory.TryRemoveUnits((itemType as vp_UnitType), units)) { //Debug.Log("Failed to remove " + amount + " units of type: " + itemType); return(false); } } else { if (!Inventory.TryRemoveItems(itemType, 1)) { //Debug.Log("Failed to remove an item of type: " + itemType); return(false); } } return(true); }
/// <summary> /// internal method which can add items by type, amount and ID. /// </summary> public virtual bool TryGiveItem(vp_ItemType itemType, int id) { if (itemType == null) { Debug.LogError("Error (" + vp_Utility.GetErrorLocation(2) + ") Item type was null."); return(false); } // forward to the correct method if this was a unit type vp_UnitType unitType = itemType as vp_UnitType; if (unitType != null) { return(TryGiveUnits(unitType, id)); // in this case treat int argument as 'amount' } // forward to the correct method if this was a unitbank type vp_UnitBankType unitBankType = itemType as vp_UnitBankType; if (unitBankType != null) { return(TryGiveUnitBank(unitBankType, unitBankType.Capacity, id)); } // enforce item cap for this type of item if (CapsEnabled) { int capacity = GetItemCap(itemType); if ((capacity != UNLIMITED) && (GetItemCount(itemType) >= capacity)) { return(false); } } // enforce space limitations of the inventory if (SpaceEnabled) { if ((UsedSpace + itemType.Space) > TotalSpace) { return(false); } } DoAddItem(itemType, id); return(true); }
/// <summary> /// /// </summary> public virtual void SetItemCap(vp_ItemType type, int cap, bool clamp = false) { SetDirty(); // see if we have an existing cap for 'type' for (int v = 0; v < m_ItemCapInstances.Count; v++) { // if so, change the cap if (m_ItemCapInstances[v].Type == type) { m_ItemCapInstances[v].Cap = cap; goto found; } } // if not found, create a new cap m_ItemCapInstances.Add(new ItemCap(type, cap)); found: // if type is a unit, update capacity of the unit bank if (type is vp_UnitType) { for (int v = 0; v < m_InternalUnitBanks.Count; v++) { if ((m_InternalUnitBanks[v].UnitType != null) && (m_InternalUnitBanks[v].UnitType == type)) { m_InternalUnitBanks[v].Capacity = cap; // clamp amount of units, if specified if (clamp) { m_InternalUnitBanks[v].ClampToCapacity(); } } } } // clamp amount of items, if specified else if (clamp) { if (GetItemCount(type) > cap) { TryRemoveItems(type, (GetItemCount(type) - cap)); } } }
/// <summary> /// /// </summary> public virtual int GetItemCap(vp_ItemType type) { if (!CapsEnabled) { return(UNLIMITED); } for (int v = 0; v < m_ItemCapInstances.Count; v++) { if (m_ItemCapInstances[v].Type == type) { return(m_ItemCapInstances[v].Cap); } } if (AllowOnlyListed) { return(0); } return(UNLIMITED); }
/// <summary> /// NOTE: only for item unit banks (such as weapons) /// </summary> public virtual bool TryReload(vp_ItemType itemType, int unitBankId, int amount) { return(TryReload(GetItem(itemType, unitBankId) as vp_UnitBankInstance, amount)); }
/// <summary> /// tries to remove an item by type and ID /// </summary> public virtual bool TryRemoveItem(vp_ItemType type, int id) { return(TryRemoveItem(GetItem(type, id) as vp_ItemInstance)); }
/// <summary> /// NOTE: only for item unit banks (such as weapons) /// </summary> public virtual bool TryReload(vp_ItemType itemType, int unitBankId) { return(TryReload(GetItem(itemType, unitBankId) as vp_UnitBankInstance, MAXCAPACITY)); }
/// <summary> /// /// </summary> public virtual void SetItemCap(vp_ItemType type, int cap, bool clamp = false) { SetDirty(); // see if we have an existing cap for 'type' for (int v = 0; v < m_ItemCapInstances.Count; v++) { // if so, change the cap if (m_ItemCapInstances[v].Type == type) { m_ItemCapInstances[v].Cap = cap; goto found; } } // if not found, create a new cap m_ItemCapInstances.Add(new ItemCap(type, cap)); found: // if type is a unit, update capacity of the unit bank if (type is vp_UnitType) { for (int v = 0; v < m_InternalUnitBanks.Count; v++) { if ((m_InternalUnitBanks[v].UnitType != null) && (m_InternalUnitBanks[v].UnitType == type)) { m_InternalUnitBanks[v].Capacity = cap; // clamp amount of units, if specified if (clamp) m_InternalUnitBanks[v].ClampToCapacity(); } } } // clamp amount of items, if specified else if (clamp) { if (GetItemCount(type) > cap) TryRemoveItems(type, (GetItemCount(type) - cap)); } }
/// <summary> /// returns true if we managed to add new items of 'itemType', /// false if not /// </summary> protected static bool TryGiveItemAsNew(Transform recipient, vp_ItemType itemType, int amount) { System.Type type = itemType.GetType(); if (type == typeof(vp_ItemType)) return vp_TargetEventReturn<vp_ItemType, int, bool>.SendUpwards(recipient, "TryGiveItem", itemType, 0); else if (type == typeof(vp_UnitBankType)) return vp_TargetEventReturn<vp_UnitBankType, int, int, bool>.SendUpwards(recipient, "TryGiveUnitBank", (itemType as vp_UnitBankType), amount, 0); else if (type == typeof(vp_UnitType)) return vp_TargetEventReturn<vp_UnitType, int, bool>.SendUpwards(recipient, "TryGiveUnits", (itemType as vp_UnitType), amount); else if (type.BaseType == typeof(vp_ItemType)) return vp_TargetEventReturn<vp_ItemType, int, bool>.SendUpwards(recipient, "TryGiveItem", itemType, 0); else if (type.BaseType == typeof(vp_UnitBankType)) return vp_TargetEventReturn<vp_UnitBankType, int, int, bool>.SendUpwards(recipient, "TryGiveUnitBank", (itemType as vp_UnitBankType), amount, 0); else if (type.BaseType == typeof(vp_UnitType)) return vp_TargetEventReturn<vp_UnitType, int, bool>.SendUpwards(recipient, "TryGiveUnits", (itemType as vp_UnitType), amount); return false; }
/// <summary> /// tries to add a number of items by type and amount. /// NOTE: all items with have ID '0'. /// </summary> public virtual bool TryGiveItems(vp_ItemType type, int amount) { bool result = false; while (amount > 0) { if (TryGiveItem(type, 0)) result = true; amount--; } return result; }
/// <summary> /// /// </summary> protected virtual void TryWieldNewItem(vp_ItemType type, bool alreadyHaveIt) { bool haveHadItBefore = m_PreviouslyOwnedItems.ContainsKey(type); if (!haveHadItBefore) m_PreviouslyOwnedItems.Add(type, null); // --- see if we should try to wield a weapon because of this item pickup --- if (m_AutoWield.Always) goto tryWield; if (m_AutoWield.IfUnarmed && (WeaponHandler.CurrentWeaponIndex < 1)) goto tryWield; if (m_AutoWield.IfOutOfAmmo && (WeaponHandler.CurrentWeaponIndex > 0) && (WeaponHandler.CurrentWeapon.AnimationType != (int)vp_Weapon.Type.Melee) && m_Player.CurrentWeaponAmmoCount.Get() < 1) goto tryWield; if (m_AutoWield.IfNotPresent && !m_AutoWield.FirstTimeOnly && !alreadyHaveIt) goto tryWield; if (m_AutoWield.FirstTimeOnly && !haveHadItBefore) goto tryWield; return; tryWield: if ((type is vp_UnitBankType)) TryWield(GetItem(type)); else if (type is vp_UnitType) TryWieldByUnit(type as vp_UnitType); else if (type is vp_ItemType) // tested last since the others derive from it TryWield(GetItem(type)); else { System.Type baseType = type.GetType(); if (baseType == null) return; baseType = baseType.BaseType; if ((baseType == typeof(vp_UnitBankType))) TryWield(GetItem(type)); else if (baseType == typeof(vp_UnitType)) TryWieldByUnit(type as vp_UnitType); else if (baseType == typeof(vp_ItemType)) TryWield(GetItem(type)); } }
/// <summary> /// if id is set: looks for a specific item, if not: /// returns the first item found /// </summary> protected virtual vp_ItemInstance GetItemFromList(vp_ItemType itemType, int id = UNIDENTIFIED) { for (int v = 0; v < m_UnitBankInstances.Count; v++) { if (m_UnitBankInstances[v].Type != itemType) continue; if ((id == UNIDENTIFIED) || m_UnitBankInstances[v].ID == id) return m_UnitBankInstances[v]; } for (int v = 0; v < ItemInstances.Count; v++) { if (ItemInstances[v].Type != itemType) continue; if ((id == UNIDENTIFIED) || ItemInstances[v].ID == id) return ItemInstances[v]; } return null; }
public vp_ItemInstance(vp_ItemType type, int id) { ID = id; Type = type; }
/// <summary> /// tries to remove a number of items by type and amount, /// regardless of their IDs /// </summary> public virtual bool TryRemoveItems(vp_ItemType type, int amount) { bool result = false; while (amount > 0) { if (TryRemoveItem(type, UNIDENTIFIED)) result = true; amount--; } return result; }
/// <summary> /// /// </summary> protected virtual void DoAddItem(vp_ItemType type, int id) { ItemInstances.Add(new vp_ItemInstance(type, id)); if (SpaceEnabled) m_UsedSpace += type.Space; m_FirstItemsDirty = true; m_ItemDictionaryDirty = true; SetDirty(); }
/// <summary> /// tries to remove an item by type and ID /// </summary> public virtual bool TryRemoveItem(vp_ItemType type, int id) { return TryRemoveItem(GetItem(type, id) as vp_ItemInstance); }
/// <summary> /// /// </summary> protected override void DoAddItem(vp_ItemType type, int id) { bool hadItBefore = HaveItem(type, id); base.DoAddItem(type, id); if (!hadItBefore) TryWield(GetItem(type, id)); }
/// <summary> /// /// </summary> public virtual int GetItemCap(vp_ItemType type) { if (!CapsEnabled) return UNLIMITED; for (int v = 0; v < m_ItemCapInstances.Count; v++) { if (m_ItemCapInstances[v].Type == type) return m_ItemCapInstances[v].Cap; } if (AllowOnlyListed) return 0; return UNLIMITED; }
/// <summary> /// returns the first item instance associated with 'id' (if any). /// if 'id' is zero or lower, returns the first item of 'itemType'. /// this method uses a temporary dictionary to speed things up. /// if the item can't be found in the dictionary, tries to add it /// to the dictionary from the serialized list. returns null if /// 'itemType' is null or no matching item can be found /// </summary> public vp_ItemInstance GetItem(vp_ItemType itemType, int id) { //Debug.Log("GetItem @ " + Time.frameCount); // TIP: turn the comments in this method into debug output for // a very detailed look at the code flow at runtime if (itemType == null) { Debug.LogError("Error (" + vp_Utility.GetErrorLocation(1, true) + ") Sent a null itemType to 'GetItem'."); return null; } if (id < 1) { //Debug.Log("no ID was specified: returning the first item of matching type"); return GetItem(itemType); } if (m_ItemDictionaryDirty) { //Debug.Log("resetting the dictionary"); m_ItemDictionary.Clear(); m_ItemDictionaryDirty = false; } //Debug.Log("we have an ID (" + id + "): try to fetch an associated instance from the dictionary"); if (!m_ItemDictionary.TryGetValue(id, out m_GetItemResult)) { //Debug.Log("DID NOT find item in the dictionary: trying to find it in the list"); m_GetItemResult = GetItemFromList(itemType, id); if ((m_GetItemResult != null) && (id > 0)) { //Debug.Log("found id '"+id+"' in the list! adding it to dictionary"); m_ItemDictionary.Add(id, m_GetItemResult); } } else if (m_GetItemResult != null) { //Debug.Log("DID find a quick-match by ID ("+id+") in the dictionary: verifying the item type"); if (m_GetItemResult.Type != itemType) { //Debug.Log("type (" + m_GetItemResult.Type + ") was wrong (expected " + itemType + ") trying to get item from the list"); Debug.LogWarning("Warning: (vp_Inventory) Player has vp_FPWeapons with identical, non-zero vp_ItemIdentifier IDs! This is much slower than using zero or differing IDs."); m_GetItemResult = GetItemFromList(itemType, id); } } else { //Debug.Log("we found item in the dictionary but it was null"); m_ItemDictionary.Remove(id); GetItem(itemType, id); } //if (m_GetItemResult != null) Debug.Log("found item: " + m_GetItemResult + ", Type: " + m_GetItemResult.Type + ", ID: " + m_GetItemResult.ID); //else Debug.Log("found no matching item"); return m_GetItemResult; }
public StartItemRecord(vp_ItemType type, int id, int amount) { Type = type; ID = id; Amount = amount; }
/// <summary> /// internal method which can add items by type, amount and ID. /// </summary> public virtual bool TryGiveItem(vp_ItemType itemType, int id) { if (itemType == null) { Debug.LogError("Error (" + vp_Utility.GetErrorLocation(2) + ") Item type was null."); return false; } // forward to the correct method if this was a unit type vp_UnitType unitType = itemType as vp_UnitType; if (unitType != null) return TryGiveUnits(unitType, id); // in this case treat int argument as 'amount' // forward to the correct method if this was a unitbank type vp_UnitBankType unitBankType = itemType as vp_UnitBankType; if (unitBankType != null) return TryGiveUnitBank(unitBankType, unitBankType.Capacity, id); // enforce item cap for this type of item if (CapsEnabled) { int capacity = GetItemCap(itemType); if ((capacity != UNLIMITED) && (GetItemCount(itemType) >= capacity)) return false; } // enforce space limitations of the inventory if (SpaceEnabled) { if ((UsedSpace + itemType.Space) > TotalSpace) return false; } DoAddItem(itemType, id); return true; }
/// <summary> /// NOTE: only for item unit banks (such as weapons) /// </summary> public virtual bool TryReload(vp_ItemType itemType, int unitBankId) { return TryReload(GetItem(itemType, unitBankId) as vp_UnitBankInstance, MAXCAPACITY); }
/// <summary> /// NOTE: only for item unit banks (such as weapons) /// </summary> public virtual bool TryReload(vp_ItemType itemType, int unitBankId, int amount) { return TryReload(GetItem(itemType, unitBankId) as vp_UnitBankInstance, amount); }
/// <summary> /// /// </summary> public virtual vp_ItemInstance GetItem(vp_ItemType itemType) { // TIP: turn the comments in this method into debug output for // a very detailed look at the code flow at runtime // recreate the dictionary if needed (items may have been added, removed) if (m_FirstItemsDirty) { //Debug.Log("recreating the 'm_FirstItemsOfType' dictionary"); m_FirstItemsOfType.Clear(); foreach (vp_ItemInstance itemInstance in ItemInstances) { if (itemInstance == null) continue; if (!m_FirstItemsOfType.ContainsKey(itemInstance.Type)) m_FirstItemsOfType.Add(itemInstance.Type, itemInstance); } foreach (vp_UnitBankInstance itemInstance in UnitBankInstances) { if (itemInstance == null) continue; if(!m_FirstItemsOfType.ContainsKey(itemInstance.Type)) m_FirstItemsOfType.Add(itemInstance.Type, itemInstance); } m_FirstItemsDirty = false; } //Debug.Log("trying to fetch an instance of the target item type"); if ((itemType == null) || !m_FirstItemsOfType.TryGetValue(itemType, out m_GetFirstItemInstanceResult)) { //Debug.Log("no match: returning null"); return null; } //Debug.Log("an instance of the target item type was found: perform a null check"); if (m_GetFirstItemInstanceResult == null) { //Debug.Log("the instance was null: so refresh dictionary and run the method all over again"); m_FirstItemsDirty = true; return GetItem(itemType); } //Debug.Log("item was found"); return m_GetFirstItemInstanceResult; }
/// <summary> /// /// </summary> public virtual bool HaveItem(vp_ItemType itemType, int id = UNIDENTIFIED) { if (itemType == null) return false; return GetItem(itemType, id) != null; }
/// <summary> /// /// </summary> protected virtual void TryWieldNewItem(vp_ItemType type, bool alreadyHaveIt) { bool haveHadItBefore = m_PreviouslyOwnedItems.ContainsKey(type); if (!haveHadItBefore) { m_PreviouslyOwnedItems.Add(type, null); } // --- see if we should try to wield a weapon because of this item pickup --- if (m_AutoWield.Always) { goto tryWield; } if (m_AutoWield.IfUnarmed && (WeaponHandler.CurrentWeaponIndex < 1)) { goto tryWield; } if (m_AutoWield.IfOutOfAmmo && (WeaponHandler.CurrentWeaponIndex > 0) && (WeaponHandler.CurrentWeapon.AnimationType != (int)vp_Weapon.Type.Melee) && m_Player.CurrentWeaponAmmoCount.Get() < 1) { goto tryWield; } if (m_AutoWield.IfNotPresent && !m_AutoWield.FirstTimeOnly && !alreadyHaveIt) { goto tryWield; } if (m_AutoWield.FirstTimeOnly && !haveHadItBefore) { goto tryWield; } return; tryWield: if ((type is vp_UnitBankType)) { TryWield(GetItem(type)); } else if (type is vp_UnitType) { TryWieldByUnit(type as vp_UnitType); } else if (type is vp_ItemType) // tested last since the others derive from it { TryWield(GetItem(type)); } else { System.Type baseType = type.GetType(); if (baseType == null) { return; } baseType = baseType.BaseType; if ((baseType == typeof(vp_UnitBankType))) { TryWield(GetItem(type)); } else if (baseType == typeof(vp_UnitType)) { TryWieldByUnit(type as vp_UnitType); } else if (baseType == typeof(vp_ItemType)) { TryWield(GetItem(type)); } } }
/// <summary> /// returns true if inventory has items of 'itemType', and the /// amount of existing items is modified or unchanged. returns /// false if there are no matching items /// </summary> protected static bool TryMatchExistingItem(vp_Inventory inventory, Transform recipient, vp_ItemType itemType, int amount) { //Debug.Log("--- TryMatchExistingItem ---"); //Debug.Log("recipient: " + recipient); //Debug.Log("item type: " + itemType); //Debug.Log("amount: " + amount); System.Type type = itemType.GetType(); if ((type == typeof(vp_UnitBankType)) || (type.BaseType == typeof(vp_UnitBankType))) { vp_UnitBankInstance ui = inventory.GetItem(itemType) as vp_UnitBankInstance; if (ui != null) { ui.Count = amount; return true; } } else if ((type == typeof(vp_UnitType)) || (type.BaseType == typeof(vp_UnitType))) { if (inventory.HaveInternalUnitBank(itemType as vp_UnitType)) { vp_UnitBankInstance ui = inventory.GetInternalUnitBank(itemType as vp_UnitType); ui.Count = amount; return true; } } else if ((type == typeof(vp_ItemType)) || (type.BaseType == typeof(vp_ItemType))) { int existing = inventory.GetItemCount(itemType); //Debug.Log("currently existing in inventory: " + existing); if (existing > 0) { int adjustment = (amount - existing); //Debug.Log("needed adjustment: " + adjustment); if (adjustment < 0) { //Debug.Log("adjustment less than zero. running 'TryRemoveItems' with argument '" + adjustment + "' and result: " + inventory.TryRemoveItems(itemType, Mathf.Abs(adjustment)); //); } else if (adjustment > 0) { //Debug.Log("adjustment more than zero. running 'TryGiveItems' with argument '" + adjustment + "' and result: " + inventory.TryGiveItems(itemType, adjustment); //); } return true; } } //Debug.Log("------------------------"); return false; }
/// <summary> /// sets item count to higher or lower than current, regardless /// of item cap. this can be used for game designs allowing /// for a one-time addition of excess items. NOTE: if caps /// should be imposed, instead use 'TryGiveItem. /// </summary> public virtual void SetItemCount(vp_ItemType type, int amount) { if (type is vp_UnitType) { SetUnitCount((vp_UnitType)type, amount); return; } // if we are to ignore item caps and inventory space, temporarily disable them bool capsEnabledBak = CapsEnabled; bool spaceEnabledBak = SpaceEnabled; CapsEnabled = false; SpaceEnabled = false; // either give or remove items to reach target amount int amountToGive = amount - GetItemCount(type); if (amountToGive > 0) TryGiveItems(type, amount); else if (amountToGive < 0) TryRemoveItems(type, -amount); CapsEnabled = capsEnabledBak; SpaceEnabled = spaceEnabledBak; }
/// <summary> /// /// </summary> public virtual int GetItemCount(vp_ItemType type) { vp_UnitType unitType = type as vp_UnitType; if (unitType != null) return GetUnitCount(unitType); int count = 0; for (int v = 0; v < ItemInstances.Count; v++) { if (ItemInstances[v].Type == type) count++; } for (int v = 0; v < m_UnitBankInstances.Count; v++) { if (m_UnitBankInstances[v].Type == type) count++; } return count; }
public ItemCap(vp_ItemType type, int cap) { Type = type; Cap = cap; }