Пример #1
0
        public void DebugDrawHUD(SpriteBatch spriteBatch, int y)
        {
            foreach (ScriptedEvent scriptedEvent in activeEvents.Where(ev => !ev.IsFinished && ev is ScriptedEvent).Cast <ScriptedEvent>())
            {
                DrawEventTargetTags(spriteBatch, scriptedEvent);
            }

            GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + (int)Math.Max(eventCoolDown, 0), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)Math.Round(currentIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, currentIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)Math.Round(targetIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, targetIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);

            GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "AvgHealth: " + (int)Math.Round(avgCrewHealth * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "AvgHullIntegrity: " + (int)Math.Round(avgHullIntegrity * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "FloodingAmount: " + (int)Math.Round(floodingAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "FireAmount: " + (int)Math.Round(fireAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "EnemyDanger: " + (int)Math.Round(enemyDanger * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont);

#if DEBUG
            if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) &&
                PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.T))
            {
                eventCoolDown = 1.0f;
            }
#endif

            if (intensityGraph == null)
            {
                intensityGraph       = new Graph();
                targetIntensityGraph = new Graph();
            }

            intensityGraphUpdateInterval = 5.0f;
            if (Timing.TotalTime > lastIntensityUpdate + intensityGraphUpdateInterval)
            {
                intensityGraph.Update(currentIntensity);
                targetIntensityGraph.Update(targetIntensity);
                lastIntensityUpdate = (float)Timing.TotalTime;
            }

            Rectangle graphRect = new Rectangle(15, y + 150, 150, 50);

            GUI.DrawRectangle(spriteBatch, graphRect, Color.Black * 0.5f, true);
            intensityGraph.Draw(spriteBatch, graphRect, 1.0f, 0.0f, Color.Lerp(Color.White, GUI.Style.Red, currentIntensity));
            targetIntensityGraph.Draw(spriteBatch, graphRect, 1.0f, 0.0f, Color.Lerp(Color.White, GUI.Style.Red, targetIntensity) * 0.5f);

            GUI.DrawLine(spriteBatch,
                         new Vector2(graphRect.Right, graphRect.Y + graphRect.Height * (1.0f - eventThreshold)),
                         new Vector2(graphRect.Right + 5, graphRect.Y + graphRect.Height * (1.0f - eventThreshold)), Color.Orange, 0, 1);

            y = graphRect.Bottom + 20;
            int x = graphRect.X;
            if (isCrewAway && crewAwayDuration < settings.FreezeDurationWhenCrewAway)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew away from sub): " + ToolBox.SecondsToReadableTime(settings.FreezeDurationWhenCrewAway - crewAwayDuration), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            else if (crewAwayResetTimer > 0.0f)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew just returned to the sub): " + ToolBox.SecondsToReadableTime(crewAwayResetTimer), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            else if (eventCoolDown > 0.0f)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y), "Event cooldown active: " + ToolBox.SecondsToReadableTime(eventCoolDown), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            else if (currentIntensity > eventThreshold)
            {
                GUI.DrawString(spriteBatch, new Vector2(x, y),
                               "Intensity too high for new events: " + (int)(currentIntensity * 100) + "%/" + (int)(eventThreshold * 100) + "%", Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }

            foreach (EventSet eventSet in pendingEventSets)
            {
                if (Submarine.MainSub == null)
                {
                    break;
                }

                GUI.DrawString(spriteBatch, new Vector2(x, y), "New event (ID " + eventSet.DebugIdentifier + ") after: ", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                y += 12;

                if (eventSet.PerCave)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y), "    submarine near cave", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (eventSet.PerWreck)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y), "    submarine near the wreck", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (eventSet.PerRuin)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y), "    submarine near the ruins", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (roundDuration < eventSet.MinMissionTime)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y),
                                   "    " + (int)(eventSet.MinDistanceTraveled * 100.0f) + "% travelled (current: " + (int)(distanceTraveled * 100.0f) + " %)",
                                   ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) ? Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, eventSet.MinDistanceTraveled - distanceTraveled) : GUI.Style.Green) * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }

                if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y),
                                   "    intensity between " + ((int)eventSet.MinIntensity) + " and " + ((int)eventSet.MaxIntensity),
                                   Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }

                if (roundDuration < eventSet.MinMissionTime)
                {
                    GUI.DrawString(spriteBatch, new Vector2(x, y),
                                   "    " + (int)(eventSet.MinMissionTime - roundDuration) + " s",
                                   Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, (eventSet.MinMissionTime - roundDuration)), null, 0, GUI.SmallFont);
                }

                y += 15;

                if (y > GameMain.GraphicsHeight * 0.9f)
                {
                    y  = graphRect.Bottom + 35;
                    x += 250;
                }
            }

            GUI.DrawString(spriteBatch, new Vector2(x, y), "Current events: ", Color.White * 0.9f, null, 0, GUI.SmallFont);
            y += 15;

            foreach (Event ev in activeEvents.Where(ev => !ev.IsFinished || PlayerInput.IsShiftDown()))
            {
                GUI.DrawString(spriteBatch, new Vector2(x + 5, y), ev.ToString(), (!ev.IsFinished ? Color.White : Color.Red) * 0.8f, null, 0, GUI.SmallFont);

                Rectangle rect = new Rectangle(new Point(x + 5, y), GUI.SmallFont.MeasureString(ev.ToString()).ToPoint());

                Rectangle outlineRect = new Rectangle(rect.Location, rect.Size);
                outlineRect.Inflate(4, 4);

                if (PinnedEvent == ev)
                {
                    GUI.DrawRectangle(spriteBatch, outlineRect, Color.White);
                }

                if (rect.Contains(PlayerInput.MousePosition))
                {
                    GUI.MouseCursor = CursorState.Hand;
                    GUI.DrawRectangle(spriteBatch, outlineRect, Color.White);

                    if (ev != PinnedEvent)
                    {
                        DrawEvent(spriteBatch, ev, rect);
                    }
                    else if (PlayerInput.SecondaryMouseButtonHeld() || PlayerInput.SecondaryMouseButtonDown())
                    {
                        PinnedEvent = null;
                    }

                    if (PlayerInput.PrimaryMouseButtonHeld() || PlayerInput.PrimaryMouseButtonDown())
                    {
                        PinnedEvent = ev;
                    }
                }

                y += 18;
                if (y > GameMain.GraphicsHeight * 0.9f)
                {
                    y  = graphRect.Bottom + 35;
                    x += 250;
                }
            }
        }
Пример #2
0
        public void DebugDrawHUD(SpriteBatch spriteBatch, int y)
        {
            GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + eventCoolDown, Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)(currentIntensity * 100), Color.Lerp(Color.White, Color.Red, currentIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)(targetIntensity * 100), Color.Lerp(Color.White, Color.Red, targetIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);

            GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "AvgHealth: " + (int)(avgCrewHealth * 100), Color.Lerp(Color.Red, Color.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "AvgHullIntegrity: " + (int)(avgHullIntegrity * 100), Color.Lerp(Color.Red, Color.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "FloodingAmount: " + (int)(floodingAmount * 100), Color.Lerp(Color.Green, Color.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "FireAmount: " + (int)(fireAmount * 100), Color.Lerp(Color.Green, Color.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
            GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "EnemyDanger: " + (int)(enemyDanger * 100), Color.Lerp(Color.Green, Color.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont);

#if DEBUG
            if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) &&
                PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.T))
            {
                eventCoolDown = 1.0f;
            }
#endif

            if (intensityGraph == null)
            {
                intensityGraph       = new Graph();
                targetIntensityGraph = new Graph();
            }

            intensityGraphUpdateInterval = 5.0f;
            if (Timing.TotalTime > lastIntensityUpdate + intensityGraphUpdateInterval)
            {
                intensityGraph.Update(currentIntensity);
                targetIntensityGraph.Update(targetIntensity);
                lastIntensityUpdate = (float)Timing.TotalTime;
            }

            Rectangle graphRect = new Rectangle(15, y + 150, 150, 50);

            GUI.DrawRectangle(spriteBatch, graphRect, Color.Black * 0.5f, true);
            intensityGraph.Draw(spriteBatch, graphRect, 1.0f, 0.0f, Color.Lerp(Color.White, Color.Red, currentIntensity));
            targetIntensityGraph.Draw(spriteBatch, graphRect, 1.0f, 0.0f, Color.Lerp(Color.White, Color.Red, targetIntensity) * 0.5f);

            GUI.DrawLine(spriteBatch,
                         new Vector2(graphRect.Right, graphRect.Y + graphRect.Height * (1.0f - eventThreshold)),
                         new Vector2(graphRect.Right + 5, graphRect.Y + graphRect.Height * (1.0f - eventThreshold)), Color.Orange, 0, 1);

            y = graphRect.Bottom + 20;
            if (eventCoolDown > 0.0f)
            {
                GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), "Event cooldown active: " + (int)eventCoolDown, Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            else if (currentIntensity > eventThreshold)
            {
                GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
                               "Intensity too high for new events: " + (int)(currentIntensity * 100) + "%/" + (int)(eventThreshold * 100) + "%", Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
                y += 15;
            }
            foreach (ScriptedEventSet eventSet in selectedEventSets)
            {
                float distanceTraveled = MathHelper.Clamp(
                    (Submarine.MainSub.WorldPosition.X - level.StartPosition.X) / (level.EndPosition.X - level.StartPosition.X),
                    0.0f, 1.0f);

                GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), "New event (ID " + eventSet.DebugIdentifier + ") after: ", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                y += 12;

                if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) &&
                    roundDuration < eventSet.MinMissionTime)
                {
                    GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
                                   "    " + (int)(eventSet.MinDistanceTraveled * 100.0f) + "% travelled (current: " + (int)(distanceTraveled * 100.0f) + " %)",
                                   Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity)
                {
                    GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
                                   "    intensity between " + ((int)eventSet.MinIntensity) + " and " + ((int)eventSet.MaxIntensity),
                                   Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                    y += 12;
                }
                if (roundDuration < eventSet.MinMissionTime)
                {
                    GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
                                   "    " + (int)(eventSet.MinMissionTime - roundDuration) + " s",
                                   Color.Orange * 0.8f, null, 0, GUI.SmallFont);
                }

                y += 15;
            }


            GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), "Current events: ", Color.White * 0.9f, null, 0, GUI.SmallFont);
            y += 12;
            foreach (ScriptedEvent scriptedEvent in events)
            {
                if (scriptedEvent.IsFinished)
                {
                    continue;
                }
                GUI.DrawString(spriteBatch, new Vector2(graphRect.X + 5, y), scriptedEvent.ToString(), Color.White * 0.8f, null, 0, GUI.SmallFont);
                y += 12;
            }
        }
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if RUN_PHYSICS_IN_SEPARATE_THREAD
            physicsTime += deltaTime;
            lock (updateLock)
            {
#endif


#if DEBUG && CLIENT
            if (GameMain.GameSession != null && !DebugConsole.IsOpen && GUI.KeyboardDispatcher.Subscriber == null)
            {
                if (GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null)
                {
                    Submarine closestSub = Submarine.FindClosest(cam.WorldViewCenter) ?? GameMain.GameSession.Submarine;

                    Vector2 targetMovement = Vector2.Zero;
                    if (PlayerInput.KeyDown(Keys.I))
                    {
                        targetMovement.Y += 1.0f;
                    }
                    if (PlayerInput.KeyDown(Keys.K))
                    {
                        targetMovement.Y -= 1.0f;
                    }
                    if (PlayerInput.KeyDown(Keys.J))
                    {
                        targetMovement.X -= 1.0f;
                    }
                    if (PlayerInput.KeyDown(Keys.L))
                    {
                        targetMovement.X += 1.0f;
                    }

                    if (targetMovement != Vector2.Zero)
                    {
                        closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                    }
                }
            }
#endif

#if CLIENT
            GameMain.LightManager?.Update((float)deltaTime);
#endif

            GameTime += deltaTime;

            foreach (PhysicsBody body in PhysicsBody.List)
            {
                if (body.Enabled && body.BodyType != FarseerPhysics.BodyType.Static)
                {
                    body.Update();
                }
            }
            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

            if (GameMain.GameSession != null)
            {
                GameMain.GameSession.Update((float)deltaTime);
            }
#if CLIENT
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            GameMain.ParticleManager.Update((float)deltaTime);

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("ParticleUpdate", sw.ElapsedTicks);
            sw.Restart();

            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, cam);
            }

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("LevelUpdate", sw.ElapsedTicks);

            if (Character.Controlled != null)
            {
                if (Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
                {
                    Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
                }
                if (Character.Controlled.Inventory != null)
                {
                    foreach (Item item in Character.Controlled.Inventory.AllItems)
                    {
                        if (Character.Controlled.HasEquippedItem(item))
                        {
                            item.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
                        }
                    }
                }
            }


            sw.Restart();

            Character.UpdateAll((float)deltaTime, cam);
#elif SERVER
            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, Camera.Instance);
            }
            Character.UpdateAll((float)deltaTime, Camera.Instance);
#endif


