Exemple #1
0
        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);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
            }
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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);
            }
        }