Example #1
0
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            var svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;

            if ((value is string || value == null) && svc != null)
            {
                // Preselect old entry.
                _dialog.SelectedItemName = value as string;

                // Restrict selection.
                var giContext = context as GridItem;
                if (giContext == null ||
                    giContext.Parent == null ||
                    giContext.Parent.Parent == null ||
                    giContext.Parent.Parent.Parent == null ||
                    giContext.Parent.Parent.Parent.Value == null)
                {
                    MessageBox.Show("Cannot edit here.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return(value);
                }
                if (giContext.Parent.Parent.Parent.Value is ShipFactory)
                {
                    // Top level item, only allow fuselage.
                    _dialog.AvailableSlots = new[] { new ItemFactory.ItemSlotInfo {
                                                         Size = ItemSlotSize.Small, Type = ItemFactory.ItemSlotInfo.ItemType.Fuselage
                                                     } };
                }
                else
                {
                    // Somewhere in the tree, get parent.
                    var containingItem = giContext.Parent.Parent.Parent.Value as ShipFactory.ItemInfo;
                    if (containingItem == null || string.IsNullOrWhiteSpace(containingItem.Name))
                    {
                        // Null parent, don't allow adding items.
                        MessageBox.Show("Cannot add to empty items.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return(value);
                    }
                    var containingFactory = FactoryManager.GetFactory(containingItem.Name) as ItemFactory;
                    if (containingFactory == null)
                    {
                        // Invalid parent, don't allow adding items.
                        MessageBox.Show("Cannot determine valid items due to invalid parent entry.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return(value);
                    }
                    // Figure out available slots.
                    var availableSlots = new List <ItemFactory.ItemSlotInfo>();
                    if (containingFactory.Slots != null)
                    {
                        availableSlots.AddRange(containingFactory.Slots);
                    }
                    else
                    {
                        // Item has no slots, don't allow adding items.
                        MessageBox.Show("Cannot add any more items: no more free slots.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return(value);
                    }
                    // Remove used ones.
                    foreach (var slot in containingItem.Slots)
                    {
                        // Skip self.
                        if (slot == context.Instance)
                        {
                            continue;
                        }

                        // Skip empty ones.
                        if (string.IsNullOrWhiteSpace(slot.Name))
                        {
                            continue;
                        }

                        // Get the item of that type.
                        var slotItemFactory = FactoryManager.GetFactory(slot.Name) as ItemFactory;
                        if (slotItemFactory == null)
                        {
                            continue;
                        }

                        // OK, try to consume a slot (the smallest one possible).
                        var type = slotItemFactory.GetType().ToItemType();
                        var size = slotItemFactory.RequiredSlotSize;
                        ItemFactory.ItemSlotInfo bestSlot = null;
                        foreach (var availableSlot in availableSlots)
                        {
                            if (availableSlot.Type != type || availableSlot.Size < size)
                            {
                                continue;
                            }
                            if (bestSlot == null || availableSlot.Size < bestSlot.Size)
                            {
                                bestSlot = availableSlot;
                            }
                        }
                        if (bestSlot != null)
                        {
                            availableSlots.Remove(bestSlot);
                        }
                    }
                    // Skip if no slots remain.
                    if (availableSlots.Count == 0)
                    {
                        MessageBox.Show("Cannot add any more items: no items known that would fit the remaining slots.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return(value);
                    }
                    // Set remaining slots.
                    _dialog.AvailableSlots = availableSlots;
                }

                if (svc.ShowDialog(_dialog) == DialogResult.OK)
                {
                    return(_dialog.SelectedItemName);
                }
            }
            return(base.EditValue(context, provider, value));
        }
Example #2
0
        /// <summary>
        /// Check default loadout (equipment) of ships for validity.
        /// </summary>
        /// <param name="factory">The factory.</param>
        private void ScanFactory(ShipFactory factory)
        {
            if (factory == null)
            {
                return;
            }

            // Check collision bounds.
            if (factory.CollisionRadius <= 0f)
            {
                AddIssue("Ship has no collision radius.", factory, "CollisionRadius", IssueType.Information);
            }

            // Validate selected items. Make sure the root item is a fuselage.
            var root = factory.Items;

            if (root != null)
            {
                // We only check if the root item is a fuselage here, other checks will
                // we done in the loop below.
                var rootItem = FactoryManager.GetFactory(root.Name) as ItemFactory;
                if (rootItem != null && !(rootItem is FuselageFactory))
                {
                    AddIssue("Root item must always be a fuselage.", factory, "Items", IssueType.Error);
                }
            }
            else
            {
                // Nothing to do.
                return;
            }

            // Start with the fuselage.
            var items = new Stack <Tuple <ShipFactory.ItemInfo, string> >();

            items.Push(Tuple.Create(root, "Items"));
            while (items.Count > 0)
            {
                // Get entry info, skip empty ones.
                var entry  = items.Pop();
                var item   = entry.Item1;
                var prefix = entry.Item2;
                if (item == null)
                {
                    continue;
                }

                // Check asset references.
                ScanReferences(factory, item, prefix);

                // Adjust prefix for further access.
                prefix = string.IsNullOrWhiteSpace(prefix) ? "" : (prefix + ".");

                // Notify about empty slots that can be removed, but keep going
                // to properly warn if any items are equipped in this null item.
                if (string.IsNullOrWhiteSpace(item.Name))
                {
                    AddIssue("Empty item name, branch will be skipped when generating the ship.", factory, prefix + "Name", IssueType.Information);
                }

                // Queue checks for children.
                for (var i = 0; i < item.Slots.Length; i++)
                {
                    items.Push(Tuple.Create(item.Slots[i], prefix + "Slots[" + i + "]"));
                }

                // Get slot information to validate occupied slots.
                var itemFactory    = FactoryManager.GetFactory(item.Name) as ItemFactory;
                var availableSlots = new List <ItemFactory.ItemSlotInfo>();
                if (itemFactory != null && itemFactory.Slots != null)
                {
                    availableSlots.AddRange(itemFactory.Slots);
                }
                for (var i = 0; i < item.Slots.Length; i++)
                {
                    var slot = item.Slots[i];

                    // Skip empty ones.
                    if (string.IsNullOrWhiteSpace(slot.Name))
                    {
                        continue;
                    }

                    // Get the item of that type. Skip if unknown (warning will come when that
                    // item itself is processed).
                    var slotItemFactory = FactoryManager.GetFactory(slot.Name) as ItemFactory;
                    if (slotItemFactory == null)
                    {
                        continue;
                    }

                    // OK, try to consume a slot (the smallest one possible).
                    var type = slotItemFactory.GetType().ToItemType();
                    var size = slotItemFactory.RequiredSlotSize;
                    ItemFactory.ItemSlotInfo bestSlot = null;
                    foreach (var availableSlot in availableSlots)
                    {
                        if (availableSlot.Type != type || availableSlot.Size < size)
                        {
                            continue;
                        }
                        if (bestSlot == null || availableSlot.Size < bestSlot.Size)
                        {
                            bestSlot = availableSlot;
                        }
                    }
                    if (bestSlot == null)
                    {
                        AddIssue("Equipped item cannot be fit into any slot.", factory, prefix + "Slots[" + i + "]", IssueType.Error);
                    }
                    else
                    {
                        availableSlots.Remove(bestSlot);
                    }
                }
            }
        }