- Autorestart works in campaign mode.
- The server select a random destination when the campaign starts and after each round, so the campaign can be played even if there's no host/client to choose the destinations. (TODO: make it possible to vote for the destination?) - Reverting to the previous save if the entire crew is dead works correctly now. - Clients load the campaign saves after receiving them (-> discovered locations/connections are synced with clients).
This commit is contained in:
@@ -73,7 +73,8 @@ namespace Barotrauma
|
||||
|
||||
setupBox.Close();
|
||||
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
campaign.Map.SelectRandomLocation(true);
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
campaign.LastSaveID++;
|
||||
};
|
||||
@@ -86,7 +87,8 @@ namespace Barotrauma
|
||||
|
||||
setupBox.Close();
|
||||
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
campaign.Map.SelectRandomLocation(true);
|
||||
};
|
||||
|
||||
var cancelButton = new GUIButton(new Rectangle(0,0,120,30), "Cancel", Alignment.BottomLeft, "", setupBox.InnerFrame);
|
||||
@@ -123,6 +125,7 @@ namespace Barotrauma
|
||||
campaign.SetDelegates();
|
||||
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
GameMain.GameSession.Map.SelectRandomLocation(true);
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
campaign.LastSaveID++;
|
||||
|
||||
@@ -145,6 +148,7 @@ namespace Barotrauma
|
||||
SaveUtil.LoadGame(saveFiles[saveIndex]);
|
||||
((MultiplayerCampaign)GameMain.GameSession.GameMode).LastSaveID++;
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
GameMain.GameSession.Map.SelectRandomLocation(true);
|
||||
|
||||
DebugConsole.NewMessage("Campaign loaded!", Color.Cyan);
|
||||
});
|
||||
@@ -179,118 +183,103 @@ namespace Barotrauma
|
||||
{
|
||||
isRunning = false;
|
||||
|
||||
if (GameMain.Server != null)
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
lastUpdateID++;
|
||||
GameMain.GameSession.EndRound("");
|
||||
return;
|
||||
}
|
||||
|
||||
lastUpdateID++;
|
||||
|
||||
bool success =
|
||||
GameMain.Server.ConnectedClients.Any(c => c.inGame && c.Character != null && !c.Character.IsDead) ||
|
||||
(GameMain.Server.Character != null && !GameMain.Server.Character.IsDead);
|
||||
bool success =
|
||||
GameMain.Server.ConnectedClients.Any(c => c.inGame && c.Character != null && !c.Character.IsDead) ||
|
||||
(GameMain.Server.Character != null && !GameMain.Server.Character.IsDead);
|
||||
|
||||
/*if (success)
|
||||
/*if (success)
|
||||
{
|
||||
if (subsToLeaveBehind == null || leavingSub == null)
|
||||
{
|
||||
if (subsToLeaveBehind == null || leavingSub == null)
|
||||
DebugConsole.ThrowError("Leaving submarine not selected -> selecting the closest one");
|
||||
|
||||
leavingSub = GetLeavingSub();
|
||||
|
||||
subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub);
|
||||
}
|
||||
}*/
|
||||
|
||||
GameMain.GameSession.EndRound("");
|
||||
|
||||
//TODO: save player inventories between mp campaign rounds
|
||||
|
||||
//remove all items that are in someone's inventory
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.Inventory == null) continue;
|
||||
foreach (Item item in c.Inventory.Items)
|
||||
{
|
||||
if (item != null) item.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
bool atEndPosition = Submarine.MainSub.AtEndPosition;
|
||||
|
||||
/*if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
|
||||
{
|
||||
Submarine.MainSub = leavingSub;
|
||||
|
||||
GameMain.GameSession.Submarine = leavingSub;
|
||||
|
||||
foreach (Submarine sub in subsToLeaveBehind)
|
||||
{
|
||||
DebugConsole.ThrowError("Leaving submarine not selected -> selecting the closest one");
|
||||
|
||||
leavingSub = GetLeavingSub();
|
||||
|
||||
subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub);
|
||||
MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine);
|
||||
LinkedSubmarine.CreateDummy(leavingSub, sub);
|
||||
}
|
||||
}*/
|
||||
|
||||
GameMain.GameSession.EndRound("");
|
||||
|
||||
//TODO: save player inventories between mp campaign rounds
|
||||
|
||||
//remove all items that are in someone's inventory
|
||||
foreach (Character c in Character.CharacterList)
|
||||
if (atEndPosition)
|
||||
{
|
||||
if (c.Inventory == null) continue;
|
||||
foreach (Item item in c.Inventory.Items)
|
||||
{
|
||||
if (item != null) item.Remove();
|
||||
}
|
||||
Map.MoveToNextLocation();
|
||||
|
||||
//select a random location to make sure we've got some destination
|
||||
//to head towards even if the host/clients don't select anything
|
||||
map.SelectRandomLocation(true);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
bool atEndPosition = Submarine.MainSub.AtEndPosition;
|
||||
|
||||
/*if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
|
||||
{
|
||||
Submarine.MainSub = leavingSub;
|
||||
|
||||
GameMain.GameSession.Submarine = leavingSub;
|
||||
|
||||
foreach (Submarine sub in subsToLeaveBehind)
|
||||
{
|
||||
MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine);
|
||||
LinkedSubmarine.CreateDummy(leavingSub, sub);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (atEndPosition)
|
||||
{
|
||||
Map.MoveToNextLocation();
|
||||
}
|
||||
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
#if CLIENT
|
||||
var summaryScreen = GUIMessageBox.VisibleBox;
|
||||
if (summaryScreen != null)
|
||||
{
|
||||
summaryScreen = summaryScreen.children[0];
|
||||
summaryScreen.RemoveChild(summaryScreen.children.Find(c => c is GUIButton));
|
||||
|
||||
var okButton = new GUIButton(new Rectangle(-120, 0, 100, 30), "Load game", Alignment.BottomRight, "", summaryScreen);
|
||||
okButton.OnClicked += GameMain.GameSession.LoadPrevious;
|
||||
okButton.OnClicked += (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return true; };
|
||||
|
||||
var quitButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Quit", Alignment.BottomRight, "", summaryScreen);
|
||||
quitButton.OnClicked += GameMain.LobbyScreen.QuitToMainMenu;
|
||||
quitButton.OnClicked += (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return true; };
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.GameSession.EndRound("");
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
}
|
||||
}
|
||||
|
||||
public static MultiplayerCampaign Load(XElement element)
|
||||
public static MultiplayerCampaign LoadNew(XElement element)
|
||||
{
|
||||
MultiplayerCampaign campaign = new MultiplayerCampaign(GameModePreset.list.Find(gm => gm.Name == "Campaign"), null);
|
||||
campaign.Load(element);
|
||||
campaign.SetDelegates();
|
||||
|
||||
return campaign;
|
||||
}
|
||||
|
||||
public void Load(XElement element)
|
||||
{
|
||||
Money = ToolBox.GetAttributeInt(element, "money", 0);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "map":
|
||||
campaign.map = Map.Load(subElement);
|
||||
if (map == null)
|
||||
{
|
||||
map = Map.LoadNew(subElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
map.Load(subElement);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
campaign.Money = ToolBox.GetAttributeInt(element, "money", 0);
|
||||
|
||||
//backwards compatibility with older save files
|
||||
if (campaign.map == null)
|
||||
{
|
||||
string mapSeed = ToolBox.GetAttributeString(element, "mapseed", "a");
|
||||
campaign.GenerateMap(mapSeed);
|
||||
campaign.map.SetLocation(ToolBox.GetAttributeInt(element, "currentlocation", 0));
|
||||
}
|
||||
|
||||
campaign.SetDelegates();
|
||||
|
||||
return campaign;
|
||||
}
|
||||
|
||||
public override void Save(XElement element)
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Barotrauma
|
||||
|
||||
public readonly EventManager EventManager;
|
||||
|
||||
public readonly GameMode GameMode;
|
||||
public GameMode GameMode;
|
||||
|
||||
//two locations used as the start and end in the MP mode
|
||||
private Location[] dummyLocations;
|
||||
@@ -51,19 +51,19 @@ namespace Barotrauma
|
||||
|
||||
public Location StartLocation
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
if (Map != null) return Map.CurrentLocation;
|
||||
|
||||
if (dummyLocations==null)
|
||||
if (dummyLocations == null)
|
||||
{
|
||||
CreateDummyLocations();
|
||||
}
|
||||
|
||||
return dummyLocations[0];
|
||||
return dummyLocations[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Location EndLocation
|
||||
{
|
||||
get
|
||||
@@ -118,12 +118,11 @@ namespace Barotrauma
|
||||
Submarine.MainSub = submarine;
|
||||
|
||||
GameMain.GameSession = this;
|
||||
|
||||
selectedSub.Name = ToolBox.GetAttributeString(doc.Root, "submarine", selectedSub.Name);
|
||||
|
||||
#if CLIENT
|
||||
CrewManager = new CrewManager();
|
||||
#endif
|
||||
|
||||
foreach (XElement subElement in doc.Root.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -135,11 +134,10 @@ namespace Barotrauma
|
||||
break;
|
||||
#endif
|
||||
case "multiplayercampaign":
|
||||
GameMode = MultiplayerCampaign.Load(subElement);
|
||||
GameMode = MultiplayerCampaign.LoadNew(subElement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void CreateDummyLocations()
|
||||
@@ -162,6 +160,12 @@ namespace Barotrauma
|
||||
dummyLocations[i] = Location.CreateRandom(new Vector2((float)rand.NextDouble() * 10000.0f, (float)rand.NextDouble() * 10000.0f));
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadPrevious()
|
||||
{
|
||||
Submarine.Unload();
|
||||
SaveUtil.LoadGame(savePath);
|
||||
}
|
||||
|
||||
public void StartRound(string levelSeed, bool loadSecondSub = false)
|
||||
{
|
||||
@@ -297,5 +301,31 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(XElement saveElement)
|
||||
{
|
||||
foreach (XElement subElement in saveElement.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
#if CLIENT
|
||||
case "gamemode": //legacy support
|
||||
case "singleplayercampaign":
|
||||
GameMode = SinglePlayerCampaign.Load(subElement);
|
||||
break;
|
||||
#endif
|
||||
case "multiplayercampaign":
|
||||
MultiplayerCampaign mpCampaign = GameMode as MultiplayerCampaign;
|
||||
if (mpCampaign == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while loading a save file: the save file is for a multiplayer campaign but the current gamemode is "+GameMode.GetType().ToString());
|
||||
break;
|
||||
}
|
||||
|
||||
mpCampaign.Load(subElement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user