#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("CharacterUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            StatusEffect.UpdateAll((float)deltaTime);

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("StatusEffectUpdate", sw.ElapsedTicks);
            sw.Restart();

            if (Character.Controlled != null &&
                Lights.LightManager.ViewTarget != null)
            {
                Vector2 targetPos = Lights.LightManager.ViewTarget.DrawPosition;
                if (Lights.LightManager.ViewTarget == Character.Controlled &&
                    (CharacterHealth.OpenHealthWindow != null || CrewManager.IsCommandInterfaceOpen || ConversationAction.IsDialogOpen))
                {
                    Vector2 screenTargetPos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) * 0.5f;
                    if (CharacterHealth.OpenHealthWindow != null)
                    {
                        screenTargetPos.X = GameMain.GraphicsWidth * (CharacterHealth.OpenHealthWindow.Alignment == Alignment.Left ? 0.75f : 0.25f);
                    }
                    else if (ConversationAction.IsDialogOpen)
                    {
                        screenTargetPos.Y = GameMain.GraphicsHeight * 0.4f;
                    }
                    Vector2 screenOffset = screenTargetPos - new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight / 2);
                    screenOffset.Y = -screenOffset.Y;
                    targetPos     -= screenOffset / cam.Zoom;
                }
                cam.TargetPos = targetPos;
            }

            cam.MoveCamera((float)deltaTime);
#endif

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody body in PhysicsBody.List)
            {
                if (body.Enabled && body.BodyType != FarseerPhysics.BodyType.Static)
                {
                    body.SetPrevTransform(body.SimPosition, body.Rotation);
                }
            }

#if CLIENT
            MapEntity.UpdateAll((float)deltaTime, cam);
#elif SERVER
            MapEntity.UpdateAll((float)deltaTime, Camera.Instance);
#endif

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("MapEntityUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif
            Character.UpdateAnimAll((float)deltaTime);

#if CLIENT
            Ragdoll.UpdateAll((float)deltaTime, cam);
#elif SERVER
            Ragdoll.UpdateAll((float)deltaTime, Camera.Instance);
#endif

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("AnimUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("SubmarineUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

#if !RUN_PHYSICS_IN_SEPARATE_THREAD
            try
            {
                GameMain.World.Step((float)Timing.Step);
            }
            catch (WorldLockedException e)
            {
                string errorMsg = "Attempted to modify the state of the physics simulation while a time step was running.";
                DebugConsole.ThrowError(errorMsg, e);
                GameAnalyticsManager.AddErrorEventOnce("GameScreen.Update:WorldLockedException" + e.Message, GameAnalyticsSDK.Net.EGAErrorSeverity.Critical, errorMsg);
            }
#endif


#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("Physics", sw.ElapsedTicks);
#endif
            UpdateProjSpecific(deltaTime);

#if RUN_PHYSICS_IN_SEPARATE_THREAD
        }
#endif
        }
Пример #4
0
        public static void UpdateEditor(Camera cam)
        {
            if (highlightedListBox != null)
            {
                highlightedListBox.UpdateManually((float)Timing.Step);
            }

            if (editingHUD != null)
            {
                if (FilteredSelectedList.Count == 0 || editingHUD.UserData != FilteredSelectedList[0])
                {
                    foreach (GUIComponent component in editingHUD.Children)
                    {
                        var textBox = component as GUITextBox;
                        if (textBox == null)
                        {
                            continue;
                        }
                        textBox.Deselect();
                    }
                    editingHUD = null;
                }
            }
            FilteredSelectedList.Clear();
            if (selectedList.Count == 0)
            {
                return;
            }
            foreach (var e in selectedList)
            {
                if (e is Gap gap && gap.ConnectedDoor != null)
                {
                    continue;
                }
                FilteredSelectedList.Add(e);
            }
            var first = FilteredSelectedList.FirstOrDefault();

            if (first != null)
            {
                first.UpdateEditing(cam);
                if (first.ResizeHorizontal || first.ResizeVertical)
                {
                    first.UpdateResizing(cam);
                }
            }

            if ((PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl)))
            {
                if (PlayerInput.KeyHit(Keys.N))
                {
                    float minX = selectedList[0].WorldRect.X, maxX = selectedList[0].WorldRect.Right;
                    for (int i = 0; i < selectedList.Count; i++)
                    {
                        minX = Math.Min(minX, selectedList[i].WorldRect.X);
                        maxX = Math.Max(maxX, selectedList[i].WorldRect.Right);
                    }

                    float centerX = (minX + maxX) / 2.0f;
                    foreach (MapEntity me in selectedList)
                    {
                        me.FlipX(false);
                        me.Move(new Vector2((centerX - me.WorldPosition.X) * 2.0f, 0.0f));
                    }
                }
                else if (PlayerInput.KeyHit(Keys.M))
                {
                    float minY = selectedList[0].WorldRect.Y - selectedList[0].WorldRect.Height, maxY = selectedList[0].WorldRect.Y;
                    for (int i = 0; i < selectedList.Count; i++)
                    {
                        minY = Math.Min(minY, selectedList[i].WorldRect.Y - selectedList[i].WorldRect.Height);
                        maxY = Math.Max(maxY, selectedList[i].WorldRect.Y);
                    }

                    float centerY = (minY + maxY) / 2.0f;
                    foreach (MapEntity me in selectedList)
                    {
                        me.FlipY(false);
                        me.Move(new Vector2(0.0f, (centerY - me.WorldPosition.Y) * 2.0f));
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);

            if (Timing.Accumulator > Timing.Step * 6.0)
            {
                //if the game's running too slowly then we have no choice
                //but to skip a bunch of steps
                //otherwise it snowballs and becomes unplayable
                Timing.Accumulator = Timing.Step;
            }

            CrossThread.ProcessTasks();

            PlayerInput.UpdateVariable();

            if (SoundManager != null)
            {
                if (WindowActive || !Config.MuteOnFocusLost)
                {
                    SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain;
                }
                else
                {
                    SoundManager.ListenerGain = 0.0f;
                }
            }

            while (Timing.Accumulator >= Timing.Step)
            {
                Timing.TotalTime += Timing.Step;

                Stopwatch sw = new Stopwatch();
                sw.Start();

                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                PlayerInput.Update(Timing.Step);


                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    ResetFrameTime();

                    if (!TitleScreen.PlayingSplashScreen)
                    {
                        SoundPlayer.Update((float)Timing.Step);
                    }

                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
                        (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) && WindowActive)))
                    {
                        loadingScreenOpen = false;
                    }

#if DEBUG
                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (Config.AutomaticQuickStartEnabled || Config.AutomaticCampaignLoadEnabled) && FirstLoad && !PlayerInput.KeyDown(Keys.LeftShift))
                    {
                        loadingScreenOpen = false;
                        FirstLoad         = false;

                        if (Config.AutomaticQuickStartEnabled)
                        {
                            MainMenuScreen.QuickStart();
                        }
                        else if (Config.AutomaticCampaignLoadEnabled)
                        {
                            IEnumerable <string> saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Singleplayer);

                            if (saveFiles.Count() > 0)
                            {
                                saveFiles = saveFiles.OrderBy(file => File.GetLastWriteTime(file));
                                try
                                {
                                    SaveUtil.LoadGame(saveFiles.Last());
                                }
                                catch (Exception e)
                                {
                                    DebugConsole.ThrowError("Loading save \"" + saveFiles.Last() + "\" failed", e);
                                    return;
                                }
                            }
                        }
                    }
#endif

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        throw new LoadingException(loadingCoroutine.Exception);
                    }
                }
                else if (hasLoaded)
                {
                    if (ConnectLobby != 0)
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        Steam.SteamManager.JoinLobby(ConnectLobby, true);

                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }
                    else if (!string.IsNullOrWhiteSpace(ConnectEndpoint))
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint);
                        Client = new GameClient(Config.PlayerName,
                                                serverSteamId != 0 ? null : ConnectEndpoint,
                                                serverSteamId,
                                                string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName);
                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }

                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
                    {
                        // Check if a text input is selected.
                        if (GUI.KeyboardDispatcher.Subscriber != null)
                        {
                            if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
                            {
                                textBox.Deselect();
                            }
                            GUI.KeyboardDispatcher.Subscriber = null;
                        }
                        //if a verification prompt (are you sure you want to x) is open, close it
                        else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
                                 GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
                        {
                            ((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
                        }
                        else if (GUIMessageBox.VisibleBox?.UserData is RoundSummary roundSummary &&
                                 roundSummary.ContinueButton != null &&
                                 roundSummary.ContinueButton.Visible)
                        {
                            GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox);
                        }
                        else if (Tutorial.Initialized && Tutorial.ContentRunning)
                        {
                            (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
                        }
                        else if (GameSession.IsTabMenuOpen)
                        {
                            gameSession.ToggleTabMenu();
                        }
                        else if (GUI.PauseMenuOpen)
                        {
                            GUI.TogglePauseMenu();
                        }
                        //open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC
                        else if ((Character.Controlled == null || !itemHudActive())
                                 //TODO: do we need to check Inventory.SelectedSlot?
                                 && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null &&
                                 !CrewManager.IsCommandInterfaceOpen &&
                                 !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled?.SelectedConstruction != null))
                        {
                            // Otherwise toggle pausing, unless another window/interface is open.
                            GUI.TogglePauseMenu();
                        }
Пример #6
0
        public override void UpdateEditing(Camera cam)
        {
            if (editingHUD == null || editingHUD.UserData as Item != this)
            {
                editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
            }

            editingHUD.Update((float)Timing.Step);

            if (Screen.Selected != GameMain.SubEditorScreen)
            {
                return;
            }

            if (!Linkable)
            {
                return;
            }

            if (!PlayerInput.KeyDown(Keys.Space))
            {
                return;
            }
            bool lClick = PlayerInput.LeftButtonClicked();
            bool rClick = PlayerInput.RightButtonClicked();

            if (!lClick && !rClick)
            {
                return;
            }

            Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);

            if (lClick)
            {
                foreach (MapEntity entity in mapEntityList)
                {
                    if (entity == this || !entity.IsHighlighted)
                    {
                        continue;
                    }
                    if (linkedTo.Contains(entity))
                    {
                        continue;
                    }
                    if (!entity.IsMouseOn(position))
                    {
                        continue;
                    }

                    linkedTo.Add(entity);
                    if (entity.Linkable && entity.linkedTo != null)
                    {
                        entity.linkedTo.Add(this);
                    }
                }
            }
            else
            {
                foreach (MapEntity entity in mapEntityList)
                {
                    if (entity == this || !entity.IsHighlighted)
                    {
                        continue;
                    }
                    if (!linkedTo.Contains(entity))
                    {
                        continue;
                    }
                    if (!entity.IsMouseOn(position))
                    {
                        continue;
                    }

                    linkedTo.Remove(entity);
                    if (entity.linkedTo != null && entity.linkedTo.Contains(this))
                    {
                        entity.linkedTo.Remove(this);
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if DEBUG && CLIENT
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
                !DebugConsole.IsOpen && GUIComponent.KeyboardDispatcher.Subscriber == null)
            {
                var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
                if (closestSub == null)
                {
                    closestSub = GameMain.GameSession.Submarine;
                }

                Vector2 targetMovement = Vector2.Zero;
                if (PlayerInput.KeyDown(Keys.I))
                {
                    targetMovement.Y += 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.K))
                {
                    targetMovement.Y -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.J))
                {
                    targetMovement.X -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.L))
                {
                    targetMovement.X += 1.0f;
                }

                if (targetMovement != Vector2.Zero)
                {
                    closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                }
            }
#endif

            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

#if CLIENT
            if (GameMain.GameSession != null)
            {
                GameMain.GameSession.Update((float)deltaTime);
            }

            GameMain.ParticleManager.Update((float)deltaTime);

            GameMain.LightManager.Update((float)deltaTime);
#endif

            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, cam);
            }

#if CLIENT
            if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
            {
                Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled);
            }
#endif

            Character.UpdateAll((float)deltaTime, cam);

            StatusEffect.UpdateAll((float)deltaTime);

#if CLIENT
            if (Character.Controlled != null && Lights.LightManager.ViewTarget != null)
            {
                cam.TargetPos = Lights.LightManager.ViewTarget.WorldPosition;
            }
#endif

            cam.MoveCamera((float)deltaTime);

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody pb in PhysicsBody.List)
            {
                pb.SetPrevTransform(pb.SimPosition, pb.Rotation);
            }

            MapEntity.UpdateAll((float)deltaTime, cam);

            Character.UpdateAnimAll((float)deltaTime);

            Ragdoll.UpdateAll((float)deltaTime, cam);

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

            GameMain.World.Step((float)deltaTime);
#if CLIENT
            if (!PlayerInput.LeftButtonHeld())
            {
                Inventory.draggingSlot = null;
                Inventory.draggingItem = null;
            }
#endif
        }
