protected override void RemoveComponentSpecific()
        {
            base.RemoveComponentSpecific();
#if CLIENT
            inventoryTopSprite?.Remove();
            inventoryBackSprite?.Remove();
            inventoryBottomSprite?.Remove();
            ContainedStateIndicator?.Remove();

            if (SubEditorScreen.IsSubEditor())
            {
                Inventory.DeleteAllItems();
                return;
            }
#endif

            foreach (Item item in Inventory.Items)
            {
                if (item == null)
                {
                    continue;
                }
                item.Drop(null);
            }
        }
Exemple #2
0
        protected override void RemoveComponentSpecific()
        {
            base.RemoveComponentSpecific();
            foreach (Wire wire in DisconnectedWires.ToList())
            {
                if (wire.OtherConnection(null) == null) //wire not connected to anything else
                {
#if CLIENT
                    if (SubEditorScreen.IsSubEditor())
                    {
                        wire.Item.Remove();
                    }
                    else
                    {
                        wire.Item.Drop(null);
                    }
#else
                    wire.Item.Drop(null);
#endif
                }
            }

            DisconnectedWires.Clear();
            foreach (Connection c in Connections)
            {
                foreach (Wire wire in c.Wires)
                {
                    if (wire == null)
                    {
                        continue;
                    }

                    if (wire.OtherConnection(c) == null) //wire not connected to anything else
                    {
#if CLIENT
                        if (SubEditorScreen.IsSubEditor())
                        {
                            wire.Item.Remove();
                        }
                        else
                        {
                            wire.Item.Drop(null);
                        }
#else
                        wire.Item.Drop(null);
#endif
                    }
                    else
                    {
                        wire.RemoveConnection(item);
                    }
                }
            }
            Connections.Clear();

#if CLIENT
            rewireSoundChannel?.FadeOutAndDispose();
            rewireSoundChannel = null;
#endif
        }
Exemple #3
0
        protected override void RemoveComponentSpecific()
        {
            base.RemoveComponentSpecific();
#if CLIENT
            inventoryTopSprite?.Remove();
            inventoryBackSprite?.Remove();
            inventoryBottomSprite?.Remove();
            ContainedStateIndicator?.Remove();

            if (SubEditorScreen.IsSubEditor())
            {
                Inventory.DeleteAllItems();
                return;
            }
#endif
            Inventory.AllItemsMod.ForEach(it => it.Drop(null));
        }
