Ejemplo n.º 1
0
        private void UpdatePreview(bool force = false)
        {
            if (force)
            {
                SetPreviews(PreviewType.Default, null);
            }

            // Figure out what to show.
            try // evil: using try-catch for flow-control, but who can stop me!? muahahaha
            {
                // Nothing selected, so skip.
                if (pgProperties.SelectedObject == null)
                {
                    SetPreviews(PreviewType.Default, null);
                    return;
                }

                var item = pgProperties.SelectedGridItem;
                while (item != null)
                {
                    // If an image asset is selected we simply show that.
                    if (item.PropertyDescriptor != null)
                    {
                        if (item.PropertyDescriptor.Attributes[typeof(EditorAttribute)] != null)
                        {
                            var editorType = Type.GetType(((EditorAttribute)item.PropertyDescriptor.Attributes[typeof(EditorAttribute)]).EditorTypeName);
                            if (editorType == typeof(TextureAssetEditor))
                            {
                                RenderTextureAssetPreview(item.Value as string);
                                return;
                            }
                            if (editorType == typeof(EffectAssetEditor))
                            {
                                RenderEffectAssetPreview(item.Value as string);
                                return;
                            }
                            if (editorType == typeof(PlanetEditor))
                            {
                                RenderPlanetPreview(FactoryManager.GetFactory(item.Value as string) as PlanetFactory);
                                return;
                            }
                            if (editorType == typeof(SunEditor))
                            {
                                RenderSunPreview(FactoryManager.GetFactory(item.Value as string) as SunFactory);
                                return;
                            }
                            if (editorType == typeof(ItemInfoEditor))
                            {
                                RenderItemPreview(FactoryManager.GetFactory(item.Value as string) as ItemFactory);
                                return;
                            }
                        }

                        // Render next-best orbit system if possible.
                        if (item.Parent != null && item.Parent.Parent != null &&
                            item.Parent.Parent.PropertyDescriptor != null &&
                            item.Parent.Parent.PropertyDescriptor.PropertyType == typeof(Orbiter))
                        {
                            RenderOrbiterPreview(item.Parent.Parent.Value as Orbiter);
                            return;
                        }
                        // Render next-best item system if possible.
                        if (item.PropertyDescriptor.PropertyType == typeof(ShipFactory.ItemInfo))
                        {
                            var info = item.Value as ShipFactory.ItemInfo;
                            if (info != null)
                            {
                                RenderItemPreview(FactoryManager.GetFactory(info.Name) as ItemFactory);
                                return;
                            }
                        }
                        if (item.PropertyDescriptor.PropertyType == typeof(ItemPool.DropInfo))
                        {
                            var info = item.Value as ItemPool.DropInfo;
                            if (info != null)
                            {
                                RenderItemPreview(FactoryManager.GetFactory(info.ItemName) as ItemFactory);
                                return;
                            }
                        }
                        // Render next-best projectile if possible.
                        if (item.PropertyDescriptor.PropertyType == typeof(ProjectileFactory[]))
                        {
                            RenderProjectilePreview(item.Value as ProjectileFactory[]);
                            return;
                        }
                    }
                    item = item.Parent;
                }

                // We're not rendering based on property grid item selection at this point, so
                // we just try to render the selected object.

                if (pgProperties.SelectedObject is PlanetFactory)
                {
                    RenderPlanetPreview(pgProperties.SelectedObject as PlanetFactory);
                    return;
                }
                if (pgProperties.SelectedObject is SunFactory)
                {
                    RenderSunPreview(pgProperties.SelectedObject as SunFactory);
                    return;
                }
                if (pgProperties.SelectedObject is SunSystemFactory)
                {
                    RenderSunSystemPreview(pgProperties.SelectedObject as SunSystemFactory);
                    return;
                }
                if (pgProperties.SelectedObject is ItemFactory)
                {
                    RenderItemPreview(pgProperties.SelectedObject as ItemFactory);
                    return;
                }
                if (pgProperties.SelectedObject is ShipFactory)
                {
                    RenderShipPreview(pgProperties.SelectedObject as ShipFactory);
                    return;
                }

                // Could not render anything, clear previews.
                SetPreviews(PreviewType.Default, null);
            }
            finally
            {
                // Update the picture box.
                pbPreview.Invalidate();
            }
        }
