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); if (lClick) { foreach (MapEntity entity in mapEntityList) { if (entity == this || !entity.IsHighlighted) { continue; } if (!entity.IsMouseOn(position)) { continue; } if (entity.Linkable && entity.linkedTo != null) { entity.linkedTo.Add(this); linkedTo.Add(entity); } } } else { foreach (MapEntity entity in mapEntityList) { if (entity == this || !entity.IsHighlighted) { continue; } if (!entity.IsMouseOn(position)) { continue; } if (entity.linkedTo != null && entity.linkedTo.Contains(this)) { entity.linkedTo.Remove(this); linkedTo.Remove(entity); } } } }
protected override void Update(float deltaTime) { base.Update(deltaTime); if (ClickableAreas.Any() && (GUI.MouseOn?.IsParentOf(this) ?? true)) { if (!Rect.Contains(PlayerInput.MousePosition)) { return; } int index = GetCaretIndexFromScreenPos(PlayerInput.MousePosition); foreach (ClickableArea clickableArea in ClickableAreas) { if (clickableArea.Data.StartIndex <= index && index <= clickableArea.Data.EndIndex) { GUI.MouseCursor = CursorState.Hand; if (PlayerInput.PrimaryMouseButtonClicked()) { clickableArea.OnClick?.Invoke(this, clickableArea); } break; } } } }
protected override void Update(float deltaTime) { if (!Visible) { return; } base.Update(deltaTime); if (Rect.Contains(PlayerInput.MousePosition) && CanBeSelected && CanBeFocused && Enabled && GUI.IsMouseOn(this)) { State = Selected ? ComponentState.HoverSelected : ComponentState.Hover; if (PlayerInput.PrimaryMouseButtonDown()) { OnButtonDown?.Invoke(); } if (PlayerInput.PrimaryMouseButtonHeld()) { if (OnPressed != null) { if (OnPressed()) { State = ComponentState.Pressed; } } else { State = ComponentState.Pressed; } } else if (PlayerInput.PrimaryMouseButtonClicked()) { GUI.PlayUISound(GUISoundType.Click); if (OnClicked != null) { if (OnClicked(this, UserData)) { State = ComponentState.Selected; } } else { Selected = !Selected; } } } else { State = Selected ? ComponentState.Selected : ComponentState.None; } foreach (GUIComponent child in Children) { child.State = State; } }
private void DrawLanguageSelectionPrompt(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice) { if (languageSelectionFont == null) { languageSelectionFont = new ScalableFont("Content/Fonts/NotoSans/NotoSans-Bold.ttf", (uint)(30 * (GameMain.GraphicsHeight / 1080.0f)), graphicsDevice); } if (languageSelectionFontCJK == null) { languageSelectionFontCJK = new ScalableFont("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf", (uint)(30 * (GameMain.GraphicsHeight / 1080.0f)), graphicsDevice, dynamicLoading: true); } if (languageSelectionCursor == null) { languageSelectionCursor = new Sprite("Content/UI/cursor.png", Vector2.Zero); } Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight * 0.3f); Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / TextManager.AvailableLanguages.Count()); foreach (string language in TextManager.AvailableLanguages) { string localizedLanguageName = TextManager.GetTranslatedLanguageName(language); var font = TextManager.IsCJK(localizedLanguageName) ? languageSelectionFontCJK : languageSelectionFont; Vector2 textSize = font.MeasureString(localizedLanguageName); bool hover = Math.Abs(PlayerInput.MousePosition.X - textPos.X) < textSize.X / 2 && Math.Abs(PlayerInput.MousePosition.Y - textPos.Y) < textSpacing.Y / 2; font.DrawString(spriteBatch, localizedLanguageName, textPos - textSize / 2, hover ? Color.White : Color.White * 0.6f); if (hover && PlayerInput.PrimaryMouseButtonClicked()) { GameMain.Config.Language = language; //reload tip in the selected language selectedTip = TextManager.Get("LoadingScreenTip", true); GameMain.Config.SetDefaultBindings(legacy: false); GameMain.Config.CheckBindings(useDefaults: true); WaitForLanguageSelection = false; languageSelectionFont?.Dispose(); languageSelectionFont = null; languageSelectionFontCJK?.Dispose(); languageSelectionFontCJK = null; break; } textPos += textSpacing; } languageSelectionCursor.Draw(spriteBatch, PlayerInput.LatestMousePosition, scale: 0.5f); }
public virtual void Update(float deltaTime) { PreUpdate?.Invoke(deltaTime); if (!enabled) { return; } if (IsMouseOver || (!RequireMouseOn && selectedWidgets.Contains(this) && PlayerInput.PrimaryMouseButtonHeld())) { Hovered?.Invoke(); System.Diagnostics.Debug.WriteLine("hovered"); if (RequireMouseOn || PlayerInput.PrimaryMouseButtonDown()) { if ((multiselect && !selectedWidgets.Contains(this)) || selectedWidgets.None()) { selectedWidgets.Add(this); Selected?.Invoke(); } } } else if (selectedWidgets.Contains(this)) { System.Diagnostics.Debug.WriteLine("selectedWidgets.Contains(this) -> remove"); selectedWidgets.Remove(this); Deselected?.Invoke(); } if (IsSelected) { if (PlayerInput.PrimaryMouseButtonDown()) { MouseDown?.Invoke(); } if (PlayerInput.PrimaryMouseButtonHeld()) { MouseHeld?.Invoke(deltaTime); } if (PlayerInput.PrimaryMouseButtonClicked()) { MouseUp?.Invoke(); } } PostUpdate?.Invoke(deltaTime); }
protected override void Update(float deltaTime) { if (!Visible) { return; } base.Update(deltaTime); if (GUI.MouseOn == this && Enabled) { State = Selected ? ComponentState.HoverSelected : ComponentState.Hover; if (PlayerInput.PrimaryMouseButtonHeld()) { State = ComponentState.Selected; } if (PlayerInput.PrimaryMouseButtonClicked()) { if (radioButtonGroup == null) { Selected = !Selected; } else if (!selected) { Selected = true; } } } else if (selected) { State = ComponentState.Selected; } else { State = ComponentState.None; } }
protected override void Update(float deltaTime) { if (!Visible) { return; } wasOpened = false; base.Update(deltaTime); if (Dropped && PlayerInput.PrimaryMouseButtonClicked()) { Rectangle listBoxRect = listBox.Rect; if (!listBoxRect.Contains(PlayerInput.MousePosition) && !button.Rect.Contains(PlayerInput.MousePosition)) { Dropped = false; if (GUI.KeyboardDispatcher.Subscriber == this) { GUI.KeyboardDispatcher.Subscriber = null; } } } }
public bool IsHit() { switch (MouseButton) { case MouseButton.None: return(PlayerInput.KeyHit(Key)); case MouseButton.PrimaryMouse: return(PlayerInput.PrimaryMouseButtonClicked()); case MouseButton.SecondaryMouse: return(PlayerInput.SecondaryMouseButtonClicked()); case MouseButton.LeftMouse: return(PlayerInput.LeftButtonClicked()); case MouseButton.RightMouse: return(PlayerInput.RightButtonClicked()); case MouseButton.MiddleMouse: return(PlayerInput.MidButtonClicked()); case MouseButton.MouseButton4: return(PlayerInput.Mouse4ButtonClicked()); case MouseButton.MouseButton5: return(PlayerInput.Mouse5ButtonClicked()); case MouseButton.MouseWheelUp: return(PlayerInput.MouseWheelUpClicked()); case MouseButton.MouseWheelDown: return(PlayerInput.MouseWheelDownClicked()); } return(false); }
public override void UpdateEditing(Camera cam) { if (editingHUD == null || editingHUD.UserData as LinkedSubmarine != this) { editingHUD = CreateEditingHUD(); } editingHUD.UpdateManually((float)Timing.Step); if (!PlayerInput.PrimaryMouseButtonClicked() || !PlayerInput.KeyDown(Keys.Space)) { return; } Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); foreach (MapEntity entity in mapEntityList) { if (entity == this || !entity.IsHighlighted || !(entity is Item) || !entity.IsMouseOn(position)) { continue; } if (((Item)entity).GetComponent <DockingPort>() == null) { continue; } if (linkedTo.Contains(entity)) { linkedTo.Remove(entity); } else { linkedTo.Add(entity); } } }
public void Draw(SpriteBatch spriteBatch, GUICustomComponent mapContainer) { Rectangle rect = mapContainer.Rect; Vector2 viewSize = new Vector2(rect.Width / zoom, rect.Height / zoom); float edgeBuffer = size * (BackgroundScale - 1.0f) / 2; drawOffset.X = MathHelper.Clamp(drawOffset.X, -size - edgeBuffer + viewSize.X / 2.0f, edgeBuffer - viewSize.X / 2.0f); drawOffset.Y = MathHelper.Clamp(drawOffset.Y, -size - edgeBuffer + viewSize.Y / 2.0f, edgeBuffer - viewSize.Y / 2.0f); drawOffsetNoise = new Vector2( (float)PerlinNoise.CalculatePerlin(Timing.TotalTime * 0.1f % 255, Timing.TotalTime * 0.1f % 255, 0) - 0.5f, (float)PerlinNoise.CalculatePerlin(Timing.TotalTime * 0.2f % 255, Timing.TotalTime * 0.2f % 255, 0.5f) - 0.5f) * 10.0f; Vector2 viewOffset = drawOffset + drawOffsetNoise; Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y) + CenterOffset; Rectangle prevScissorRect = GameMain.Instance.GraphicsDevice.ScissorRectangle; spriteBatch.End(); spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, rect); spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable); for (int x = 0; x < mapTiles.GetLength(0); x++) { for (int y = 0; y < mapTiles.GetLength(1); y++) { Vector2 mapPos = new Vector2( x * generationParams.TileSpriteSpacing.X + ((y % 2 == 0) ? 0.0f : generationParams.TileSpriteSpacing.X * 0.5f), y * generationParams.TileSpriteSpacing.Y); mapPos.X -= size / 2 * (BackgroundScale - 1.0f); mapPos.Y -= size / 2 * (BackgroundScale - 1.0f); Vector2 scale = new Vector2( generationParams.TileSpriteSize.X / mapTiles[x, y].Sprite.size.X, generationParams.TileSpriteSize.Y / mapTiles[x, y].Sprite.size.Y); mapTiles[x, y].Sprite.Draw(spriteBatch, rectCenter + (mapPos + viewOffset) * zoom, Color.White, origin: new Vector2(256.0f, 256.0f), rotate: 0, scale: scale * zoom, spriteEffect: mapTiles[x, y].SpriteEffect); } } #if DEBUG if (generationParams.ShowNoiseMap) { GUI.DrawRectangle(spriteBatch, rectCenter + (borders.Location.ToVector2() + viewOffset) * zoom, borders.Size.ToVector2() * zoom, Color.White, true); } #endif Vector2 topLeft = rectCenter + viewOffset * zoom; topLeft.X = (int)topLeft.X; topLeft.Y = (int)topLeft.Y; Vector2 bottomRight = rectCenter + (viewOffset + new Vector2(size, size)) * zoom; bottomRight.X = (int)bottomRight.X; bottomRight.Y = (int)bottomRight.Y; spriteBatch.Draw(noiseTexture, destinationRectangle: new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)(bottomRight.X - topLeft.X), (int)(bottomRight.Y - topLeft.Y)), sourceRectangle: null, color: Color.White); if (topLeft.X > rect.X) { GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Y, (int)(topLeft.X - rect.X), rect.Height), Color.Black * 0.8f, true); } if (topLeft.Y > rect.Y) { GUI.DrawRectangle(spriteBatch, new Rectangle((int)topLeft.X, rect.Y, (int)(bottomRight.X - topLeft.X), (int)(topLeft.Y - rect.Y)), Color.Black * 0.8f, true); } if (bottomRight.X < rect.Right) { GUI.DrawRectangle(spriteBatch, new Rectangle((int)bottomRight.X, rect.Y, (int)(rect.Right - bottomRight.X), rect.Height), Color.Black * 0.8f, true); } if (bottomRight.Y < rect.Bottom) { GUI.DrawRectangle(spriteBatch, new Rectangle((int)topLeft.X, (int)bottomRight.Y, (int)(bottomRight.X - topLeft.X), (int)(rect.Bottom - bottomRight.Y)), Color.Black * 0.8f, true); } var sourceRect = rect; float rawNoiseScale = 1.0f + Noise[(int)(Timing.TotalTime * 100 % Noise.GetLength(0) - 1), (int)(Timing.TotalTime * 100 % Noise.GetLength(1) - 1)]; cameraNoiseStrength = Noise[(int)(Timing.TotalTime * 10 % Noise.GetLength(0) - 1), (int)(Timing.TotalTime * 10 % Noise.GetLength(1) - 1)]; rawNoiseSprite.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(), startOffset: new Point(Rand.Range(0, rawNoiseSprite.SourceRect.Width), Rand.Range(0, rawNoiseSprite.SourceRect.Height)), color: Color.White * cameraNoiseStrength * 0.5f, textureScale: Vector2.One * rawNoiseScale); rawNoiseSprite.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(), startOffset: new Point(Rand.Range(0, rawNoiseSprite.SourceRect.Width), Rand.Range(0, rawNoiseSprite.SourceRect.Height)), color: new Color(20, 20, 20, 100), textureScale: Vector2.One * rawNoiseScale * 2); if (generationParams.ShowLocations) { foreach (LocationConnection connection in connections) { Color connectionColor; if (GameMain.DebugDraw) { float sizeFactor = MathUtils.InverseLerp( MapGenerationParams.Instance.SmallLevelConnectionLength, MapGenerationParams.Instance.LargeLevelConnectionLength, connection.Length); connectionColor = ToolBox.GradientLerp(sizeFactor, Color.LightGreen, GUI.Style.Orange, GUI.Style.Red); } else { connectionColor = ToolBox.GradientLerp(connection.Difficulty / 100.0f, MapGenerationParams.Instance.LowDifficultyColor, MapGenerationParams.Instance.MediumDifficultyColor, MapGenerationParams.Instance.HighDifficultyColor); } int width = (int)(3 * zoom); if (SelectedLocation != CurrentLocation && (connection.Locations.Contains(SelectedLocation) && connection.Locations.Contains(CurrentLocation))) { connectionColor = Color.Gold; width *= 2; } else if (highlightedLocation != CurrentLocation && (connection.Locations.Contains(highlightedLocation) && connection.Locations.Contains(CurrentLocation))) { connectionColor = Color.Lerp(connectionColor, Color.White, 0.5f); width *= 2; } else if (!connection.Passed) { //crackColor *= 0.5f; } for (int i = 0; i < connection.CrackSegments.Count; i++) { var segment = connection.CrackSegments[i]; Vector2 start = rectCenter + (segment[0] + viewOffset) * zoom; Vector2 end = rectCenter + (segment[1] + viewOffset) * zoom; if (!rect.Contains(start) && !rect.Contains(end)) { continue; } else { if (MathUtils.GetLineRectangleIntersection(start, end, new Rectangle(rect.X, rect.Y + rect.Height, rect.Width, rect.Height), out Vector2 intersection)) { if (!rect.Contains(start)) { start = intersection; } else { end = intersection; } } } float distFromPlayer = Vector2.Distance(CurrentLocation.MapPosition, (segment[0] + segment[1]) / 2.0f); float dist = Vector2.Distance(start, end); float a = GameMain.DebugDraw ? 1.0f : (200.0f - distFromPlayer) / 200.0f; spriteBatch.Draw(generationParams.ConnectionSprite.Texture, new Rectangle((int)start.X, (int)start.Y, (int)(dist - 1 * zoom), width), null, connectionColor * MathHelper.Clamp(a, 0.1f, 0.5f), MathUtils.VectorToAngle(end - start), new Vector2(0, 16), SpriteEffects.None, 0.01f); } if (GameMain.DebugDraw && zoom > 1.0f && generationParams.ShowLevelTypeNames) { Vector2 center = rectCenter + (connection.CenterPos + viewOffset) * zoom; if (rect.Contains(center)) { GUI.DrawString(spriteBatch, center, connection.Biome.Identifier + " (" + connection.Difficulty + ")", Color.White); } } } rect.Inflate(8, 8); GUI.DrawRectangle(spriteBatch, rect, Color.Black, false, 0.0f, 8); GUI.DrawRectangle(spriteBatch, rect, Color.LightGray); for (int i = 0; i < Locations.Count; i++) { Location location = Locations[i]; Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom; Rectangle drawRect = location.Type.Sprite.SourceRect; drawRect.X = (int)pos.X - drawRect.Width / 2; drawRect.Y = (int)pos.Y - drawRect.Width / 2; if (!rect.Intersects(drawRect)) { continue; } Color color = location.Type.SpriteColor; if (location.Connections.Find(c => c.Locations.Contains(CurrentLocation)) == null) { color *= 0.5f; } float iconScale = location == CurrentLocation ? 1.2f : 1.0f; if (location == highlightedLocation) { iconScale *= 1.1f; color = Color.Lerp(color, Color.White, 0.5f); } float distFromPlayer = Vector2.Distance(CurrentLocation.MapPosition, location.MapPosition); color *= MathHelper.Clamp((1000.0f - distFromPlayer) / 500.0f, 0.1f, 1.0f); location.Type.Sprite.Draw(spriteBatch, pos, color, scale: MapGenerationParams.Instance.LocationIconSize / location.Type.Sprite.size.X * iconScale * zoom); MapGenerationParams.Instance.LocationIndicator.Draw(spriteBatch, pos, color, scale: MapGenerationParams.Instance.LocationIconSize / MapGenerationParams.Instance.LocationIndicator.size.X * iconScale * zoom * 1.4f); } //PLACEHOLDER until the stuff at the center of the map is implemented float centerIconSize = 50.0f; Vector2 centerPos = rectCenter + (new Vector2(size / 2) + viewOffset) * zoom; bool mouseOn = Vector2.Distance(PlayerInput.MousePosition, centerPos) < centerIconSize * zoom; var centerLocationType = LocationType.List.Last(); Color centerColor = centerLocationType.SpriteColor * (mouseOn ? 1.0f : 0.6f); centerLocationType.Sprite.Draw(spriteBatch, centerPos, centerColor, scale: centerIconSize / centerLocationType.Sprite.size.X * zoom); MapGenerationParams.Instance.LocationIndicator.Draw(spriteBatch, centerPos, centerColor, scale: centerIconSize / MapGenerationParams.Instance.LocationIndicator.size.X * zoom * 1.2f); if (mouseOn && PlayerInput.PrimaryMouseButtonClicked() && !messageBoxOpen) { if (TextManager.ContainsTag("centerarealockedheader") && TextManager.ContainsTag("centerarealockedtext")) { var messageBox = new GUIMessageBox( TextManager.Get("centerarealockedheader"), TextManager.Get("centerarealockedtext")); messageBoxOpen = true; CoroutineManager.StartCoroutine(WaitForMessageBoxClosed(messageBox)); } else { //if the message cannot be shown in the selected language, //show the campaign roadmap (which mentions the center location not being reachable) var messageBox = new GUIMessageBox(TextManager.Get("CampaignRoadMapTitle"), TextManager.Get("CampaignRoadMapText")); messageBoxOpen = true; CoroutineManager.StartCoroutine(WaitForMessageBoxClosed(messageBox)); } } } DrawDecorativeHUD(spriteBatch, rect); for (int i = 0; i < 2; i++) { Location location = (i == 0) ? highlightedLocation : CurrentLocation; if (location == null) { continue; } Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom; pos.X += 25 * zoom; pos.Y -= 5 * zoom; Vector2 size = GUI.LargeFont.MeasureString(location.Name); GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw( spriteBatch, new Rectangle((int)pos.X - 30, (int)(pos.Y - 10), (int)size.X + 60, (int)(size.Y + 50 * GUI.Scale)), Color.Black * hudOpenState * 0.7f); GUI.DrawString(spriteBatch, pos, location.Name, Color.White * hudOpenState * 1.5f, font: GUI.LargeFont); GUI.DrawString(spriteBatch, pos + Vector2.UnitY * size.Y * 0.8f, location.Type.Name, Color.White * hudOpenState * 1.5f); } spriteBatch.End(); GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect; spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable); }
public static void Update(float deltaTime, Character character, Camera cam) { if (GUI.DisableHUD) { if (character.Inventory != null && !LockInventory(character)) { character.Inventory.UpdateSlotInput(); } return; } if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen) { if (character.Info != null && !character.ShouldLockHud() && character.SelectedCharacter == null) { bool mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && GUI.MouseOn == null; if (mouseOnPortrait && PlayerInput.PrimaryMouseButtonClicked()) { CharacterHealth.OpenHealthWindow = character.CharacterHealth; } } if (character.Inventory != null) { if (!LockInventory(character)) { character.Inventory.Update(deltaTime, cam); } 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.UpdateHUD(character, deltaTime, cam); } } } } if (character.IsHumanoid && character.SelectedCharacter != null && character.SelectedCharacter.Inventory != null) { if (character.SelectedCharacter.CanInventoryBeAccessed) { character.SelectedCharacter.Inventory.Update(deltaTime, cam); } character.SelectedCharacter.CharacterHealth.UpdateHUD(deltaTime); } Inventory.UpdateDragging(); } if (focusedItem != null) { if (character.FocusedItem != null) { focusedItemOverlayTimer = Math.Min(focusedItemOverlayTimer + deltaTime, ItemOverlayDelay + 1.0f); } else { focusedItemOverlayTimer = Math.Max(focusedItemOverlayTimer - deltaTime, 0.0f); if (focusedItemOverlayTimer <= 0.0f) { focusedItem = null; shouldRecreateHudTexts = true; } } } if (brokenItemsCheckTimer > 0.0f) { brokenItemsCheckTimer -= deltaTime; } else { brokenItems.Clear(); brokenItemsCheckTimer = 1.0f; foreach (Item item in Item.ItemList) { if (item.Submarine == null || item.Submarine.TeamID != character.TeamID || item.Submarine.Info.IsWreck) { continue; } if (!item.Repairables.Any(r => item.ConditionPercentage <= r.RepairIconThreshold)) { continue; } if (Submarine.VisibleEntities != null && !Submarine.VisibleEntities.Contains(item)) { continue; } Vector2 diff = item.WorldPosition - character.WorldPosition; if (Submarine.CheckVisibility(character.SimPosition, character.SimPosition + ConvertUnits.ToSimUnits(diff)) == null) { brokenItems.Add(item); } } } }
public override void UpdatePlacing(Camera cam) { Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (PlayerInput.SecondaryMouseButtonClicked()) { selected = null; return; } var potentialContainer = MapEntity.GetPotentialContainer(position); if (!ResizeHorizontal && !ResizeVertical) { if (PlayerInput.PrimaryMouseButtonClicked()) { var item = new Item(new Rectangle((int)position.X, (int)position.Y, (int)(sprite.size.X * Scale), (int)(sprite.size.Y * Scale)), this, Submarine.MainSub) { Submarine = Submarine.MainSub }; item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f); item.FindHull(); item.Submarine = Submarine.MainSub; if (PlayerInput.IsShiftDown()) { if (potentialContainer?.OwnInventory?.TryPutItem(item, Character.Controlled) ?? false) { SoundPlayer.PlayUISound(GUISoundType.PickItem); } } SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List <MapEntity> { item }, false)); placePosition = Vector2.Zero; return; } } else { Vector2 placeSize = size * Scale; if (placePosition == Vector2.Zero) { if (PlayerInput.PrimaryMouseButtonHeld()) { placePosition = position; } } else { if (ResizeHorizontal) { placeSize.X = Math.Max(position.X - placePosition.X, size.X); } if (ResizeVertical) { placeSize.Y = Math.Max(placePosition.Y - position.Y, size.Y); } if (PlayerInput.PrimaryMouseButtonReleased()) { var item = new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.MainSub); placePosition = Vector2.Zero; item.Submarine = Submarine.MainSub; item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f); item.FindHull(); //selected = null; return; } position = placePosition; } } if (potentialContainer != null) { potentialContainer.IsHighlighted = true; } //if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null; }
/// <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(); }
private IEnumerable <object> DoInitialCameraTransition() { while (GameMain.Instance.LoadingScreenOpen) { yield return(CoroutineStatus.Running); } Character prevControlled = Character.Controlled; if (prevControlled?.AIController != null) { prevControlled.AIController.Enabled = false; } Character.Controlled = null; if (prevControlled != null) { prevControlled.ClearInputs(); } GUI.DisableHUD = true; while (GameMain.Instance.LoadingScreenOpen) { yield return(CoroutineStatus.Running); } if (IsFirstRound || showCampaignResetText) { overlayColor = Color.LightGray; overlaySprite = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId); overlayTextColor = Color.Transparent; overlayText = TextManager.GetWithVariables(showCampaignResetText ? "campaignend4" : "campaignstart", new string[] { "xxxx", "yyyy" }, new string[] { Map.CurrentLocation.Name, TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass) }); string pressAnyKeyText = TextManager.Get("pressanykey"); float fadeInDuration = 2.0f; float textDuration = 10.0f; float timer = 0.0f; while (true) { if (timer > fadeInDuration) { overlayTextBottom = pressAnyKeyText; if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) { break; } } overlayTextColor = Color.Lerp(Color.Transparent, Color.White, (timer - 1.0f) / fadeInDuration); timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration); yield return(CoroutineStatus.Running); } var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam, null, null, fadeOut: false, duration: 5, startZoom: 1.5f, endZoom: 1.0f) { AllowInterrupt = true, RemoveControlFromCharacter = false }; fadeInDuration = 1.0f; timer = 0.0f; overlayTextColor = Color.Transparent; overlayText = ""; while (timer < fadeInDuration) { overlayColor = Color.Lerp(Color.LightGray, Color.Transparent, timer / fadeInDuration); timer += CoroutineManager.DeltaTime; yield return(CoroutineStatus.Running); } overlayColor = Color.Transparent; while (transition.Running) { yield return(CoroutineStatus.Running); } showCampaignResetText = false; } else { ISpatialEntity transitionTarget; if (prevControlled != null) { transitionTarget = prevControlled; } else { transitionTarget = Submarine.MainSub; } var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam, null, null, fadeOut: false, duration: 5, startZoom: 0.5f, endZoom: 1.0f) { AllowInterrupt = true, RemoveControlFromCharacter = false }; while (transition.Running) { yield return(CoroutineStatus.Running); } } if (prevControlled != null) { prevControlled.SelectedConstruction = null; if (prevControlled.AIController != null) { prevControlled.AIController.Enabled = true; } } if (prevControlled != null) { Character.Controlled = prevControlled; } GUI.DisableHUD = false; yield return(CoroutineStatus.Success); }
partial void UpdateProjSpecific(float deltaTime, Camera cam) { serverUpdateDelay -= deltaTime; if (serverUpdateDelay <= 0.0f) { ApplyRemoteState(); } if (networkUpdatePending) { networkUpdateTimer += deltaTime; if (networkUpdateTimer > 0.2f) { if (!pendingSectionUpdates.Any() && !pendingDecalUpdates.Any()) { GameMain.NetworkMember?.CreateEntityEvent(this); } foreach (Decal decal in pendingDecalUpdates) { GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { decal }); } foreach (int pendingSectionUpdate in pendingSectionUpdates) { GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { pendingSectionUpdate }); } pendingSectionUpdates.Clear(); networkUpdatePending = false; networkUpdateTimer = 0.0f; } } if (!IdFreed) { if (EditWater) { Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); if (Submarine.RectContains(WorldRect, position)) { if (PlayerInput.PrimaryMouseButtonHeld()) { WaterVolume += 1500.0f; networkUpdatePending = true; serverUpdateDelay = 0.5f; } else if (PlayerInput.SecondaryMouseButtonHeld()) { WaterVolume -= 1500.0f; networkUpdatePending = true; serverUpdateDelay = 0.5f; } } } else if (EditFire) { Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); if (Submarine.RectContains(WorldRect, position)) { if (PlayerInput.PrimaryMouseButtonClicked()) { new FireSource(position, this, isNetworkMessage: true); networkUpdatePending = true; serverUpdateDelay = 0.5f; } } } } if (waterVolume < 1.0f) { return; } for (int i = 1; i < waveY.Length - 1; i++) { float maxDelta = Math.Max(Math.Abs(rightDelta[i]), Math.Abs(leftDelta[i])); if (maxDelta > 1.0f && maxDelta > Rand.Range(1.0f, 10.0f)) { var particlePos = new Vector2(rect.X + WaveWidth * i, surface + waveY[i]); if (Submarine != null) { particlePos += Submarine.Position; } GameMain.ParticleManager.CreateParticle("mist", particlePos, new Vector2(0.0f, -50.0f), 0.0f, this); } } }
private void UpdateChildrenRect() { //dragging if (CanDragElements && draggedElement != null) { if (!PlayerInput.PrimaryMouseButtonHeld()) { OnRearranged?.Invoke(this, draggedElement.UserData); draggedElement = null; RepositionChildren(); } else { draggedElement.RectTransform.AbsoluteOffset = isHorizontal ? draggedReferenceOffset + new Point((int)PlayerInput.MousePosition.X - draggedReferenceRectangle.Center.X, 0) : draggedReferenceOffset + new Point(0, (int)PlayerInput.MousePosition.Y - draggedReferenceRectangle.Center.Y); int index = Content.RectTransform.GetChildIndex(draggedElement.RectTransform); int currIndex = index; if (isHorizontal) { while (currIndex > 0 && PlayerInput.MousePosition.X < draggedReferenceRectangle.Left) { currIndex--; draggedReferenceRectangle.X -= draggedReferenceRectangle.Width; draggedReferenceOffset.X -= draggedReferenceRectangle.Width; } while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.X > draggedReferenceRectangle.Right) { currIndex++; draggedReferenceRectangle.X += draggedReferenceRectangle.Width; draggedReferenceOffset.X += draggedReferenceRectangle.Width; } } else { while (currIndex > 0 && PlayerInput.MousePosition.Y < draggedReferenceRectangle.Top) { currIndex--; draggedReferenceRectangle.Y -= draggedReferenceRectangle.Height; draggedReferenceOffset.Y -= draggedReferenceRectangle.Height; } while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.Y > draggedReferenceRectangle.Bottom) { currIndex++; draggedReferenceRectangle.Y += draggedReferenceRectangle.Height; draggedReferenceOffset.Y += draggedReferenceRectangle.Height; } } if (currIndex != index) { draggedElement.RectTransform.RepositionChildInHierarchy(currIndex); } return; } } if (SelectTop) { foreach (GUIComponent child in Content.Children) { child.CanBeFocused = !selected.Contains(child); if (!child.CanBeFocused) { child.State = ComponentState.None; } } } if (SelectTop && Content.Children.Any() && scrollToElement == null) { GUIComponent component = Content.Children.FirstOrDefault(c => (c.Rect.Y - Content.Rect.Y) / (float)c.Rect.Height > -0.1f); if (component != null && !selected.Contains(component)) { int index = Content.Children.ToList().IndexOf(component); if (index >= 0) { Select(index, false, false, takeKeyBoardFocus: true); } } } for (int i = 0; i < Content.CountChildren; i++) { var child = Content.RectTransform.GetChild(i)?.GUIComponent; if (child == null || !child.Visible) { continue; } // selecting if (Enabled && CanBeFocused && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child)) { child.State = ComponentState.Hover; var mouseDown = useMouseDownToSelect ? PlayerInput.PrimaryMouseButtonDown() : PlayerInput.PrimaryMouseButtonClicked(); if (mouseDown) { if (SelectTop) { ScrollToElement(child); Select(i, autoScroll: false, takeKeyBoardFocus: true); } else { Select(i, autoScroll: false, takeKeyBoardFocus: true); } } if (CanDragElements && PlayerInput.PrimaryMouseButtonDown() && GUI.MouseOn == child) { draggedElement = child; draggedReferenceRectangle = child.Rect; draggedReferenceOffset = child.RectTransform.AbsoluteOffset; } } else if (selected.Contains(child)) { child.State = ComponentState.Selected; if (CheckSelected != null) { if (CheckSelected() != child.UserData) { selected.Remove(child); } } } else { child.State = !child.ExternalHighlight ? ComponentState.None : ComponentState.Hover; } } }
protected override void Update(float deltaTime) { if (!Visible) { return; } if (!enabled) { return; } Frame.State = GUI.MouseOn == Frame ? ComponentState.Hover : ComponentState.None; if (Frame.State == ComponentState.Hover && PlayerInput.PrimaryMouseButtonHeld()) { Frame.State = ComponentState.Pressed; } if (IsBooleanSwitch && (!PlayerInput.PrimaryMouseButtonHeld() || (GUI.MouseOn != this && !IsParentOf(GUI.MouseOn)))) { int dir = Math.Sign(barScroll - (minValue + maxValue) / 2.0f); if (dir == 0) { dir = 1; } if ((barScroll <= maxValue && dir > 0) || (barScroll > minValue && dir < 0)) { BarScroll += dir * 0.1f; } } if (DraggingBar == this) { GUI.ForceMouseOn(this); if (dragStartPos == null) { dragStartPos = PlayerInput.MousePosition; } if (!PlayerInput.PrimaryMouseButtonHeld()) { if (IsBooleanSwitch && GUI.MouseOn == Bar && Vector2.Distance(dragStartPos.Value, PlayerInput.MousePosition) < 5) { BarScroll = BarScroll > 0.5f ? 0.0f : 1.0f; OnMoved?.Invoke(this, BarScroll); } OnReleased?.Invoke(this, BarScroll); DraggingBar = null; dragStartPos = null; } if ((isHorizontal && PlayerInput.MousePosition.X > Rect.X && PlayerInput.MousePosition.X < Rect.Right) || (!isHorizontal && PlayerInput.MousePosition.Y > Rect.Y && PlayerInput.MousePosition.Y < Rect.Bottom)) { MoveButton(PlayerInput.MouseSpeed); } } else if (GUI.MouseOn == Frame) { if (PlayerInput.PrimaryMouseButtonClicked()) { DraggingBar?.OnReleased?.Invoke(DraggingBar, DraggingBar.BarScroll); if (IsBooleanSwitch) { MoveButton(new Vector2( Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Rect.Width, Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Rect.Height)); } else { MoveButton(new Vector2( Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width, Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height)); } } } }
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; CurrentLocation.CreateStore(); OnLocationChanged?.Invoke(prevLocation, CurrentLocation); SelectLocation(-1); if (GameMain.Client == null) { 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); } } } }
private IEnumerable <object> DoInitialCameraTransition() { while (GameMain.Instance.LoadingScreenOpen) { yield return(CoroutineStatus.Running); } Character prevControlled = Character.Controlled; if (prevControlled?.AIController != null) { prevControlled.AIController.Enabled = false; } Character.Controlled = null; prevControlled?.ClearInputs(); GUI.DisableHUD = true; while (GameMain.Instance.LoadingScreenOpen) { yield return(CoroutineStatus.Running); } if (IsFirstRound || showCampaignResetText) { overlayColor = Color.LightGray; overlaySprite = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId); overlayTextColor = Color.Transparent; overlayText = TextManager.GetWithVariables(showCampaignResetText ? "campaignend4" : "campaignstart", new string[] { "xxxx", "yyyy" }, new string[] { Map.CurrentLocation.Name, TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass) }); string pressAnyKeyText = TextManager.Get("pressanykey"); float fadeInDuration = 2.0f; float textDuration = 10.0f; float timer = 0.0f; while (true) { if (timer > fadeInDuration) { overlayTextBottom = pressAnyKeyText; if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) { break; } } if (GameMain.GameSession == null) { GUI.DisableHUD = false; yield return(CoroutineStatus.Success); } overlayTextColor = Color.Lerp(Color.Transparent, Color.White, (timer - 1.0f) / fadeInDuration); timer = Math.Min(timer + CoroutineManager.UnscaledDeltaTime, textDuration); yield return(CoroutineStatus.Running); } var outpost = GameMain.GameSession.Level.StartOutpost; var borders = outpost.GetDockedBorders(); borders.Location += outpost.WorldPosition.ToPoint(); GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2); float startZoom = 0.8f / ((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X); GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom); var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam, null, null, fadeOut: false, losFadeIn: true, waitDuration: 1, panDuration: 5, startZoom: startZoom, endZoom: 1.0f) { AllowInterrupt = true, RemoveControlFromCharacter = false }; fadeInDuration = 1.0f; timer = 0.0f; overlayTextColor = Color.Transparent; overlayText = ""; while (timer < fadeInDuration) { overlayColor = Color.Lerp(Color.LightGray, Color.Transparent, timer / fadeInDuration); timer += CoroutineManager.UnscaledDeltaTime; yield return(CoroutineStatus.Running); } overlayColor = Color.Transparent; while (transition.Running) { yield return(CoroutineStatus.Running); } showCampaignResetText = false; } else { ISpatialEntity transitionTarget; transitionTarget = (ISpatialEntity)prevControlled ?? Submarine.MainSub; var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam, null, null, fadeOut: false, losFadeIn: prevControlled != null, panDuration: 5, startZoom: 0.5f, endZoom: 1.0f) { AllowInterrupt = true, RemoveControlFromCharacter = false }; while (transition.Running) { yield return(CoroutineStatus.Running); } } if (prevControlled != null) { prevControlled.SelectedConstruction = null; if (prevControlled.AIController != null) { prevControlled.AIController.Enabled = true; } } if (prevControlled != null) { Character.Controlled = prevControlled; } GUI.DisableHUD = false; yield return(CoroutineStatus.Success); }
public override void UpdateEditing(Camera cam) { 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.GetType() != typeof(WayPoint)) { continue; } if (e == this) { continue; } if (!Submarine.RectContains(e.Rect, position)) { 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; // } //}); } } }
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 } }
private void UpdateChildrenRect() { //dragging if (CanDragElements && draggedElement != null) { if (!PlayerInput.LeftButtonHeld()) { OnRearranged?.Invoke(this, draggedElement.UserData); draggedElement = null; RepositionChildren(); } else { draggedElement.RectTransform.AbsoluteOffset = draggedReferenceOffset + new Point(0, (int)PlayerInput.MousePosition.Y - draggedReferenceRectangle.Center.Y); int index = Content.RectTransform.GetChildIndex(draggedElement.RectTransform); int currIndex = index; while (currIndex > 0 && PlayerInput.MousePosition.Y < draggedReferenceRectangle.Top) { currIndex--; draggedReferenceRectangle.Y -= draggedReferenceRectangle.Height; draggedReferenceOffset.Y -= draggedReferenceRectangle.Height; } while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.Y > draggedReferenceRectangle.Bottom) { currIndex++; draggedReferenceRectangle.Y += draggedReferenceRectangle.Height; draggedReferenceOffset.Y += draggedReferenceRectangle.Height; } if (currIndex != index) { draggedElement.RectTransform.RepositionChildInHierarchy(currIndex); } return; } } for (int i = 0; i < Content.CountChildren; i++) { var child = Content.RectTransform.GetChild(i)?.GUIComponent; if (child == null) { continue; } // selecting if (Enabled && CanBeFocused && child.CanBeFocused && (GUI.IsMouseOn(child)) && child.Rect.Contains(PlayerInput.MousePosition)) { child.State = ComponentState.Hover; var mouseDown = useMouseDownToSelect ? PlayerInput.PrimaryMouseButtonDown() : PlayerInput.PrimaryMouseButtonClicked(); if (mouseDown) { Select(i, autoScroll: false); } if (CanDragElements && PlayerInput.LeftButtonDown() && GUI.MouseOn == child) { draggedElement = child; draggedReferenceRectangle = child.Rect; draggedReferenceOffset = child.RectTransform.AbsoluteOffset; } } else if (selected.Contains(child)) { child.State = ComponentState.Selected; if (CheckSelected != null) { if (CheckSelected() != child.UserData) { selected.Remove(child); } } } else { child.State = !child.ExternalHighlight ? ComponentState.None : ComponentState.Hover; } } }
protected override void Update(float deltaTime) { if (!Visible) { return; } base.Update(deltaTime); if (Rect.Contains(PlayerInput.MousePosition) && CanBeSelected && CanBeFocused && Enabled && GUI.IsMouseOn(this)) { State = Selected ? ComponentState.HoverSelected : ComponentState.Hover; if (PlayerInput.PrimaryMouseButtonDown()) { OnButtonDown?.Invoke(); } if (PlayerInput.PrimaryMouseButtonHeld()) { if (OnPressed != null) { if (OnPressed()) { State = ComponentState.Pressed; } } else { State = ComponentState.Pressed; } } else if (PlayerInput.PrimaryMouseButtonClicked()) { GUI.PlayUISound(GUISoundType.Click); if (OnClicked != null) { if (OnClicked(this, UserData)) { State = ComponentState.Selected; } } else { Selected = !Selected; } } } else { if (!ExternalHighlight) { State = Selected ? ComponentState.Selected : ComponentState.None; } else { State = ComponentState.Hover; } } foreach (GUIComponent child in Children) { child.State = State; } if (Pulse) { pulseTimer += deltaTime; if (pulseTimer > 1.0f) { if (!flashed) { flashed = true; Frame.Flash(Color.White * 0.2f, 0.8f, true); } pulseExpand += deltaTime; if (pulseExpand > 1.0f) { pulseTimer = 0.0f; pulseExpand = 0.0f; flashed = false; } } } }
/// <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 GameMain.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 && FirstLoad) { loadingScreenOpen = false; FirstLoad = false; MainMenuScreen.QuickStart(); } #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 (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(); } bool itemHudActive() { if (Character.Controlled?.SelectedConstruction == null) { return(false); } return (Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null) || ((Character.Controlled.ViewTarget as Item)?.Prefab?.FocusOnSelected ?? false)); } } #if DEBUG if (GameMain.NetworkMember == null) { if (PlayerInput.KeyHit(Keys.P) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox)) { DebugConsole.Paused = !DebugConsole.Paused; } } #endif GUI.ClearUpdateList(); Paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning || DebugConsole.Paused) && (NetworkMember == null || !NetworkMember.GameStarted); #if !DEBUG if (NetworkMember == null && !WindowActive && !Paused && true && Screen.Selected != MainMenuScreen && Config.PauseOnFocusLost) { GUI.TogglePauseMenu(); Paused = true; } #endif Screen.Selected.AddToGUIUpdateList(); if (Client != null) { Client.AddToGUIUpdateList(); } FileSelection.AddToGUIUpdateList(); DebugConsole.AddToGUIUpdateList(); DebugConsole.Update((float)Timing.Step); Paused = Paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted)); if (!Paused) { Screen.Selected.Update(Timing.Step); } else if (Tutorial.Initialized && Tutorial.ContentRunning) { (GameSession.GameMode as TutorialMode).Update((float)Timing.Step); } else if (DebugConsole.Paused) { if (Screen.Selected.Cam == null) { DebugConsole.Paused = false; } else { Screen.Selected.Cam.MoveCamera((float)Timing.Step); } } if (NetworkMember != null) { NetworkMember.Update((float)Timing.Step); } GUI.Update((float)Timing.Step); } CoroutineManager.Update((float)Timing.Step, Paused ? 0.0f : (float)Timing.Step); SteamManager.Update((float)Timing.Step); TaskPool.Update(); SoundManager?.Update(); Timing.Accumulator -= Timing.Step; sw.Stop(); PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks); PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency); PerformanceCounter.UpdateIterationsGraph.Update(updateIterations); } if (!Paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; } }