Exemple #4
0
        public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
        {
            if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation) || !MathUtils.NearlyEqual(item.Scale, prevScale))
            {
                UpdateTransformedBarrelPos();
            }
            Vector2 drawPos = GetDrawPos();

            float recoilOffset = 0.0f;

            if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f)
            {
                float diff = RetractionTime - RecoilTime;
                if (recoilTimer >= diff)
                {
                    //move the barrel backwards 0.1 seconds (defined by RecoilTime) after launching
                    recoilOffset = RecoilDistance * (1.0f - (recoilTimer - diff) / RecoilTime);
                }
                else if (recoilTimer <= diff - RetractionDelay)
                {
                    //move back to normal position while reloading
                    float t = diff - RetractionDelay;
                    recoilOffset = RecoilDistance * recoilTimer / t;
                }
                else
                {
                    recoilOffset = RecoilDistance;
                }
            }

            railSprite?.Draw(spriteBatch,
                             drawPos,
                             item.SpriteColor,
                             rotation + MathHelper.PiOver2, item.Scale,
                             SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));

            barrelSprite?.Draw(spriteBatch,
                               drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
                               item.SpriteColor,
                               rotation + MathHelper.PiOver2, item.Scale,
                               SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));

            float chargeRatio = currentChargeTime / MaxChargeTime;

            foreach ((Sprite chargeSprite, Vector2 position) in chargeSprites)
            {
                chargeSprite?.Draw(spriteBatch,
                                   drawPos - MathUtils.RotatePoint(new Vector2(position.X * chargeRatio, position.Y * chargeRatio) * item.Scale, rotation + MathHelper.PiOver2),
                                   item.SpriteColor,
                                   rotation + MathHelper.PiOver2, item.Scale,
                                   SpriteEffects.None, item.SpriteDepth + (chargeSprite.Depth - item.Sprite.Depth));
            }

            int spinningBarrelCount = spinningBarrelSprites.Count;

            for (int i = 0; i < spinningBarrelCount; i++)
            {
                // this block is messy since I was debugging it with a bunch of values, should be cleaned up / optimized if prototype is accepted
                Sprite spinningBarrel       = spinningBarrelSprites[i];
                float  barrelCirclePosition = (MaxCircle * i / spinningBarrelCount + currentBarrelSpin) % MaxCircle;

                float newDepth = item.SpriteDepth + (spinningBarrel.Depth - item.Sprite.Depth) + (barrelCirclePosition > HalfCircle ? 0.0f : 0.001f);

                float barrelColorPosition = (barrelCirclePosition + QuarterCircle) % MaxCircle;
                float colorOffset         = Math.Abs(barrelColorPosition - HalfCircle) / HalfCircle;
                Color newColorModifier    = Color.Lerp(Color.Black, Color.Gray, colorOffset);

                float barrelHalfCirclePosition = Math.Abs(barrelCirclePosition - HalfCircle);
                float barrelPositionModifier   = MathUtils.SmoothStep(barrelHalfCirclePosition / HalfCircle);
                float newPositionOffset        = barrelPositionModifier * SpinningBarrelDistance;

                spinningBarrel.Draw(spriteBatch,
                                    drawPos - MathUtils.RotatePoint(new Vector2(newPositionOffset, 0f) * item.Scale, rotation + MathHelper.PiOver2),
                                    Color.Lerp(item.SpriteColor, newColorModifier, 0.8f),
                                    rotation + MathHelper.PiOver2, item.Scale,
                                    SpriteEffects.None, newDepth);
            }

            if (!editing || GUI.DisableHUD || !item.IsSelected)
            {
                return;
            }

            const float widgetRadius = 60.0f;

            Vector2 center = new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2));

            GUI.DrawLine(spriteBatch,
                         drawPos,
                         drawPos + center * widgetRadius,
                         Color.LightGreen);

            const float coneRadius    = 300.0f;
            float       radians       = maxRotation - minRotation;
            float       circleRadius  = coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
            float       lineThickness = 1f / Screen.Selected.Cam.Zoom;

            if (Math.Abs(minRotation - maxRotation) < 0.02f)
            {
                spriteBatch.DrawLine(drawPos, drawPos + center * circleRadius, GUI.Style.Green, thickness: lineThickness);
            }
            else if (radians > Math.PI * 2)
            {
                spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUI.Style.Red, thickness: lineThickness);
            }
            else
            {
                spriteBatch.DrawSector(drawPos, circleRadius, radians, (int)Math.Abs(90 * radians), GUI.Style.Green, offset: minRotation, thickness: lineThickness);
            }

            int    baseWidgetScale   = GUI.IntScale(16);
            int    widgetSize        = (int)(Math.Max(baseWidgetScale, baseWidgetScale / Screen.Selected.Cam.Zoom));
            float  widgetThickness   = Math.Max(1f, lineThickness);
            Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) =>
            {
                widget.Selected += () =>
                {
                    oldRotation = RotationLimits;
                };
                widget.MouseDown += () =>
                {
                    widget.color = GUI.Style.Green;
                    prevAngle    = minRotation;
                };
                widget.Deselected += () =>
                {
                    widget.color = Color.Yellow;
                    item.CreateEditingHUD();
                    RotationLimits = RotationLimits;
                    if (SubEditorScreen.IsSubEditor())
                    {
                        SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
                    }
                };
                widget.MouseHeld += (deltaTime) =>
                {
                    minRotation = GetRotationAngle(GetDrawPos());
                    UpdateBarrel();
                    MapEntity.DisableSelect = true;
                };
                widget.PreUpdate += (deltaTime) =>
                {
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                    widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
                };
                widget.PostUpdate += (deltaTime) =>
                {
                    widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                };
                widget.PreDraw += (sprtBtch, deltaTime) =>
                {
                    widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation);
                    widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
                    widget.Update(deltaTime);
                };
            });

            Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) =>
            {
                widget.Selected += () =>
                {
                    oldRotation = RotationLimits;
                };
                widget.MouseDown += () =>
                {
                    widget.color = GUI.Style.Green;
                    prevAngle    = maxRotation;
                };
                widget.Deselected += () =>
                {
                    widget.color = Color.Yellow;
                    item.CreateEditingHUD();
                    RotationLimits = RotationLimits;
                    if (SubEditorScreen.IsSubEditor())
                    {
                        SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
                    }
                };
                widget.MouseHeld += (deltaTime) =>
                {
                    maxRotation = GetRotationAngle(GetDrawPos());
                    UpdateBarrel();
                    MapEntity.DisableSelect = true;
                };
                widget.PreUpdate += (deltaTime) =>
                {
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                    widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
                };
                widget.PostUpdate += (deltaTime) =>
                {
                    widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                };
                widget.PreDraw += (sprtBtch, deltaTime) =>
                {
                    widget.tooltip = "Max: " + (int)MathHelper.ToDegrees(maxRotation);
                    widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
                    widget.Update(deltaTime);
                };
            });

            minRotationWidget.Draw(spriteBatch, (float)Timing.Step);
            maxRotationWidget.Draw(spriteBatch, (float)Timing.Step);

            Vector2 GetDrawPos()
            {
                Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y);

                if (item.Submarine != null)
                {
                    drawPos += item.Submarine.DrawPosition;
                }
                drawPos.Y = -drawPos.Y;
                return(drawPos);
            }

            void UpdateBarrel()
            {
                rotation = (minRotation + maxRotation) / 2;
            }
        }