Ejemplo n.º 2
0
        private bool HandleObjectNameChanged(object oldValue, object newValue, GridItem changedItem)
        {
            // See if what we changed is the name of the selected object.
            if (ReferenceEquals(changedItem.PropertyDescriptor, TypeDescriptor.GetProperties(pgProperties.SelectedObject)["Name"]))
            {
                // Yes, get old and new value.
                var oldName = oldValue as string;
                var newName = newValue as string;

                // Adjust manager layout, this will throw as necessary.
                tvData.BeginUpdate();
                try
                {
                    if (pgProperties.SelectedObject is IFactory)
                    {
                        FactoryManager.Rename(oldName, newName);
                    }
                    else if (pgProperties.SelectedObject is ItemPool)
                    {
                        ItemPoolManager.Rename(oldName, newName);
                    }
                    else if (pgProperties.SelectedObject is AttributePool)
                    {
                        AttributePoolManager.Rename(oldName, newName);
                    }
                }
                catch (ArgumentException ex)
                {
                    // Revert to old name.
                    if (pgProperties.SelectedObject is IFactory)
                    {
                        ((IFactory)pgProperties.SelectedObject).Name = oldName;
                    }
                    else if (pgProperties.SelectedObject is ItemPool)
                    {
                        ((ItemPool)pgProperties.SelectedObject).Name = oldName;
                    }
                    else if (pgProperties.SelectedObject is AttributePool)
                    {
                        ((AttributePool)pgProperties.SelectedObject).Name = oldName;
                    }

                    // Tell the user why.
                    MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(false);
                }
                finally
                {
                    // Stop updating the tree.
                    tvData.EndUpdate();
                }

                if (pgProperties.SelectedObject is IFactory)
                {
                    SelectFactory((IFactory)pgProperties.SelectedObject);
                }
                else if (pgProperties.SelectedObject is ItemPool)
                {
                    SelectItemPool((ItemPool)pgProperties.SelectedObject);
                }
                else if (pgProperties.SelectedObject is AttributePool)
                {
                    SelectAttributePool((AttributePool)pgProperties.SelectedObject);
                }

                SelectProperty("Name");
            }
            else
            {
                // Rescan for issues related to this property.
                if (changedItem.PropertyDescriptor != null &&
                    changedItem.PropertyDescriptor.Attributes[typeof(TriggersFullValidationAttribute)] == null)
                {
                    if (pgProperties.SelectedObject is IFactory)
                    {
                        ScanForIssues((IFactory)pgProperties.SelectedObject);
                    }
                    else if (pgProperties.SelectedObject is ItemPool)
                    {
                        ScanForIssues((ItemPool)pgProperties.SelectedObject);
                    }

                    // Done, avoid the full rescan.
                    return(true);
                }
            }

            // Do a full scan when we come here.
            ScanForIssues();
            return(true);
        }