Пример #8
0
        public override void UpdateEditing(Camera cam)
        {
            if (editingHUD == null || editingHUD.UserData as Hull != this)
            {
                editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
            }

            if (!PlayerInput.KeyDown(Keys.Space))
            {
                return;
            }
            bool lClick = PlayerInput.PrimaryMouseButtonClicked();
            bool rClick = PlayerInput.SecondaryMouseButtonClicked();

            if (!lClick && !rClick)
            {
                return;
            }

            Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);

            foreach (MapEntity entity in mapEntityList)
            {
                if (entity == this || !entity.IsHighlighted)
                {
                    continue;
                }
                if (!entity.IsMouseOn(position))
                {
                    continue;
                }
                if (entity.linkedTo == null || !entity.Linkable)
                {
                    continue;
                }
                if (entity.linkedTo.Contains(this) || linkedTo.Contains(entity) || rClick)
                {
                    if (entity == this || !entity.IsHighlighted)
                    {
                        continue;
                    }
                    if (!entity.IsMouseOn(position))
                    {
                        continue;
                    }
                    if (entity.linkedTo.Contains(this))
                    {
                        entity.linkedTo.Remove(this);
                        linkedTo.Remove(entity);
                    }
                }
                else
                {
                    if (!entity.linkedTo.Contains(this))
                    {
                        entity.linkedTo.Add(this);
                    }
                    if (!linkedTo.Contains(this))
                    {
                        linkedTo.Add(entity);
                    }
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Update the selection logic in submarine editor
        /// </summary>
        public static void UpdateSelecting(Camera cam)
        {
            if (resizing)
            {
                if (selectedList.Count == 0)
                {
                    resizing = false;
                }
                return;
            }

            foreach (MapEntity e in mapEntityList)
            {
                e.isHighlighted = false;
            }

            if (DisableSelect)
            {
                DisableSelect = false;
                return;
            }

            if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow)
            {
                if (highlightedListBox == null ||
                    (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))
                {
                    UpdateHighlightedListBox(null);
                    return;
                }
            }

            if (MapEntityPrefab.Selected != null)
            {
                selectionPos = Vector2.Zero;
                selectedList.Clear();
                return;
            }

            if (PlayerInput.KeyDown(Keys.Delete))
            {
                selectedList.ForEach(e => e.Remove());
                selectedList.Clear();
            }

            if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
            {
                if (PlayerInput.GetKeyboardState.IsKeyDown(Keys.C) &&
                    PlayerInput.GetOldKeyboardState.IsKeyUp(Keys.C))
                {
                    CopyEntities(selectedList);
                }
                else if (PlayerInput.GetKeyboardState.IsKeyDown(Keys.X) &&
                         PlayerInput.GetOldKeyboardState.IsKeyUp(Keys.X))
                {
                    CopyEntities(selectedList);

                    selectedList.ForEach(e => e.Remove());
                    selectedList.Clear();
                }
                else if (copiedList.Count > 0 &&
                         PlayerInput.GetKeyboardState.IsKeyDown(Keys.V) &&
                         PlayerInput.GetOldKeyboardState.IsKeyUp(Keys.V))
                {
                    List <MapEntity> prevEntities = new List <MapEntity>(mapEntityList);
                    Clone(copiedList);

                    var clones = mapEntityList.Except(prevEntities).ToList();

                    Vector2 center = Vector2.Zero;
                    clones.ForEach(c => center += c.WorldPosition);
                    center = Submarine.VectorToWorldGrid(center / clones.Count);

                    Vector2 moveAmount = Submarine.VectorToWorldGrid(cam.WorldViewCenter - center);

                    selectedList = new List <MapEntity>(clones);
                    foreach (MapEntity clone in selectedList)
                    {
                        clone.Move(moveAmount);
                        clone.Submarine = Submarine.MainSub;
                    }
                }
            }

            Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);

            MapEntity highLightedEntity = null;

            if (startMovingPos == Vector2.Zero)
            {
                List <MapEntity> highlightedEntities = new List <MapEntity>();
                if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn))
                {
                    highLightedEntity = GUI.MouseOn.UserData as MapEntity;
                }
                else
                {
                    foreach (MapEntity e in mapEntityList)
                    {
                        if (!e.SelectableInEditor)
                        {
                            continue;
                        }

                        if (e.IsMouseOn(position))
                        {
                            int i = 0;
                            while (i < highlightedEntities.Count &&
                                   e.Sprite != null &&
                                   (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth))
                            {
                                i++;
                            }

                            highlightedEntities.Insert(i, e);

                            if (i == 0)
                            {
                                highLightedEntity = e;
                            }
                        }
                    }

                    if (PlayerInput.MouseSpeed.LengthSquared() > 10)
                    {
                        highlightTimer = 0.0f;
                    }
                    else
                    {
                        bool mouseNearHighlightBox = false;

                        if (highlightedListBox != null)
                        {
                            Rectangle expandedRect = highlightedListBox.Rect;
                            expandedRect.Inflate(20, 20);
                            mouseNearHighlightBox = expandedRect.Contains(PlayerInput.MousePosition);
                            if (!mouseNearHighlightBox)
                            {
                                highlightedListBox = null;
                            }
                        }

                        highlightTimer += (float)Timing.Step;
                        if (highlightTimer > 1.0f)
                        {
                            if (!mouseNearHighlightBox)
                            {
                                UpdateHighlightedListBox(highlightedEntities);
                                highlightTimer = 0.0f;
                            }
                        }
                    }
                }

                if (highLightedEntity != null)
                {
                    highLightedEntity.isHighlighted = true;
                }
            }

            Vector2 nudgeAmount = Vector2.Zero;

            if (PlayerInput.KeyHit(Keys.Up))
            {
                nudgeAmount.Y = 1f;
            }
            if (PlayerInput.KeyHit(Keys.Down))
            {
                nudgeAmount.Y = -1f;
            }
            if (PlayerInput.KeyHit(Keys.Left))
            {
                nudgeAmount.X = -1f;
            }
            if (PlayerInput.KeyHit(Keys.Right))
            {
                nudgeAmount.X = 1f;
            }
            if (nudgeAmount != Vector2.Zero)
            {
                foreach (MapEntity entityToNudge in selectedList)
                {
                    entityToNudge.Move(nudgeAmount);
                }
            }

            //started moving selected entities
            if (startMovingPos != Vector2.Zero)
            {
                if (PlayerInput.LeftButtonReleased())
                {
                    //mouse released -> move the entities to the new position of the mouse

                    Vector2 moveAmount = position - startMovingPos;
                    moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X;
                    moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y;
                    if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y)
                    {
                        moveAmount = Submarine.VectorToWorldGrid(moveAmount);
                        //clone
                        if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                        {
                            var clones = Clone(selectedList);
                            selectedList = clones;
                            selectedList.ForEach(c => c.Move(moveAmount));
                        }
                        else // move
                        {
                            foreach (MapEntity e in selectedList)
                            {
                                e.Move(moveAmount);
                            }
                        }
                    }
                    startMovingPos = Vector2.Zero;
                }
            }
            //started dragging a "selection rectangle"
            else if (selectionPos != Vector2.Zero)
            {
                selectionSize.X = position.X - selectionPos.X;
                selectionSize.Y = selectionPos.Y - position.Y;

                List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize);
                if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y)
                {
                    newSelection = FindSelectedEntities(selectionPos, selectionSize);
                }
                else
                {
                    if (highLightedEntity != null)
                    {
                        newSelection.Add(highLightedEntity);
                    }
                }

                if (PlayerInput.LeftButtonReleased())
                {
                    if (PlayerInput.KeyDown(Keys.LeftControl) ||
                        PlayerInput.KeyDown(Keys.RightControl))
                    {
                        foreach (MapEntity e in newSelection)
                        {
                            if (selectedList.Contains(e))
                            {
                                selectedList.Remove(e);
                            }
                            else
                            {
                                selectedList.Add(e);
                            }
                        }
                    }
                    else
                    {
                        selectedList = newSelection;
                    }

                    //select wire if both items it's connected to are selected
                    var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList();
                    foreach (Item item in selectedItems)
                    {
                        if (item.Connections == null)
                        {
                            continue;
                        }
                        foreach (Connection c in item.Connections)
                        {
                            foreach (Wire w in c.Wires)
                            {
                                if (w == null || selectedList.Contains(w.Item))
                                {
                                    continue;
                                }

                                if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item))
                                {
                                    selectedList.Add(w.Item);
                                }
                            }
                        }
                    }

                    selectionPos  = Vector2.Zero;
                    selectionSize = Vector2.Zero;
                }
            }
            //default, not doing anything specific yet
            else
            {
                if (PlayerInput.LeftButtonHeld() &&
                    PlayerInput.KeyUp(Keys.Space) &&
                    (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))))
                {
                    //if clicking a selected entity, start moving it
                    foreach (MapEntity e in selectedList)
                    {
                        if (e.IsMouseOn(position))
                        {
                            startMovingPos = position;
                        }
                    }
                    selectionPos = position;

                    //stop camera movement to prevent accidental dragging or rect selection
                    Screen.Selected.Cam.StopMovement();
                }
            }
        }
Пример #10
0
        protected override void Update(float deltaTime)
        {
            if (!Visible)
            {
                return;
            }

            if (flashTimer > 0.0f)
            {
                flashTimer -= deltaTime;
            }
            if (!Enabled)
            {
                return;
            }

            if (skipUpdate)
            {
                skipUpdate = false;
                return;
            }

            if (MouseRect.Contains(PlayerInput.MousePosition) && (GUI.MouseOn == null || (!(GUI.MouseOn is GUIButton) && GUI.IsMouseOn(this))))
            {
                State = ComponentState.Hover;
                if (PlayerInput.PrimaryMouseButtonDown())
                {
                    mouseHeldInside = true;
                    Select();
                }
                else
                {
                    isSelecting = PlayerInput.PrimaryMouseButtonHeld();
                }
                if (PlayerInput.DoubleClicked())
                {
                    SelectAll();
                }
                if (isSelecting)
                {
                    if (!MathUtils.NearlyEqual(PlayerInput.MouseSpeed.X, 0))
                    {
                        CaretIndex = textBlock.GetCaretIndexFromScreenPos(PlayerInput.MousePosition);
                        CalculateCaretPos();
                        CalculateSelection();
                    }
                }
            }
            else
            {
                if ((PlayerInput.LeftButtonClicked() || PlayerInput.RightButtonClicked()) && selected)
                {
                    if (!mouseHeldInside)
                    {
                        Deselect();
                    }
                    mouseHeldInside = false;
                }
                isSelecting = false;
                State       = ComponentState.None;
            }
            if (!isSelecting)
            {
                isSelecting = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift);
            }

            if (CaretEnabled)
            {
                if (textBlock.OverflowClipActive)
                {
                    if (CaretScreenPos.X < textBlock.Rect.X + textBlock.Padding.X)
                    {
                        textBlock.TextPos = new Vector2(textBlock.TextPos.X + ((textBlock.Rect.X + textBlock.Padding.X) - CaretScreenPos.X), textBlock.TextPos.Y);
                        CalculateCaretPos();
                    }
                    else if (CaretScreenPos.X > textBlock.Rect.Right - textBlock.Padding.Z)
                    {
                        textBlock.TextPos = new Vector2(textBlock.TextPos.X - (CaretScreenPos.X - (textBlock.Rect.Right - textBlock.Padding.Z)), textBlock.TextPos.Y);
                        CalculateCaretPos();
                    }
                }
                caretTimer  += deltaTime;
                caretVisible = ((caretTimer * 1000.0f) % 1000) < 500;
                if (caretVisible && caretPosDirty)
                {
                    CalculateCaretPos();
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == this)
            {
                State = ComponentState.Selected;
                Character.DisableControls = true;
                if (OnEnterPressed != null && PlayerInput.KeyHit(Keys.Enter))
                {
                    OnEnterPressed(this, Text);
                }
            }
            else if (Selected)
            {
                Deselect();
            }

            textBlock.State = State;
        }
Пример #11
0
        public void ReceiveCommandInput(char command)
        {
            if (Text == null)
            {
                Text = "";
            }

            switch (command)
            {
            case '\b' when !Readonly:     //backspace
                if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                {
                    SetText(string.Empty, false);
                    CaretIndex = Text.Length;
                }
                else if (selectedCharacters > 0)
                {
                    RemoveSelectedText();
                }
                else if (Text.Length > 0 && CaretIndex > 0)
                {
                    CaretIndex--;
                    SetText(Text.Remove(CaretIndex, 1));
                    CalculateCaretPos();
                    ClearSelection();
                }
                OnTextChanged?.Invoke(this, Text);
                break;

            case (char)0x3:     // ctrl-c
                CopySelectedText();
                break;

            case (char)0x16 when !Readonly:     // ctrl-v
                string text = GetCopiedText();
                RemoveSelectedText();
                if (SetText(Text.Insert(CaretIndex, text)))
                {
                    CaretIndex = Math.Min(Text.Length, CaretIndex + text.Length);
                    OnTextChanged?.Invoke(this, Text);
                }
                break;

            case (char)0x18:     // ctrl-x
                CopySelectedText();
                if (!Readonly)
                {
                    RemoveSelectedText();
                }
                break;

            case (char)0x1:     // ctrl-a
                SelectAll();
                break;

            case (char)0x1A when !Readonly:     // ctrl-z
                text = memento.Undo();
                if (text != Text)
                {
                    ClearSelection();
                    SetText(text, false);
                    CaretIndex = Text.Length;
                    OnTextChanged?.Invoke(this, Text);
                }
                break;

            case (char)0x12 when !Readonly:     // ctrl-r
                text = memento.Redo();
                if (text != Text)
                {
                    ClearSelection();
                    SetText(text, false);
                    CaretIndex = Text.Length;
                    OnTextChanged?.Invoke(this, Text);
                }
                break;
            }
        }
