public void EndRound(string endMessage) { if (Mission != null) { Mission.End(); } GameAnalyticsManager.AddProgressionEvent( (Mission == null || Mission.Completed) ? GameAnalyticsSDK.Net.EGAProgressionStatus.Complete : GameAnalyticsSDK.Net.EGAProgressionStatus.Fail, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (RoundSummary != null) { GUIFrame summaryFrame = RoundSummary.CreateSummaryFrame(endMessage); GUIMessageBox.MessageBoxes.Add(summaryFrame); var okButton = new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), summaryFrame.Children.First().Children.First().FindChild("buttonarea").RectTransform), TextManager.Get("OK")) { OnClicked = (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(summaryFrame); return(true); } }; } TabMenu.OnRoundEnded(); #endif EventManager?.EndRound(); SteamAchievementManager.OnRoundEnded(this); Mission = null; StatusEffect.StopAll(); }
public Task SelectSummaryScreen(RoundSummary roundSummary, LevelData newLevel, bool mirror, Action action) { var roundSummaryScreen = RoundSummaryScreen.Select(overlaySprite, roundSummary); GUI.ClearCursorWait(); var loadTask = Task.Run(async() => { await Task.Yield(); Rand.ThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; try { GameMain.GameSession.StartRound(newLevel, mirrorLevel: mirror); } catch (Exception e) { roundSummaryScreen.LoadException = e; } Rand.ThreadId = 0; }); TaskPool.Add("AsyncCampaignStartRound", loadTask, (t) => { overlayColor = Color.Transparent; action?.Invoke(); }); return(loadTask); }
public static RoundSummaryScreen Select(Sprite backgroundSprite, RoundSummary roundSummary) { var summaryScreen = new RoundSummaryScreen() { roundSummary = roundSummary, backgroundSprite = backgroundSprite, prevGuiElementParent = roundSummary.Frame.RectTransform.Parent, loadText = TextManager.Get("campaignstartingpleasewait") }; roundSummary.Frame.RectTransform.Parent = summaryScreen.Frame.RectTransform; summaryScreen.Select(); summaryScreen.AddToGUIUpdateList(); return(summaryScreen); }
public void EndRound(string endMessage, List <TraitorMissionResult> traitorResults = null, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None) { if (Mission != null) { Mission.End(); } GameAnalyticsManager.AddProgressionEvent( (Mission == null || Mission.Completed) ? GameAnalyticsSDK.Net.EGAProgressionStatus.Complete : GameAnalyticsSDK.Net.EGAProgressionStatus.Fail, GameMode.Preset.Identifier, Mission == null ? "None" : Mission.GetType().ToString()); #if CLIENT if (GUI.PauseMenuOpen) { GUI.TogglePauseMenu(); } GUI.PreventPauseMenuToggle = true; if (!(GameMode is TestGameMode) && Screen.Selected == GameMain.GameScreen && RoundSummary != null) { GUI.ClearMessages(); GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData is RoundSummary); GUIFrame summaryFrame = RoundSummary.CreateSummaryFrame(this, endMessage, traitorResults, transitionType); GUIMessageBox.MessageBoxes.Add(summaryFrame); RoundSummary.ContinueButton.OnClicked = (_, __) => { GUIMessageBox.MessageBoxes.Remove(summaryFrame); return(true); }; } if (GameMain.NetLobbyScreen != null) { GameMain.NetLobbyScreen.OnRoundEnded(); } TabMenu.OnRoundEnded(); GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "ConversationAction" || ReadyCheck.IsReadyCheck(mb)); #endif SteamAchievementManager.OnRoundEnded(this); GameMode?.End(transitionType); EventManager?.EndRound(); StatusEffect.StopAll(); Mission = null; IsRunning = false; }
public void EndRound(string endMessage, List <TraitorMissionResult> traitorResults = null, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None) { foreach (Mission mission in missions) { mission.End(); } #if CLIENT if (GUI.PauseMenuOpen) { GUI.TogglePauseMenu(); } GUI.PreventPauseMenuToggle = true; if (!(GameMode is TestGameMode) && Screen.Selected == GameMain.GameScreen && RoundSummary != null) { GUI.ClearMessages(); GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData is RoundSummary); GUIFrame summaryFrame = RoundSummary.CreateSummaryFrame(this, endMessage, traitorResults, transitionType); GUIMessageBox.MessageBoxes.Add(summaryFrame); RoundSummary.ContinueButton.OnClicked = (_, __) => { GUIMessageBox.MessageBoxes.Remove(summaryFrame); return(true); }; } if (GameMain.NetLobbyScreen != null) { GameMain.NetLobbyScreen.OnRoundEnded(); } TabMenu.OnRoundEnded(); GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "ConversationAction" || ReadyCheck.IsReadyCheck(mb)); #endif SteamAchievementManager.OnRoundEnded(this); GameMode?.End(transitionType); EventManager?.EndRound(); StatusEffect.StopAll(); missions.Clear(); IsRunning = false; #if CLIENT HintManager.OnRoundEnded(); #endif }
public void StartRound(Level level, bool reloadSub = true, bool loadSecondSub = false) { #if CLIENT GameMain.LightManager.LosEnabled = GameMain.NetworkMember == null || GameMain.NetworkMember.CharacterInfo != null; #endif this.level = level; if (submarine == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected"); return; } if (reloadSub || Submarine.MainSub != submarine) { submarine.Load(true); } Submarine.MainSub = submarine; if (loadSecondSub) { if (Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(Submarine.MainSub.FilePath, Submarine.MainSub.MD5Hash.Hash, true); Submarine.MainSubs[1].Load(false); } else if (reloadSub) { Submarine.MainSubs[1].Load(false); } } if (level != null) { level.Generate(); submarine.SetPosition(submarine.FindSpawnPos(level.StartPosition - new Vector2(0.0f, 2000.0f))); } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { currentMission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { Mission.Start(Level.Loaded); } EventManager.StartRound(level); if (GameMode != null) { GameMode.MsgBox(); } #if CLIENT roundSummary = new RoundSummary(this); GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); SoundPlayer.SwitchMusic(); #endif }
protected override IEnumerable <object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List <TraitorMissionResult> traitorResults = null) { NextLevel = newLevel; bool success = CrewManager.GetCharacters().Any(c => !c.IsDead); SoundPlayer.OverrideMusicType = success ? "endround" : "crewdead"; SoundPlayer.OverrideMusicDuration = 18.0f; crewDead = false; GameMain.GameSession.EndRound("", traitorResults, transitionType); var continueButton = GameMain.GameSession.RoundSummary?.ContinueButton; RoundSummary roundSummary = null; if (GUIMessageBox.VisibleBox?.UserData is RoundSummary) { roundSummary = GUIMessageBox.VisibleBox?.UserData as RoundSummary; } if (continueButton != null) { continueButton.Visible = false; } lastControlledCharacter = Character.Controlled; Character.Controlled = null; switch (transitionType) { case TransitionType.None: throw new InvalidOperationException("Level transition failed (no transitions available)."); case TransitionType.ReturnToPreviousLocation: //deselect destination on map map.SelectLocation(-1); break; case TransitionType.ProgressToNextLocation: Map.MoveToNextLocation(); break; } Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime)); var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, transitionType == TransitionType.LeaveLocation ? Alignment.BottomCenter : Alignment.Center, fadeOut: false, duration: EndTransitionDuration); GUI.ClearMessages(); Location portraitLocation = Map.SelectedLocation ?? Map.CurrentLocation; overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId); float fadeOutDuration = endTransition.Duration; float t = 0.0f; while (t < fadeOutDuration || endTransition.Running) { t += CoroutineManager.UnscaledDeltaTime; overlayColor = Color.Lerp(Color.Transparent, Color.White, t / fadeOutDuration); yield return(CoroutineStatus.Running); } overlayColor = Color.White; yield return(CoroutineStatus.Running); //-------------------------------------- bool save = false; if (success) { if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); foreach (Submarine sub in subsToLeaveBehind) { MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); LinkedSubmarine.CreateDummy(leavingSub, sub); } } GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine); if (PendingSubmarineSwitch != null) { SubmarineInfo previousSub = GameMain.GameSession.SubmarineInfo; GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch; PendingSubmarineSwitch = null; for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++) { if (GameMain.GameSession.OwnedSubmarines[i].Name == previousSub.Name) { GameMain.GameSession.OwnedSubmarines[i] = previousSub; break; } } } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } else { PendingSubmarineSwitch = null; EnableRoundSummaryGameOverState(); } //-------------------------------------- SelectSummaryScreen(roundSummary, newLevel, mirror, () => { GameMain.GameScreen.Select(); if (continueButton != null) { continueButton.Visible = true; } GUI.DisableHUD = false; GUI.ClearCursorWait(); overlayColor = Color.Transparent; }); yield return(CoroutineStatus.Success); }
public void StartRound(Level level, bool reloadSub = true, bool loadSecondSub = false, bool mirrorLevel = false) { #if CLIENT GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null; if (GameMain.Client == null) { GameMain.LightManager.LosMode = GameMain.Config.LosMode; } #endif this.Level = level; if (Submarine == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected"); return; } if (reloadSub || Submarine.MainSub != Submarine) { Submarine.Load(true); } Submarine.MainSub = Submarine; if (loadSecondSub) { if (Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(Submarine.MainSub.FilePath, Submarine.MainSub.MD5Hash.Hash, true); Submarine.MainSubs[1].Load(false); } else if (reloadSub) { Submarine.MainSubs[1].Load(false); } } if (level != null) { level.Generate(mirrorLevel); if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Vector2 startOutpostSize = Vector2.Zero; if (Level.Loaded.StartOutpost != null) { startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2(); } Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { outPostPort = port; continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if (myPort == null || dist < closestDistance) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance); myPort.Dock(outPostPort); myPort.Lock(true); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition)); } } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { Mission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { Mission.Start(Level.Loaded); } EventManager.StartRound(level); SteamAchievementManager.OnStartRound(); if (GameMode != null) { GameMode.MsgBox(); if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { mpCampaign.CargoManager.CreateItems(); } } GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level.Seed)); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (GameMode is SinglePlayerCampaign) { SteamAchievementManager.OnBiomeDiscovered(level.Biome); } roundSummary = new RoundSummary(this); GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); if (!(GameMode is TutorialMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); GUI.AddMessage(level.Biome.Name, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.Get("Destination") + ": " + EndLocation.Name, Color.CadetBlue, playSound: false); GUI.AddMessage(TextManager.Get("Mission") + ": " + (Mission == null ? TextManager.Get("None") : Mission.Name), Color.CadetBlue, playSound: false); } #endif RoundStartTime = Timing.TotalTime; GameMain.ResetFrameTime(); }
public void StartRound(LevelData levelData, bool mirrorLevel = false, SubmarineInfo startOutpost = null, SubmarineInfo endOutpost = null) { MirrorLevel = mirrorLevel; if (SubmarineInfo == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected."); return; } if (SubmarineInfo.IsFileCorrupted) { DebugConsole.ThrowError("Couldn't start game session, submarine file corrupted."); return; } if (SubmarineInfo.SubmarineElement.Elements().Count() == 0) { DebugConsole.ThrowError("Couldn't start game session, saved submarine is empty. The submarine file may be corrupted."); return; } LevelData = levelData; Submarine.Unload(); Submarine = Submarine.MainSub = new Submarine(SubmarineInfo); foreach (Submarine sub in Submarine.GetConnectedSubs()) { sub.TeamID = CharacterTeamType.Team1; foreach (Item item in Item.ItemList) { if (item.Submarine != sub) { continue; } foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = sub.TeamID; } } } foreach (Mission mission in GameMode.Missions) { // setting level for missions that may involve difficulty-related submarine creation mission.SetLevel(levelData); } if (Submarine.MainSubs[1] == null) { var enemySubmarineInfo = GameMode is PvPMode ? SubmarineInfo : GameMode.Missions.FirstOrDefault(m => m.EnemySubmarineInfo != null)?.EnemySubmarineInfo; if (enemySubmarineInfo != null) { Submarine.MainSubs[1] = new Submarine(enemySubmarineInfo, true); } } if (GameMain.NetworkMember?.ServerSettings?.LockAllDefaultWires ?? false) { foreach (Item item in Item.ItemList) { if (item.Submarine == Submarine.MainSubs[0] || (Submarine.MainSubs[1] != null && item.Submarine == Submarine.MainSubs[1])) { Wire wire = item.GetComponent <Wire>(); if (wire != null && !wire.NoAutoLock && wire.Connections.Any(c => c != null)) { wire.Locked = true; } } } } Level level = null; if (levelData != null) { level = Level.Generate(levelData, mirrorLevel, startOutpost, endOutpost); } InitializeLevel(level); #if CLIENT if (GameMode is CampaignMode) { SteamAchievementManager.OnBiomeDiscovered(levelData.Biome); } var existingRoundSummary = GUIMessageBox.MessageBoxes.Find(mb => mb.UserData is RoundSummary)?.UserData as RoundSummary; if (existingRoundSummary?.ContinueButton != null) { existingRoundSummary.ContinueButton.Visible = true; } RoundSummary = new RoundSummary(Submarine.Info, GameMode, Missions, StartLocation, EndLocation); if (!(GameMode is TutorialMode) && !(GameMode is TestGameMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); if (EndLocation != null) { GUI.AddMessage(levelData.Biome.DisplayName, Color.Lerp(Color.CadetBlue, Color.DarkRed, levelData.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false); if (missions.Count > 1) { string joinedMissionNames = string.Join(", ", missions.Select(m => m.Name)); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), joinedMissionNames), Color.CadetBlue, playSound: false); } else { var mission = missions.FirstOrDefault(); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), mission?.Name ?? TextManager.Get("None")), Color.CadetBlue, playSound: false); } } else { GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Location"), StartLocation.Name), Color.CadetBlue, playSound: false); } } GUI.PreventPauseMenuToggle = false; HintManager.OnRoundStarted(); #endif }
public void Draw(SpriteBatch spriteBatch, GUICustomComponent mapContainer) { Rectangle rect = mapContainer.Rect; Vector2 viewSize = new Vector2(rect.Width / zoom, rect.Height / zoom); Vector2 edgeBuffer = rect.Size.ToVector2() / 2; DrawOffset.X = MathHelper.Clamp(DrawOffset.X, -Width - edgeBuffer.X + viewSize.X / 2.0f, edgeBuffer.X - viewSize.X / 2.0f); DrawOffset.Y = MathHelper.Clamp(DrawOffset.Y, -Height - edgeBuffer.Y + viewSize.Y / 2.0f, edgeBuffer.Y - 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); 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); Vector2 topLeft = rectCenter + viewOffset; Vector2 bottomRight = rectCenter + (viewOffset + new Vector2(Width, Height)); Vector2 mapTileSize = mapTiles[0, 0].size * generationParams.MapTileScale; int startX = (int)Math.Floor(-topLeft.X / mapTileSize.X) - 1; int startY = (int)Math.Floor(-topLeft.Y / mapTileSize.Y) - 1; int endX = (int)Math.Ceiling((-topLeft.X + rect.Width) / mapTileSize.X); int endY = (int)Math.Ceiling((-topLeft.Y + rect.Height) / mapTileSize.Y); float noiseT = (float)(Timing.TotalTime * 0.01f); cameraNoiseStrength = (float)PerlinNoise.CalculatePerlin(noiseT, noiseT * 0.5f, noiseT * 0.2f); float noiseScale = (float)PerlinNoise.CalculatePerlin(noiseT * 5.0f, noiseT * 2.0f, 0) * 5.0f; for (int x = startX; x <= endX; x++) { for (int y = startY; y <= endY; y++) { int tileX = Math.Abs(x) % mapTiles.GetLength(0); int tileY = Math.Abs(y) % mapTiles.GetLength(1); Vector2 tilePos = rectCenter + (viewOffset + new Vector2(x, y) * mapTileSize) * zoom; mapTiles[tileX, tileY].Draw(spriteBatch, tilePos, Color.White, origin: Vector2.Zero, scale: generationParams.MapTileScale * zoom); if (GameMain.DebugDraw) { continue; } if (!tileDiscovered[tileX, tileY] || x < 0 || y < 0 || x >= tileDiscovered.GetLength(0) || y >= tileDiscovered.GetLength(1)) { generationParams.FogOfWarSprite?.Draw(spriteBatch, tilePos, Color.White * cameraNoiseStrength, origin: Vector2.Zero, scale: generationParams.MapTileScale * zoom); noiseOverlay.DrawTiled(spriteBatch, tilePos, mapTileSize * zoom, startOffset: new Vector2(Rand.Range(0.0f, noiseOverlay.SourceRect.Width), Rand.Range(0.0f, noiseOverlay.SourceRect.Height)), color: Color.White * cameraNoiseStrength * 0.2f, textureScale: Vector2.One * noiseScale); } } } if (GameMain.DebugDraw) { if (topLeft.X > rect.X) { GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Y, (int)(topLeft.X - rect.X), rect.Height), Color.Black * 0.5f, 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.5f, 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.5f, 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.5f, true); } } float rawNoiseScale = 1.0f + PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1)); cameraNoiseStrength = PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1)); noiseOverlay.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(), startOffset: new Vector2(Rand.Range(0.0f, noiseOverlay.SourceRect.Width), Rand.Range(0.0f, noiseOverlay.SourceRect.Height)), color: Color.White * cameraNoiseStrength * 0.1f, textureScale: Vector2.One * rawNoiseScale); noiseOverlay.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(), startOffset: new Vector2(Rand.Range(0.0f, noiseOverlay.SourceRect.Width), Rand.Range(0.0f, noiseOverlay.SourceRect.Height)), color: new Color(20, 20, 20, 50), textureScale: Vector2.One * rawNoiseScale * 2); noiseOverlay.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight), startOffset: new Vector2(Rand.Range(0.0f, noiseOverlay.SourceRect.Width), Rand.Range(0.0f, noiseOverlay.SourceRect.Height)), color: Color.White * cameraNoiseStrength * 0.1f, textureScale: Vector2.One * noiseScale); Pair <Rectangle, string> tooltip = null; if (generationParams.ShowLocations) { foreach (LocationConnection connection in Connections) { if (IsInFogOfWar(connection.Locations[0]) && IsInFogOfWar(connection.Locations[1])) { continue; } DrawConnection(spriteBatch, connection, rect, viewOffset); } for (int i = 0; i < Locations.Count; i++) { Location location = Locations[i]; if (IsInFogOfWar(location)) { continue; } 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; } if (location == CurrentDisplayLocation) { generationParams.CurrentLocationIndicator.Draw(spriteBatch, rectCenter + (currLocationIndicatorPos + viewOffset) * zoom, generationParams.IndicatorColor, generationParams.CurrentLocationIndicator.Origin, 0, Vector2.One * (generationParams.LocationIconSize / generationParams.CurrentLocationIndicator.size.X) * 1.7f * zoom); } if (location == SelectedLocation) { generationParams.SelectedLocationIndicator.Draw(spriteBatch, rectCenter + (location.MapPosition + viewOffset) * zoom, generationParams.IndicatorColor, generationParams.SelectedLocationIndicator.Origin, 0, Vector2.One * (generationParams.LocationIconSize / generationParams.SelectedLocationIndicator.size.X) * 1.7f * zoom); } Color color = location.Type.SpriteColor; if (!location.Discovered) { color = Color.White; } if (location.Connections.Find(c => c.Locations.Contains(CurrentDisplayLocation)) == null) { color *= 0.5f; } float iconScale = location == CurrentDisplayLocation ? 1.2f : 1.0f; if (location == HighlightedLocation) { iconScale *= 1.2f; } location.Type.Sprite.Draw(spriteBatch, pos, color, scale: generationParams.LocationIconSize / location.Type.Sprite.size.X * iconScale * zoom); if (location.TypeChangeTimer <= 0 && !string.IsNullOrEmpty(location.LastTypeChangeMessage) && generationParams.TypeChangeIcon != null) { Vector2 typeChangeIconPos = pos + new Vector2(1.35f, -0.35f) * generationParams.LocationIconSize * 0.5f * zoom; float typeChangeIconScale = 18.0f / generationParams.TypeChangeIcon.SourceRect.Width; generationParams.TypeChangeIcon.Draw(spriteBatch, typeChangeIconPos, GUI.Style.Red, scale: typeChangeIconScale * zoom); if (Vector2.Distance(PlayerInput.MousePosition, typeChangeIconPos) < generationParams.TypeChangeIcon.SourceRect.Width * zoom) { tooltip = new Pair <Rectangle, string>( new Rectangle(typeChangeIconPos.ToPoint(), new Point(30)), location.LastTypeChangeMessage); } } if (location != CurrentLocation && CurrentLocation.AvailableMissions.Any(m => m.Locations.Contains(location)) && generationParams.MissionIcon != null) { Vector2 missionIconPos = pos + new Vector2(1.35f, 0.35f) * generationParams.LocationIconSize * 0.5f * zoom; float missionIconScale = 18.0f / generationParams.MissionIcon.SourceRect.Width; generationParams.MissionIcon.Draw(spriteBatch, missionIconPos, generationParams.IndicatorColor, scale: missionIconScale * zoom); if (Vector2.Distance(PlayerInput.MousePosition, missionIconPos) < generationParams.MissionIcon.SourceRect.Width * zoom) { var availableMissions = CurrentLocation.AvailableMissions.Where(m => m.Locations.Contains(location)); tooltip = new Pair <Rectangle, string>( new Rectangle(missionIconPos.ToPoint(), new Point(30)), TextManager.Get("mission") + '\n' + string.Join('\n', availableMissions.Select(m => "- " + m.Name))); } } if (GameMain.DebugDraw && location == HighlightedLocation && (!location.Discovered || !location.Type.HasOutpost)) { if (location.Reputation != null) { Vector2 dPos = pos; dPos.Y += 48; string name = $"Reputation: {location.Name}"; Vector2 nameSize = GUI.SmallFont.MeasureString(name); GUI.DrawString(spriteBatch, dPos, name, Color.White, Color.Black * 0.8f, 4, font: GUI.SmallFont); dPos.Y += nameSize.Y + 16; Rectangle bgRect = new Rectangle((int)dPos.X, (int)dPos.Y, 256, 32); bgRect.Inflate(8, 8); Color barColor = ToolBox.GradientLerp(location.Reputation.NormalizedValue, Color.Red, Color.Yellow, Color.LightGreen); GUI.DrawRectangle(spriteBatch, bgRect, Color.Black * 0.8f, isFilled: true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)dPos.X, (int)dPos.Y, (int)(location.Reputation.NormalizedValue * 255), 32), barColor, isFilled: true); string reputationValue = ((int)location.Reputation.Value).ToString(); Vector2 repValueSize = GUI.SubHeadingFont.MeasureString(reputationValue); GUI.DrawString(spriteBatch, dPos + (new Vector2(256, 32) / 2) - (repValueSize / 2), reputationValue, Color.White, Color.Black, font: GUI.SubHeadingFont); GUI.DrawRectangle(spriteBatch, new Rectangle((int)dPos.X, (int)dPos.Y, 256, 32), Color.White); } } } } DrawDecorativeHUD(spriteBatch, rect); if (HighlightedLocation != null) { Vector2 pos = rectCenter + (HighlightedLocation.MapPosition + viewOffset) * zoom; pos.X += 50 * zoom; Vector2 nameSize = GUI.LargeFont.MeasureString(HighlightedLocation.Name); Vector2 typeSize = GUI.Font.MeasureString(HighlightedLocation.Type.Name); Vector2 size = new Vector2(Math.Max(nameSize.X, typeSize.X), nameSize.Y + typeSize.Y); bool showReputation = HighlightedLocation.Discovered && HighlightedLocation.Type.HasOutpost && HighlightedLocation.Reputation != null; string repLabelText = null, repValueText = null; Vector2 repLabelSize = Vector2.Zero, repBarSize = Vector2.Zero; if (showReputation) { repLabelText = TextManager.Get("reputation"); repLabelSize = GUI.Font.MeasureString(repLabelText); size.X = Math.Max(size.X, repLabelSize.X); repBarSize = new Vector2(Math.Max(0.75f * size.X, 100), repLabelSize.Y); size.X = Math.Max(size.X, (4.0f / 3.0f) * repBarSize.X); size.Y += 2 * repLabelSize.Y + 4 + repBarSize.Y; repValueText = ((int)HighlightedLocation.Reputation.Value).ToString(); } GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw( spriteBatch, new Rectangle((int)(pos.X - 60 * GUI.Scale), (int)(pos.Y - size.Y), (int)(size.X + 120 * GUI.Scale), (int)(size.Y * 2.2f)), Color.Black * hudVisibility); var topLeftPos = pos - new Vector2(0.0f, size.Y / 2); GUI.DrawString(spriteBatch, topLeftPos, HighlightedLocation.Name, GUI.Style.TextColor * hudVisibility * 1.5f, font: GUI.LargeFont); topLeftPos += new Vector2(0.0f, nameSize.Y); GUI.DrawString(spriteBatch, topLeftPos, HighlightedLocation.Type.Name, GUI.Style.TextColor * hudVisibility * 1.5f); if (showReputation) { topLeftPos += new Vector2(0.0f, typeSize.Y + repLabelSize.Y); GUI.DrawString(spriteBatch, topLeftPos, repLabelText, GUI.Style.TextColor * hudVisibility * 1.5f); topLeftPos += new Vector2(0.0f, repLabelSize.Y + 4); Rectangle repBarRect = new Rectangle(new Point((int)topLeftPos.X, (int)topLeftPos.Y), new Point((int)repBarSize.X, (int)repBarSize.Y)); RoundSummary.DrawReputationBar(spriteBatch, repBarRect, HighlightedLocation.Reputation.NormalizedValue); GUI.DrawString(spriteBatch, new Vector2(repBarRect.Right + 4, repBarRect.Top), repValueText, GUI.Style.TextColor); } } if (tooltip != null) { GUIComponent.DrawToolTip(spriteBatch, tooltip.Second, tooltip.First); } spriteBatch.End(); GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect; spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable); }
public void StartRound(Level level, bool reloadSub = true, bool loadSecondSub = false) { #if CLIENT GameMain.LightManager.LosEnabled = GameMain.NetworkMember == null || GameMain.NetworkMember.CharacterInfo != null; #endif this.level = level; if (submarine == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected"); return; } if (reloadSub || Submarine.MainSub != submarine) { submarine.Load(true); } Submarine.MainSub = submarine; if (loadSecondSub) { if (Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(Submarine.MainSub.FilePath, Submarine.MainSub.MD5Hash.Hash, true); Submarine.MainSubs[1].Load(false); } else if (reloadSub) { Submarine.MainSubs[1].Load(false); } } if (level != null) { level.Generate(); submarine.SetPosition(submarine.FindSpawnPos(level.StartPosition - new Vector2(0.0f, 2000.0f))); } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { currentMission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { Mission.Start(Level.Loaded); } EventManager.StartRound(level); if (GameMode != null) { GameMode.MsgBox(); if (GameMode is MultiPlayerCampaign campaign && GameMain.Server != null) { campaign.CargoManager.CreateItems(); } } GameAnalyticsManager.AddDesignEvent("Submarine:" + submarine.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level.Seed)); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Name, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT roundSummary = new RoundSummary(this); GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); SoundPlayer.SwitchMusic(); #endif }
public void StartRound(LevelData levelData, bool mirrorLevel = false, SubmarineInfo startOutpost = null, SubmarineInfo endOutpost = null) { if (SubmarineInfo == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected."); return; } if (SubmarineInfo.IsFileCorrupted) { DebugConsole.ThrowError("Couldn't start game session, submarine file corrupted."); return; } if (SubmarineInfo.SubmarineElement.Elements().Count() == 0) { DebugConsole.ThrowError("Couldn't start game session, saved submarine is empty. The submarine file may be corrupted."); return; } LevelData = levelData; if (GameMode is CampaignMode campaignMode && GameMode.Mission != null && LevelData != null && LevelData.Type == LevelData.LevelType.Outpost) { campaignMode.Map.CurrentLocation.SelectedMission = null; } Submarine.Unload(); Submarine = Submarine.MainSub = new Submarine(SubmarineInfo); foreach (Submarine sub in Submarine.GetConnectedSubs()) { sub.TeamID = CharacterTeamType.Team1; foreach (Item item in Item.ItemList) { if (item.Submarine != sub) { continue; } foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>()) { wifiComponent.TeamID = sub.TeamID; } } } if (GameMode is PvPMode && Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(SubmarineInfo, true); } Level level = null; if (levelData != null) { level = Level.Generate(levelData, mirrorLevel, startOutpost, endOutpost); } InitializeLevel(level); GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Info.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(levelData?.Seed ?? "[NO_LEVEL]")); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (GameMode is CampaignMode) { SteamAchievementManager.OnBiomeDiscovered(levelData.Biome); } var existingRoundSummary = GUIMessageBox.MessageBoxes.Find(mb => mb.UserData is RoundSummary)?.UserData as RoundSummary; if (existingRoundSummary?.ContinueButton != null) { existingRoundSummary.ContinueButton.Visible = true; } RoundSummary = new RoundSummary(Submarine.Info, GameMode, Mission, StartLocation, EndLocation); if (!(GameMode is TutorialMode) && !(GameMode is TestGameMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); if (EndLocation != null) { GUI.AddMessage(levelData.Biome.DisplayName, Color.Lerp(Color.CadetBlue, Color.DarkRed, levelData.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), (Mission == null ? TextManager.Get("None") : Mission.Name)), Color.CadetBlue, playSound: false); } else { GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Location"), StartLocation.Name), Color.CadetBlue, playSound: false); } } GUI.PreventPauseMenuToggle = false; #endif }
public void StartRound(Level level, bool mirrorLevel = false) { //make sure no status effects have been carried on from the next round //(they should be stopped in EndRound, this is a safeguard against cases where the round is ended ungracefully) StatusEffect.StopAll(); #if CLIENT GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null; if (GameMain.Client == null) { GameMain.LightManager.LosMode = GameMain.Config.LosMode; } #endif this.Level = level; if (SubmarineInfo == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected."); return; } if (SubmarineInfo.IsFileCorrupted) { DebugConsole.ThrowError("Couldn't start game session, submarine file corrupted."); return; } Submarine.Unload(); Submarine = Submarine.MainSub = new Submarine(SubmarineInfo); Submarine.MainSub = Submarine; if (GameMode.Mission != null && GameMode.Mission.TeamCount > 1 && Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(SubmarineInfo, true); } if (level != null) { level.Generate(mirrorLevel); if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Vector2 startOutpostSize = Vector2.Zero; if (Level.Loaded.StartOutpost != null) { startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2(); } Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { outPostPort = port; continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if (myPort == null || dist < closestDistance || (port.MainDockingPort && !myPort.MainDockingPort)) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance); myPort.Dock(outPostPort); myPort.Lock(true); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition)); } } foreach (var sub in Submarine.Loaded) { if (sub.Info.IsOutpost) { sub.DisableObstructedWayPoints(); } } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { Mission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { int prevEntityCount = Entity.GetEntityList().Count; Mission.Start(Level.Loaded); if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && Entity.GetEntityList().Count != prevEntityCount) { DebugConsole.ThrowError( "Entity count has changed after starting a mission as a client. " + "The clients should not instantiate entities themselves when starting the mission," + " but instead the server should inform the client of the spawned entities using Mission.ServerWriteInitial."); } } EventManager?.StartRound(level); SteamAchievementManager.OnStartRound(); if (GameMode != null) { GameMode.ShowStartMessage(); if (GameMain.NetworkMember == null) { //only place items and corpses here in single player //the server does this after loading the respawn shuttle Level?.SpawnCorpses(); AutoItemPlacer.PlaceIfNeeded(GameMode); } if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { mpCampaign.CargoManager.CreateItems(); } } GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Info.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level?.Seed ?? "[NO_LEVEL]")); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (GameMode is SinglePlayerCampaign) { SteamAchievementManager.OnBiomeDiscovered(level.Biome); } if (!(GameMode is SubTestMode)) { RoundSummary = new RoundSummary(this); } GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); if (!(GameMode is TutorialMode) && !(GameMode is SubTestMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); GUI.AddMessage(level.Biome.DisplayName, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), (Mission == null ? TextManager.Get("None") : Mission.Name)), Color.CadetBlue, playSound: false); } #endif RoundStartTime = Timing.TotalTime; GameMain.ResetFrameTime(); }