Ejemplo n.º 3
0
        private void RenderOrbit(Orbit orbit, float origin, float scale, System.Drawing.Graphics graphics, SolidBrush brush, int number = 0)
        {
            if (orbit == null)
            {
                return;
            }
            if (orbit.Orbiters != null)
            {
                // Check each orbiting object.
                foreach (var orbiter in orbit.Orbiters)
                {
                    var localOrigin = origin;
                    // We can only really draw something useful if we have a radius...
                    if (orbiter.OrbitRadius != null)
                    {
                        // Figure out max radius of children.
                        var maxOrbit = scale * GetMaxRadius(orbiter.Moons);

                        // Draw actual stuff at max bounds.
                        localOrigin += orbiter.OrbitRadius.High * scale;
                        var orbiterFactory = FactoryManager.GetFactory(orbiter.Name) as PlanetFactory;
                        if (orbiterFactory != null)
                        {
                            brush.Color = System.Drawing.Color.FromArgb(150, orbiterFactory.SurfaceTint.R,
                                                                        orbiterFactory.SurfaceTint.G,
                                                                        orbiterFactory.SurfaceTint.B);
                            if (orbiterFactory.Radius != null)
                            {
                                var diameter = orbiterFactory.Radius.Low * scale * 2;
                                graphics.FillEllipse(brush, localOrigin - diameter / 2f, pbPreview.Image.Height / 2f - diameter / 2f, diameter, diameter);
                                diameter = orbiterFactory.Radius.High * scale * 2;
                                graphics.FillEllipse(brush, localOrigin - diameter / 2f, pbPreview.Image.Height / 2f - diameter / 2f, diameter, diameter);

                                maxOrbit = Math.Max(maxOrbit, orbiterFactory.Radius.High * scale);
                            }
                        }

                        // Half the interval of variance we have for our radius.
                        var halfVariance = scale * (orbiter.OrbitRadius.High - orbiter.OrbitRadius.Low) / 2f;

                        // Add it to the max orbit to get the overall maximum possible
                        // when rendering a circle with its center in the middle of the
                        // variance interval. (and times two for width/height)
                        maxOrbit = (maxOrbit + halfVariance) * 2;

                        // Show the indicator of the maximum bounds for this orbiter.
                        brush.Color = System.Drawing.Color.FromArgb(20, 255, 165, 0);
                        graphics.FillEllipse(brush, origin + scale * orbiter.OrbitRadius.Low + halfVariance - maxOrbit / 2f, pbPreview.Image.Height / 2f - maxOrbit / 2f, maxOrbit, maxOrbit);

                        // Draw own orbit.
                        var color = OrbitColors[number % OrbitColors.Length];
                        using (var p = new Pen(System.Drawing.Color.FromArgb(210, color.R, color.G, color.B)))
                        {
                            float orbitX, orbitY;

                            var eccentricity = orbiter.Eccentricity.Low;
                            Orbiter.ComputeRadii(orbiter.OrbitRadius.High * scale, eccentricity, out orbitX, out orbitY);
                            graphics.DrawEllipse(p, origin - orbitX + orbitX * eccentricity, pbPreview.Image.Height / 2f - orbitY, orbitX * 2, orbitY * 2);

                            p.Color = System.Drawing.Color.FromArgb(110, color.R, color.G, color.B);

                            eccentricity = orbiter.Eccentricity.High;
                            Orbiter.ComputeRadii(orbiter.OrbitRadius.Low * scale, eccentricity, out orbitX, out orbitY);
                            graphics.DrawEllipse(p, origin - orbitX + orbitX * eccentricity, pbPreview.Image.Height / 2f - orbitY, orbitX * 2, orbitY * 2);
                        }
                    }

                    // Render children.
                    RenderOrbit(orbiter.Moons, localOrigin, scale, graphics, brush, ++number);
                }
            }
        }
Ejemplo n.º 4
0
        public override T Load <T>(string assetName)
        {
            var g = (IGraphicsDeviceService)ServiceProvider.GetService(typeof(IGraphicsDeviceService));

            if (typeof(T) == typeof(Texture2D))
            {
                if (_textures.ContainsKey(assetName))
                {
                    return((T)(object)_textures[assetName]);
                }

                using (var img = Image.FromFile(ContentProjectManager.GetTexturePath(assetName)))
                {
                    var bmp  = new Bitmap(img);
                    var data = new uint[bmp.Width * bmp.Height];
                    for (var y = 0; y < bmp.Height; ++y)
                    {
                        for (var x = 0; x < bmp.Width; ++x)
                        {
                            var pixel = bmp.GetPixel(x, y);
                            data[x + y * bmp.Width] =
                                Microsoft.Xna.Framework.Color.FromNonPremultiplied(pixel.R, pixel.G, pixel.B, pixel.A).
                                PackedValue;
                        }
                    }
                    if (g != null)
                    {
                        var t = new Texture2D(g.GraphicsDevice, img.Width, img.Height);
                        t.SetData(data);
                        _textures.Add(assetName, t);
                        return((T)(object)t);
                    }
                    else
                    {
                        throw new InvalidOperationException("Must wait with loading until graphics device is initialized.");
                    }
                }
            }
            else if (typeof(T) == typeof(Effect))
            {
                if (_shaders.ContainsKey(assetName))
                {
                    return((T)(object)_shaders[assetName]);
                }

                var shaderPath = ContentProjectManager.GetShaderPath(assetName);
                if (shaderPath != null)
                {
                    using (var file = File.OpenText(shaderPath))
                    {
                        var sourceCode = file.ReadToEnd();

                        var effectSource = new EffectContent
                        {
                            EffectCode = sourceCode,
                            Identity   = new ContentIdentity {
                                SourceFilename = assetName
                            }
                        };
                        var processor      = new EffectProcessor();
                        var compiledEffect = processor.Process(effectSource, new DummyProcessorContext());
                        var effect         = new Effect(g.GraphicsDevice, compiledEffect.GetEffectCode());
                        _shaders.Add(assetName, effect);
                        return((T)(object)effect);
                    }
                }
            }
            else if (typeof(T) == typeof(ParticleEffect))
            {
                using (var xmlReader = XmlReader.Create(ContentProjectManager.GetEffectPath(assetName)))
                {
                    var effect = IntermediateSerializer.Deserialize <ParticleEffect>(xmlReader, null);
                    effect.Initialise();
                    effect.LoadContent(this);
                    return((T)(object)effect);
                }
            }
            else if (typeof(T) == typeof(IFactory[]))
            {
                return((T)(object)FactoryManager.GetFactoriesFromFile(assetName).ToArray());
            }
            else if (typeof(T) == typeof(ItemPool[]))
            {
                return((T)(object)ItemPoolManager.GetItemPools().ToArray());
            }
            else if (typeof(T) == typeof(AttributePool[]))
            {
                return((T)(object)AttributePoolManager.GetAttributePools().ToArray());
            }
            return(default(T));
        }