Exemple #5
0
        public override void Update(float deltaTime, Camera cam)
        {
            if (nodes.Count == 0)
            {
                return;
            }

            Character user = item.ParentInventory?.Owner as Character;

            editNodeDelay = (user?.SelectedConstruction == null) ? editNodeDelay - deltaTime : 0.5f;

            Submarine sub = item.Submarine;

            if (connections[0] != null && connections[0].Item.Submarine != null)
            {
                sub = connections[0].Item.Submarine;
            }
            if (connections[1] != null && connections[1].Item.Submarine != null)
            {
                sub = connections[1].Item.Submarine;
            }

            if (Screen.Selected != GameMain.SubEditorScreen)
            {
                if (user != null)
                {
                    NoAutoLock = true;
                }

                //cannot run wires from sub to another
                if (item.Submarine != sub && sub != null && item.Submarine != null)
                {
                    ClearConnections();
                    return;
                }

                if (item.CurrentHull == null)
                {
                    Structure attachTarget = Structure.GetAttachTarget(item.WorldPosition);
                    canPlaceNode = attachTarget != null;

                    sub ??= attachTarget?.Submarine;
                    Vector2 attachPos = GetAttachPosition(user);
                    newNodePos = sub == null ?
                                 attachPos :
                                 attachPos - sub.Position - sub.HiddenSubPosition;
                }
                else
                {
                    newNodePos = GetAttachPosition(user);
                    if (sub != null)
                    {
                        newNodePos -= sub.HiddenSubPosition;
                    }
                    canPlaceNode = true;
                }

                //prevent the wire from extending too far when rewiring
                if (nodes.Count > 0)
                {
                    if (user == null)
                    {
                        return;
                    }

                    Vector2 prevNodePos = nodes[nodes.Count - 1];
                    if (sub != null)
                    {
                        prevNodePos += sub.HiddenSubPosition;
                    }

                    currLength = 0.0f;
                    for (int i = 0; i < nodes.Count - 1; i++)
                    {
                        currLength += Vector2.Distance(nodes[i], nodes[i + 1]);
                    }
                    Vector2 itemPos = item.Position;
                    if (sub != null && user.Submarine == null)
                    {
                        prevNodePos += sub.Position;
                    }
                    currLength += Vector2.Distance(prevNodePos, itemPos);
                    if (currLength > MaxLength)
                    {
                        Vector2 diff        = prevNodePos - user.Position;
                        Vector2 pullBackDir = diff == Vector2.Zero ? Vector2.Zero : Vector2.Normalize(diff);
                        Vector2 forceDir    = pullBackDir;
                        if (!user.AnimController.InWater)
                        {
                            forceDir.Y = 0.0f;
                        }
                        user.AnimController.Collider.ApplyForce(forceDir * user.Mass * 50.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity * 0.5f);
                        if (diff.LengthSquared() > 50.0f * 50.0f)
                        {
                            user.AnimController.UpdateUseItem(true, user.WorldPosition + pullBackDir * Math.Min(150.0f, diff.Length()));
                        }

                        if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
                        {
                            if (currLength > MaxLength * 1.5f)
                            {
                                ClearConnections();
#if SERVER
                                CreateNetworkEvent();
#endif
                                return;
                            }
                        }
                    }
                }
            }
            else
            {
#if CLIENT
                bool disableGrid = SubEditorScreen.IsSubEditor() && PlayerInput.IsShiftDown();
                newNodePos = disableGrid ? item.Position : RoundNode(item.Position);
#else
                newNodePos = RoundNode(item.Position);
#endif
                if (sub != null)
                {
                    newNodePos -= sub.HiddenSubPosition;
                }
                canPlaceNode = true;
            }

            if (item != null)
            {
                Vector2 relativeNodePos = newNodePos - item.Position;

                if (sub != null)
                {
                    relativeNodePos += sub.HiddenSubPosition;
                }

                sectionExtents = new Vector2(
                    Math.Max(Math.Abs(relativeNodePos.X), sectionExtents.X),
                    Math.Max(Math.Abs(relativeNodePos.Y), sectionExtents.Y));
            }
        }
        public void DrawContainedItems(SpriteBatch spriteBatch, float itemDepth)
        {
            Vector2 transformedItemPos                = ItemPos * item.Scale;
            Vector2 transformedItemInterval           = ItemInterval * item.Scale;
            Vector2 transformedItemIntervalHorizontal = new Vector2(transformedItemInterval.X, 0.0f);
            Vector2 transformedItemIntervalVertical   = new Vector2(0.0f, transformedItemInterval.Y);

            if (item.body == null)
            {
                if (item.FlippedX)
                {
                    transformedItemPos.X                = -transformedItemPos.X;
                    transformedItemPos.X               += item.Rect.Width;
                    transformedItemInterval.X           = -transformedItemInterval.X;
                    transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X;
                }
                if (item.FlippedY)
                {
                    transformedItemPos.Y              = -transformedItemPos.Y;
                    transformedItemPos.Y             -= item.Rect.Height;
                    transformedItemInterval.Y         = -transformedItemInterval.Y;
                    transformedItemIntervalVertical.Y = -transformedItemIntervalVertical.Y;
                }
                transformedItemPos += new Vector2(item.Rect.X, item.Rect.Y);
                if (item.Submarine != null)
                {
                    transformedItemPos += item.Submarine.DrawPosition;
                }

                if (Math.Abs(item.Rotation) > 0.01f)
                {
                    Matrix transform = Matrix.CreateRotationZ(MathHelper.ToRadians(-item.Rotation));
                    transformedItemPos                = Vector2.Transform(transformedItemPos - item.DrawPosition, transform) + item.DrawPosition;
                    transformedItemInterval           = Vector2.Transform(transformedItemInterval, transform);
                    transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
                    transformedItemIntervalVertical   = Vector2.Transform(transformedItemIntervalVertical, transform);
                }
            }
            else
            {
                Matrix transform = Matrix.CreateRotationZ(item.body.DrawRotation);
                if (item.body.Dir == -1.0f)
                {
                    transformedItemPos.X                = -transformedItemPos.X;
                    transformedItemInterval.X           = -transformedItemInterval.X;
                    transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X;
                }

                transformedItemPos                = Vector2.Transform(transformedItemPos, transform);
                transformedItemInterval           = Vector2.Transform(transformedItemInterval, transform);
                transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
                transformedItemPos               += item.body.DrawPosition;
            }

            Vector2 currentItemPos = transformedItemPos;

            SpriteEffects spriteEffects = SpriteEffects.None;

            if ((item.body != null && item.body.Dir == -1) || item.FlippedX)
            {
                spriteEffects |= MathUtils.NearlyEqual(ItemRotation % 180, 90.0f) ? SpriteEffects.FlipVertically : SpriteEffects.FlipHorizontally;
            }
            if (item.FlippedY)
            {
                spriteEffects |= MathUtils.NearlyEqual(ItemRotation % 180, 90.0f) ? SpriteEffects.FlipHorizontally : SpriteEffects.FlipVertically;
            }

            bool isWiringMode = SubEditorScreen.TransparentWiringMode && SubEditorScreen.IsWiringMode();

            int i = 0;

            foreach (Item containedItem in Inventory.AllItems)
            {
                if (AutoInteractWithContained)
                {
                    containedItem.IsHighlighted = item.IsHighlighted;
                    item.IsHighlighted          = false;
                }

                Vector2 origin = containedItem.Sprite.Origin;
                if (item.FlippedX)
                {
                    origin.X = containedItem.Sprite.SourceRect.Width - origin.X;
                }
                if (item.FlippedY)
                {
                    origin.Y = containedItem.Sprite.SourceRect.Height - origin.Y;
                }

                float containedSpriteDepth = ContainedSpriteDepth < 0.0f ? containedItem.Sprite.Depth : ContainedSpriteDepth;
                if (i < containedSpriteDepths.Length)
                {
                    containedSpriteDepth = containedSpriteDepths[i];
                }
                containedSpriteDepth = itemDepth + (containedSpriteDepth - (item.Sprite?.Depth ?? item.SpriteDepth)) / 10000.0f;

                containedItem.Sprite.Draw(
                    spriteBatch,
                    new Vector2(currentItemPos.X, -currentItemPos.Y),
                    isWiringMode ? containedItem.GetSpriteColor() * 0.15f : containedItem.GetSpriteColor(),
                    origin,
                    -(containedItem.body == null ? 0.0f : containedItem.body.DrawRotation),
                    containedItem.Scale,
                    spriteEffects,
                    depth: containedSpriteDepth);

                foreach (ItemContainer ic in containedItem.GetComponents <ItemContainer>())
                {
                    if (ic.hideItems)
                    {
                        continue;
                    }
                    ic.DrawContainedItems(spriteBatch, containedSpriteDepth);
                }

                i++;
                if (Math.Abs(ItemInterval.X) > 0.001f && Math.Abs(ItemInterval.Y) > 0.001f)
                {
                    //interval set on both axes -> use a grid layout
                    currentItemPos += transformedItemIntervalHorizontal;
                    if (i % ItemsPerRow == 0)
                    {
                        currentItemPos  = transformedItemPos;
                        currentItemPos += transformedItemIntervalVertical * (i / ItemsPerRow);
                    }
                }
                else
                {
                    currentItemPos += transformedItemInterval;
                }
            }
        }
