private void InitializeJobItem(Character character, WayPoint spawnPoint, XElement itemElement, Item parentItem = null) { string itemName = itemElement.GetAttributeString("name", ""); ItemPrefab itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemName + "\". Matching item prefab not found."); return; } Item item = new Item(itemPrefab, character.Position, null); if (GameMain.Server != null && Entity.Spawner != null) { Entity.Spawner.CreateNetworkEvent(item, false); } if (itemElement.GetAttributeBool("equip", false)) { List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots); allowedSlots.Remove(InvSlotType.Any); character.Inventory.TryPutItem(item, null, allowedSlots); } else { character.Inventory.TryPutItem(item, null, item.AllowedSlots); } if (item.Prefab.NameMatches("ID Card") && spawnPoint != null) { foreach (string s in spawnPoint.IdCardTags) { item.AddTag(s); } item.AddTag("name:" + character.Name); item.AddTag("job:" + Name); if (!string.IsNullOrWhiteSpace(spawnPoint.IdCardDesc)) { item.Description = spawnPoint.IdCardDesc; } } foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = character.TeamID; } if (parentItem != null) { parentItem.Combine(item); } foreach (XElement childItemElement in itemElement.Elements()) { InitializeJobItem(character, spawnPoint, childItemElement, item); } }
public static Item FindItemRecursive(Item item, Predicate <Item> condition) { if (condition.Invoke(item)) { return(item); } var containers = item.GetComponents <ItemContainer>(); if (containers != null) { foreach (var container in containers) { foreach (var inventoryItem in container.Inventory.Items) { var findItem = FindItemRecursive(inventoryItem, condition); if (findItem != null) { return(findItem); } } } } return(null); }
private static bool SpawnItem(ItemPrefab itemPrefab, List <ItemContainer> containers, KeyValuePair <ItemContainer, PreferredContainer> validContainer) { bool success = false; if (Rand.Value() > validContainer.Value.SpawnProbability) { return(false); } // Don't add dangerously reactive materials in thalamus wrecks if (validContainer.Key.Item.Submarine.WreckAI != null && itemPrefab.Tags.Contains("explodesinwater")) { return(false); } int amount = Rand.Range(validContainer.Value.MinAmount, validContainer.Value.MaxAmount + 1); for (int i = 0; i < amount; i++) { if (validContainer.Key.Inventory.IsFull()) { containers.Remove(validContainer.Key); break; } var item = new Item(itemPrefab, validContainer.Key.Item.Position, validContainer.Key.Item.Submarine); spawnedItems.Add(item); #if SERVER Entity.Spawner.CreateNetworkEvent(item, remove: false); #endif validContainer.Key.Inventory.TryPutItem(item, null); containers.AddRange(item.GetComponents <ItemContainer>()); success = true; } return(success); }
private static bool SpawnItem(ItemPrefab itemPrefab, List <ItemContainer> containers, KeyValuePair <ItemContainer, PreferredContainer> validContainer) { bool success = false; if (Rand.Value(Rand.RandSync.Server) > validContainer.Value.SpawnProbability) { return(false); } // Don't add dangerously reactive materials in thalamus wrecks if (validContainer.Key.Item.Submarine.WreckAI != null && itemPrefab.Tags.Contains("explodesinwater")) { return(false); } int amount = Rand.Range(validContainer.Value.MinAmount, validContainer.Value.MaxAmount + 1, Rand.RandSync.Server); for (int i = 0; i < amount; i++) { if (validContainer.Key.Inventory.IsFull(takeStacksIntoAccount: true)) { containers.Remove(validContainer.Key); break; } if (!validContainer.Key.Inventory.CanBePut(itemPrefab)) { break; } var item = new Item(itemPrefab, validContainer.Key.Item.Position, validContainer.Key.Item.Submarine) { SpawnedInOutpost = validContainer.Key.Item.SpawnedInOutpost, AllowStealing = validContainer.Key.Item.AllowStealing, OriginalModuleIndex = validContainer.Key.Item.OriginalModuleIndex, OriginalContainerIndex = Item.ItemList.Where(it => it.Submarine == validContainer.Key.Item.Submarine && it.OriginalModuleIndex == validContainer.Key.Item.OriginalModuleIndex).ToList().IndexOf(validContainer.Key.Item) }; foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = validContainer.Key.Item.Submarine.TeamID; } spawnedItems.Add(item); validContainer.Key.Inventory.TryPutItem(item, null, createNetworkEvent: false); containers.AddRange(item.GetComponents <ItemContainer>()); success = true; } return(success); }
static void itemSpawned(Item item) { Submarine sub = item.Submarine ?? item.GetRootContainer()?.Submarine; if (sub != null) { foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = sub.TeamID; } } }
public override bool TryPutItem(Item item, int index, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true, bool ignoreCondition = false) { if (index < 0 || index >= slots.Length) { string errorMsg = "CharacterInventory.TryPutItem failed: index was out of range(" + index + ").\n" + Environment.StackTrace.CleanupStackTrace(); GameAnalyticsManager.AddErrorEventOnce("CharacterInventory.TryPutItem:IndexOutOfRange", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); return(false); } #if CLIENT if (PersonalSlots.HasFlag(SlotTypes[index])) { hidePersonalSlots = false; } #endif //there's already an item in the slot if (slots[index].Any()) { if (slots[index].Contains(item)) { return(false); } return(base.TryPutItem(item, index, allowSwapping, allowCombine, user, createNetworkEvent, ignoreCondition)); } if (SlotTypes[index] == InvSlotType.Any) { if (!item.GetComponents <Pickable>().Any(p => p.AllowedSlots.Contains(InvSlotType.Any))) { return(false); } if (slots[index].Any()) { return(slots[index].Contains(item)); } PutItem(item, index, user, true, createNetworkEvent); return(true); } InvSlotType placeToSlots = InvSlotType.None; bool slotsFree = true; foreach (Pickable pickable in item.GetComponents <Pickable>()) { foreach (InvSlotType allowedSlot in pickable.AllowedSlots) { if (!allowedSlot.HasFlag(SlotTypes[index])) { continue; } #if CLIENT if (PersonalSlots.HasFlag(allowedSlot)) { hidePersonalSlots = false; } #endif for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(SlotTypes[i]) && slots[i].Any() && !slots[i].Contains(item)) { slotsFree = false; break; } placeToSlots = allowedSlot; } } } if (!slotsFree) { return(false); } return(TryPutItem(item, user, new List <InvSlotType>() { placeToSlots }, createNetworkEvent, ignoreCondition)); }
/// <summary> /// If there is room, puts the item in the inventory and returns true, otherwise returns false /// </summary> public override bool TryPutItem(Item item, Character user, IEnumerable <InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool ignoreCondition = false) { if (allowedSlots == null || !allowedSlots.Any()) { return(false); } if (item == null) { #if DEBUG throw new Exception("item null"); #else return(false); #endif } if (item.Removed) { #if DEBUG throw new Exception("Tried to put a removed item (" + item.Name + ") in an inventory"); #else DebugConsole.ThrowError("Tried to put a removed item (" + item.Name + ") in an inventory.\n" + Environment.StackTrace.CleanupStackTrace()); return(false); #endif } bool inSuitableSlot = false; bool inWrongSlot = false; int currentSlot = -1; for (int i = 0; i < capacity; i++) { if (slots[i].Contains(item)) { currentSlot = i; if (allowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { inSuitableSlot = true; } else if (!allowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { inWrongSlot = true; } } } //all good if (inSuitableSlot && !inWrongSlot) { return(true); } //try to place the item in a LimbSlot.Any slot if that's allowed if (allowedSlots.Contains(InvSlotType.Any) && item.AllowedSlots.Contains(InvSlotType.Any)) { int freeIndex = CheckIfAnySlotAvailable(item, inWrongSlot); if (freeIndex > -1) { PutItem(item, freeIndex, user, true, createNetworkEvent); item.Unequip(character); return(true); } } int placedInSlot = -1; foreach (InvSlotType allowedSlot in allowedSlots) { if (allowedSlot.HasFlag(InvSlotType.RightHand) && character.AnimController.GetLimb(LimbType.RightHand) == null) { continue; } if (allowedSlot.HasFlag(InvSlotType.LeftHand) && character.AnimController.GetLimb(LimbType.LeftHand) == null) { continue; } //check if all the required slots are free bool free = true; for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(SlotTypes[i]) && item.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i])) && slots[i].Items.Any(it => it != item)) { #if CLIENT if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; } #endif if (!slots[i].First().AllowedSlots.Contains(InvSlotType.Any) || !TryPutItem(slots[i].FirstOrDefault(), character, new List <InvSlotType> { InvSlotType.Any }, true, ignoreCondition)) { free = false; #if CLIENT for (int j = 0; j < capacity; j++) { if (visualSlots != null && slots[j] == slots[i]) { visualSlots[j].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f); } } #endif } } } if (!free) { continue; } for (int i = 0; i < capacity; i++) { if (allowedSlot.HasFlag(SlotTypes[i]) && item.GetComponents <Pickable>().Any(p => p.AllowedSlots.Any(s => s.HasFlag(SlotTypes[i]))) && slots[i].Empty()) { #if CLIENT if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; } #endif bool removeFromOtherSlots = item.ParentInventory != this; if (placedInSlot == -1 && inWrongSlot) { if (!slots[i].HideIfEmpty || SlotTypes[currentSlot] != InvSlotType.Any) { removeFromOtherSlots = true; } } PutItem(item, i, user, removeFromOtherSlots, createNetworkEvent); item.Equip(character); placedInSlot = i; } } if (placedInSlot > -1) { break; } } return(placedInSlot > -1); }
private void InitializeJobItem(Character character, XElement itemElement, WayPoint spawnPoint = null, Item parentItem = null) { ItemPrefab itemPrefab; if (itemElement.Attribute("name") != null) { string itemName = itemElement.Attribute("name").Value; DebugConsole.ThrowError("Error in Job config (" + Name + ") - use item identifiers instead of names to configure the items."); itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemName + "\". Matching item prefab not found."); return; } } else { string itemIdentifier = itemElement.GetAttributeString("identifier", ""); itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemIdentifier + "\". Matching item prefab not found."); return; } } Item item = new Item(itemPrefab, character.Position, null); #if SERVER if (GameMain.Server != null && Entity.Spawner != null) { if (GameMain.Server.EntityEventManager.UniqueEvents.Any(ev => ev.Entity == item)) { string errorMsg = $"Error while spawning job items. Item {item.Name} created network events before the spawn event had been created."; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Job.InitializeJobItem:EventsBeforeSpawning", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); GameMain.Server.EntityEventManager.UniqueEvents.RemoveAll(ev => ev.Entity == item); GameMain.Server.EntityEventManager.Events.RemoveAll(ev => ev.Entity == item); } Entity.Spawner.CreateNetworkEvent(item, false); } #endif if (itemElement.GetAttributeBool("equip", false)) { List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots); allowedSlots.Remove(InvSlotType.Any); character.Inventory.TryPutItem(item, null, allowedSlots); } else { character.Inventory.TryPutItem(item, null, item.AllowedSlots); } Wearable wearable = ((List <ItemComponent>)item.Components)?.Find(c => c is Wearable) as Wearable; if (wearable != null) { if (Variant > 0 && Variant <= wearable.Variants) { wearable.Variant = Variant; } else { wearable.Variant = wearable.Variant; //force server event if (wearable.Variants > 0 && Variant == 0) { //set variant to the same as the wearable to get the rest of the character's gear //to use the same variant (if possible) Variant = wearable.Variant; } } } if (item.Prefab.Identifier == "idcard" && spawnPoint != null) { foreach (string s in spawnPoint.IdCardTags) { item.AddTag(s); } item.AddTag("name:" + character.Name); item.AddTag("job:" + Name); if (!string.IsNullOrWhiteSpace(spawnPoint.IdCardDesc)) { item.Description = spawnPoint.IdCardDesc; } IdCard idCardComponent = item.GetComponent <IdCard>(); if (idCardComponent != null) { idCardComponent.Initialize(character.Info); } } foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = character.TeamID; } if (parentItem != null) { parentItem.Combine(item, user: null); } foreach (XElement childItemElement in itemElement.Elements()) { InitializeJobItem(character, childItemElement, spawnPoint, item); } }
public static Item ReadSpawnData(NetBuffer msg, bool spawn = true) { string itemName = msg.ReadString(); string itemIdentifier = msg.ReadString(); bool descriptionChanged = msg.ReadBoolean(); string itemDesc = ""; if (descriptionChanged) { itemDesc = msg.ReadString(); } ushort itemId = msg.ReadUInt16(); ushort inventoryId = msg.ReadUInt16(); DebugConsole.Log("Received entity spawn message for item " + itemName + "."); Vector2 pos = Vector2.Zero; Submarine sub = null; int itemContainerIndex = -1; int inventorySlotIndex = -1; if (inventoryId > 0) { itemContainerIndex = msg.ReadByte(); inventorySlotIndex = msg.ReadByte(); } else { pos = new Vector2(msg.ReadSingle(), msg.ReadSingle()); ushort subID = msg.ReadUInt16(); if (subID > 0) { sub = Submarine.Loaded.Find(s => s.ID == subID); } } byte teamID = msg.ReadByte(); bool tagsChanged = msg.ReadBoolean(); string tags = ""; if (tagsChanged) { tags = msg.ReadString(); } if (!spawn) { return(null); } //---------------------------------------- var itemPrefab = MapEntityPrefab.Find(itemName, itemIdentifier) as ItemPrefab; if (itemPrefab == null) { return(null); } Inventory inventory = null; var inventoryOwner = FindEntityByID(inventoryId); if (inventoryOwner != null) { if (inventoryOwner is Character) { inventory = (inventoryOwner as Character).Inventory; } else if (inventoryOwner is Item) { if ((inventoryOwner as Item).components[itemContainerIndex] is ItemContainer container) { inventory = container.Inventory; } } } var item = new Item(itemPrefab, pos, sub) { ID = itemId }; foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = (Character.TeamType)teamID; } if (descriptionChanged) { item.Description = itemDesc; } if (tagsChanged) { item.Tags = tags; } if (sub != null) { item.CurrentHull = Hull.FindHull(pos + sub.Position, null, true); item.Submarine = item.CurrentHull?.Submarine; } if (inventory != null) { if (inventorySlotIndex >= 0 && inventorySlotIndex < 255 && inventory.TryPutItem(item, inventorySlotIndex, false, false, null, false)) { return(null); } inventory.TryPutItem(item, null, item.AllowedSlots, false); } return(item); }
private void InitializeItems(Character character, XElement itemElement, Submarine submarine, Item parentItem = null) { ItemPrefab itemPrefab; string itemIdentifier = itemElement.GetAttributeString("identifier", ""); itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab; if (itemPrefab == null) { DebugConsole.ThrowError("Tried to spawn \"" + Identifier + "\" with the item \"" + itemIdentifier + "\". Matching item prefab not found."); return; } Item item = new Item(itemPrefab, character.Position, null); #if SERVER if (GameMain.Server != null && Entity.Spawner != null) { if (GameMain.Server.EntityEventManager.UniqueEvents.Any(ev => ev.Entity == item)) { string errorMsg = $"Error while spawning job items. Item {item.Name} created network events before the spawn event had been created."; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Job.InitializeJobItem:EventsBeforeSpawning", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); GameMain.Server.EntityEventManager.UniqueEvents.RemoveAll(ev => ev.Entity == item); GameMain.Server.EntityEventManager.Events.RemoveAll(ev => ev.Entity == item); } Entity.Spawner.CreateNetworkEvent(item, false); } #endif if (itemElement.GetAttributeBool("equip", false)) { List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots); allowedSlots.Remove(InvSlotType.Any); character.Inventory.TryPutItem(item, null, allowedSlots); } else { character.Inventory.TryPutItem(item, null, item.AllowedSlots); } if (item.Prefab.Identifier == "idcard" || item.Prefab.Identifier == "idcardwreck") { item.AddTag("name:" + character.Name); item.ReplaceTag("wreck_id", Level.Loaded.GetWreckIDTag("wreck_id", submarine)); var job = character.Info?.Job; if (job != null) { item.AddTag("job:" + job.Name); } } foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = character.TeamID; } if (parentItem != null) { parentItem.Combine(item, user: null); } foreach (XElement childItemElement in itemElement.Elements()) { InitializeItems(character, childItemElement, submarine, item); } }