Пример #12
0
        public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true)
        {
            prevPosition = position;
            prevZoom     = zoom;

            float moveSpeed = 20.0f / zoom;

            Vector2 moveCam = Vector2.Zero;

            if (targetPos == Vector2.Zero)
            {
                if (allowMove && GUIComponent.KeyboardDispatcher.Subscriber == null)
                {
                    if (PlayerInput.KeyDown(Keys.LeftShift))
                    {
                        moveSpeed *= 3.0f;
                    }
                    if (PlayerInput.KeyDown(Keys.LeftControl))
                    {
                        moveSpeed *= 0.5f;
                    }

                    if (GameMain.Config.KeyBind(InputType.Left).IsDown())
                    {
                        moveCam.X -= moveSpeed;
                    }
                    if (GameMain.Config.KeyBind(InputType.Right).IsDown())
                    {
                        moveCam.X += moveSpeed;
                    }
                    if (GameMain.Config.KeyBind(InputType.Down).IsDown())
                    {
                        moveCam.Y -= moveSpeed;
                    }
                    if (GameMain.Config.KeyBind(InputType.Up).IsDown())
                    {
                        moveCam.Y += moveSpeed;
                    }
                }

                if (Screen.Selected == GameMain.GameScreen && FollowSub)
                {
                    var closestSub = Submarine.FindClosest(WorldViewCenter);
                    if (closestSub != null)
                    {
                        moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(closestSub.Velocity * deltaTime);
                    }
                }

                moveCam = moveCam * deltaTime * 60.0f;

                if (allowZoom)
                {
                    Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
                    Vector2 diffViewCenter;
                    diffViewCenter = ((mouseInWorld - Position) * Zoom);
                    if (GUIComponent.MouseOn == null)
                    {
                        Zoom = MathHelper.Clamp(zoom + (PlayerInput.ScrollWheelSpeed / 1000.0f) * zoom, GameMain.DebugDraw ? 0.01f : 0.1f, 2.0f);
                    }
                    if (!PlayerInput.KeyDown(Keys.F))
                    {
                        Position = mouseInWorld - (diffViewCenter / Zoom);
                    }
                }
            }
            else
            {
                Vector2 mousePos = PlayerInput.MousePosition;

                Vector2 offset = mousePos - new Vector2(resolution.X / 2.0f, resolution.Y / 2.0f);

                offset.X = offset.X / (resolution.X * 0.4f);
                offset.Y = -offset.Y / (resolution.Y * 0.3f);

                if (offset.Length() > 1.0f)
                {
                    offset.Normalize();
                }

                offset = offset * offsetAmount;
                float newZoom;
                newZoom = (Math.Min(DefaultZoom - Math.Min(offset.Length() / resolution.Y, 1.0f), 1.0f) + ZoomModifier);

                Zoom += (newZoom - zoom) / ZoomSmoothness;

                Vector2 diff = (targetPos + offset) - position;

                moveCam = diff / MoveSmoothness;
            }

            shakeTargetPosition = Rand.Vector(Shake);
            shakePosition       = Vector2.Lerp(shakePosition, shakeTargetPosition, 0.5f);
            Shake = MathHelper.Lerp(Shake, 0.0f, deltaTime * 2.0f);

            Translate(moveCam + shakePosition);
        }
Пример #13
0
        protected override void Update(float deltaTime)
        {
            if (!Visible)
            {
                return;
            }

            if (flashTimer > 0.0f)
            {
                flashTimer -= deltaTime;
            }
            if (!Enabled)
            {
                return;
            }
            if (MouseRect.Contains(PlayerInput.MousePosition) && (GUI.MouseOn == null || GUI.IsMouseOn(this)))
            {
                state = ComponentState.Hover;
                if (PlayerInput.LeftButtonDown())
                {
                    Select();
                }
                else
                {
                    isSelecting = PlayerInput.LeftButtonHeld();
                }
                if (PlayerInput.DoubleClicked())
                {
                    SelectAll();
                }
                if (isSelecting)
                {
                    if (!MathUtils.NearlyEqual(PlayerInput.MouseSpeed.X, 0))
                    {
                        CaretIndex = GetCaretIndexFromScreenPos(PlayerInput.MousePosition);
                        CalculateCaretPos();
                        CalculateSelection();
                    }
                }
            }
            else
            {
                isSelecting = false;
                state       = ComponentState.None;
            }
            if (!isSelecting)
            {
                isSelecting = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift);
            }

            if (CaretEnabled)
            {
                caretTimer  += deltaTime;
                caretVisible = ((caretTimer * 1000.0f) % 1000) < 500;
                if (caretVisible && caretPosDirty)
                {
                    CalculateCaretPos();
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == this)
            {
                state = ComponentState.Selected;
                Character.DisableControls = true;
                if (OnEnterPressed != null && PlayerInput.KeyHit(Keys.Enter))
                {
                    OnEnterPressed(this, Text);
                }
            }
            else if (Selected)
            {
                Deselect();
            }

            textBlock.State = state;
        }
Пример #14
0
 public override void Update(double deltaTime)
 {
     base.Update(deltaTime);
     Widget.EnableMultiSelect  = PlayerInput.KeyDown(Keys.LeftControl);
     spriteList.SelectMultiple = Widget.EnableMultiSelect;
     // Select rects with the mouse
     if (Widget.selectedWidgets.None() || Widget.EnableMultiSelect)
     {
         if (selectedTexture != null)
         {
             foreach (Sprite sprite in loadedSprites)
             {
                 if (sprite.Texture != selectedTexture)
                 {
                     continue;
                 }
                 if (PlayerInput.LeftButtonClicked())
                 {
                     var scaledRect = new Rectangle(textureRect.Location + sprite.SourceRect.Location.Multiply(zoom), sprite.SourceRect.Size.Multiply(zoom));
                     if (scaledRect.Contains(PlayerInput.MousePosition))
                     {
                         spriteList.Select(sprite, autoScroll: false);
                         UpdateScrollBar(spriteList);
                         UpdateScrollBar(textureList);
                     }
                 }
             }
         }
     }
     if (GUI.MouseOn == null)
     {
         if (PlayerInput.ScrollWheelSpeed != 0)
         {
             zoom = MathHelper.Clamp(zoom + PlayerInput.ScrollWheelSpeed * (float)deltaTime * 0.05f * zoom, minZoom, maxZoom);
             zoomBar.BarScroll = GetBarScrollValue();
         }
         widgets.Values.ForEach(w => w.Update((float)deltaTime));
         if (PlayerInput.MidButtonHeld())
         {
             // "Camera" Pan
             Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 100.0f;
             viewAreaOffset += moveSpeed.ToPoint();
         }
     }
     if (PlayerInput.KeyHit(Keys.Left))
     {
         foreach (var sprite in selectedSprites)
         {
             var newRect = sprite.SourceRect;
             newRect.X--;
             UpdateSourceRect(sprite, newRect);
         }
     }
     if (PlayerInput.KeyHit(Keys.Right))
     {
         foreach (var sprite in selectedSprites)
         {
             var newRect = sprite.SourceRect;
             newRect.X++;
             UpdateSourceRect(sprite, newRect);
         }
     }
     if (PlayerInput.KeyHit(Keys.Down))
     {
         foreach (var sprite in selectedSprites)
         {
             var newRect = sprite.SourceRect;
             newRect.Y++;
             UpdateSourceRect(sprite, newRect);
         }
     }
     if (PlayerInput.KeyHit(Keys.Up))
     {
         foreach (var sprite in selectedSprites)
         {
             var newRect = sprite.SourceRect;
             newRect.Y--;
             UpdateSourceRect(sprite, newRect);
         }
     }
 }
Пример #15
0
        public override void UpdateEditing(Camera cam, float deltaTime)
        {
            if (editingHUD == null || editingHUD.UserData != this)
            {
                editingHUD = CreateEditingHUD();
            }

            if (IsSelected && PlayerInput.PrimaryMouseButtonClicked() && GUI.MouseOn == null)
            {
                Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);

                if (PlayerInput.KeyDown(Keys.Space))
                {
                    foreach (MapEntity e in mapEntityList)
                    {
                        if (!(e is WayPoint) || e == this || !e.IsHighlighted)
                        {
                            continue;
                        }

                        if (linkedTo.Contains(e))
                        {
                            linkedTo.Remove(e);
                            e.linkedTo.Remove(this);
                        }
                        else
                        {
                            linkedTo.Add(e);
                            e.linkedTo.Add(this);
                        }
                    }
                }
                else
                {
                    FindHull();
                    // Update gaps, ladders, and stairs
                    UpdateLinkedEntity(position, Gap.GapList, gap => ConnectedGap = gap, gap =>
                    {
                        if (ConnectedGap == gap)
                        {
                            ConnectedGap = null;
                        }
                    });
                    UpdateLinkedEntity(position, Item.ItemList, i =>
                    {
                        var ladder = i?.GetComponent <Ladder>();
                        if (ladder != null)
                        {
                            Ladders = ladder;
                        }
                    }, i =>
                    {
                        var ladder = i?.GetComponent <Ladder>();
                        if (ladder != null)
                        {
                            if (Ladders == ladder)
                            {
                                Ladders = null;
                            }
                        }
                    }, inflate: 5);
                    FindStairs();
                    // TODO: Cannot check the rectangle, since the rectangle is not rotated -> Need to use the collider.
                    //var stairList = mapEntityList.Where(me => me is Structure s && s.StairDirection != Direction.None).Select(me => me as Structure);
                    //UpdateLinkedEntity(position, stairList, s =>
                    //{
                    //    Stairs = s;
                    //}, s =>
                    //{
                    //    if (Stairs == s)
                    //    {
                    //        Stairs = null;
                    //    }
                    //});
                }
            }
        }
Пример #16
0
        public void Update(float deltaTime, GUICustomComponent mapContainer)
        {
            Rectangle rect = mapContainer.Rect;

            subReticlePosition  = Vector2.Lerp(subReticlePosition, CurrentLocation.MapPosition, deltaTime);
            subReticleAnimState = 0.8f - Vector2.Distance(subReticlePosition, CurrentLocation.MapPosition) / 50.0f;
            subReticleAnimState = MathHelper.Clamp(subReticleAnimState + (float)Math.Sin(Timing.TotalTime * 3.5f) * 0.2f, 0.0f, 1.0f);

            targetReticleAnimState = SelectedLocation == null?
                                     Math.Max(targetReticleAnimState - deltaTime, 0.0f) :
                                         Math.Min(targetReticleAnimState + deltaTime, 0.6f + (float)Math.Sin(Timing.TotalTime * 2.5f) * 0.4f);

#if DEBUG
            if (GameMain.DebugDraw)
            {
                if (editor == null)
                {
                    CreateEditor();
                }
                editor.AddToGUIUpdateList(order: 1);
            }
#endif

            if (mapAnimQueue.Count > 0)
            {
                hudOpenState = Math.Max(hudOpenState - deltaTime, 0.0f);
                UpdateMapAnim(mapAnimQueue.Peek(), deltaTime);
                if (mapAnimQueue.Peek().Finished)
                {
                    mapAnimQueue.Dequeue();
                }
                return;
            }

            hudOpenState = Math.Min(hudOpenState + deltaTime, 0.75f + (float)Math.Sin(Timing.TotalTime * 3.0f) * 0.25f);

            Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y) + CenterOffset;

            float closestDist = 0.0f;
            highlightedLocation = null;
            if (GUI.MouseOn == null || GUI.MouseOn == mapContainer)
            {
                for (int i = 0; i < Locations.Count; i++)
                {
                    Location location = Locations[i];
                    Vector2  pos      = rectCenter + (location.MapPosition + drawOffset) * zoom;

                    if (!rect.Contains(pos))
                    {
                        continue;
                    }

                    float iconScale = MapGenerationParams.Instance.LocationIconSize / location.Type.Sprite.size.X;

                    Rectangle drawRect = location.Type.Sprite.SourceRect;
                    drawRect.Width  = (int)(drawRect.Width * iconScale * zoom * 1.4f);
                    drawRect.Height = (int)(drawRect.Height * iconScale * zoom * 1.4f);
                    drawRect.X      = (int)pos.X - drawRect.Width / 2;
                    drawRect.Y      = (int)pos.Y - drawRect.Width / 2;

                    if (!drawRect.Contains(PlayerInput.MousePosition))
                    {
                        continue;
                    }

                    float dist = Vector2.Distance(PlayerInput.MousePosition, pos);
                    if (highlightedLocation == null || dist < closestDist)
                    {
                        closestDist         = dist;
                        highlightedLocation = location;
                    }
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                float   moveSpeed  = 1000.0f;
                Vector2 moveAmount = Vector2.Zero;
                if (PlayerInput.KeyDown(InputType.Left))
                {
                    moveAmount += Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Right))
                {
                    moveAmount -= Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Up))
                {
                    moveAmount += Vector2.UnitY;
                }
                if (PlayerInput.KeyDown(InputType.Down))
                {
                    moveAmount -= Vector2.UnitY;
                }
                drawOffset += moveAmount * moveSpeed / zoom * deltaTime;
            }

            if (GUI.MouseOn == mapContainer)
            {
                foreach (LocationConnection connection in connections)
                {
                    if (highlightedLocation != CurrentLocation &&
                        connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(CurrentLocation))
                    {
                        if (PlayerInput.PrimaryMouseButtonClicked() &&
                            SelectedLocation != highlightedLocation && highlightedLocation != null)
                        {
                            //clients aren't allowed to select the location without a permission
                            if (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign))
                            {
                                SelectedConnection     = connection;
                                SelectedLocation       = highlightedLocation;
                                targetReticleAnimState = 0.0f;

                                OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
                                GameMain.Client?.SendCampaignState();
                            }
                        }
                    }
                }

                zoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
                zoom  = MathHelper.Clamp(zoom, 1.0f, 4.0f);

                if (PlayerInput.MidButtonHeld() || (highlightedLocation == null && PlayerInput.PrimaryMouseButtonHeld()))
                {
                    drawOffset += PlayerInput.MouseSpeed / zoom;
                }