Exemple #7
0
        public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
        {
            if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation) || !MathUtils.NearlyEqual(item.Scale, prevScale))
            {
                UpdateTransformedBarrelPos();
            }
            Vector2 drawPos = GetDrawPos();

            float recoilOffset = 0.0f;

            if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f)
            {
                float diff = RetractionTime - RecoilTime;
                if (recoilTimer >= diff)
                {
                    //move the barrel backwards 0.1 seconds (defined by RecoilTime) after launching
                    recoilOffset = RecoilDistance * (1.0f - (recoilTimer - diff) / RecoilTime);
                }
                else if (recoilTimer <= diff - RetractionDelay)
                {
                    //move back to normal position while reloading
                    float t = diff - RetractionDelay;
                    recoilOffset = RecoilDistance * recoilTimer / t;
                }
                else
                {
                    recoilOffset = RecoilDistance;
                }
            }

            railSprite?.Draw(spriteBatch,
                             drawPos,
                             item.SpriteColor,
                             rotation + MathHelper.PiOver2, item.Scale,
                             SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));

            barrelSprite?.Draw(spriteBatch,
                               drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
                               item.SpriteColor,
                               rotation + MathHelper.PiOver2, item.Scale,
                               SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));

            if (!editing || GUI.DisableHUD || !item.IsSelected)
            {
                return;
            }

            const float widgetRadius = 60.0f;

            Vector2 center = new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2));

            GUI.DrawLine(spriteBatch,
                         drawPos,
                         drawPos + center * widgetRadius,
                         Color.LightGreen);

            const float coneRadius    = 300.0f;
            float       radians       = maxRotation - minRotation;
            float       circleRadius  = coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
            float       lineThickness = 1f / Screen.Selected.Cam.Zoom;

            if (Math.Abs(minRotation - maxRotation) < 0.02f)
            {
                spriteBatch.DrawLine(drawPos, drawPos + center * circleRadius, GUI.Style.Green, thickness: lineThickness);
            }
            else if (radians > Math.PI * 2)
            {
                spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUI.Style.Red, thickness: lineThickness);
            }
            else
            {
                spriteBatch.DrawSector(drawPos, circleRadius, radians, (int)Math.Abs(90 * radians), GUI.Style.Green, offset: minRotation, thickness: lineThickness);
            }

            int    baseWidgetScale   = GUI.IntScale(16);
            int    widgetSize        = (int)(Math.Max(baseWidgetScale, baseWidgetScale / Screen.Selected.Cam.Zoom));
            float  widgetThickness   = Math.Max(1f, lineThickness);
            Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) =>
            {
                widget.Selected += () =>
                {
                    oldRotation = RotationLimits;
                };
                widget.MouseDown += () =>
                {
                    widget.color = GUI.Style.Green;
                    prevAngle    = minRotation;
                };
                widget.Deselected += () =>
                {
                    widget.color = Color.Yellow;
                    item.CreateEditingHUD();
                    RotationLimits = RotationLimits;
                    if (SubEditorScreen.IsSubEditor())
                    {
                        SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
                    }
                };
                widget.MouseHeld += (deltaTime) =>
                {
                    minRotation = GetRotationAngle(GetDrawPos());
                    UpdateBarrel();
                    MapEntity.DisableSelect = true;
                };
                widget.PreUpdate += (deltaTime) =>
                {
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                    widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
                };
                widget.PostUpdate += (deltaTime) =>
                {
                    widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                };
                widget.PreDraw += (sprtBtch, deltaTime) =>
                {
                    widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation);
                    widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
                    widget.Update(deltaTime);
                };
            });

            Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) =>
            {
                widget.Selected += () =>
                {
                    oldRotation = RotationLimits;
                };
                widget.MouseDown += () =>
                {
                    widget.color = GUI.Style.Green;
                    prevAngle    = maxRotation;
                };
                widget.Deselected += () =>
                {
                    widget.color = Color.Yellow;
                    item.CreateEditingHUD();
                    RotationLimits = RotationLimits;
                    if (SubEditorScreen.IsSubEditor())
                    {
                        SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
                    }
                };
                widget.MouseHeld += (deltaTime) =>
                {
                    maxRotation = GetRotationAngle(GetDrawPos());
                    UpdateBarrel();
                    MapEntity.DisableSelect = true;
                };
                widget.PreUpdate += (deltaTime) =>
                {
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                    widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
                };
                widget.PostUpdate += (deltaTime) =>
                {
                    widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                };
                widget.PreDraw += (sprtBtch, deltaTime) =>
                {
                    widget.tooltip = "Max: " + (int)MathHelper.ToDegrees(maxRotation);
                    widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
                    widget.Update(deltaTime);
                };
            });

            minRotationWidget.Draw(spriteBatch, (float)Timing.Step);
            maxRotationWidget.Draw(spriteBatch, (float)Timing.Step);

            Vector2 GetDrawPos()
            {
                Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y);

                if (item.Submarine != null)
                {
                    drawPos += item.Submarine.DrawPosition;
                }
                drawPos.Y = -drawPos.Y;
                return(drawPos);
            }

            void UpdateBarrel()
            {
                rotation = (minRotation + maxRotation) / 2;
            }
        }
