Ejemplo n.º 1
0
        private void DeleteUndelete(bool redo)
        {
            bool wasDeleted = WasDeleted;

            // We are redoing instead of undoing, flip the behavior
            if (redo)
            {
                wasDeleted = !wasDeleted;
            }

            if (wasDeleted)
            {
                Debug.Assert(Receivers.All(entity => entity.GetReplacementOrThis().Removed), "Tried to redo a deletion but some items were not deleted");

                List <MapEntity> clones = MapEntity.Clone(CloneList);
                int length = Math.Min(Receivers.Count, clones.Count);
                for (int i = 0; i < length; i++)
                {
                    MapEntity clone = clones[i], receiver = Receivers[i];

                    if (receiver.GetReplacementOrThis() is Item item && clone is Item cloneItem)
                    {
                        foreach (ItemComponent ic in item.Components)
                        {
                            int           index     = item.GetComponentIndex(ic);
                            ItemComponent component = cloneItem.Components.ElementAtOrDefault(index);
                            switch (component)
                            {
                            case null:
                                continue;

                            case ItemContainer newContainer when newContainer.Inventory != null && ic is ItemContainer itemContainer && itemContainer.Inventory != null:
                                itemContainer.Inventory.GetReplacementOrThiS().ReplacedBy = newContainer.Inventory;
                                goto default;

                            default:
                                ic.GetReplacementOrThis().ReplacedBy = component;
                                break;
                            }
                        }
                    }

                    receiver.GetReplacementOrThis().ReplacedBy = clone;
                }

                for (int i = 0; i < length; i++)
                {
                    MapEntity clone = clones[i], receiver = Receivers[i];

                    if (clone is Item it)
                    {
                        foreach (var(slotRef, inventory) in PreviousInventories)
                        {
                            if (slotRef.Item == receiver)
                            {
                                inventory.GetReplacementOrThiS().TryPutItem(it, slotRef.Slot, false, false, null, createNetworkEvent: false);
                            }
                        }
                    }
                }

                foreach (MapEntity clone in clones)
                {
                    clone.Submarine = Submarine.MainSub;
                }
            }
            else
            {
                foreach (MapEntity t in Receivers)
                {
                    MapEntity receiver = t.GetReplacementOrThis();
                    if (!receiver.Removed)
                    {
                        receiver.Remove();
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates a command where all entities share the same state.
        /// </summary>
        /// <param name="receivers">Entities that were deleted or added</param>
        /// <param name="wasDeleted">Whether or not all entities are or are going to be deleted</param>
        /// <param name="handleInventoryBehavior">Ignore item inventories when set to false, workaround for pasting</param>
        public AddOrDeleteCommand(List <MapEntity> receivers, bool wasDeleted, bool handleInventoryBehavior = true)
        {
            WasDeleted = wasDeleted;
            Receivers  = receivers;

            try
            {
                foreach (MapEntity receiver in receivers)
                {
                    if (receiver is Item it && it.ParentInventory != null)
                    {
                        PreviousInventories.Add(new InventorySlotItem(Array.IndexOf(it.ParentInventory.Items, it), it), it.ParentInventory);
                    }
                }

                List <MapEntity> clonedTargets = MapEntity.Clone(receivers);

                List <MapEntity> itemsToDelete = new List <MapEntity>();
                foreach (MapEntity receiver in Receivers)
                {
                    if (receiver is Item it)
                    {
                        foreach (ItemContainer component in it.GetComponents <ItemContainer>())
                        {
                            if (component.Inventory == null)
                            {
                                continue;
                            }

                            itemsToDelete.AddRange(component.Inventory.Items.Where(item => item != null && !item.Removed));
                        }
                    }
                }

                if (itemsToDelete.Any() && handleInventoryBehavior)
                {
                    ContainedItemsCommand.Add(new AddOrDeleteCommand(itemsToDelete, wasDeleted));
                    if (wasDeleted)
                    {
                        foreach (MapEntity item in itemsToDelete)
                        {
                            if (item != null && !item.Removed)
                            {
                                item.Remove();
                            }
                        }
                    }
                }

                foreach (MapEntity clone in clonedTargets)
                {
                    clone.ShallowRemove();
                    if (clone is Item it)
                    {
                        foreach (ItemContainer container in it.GetComponents <ItemContainer>())
                        {
                            container.Inventory?.DeleteAllItems();
                        }
                    }
                }

                CloneList = clonedTargets;
            }
            // This should never happen except if we decide to make a new type of MapEntity that isn't finished yet
            catch (Exception e)
            {
                Receivers = new List <MapEntity>();
                CloneList = new List <MapEntity>();
                DebugConsole.ThrowError("Could not store object", e);
            }
        }