#if DEBUG
                if (PlayerInput.DoubleClicked() && highlightedLocation != null)
                {
                    var passedConnection = CurrentLocation.Connections.Find(c => c.OtherLocation(CurrentLocation) == highlightedLocation);
                    if (passedConnection != null)
                    {
                        passedConnection.Passed = true;
                    }

                    Location prevLocation = CurrentLocation;
                    CurrentLocation            = highlightedLocation;
                    CurrentLocation.Discovered = true;
                    OnLocationChanged?.Invoke(prevLocation, CurrentLocation);
                    SelectLocation(-1);
                    ProgressWorld();
                }
#endif
            }
        }
Пример #17
0
        public void ReceiveCommandInput(char command)
        {
            if (Text == null)
            {
                Text = "";
            }

            // Prevent alt gr from triggering any of these as that combination is often needed for special characters
            if (PlayerInput.IsAltDown())
            {
                return;
            }

            switch (command)
            {
            case '\b' when !Readonly:     //backspace
                if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                {
                    SetText(string.Empty, false);
                    CaretIndex = Text.Length;
                }
                else if (selectedCharacters > 0)
                {
                    RemoveSelectedText();
                }
                else if (Text.Length > 0 && CaretIndex > 0)
                {
                    CaretIndex--;
                    SetText(Text.Remove(CaretIndex, 1));
                    CalculateCaretPos();
                    ClearSelection();
                }
                OnTextChanged?.Invoke(this, Text);
                break;

            case (char)0x3:     // ctrl-c
                CopySelectedText();
                break;

            case (char)0x16 when !Readonly:     // ctrl-v
                string text = GetCopiedText();
                RemoveSelectedText();
                if (SetText(Text.Insert(CaretIndex, text)))
                {
                    CaretIndex = Math.Min(Text.Length, CaretIndex + text.Length);
                    OnTextChanged?.Invoke(this, Text);
                }
                break;

            case (char)0x18:     // ctrl-x
                CopySelectedText();
                if (!Readonly)
                {
                    RemoveSelectedText();
                }
                break;

            case (char)0x1:     // ctrl-a
                if (PlayerInput.IsCtrlDown())
                {
                    SelectAll();
                }
                break;

            case (char)0x1A when !Readonly && !SubEditorScreen.IsSubEditor():     // ctrl-z
                text = memento.Undo();
                if (text != Text)
                {
                    ClearSelection();
                    SetText(text, false);
                    CaretIndex = Text.Length;
                    OnTextChanged?.Invoke(this, Text);
                }
                break;

            case (char)0x12 when !Readonly && !SubEditorScreen.IsSubEditor():     // ctrl-r
                text = memento.Redo();
                if (text != Text)
                {
                    ClearSelection();
                    SetText(text, false);
                    CaretIndex = Text.Length;
                    OnTextChanged?.Invoke(this, Text);
                }
                break;
            }
        }
Пример #18
0
        public static void Draw(SpriteBatch spriteBatch, Character character, Camera cam)
        {
            if (GUI.DisableHUD)
            {
                return;
            }

            character.CharacterHealth.Alignment = Alignment.Right;

            if (GameMain.GameSession?.CrewManager != null)
            {
                orderIndicatorCount.Clear();
                foreach (Pair <Order, float> timedOrder in GameMain.GameSession.CrewManager.ActiveOrders)
                {
                    DrawOrderIndicator(spriteBatch, cam, character, timedOrder.First, MathHelper.Clamp(timedOrder.Second / 10.0f, 0.2f, 1.0f));
                }

                if (character.CurrentOrder != null)
                {
                    DrawOrderIndicator(spriteBatch, cam, character, character.CurrentOrder, 1.0f);
                }
            }

            foreach (Character.ObjectiveEntity objectiveEntity in character.ActiveObjectiveEntities)
            {
                DrawObjectiveIndicator(spriteBatch, cam, character, objectiveEntity, 1.0f);
            }

            foreach (Item brokenItem in brokenItems)
            {
                if (brokenItem.NonInteractable)
                {
                    continue;
                }
                float   dist    = Vector2.Distance(character.WorldPosition, brokenItem.WorldPosition);
                Vector2 drawPos = brokenItem.DrawPosition;
                float   alpha   = Math.Min((1000.0f - dist) / 1000.0f * 2.0f, 1.0f);
                if (alpha <= 0.0f)
                {
                    continue;
                }
                GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, GUI.BrokenIcon,
                                  Color.Lerp(GUI.Style.Red, GUI.Style.Orange * 0.5f, brokenItem.Condition / brokenItem.MaxCondition) * alpha);
            }

            if (!character.IsIncapacitated && character.Stun <= 0.0f)
            {
                if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected)
                {
                    DrawCharacterHoverTexts(spriteBatch, cam, character);
                }

                if (character.FocusedItem != null)
                {
                    if (focusedItem != character.FocusedItem)
                    {
                        focusedItemOverlayTimer = Math.Min(1.0f, focusedItemOverlayTimer);
                        shouldRecreateHudTexts  = true;
                    }
                    focusedItem = character.FocusedItem;
                }

                if (focusedItem != null && focusedItemOverlayTimer > ItemOverlayDelay)
                {
                    Vector2 circlePos  = cam.WorldToScreen(focusedItem.DrawPosition);
                    float   circleSize = Math.Max(focusedItem.Rect.Width, focusedItem.Rect.Height) * 1.5f;
                    circleSize = MathHelper.Clamp(circleSize, 45.0f, 100.0f) * Math.Min((focusedItemOverlayTimer - 1.0f) * 5.0f, 1.0f);
                    if (circleSize > 0.0f)
                    {
                        Vector2 scale = new Vector2(circleSize / GUI.Style.FocusIndicator.FrameSize.X);
                        GUI.Style.FocusIndicator.Draw(spriteBatch,
                                                      (int)((focusedItemOverlayTimer - 1.0f) * GUI.Style.FocusIndicator.FrameCount * 3.0f),
                                                      circlePos,
                                                      Color.LightBlue * 0.3f,
                                                      origin: GUI.Style.FocusIndicator.FrameSize.ToVector2() / 2,
                                                      rotate: (float)Timing.TotalTime,
                                                      scale: scale);
                    }

                    if (!GUI.DisableItemHighlights && !Inventory.DraggingItemToWorld)
                    {
                        bool shiftDown = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift);
                        if (shouldRecreateHudTexts || heldDownShiftWhenGotHudTexts != shiftDown)
                        {
                            shouldRecreateHudTexts       = true;
                            heldDownShiftWhenGotHudTexts = shiftDown;
                        }
                        var hudTexts = focusedItem.GetHUDTexts(character, shouldRecreateHudTexts);
                        shouldRecreateHudTexts = false;

                        int dir = Math.Sign(focusedItem.WorldPosition.X - character.WorldPosition.X);

                        Vector2 textSize      = GUI.Font.MeasureString(focusedItem.Name);
                        Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(focusedItem.Name);

                        Vector2 startPos = cam.WorldToScreen(focusedItem.DrawPosition);
                        startPos.Y -= (hudTexts.Count + 1) * textSize.Y;
                        if (focusedItem.Sprite != null)
                        {
                            startPos.X += (int)(circleSize * 0.4f * dir);
                            startPos.Y -= (int)(circleSize * 0.4f);
                        }

                        Vector2 textPos = startPos;
                        if (dir == -1)
                        {
                            textPos.X -= largeTextSize.X;
                        }

                        float alpha = MathHelper.Clamp((focusedItemOverlayTimer - ItemOverlayDelay) * 2.0f, 0.0f, 1.0f);

                        GUI.DrawString(spriteBatch, textPos, focusedItem.Name, GUI.Style.TextColor * alpha, Color.Black * alpha * 0.7f, 2, font: GUI.SubHeadingFont);
                        startPos.X += dir * 10.0f * GUI.Scale;
                        textPos.X  += dir * 10.0f * GUI.Scale;
                        textPos.Y  += largeTextSize.Y;
                        foreach (ColoredText coloredText in hudTexts)
                        {
                            if (dir == -1)
                            {
                                textPos.X = (int)(startPos.X - GUI.SmallFont.MeasureString(coloredText.Text).X);
                            }
                            GUI.DrawString(spriteBatch, textPos, coloredText.Text, coloredText.Color * alpha, Color.Black * alpha * 0.7f, 2, GUI.SmallFont);
                            textPos.Y += textSize.Y;
                        }
                    }
                }

                foreach (HUDProgressBar progressBar in character.HUDProgressBars.Values)
                {
                    progressBar.Draw(spriteBatch, cam);
                }
            }

            if (character.SelectedConstruction != null &&
                (character.CanInteractWith(Character.Controlled.SelectedConstruction) || Screen.Selected == GameMain.SubEditorScreen))
            {
                character.SelectedConstruction.DrawHUD(spriteBatch, cam, Character.Controlled);
            }

            if (character.Inventory != null)
            {
                for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
                {
                    var item = character.Inventory.Items[i];
                    if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any)
                    {
                        continue;
                    }

                    foreach (ItemComponent ic in item.Components)
                    {
                        if (ic.DrawHudWhenEquipped)
                        {
                            ic.DrawHUD(spriteBatch, character);
                        }
                    }
                }
            }
            bool mouseOnPortrait = false;

            if (character.Stun <= 0.1f && !character.IsDead)
            {
                if (CharacterHealth.OpenHealthWindow == null && character.SelectedCharacter == null)
                {
                    if (character.Info != null && !character.ShouldLockHud())
                    {
                        character.Info.DrawBackground(spriteBatch);
                        character.Info.DrawJobIcon(spriteBatch,
                                                   new Rectangle(
                                                       (int)(HUDLayoutSettings.BottomRightInfoArea.X + HUDLayoutSettings.BottomRightInfoArea.Width * 0.05f),
                                                       (int)(HUDLayoutSettings.BottomRightInfoArea.Y + HUDLayoutSettings.BottomRightInfoArea.Height * 0.1f),
                                                       (int)(HUDLayoutSettings.BottomRightInfoArea.Width / 2),
                                                       (int)(HUDLayoutSettings.BottomRightInfoArea.Height * 0.7f)));
                        character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), new Vector2(-12 * GUI.Scale, 4 * GUI.Scale), targetWidth: HUDLayoutSettings.PortraitArea.Width, true);
                    }
                    mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud();
                    if (mouseOnPortrait)
                    {
                        GUI.UIGlow.Draw(spriteBatch, HUDLayoutSettings.BottomRightInfoArea, GUI.Style.Green * 0.5f);
                    }
                }
                if (ShouldDrawInventory(character))
                {
                    character.Inventory.Locked = LockInventory(character);
                    character.Inventory.DrawOwn(spriteBatch);
                    character.Inventory.CurrentLayout = CharacterHealth.OpenHealthWindow == null && character.SelectedCharacter == null ?
                                                        CharacterInventory.Layout.Default :
                                                        CharacterInventory.Layout.Right;
                }
            }

            if (!character.IsIncapacitated && character.Stun <= 0.0f)
            {
                if (character.IsHumanoid && character.SelectedCharacter != null && character.SelectedCharacter.Inventory != null)
                {
                    if (character.SelectedCharacter.CanInventoryBeAccessed)
                    {
                        ///character.Inventory.CurrentLayout = Alignment.Left;
                        character.SelectedCharacter.Inventory.CurrentLayout = CharacterInventory.Layout.Left;
                        character.SelectedCharacter.Inventory.DrawOwn(spriteBatch);
                    }
                    else
                    {
                        //character.Inventory.CurrentLayout = (CharacterHealth.OpenHealthWindow == null) ? Alignment.Center : Alignment.Left;
                    }
                    if (CharacterHealth.OpenHealthWindow == character.SelectedCharacter.CharacterHealth)
                    {
                        character.SelectedCharacter.CharacterHealth.Alignment = Alignment.Left;
                        character.SelectedCharacter.CharacterHealth.DrawStatusHUD(spriteBatch);
                    }
                }
                else if (character.Inventory != null)
                {
                    //character.Inventory.CurrentLayout = (CharacterHealth.OpenHealthWindow == null) ? Alignment.Center : Alignment.Left;
                }
            }

            if (mouseOnPortrait)
            {
                GUIComponent.DrawToolTip(
                    spriteBatch,
                    character.Info?.Job == null ? character.DisplayName : character.DisplayName + " (" + character.Info.Job.Name + ")",
                    HUDLayoutSettings.PortraitArea);
            }
        }
Пример #19
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if DEBUG && CLIENT
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
                !DebugConsole.IsOpen && GUI.KeyboardDispatcher.Subscriber == null)
            {
                var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
                if (closestSub == null)
                {
                    closestSub = GameMain.GameSession.Submarine;
                }

                Vector2 targetMovement = Vector2.Zero;
                if (PlayerInput.KeyDown(Keys.I))
                {
                    targetMovement.Y += 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.K))
                {
                    targetMovement.Y -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.J))
                {
                    targetMovement.X -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.L))
                {
                    targetMovement.X += 1.0f;
                }

                if (targetMovement != Vector2.Zero)
                {
                    closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                }
            }
