From 980f8e0d33c94b3245ef844782af13a145db6251 Mon Sep 17 00:00:00 2001 From: Regalis Date: Wed, 26 Oct 2016 19:22:40 +0300 Subject: [PATCH] - option to select which location autopilot navigates towards - generating "dummy locations" for the MP gamesessions (visible in sonar and mission descriptions) - EndGame network message tells the clients if the mission was successful (because the message may arrive before the sub has reached the exit or before some character has died at the client's end) --- .../Source/Events/Missions/CombatMission.cs | 15 +-- Subsurface/Source/Events/Missions/Mission.cs | 16 ++- .../GameSession/GameModes/MissionMode.cs | 8 +- Subsurface/Source/GameSession/GameSession.cs | 52 ++++++- .../Source/GameSession/InfoTextManager.cs | 5 +- Subsurface/Source/GameSession/ShiftSummary.cs | 4 +- .../Source/Items/Components/Machines/Radar.cs | 9 +- .../Items/Components/Machines/Steering.cs | 127 +++++++++++++++--- Subsurface/Source/Networking/GameClient.cs | 7 + Subsurface/Source/Networking/GameServer.cs | 2 + 10 files changed, 184 insertions(+), 61 deletions(-) diff --git a/Subsurface/Source/Events/Missions/CombatMission.cs b/Subsurface/Source/Events/Missions/CombatMission.cs index 02b9ff903..87809baf0 100644 --- a/Subsurface/Source/Events/Missions/CombatMission.cs +++ b/Subsurface/Source/Events/Missions/CombatMission.cs @@ -43,7 +43,7 @@ namespace Barotrauma return successMessage .Replace("[loser]", teamNames[1 - winner]) - .Replace("[winner]", teamNames[winner]); + .Replace("[winner]", teamNames[winner]); } } @@ -57,11 +57,11 @@ namespace Barotrauma ToolBox.GetAttributeString(element, "description2", "") }; - for (int i = 0; i < descriptions.Length; i++ ) + for (int i = 0; i < descriptions.Length; i++) { - for (int n = 0; n < 2;n++ ) + for (int n = 0; n < 2; n++) { - descriptions[i] = descriptions[i].Replace("[location" + (n + 1) + "]", Locations[n]); + descriptions[i] = descriptions[i].Replace("[location" + (n + 1) + "]", locations[n].Name); } } @@ -69,7 +69,7 @@ namespace Barotrauma { ToolBox.GetAttributeString(element, "teamname1", "Team A"), ToolBox.GetAttributeString(element, "teamname2", "Team B") - }; + }; } public static string GetTeamName(int teamID) @@ -136,10 +136,7 @@ namespace Barotrauma DebugConsole.ThrowError("Combat missions cannot be played in the single player mode."); return; } - - Items.Components.Radar.StartMarker = Locations[0]; - Items.Components.Radar.EndMarker = Locations[1]; - + subs = new Submarine[] { Submarine.MainSubs[0], Submarine.MainSubs[1] }; subs[1].SetPosition(Level.Loaded.EndPosition - new Vector2(0.0f, 2000.0f)); subs[1].FlipX(); diff --git a/Subsurface/Source/Events/Missions/Mission.cs b/Subsurface/Source/Events/Missions/Mission.cs index 8263dfc87..1dd37f692 100644 --- a/Subsurface/Source/Events/Missions/Mission.cs +++ b/Subsurface/Source/Events/Missions/Mission.cs @@ -26,9 +26,7 @@ namespace Barotrauma protected List messages; private int reward; - - protected string[] Locations = new string[2]; - + public string Name { get { return name; } @@ -47,6 +45,7 @@ namespace Barotrauma public bool Completed { get { return completed; } + set { completed = value; } } public virtual string RadarLabel @@ -111,11 +110,9 @@ namespace Barotrauma headers.Add(ToolBox.GetAttributeString(subElement, "header", "")); messages.Add(ToolBox.GetAttributeString(subElement, "text", "")); } - - + for (int n = 0; n < 2; n++) { - Locations[n] = locations[n].Name; description = description.Replace("[location" + (n + 1) + "]", locations[n].Name); successMessage = successMessage.Replace("[location" + (n + 1) + "]", locations[n].Name); @@ -227,7 +224,12 @@ namespace Barotrauma public virtual void Update(float deltaTime) { } - public virtual bool AssignTeamIDs(List clients,out int hostTeam) { clients.ForEach(client => { client.TeamID = 1; }); hostTeam = 1; return false; } + public virtual bool AssignTeamIDs(List clients, out int hostTeam) + { + clients.ForEach(c => c.TeamID = 1); + hostTeam = 1; + return false; + } public void ShowMessage(int index) { diff --git a/Subsurface/Source/GameSession/GameModes/MissionMode.cs b/Subsurface/Source/GameSession/GameModes/MissionMode.cs index e84fc9769..24bf6e751 100644 --- a/Subsurface/Source/GameSession/GameModes/MissionMode.cs +++ b/Subsurface/Source/GameSession/GameModes/MissionMode.cs @@ -17,15 +17,9 @@ namespace Barotrauma public MissionMode(GameModePreset preset, object param) : base(preset, param) { - Location[] locations = new Location[2]; + Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation }; MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed)); - - for (int i = 0; i < 2; i++) - { - locations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f)); - } - mission = Mission.LoadRandom(locations, rand, param as string); } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index ecc1c89bb..3414f680b 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -13,6 +13,9 @@ namespace Barotrauma public readonly GameMode gameMode; + //two locations used as the start and end in the MP mode + private Location[] dummyLocations; + private InfoFrameTab selectedTab; private GUIButton infoButton; private GUIFrame infoFrame; @@ -50,7 +53,37 @@ namespace Barotrauma return (mode == null) ? null : mode.Map; } } - + + public Location StartLocation + { + get + { + if (Map != null) return Map.CurrentLocation; + + if (dummyLocations==null) + { + CreateDummyLocations(); + } + + return dummyLocations[0]; + } + } + + public Location EndLocation + { + get + { + if (Map != null) return Map.SelectedLocation; + + if (dummyLocations == null) + { + CreateDummyLocations(); + } + + return dummyLocations[1]; + } + } + public Submarine Submarine { get { return submarine; } @@ -79,12 +112,10 @@ namespace Barotrauma this.saveFile = saveFile; - //guiRoot = new GUIFrame(new Rectangle(0,0,GameMain.GraphicsWidth,GameMain.GraphicsWidth), Color.Transparent); - infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", GUI.Style, null); infoButton.OnClicked = ToggleInfoFrame; - if (gameModePreset!=null) gameMode = gameModePreset.Instantiate(missionType); + if (gameModePreset != null) gameMode = gameModePreset.Instantiate(missionType); this.submarine = submarine; } @@ -107,6 +138,17 @@ namespace Barotrauma } } + private void CreateDummyLocations() + { + dummyLocations = new Location[2]; + + MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed)); + for (int i = 0; i < 2; i++) + { + dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f)); + } + } + public void StartShift(string levelSeed, bool loadSecondSub = true) { Level level = Level.CreateRandom(levelSeed); @@ -164,8 +206,6 @@ namespace Barotrauma if (gameMode!=null) gameMode.Start(); - Items.Components.Radar.StartMarker = "Start"; - Items.Components.Radar.EndMarker = "End"; if (gameMode.Mission != null) Mission.Start(Level.Loaded); TaskManager.StartShift(level); diff --git a/Subsurface/Source/GameSession/InfoTextManager.cs b/Subsurface/Source/GameSession/InfoTextManager.cs index 14e5d4566..e72f1eef3 100644 --- a/Subsurface/Source/GameSession/InfoTextManager.cs +++ b/Subsurface/Source/GameSession/InfoTextManager.cs @@ -58,10 +58,9 @@ namespace Barotrauma } if (Submarine.MainSub != null) text = text.Replace("[sub]", Submarine.MainSub.Name); - if (GameMain.GameSession != null && GameMain.GameSession.Map != null) + if (GameMain.GameSession != null && GameMain.GameSession.StartLocation != null) { - if (GameMain.GameSession.Map.CurrentLocation!=null) - text = text.Replace("[location]", GameMain.GameSession.Map.CurrentLocation.Name); + text = text.Replace("[location]", GameMain.GameSession.StartLocation.Name); } return text; diff --git a/Subsurface/Source/GameSession/ShiftSummary.cs b/Subsurface/Source/GameSession/ShiftSummary.cs index 1816d5554..a9b9e2a48 100644 --- a/Subsurface/Source/GameSession/ShiftSummary.cs +++ b/Subsurface/Source/GameSession/ShiftSummary.cs @@ -15,8 +15,8 @@ namespace Barotrauma { this.gameSession = gameSession; - startLocation = gameSession.Map==null ? null : gameSession.Map.CurrentLocation; - endLocation = gameSession.Map==null ? null : gameSession.Map.SelectedLocation; + startLocation = gameSession.StartLocation; + endLocation = gameSession.EndLocation; selectedMission = gameSession.Mission; } diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index 3c535d34d..11bce3861 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -20,10 +20,7 @@ namespace Barotrauma.Items.Components private List radarBlips; private float prevPingRadius; - - public static string StartMarker = "Start"; - public static string EndMarker = "End"; - + [HasDefaultValue(10000.0f, false)] public float Range { @@ -266,11 +263,11 @@ namespace Barotrauma.Items.Components DrawMarker(spriteBatch, - (GameMain.GameSession.Map == null) ? StartMarker : GameMain.GameSession.Map.CurrentLocation.Name, + GameMain.GameSession.StartLocation.Name, (Level.Loaded.StartPosition - item.WorldPosition), displayScale, center, (rect.Width * 0.5f)); DrawMarker(spriteBatch, - (GameMain.GameSession.Map == null) ? EndMarker : GameMain.GameSession.Map.SelectedLocation.Name, + GameMain.GameSession.EndLocation.Name, (Level.Loaded.EndPosition - item.WorldPosition), displayScale, center, (rect.Width * 0.5f)); if (GameMain.GameSession.Mission != null) diff --git a/Subsurface/Source/Items/Components/Machines/Steering.cs b/Subsurface/Source/Items/Components/Machines/Steering.cs index 56bcd1f13..3cfff69fc 100644 --- a/Subsurface/Source/Items/Components/Machines/Steering.cs +++ b/Subsurface/Source/Items/Components/Machines/Steering.cs @@ -19,7 +19,8 @@ namespace Barotrauma.Items.Components private Vector2 targetVelocity; private GUITickBox autopilotTickBox, maintainPosTickBox; - + private GUITickBox levelEndTickBox, levelStartTickBox; + private bool autoPilot; private Vector2? posToMaintain; @@ -47,21 +48,23 @@ namespace Barotrauma.Items.Components if (value == autoPilot) return; autoPilot = value; - autopilotTickBox.Selected = value; maintainPosTickBox.Enabled = autoPilot; - + levelEndTickBox.Enabled = autoPilot; + levelStartTickBox.Enabled = autoPilot; + if (autoPilot) { - if (pathFinder==null) pathFinder = new PathFinder(WayPoint.WayPointList, false); - steeringPath = pathFinder.FindPath( - ConvertUnits.ToSimUnits(item.WorldPosition), - TargetPosition == null ? ConvertUnits.ToSimUnits(Level.Loaded.EndPosition) : (Vector2)TargetPosition); + if (pathFinder == null) pathFinder = new PathFinder(WayPoint.WayPointList, false); + ToggleMaintainPosition(maintainPosTickBox); } else { maintainPosTickBox.Selected = false; + levelEndTickBox.Selected = false; + levelStartTickBox.Selected = false; + posToMaintain = null; } } @@ -114,9 +117,24 @@ namespace Barotrauma.Items.Components return true; }; - maintainPosTickBox = new GUITickBox(new Rectangle(0, 50, 20, 20), "Maintain position", Alignment.TopLeft, GuiFrame); + maintainPosTickBox = new GUITickBox(new Rectangle(5, 50, 15, 15), "Maintain position", Alignment.TopLeft, GUI.SmallFont, GuiFrame); maintainPosTickBox.Enabled = false; maintainPosTickBox.OnSelected = ToggleMaintainPosition; + + levelStartTickBox = new GUITickBox( + new Rectangle(5, 70, 15, 15), + GameMain.GameSession.StartLocation.Name, + Alignment.TopLeft, GUI.SmallFont, GuiFrame); + levelStartTickBox.Enabled = false; + levelStartTickBox.OnSelected = SelectDestination; + + levelEndTickBox = new GUITickBox( + new Rectangle(5, 90, 15, 15), + GameMain.GameSession.EndLocation.Name, + Alignment.TopLeft, GUI.SmallFont, GuiFrame); + levelEndTickBox.Enabled = false; + levelEndTickBox.OnSelected = SelectDestination; + } public override void Update(float deltaTime, Camera cam) @@ -332,6 +350,28 @@ namespace Barotrauma.Items.Components } + private void UpdatePath() + { + Vector2 target; + if (TargetPosition != null) + { + target = (Vector2)TargetPosition; + } + else + { + if (levelEndTickBox.Selected) + { + target = ConvertUnits.ToSimUnits(Level.Loaded.EndPosition); + } + else + { + target = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition); + } + } + + steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(item.WorldPosition), target); + } + private void SteerTowardsPosition(Vector2 worldPosition) { float prediction = 10.0f; @@ -346,7 +386,7 @@ namespace Barotrauma.Items.Components } else { - TargetVelocity = targetSpeed/5.0f; + TargetVelocity = targetSpeed / 5.0f; } } @@ -354,21 +394,42 @@ namespace Barotrauma.Items.Components { valueChanged = true; - if (tickBox.Selected) - { - if (item.Submarine == null) - { - posToMaintain = null; - } - else - { - posToMaintain = item.Submarine.WorldPosition; - } - } - else + levelStartTickBox.Selected = false; + levelEndTickBox.Selected = false; + + if (item.Submarine == null) { posToMaintain = null; } + else + { + posToMaintain = item.Submarine.WorldPosition; + } + + tickBox.Selected = true; + + return true; + } + + private bool SelectDestination(GUITickBox tickBox) + { + valueChanged = true; + + if (tickBox == levelStartTickBox) + { + levelEndTickBox.Selected = false; + } + else + { + levelStartTickBox.Selected = false; + } + + maintainPosTickBox.Selected = false; + posToMaintain = null; + + UpdatePath(); + + tickBox.Selected = true; return true; } @@ -399,6 +460,10 @@ namespace Barotrauma.Items.Components message.Write(((Vector2)posToMaintain).X); message.Write(((Vector2)posToMaintain).Y); } + else + { + message.Write(levelStartTickBox.Selected); + } } return true; @@ -411,6 +476,8 @@ namespace Barotrauma.Items.Components Vector2? newPosToMaintain = null; + bool headingToStart = false; + try { newTargetVelocity = new Vector2(message.ReadFloat(), message.ReadFloat()); @@ -424,6 +491,10 @@ namespace Barotrauma.Items.Components message.ReadFloat(), message.ReadFloat()); } + else + { + headingToStart = message.ReadBoolean(); + } } } @@ -437,6 +508,20 @@ namespace Barotrauma.Items.Components maintainPosTickBox.Selected = newPosToMaintain != null; posToMaintain = newPosToMaintain; + + if (posToMaintain == null && autoPilot) + { + levelStartTickBox.Selected = headingToStart; + levelEndTickBox.Selected = !headingToStart; + + UpdatePath(); + } + else + { + levelStartTickBox.Selected = false; + levelEndTickBox.Selected = false; + } + } } } diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index e4e0b2b0f..56cedfa1a 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -566,6 +566,13 @@ namespace Barotrauma.Networking break; case (byte)PacketTypes.EndGame: string endMessage = inc.ReadString(); + bool missionSuccessful = inc.ReadBoolean(); + + if (missionSuccessful && GameMain.GameSession.Mission != null) + { + GameMain.GameSession.Mission.Completed = true; + } + CoroutineManager.StartCoroutine(EndGame(endMessage)); break; case (byte)PacketTypes.Respawn: diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index f4714b826..72cfd7bbc 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -1082,6 +1082,7 @@ namespace Barotrauma.Networking endMessage += TraitorManager.GetEndMessage(); } + Mission mission = GameMain.GameSession.Mission; GameMain.GameSession.gameMode.End(endMessage); if (autoRestart) AutoRestartTimer = AutoRestartInterval; @@ -1108,6 +1109,7 @@ namespace Barotrauma.Networking NetOutgoingMessage msg = server.CreateMessage(); msg.Write((byte)PacketTypes.EndGame); msg.Write(endMessage); + msg.Write(mission != null && mission.Completed); if (server.ConnectionsCount > 0) {