Ejemplo n.º 5
0
        private void RemoveClick(object sender, EventArgs e)
        {
            if (pgProperties.SelectedObject == null)
            {
                return;
            }

            if (tvData.Focused || (sender == miDelete && miDelete.Visible))
            {
                if (pgProperties.SelectedObject is IFactory)
                {
                    var factory = (IFactory)pgProperties.SelectedObject;
                    if ((ModifierKeys & Keys.Shift) != 0 ||
                        MessageBox.Show(this,
                                        "Are you sure you wish to delete the factory '" + factory.Name + "'?",
                                        "Confirmation", MessageBoxButtons.YesNo,
                                        MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        FactoryManager.Remove(factory);

                        // Add undo command.
                        PushUndo("remove factory", () =>
                        {
                            FactoryManager.Add(factory);
                            return(true);
                        });
                    }
                }
                else if (pgProperties.SelectedObject is ItemPool)
                {
                    var itemPool = (ItemPool)pgProperties.SelectedObject;
                    if ((ModifierKeys & Keys.Shift) != 0 ||
                        MessageBox.Show(this,
                                        "Are you sure you wish to delete the item pool '" + itemPool.Name + "'?",
                                        "Confirmation", MessageBoxButtons.YesNo,
                                        MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        ItemPoolManager.Remove(itemPool);

                        // Add undo command.
                        PushUndo("remove item pool", () =>
                        {
                            ItemPoolManager.Add(itemPool);
                            return(true);
                        });
                    }
                }
                else if (pgProperties.SelectedObject is AttributePool)
                {
                    var attributePool = (AttributePool)pgProperties.SelectedObject;
                    if ((ModifierKeys & Keys.Shift) != 0 ||
                        MessageBox.Show(this,
                                        "Are you sure you wish to delete the attribute pool '" + attributePool.Name + "'?",
                                        "Confirmation", MessageBoxButtons.YesNo,
                                        MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        AttributePoolManager.Remove(attributePool);

                        // Add undo command.
                        PushUndo("remove attribute pool", () =>
                        {
                            AttributePoolManager.Add(attributePool);
                            return(true);
                        });
                    }
                }
            }
        }
Ejemplo n.º 6
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));
        }