#endif

            GameTime += deltaTime;

            foreach (PhysicsBody body in PhysicsBody.List)
            {
                body.Update((float)deltaTime);
            }
            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

            if (GameMain.GameSession != null)
            {
                GameMain.GameSession.Update((float)deltaTime);
            }
#if CLIENT
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            GameMain.ParticleManager.Update((float)deltaTime);

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("ParticleUpdate", sw.ElapsedTicks);
            sw.Restart();

            GameMain.LightManager.Update((float)deltaTime);

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("LightUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, cam);
            }

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("LevelUpdate", sw.ElapsedTicks);

            if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
            {
                Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
            }
            sw.Restart();
#endif

            Character.UpdateAll((float)deltaTime, cam);

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("CharacterUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            StatusEffect.UpdateAll((float)deltaTime);

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("StatusEffectUpdate", sw.ElapsedTicks);
            sw.Restart();

            if (Character.Controlled != null &&
                Lights.LightManager.ViewTarget != null)
            {
                Vector2 targetPos = Lights.LightManager.ViewTarget.DrawPosition;
                if (Lights.LightManager.ViewTarget == Character.Controlled && CharacterHealth.OpenHealthWindow != null)
                {
                    Vector2 screenTargetPos = CharacterHealth.OpenHealthWindow.Alignment == Alignment.Left ?
                                              new Vector2(GameMain.GraphicsWidth * 0.75f, GameMain.GraphicsHeight * 0.5f) :
                                              new Vector2(GameMain.GraphicsWidth * 0.25f, GameMain.GraphicsHeight * 0.5f);
                    Vector2 screenOffset = screenTargetPos - new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight / 2);
                    screenOffset.Y = -screenOffset.Y;
                    targetPos     -= screenOffset / cam.Zoom;
                }
                cam.TargetPos = targetPos;
            }
#endif

            cam.MoveCamera((float)deltaTime);

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody pb in PhysicsBody.List)
            {
                pb.SetPrevTransform(pb.SimPosition, pb.Rotation);
            }

            MapEntity.UpdateAll((float)deltaTime, cam);
#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("MapEntityUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif
            Character.UpdateAnimAll((float)deltaTime);

            Ragdoll.UpdateAll((float)deltaTime, cam);

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("AnimUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("SubmarineUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            GameMain.World.Step((float)deltaTime);

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("Physics", sw.ElapsedTicks);
#endif

#if CLIENT
            if (!PlayerInput.LeftButtonHeld())
            {
                Inventory.draggingSlot = null;
                Inventory.draggingItem = null;
            }
#endif
        }
Пример #20
0
        /// <summary>
        /// Update the selection logic in submarine editor
        /// </summary>
        public static void UpdateSelecting(Camera cam)
        {
            if (resizing)
            {
                if (selectedList.Count == 0)
                {
                    resizing = false;
                }
                return;
            }

            foreach (MapEntity e in mapEntityList)
            {
                e.isHighlighted = false;
            }

            if (DisableSelect)
            {
                DisableSelect = false;
                return;
            }

            if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow)
            {
                if (highlightedListBox == null ||
                    (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))
                {
                    UpdateHighlightedListBox(null, false);
                    return;
                }
            }

            if (MapEntityPrefab.Selected != null)
            {
                selectionPos = Vector2.Zero;
                selectedList.Clear();
                return;
            }
            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                if (PlayerInput.KeyHit(Keys.Delete))
                {
                    if (selectedList.Any())
                    {
                        SubEditorScreen.StoreCommand(new AddOrDeleteCommand(selectedList, true));
                    }
                    selectedList.ForEach(e => { if (!e.Removed)
                                                {
                                                    e.Remove();
                                                }
                                         });
                    selectedList.Clear();
                }

                if (PlayerInput.IsCtrlDown())
                {
#if DEBUG
                    if (PlayerInput.KeyHit(Keys.D))
                    {
                        bool terminate = false;
                        foreach (MapEntity entity in selectedList)
                        {
                            if (entity is Item item && item.GetComponent <Planter>() is { } planter)
                            {
                                planter.Update(1.0f, cam);
                                for (var i = 0; i < planter.GrowableSeeds.Length; i++)
                                {
                                    Growable  seed = planter.GrowableSeeds[i];
                                    PlantSlot slot = planter.PlantSlots.ContainsKey(i) ? planter.PlantSlots[i] : Planter.NullSlot;
                                    if (seed == null)
                                    {
                                        continue;
                                    }

                                    seed.CreateDebugHUD(planter, slot);
                                    terminate = true;
                                    break;
                                }
                            }

                            if (terminate)
                            {
                                break;
                            }
                        }
                    }
#endif
                    if (PlayerInput.KeyHit(Keys.C))
                    {
                        Copy(selectedList);
                    }
                    else if (PlayerInput.KeyHit(Keys.X))
                    {
                        Cut(selectedList);
                    }
                    else if (PlayerInput.KeyHit(Keys.V))
                    {
                        Paste(cam.WorldViewCenter);
                    }
                    else if (PlayerInput.KeyHit(Keys.G))
                    {
                        if (selectedList.Any())
                        {
                            if (SelectionGroups.ContainsKey(selectedList.Last()))
                            {
                                // Ungroup all selected
                                selectedList.ForEach(e => SelectionGroups.Remove(e));
                            }
                            else
                            {
                                foreach (var entity in selectedList)
                                {
                                    // Remove the old group, if any
                                    SelectionGroups.Remove(entity);
                                    // Create a group that can be accessed with any member
                                    SelectionGroups.Add(entity, selectedList);
                                }
                            }
                        }
                    }
                }
            }

            Vector2   position          = cam.ScreenToWorld(PlayerInput.MousePosition);
            MapEntity highLightedEntity = null;
            if (startMovingPos == Vector2.Zero)
            {
                List <MapEntity> highlightedEntities = new List <MapEntity>();
                if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn))
                {
                    highLightedEntity = GUI.MouseOn.UserData as MapEntity;
                }
                else
                {
                    foreach (MapEntity e in mapEntityList)
                    {
                        if (!e.SelectableInEditor)
                        {
                            continue;
                        }

                        if (e.IsMouseOn(position))
                        {
                            int i = 0;
                            while (i < highlightedEntities.Count &&
                                   e.Sprite != null &&
                                   (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth))
                            {
                                i++;
                            }

                            highlightedEntities.Insert(i, e);

                            if (i == 0)
                            {
                                highLightedEntity = e;
                            }
                        }
                    }

                    UpdateHighlighting(highlightedEntities);
                }

                if (highLightedEntity != null)
                {
                    highLightedEntity.isHighlighted = true;
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                int up    = PlayerInput.KeyDown(Keys.Up) ? 1 : 0,
                    down  = PlayerInput.KeyDown(Keys.Down) ? -1 : 0,
                    left  = PlayerInput.KeyDown(Keys.Left) ? -1 : 0,
                    right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0;

                int xKeysDown = (left + right);
                int yKeysDown = (up + down);

                if (xKeysDown != 0 || yKeysDown != 0)
                {
                    keyDelay += (float)Timing.Step;
                }
                else
                {
                    keyDelay = 0;
                }

                Vector2 nudgeAmount = Vector2.Zero;

                if (keyDelay >= 0.5f)
                {
                    nudgeAmount.Y = yKeysDown;
                    nudgeAmount.X = xKeysDown;
                }

                if (PlayerInput.KeyHit(Keys.Up))
                {
                    nudgeAmount.Y = 1f;
                }
                if (PlayerInput.KeyHit(Keys.Down))
                {
                    nudgeAmount.Y = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Left))
                {
                    nudgeAmount.X = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Right))
                {
                    nudgeAmount.X = 1f;
                }
                if (nudgeAmount != Vector2.Zero)
                {
                    foreach (MapEntity entityToNudge in selectedList)
                    {
                        entityToNudge.Move(nudgeAmount);
                    }
                }
            }
            else
            {
                keyDelay = 0;
            }

            bool isShiftDown = PlayerInput.IsShiftDown();

            //started moving selected entities
            if (startMovingPos != Vector2.Zero)
            {
                Item targetContainer = GetPotentialContainer(position, selectedList);

                if (targetContainer != null)
                {
                    targetContainer.IsHighlighted = true;
                }

                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    //mouse released -> move the entities to the new position of the mouse

                    Vector2 moveAmount = position - startMovingPos;

                    if (!isShiftDown)
                    {
                        moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X;
                        moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y;
                    }

                    if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown)
                    {
                        if (!isShiftDown)
                        {
                            moveAmount = Submarine.VectorToWorldGrid(moveAmount);
                        }

                        //clone
                        if (PlayerInput.IsCtrlDown())
                        {
                            var clones = Clone(selectedList).Where(c => c != null).ToList();
                            selectedList = clones;
                            selectedList.ForEach(c => c.Move(moveAmount));
                            SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false));
                        }
                        else // move
                        {
                            var oldRects = selectedList.Select(e => e.Rect).ToList();
                            List <MapEntity> deposited = new List <MapEntity>();
                            foreach (MapEntity e in selectedList)
                            {
                                e.Move(moveAmount);

                                if (isShiftDown && e is Item item && targetContainer != null)
                                {
                                    if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled))
                                    {
                                        SoundPlayer.PlayUISound(GUISoundType.DropItem);
                                        deposited.Add(item);
                                    }
                                    else
                                    {
                                        SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
                                    }
                                }
                            }

                            SubEditorScreen.StoreCommand(new TransformCommand(new List <MapEntity>(selectedList), selectedList.Select(entity => entity.Rect).ToList(), oldRects, false));
                            if (deposited.Any() && deposited.Any(entity => entity is Item))
                            {
                                var depositedItems = deposited.Where(entity => entity is Item).Cast <Item>().ToList();
                                SubEditorScreen.StoreCommand(new InventoryPlaceCommand(targetContainer.OwnInventory, depositedItems, false));
                            }

                            deposited.ForEach(entity => { selectedList.Remove(entity); });
                        }
                    }
                    startMovingPos = Vector2.Zero;
                }
            }
            //started dragging a "selection rectangle"
            else if (selectionPos != Vector2.Zero)
            {
                selectionSize.X = position.X - selectionPos.X;
                selectionSize.Y = selectionPos.Y - position.Y;

                List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize);
                if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y)
                {
                    newSelection = FindSelectedEntities(selectionPos, selectionSize);
                }
                else
                {
                    if (highLightedEntity != null)
                    {
                        if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group))
                        {
                            newSelection.AddRange(group);
                        }
                        else
                        {
                            newSelection.Add(highLightedEntity);
                        }
                    }
                }

                if (PlayerInput.PrimaryMouseButtonReleased())
                {
                    if (PlayerInput.IsCtrlDown())
                    {
                        foreach (MapEntity e in newSelection)
                        {
                            if (selectedList.Contains(e))
                            {
                                RemoveSelection(e);
                            }
                            else
                            {
                                AddSelection(e);
                            }
                        }
                    }
                    else
                    {
                        selectedList = new List <MapEntity>(newSelection);
                        //selectedList.Clear();
                        //newSelection.ForEach(e => AddSelection(e));
                        foreach (var entity in newSelection)
                        {
                            HandleDoorGapLinks(entity,
                                               onGapFound: (door, gap) =>
                            {
                                door.RefreshLinkedGap();
                                if (!selectedList.Contains(gap))
                                {
                                    selectedList.Add(gap);
                                }
                            },
                                               onDoorFound: (door, gap) =>
                            {
                                if (!selectedList.Contains(door.Item))
                                {
                                    selectedList.Add(door.Item);
                                }
                            });
                        }
                    }

                    //select wire if both items it's connected to are selected
                    var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList();
                    foreach (Item item in selectedItems)
                    {
                        if (item.Connections == null)
                        {
                            continue;
                        }
                        foreach (Connection c in item.Connections)
                        {
                            foreach (Wire w in c.Wires)
                            {
                                if (w == null || selectedList.Contains(w.Item))
                                {
                                    continue;
                                }

                                if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item))
                                {
                                    selectedList.Add(w.Item);
                                }
                            }
                        }
                    }

                    selectionPos  = Vector2.Zero;
                    selectionSize = Vector2.Zero;
                }
            }
            //default, not doing anything specific yet
            else
            {
                if (PlayerInput.PrimaryMouseButtonHeld() &&
                    PlayerInput.KeyUp(Keys.Space) &&
                    (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))))
                {
                    //if clicking a selected entity, start moving it
                    foreach (MapEntity e in selectedList)
                    {
                        if (e.IsMouseOn(position))
                        {
                            startMovingPos = position;
                        }
                    }
                    selectionPos = position;

                    //stop camera movement to prevent accidental dragging or rect selection
                    Screen.Selected.Cam.StopMovement();
                }
            }
        }
