diff --git a/Barotrauma/BarotraumaClient/BarotraumaClient.csproj b/Barotrauma/BarotraumaClient/BarotraumaClient.csproj
index 4866af852..b8d454aa4 100644
--- a/Barotrauma/BarotraumaClient/BarotraumaClient.csproj
+++ b/Barotrauma/BarotraumaClient/BarotraumaClient.csproj
@@ -80,6 +80,7 @@
+
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/MultiPlayerCampaign.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/MultiPlayerCampaign.cs
new file mode 100644
index 000000000..66b46f085
--- /dev/null
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/MultiPlayerCampaign.cs
@@ -0,0 +1,166 @@
+using Barotrauma.Networking;
+using Lidgren.Network;
+using Microsoft.Xna.Framework;
+using System;
+using System.Collections.Generic;
+
+namespace Barotrauma
+{
+ partial class MultiPlayerCampaign : CampaignMode
+ {
+ public static GUIComponent StartCampaignSetup()
+ {
+ GUIFrame background = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f, null);
+
+ GUIFrame setupBox = new GUIFrame(new Rectangle(0, 0, 500, 500), null, Alignment.Center, "", background);
+ setupBox.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
+ new GUITextBlock(new Rectangle(0, 0, 10, 10), "Campaign Setup", "", setupBox, GUI.LargeFont);
+ setupBox.Padding = new Vector4(20.0f, 80.0f, 20.0f, 20.0f);
+
+ var newCampaignContainer = new GUIFrame(new Rectangle(0, 40, 0, 0), null, setupBox);
+ var loadCampaignContainer = new GUIFrame(new Rectangle(0, 40, 0, 0), null, setupBox);
+
+ var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer);
+
+ var newCampaignButton = new GUIButton(new Rectangle(0, 0, 120, 20), "New campaign", "", setupBox);
+ newCampaignButton.OnClicked += (btn, obj) =>
+ {
+ newCampaignContainer.Visible = true;
+ loadCampaignContainer.Visible = false;
+ return true;
+ };
+
+ var loadCampaignButton = new GUIButton(new Rectangle(130, 0, 120, 20), "Load campaign", "", setupBox);
+ loadCampaignButton.OnClicked += (btn, obj) =>
+ {
+ newCampaignContainer.Visible = false;
+ loadCampaignContainer.Visible = true;
+ return true;
+ };
+
+ loadCampaignContainer.Visible = false;
+
+ campaignSetupUI.StartNewGame = (Submarine sub, string saveName, string mapSeed) =>
+ {
+ GameMain.GameSession = new GameSession(new Submarine(sub.FilePath, ""), saveName, GameModePreset.list.Find(g => g.Name == "Campaign"));
+ var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
+ campaign.GenerateMap(mapSeed);
+ campaign.SetDelegates();
+
+ background.Visible = false;
+
+ GameMain.NetLobbyScreen.ToggleCampaignMode(true);
+ campaign.Map.SelectRandomLocation(true);
+ SaveUtil.SaveGame(GameMain.GameSession.SavePath);
+ campaign.LastSaveID++;
+ };
+
+ campaignSetupUI.LoadGame = (string fileName) =>
+ {
+ SaveUtil.LoadGame(fileName);
+ var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
+ campaign.LastSaveID++;
+
+ background.Visible = false;
+
+ GameMain.NetLobbyScreen.ToggleCampaignMode(true);
+ campaign.Map.SelectRandomLocation(true);
+ };
+
+ var cancelButton = new GUIButton(new Rectangle(0, 0, 120, 30), "Cancel", Alignment.BottomLeft, "", setupBox);
+ cancelButton.OnClicked += (btn, obj) =>
+ {
+ background.Visible = false;
+ int otherModeIndex = 0;
+ for (otherModeIndex = 0; otherModeIndex < GameMain.NetLobbyScreen.ModeList.children.Count; otherModeIndex++)
+ {
+ if (GameMain.NetLobbyScreen.ModeList.children[otherModeIndex].UserData is MultiPlayerCampaign) continue;
+ break;
+ }
+
+ GameMain.NetLobbyScreen.SelectMode(otherModeIndex);
+ return true;
+ };
+
+ return background;
+ }
+
+ public void ClientWrite(NetBuffer msg)
+ {
+ System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue);
+
+ msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex);
+
+ msg.Write((UInt16)CargoManager.PurchasedItems.Count);
+ foreach (ItemPrefab ip in CargoManager.PurchasedItems)
+ {
+ msg.Write((UInt16)MapEntityPrefab.List.IndexOf(ip));
+ }
+ }
+
+ //static because we may need to instantiate the campaign if it hasn't been done yet
+ public static void ClientRead(NetBuffer msg)
+ {
+ byte campaignID = msg.ReadByte();
+ UInt16 updateID = msg.ReadUInt16();
+ UInt16 saveID = msg.ReadUInt16();
+ string mapSeed = msg.ReadString();
+ UInt16 currentLocIndex = msg.ReadUInt16();
+ UInt16 selectedLocIndex = msg.ReadUInt16();
+
+ int money = msg.ReadInt32();
+
+ UInt16 purchasedItemCount = msg.ReadUInt16();
+ List purchasedItems = new List();
+ for (int i = 0; i < purchasedItemCount; i++)
+ {
+ UInt16 itemPrefabIndex = msg.ReadUInt16();
+ purchasedItems.Add(MapEntityPrefab.List[itemPrefabIndex] as ItemPrefab);
+ }
+
+ MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
+ if (campaign == null || campaignID != campaign.CampaignID)
+ {
+ string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer);
+
+ GameMain.GameSession = new GameSession(null, savePath, GameModePreset.list.Find(g => g.Name == "Campaign"));
+
+ campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
+ campaign.CampaignID = campaignID;
+ campaign.GenerateMap(mapSeed);
+ }
+
+ GameMain.NetLobbyScreen.ToggleCampaignMode(true);
+ if (NetIdUtils.IdMoreRecent(campaign.lastUpdateID, updateID)) return;
+
+ //server has a newer save file
+ if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID))
+ {
+ /*//stop any active campaign save transfers, they're outdated now
+ List saveTransfers =
+ GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave);
+
+ foreach (var transfer in saveTransfers)
+ {
+ GameMain.Client.FileReceiver.StopTransfer(transfer);
+ }
+
+ GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/
+ campaign.PendingSaveID = saveID;
+ }
+ //we've got the latest save file
+ else if (!NetIdUtils.IdMoreRecent(saveID, campaign.lastSaveID))
+ {
+ campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex);
+ campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
+
+ campaign.Money = money;
+ campaign.CargoManager.SetPurchasedItems(purchasedItems);
+
+ campaign.lastUpdateID = updateID;
+ }
+ }
+ }
+
+
+}
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
index ea2f467ca..79174cdae 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
@@ -722,8 +722,8 @@ namespace Barotrauma.Networking
inc.ReadPadBits();
GameModePreset gameMode = GameModePreset.list.Find(gm => gm.Name == modeName);
- MultiplayerCampaign campaign = GameMain.NetLobbyScreen.SelectedMode == GameMain.GameSession?.GameMode.Preset ?
- GameMain.GameSession?.GameMode as MultiplayerCampaign : null;
+ MultiPlayerCampaign campaign = GameMain.NetLobbyScreen.SelectedMode == GameMain.GameSession?.GameMode.Preset ?
+ GameMain.GameSession?.GameMode as MultiPlayerCampaign : null;
if (gameMode == null)
{
@@ -955,7 +955,7 @@ namespace Barotrauma.Networking
inc.ReadPadBits();
if (campaignUpdated)
{
- MultiplayerCampaign.ClientRead(inc);
+ MultiPlayerCampaign.ClientRead(inc);
}
lastSentChatMsgID = inc.ReadUInt16();
@@ -1065,7 +1065,7 @@ namespace Barotrauma.Networking
outmsg.Write(GameMain.NetLobbyScreen.LastUpdateID);
outmsg.Write(ChatMessage.LastID);
- var campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
+ var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
if (campaign == null || campaign.LastSaveID == 0)
{
outmsg.Write((UInt16)0);
@@ -1228,7 +1228,7 @@ namespace Barotrauma.Networking
break;
case FileTransferType.CampaignSave:
- var campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
+ var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
if (campaign == null) return;
GameMain.GameSession.SavePath = transfer.FilePath;
@@ -1446,7 +1446,7 @@ namespace Barotrauma.Networking
public void SendCampaignState()
{
- MultiplayerCampaign campaign = GameMain.GameSession.GameMode as MultiplayerCampaign;
+ MultiPlayerCampaign campaign = GameMain.GameSession.GameMode as MultiPlayerCampaign;
if (campaign == null)
{
DebugConsole.ThrowError("Failed send campaign state to the server (no campaign active).\n" + Environment.StackTrace);
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
index b15d94a3b..e7ab7c100 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
@@ -57,6 +57,7 @@ namespace Barotrauma
private GUITickBox shuttleTickBox;
private CampaignUI campaignUI;
+ private GUIComponent campaignSetupUI;
private Sprite backgroundSprite;
@@ -1111,7 +1112,11 @@ namespace Barotrauma
{
base.AddToGUIUpdateList();
- if (jobInfoFrame != null)
+ if (campaignSetupUI != null)
+ {
+ campaignSetupUI.AddToGUIUpdateList();
+ }
+ else if (jobInfoFrame != null)
{
jobInfoFrame.AddToGUIUpdateList();
}
@@ -1155,10 +1160,21 @@ namespace Barotrauma
if (campaignContainer.Visible && campaignUI != null)
{
- //campaignContainer.Update((float)deltaTime);
campaignUI.Update((float)deltaTime);
}
+ if (campaignSetupUI != null)
+ {
+ if (!campaignSetupUI.Visible)
+ {
+ campaignSetupUI = null;
+ }
+ else
+ {
+ campaignSetupUI.Update((float)deltaTime);
+ }
+ }
+
if (autoRestartTimer != 0.0f && autoRestartBox.Selected)
{
autoRestartTimer = Math.Max(autoRestartTimer - (float)deltaTime, 0.0f);
@@ -1186,6 +1202,11 @@ namespace Barotrauma
campaignUI.Draw(spriteBatch);
}
+ if (campaignSetupUI != null)
+ {
+ campaignSetupUI.Draw(spriteBatch);
+ }
+
if (playerFrame != null) playerFrame.Draw(spriteBatch);
GUI.Draw((float)deltaTime, spriteBatch, null);
@@ -1254,7 +1275,7 @@ namespace Barotrauma
{
if (GameMain.Server != null)
{
- MultiplayerCampaign.StartCampaignSetup();
+ campaignSetupUI = MultiPlayerCampaign.StartCampaignSetup();
return;
}
}
@@ -1282,7 +1303,7 @@ namespace Barotrauma
// -> don't select the mode yet and start campaign setup
if (GameMain.Server != null && !campaignContainer.Visible)
{
- MultiplayerCampaign.StartCampaignSetup();
+ campaignSetupUI = MultiPlayerCampaign.StartCampaignSetup();
return false;
}
}
diff --git a/Barotrauma/BarotraumaServer/BarotraumaServer.csproj b/Barotrauma/BarotraumaServer/BarotraumaServer.csproj
index 02a4df579..5c5731d47 100644
--- a/Barotrauma/BarotraumaServer/BarotraumaServer.csproj
+++ b/Barotrauma/BarotraumaServer/BarotraumaServer.csproj
@@ -83,6 +83,7 @@
+
@@ -138,9 +139,7 @@
-
-
-
+