Ejemplo n.º 7
0
 private void NameChanged(object sender, EventArgs e)
 {
     btnOK.Enabled = !string.IsNullOrWhiteSpace(tbName.Text) && !FactoryManager.HasFactory(tbName.Text.Trim());
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Check all known asset reference types for validity (i.e. whether the referenced object exists).
        /// </summary>
        /// <param name="main">The main object this relates to.</param>
        /// <param name="current">The current object being checked (that is some child of the main object).</param>
        /// <param name="prefix">The "path" to the current object in the main object, separated by dots ('.').</param>
        private void ScanReferences(object main, object current, string prefix = null)
        {
            // Skip null objects.
            if (main == null || current == null)
            {
                return;
            }

            // Adjust our prefix.
            prefix = string.IsNullOrWhiteSpace(prefix) ? "" : (prefix + ".");

            // Known checks: editor type to recognize the property, display name (in issue) and method to check validity.
            var checks = new[]
            {
                Tuple.Create <Type, string, Func <string, bool> >(typeof(TextureAssetEditor), "texture asset", ContentProjectManager.HasTextureAsset),
                Tuple.Create <Type, string, Func <string, bool> >(typeof(EffectAssetEditor), "effect asset", ContentProjectManager.HasEffectAsset),
                Tuple.Create <Type, string, Func <string, bool> >(typeof(ItemInfoEditor), "item", s => FactoryManager.GetFactory(s) as ItemFactory != null),
                Tuple.Create <Type, string, Func <string, bool> >(typeof(ItemPoolEditor), "item", s => FactoryManager.GetFactory(s) as ItemFactory != null),
                Tuple.Create <Type, string, Func <string, bool> >(typeof(ItemPoolChooserEditor), "item pool", s => ItemPoolManager.GetItemPool(s) != null),
                Tuple.Create <Type, string, Func <string, bool> >(typeof(PlanetEditor), "planet", s => FactoryManager.GetFactory(s) as PlanetFactory != null),
                Tuple.Create <Type, string, Func <string, bool> >(typeof(SunEditor), "sun", s => FactoryManager.GetFactory(s) as SunFactory != null)
            };

            // Perform all checks.
            foreach (var check in checks)
            {
                // Get properties we can handle with this check.
                foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(current, new Attribute[] { new EditorAttribute(check.Item1, typeof(UITypeEditor)) }))
                {
                    // See if the actual value is a string, which is the format we store the references in.
                    if (property.PropertyType != typeof(string))
                    {
                        AddIssue("Property marked as " + check.Item2 + " is not of type string.", main, prefix + property.Name, IssueType.Warning);
                    }
                    else
                    {
                        // Check if the reference is valid, ignore empty ones.
                        var path = (string)property.GetValue(current);
                        if (!string.IsNullOrWhiteSpace(path) && !check.Item3(path.Replace('\\', '/')))
                        {
                            AddIssue("Invalid or unknown " + check.Item2 + " name.", main, prefix + property.Name, IssueType.Error);
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Checks orbits for validity.
        /// </summary>
        /// <param name="factory">The factory.</param>
        private void ScanFactory(SunSystemFactory factory)
        {
            if (factory == null)
            {
                return;
            }

            // Get sun factory, to extract base radius offset, if possible.
            var sunFactory = FactoryManager.GetFactory(factory.Sun) as SunFactory;
            var orbits     = new Stack <Tuple <Orbit, float, string> >();

            orbits.Push(Tuple.Create(factory.Planets, sunFactory != null && sunFactory.OffsetRadius != null ? sunFactory.OffsetRadius.High : 0f, "Planets"));
            while (orbits.Count > 0)
            {
                var data   = orbits.Pop();
                var orbit  = data.Item1;
                var radius = data.Item2;
                var prefix = string.IsNullOrWhiteSpace(data.Item3) ? "" : (data.Item3 + ".");
                if (orbit == null)
                {
                    continue;
                }

                for (var i = 0; i < orbit.Orbiters.Length; i++)
                {
                    var orbiter     = orbit.Orbiters[i];
                    var localPrefix = prefix + "Orbiters[" + i + "].";
                    var childRadius = radius;

                    ScanReferences(factory, orbiter, localPrefix);

                    if (orbiter.ChanceToExist <= 0)
                    {
                        AddIssue("Planet will never be generated (probability <= 0).", factory, localPrefix + "ChanceToExist", IssueType.Information);
                    }

                    if (orbiter.Eccentricity != null &&
                        (orbiter.Eccentricity.Low < 0 || orbiter.Eccentricity.High < 0 ||
                         orbiter.Eccentricity.Low > 1 || orbiter.Eccentricity.High > 1))
                    {
                        AddIssue("Planet orbit ellipse eccentricity is in invalid value-range (should be in [0, 1]).", factory, localPrefix + "Eccentricity", IssueType.Warning);
                    }

                    if (orbiter.OrbitRadius == null)
                    {
                        AddIssue("Nor orbit radius set for planet.", factory, localPrefix + "OrbitRadius", IssueType.Error);
                    }
                    else
                    {
                        // Check if we're too large (exceeding cell size). Only trigger this message
                        // for the first object exceeding the bounds, not for its children.
                        childRadius += orbiter.OrbitRadius.High;
                        if (radius < Engine.Util.UnitConversion.ToScreenUnits(CellSystem.CellSize) / 2f &&
                            childRadius >= Engine.Util.UnitConversion.ToScreenUnits(CellSystem.CellSize) / 2f)
                        {
                            AddIssue("Accumulative radii of orbits potentially exceed cell size.", factory, localPrefix + "OrbitRadius", IssueType.Warning);
                        }

                        if (orbiter.OrbitRadius.Low <= 0 || orbiter.OrbitRadius.High <= 0)
                        {
                            AddIssue("Orbit radius should be larger than zero for planet.", factory,
                                     localPrefix + "OrbitRadius", IssueType.Warning);
                        }
                    }

                    orbits.Push(Tuple.Create(orbiter.Moons, childRadius, localPrefix + "Moons"));
                }
            }
        }
Ejemplo n.º 10
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);
                    }
                }
            }
        }