Пример #21
0
        /// <summary>
        /// Update the selection logic in submarine editor
        /// </summary>
        public static void UpdateSelecting(Camera cam)
        {
            if (resizing)
            {
                if (selectedList.Count == 0)
                {
                    resizing = false;
                }
                return;
            }

            foreach (MapEntity e in mapEntityList)
            {
                e.isHighlighted = false;
            }

            if (DisableSelect)
            {
                DisableSelect = false;
                return;
            }

            if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow)
            {
                if (highlightedListBox == null ||
                    (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))
                {
                    UpdateHighlightedListBox(null);
                    return;
                }
            }

            if (MapEntityPrefab.Selected != null)
            {
                selectionPos = Vector2.Zero;
                selectedList.Clear();
                return;
            }
            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                if (PlayerInput.KeyDown(Keys.Delete))
                {
                    selectedList.ForEach(e => e.Remove());
                    selectedList.Clear();
                }

                if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                {
                    if (PlayerInput.KeyHit(Keys.C))
                    {
                        CopyEntities(selectedList);
                    }
                    else if (PlayerInput.KeyHit(Keys.X))
                    {
                        CopyEntities(selectedList);

                        selectedList.ForEach(e => e.Remove());
                        selectedList.Clear();
                    }
                    else if (copiedList.Count > 0 && PlayerInput.KeyHit(Keys.V))
                    {
                        List <MapEntity> prevEntities = new List <MapEntity>(mapEntityList);
                        Clone(copiedList);

                        var clones = mapEntityList.Except(prevEntities).ToList();

                        Vector2 center = Vector2.Zero;
                        clones.ForEach(c => center += c.WorldPosition);
                        center = Submarine.VectorToWorldGrid(center / clones.Count);

                        Vector2 moveAmount = Submarine.VectorToWorldGrid(cam.WorldViewCenter - center);

                        selectedList = new List <MapEntity>(clones);
                        foreach (MapEntity clone in selectedList)
                        {
                            clone.Move(moveAmount);
                            clone.Submarine = Submarine.MainSub;
                        }
                    }
                    else if (PlayerInput.KeyHit(Keys.G))
                    {
                        if (selectedList.Any())
                        {
                            if (SelectionGroups.ContainsKey(selectedList.Last()))
                            {
                                // Ungroup all selected
                                selectedList.ForEach(e => SelectionGroups.Remove(e));
                            }
                            else
                            {
                                foreach (var entity in selectedList)
                                {
                                    // Remove the old group, if any
                                    SelectionGroups.Remove(entity);
                                    // Create a group that can be accessed with any member
                                    SelectionGroups.Add(entity, selectedList);
                                }
                            }
                        }
                    }
                    else if (PlayerInput.KeyHit(Keys.Z))
                    {
                        SetPreviousRects(e => e.rectMemento.Undo());
                    }
                    else if (PlayerInput.KeyHit(Keys.R))
                    {
                        SetPreviousRects(e => e.rectMemento.Redo());
                    }

                    void SetPreviousRects(Func <MapEntity, Rectangle> memoryMethod)
                    {
                        foreach (var e in SelectedList)
                        {
                            if (e.rectMemento != null)
                            {
                                Point diff = memoryMethod(e).Location - e.Rect.Location;
                                // We have to call the move method, because there's a lot more than just storing the rect (in some cases)
                                // We also have to reassign the rect, because the move method does not set the width and height. They might have changed too.
                                // The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures.
                                e.Move(diff.ToVector2());
                                e.Rect = e.rectMemento.Current;
                            }
                        }
                    }
                }
            }

            Vector2   position          = cam.ScreenToWorld(PlayerInput.MousePosition);
            MapEntity highLightedEntity = null;

            if (startMovingPos == Vector2.Zero)
            {
                List <MapEntity> highlightedEntities = new List <MapEntity>();
                if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn))
                {
                    highLightedEntity = GUI.MouseOn.UserData as MapEntity;
                }
                else
                {
                    foreach (MapEntity e in mapEntityList)
                    {
                        if (!e.SelectableInEditor)
                        {
                            continue;
                        }

                        if (e.IsMouseOn(position))
                        {
                            int i = 0;
                            while (i < highlightedEntities.Count &&
                                   e.Sprite != null &&
                                   (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth))
                            {
                                i++;
                            }

                            highlightedEntities.Insert(i, e);

                            if (i == 0)
                            {
                                highLightedEntity = e;
                            }
                        }
                    }

                    if (PlayerInput.MouseSpeed.LengthSquared() > 10)
                    {
                        highlightTimer = 0.0f;
                    }
                    else
                    {
                        bool mouseNearHighlightBox = false;

                        if (highlightedListBox != null)
                        {
                            Rectangle expandedRect = highlightedListBox.Rect;
                            expandedRect.Inflate(20, 20);
                            mouseNearHighlightBox = expandedRect.Contains(PlayerInput.MousePosition);
                            if (!mouseNearHighlightBox)
                            {
                                highlightedListBox = null;
                            }
                        }

                        highlightTimer += (float)Timing.Step;
                        if (highlightTimer > 1.0f)
                        {
                            if (!mouseNearHighlightBox)
                            {
                                UpdateHighlightedListBox(highlightedEntities);
                                highlightTimer = 0.0f;
                            }
                        }
                    }
                }

                if (highLightedEntity != null)
                {
                    highLightedEntity.isHighlighted = true;
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                Vector2 nudgeAmount = Vector2.Zero;
                if (PlayerInput.KeyHit(Keys.Up))
                {
                    nudgeAmount.Y = 1f;
                }
                if (PlayerInput.KeyHit(Keys.Down))
                {
                    nudgeAmount.Y = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Left))
                {
                    nudgeAmount.X = -1f;
                }
                if (PlayerInput.KeyHit(Keys.Right))
                {
                    nudgeAmount.X = 1f;
                }
                if (nudgeAmount != Vector2.Zero)
                {
                    foreach (MapEntity entityToNudge in selectedList)
                    {
                        entityToNudge.Move(nudgeAmount);
                    }
                }
            }

            //started moving selected entities
            if (startMovingPos != Vector2.Zero)
            {
                if (PlayerInput.LeftButtonReleased())
                {
                    //mouse released -> move the entities to the new position of the mouse

                    Vector2 moveAmount = position - startMovingPos;
                    moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X;
                    moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y;
                    if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y)
                    {
                        moveAmount = Submarine.VectorToWorldGrid(moveAmount);
                        //clone
                        if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                        {
                            var clones = Clone(selectedList);
                            selectedList = clones;
                            selectedList.ForEach(c => c.Move(moveAmount));
                        }
                        else // move
                        {
                            foreach (MapEntity e in selectedList)
                            {
                                if (e.rectMemento == null)
                                {
                                    e.rectMemento = new Memento <Rectangle>();
                                    e.rectMemento.Store(e.Rect);
                                }
                                e.Move(moveAmount);
                                e.rectMemento.Store(e.Rect);
                            }
                        }
                    }
                    startMovingPos = Vector2.Zero;
                }
            }
            //started dragging a "selection rectangle"
            else if (selectionPos != Vector2.Zero)
            {
                selectionSize.X = position.X - selectionPos.X;
                selectionSize.Y = selectionPos.Y - position.Y;

                List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize);
                if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y)
                {
                    newSelection = FindSelectedEntities(selectionPos, selectionSize);
                }
                else
                {
                    if (highLightedEntity != null)
                    {
                        if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group))
                        {
                            newSelection.AddRange(group);
                        }
                        else
                        {
                            newSelection.Add(highLightedEntity);
                        }
                    }
                }

                if (PlayerInput.LeftButtonReleased())
                {
                    if (PlayerInput.KeyDown(Keys.LeftControl) ||
                        PlayerInput.KeyDown(Keys.RightControl))
                    {
                        foreach (MapEntity e in newSelection)
                        {
                            if (selectedList.Contains(e))
                            {
                                RemoveSelection(e);
                            }
                            else
                            {
                                AddSelection(e);
                            }
                        }
                    }
                    else
                    {
                        selectedList = newSelection;
                        //selectedList.Clear();
                        //newSelection.ForEach(e => AddSelection(e));
                        foreach (var entity in newSelection)
                        {
                            HandleDoorGapLinks(entity,
                                               onGapFound: (door, gap) =>
                            {
                                door.RefreshLinkedGap();
                                if (!selectedList.Contains(gap))
                                {
                                    selectedList.Add(gap);
                                }
                            },
                                               onDoorFound: (door, gap) =>
                            {
                                if (!selectedList.Contains(door.Item))
                                {
                                    selectedList.Add(door.Item);
                                }
                            });
                        }
                    }

                    //select wire if both items it's connected to are selected
                    var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList();
                    foreach (Item item in selectedItems)
                    {
                        if (item.Connections == null)
                        {
                            continue;
                        }
                        foreach (Connection c in item.Connections)
                        {
                            foreach (Wire w in c.Wires)
                            {
                                if (w == null || selectedList.Contains(w.Item))
                                {
                                    continue;
                                }

                                if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item))
                                {
                                    selectedList.Add(w.Item);
                                }
                            }
                        }
                    }

                    selectionPos  = Vector2.Zero;
                    selectionSize = Vector2.Zero;
                }
            }
            //default, not doing anything specific yet
            else
            {
                if (PlayerInput.LeftButtonHeld() &&
                    PlayerInput.KeyUp(Keys.Space) &&
                    (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))))
                {
                    //if clicking a selected entity, start moving it
                    foreach (MapEntity e in selectedList)
                    {
                        if (e.IsMouseOn(position))
                        {
                            startMovingPos = position;
                        }
                    }
                    selectionPos = position;

                    //stop camera movement to prevent accidental dragging or rect selection
                    Screen.Selected.Cam.StopMovement();
                }
            }
        }
Пример #22
0
        public void Update(float deltaTime, GUICustomComponent mapContainer)
        {
            Rectangle rect = mapContainer.Rect;

            if (CurrentDisplayLocation != null)
            {
                if (!CurrentDisplayLocation.Discovered)
                {
                    RemoveFogOfWar(CurrentDisplayLocation);
                    CurrentDisplayLocation.Discovered = true;
                    if (CurrentDisplayLocation.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
                    {
                        furthestDiscoveredLocation = CurrentDisplayLocation;
                    }
                }
            }

            currLocationIndicatorPos = Vector2.Lerp(currLocationIndicatorPos, CurrentDisplayLocation.MapPosition, deltaTime);
#if DEBUG
            if (GameMain.DebugDraw)
            {
                if (editor == null)
                {
                    CreateEditor();
                }
                editor.AddToGUIUpdateList(order: 1);
            }
#endif

            if (mapAnimQueue.Count > 0)
            {
                hudVisibility = Math.Max(hudVisibility - deltaTime, 0.0f);
                UpdateMapAnim(mapAnimQueue.Peek(), deltaTime);
                if (mapAnimQueue.Peek().Finished)
                {
                    mapAnimQueue.Dequeue();
                }
                return;
            }

            hudVisibility = Math.Min(hudVisibility + deltaTime, 0.75f + (float)Math.Sin(Timing.TotalTime * 3.0f) * 0.25f);

            Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
            Vector2 viewOffset = DrawOffset + drawOffsetNoise;

            float closestDist = 0.0f;
            HighlightedLocation = null;
            if (GUI.MouseOn == null || GUI.MouseOn == mapContainer)
            {
                for (int i = 0; i < Locations.Count; i++)
                {
                    Location location = Locations[i];
                    if (IsInFogOfWar(location) && !(CurrentDisplayLocation?.Connections.Any(c => c.Locations.Contains(location)) ?? false) && !GameMain.DebugDraw)
                    {
                        continue;
                    }

                    Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
                    if (!rect.Contains(pos))
                    {
                        continue;
                    }

                    float iconScale = generationParams.LocationIconSize / location.Type.Sprite.size.X;
                    if (location == CurrentDisplayLocation)
                    {
                        iconScale *= 1.2f;
                    }

                    Rectangle drawRect = location.Type.Sprite.SourceRect;
                    drawRect.Width  = (int)(drawRect.Width * iconScale * zoom * 1.4f);
                    drawRect.Height = (int)(drawRect.Height * iconScale * zoom * 1.4f);
                    drawRect.X      = (int)pos.X - drawRect.Width / 2;
                    drawRect.Y      = (int)pos.Y - drawRect.Width / 2;

                    if (!drawRect.Contains(PlayerInput.MousePosition))
                    {
                        continue;
                    }

                    float dist = Vector2.Distance(PlayerInput.MousePosition, pos);
                    if (HighlightedLocation == null || dist < closestDist)
                    {
                        closestDist         = dist;
                        HighlightedLocation = location;
                    }
                }
            }

            if (GUI.KeyboardDispatcher.Subscriber == null)
            {
                float   moveSpeed  = 1000.0f;
                Vector2 moveAmount = Vector2.Zero;
                if (PlayerInput.KeyDown(InputType.Left))
                {
                    moveAmount += Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Right))
                {
                    moveAmount -= Vector2.UnitX;
                }
                if (PlayerInput.KeyDown(InputType.Up))
                {
                    moveAmount += Vector2.UnitY;
                }
                if (PlayerInput.KeyDown(InputType.Down))
                {
                    moveAmount -= Vector2.UnitY;
                }
                DrawOffset += moveAmount * moveSpeed / zoom * deltaTime;
            }

            targetZoom = MathHelper.Clamp(targetZoom, generationParams.MinZoom, generationParams.MaxZoom);
            zoom       = MathHelper.Lerp(zoom, targetZoom, 0.1f);

            if (GUI.MouseOn == mapContainer)
            {
                foreach (LocationConnection connection in Connections)
                {
                    if (HighlightedLocation != CurrentDisplayLocation &&
                        connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
                    {
                        if (PlayerInput.PrimaryMouseButtonClicked() &&
                            SelectedLocation != HighlightedLocation && HighlightedLocation != null)
                        {
                            //clients aren't allowed to select the location without a permission
                            if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign() ?? false)
                            {
                                SelectedConnection = connection;
                                SelectedLocation   = HighlightedLocation;

                                OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
                                GameMain.Client?.SendCampaignState();
                            }
                        }
                    }
                }

                targetZoom += PlayerInput.ScrollWheelSpeed / 500.0f;

                if (PlayerInput.MidButtonHeld() || (HighlightedLocation == null && PlayerInput.PrimaryMouseButtonHeld()))
                {
                    DrawOffset += PlayerInput.MouseSpeed / zoom;
                }
                if (AllowDebugTeleport)
                {
                    if (PlayerInput.DoubleClicked() && HighlightedLocation != null)
                    {
                        var passedConnection = CurrentDisplayLocation.Connections.Find(c => c.OtherLocation(CurrentDisplayLocation) == HighlightedLocation);
                        if (passedConnection != null)
                        {
                            passedConnection.Passed = true;
                        }

                        Location prevLocation = CurrentDisplayLocation;
                        CurrentLocation = HighlightedLocation;
                        Level.Loaded.DebugSetStartLocation(CurrentLocation);
                        Level.Loaded.DebugSetEndLocation(null);

                        CurrentLocation.Discovered = true;
                        OnLocationChanged?.Invoke(prevLocation, CurrentLocation);
                        SelectLocation(-1);
                        if (GameMain.Client == null)
                        {
                            CurrentLocation.CreateStore();
                            ProgressWorld();
                        }
                        else
                        {
                            GameMain.Client.SendCampaignState();
                        }
                    }

                    if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftShift) && PlayerInput.PrimaryMouseButtonClicked() && HighlightedLocation != null)
                    {
                        int distance = DistanceToClosestLocationWithOutpost(HighlightedLocation, out Location foundLocation);
                        DebugConsole.NewMessage($"Distance to closest outpost from {HighlightedLocation.Name} to {foundLocation?.Name} is {distance}");
                    }

                    if (PlayerInput.PrimaryMouseButtonClicked() && HighlightedLocation == null)
                    {
                        SelectLocation(-1);
                    }
                }
            }
        }