Exemple #8
0
        public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
        {
            if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation))
            {
                UpdateTransformedBarrelPos();
            }
            Vector2 drawPos = GetDrawPos();

            float recoilOffset = 0.0f;

            if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f)
            {
                float diff = RetractionTime - RecoilTime;
                if (recoilTimer >= diff)
                {
                    //move the barrel backwards 0.1 seconds (defined by RecoilTime) after launching
                    recoilOffset = RecoilDistance * (1.0f - (recoilTimer - diff) / RecoilTime);
                }
                else if (recoilTimer <= diff - RetractionDelay)
                {
                    //move back to normal position while reloading
                    float t = diff - RetractionDelay;
                    recoilOffset = RecoilDistance * recoilTimer / t;
                }
                else
                {
                    recoilOffset = RecoilDistance;
                }
            }

            railSprite?.Draw(spriteBatch,
                             drawPos,
                             item.SpriteColor,
                             rotation + MathHelper.PiOver2, item.Scale,
                             SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));

            barrelSprite?.Draw(spriteBatch,
                               drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale,
                               item.SpriteColor,
                               rotation + MathHelper.PiOver2, item.Scale,
                               SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));

            if (!editing || GUI.DisableHUD || !item.IsSelected)
            {
                return;
            }

            float widgetRadius = 60.0f;

            GUI.DrawLine(spriteBatch,
                         drawPos,
                         drawPos + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius,
                         GUI.Style.Green);

            GUI.DrawLine(spriteBatch,
                         drawPos,
                         drawPos + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * widgetRadius,
                         GUI.Style.Green);

            GUI.DrawLine(spriteBatch,
                         drawPos,
                         drawPos + new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)) * widgetRadius,
                         Color.LightGreen);

            Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: 10, initMethod: (widget) =>
            {
                widget.Selected += () =>
                {
                    oldRotation = RotationLimits;
                };
                widget.MouseDown += () =>
                {
                    widget.color = GUI.Style.Green;
                    prevAngle    = minRotation;
                };
                widget.Deselected += () =>
                {
                    widget.color = Color.Yellow;
                    item.CreateEditingHUD();
                    if (SubEditorScreen.IsSubEditor())
                    {
                        SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
                    }
                };
                widget.MouseHeld += (deltaTime) =>
                {
                    minRotation = GetRotationAngle(GetDrawPos());
                    if (minRotation > maxRotation)
                    {
                        float temp  = minRotation;
                        minRotation = maxRotation;
                        maxRotation = temp;
                    }
                    MapEntity.DisableSelect = true;
                };
                widget.PreUpdate += (deltaTime) =>
                {
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                    widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
                };
                widget.PostUpdate += (deltaTime) =>
                {
                    widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                };
                widget.PreDraw += (sprtBtch, deltaTime) =>
                {
                    widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation);
                    widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius;
                    widget.Update(deltaTime);
                };
            });

            Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: 10, initMethod: (widget) =>
            {
                widget.Selected += () =>
                {
                    oldRotation = RotationLimits;
                };
                widget.MouseDown += () =>
                {
                    widget.color = GUI.Style.Green;
                    prevAngle    = minRotation;
                };
                widget.Deselected += () =>
                {
                    widget.color = Color.Yellow;
                    item.CreateEditingHUD();
                    if (SubEditorScreen.IsSubEditor())
                    {
                        SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
                    }
                };
                widget.MouseHeld += (deltaTime) =>
                {
                    maxRotation = GetRotationAngle(GetDrawPos());
                    if (minRotation > maxRotation)
                    {
                        float temp  = minRotation;
                        minRotation = maxRotation;
                        maxRotation = temp;
                    }
                    MapEntity.DisableSelect = true;
                };
                widget.PreUpdate += (deltaTime) =>
                {
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                    widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
                };
                widget.PostUpdate += (deltaTime) =>
                {
                    widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
                    widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
                };
                widget.PreDraw += (sprtBtch, deltaTime) =>
                {
                    widget.tooltip = "Max: " + (int)MathHelper.ToDegrees(maxRotation);
                    widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * widgetRadius;
                    widget.Update(deltaTime);
                };
            });

            minRotationWidget.Draw(spriteBatch, (float)Timing.Step);
            maxRotationWidget.Draw(spriteBatch, (float)Timing.Step);

            Vector2 GetDrawPos()
            {
                Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y);

                if (item.Submarine != null)
                {
                    drawPos += item.Submarine.DrawPosition;
                }
                drawPos.Y = -drawPos.Y;
                return(drawPos);
            }
        }