Exemple #1
0
        /// <summary>Renders the equipment starting from the specified slot.</summary>
        private void RenderEquipment(
            SpaceItemSlot slot,
            Vector2 offset,
            int depth               = 1,
            float order             = 0.5f,
            ItemSlotSize parentSize = ItemSlotSize.Small,
            bool?mirrored           = null)
        {
            // Nothing to do if there's no item in the slot.
            if (slot.Item <= 0)
            {
                return;
            }

            // Get item info.
            var item = (SpaceItem)Manager.GetComponent(slot.Item, Item.TypeId);

            // Adjust depth we want to render at.
            order -= (item.DrawBelowParent ? -0.25f : 0.25f) / depth;

            // See if we should mirror rendering (e.g. left wing).
            var slotOffset = slot.Offset;
            var itemOffset = item.ModelOffset;

            if (mirrored.HasValue)
            {
                if (mirrored.Value)
                {
                    slotOffset.Y = -slotOffset.Y;
                }
            }
// ReSharper disable CompareOfFloatsByEqualityOperator Intentional.
            else if (slotOffset.Y != 0.0f)
// ReSharper restore CompareOfFloatsByEqualityOperator
            {
                mirrored = slot.Offset.Y < 0;
            }
            if (mirrored.HasValue && mirrored.Value)
            {
                itemOffset.Y = -itemOffset.Y;
            }

            // Move the offset according to rotation and accumulate it.
            var localOffset  = offset + parentSize.Scale() * slotOffset;
            var renderOffset = localOffset + item.RequiredSlotSize.Scale() * itemOffset;

            // Render this particular item.
            foreach (SimpleTextureDrawable drawable in Manager.GetComponents(item.Entity, SimpleTextureDrawable.TypeId))
            {
                drawable.Draw(
                    _spriteBatch,
                    renderOffset,
                    0f,
                    item.RequiredSlotSize.Scale() / drawable.Scale,
                    mirrored.HasValue && mirrored.Value ? SpriteEffects.FlipVertically : SpriteEffects.None,
                    order);
            }

            // Render sub-items.
            foreach (SpaceItemSlot childSlot in Manager.GetComponents(item.Entity, ItemSlot.TypeId))
            {
                RenderEquipment(childSlot, localOffset, depth + 1, order, item.RequiredSlotSize, mirrored);
            }
        }
Exemple #2
0
        /// <summary>
        ///     Computes the size of the model, i.e. the area covered by the fully rendered equipment starting with the
        ///     specified slot.
        /// </summary>
        private RectangleF ComputeModelSize(
            SpaceItemSlot slot, Vector2 offset, ItemSlotSize parentSize = ItemSlotSize.Small, bool?mirrored = null)
        {
            // Nothing to do if there's no item in the slot.
            if (slot.Item <= 0)
            {
                return(RectangleF.Empty);
            }

            // Get item info.
            var item = (SpaceItem)Manager.GetComponent(slot.Item, Item.TypeId);

            // Get required bounds to render this item.
            var bounds = Manager.GetComponents(item.Entity, SimpleTextureDrawable.TypeId)
                         .Cast <SimpleTextureDrawable>()
                         .Aggregate(
                RectangleF.Empty,
                (current, drawable) =>
            {
                var b = (RectangleF)drawable.Texture.Bounds;
                b.Offset(-b.Width / 2f, -b.Height / 2f);
                return(RectangleF.Union(current, b));
            });

            // See if we should mirror rendering (e.g. left wing).
            var slotOffset = slot.Offset;
            var itemOffset = item.ModelOffset;

            if (mirrored.HasValue)
            {
                if (mirrored.Value)
                {
                    slotOffset.Y = -slotOffset.Y;
                }
            }
// ReSharper disable CompareOfFloatsByEqualityOperator Intentional.
            else if (slotOffset.Y != 0.0f)
// ReSharper restore CompareOfFloatsByEqualityOperator
            {
                mirrored = slot.Offset.Y < 0;
            }
            if (mirrored.HasValue && mirrored.Value)
            {
                itemOffset.Y = -itemOffset.Y;
            }

            // Move the offset according to rotation and accumulate it.
            var localOffset  = offset + parentSize.Scale() * slotOffset;
            var renderOffset = localOffset + item.RequiredSlotSize.Scale() * itemOffset;

            // Adjust to actual area the texture is rendered to.
            bounds.Offset(renderOffset);
            bounds.Inflate(
                -bounds.Width / 2f * (1 - item.RequiredSlotSize.Scale()),
                -bounds.Height / 2f * (1 - item.RequiredSlotSize.Scale()));

            // Check sub-items.
            return(Manager.GetComponents(item.Entity, ItemSlot.TypeId)
                   .Cast <SpaceItemSlot>()
                   .Aggregate(bounds, (current, childSlot) => RectangleF.Union(current, ComputeModelSize(childSlot, localOffset, item.RequiredSlotSize, mirrored))));
        }