Пример #23
0
        public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true)
        {
            prevPosition = position;
            prevZoom     = zoom;

            float moveSpeed = 20.0f / zoom;

            Vector2 moveCam = Vector2.Zero;

            if (targetPos == Vector2.Zero)
            {
                Vector2 moveInput = Vector2.Zero;
                if (allowMove && !Freeze)
                {
                    if (GUI.KeyboardDispatcher.Subscriber == null)
                    {
                        if (PlayerInput.KeyDown(Keys.LeftShift))
                        {
                            moveSpeed *= 2.0f;
                        }
                        if (PlayerInput.KeyDown(Keys.LeftControl))
                        {
                            moveSpeed *= 0.5f;
                        }

                        if (GameMain.Config.KeyBind(InputType.Left).IsDown())
                        {
                            moveInput.X -= 1.0f;
                        }
                        if (GameMain.Config.KeyBind(InputType.Right).IsDown())
                        {
                            moveInput.X += 1.0f;
                        }
                        if (GameMain.Config.KeyBind(InputType.Down).IsDown())
                        {
                            moveInput.Y -= 1.0f;
                        }
                        if (GameMain.Config.KeyBind(InputType.Up).IsDown())
                        {
                            moveInput.Y += 1.0f;
                        }
                    }

                    velocity = Vector2.Lerp(velocity, moveInput, deltaTime * 10.0f);
                    moveCam  = velocity * moveSpeed * deltaTime * 60.0f;

                    if (Screen.Selected == GameMain.GameScreen && FollowSub)
                    {
                        var closestSub = Submarine.FindClosest(WorldViewCenter);
                        if (closestSub != null)
                        {
                            moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(closestSub.Velocity * deltaTime);
                        }
                    }
                }

                if (allowZoom && GUI.MouseOn == null)
                {
                    Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
                    Vector2 diffViewCenter;
                    diffViewCenter = ((mouseInWorld - Position) * Zoom);
                    targetZoom     = MathHelper.Clamp(
                        targetZoom + (PlayerInput.ScrollWheelSpeed / 1000.0f) * zoom,
                        GameMain.DebugDraw ? MinZoom * 0.1f : MinZoom,
                        MaxZoom);

                    Zoom = MathHelper.Lerp(Zoom, targetZoom, deltaTime * 10.0f);
                    if (!PlayerInput.KeyDown(Keys.F))
                    {
                        Position = mouseInWorld - (diffViewCenter / Zoom);
                    }
                }
            }
            else if (allowMove)
            {
                Vector2 mousePos = PlayerInput.MousePosition;
                Vector2 offset   = mousePos - resolution.ToVector2() / 2;
                offset.X = offset.X / (resolution.X * 0.4f);
                offset.Y = -offset.Y / (resolution.Y * 0.3f);
                if (offset.LengthSquared() > 1.0f)
                {
                    offset.Normalize();
                }
                offset *= offsetAmount;
                // Freeze the camera movement by default, when the cursor is on top of an ui element.
                // Setting a positive value to the OffsetAmount, will override this behaviour.
                if (GUI.MouseOn != null && offsetAmount > 0)
                {
                    Freeze = true;
                }
                if (CharacterHealth.OpenHealthWindow != null || CrewManager.IsCommandInterfaceOpen || ConversationAction.IsDialogOpen)
                {
                    offset *= 0;
                    Freeze  = false;
                }
                if (Freeze)
                {
                    offset = previousOffset;
                }
                else
                {
                    previousOffset = offset;
                }

                //how much to zoom out (zoom completely out when offset is 1000)
                float zoomOutAmount = GetZoomAmount(offset);
                //zoom amount when resolution is not taken into account
                float unscaledZoom = MathHelper.Lerp(DefaultZoom, MinZoom, zoomOutAmount);
                //zoom with resolution taken into account (zoom further out on smaller resolutions)
                float scaledZoom = unscaledZoom * globalZoomScale;

                //an ad-hoc way of allowing the players to have roughly the same maximum view distance regardless of the resolution,
                //while still keeping the zoom around 1.0 when not looking further away (because otherwise we'd always be downsampling
                //on lower resolutions, which doesn't look that good)
                float newZoom = MathHelper.Lerp(unscaledZoom, scaledZoom,
                                                (GameMain.Config == null || GameMain.Config.EnableMouseLook) ? (float)Math.Sqrt(zoomOutAmount) : 0.3f);

                Zoom += (newZoom - zoom) / ZoomSmoothness;

                //force targetzoom to the current zoom value, so the camera stays at the same zoom when switching to freecam
                targetZoom = Zoom;

                Vector2 diff = (targetPos + offset) - position;

                moveCam = diff / MoveSmoothness;
            }
            rotation        += angularVelocity * deltaTime;
            angularVelocity *= (1.0f - angularDamping);
            angularVelocity += -rotation * angularSpring;

            angularDamping = 0.05f;
            angularSpring  = 0.2f;

            if (Shake < 0.01f)
            {
                shakePosition = Vector2.Zero;
                shakeTimer    = 0.0f;
            }
            else
            {
                shakeTimer += deltaTime * 5.0f;
                Vector2 noisePos = new Vector2((float)PerlinNoise.CalculatePerlin(shakeTimer, shakeTimer, 0) - 0.5f, (float)PerlinNoise.CalculatePerlin(shakeTimer, shakeTimer, 0.5f) - 0.5f);

                shakePosition = noisePos * Shake * 2.0f;
                Shake         = MathHelper.Lerp(Shake, 0.0f, deltaTime * 2.0f);
            }

            Translate(moveCam + shakePosition);
            Freeze = false;
        }
Пример #24
0
        public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true, bool?followSub = null)
        {
            prevPosition = position;
            prevZoom     = zoom;

            float moveSpeed = 20.0f / zoom;

            Vector2 moveCam = Vector2.Zero;

            if (TargetPos == Vector2.Zero)
            {
                Vector2 moveInput = Vector2.Zero;
                if (allowMove && !Freeze)
                {
                    if (GUI.KeyboardDispatcher.Subscriber == null)
                    {
                        if (PlayerInput.KeyDown(Keys.LeftShift))
                        {
                            moveSpeed *= 2.0f;
                        }
                        if (PlayerInput.KeyDown(Keys.LeftControl))
                        {
                            moveSpeed *= 0.5f;
                        }

                        if (GameMain.Config.KeyBind(InputType.Left).IsDown())
                        {
                            moveInput.X -= 1.0f;
                        }
                        if (GameMain.Config.KeyBind(InputType.Right).IsDown())
                        {
                            moveInput.X += 1.0f;
                        }
                        if (GameMain.Config.KeyBind(InputType.Down).IsDown())
                        {
                            moveInput.Y -= 1.0f;
                        }
                        if (GameMain.Config.KeyBind(InputType.Up).IsDown())
                        {
                            moveInput.Y += 1.0f;
                        }
                    }

                    velocity = Vector2.Lerp(velocity, moveInput, deltaTime * 10.0f);
                    moveCam  = velocity * moveSpeed * deltaTime * FreeCamMoveSpeed * 60.0f;

                    if (Screen.Selected == GameMain.GameScreen && (followSub ?? FollowSub))
                    {
                        var closestSub = Submarine.FindClosest(WorldViewCenter);
                        if (closestSub != null)
                        {
                            moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(closestSub.Velocity * deltaTime);
                        }
                    }
                }

                if (allowZoom)
                {
                    Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
                    Vector2 diffViewCenter;
                    diffViewCenter = (mouseInWorld - Position) * Zoom;
                    targetZoom     = MathHelper.Clamp(
                        targetZoom + PlayerInput.ScrollWheelSpeed / 1000.0f * zoom,
                        GameMain.DebugDraw ? MinZoom * 0.1f : MinZoom,
                        MaxZoom);

                    if (PlayerInput.KeyDown(Keys.LeftControl))
                    {
                        Zoom += (targetZoom - zoom) / (ZoomSmoothness * 10.0f);
                    }
                    else
                    {
                        Zoom = MathHelper.Lerp(Zoom, targetZoom, deltaTime * 10.0f);
                    }
                    if (!PlayerInput.KeyDown(Keys.F))
                    {
                        Position = mouseInWorld - (diffViewCenter / Zoom);
                    }
                }
            }
            else if (allowMove)
            {
                Vector2 mousePos = PlayerInput.MousePosition;
                Vector2 offset   = mousePos - Resolution.ToVector2() / 2;
                offset.X = offset.X / (Resolution.X * 0.4f);
                offset.Y = -offset.Y / (Resolution.Y * 0.3f);
                if (offset.LengthSquared() > 1.0f)
                {
                    offset.Normalize();
                }
                float offsetUnscaledLen = offset.Length();
                offset *= OffsetAmount;
                // Freeze the camera movement by default, when the cursor is on top of an ui element.
                // Setting a positive value to the OffsetAmount, will override this behaviour.
                if (GUI.MouseOn != null && OffsetAmount > 0)
                {
                    Freeze = true;
                }
                if (CharacterHealth.OpenHealthWindow != null || CrewManager.IsCommandInterfaceOpen || ConversationAction.IsDialogOpen)
                {
                    offset *= 0;
                    Freeze  = false;
                }
                if (Freeze)
                {
                    if (offset.LengthSquared() > 0.001f)
                    {
                        offset = previousOffset;
                    }
                }
                else
                {
                    previousOffset = offset;
                }

                if (allowZoom)
                {
                    //how much to zoom out (zoom completely out when offset is 1000)
                    float zoomOutAmount = GetZoomAmount(offset);
                    //scaled zoom amount
                    float scaledZoom = MathHelper.Lerp(DefaultZoom, MinZoom, zoomOutAmount) * globalZoomScale;
                    //zoom in further if zoomOutAmount is low and resolution is lower than reference
                    float newZoom = scaledZoom * (MathHelper.Lerp(0.3f * (1f - Math.Min(globalZoomScale, 1f)), 0f,
                                                                  (GameMain.Config == null || GameMain.Config.EnableMouseLook) ? (float)Math.Sqrt(offsetUnscaledLen) : 0.3f) + 1f);

                    Zoom += (newZoom - zoom) / ZoomSmoothness;
                }

                //force targetzoom to the current zoom value, so the camera stays at the same zoom when switching to freecam
                targetZoom = Zoom;

                Vector2 diff = (TargetPos + offset) - position;

                moveCam = diff / MoveSmoothness;
            }
            rotation        += angularVelocity * deltaTime;
            angularVelocity *= (1.0f - angularDamping);
            angularVelocity += -rotation * angularSpring;

            angularDamping = 0.05f;
            angularSpring  = 0.2f;

            if (Shake < 0.01f)
            {
                shakePosition = Vector2.Zero;
                shakeTimer    = 0.0f;
            }
            else
            {
                shakeTimer += deltaTime * 5.0f;
                Vector2 noisePos = new Vector2((float)PerlinNoise.CalculatePerlin(shakeTimer, shakeTimer, 0) - 0.5f, (float)PerlinNoise.CalculatePerlin(shakeTimer, shakeTimer, 0.5f) - 0.5f);

                shakePosition = noisePos * Shake * 2.0f;
                Shake         = MathHelper.Lerp(Shake, 0.0f, deltaTime * 2.0f);
            }

            Translate(moveCam + shakePosition);
            Freeze = false;
        }