Progress on multiplayer campaign:
- Moved SaveUtils to the shared project. - Moved the "new game"/"load game" menu logic to a separate class. - Somewhat functional campaign UI in the server lobby (only the map view is usable atm though).
This commit is contained in:
@@ -196,6 +196,7 @@
|
|||||||
<Compile Include="Source\PlayerInput.cs" />
|
<Compile Include="Source\PlayerInput.cs" />
|
||||||
<Compile Include="Source\Program.cs" />
|
<Compile Include="Source\Program.cs" />
|
||||||
<Compile Include="Source\Screens\BlurEffect.cs" />
|
<Compile Include="Source\Screens\BlurEffect.cs" />
|
||||||
|
<Compile Include="Source\Screens\CampaignSetupUI.cs" />
|
||||||
<Compile Include="Source\Screens\CampaignUI.cs" />
|
<Compile Include="Source\Screens\CampaignUI.cs" />
|
||||||
<Compile Include="Source\Screens\EditCharacterScreen.cs" />
|
<Compile Include="Source\Screens\EditCharacterScreen.cs" />
|
||||||
<Compile Include="Source\Screens\EditMapScreen.cs" />
|
<Compile Include="Source\Screens\EditMapScreen.cs" />
|
||||||
|
|||||||
@@ -525,9 +525,19 @@ namespace Barotrauma
|
|||||||
if (children.Contains(child)) children.Remove(child);
|
if (children.Contains(child)) children.Remove(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUIComponent FindChild(object userData)
|
public GUIComponent FindChild(object userData, bool recursive = false)
|
||||||
{
|
{
|
||||||
return children.FirstOrDefault(c => c.userData == userData);
|
var matchingChild = children.FirstOrDefault(c => c.userData == userData);
|
||||||
|
if (recursive && matchingChild == null)
|
||||||
|
{
|
||||||
|
foreach (GUIComponent child in children)
|
||||||
|
{
|
||||||
|
matchingChild = child.FindChild(userData, recursive);
|
||||||
|
if (matchingChild != null) return matchingChild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchingChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GUIComponent> FindChildren(object userData)
|
public List<GUIComponent> FindChildren(object userData)
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ namespace Barotrauma
|
|||||||
get { return MessageBoxes.Count == 0 ? null : MessageBoxes[0]; }
|
get { return MessageBoxes.Count == 0 ? null : MessageBoxes[0]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GUIFrame InnerFrame
|
||||||
|
{
|
||||||
|
get { return children[0] as GUIFrame; }
|
||||||
|
}
|
||||||
|
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
get { return (children[0].children[1] as GUITextBlock).Text; }
|
get { return (children[0].children[1] as GUITextBlock).Text; }
|
||||||
@@ -78,12 +83,15 @@ namespace Barotrauma
|
|||||||
MessageBoxes.Add(this);
|
MessageBoxes.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
|
||||||
public bool Close(GUIButton button, object obj)
|
|
||||||
{
|
{
|
||||||
if (parent != null) parent.RemoveChild(this);
|
if (parent != null) parent.RemoveChild(this);
|
||||||
if (MessageBoxes.Contains(this)) MessageBoxes.Remove(this);
|
if (MessageBoxes.Contains(this)) MessageBoxes.Remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Close(GUIButton button, object obj)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public override void Save(XElement element)
|
public override void Save(XElement element)
|
||||||
{
|
{
|
||||||
XElement modeElement = new XElement("gamemode");
|
XElement modeElement = new XElement("SinglePlayerCampaign");
|
||||||
|
|
||||||
modeElement.Add(new XAttribute("money", Money));
|
modeElement.Add(new XAttribute("money", Money));
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
SinglePlayerCampaign mode = (GameMode as SinglePlayerCampaign);
|
CampaignMode mode = (GameMode as CampaignMode);
|
||||||
return (mode == null) ? null : mode.Map;
|
return (mode == null) ? null : mode.Map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,32 +168,5 @@ namespace Barotrauma
|
|||||||
if (GameMode != null) GameMode.Draw(spriteBatch);
|
if (GameMode != null) GameMode.Draw(spriteBatch);
|
||||||
if (infoFrame != null) infoFrame.Draw(spriteBatch);
|
if (infoFrame != null) infoFrame.Draw(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(string filePath)
|
|
||||||
{
|
|
||||||
if (!(GameMode is CampaignMode))
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("GameSessions can only be saved when playing in a campaign mode.");
|
|
||||||
}
|
|
||||||
|
|
||||||
XDocument doc = new XDocument(
|
|
||||||
new XElement("Gamesession"));
|
|
||||||
|
|
||||||
var now = DateTime.Now;
|
|
||||||
doc.Root.Add(new XAttribute("savetime", now.ToShortTimeString() + ", " + now.ToShortDateString()));
|
|
||||||
doc.Root.Add(new XAttribute("submarine", submarine == null ? "" : submarine.Name));
|
|
||||||
doc.Root.Add(new XAttribute("mapseed", Map.Seed));
|
|
||||||
|
|
||||||
((CampaignMode)GameMode).Save(doc.Root);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
doc.Save(filePath);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Saving gamesession to \"" + filePath + "\" failed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -68,6 +66,9 @@ namespace Barotrauma
|
|||||||
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
|
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
|
||||||
Vector2 offset = -currentLocation.MapPosition;
|
Vector2 offset = -currentLocation.MapPosition;
|
||||||
|
|
||||||
|
Rectangle prevScissorRect = GameMain.Instance.GraphicsDevice.ScissorRectangle;
|
||||||
|
GameMain.Instance.GraphicsDevice.ScissorRectangle = rect;
|
||||||
|
|
||||||
iceTexture.DrawTiled(spriteBatch, new Vector2(rect.X, rect.Y), new Vector2(rect.Width, rect.Height), Vector2.Zero, Color.White * 0.8f);
|
iceTexture.DrawTiled(spriteBatch, new Vector2(rect.X, rect.Y), new Vector2(rect.Width, rect.Height), Vector2.Zero, Color.White * 0.8f);
|
||||||
|
|
||||||
foreach (LocationConnection connection in connections)
|
foreach (LocationConnection connection in connections)
|
||||||
@@ -197,31 +198,8 @@ namespace Barotrauma
|
|||||||
GUI.DrawString(spriteBatch, pos, location.Name, Color.White, Color.Black * 0.8f, 3);
|
GUI.DrawString(spriteBatch, pos, location.Name, Color.White, Color.Black * 0.8f, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save(XElement element)
|
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
||||||
{
|
|
||||||
XElement mapElement = new XElement("map");
|
|
||||||
|
|
||||||
mapElement.Add(new XAttribute("currentlocation", CurrentLocationIndex));
|
|
||||||
mapElement.Add(new XAttribute("seed", Seed));
|
|
||||||
mapElement.Add(new XAttribute("size", size));
|
|
||||||
|
|
||||||
List<int> discoveredLocations = new List<int>();
|
|
||||||
for (int i = 0; i < locations.Count; i++)
|
|
||||||
{
|
|
||||||
if (locations[i].Discovered) discoveredLocations.Add(i);
|
|
||||||
}
|
|
||||||
mapElement.Add(new XAttribute("discovered", string.Join(",", discoveredLocations)));
|
|
||||||
|
|
||||||
List<int> passedConnections = new List<int>();
|
|
||||||
for (int i = 0; i < connections.Count; i++)
|
|
||||||
{
|
|
||||||
if (connections[i].Passed) passedConnections.Add(i);
|
|
||||||
}
|
|
||||||
mapElement.Add(new XAttribute("passed", string.Join(",", passedConnections)));
|
|
||||||
|
|
||||||
element.Add(mapElement);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
|||||||
if (value == allowSubVoting) return;
|
if (value == allowSubVoting) return;
|
||||||
allowSubVoting = value;
|
allowSubVoting = value;
|
||||||
GameMain.NetLobbyScreen.SubList.Enabled = value || GameMain.Server != null;
|
GameMain.NetLobbyScreen.SubList.Enabled = value || GameMain.Server != null;
|
||||||
GameMain.NetLobbyScreen.InfoFrame.FindChild("subvotes").Visible = value;
|
GameMain.NetLobbyScreen.InfoFrame.FindChild("subvotes", true).Visible = value;
|
||||||
|
|
||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
@@ -36,7 +36,7 @@ namespace Barotrauma
|
|||||||
if (value == allowModeVoting) return;
|
if (value == allowModeVoting) return;
|
||||||
allowModeVoting = value;
|
allowModeVoting = value;
|
||||||
GameMain.NetLobbyScreen.ModeList.Enabled = value || GameMain.Server != null;
|
GameMain.NetLobbyScreen.ModeList.Enabled = value || GameMain.Server != null;
|
||||||
GameMain.NetLobbyScreen.InfoFrame.FindChild("modevotes").Visible = value;
|
GameMain.NetLobbyScreen.InfoFrame.FindChild("modevotes", true).Visible = value;
|
||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
UpdateVoteTexts(GameMain.Server.ConnectedClients, VoteType.Mode);
|
UpdateVoteTexts(GameMain.Server.ConnectedClients, VoteType.Mode);
|
||||||
|
|||||||
@@ -0,0 +1,210 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
class CampaignSetupUI
|
||||||
|
{
|
||||||
|
private GUIComponent newGameContainer, loadGameContainer;
|
||||||
|
|
||||||
|
private GUIListBox subList;
|
||||||
|
private GUIListBox saveList;
|
||||||
|
|
||||||
|
private GUITextBox saveNameBox, seedBox;
|
||||||
|
|
||||||
|
public Action<Submarine, string, string> StartNewGame;
|
||||||
|
public Action<string> LoadGame;
|
||||||
|
|
||||||
|
private bool isMultiplayer;
|
||||||
|
|
||||||
|
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer)
|
||||||
|
{
|
||||||
|
this.isMultiplayer = isMultiplayer;
|
||||||
|
this.newGameContainer = newGameContainer;
|
||||||
|
this.loadGameContainer = loadGameContainer;
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Selected submarine:", null, null, Alignment.Left, "", newGameContainer);
|
||||||
|
subList = new GUIListBox(new Rectangle(0, 30, 230, newGameContainer.Rect.Height - 100), "", newGameContainer);
|
||||||
|
|
||||||
|
UpdateSubList();
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 0, 100, 20),
|
||||||
|
"Save name: ", "", Alignment.Left, Alignment.Left, newGameContainer);
|
||||||
|
|
||||||
|
saveNameBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 30, 180, 20),
|
||||||
|
Alignment.TopLeft, "", newGameContainer);
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 60, 100, 20),
|
||||||
|
"Map Seed: ", "", Alignment.Left, Alignment.Left, newGameContainer);
|
||||||
|
|
||||||
|
seedBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 90, 180, 20),
|
||||||
|
Alignment.TopLeft, "", newGameContainer);
|
||||||
|
seedBox.Text = ToolBox.RandomSeed(8);
|
||||||
|
|
||||||
|
var startButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, "", newGameContainer);
|
||||||
|
startButton.OnClicked = (GUIButton btn, object userData) =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(saveNameBox.Text))
|
||||||
|
{
|
||||||
|
saveNameBox.Flash(Color.Red);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Submarine selectedSub = subList.SelectedData as Submarine;
|
||||||
|
if (selectedSub != null && selectedSub.HasTag(SubmarineTag.Shuttle))
|
||||||
|
{
|
||||||
|
var msgBox = new GUIMessageBox("Shuttle selected",
|
||||||
|
"Most shuttles are not adequately equipped to deal with the dangers of the Europan depths. " +
|
||||||
|
"Are you sure you want to choose a shuttle as your vessel?",
|
||||||
|
new string[] { "Yes", "No" });
|
||||||
|
|
||||||
|
msgBox.Buttons[0].OnClicked = (button, obj) => { StartNewGame?.Invoke(selectedSub, saveNameBox.Text, seedBox.Text); return true; };
|
||||||
|
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||||
|
|
||||||
|
msgBox.Buttons[1].OnClicked = msgBox.Close;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartNewGame?.Invoke(selectedSub, saveNameBox.Text, seedBox.Text);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdateLoadMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateDefaultSaveName()
|
||||||
|
{
|
||||||
|
saveNameBox.Text = SaveUtil.CreateSavePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSubList()
|
||||||
|
{
|
||||||
|
var subsToShow = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
|
||||||
|
|
||||||
|
subList.ClearChildren();
|
||||||
|
|
||||||
|
foreach (Submarine sub in subsToShow)
|
||||||
|
{
|
||||||
|
var textBlock = new GUITextBlock(
|
||||||
|
new Rectangle(0, 0, 0, 25),
|
||||||
|
ToolBox.LimitString(sub.Name, GUI.Font, subList.Rect.Width - 65), "ListBoxElement",
|
||||||
|
Alignment.Left, Alignment.Left, subList)
|
||||||
|
{
|
||||||
|
Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f),
|
||||||
|
ToolTip = sub.Description,
|
||||||
|
UserData = sub
|
||||||
|
};
|
||||||
|
|
||||||
|
if (sub.HasTag(SubmarineTag.Shuttle))
|
||||||
|
{
|
||||||
|
textBlock.TextColor = textBlock.TextColor * 0.85f;
|
||||||
|
|
||||||
|
var shuttleText = new GUITextBlock(new Rectangle(0, 0, 0, 25), "Shuttle", "", Alignment.Left, Alignment.CenterY | Alignment.Right, textBlock, false, GUI.SmallFont);
|
||||||
|
shuttleText.TextColor = textBlock.TextColor * 0.8f;
|
||||||
|
shuttleText.ToolTip = textBlock.ToolTip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Submarine.SavedSubmarines.Count > 0) subList.Select(Submarine.SavedSubmarines[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateLoadMenu()
|
||||||
|
{
|
||||||
|
loadGameContainer.ClearChildren();
|
||||||
|
|
||||||
|
string[] saveFiles = SaveUtil.GetSaveFiles(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer);
|
||||||
|
|
||||||
|
saveList = new GUIListBox(new Rectangle(0, 0, 200, loadGameContainer.Rect.Height - 80), Color.White, "", loadGameContainer);
|
||||||
|
saveList.OnSelected = SelectSaveFile;
|
||||||
|
|
||||||
|
foreach (string saveFile in saveFiles)
|
||||||
|
{
|
||||||
|
GUITextBlock textBlock = new GUITextBlock(
|
||||||
|
new Rectangle(0, 0, 0, 25),
|
||||||
|
Path.GetFileNameWithoutExtension(saveFile),
|
||||||
|
"ListBoxElement",
|
||||||
|
Alignment.Left,
|
||||||
|
Alignment.Left,
|
||||||
|
saveList);
|
||||||
|
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
textBlock.UserData = saveFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
var button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.Right | Alignment.Bottom, "", loadGameContainer);
|
||||||
|
button.OnClicked = (btn, obj) => { LoadGame?.Invoke(saveList.SelectedData as string); return true; };
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool SelectSaveFile(GUIComponent component, object obj)
|
||||||
|
{
|
||||||
|
string fileName = (string)obj;
|
||||||
|
|
||||||
|
XDocument doc = SaveUtil.LoadGameSessionDoc(fileName);
|
||||||
|
|
||||||
|
if (doc == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error loading save file \"" + fileName + "\". The file may be corrupted.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveSaveFrame();
|
||||||
|
|
||||||
|
string subName = ToolBox.GetAttributeString(doc.Root, "submarine", "");
|
||||||
|
string saveTime = ToolBox.GetAttributeString(doc.Root, "savetime", "unknown");
|
||||||
|
string mapseed = ToolBox.GetAttributeString(doc.Root, "mapseed", "unknown");
|
||||||
|
|
||||||
|
GUIFrame saveFileFrame = new GUIFrame(new Rectangle((int)(saveList.Rect.Width + 20), 0, 200, 230), Color.Black * 0.4f, "", loadGameContainer);
|
||||||
|
saveFileFrame.UserData = "savefileframe";
|
||||||
|
saveFileFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 0, 0, 20), Path.GetFileNameWithoutExtension(fileName), "", Alignment.TopLeft, Alignment.TopLeft, saveFileFrame, false, GUI.LargeFont);
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 35, 0, 20), "Submarine: ", "", saveFileFrame).Font = GUI.SmallFont;
|
||||||
|
new GUITextBlock(new Rectangle(15, 52, 0, 20), subName, "", saveFileFrame).Font = GUI.SmallFont;
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 70, 0, 20), "Last saved: ", "", saveFileFrame).Font = GUI.SmallFont;
|
||||||
|
new GUITextBlock(new Rectangle(15, 85, 0, 20), saveTime, "", saveFileFrame).Font = GUI.SmallFont;
|
||||||
|
|
||||||
|
new GUITextBlock(new Rectangle(0, 105, 0, 20), "Map seed: ", "", saveFileFrame).Font = GUI.SmallFont;
|
||||||
|
new GUITextBlock(new Rectangle(15, 120, 0, 20), mapseed, "", saveFileFrame).Font = GUI.SmallFont;
|
||||||
|
|
||||||
|
var deleteSaveButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Delete", Alignment.BottomCenter, "", saveFileFrame);
|
||||||
|
deleteSaveButton.UserData = fileName;
|
||||||
|
deleteSaveButton.OnClicked = DeleteSave;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DeleteSave(GUIButton button, object obj)
|
||||||
|
{
|
||||||
|
string saveFile = obj as string;
|
||||||
|
|
||||||
|
if (obj == null) return false;
|
||||||
|
|
||||||
|
SaveUtil.DeleteSave(saveFile);
|
||||||
|
|
||||||
|
UpdateLoadMenu();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveSaveFrame()
|
||||||
|
{
|
||||||
|
GUIComponent prevFrame = null;
|
||||||
|
foreach (GUIComponent child in loadGameContainer.children)
|
||||||
|
{
|
||||||
|
if (child.UserData as string != "savefileframe") continue;
|
||||||
|
|
||||||
|
prevFrame = child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
loadGameContainer.RemoveChild(prevFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Level selectedLevel;
|
private Level selectedLevel;
|
||||||
|
|
||||||
float mapZoom = 3.0f;
|
private float mapZoom = 3.0f;
|
||||||
|
|
||||||
public Action StartRound;
|
public Action StartRound;
|
||||||
public Action<Location, LocationConnection> OnLocationSelected;
|
public Action<Location, LocationConnection> OnLocationSelected;
|
||||||
@@ -126,12 +126,11 @@ namespace Barotrauma
|
|||||||
x += 110;
|
x += 110;
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectTab(Tab.Crew);
|
SelectTab(Tab.Map);
|
||||||
|
|
||||||
GameMain.GameSession.Map.OnLocationSelected += SelectLocation;
|
GameMain.GameSession.Map.OnLocationSelected += SelectLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void UpdateLocationTab(Location location)
|
private void UpdateLocationTab(Location location)
|
||||||
{
|
{
|
||||||
if (location.HireManager == null)
|
if (location.HireManager == null)
|
||||||
@@ -163,11 +162,14 @@ namespace Barotrauma
|
|||||||
mapZoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
|
mapZoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
|
||||||
mapZoom = MathHelper.Clamp(mapZoom, 1.0f, 4.0f);
|
mapZoom = MathHelper.Clamp(mapZoom, 1.0f, 4.0f);
|
||||||
|
|
||||||
GameMain.GameSession.Map.Update((float)deltaTime, new Rectangle(
|
if (GameMain.GameSession?.Map != null)
|
||||||
tabs[(int)selectedTab].Rect.X + 20,
|
{
|
||||||
tabs[(int)selectedTab].Rect.Y + 20,
|
GameMain.GameSession.Map.Update(deltaTime, new Rectangle(
|
||||||
tabs[(int)selectedTab].Rect.Width - 310,
|
tabs[(int)selectedTab].Rect.X + 20,
|
||||||
tabs[(int)selectedTab].Rect.Height - 40), mapZoom);
|
tabs[(int)selectedTab].Rect.Y + 20,
|
||||||
|
tabs[(int)selectedTab].Rect.Width - 310,
|
||||||
|
tabs[(int)selectedTab].Rect.Height - 40), mapZoom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch)
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
@@ -179,7 +181,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
|
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable);
|
||||||
*/
|
*/
|
||||||
if (selectedTab == Tab.Map)
|
if (selectedTab == Tab.Map && GameMain.GameSession?.Map != null)
|
||||||
{
|
{
|
||||||
GameMain.GameSession.Map.Draw(spriteBatch, new Rectangle(
|
GameMain.GameSession.Map.Draw(spriteBatch, new Rectangle(
|
||||||
tabs[(int)selectedTab].Rect.X + 20,
|
tabs[(int)selectedTab].Rect.X + 20,
|
||||||
@@ -278,17 +280,15 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (location == null) return;
|
if (location == null) return;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 250, 0), location.Name, "", Alignment.TopLeft, Alignment.TopCenter, locationPanel, true, GUI.LargeFont);
|
var titleText = new GUITextBlock(new Rectangle(0, 0, 250, 0), location.Name, "", Alignment.TopLeft, Alignment.TopCenter, locationPanel, true, GUI.LargeFont);
|
||||||
|
|
||||||
if (GameMain.GameSession.Map.SelectedConnection != null && GameMain.GameSession.Map.SelectedConnection.Mission != null)
|
if (GameMain.GameSession.Map.SelectedConnection != null && GameMain.GameSession.Map.SelectedConnection.Mission != null)
|
||||||
{
|
{
|
||||||
var mission = GameMain.GameSession.Map.SelectedConnection.Mission;
|
var mission = GameMain.GameSession.Map.SelectedConnection.Mission;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 80, 0, 20), "Mission: " + mission.Name, "", locationPanel);
|
new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 20, 0, 20), "Mission: " + mission.Name, "", locationPanel);
|
||||||
|
new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 40, 0, 20), "Reward: " + mission.Reward + " credits", "", locationPanel);
|
||||||
new GUITextBlock(new Rectangle(0, 100, 0, 20), "Reward: " + mission.Reward + " credits", "", locationPanel);
|
new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 70, 0, 0), mission.Description, "", Alignment.TopLeft, Alignment.TopLeft, locationPanel, true, GUI.SmallFont);
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 130, 0, 0), mission.Description, "", locationPanel, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startButton.Enabled = true;
|
startButton.Enabled = true;
|
||||||
|
|||||||
@@ -11,15 +11,12 @@ namespace Barotrauma
|
|||||||
class MainMenuScreen : Screen
|
class MainMenuScreen : Screen
|
||||||
{
|
{
|
||||||
public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4 }
|
public enum Tab { NewGame = 1, LoadGame = 2, HostServer = 3, Settings = 4 }
|
||||||
|
|
||||||
GUIFrame buttonsTab;
|
private GUIFrame buttonsTab;
|
||||||
|
|
||||||
private GUIFrame[] menuTabs;
|
private GUIFrame[] menuTabs;
|
||||||
private GUIListBox subList;
|
|
||||||
|
|
||||||
private GUIListBox saveList;
|
private CampaignSetupUI campaignSetupUI;
|
||||||
|
|
||||||
private GUITextBox saveNameBox, seedBox;
|
|
||||||
|
|
||||||
private GUITextBox serverNameBox, portBox, passwordBox, maxPlayersBox;
|
private GUITextBox serverNameBox, portBox, passwordBox, maxPlayersBox;
|
||||||
private GUITickBox isPublicBox, useUpnpBox;
|
private GUITickBox isPublicBox, useUpnpBox;
|
||||||
@@ -30,12 +27,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public MainMenuScreen(GameMain game)
|
public MainMenuScreen(GameMain game)
|
||||||
{
|
{
|
||||||
menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length+1];
|
menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1];
|
||||||
|
|
||||||
buttonsTab = new GUIFrame(new Rectangle(0,0,0,0), Color.Transparent, Alignment.Left | Alignment.CenterY);
|
buttonsTab = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Transparent, Alignment.Left | Alignment.CenterY);
|
||||||
buttonsTab.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
buttonsTab.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||||
//menuTabs[(int)Tabs.Main].Padding = GUI.style.smallPadding;
|
|
||||||
|
|
||||||
|
|
||||||
int y = (int)(GameMain.GraphicsHeight * 0.3f);
|
int y = (int)(GameMain.GraphicsHeight * 0.3f);
|
||||||
|
|
||||||
@@ -86,62 +81,17 @@ namespace Barotrauma
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
menuTabs[(int)Tab.NewGame] = new GUIFrame(panelRect, "");
|
menuTabs[(int)Tab.NewGame] = new GUIFrame(panelRect, "");
|
||||||
menuTabs[(int)Tab.NewGame].Padding = new Vector4(20.0f,20.0f,20.0f,20.0f);
|
menuTabs[(int)Tab.NewGame].Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||||
|
|
||||||
//new GUITextBlock(new Rectangle(0, -20, 0, 30), "New Game", null, null, Alignment.CenterX, "", menuTabs[(int)Tabs.NewGame]);
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Selected submarine:", null, null, Alignment.Left, "", menuTabs[(int)Tab.NewGame]);
|
|
||||||
subList = new GUIListBox(new Rectangle(0, 30, 230, panelRect.Height-100), "", menuTabs[(int)Tab.NewGame]);
|
|
||||||
|
|
||||||
UpdateSubList();
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 0, 100, 20),
|
|
||||||
"Save name: ", "", Alignment.Left, Alignment.Left, menuTabs[(int)Tab.NewGame]);
|
|
||||||
|
|
||||||
saveNameBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 30, 180, 20),
|
|
||||||
Alignment.TopLeft, "", menuTabs[(int)Tab.NewGame]);
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 60, 100, 20),
|
|
||||||
"Map Seed: ", "", Alignment.Left, Alignment.Left, menuTabs[(int)Tab.NewGame]);
|
|
||||||
|
|
||||||
seedBox = new GUITextBox(new Rectangle((int)(subList.Rect.Width + 30), 90, 180, 20),
|
|
||||||
Alignment.TopLeft, "", menuTabs[(int)Tab.NewGame]);
|
|
||||||
seedBox.Text = ToolBox.RandomSeed(8);
|
|
||||||
|
|
||||||
|
|
||||||
button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, "", menuTabs[(int)Tab.NewGame]);
|
|
||||||
button.OnClicked = (GUIButton btn, object userData) =>
|
|
||||||
{
|
|
||||||
Submarine selectedSub = subList.SelectedData as Submarine;
|
|
||||||
if (selectedSub != null && selectedSub.HasTag(SubmarineTag.Shuttle))
|
|
||||||
{
|
|
||||||
var msgBox = new GUIMessageBox("Shuttle selected",
|
|
||||||
"Most shuttles are not adequately equipped to deal with the dangers of the Europan depths. "+
|
|
||||||
"Are you sure you want to choose a shuttle as your vessel?",
|
|
||||||
new string[] {"Yes", "No"});
|
|
||||||
|
|
||||||
msgBox.Buttons[0].OnClicked = StartGame;
|
|
||||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
|
||||||
|
|
||||||
msgBox.Buttons[1].OnClicked = msgBox.Close;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
StartGame(btn, userData);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
|
|
||||||
menuTabs[(int)Tab.LoadGame] = new GUIFrame(panelRect, "");
|
menuTabs[(int)Tab.LoadGame] = new GUIFrame(panelRect, "");
|
||||||
//menuTabs[(int)Tabs.LoadGame].Padding = GUI.style.smallPadding;
|
|
||||||
|
|
||||||
|
campaignSetupUI = new CampaignSetupUI(false, menuTabs[(int)Tab.NewGame], menuTabs[(int)Tab.LoadGame]);
|
||||||
|
campaignSetupUI.LoadGame = LoadGame;
|
||||||
|
campaignSetupUI.StartNewGame = StartGame;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
menuTabs[(int)Tab.HostServer] = new GUIFrame(panelRect, "");
|
menuTabs[(int)Tab.HostServer] = new GUIFrame(panelRect, "");
|
||||||
//menuTabs[(int)Tabs.JoinServer].Padding = GUI.style.smallPadding;
|
|
||||||
|
|
||||||
//new GUITextBlock(new Rectangle(0, -25, 0, 30), "Host Server", "", Alignment.CenterX, Alignment.CenterX, menuTabs[(int)Tabs.HostServer], false, GUI.LargeFont);
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 0, 100, 30), "Server Name:", "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
|
new GUITextBlock(new Rectangle(0, 0, 100, 30), "Server Name:", "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]);
|
||||||
serverNameBox = new GUITextBox(new Rectangle(160, 0, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);
|
serverNameBox = new GUITextBox(new Rectangle(160, 0, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]);
|
||||||
@@ -194,41 +144,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Submarine.Unload();
|
Submarine.Unload();
|
||||||
|
|
||||||
UpdateSubList();
|
campaignSetupUI.UpdateSubList();
|
||||||
|
|
||||||
SelectTab(null, 0);
|
SelectTab(null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSubList()
|
|
||||||
{
|
|
||||||
var subsToShow = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
|
|
||||||
|
|
||||||
subList.ClearChildren();
|
|
||||||
|
|
||||||
foreach (Submarine sub in subsToShow)
|
|
||||||
{
|
|
||||||
var textBlock = new GUITextBlock(
|
|
||||||
new Rectangle(0, 0, 0, 25),
|
|
||||||
ToolBox.LimitString(sub.Name, GUI.Font, subList.Rect.Width - 65), "ListBoxElement",
|
|
||||||
Alignment.Left, Alignment.Left, subList)
|
|
||||||
{
|
|
||||||
Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f),
|
|
||||||
ToolTip = sub.Description,
|
|
||||||
UserData = sub
|
|
||||||
};
|
|
||||||
|
|
||||||
if (sub.HasTag(SubmarineTag.Shuttle))
|
|
||||||
{
|
|
||||||
textBlock.TextColor = textBlock.TextColor * 0.85f;
|
|
||||||
|
|
||||||
var shuttleText = new GUITextBlock(new Rectangle(0, 0, 0, 25), "Shuttle", "", Alignment.Left, Alignment.CenterY | Alignment.Right, textBlock, false, GUI.SmallFont);
|
|
||||||
shuttleText.TextColor = textBlock.TextColor * 0.8f;
|
|
||||||
shuttleText.ToolTip = textBlock.ToolTip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Submarine.SavedSubmarines.Count > 0) subList.Select(Submarine.SavedSubmarines[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SelectTab(GUIButton button, object obj)
|
public bool SelectTab(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -276,10 +196,10 @@ namespace Barotrauma
|
|||||||
switch (selectedTab)
|
switch (selectedTab)
|
||||||
{
|
{
|
||||||
case Tab.NewGame:
|
case Tab.NewGame:
|
||||||
saveNameBox.Text = SaveUtil.CreateSavePath();
|
campaignSetupUI.CreateDefaultSaveName();
|
||||||
break;
|
break;
|
||||||
case Tab.LoadGame:
|
case Tab.LoadGame:
|
||||||
UpdateLoadScreen();
|
campaignSetupUI.UpdateLoadMenu();
|
||||||
break;
|
break;
|
||||||
case Tab.Settings:
|
case Tab.Settings:
|
||||||
GameMain.Config.ResetSettingsFrame();
|
GameMain.Config.ResetSettingsFrame();
|
||||||
@@ -379,99 +299,6 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateLoadScreen()
|
|
||||||
{
|
|
||||||
menuTabs[(int)Tab.LoadGame].ClearChildren();
|
|
||||||
|
|
||||||
string[] saveFiles = SaveUtil.GetSaveFiles();
|
|
||||||
|
|
||||||
saveList = new GUIListBox(new Rectangle(0, 0, 200, menuTabs[(int)Tab.LoadGame].Rect.Height - 80), Color.White, "", menuTabs[(int)Tab.LoadGame]);
|
|
||||||
saveList.OnSelected = SelectSaveFile;
|
|
||||||
|
|
||||||
foreach (string saveFile in saveFiles)
|
|
||||||
{
|
|
||||||
GUITextBlock textBlock = new GUITextBlock(
|
|
||||||
new Rectangle(0, 0, 0, 25),
|
|
||||||
saveFile,
|
|
||||||
"ListBoxElement",
|
|
||||||
Alignment.Left,
|
|
||||||
Alignment.Left,
|
|
||||||
saveList);
|
|
||||||
textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
|
|
||||||
textBlock.UserData = saveFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
var button = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.Right | Alignment.Bottom, "", menuTabs[(int)Tab.LoadGame]);
|
|
||||||
button.OnClicked = LoadGame;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool SelectSaveFile(GUIComponent component, object obj)
|
|
||||||
{
|
|
||||||
string fileName = (string)obj;
|
|
||||||
|
|
||||||
XDocument doc = SaveUtil.LoadGameSessionDoc(fileName);
|
|
||||||
|
|
||||||
if (doc==null)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error loading save file \""+fileName+"\". The file may be corrupted.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveSaveFrame();
|
|
||||||
|
|
||||||
string subName = ToolBox.GetAttributeString(doc.Root, "submarine", "");
|
|
||||||
|
|
||||||
string saveTime = ToolBox.GetAttributeString(doc.Root, "savetime", "unknown");
|
|
||||||
|
|
||||||
string mapseed = ToolBox.GetAttributeString(doc.Root, "mapseed", "unknown");
|
|
||||||
|
|
||||||
GUIFrame saveFileFrame = new GUIFrame(new Rectangle((int)(saveList.Rect.Width + 20), 0, 200, 230), Color.Black*0.4f, "", menuTabs[(int)Tab.LoadGame]);
|
|
||||||
saveFileFrame.UserData = "savefileframe";
|
|
||||||
saveFileFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0,0,0,20), fileName, "", Alignment.TopLeft, Alignment.TopLeft, saveFileFrame, false, GUI.LargeFont);
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 35, 0, 20), "Submarine: ", "", saveFileFrame).Font = GUI.SmallFont;
|
|
||||||
new GUITextBlock(new Rectangle(15, 52, 0, 20), subName, "", saveFileFrame).Font = GUI.SmallFont;
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 70, 0, 20), "Last saved: ", "", saveFileFrame).Font = GUI.SmallFont;
|
|
||||||
new GUITextBlock(new Rectangle(15, 85, 0, 20), saveTime, "", saveFileFrame).Font = GUI.SmallFont;
|
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(0, 105, 0, 20), "Map seed: ", "", saveFileFrame).Font = GUI.SmallFont;
|
|
||||||
new GUITextBlock(new Rectangle(15, 120, 0, 20), mapseed, "", saveFileFrame).Font = GUI.SmallFont;
|
|
||||||
|
|
||||||
var deleteSaveButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Delete", Alignment.BottomCenter, "", saveFileFrame);
|
|
||||||
deleteSaveButton.UserData = fileName;
|
|
||||||
deleteSaveButton.OnClicked = DeleteSave;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool DeleteSave(GUIButton button, object obj)
|
|
||||||
{
|
|
||||||
string saveFile = obj as string;
|
|
||||||
|
|
||||||
if (obj == null) return false;
|
|
||||||
|
|
||||||
SaveUtil.DeleteSave(saveFile);
|
|
||||||
|
|
||||||
UpdateLoadScreen();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveSaveFrame()
|
|
||||||
{
|
|
||||||
GUIComponent prevFrame = null;
|
|
||||||
foreach (GUIComponent child in menuTabs[(int)Tab.LoadGame].children)
|
|
||||||
{
|
|
||||||
if (child.UserData as string != "savefileframe") continue;
|
|
||||||
|
|
||||||
prevFrame = child;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
menuTabs[(int)Tab.LoadGame].RemoveChild(prevFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AddToGUIUpdateList()
|
public override void AddToGUIUpdateList()
|
||||||
{
|
{
|
||||||
@@ -513,53 +340,42 @@ namespace Barotrauma
|
|||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool StartGame(GUIButton button, object userData)
|
private void StartGame(Submarine selectedSub, string saveName, string mapSeed)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(saveNameBox.Text)) return false;
|
if (string.IsNullOrEmpty(saveName)) return;
|
||||||
|
|
||||||
string[] existingSaveFiles = SaveUtil.GetSaveFiles();
|
string[] existingSaveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Singleplayer);
|
||||||
|
|
||||||
if (Array.Find(existingSaveFiles, s => s == saveNameBox.Text)!=null)
|
if (Array.Find(existingSaveFiles, s => s == saveName) != null)
|
||||||
{
|
{
|
||||||
new GUIMessageBox("Save name already in use", "Please choose another name for the save file");
|
new GUIMessageBox("Save name already in use", "Please choose another name for the save file");
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Submarine selectedSub = subList.SelectedData as Submarine;
|
|
||||||
if (selectedSub == null)
|
if (selectedSub == null)
|
||||||
{
|
{
|
||||||
new GUIMessageBox("Submarine not selected", "Please select a submarine");
|
new GUIMessageBox("Submarine not selected", "Please select a submarine");
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Directory.Exists(SaveUtil.TempPath))
|
if (!Directory.Exists(SaveUtil.TempPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(SaveUtil.TempPath);
|
Directory.CreateDirectory(SaveUtil.TempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
File.Copy(selectedSub.FilePath, Path.Combine(SaveUtil.TempPath, selectedSub.Name+".sub"), true);
|
File.Copy(selectedSub.FilePath, Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"), true);
|
||||||
|
|
||||||
selectedSub = new Submarine(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"), "");
|
selectedSub = new Submarine(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"), "");
|
||||||
|
|
||||||
GameMain.GameSession = new GameSession(selectedSub, saveNameBox.Text, GameModePreset.list.Find(gm => gm.Name == "Single Player"));
|
GameMain.GameSession = new GameSession(selectedSub, saveName, GameModePreset.list.Find(gm => gm.Name == "Single Player"));
|
||||||
(GameMain.GameSession.GameMode as CampaignMode).GenerateMap(seedBox.Text);
|
(GameMain.GameSession.GameMode as CampaignMode).GenerateMap(mapSeed);
|
||||||
|
|
||||||
GameMain.LobbyScreen.Select();
|
GameMain.LobbyScreen.Select();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool PreviousTab(GUIButton button, object obj)
|
private void LoadGame(string saveFile)
|
||||||
{
|
{
|
||||||
//selectedTab = (int)Tabs.Main;
|
if (string.IsNullOrWhiteSpace(saveFile)) return;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool LoadGame(GUIButton button, object obj)
|
|
||||||
{
|
|
||||||
string saveFile = saveList.SelectedData as string;
|
|
||||||
if (string.IsNullOrWhiteSpace(saveFile)) return false;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -568,13 +384,11 @@ namespace Barotrauma
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Loading save \""+saveFile+"\" failed", e);
|
DebugConsole.ThrowError("Loading save \""+saveFile+"\" failed", e);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GameMain.LobbyScreen.Select();
|
GameMain.LobbyScreen.Select();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUITextBox textBox, seedBox;
|
private GUITextBox textBox, seedBox;
|
||||||
|
|
||||||
|
private GUIFrame defaultModeContainer, campaignContainer;
|
||||||
|
|
||||||
|
private GUIButton campaignViewButton;
|
||||||
|
|
||||||
private GUIFrame myPlayerFrame;
|
private GUIFrame myPlayerFrame;
|
||||||
|
|
||||||
private GUIFrame jobInfoFrame;
|
private GUIFrame jobInfoFrame;
|
||||||
@@ -44,6 +48,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUIDropDown shuttleList;
|
private GUIDropDown shuttleList;
|
||||||
|
|
||||||
|
private CampaignUI campaignUI;
|
||||||
|
|
||||||
private Sprite backgroundSprite;
|
private Sprite backgroundSprite;
|
||||||
|
|
||||||
private GUITextBox serverMessage;
|
private GUITextBox serverMessage;
|
||||||
@@ -215,37 +221,43 @@ namespace Barotrauma
|
|||||||
playerList = new GUIListBox(new Rectangle(0, 0, 0, 0), null, "", playerListFrame);
|
playerList = new GUIListBox(new Rectangle(0, 0, 0, 0), null, "", playerListFrame);
|
||||||
playerList.OnSelected = SelectPlayer;
|
playerList.OnSelected = SelectPlayer;
|
||||||
|
|
||||||
|
defaultModeContainer = new GUIFrame(new Rectangle(0, 10, 0, 0), null, infoFrame);
|
||||||
|
|
||||||
|
campaignContainer = new GUIFrame(new Rectangle(0, 20, 0, 0), null, infoFrame);
|
||||||
|
campaignContainer.Visible = false;
|
||||||
|
var backButton = new GUIButton(new Rectangle(0, -20, 100, 30), "Back", "", campaignContainer);
|
||||||
|
backButton.OnClicked += (btn, obj) => { ToggleCampaignView(false); return true; };
|
||||||
|
|
||||||
|
|
||||||
//submarine list ------------------------------------------------------------------
|
//submarine list ------------------------------------------------------------------
|
||||||
|
|
||||||
int columnWidth = infoFrame.Rect.Width / 3 - 5;
|
int columnWidth = infoFrame.Rect.Width / 3 - 5;
|
||||||
int columnX = 0;
|
int columnX = 0;
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(columnX, 120, columnWidth, 30), "Submarine:", "", infoFrame);
|
new GUITextBlock(new Rectangle(columnX, 110, columnWidth, 30), "Submarine:", "", defaultModeContainer);
|
||||||
subList = new GUIListBox(new Rectangle(columnX, 150, columnWidth, infoFrame.Rect.Height - 150 - 80), Color.White, "", infoFrame);
|
subList = new GUIListBox(new Rectangle(columnX, 140, columnWidth, defaultModeContainer.Rect.Height - 170), Color.White, "", defaultModeContainer);
|
||||||
subList.OnSelected = VotableClicked;
|
subList.OnSelected = VotableClicked;
|
||||||
|
|
||||||
var voteText = new GUITextBlock(new Rectangle(columnX, 120, columnWidth, 30), "Votes: ", "", Alignment.TopLeft, Alignment.TopRight, infoFrame);
|
var voteText = new GUITextBlock(new Rectangle(columnX, 110, columnWidth, 30), "Votes: ", "", Alignment.TopLeft, Alignment.TopRight, defaultModeContainer);
|
||||||
voteText.UserData = "subvotes";
|
voteText.UserData = "subvotes";
|
||||||
voteText.Visible = false;
|
voteText.Visible = false;
|
||||||
|
|
||||||
//UpdateSubList(Submarine.SavedSubmarines);
|
|
||||||
|
|
||||||
columnX += columnWidth + 20;
|
columnX += columnWidth + 20;
|
||||||
|
|
||||||
|
|
||||||
//respawn shuttle ------------------------------------------------------------------
|
//respawn shuttle ------------------------------------------------------------------
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(columnX, 120, 20, 20), "Respawn shuttle:", "", infoFrame);
|
new GUITextBlock(new Rectangle(columnX, 110, 20, 20), "Respawn shuttle:", "", defaultModeContainer);
|
||||||
shuttleList = new GUIDropDown(new Rectangle(columnX, 150, 200, 20), "", "", infoFrame);
|
shuttleList = new GUIDropDown(new Rectangle(columnX, 140, 200, 20), "", "", defaultModeContainer);
|
||||||
|
|
||||||
|
|
||||||
//gamemode ------------------------------------------------------------------
|
//gamemode ------------------------------------------------------------------
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(columnX, 180, 0, 30), "Game mode: ", "", infoFrame);
|
new GUITextBlock(new Rectangle(columnX, 170, 0, 30), "Game mode: ", "", defaultModeContainer);
|
||||||
modeList = new GUIListBox(new Rectangle(columnX, 200, columnWidth, infoFrame.Rect.Height - 300), "", infoFrame);
|
modeList = new GUIListBox(new Rectangle(columnX, 200, columnWidth, defaultModeContainer.Rect.Height - 230), "", defaultModeContainer);
|
||||||
modeList.OnSelected = VotableClicked;
|
modeList.OnSelected = VotableClicked;
|
||||||
|
|
||||||
voteText = new GUITextBlock(new Rectangle(columnX, 120, columnWidth, 30), "Votes: ", "", Alignment.TopLeft, Alignment.TopRight, infoFrame);
|
voteText = new GUITextBlock(new Rectangle(columnX, 170, columnWidth, 30), "Votes: ", "", Alignment.TopLeft, Alignment.TopRight, defaultModeContainer);
|
||||||
voteText.UserData = "modevotes";
|
voteText.UserData = "modevotes";
|
||||||
voteText.Visible = false;
|
voteText.Visible = false;
|
||||||
|
|
||||||
@@ -265,7 +277,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//mission type ------------------------------------------------------------------
|
//mission type ------------------------------------------------------------------
|
||||||
|
|
||||||
missionTypeBlock = new GUITextBlock(new Rectangle(columnX, -10, 300, 20), "Mission type:", "", Alignment.BottomLeft, Alignment.CenterLeft, infoFrame);
|
missionTypeBlock = new GUITextBlock(new Rectangle(columnX, -10, 300, 20), "Mission type:", "", Alignment.BottomLeft, Alignment.CenterLeft, defaultModeContainer);
|
||||||
missionTypeBlock.Padding = Vector4.Zero;
|
missionTypeBlock.Padding = Vector4.Zero;
|
||||||
missionTypeBlock.UserData = 0;
|
missionTypeBlock.UserData = 0;
|
||||||
|
|
||||||
@@ -296,46 +308,46 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//seed ------------------------------------------------------------------
|
//seed ------------------------------------------------------------------
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(columnX, 120, 180, 20),
|
new GUITextBlock(new Rectangle(columnX, 110, 180, 20),
|
||||||
"Level Seed: ", "", Alignment.Left, Alignment.TopLeft, infoFrame);
|
"Level Seed: ", "", Alignment.Left, Alignment.TopLeft, defaultModeContainer);
|
||||||
|
|
||||||
seedBox = new GUITextBox(new Rectangle(columnX, 150, columnWidth / 2, 20),
|
seedBox = new GUITextBox(new Rectangle(columnX, 140, columnWidth / 2, 20),
|
||||||
Alignment.TopLeft, "", infoFrame);
|
Alignment.TopLeft, "", defaultModeContainer);
|
||||||
seedBox.OnTextChanged = SelectSeed;
|
seedBox.OnTextChanged = SelectSeed;
|
||||||
LevelSeed = ToolBox.RandomSeed(8);
|
LevelSeed = ToolBox.RandomSeed(8);
|
||||||
|
|
||||||
//traitor probability ------------------------------------------------------------------
|
//traitor probability ------------------------------------------------------------------
|
||||||
|
|
||||||
new GUITextBlock(new Rectangle(columnX, 180, 20, 20), "Traitors:", "", infoFrame);
|
new GUITextBlock(new Rectangle(columnX, 170, 20, 20), "Traitors:", "", defaultModeContainer);
|
||||||
|
|
||||||
traitorProbabilityButtons = new GUIButton[2];
|
traitorProbabilityButtons = new GUIButton[2];
|
||||||
|
|
||||||
traitorProbabilityButtons[0] = new GUIButton(new Rectangle(columnX, 205, 20, 20), "<", "", infoFrame);
|
traitorProbabilityButtons[0] = new GUIButton(new Rectangle(columnX, 195, 20, 20), "<", "", defaultModeContainer);
|
||||||
traitorProbabilityButtons[0].UserData = -1;
|
traitorProbabilityButtons[0].UserData = -1;
|
||||||
|
|
||||||
traitorProbabilityText = new GUITextBlock(new Rectangle(columnX + 20, 205, 80, 20), "No", null, null, Alignment.Center, "", infoFrame);
|
traitorProbabilityText = new GUITextBlock(new Rectangle(columnX + 20, 195, 80, 20), "No", null, null, Alignment.Center, "", defaultModeContainer);
|
||||||
|
|
||||||
traitorProbabilityButtons[1] = new GUIButton(new Rectangle(columnX + 100, 205, 20, 20), ">", "", infoFrame);
|
traitorProbabilityButtons[1] = new GUIButton(new Rectangle(columnX + 100, 195, 20, 20), ">", "", defaultModeContainer);
|
||||||
traitorProbabilityButtons[1].UserData = 1;
|
traitorProbabilityButtons[1].UserData = 1;
|
||||||
|
|
||||||
|
|
||||||
//automatic restart ------------------------------------------------------------------
|
//automatic restart ------------------------------------------------------------------
|
||||||
|
|
||||||
autoRestartBox = new GUITickBox(new Rectangle(columnX, 240, 20, 20), "Automatic restart", Alignment.TopLeft, infoFrame);
|
autoRestartBox = new GUITickBox(new Rectangle(columnX, 230, 20, 20), "Automatic restart", Alignment.TopLeft, defaultModeContainer);
|
||||||
autoRestartBox.OnSelected = ToggleAutoRestart;
|
autoRestartBox.OnSelected = ToggleAutoRestart;
|
||||||
|
|
||||||
var restartText = new GUITextBlock(new Rectangle(columnX, 265, 20, 20), "", "", infoFrame);
|
var restartText = new GUITextBlock(new Rectangle(columnX, 255, 20, 20), "", "", defaultModeContainer);
|
||||||
restartText.Font = GUI.SmallFont;
|
restartText.Font = GUI.SmallFont;
|
||||||
restartText.TextGetter = AutoRestartText;
|
restartText.TextGetter = AutoRestartText;
|
||||||
|
|
||||||
//server info ------------------------------------------------------------------
|
//server info ------------------------------------------------------------------
|
||||||
|
|
||||||
var serverName = new GUITextBox(new Rectangle(0, 0, 200, 20), null, null, Alignment.TopLeft, Alignment.TopLeft, "", infoFrame);
|
var serverName = new GUITextBox(new Rectangle(0, 0, 200, 20), null, null, Alignment.TopLeft, Alignment.TopLeft, "", defaultModeContainer);
|
||||||
serverName.TextGetter = GetServerName;
|
serverName.TextGetter = GetServerName;
|
||||||
serverName.Enabled = GameMain.Server != null;
|
serverName.Enabled = GameMain.Server != null;
|
||||||
serverName.OnTextChanged = ChangeServerName;
|
serverName.OnTextChanged = ChangeServerName;
|
||||||
|
|
||||||
serverMessage = new GUITextBox(new Rectangle(0, 30, 360, 70), null, null, Alignment.TopLeft, Alignment.TopLeft, "", infoFrame);
|
serverMessage = new GUITextBox(new Rectangle(0, 30, 360, 70), null, null, Alignment.TopLeft, Alignment.TopLeft, "", defaultModeContainer);
|
||||||
serverMessage.Wrap = true;
|
serverMessage.Wrap = true;
|
||||||
serverMessage.OnTextChanged = UpdateServerMessage;
|
serverMessage.OnTextChanged = UpdateServerMessage;
|
||||||
|
|
||||||
@@ -422,10 +434,14 @@ namespace Barotrauma
|
|||||||
missionTypeButtons[0].OnClicked = ToggleMissionType;
|
missionTypeButtons[0].OnClicked = ToggleMissionType;
|
||||||
missionTypeButtons[1].OnClicked = ToggleMissionType;
|
missionTypeButtons[1].OnClicked = ToggleMissionType;
|
||||||
|
|
||||||
StartButton = new GUIButton(new Rectangle(0, 0, 80, 30), "Start", Alignment.BottomRight, "", infoFrame);
|
StartButton = new GUIButton(new Rectangle(0, 0, 80, 30), "Start", Alignment.BottomRight, "", defaultModeContainer);
|
||||||
StartButton.OnClicked = GameMain.Server.StartGameClicked;
|
StartButton.OnClicked = GameMain.Server.StartGameClicked;
|
||||||
|
|
||||||
GUIButton settingsButton = new GUIButton(new Rectangle(-100, 0, 80, 30), "Settings", Alignment.BottomRight, "", infoFrame);
|
campaignViewButton = new GUIButton(new Rectangle(0, 0, 130, 30), "Campaign view", Alignment.BottomRight, "", defaultModeContainer);
|
||||||
|
campaignViewButton.OnClicked = (btn, obj) => { ToggleCampaignView(true); return true; };
|
||||||
|
campaignViewButton.Visible = false;
|
||||||
|
|
||||||
|
GUIButton settingsButton = new GUIButton(new Rectangle(-110, 0, 80, 20), "Settings", Alignment.TopRight, "", infoFrame);
|
||||||
settingsButton.OnClicked = GameMain.Server.ToggleSettingsFrame;
|
settingsButton.OnClicked = GameMain.Server.ToggleSettingsFrame;
|
||||||
settingsButton.UserData = "settingsButton";
|
settingsButton.UserData = "settingsButton";
|
||||||
|
|
||||||
@@ -983,6 +999,12 @@ namespace Barotrauma
|
|||||||
menu.Update((float)deltaTime);
|
menu.Update((float)deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (campaignContainer.Visible && campaignUI != null)
|
||||||
|
{
|
||||||
|
campaignContainer.Update((float)deltaTime);
|
||||||
|
campaignUI.Update((float)deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
if (autoRestartTimer != 0.0f && autoRestartBox.Selected)
|
if (autoRestartTimer != 0.0f && autoRestartBox.Selected)
|
||||||
{
|
{
|
||||||
autoRestartTimer = Math.Max(autoRestartTimer - (float)deltaTime, 0.0f);
|
autoRestartTimer = Math.Max(autoRestartTimer - (float)deltaTime, 0.0f);
|
||||||
@@ -1009,6 +1031,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (playerFrame != null) playerFrame.Draw(spriteBatch);
|
if (playerFrame != null) playerFrame.Draw(spriteBatch);
|
||||||
|
|
||||||
|
if (campaignContainer.Visible && campaignUI != null)
|
||||||
|
{
|
||||||
|
campaignUI.Draw(spriteBatch);
|
||||||
|
}
|
||||||
|
|
||||||
GUI.Draw((float)deltaTime, spriteBatch, null);
|
GUI.Draw((float)deltaTime, spriteBatch, null);
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
@@ -1071,27 +1098,50 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
modeList.Select(modeIndex, true);
|
modeList.Select(modeIndex, true);
|
||||||
|
|
||||||
|
ToggleCampaignMode(SelectedMode.Name == "Campaign");
|
||||||
missionTypeBlock.Visible = SelectedMode != null && SelectedMode.Name == "Mission";
|
missionTypeBlock.Visible = SelectedMode != null && SelectedMode.Name == "Mission";
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SelectMode(GUIComponent component, object obj)
|
private bool SelectMode(GUIComponent component, object obj)
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember == null) return false;
|
if (GameMain.NetworkMember == null) return false;
|
||||||
|
|
||||||
//if (GameMain.Server==null)
|
|
||||||
//{
|
|
||||||
// return VotableClicked(component, obj);
|
|
||||||
//}
|
|
||||||
|
|
||||||
GameModePreset modePreset = obj as GameModePreset;
|
GameModePreset modePreset = obj as GameModePreset;
|
||||||
if (modePreset == null) return false;
|
if (modePreset == null) return false;
|
||||||
|
|
||||||
missionTypeBlock.Visible = modePreset.Name == "Mission";
|
missionTypeBlock.Visible = modePreset.Name == "Mission";
|
||||||
lastUpdateID++;
|
|
||||||
|
if (modePreset.Name == "Campaign")
|
||||||
|
{
|
||||||
|
MultiplayerCampaign.StartCampaignSetup();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastUpdateID++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ToggleCampaignView(bool enabled)
|
||||||
|
{
|
||||||
|
defaultModeContainer.Visible = !enabled;
|
||||||
|
StartButton.Visible = !enabled;
|
||||||
|
|
||||||
|
campaignContainer.Visible = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToggleCampaignMode(bool enabled)
|
||||||
|
{
|
||||||
|
StartButton.Visible = !enabled;
|
||||||
|
campaignViewButton.Visible = enabled;
|
||||||
|
|
||||||
|
ToggleCampaignView(enabled);
|
||||||
|
|
||||||
|
if (enabled && campaignUI == null)
|
||||||
|
{
|
||||||
|
campaignUI = new CampaignUI(GameMain.GameSession.GameMode as CampaignMode, campaignContainer);
|
||||||
|
campaignUI.StartRound = () => { GameMain.Server.StartGame(); };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool SelectSeed(GUITextBox textBox, string seed)
|
private bool SelectSeed(GUITextBox textBox, string seed)
|
||||||
{
|
{
|
||||||
if (GameMain.Server == null) return false;
|
if (GameMain.Server == null) return false;
|
||||||
@@ -1102,26 +1152,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private bool ChangeCharacterName(GUITextBox textBox, string newName)
|
|
||||||
//{
|
|
||||||
// if (string.IsNullOrEmpty(newName)) return false;
|
|
||||||
|
|
||||||
// if (GameMain.NetworkMember == null || GameMain.NetworkMember.CharacterInfo == null) return true;
|
|
||||||
|
|
||||||
// GameMain.NetworkMember.CharacterInfo.Name = newName;
|
|
||||||
// if (GameMain.Client != null)
|
|
||||||
// {
|
|
||||||
// GameMain.Client.Name = newName;
|
|
||||||
// GameMain.Client.SendCharacterData();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// textBox.Text = newName;
|
|
||||||
// textBox.Selected = false;
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
private bool ViewJobInfo(GUIButton button, object obj)
|
private bool ViewJobInfo(GUIButton button, object obj)
|
||||||
{
|
{
|
||||||
GUIComponent jobText = button.Parent;
|
GUIComponent jobText = button.Parent;
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
|
||||||
{
|
|
||||||
public partial class SaveUtil
|
|
||||||
{
|
|
||||||
public static void SaveGame(string fileName)
|
|
||||||
{
|
|
||||||
fileName = Path.Combine(SaveFolder, fileName);
|
|
||||||
|
|
||||||
string tempPath = Path.Combine(SaveFolder, "temp");
|
|
||||||
|
|
||||||
Directory.CreateDirectory(tempPath);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ClearFolder(tempPath, new string[] { GameMain.GameSession.Submarine.FilePath });
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Submarine.MainSub != null && Submarine.Loaded.Contains(Submarine.MainSub))
|
|
||||||
{
|
|
||||||
Submarine.MainSub.FilePath = Path.Combine(tempPath, Submarine.MainSub.Name + ".sub");
|
|
||||||
Submarine.MainSub.SaveAs(Submarine.MainSub.FilePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error saving submarine", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GameMain.GameSession.Save(Path.Combine(tempPath, "gamesession.xml"));
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error saving gamesession", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CompressDirectory(tempPath, fileName+".save", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error compressing save file", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LoadGame(string fileName)
|
|
||||||
{
|
|
||||||
string filePath = Path.Combine(SaveFolder, fileName+".save");
|
|
||||||
|
|
||||||
DecompressToDirectory(filePath, TempPath, null);
|
|
||||||
|
|
||||||
XDocument doc = ToolBox.TryLoadXml(Path.Combine(TempPath, "gamesession.xml"));
|
|
||||||
|
|
||||||
string subPath = Path.Combine(TempPath, ToolBox.GetAttributeString(doc.Root, "submarine", ""))+".sub";
|
|
||||||
Submarine selectedMap = new Submarine(subPath, "");// Submarine.Load();
|
|
||||||
GameMain.GameSession = new GameSession(selectedMap, fileName, doc);
|
|
||||||
|
|
||||||
//Directory.Delete(tempPath, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static XDocument LoadGameSessionDoc(string fileName)
|
|
||||||
{
|
|
||||||
string filePath = Path.Combine(SaveFolder, fileName + ".save");
|
|
||||||
|
|
||||||
string tempPath = Path.Combine(SaveFolder, "temp");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DecompressToDirectory(filePath, tempPath, null);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ToolBox.TryLoadXml(Path.Combine(tempPath, "gamesession.xml"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DeleteSave(string fileName)
|
|
||||||
{
|
|
||||||
fileName = Path.Combine(SaveFolder, fileName + ".save");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("ERROR: deleting save file \""+fileName+" failed.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string[] GetSaveFiles()
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(SaveFolder))
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Save folder \"" + SaveFolder + " not found! Attempting to create a new folder");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(SaveFolder);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Failed to create the folder \"" + SaveFolder + "\"!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] files = Directory.GetFiles(SaveFolder, "*.save");
|
|
||||||
|
|
||||||
for (int i = 0; i < files.Length; i++)
|
|
||||||
{
|
|
||||||
files[i] = Path.GetFileNameWithoutExtension(files[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string CreateSavePath(string fileName="Save")
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(SaveFolder))
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Save folder \""+SaveFolder+"\" not found. Created new folder");
|
|
||||||
Directory.CreateDirectory(SaveFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
string extension = ".save";
|
|
||||||
string pathWithoutExtension = Path.Combine(SaveFolder, fileName);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while (File.Exists(pathWithoutExtension + " " + i + extension))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileName + " " + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CompressStringToFile(string fileName, string value)
|
|
||||||
{
|
|
||||||
// A.
|
|
||||||
// Write string to temporary file.
|
|
||||||
string temp = Path.GetTempFileName();
|
|
||||||
File.WriteAllText(temp, value);
|
|
||||||
|
|
||||||
// B.
|
|
||||||
// Read file into byte array buffer.
|
|
||||||
byte[] b;
|
|
||||||
using (FileStream f = new FileStream(temp, FileMode.Open))
|
|
||||||
{
|
|
||||||
b = new byte[f.Length];
|
|
||||||
f.Read(b, 0, (int)f.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// C.
|
|
||||||
// Use GZipStream to write compressed bytes to target file.
|
|
||||||
using (FileStream f2 = new FileStream(fileName, FileMode.Create))
|
|
||||||
using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false))
|
|
||||||
{
|
|
||||||
gz.Write(b, 0, b.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CompressFile(string sDir, string sRelativePath, GZipStream zipStream)
|
|
||||||
{
|
|
||||||
//Compress file name
|
|
||||||
char[] chars = sRelativePath.ToCharArray();
|
|
||||||
zipStream.Write(BitConverter.GetBytes(chars.Length), 0, sizeof(int));
|
|
||||||
foreach (char c in chars)
|
|
||||||
zipStream.Write(BitConverter.GetBytes(c), 0, sizeof(char));
|
|
||||||
|
|
||||||
//Compress file content
|
|
||||||
byte[] bytes = File.ReadAllBytes(Path.Combine(sDir, sRelativePath));
|
|
||||||
zipStream.Write(BitConverter.GetBytes(bytes.Length), 0, sizeof(int));
|
|
||||||
zipStream.Write(bytes, 0, bytes.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CompressDirectory(string sInDir, string sOutFile, ProgressDelegate progress)
|
|
||||||
{
|
|
||||||
string[] sFiles = Directory.GetFiles(sInDir, "*.*", SearchOption.AllDirectories);
|
|
||||||
int iDirLen = sInDir[sInDir.Length - 1] == Path.DirectorySeparatorChar ? sInDir.Length : sInDir.Length + 1;
|
|
||||||
|
|
||||||
using (FileStream outFile = new FileStream(sOutFile, FileMode.Create, FileAccess.Write, FileShare.None))
|
|
||||||
using (GZipStream str = new GZipStream(outFile, CompressionMode.Compress))
|
|
||||||
foreach (string sFilePath in sFiles)
|
|
||||||
{
|
|
||||||
string sRelativePath = sFilePath.Substring(iDirLen);
|
|
||||||
if (progress != null)
|
|
||||||
progress(sRelativePath);
|
|
||||||
CompressFile(sInDir, sRelativePath, str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ClearFolder(string FolderName, string[] ignoredFiles = null)
|
|
||||||
{
|
|
||||||
DirectoryInfo dir = new DirectoryInfo(FolderName);
|
|
||||||
|
|
||||||
foreach (FileInfo fi in dir.GetFiles())
|
|
||||||
{
|
|
||||||
bool ignore = false;
|
|
||||||
foreach (string ignoredFile in ignoredFiles)
|
|
||||||
{
|
|
||||||
if (Path.GetFullPath(fi.FullName).Equals(Path.GetFullPath(ignoredFile)))
|
|
||||||
{
|
|
||||||
ignore = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ignore) continue;
|
|
||||||
|
|
||||||
fi.IsReadOnly = false;
|
|
||||||
fi.Delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (DirectoryInfo di in dir.GetDirectories())
|
|
||||||
{
|
|
||||||
ClearFolder(di.FullName, ignoredFiles);
|
|
||||||
di.Delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -37,7 +37,6 @@ namespace Barotrauma
|
|||||||
new GameModePreset("Single Player", typeof(SinglePlayerCampaign), true);
|
new GameModePreset("Single Player", typeof(SinglePlayerCampaign), true);
|
||||||
new GameModePreset("Tutorial", typeof(TutorialMode), true);
|
new GameModePreset("Tutorial", typeof(TutorialMode), true);
|
||||||
#endif
|
#endif
|
||||||
new GameModePreset("Campaign", typeof(MultiplayerCampaign), false);
|
|
||||||
|
|
||||||
var mode = new GameModePreset("SandBox", typeof(GameMode), false);
|
var mode = new GameModePreset("SandBox", typeof(GameMode), false);
|
||||||
mode.Description = "A game mode with no specific objectives.";
|
mode.Description = "A game mode with no specific objectives.";
|
||||||
@@ -46,6 +45,8 @@ namespace Barotrauma
|
|||||||
mode.Description = "The crew must work together to complete a specific task, such as retrieving "
|
mode.Description = "The crew must work together to complete a specific task, such as retrieving "
|
||||||
+ "an alien artifact or killing a creature that's terrorizing nearby outposts. The game ends "
|
+ "an alien artifact or killing a creature that's terrorizing nearby outposts. The game ends "
|
||||||
+ "when the task is completed or everyone in the crew has died.";
|
+ "when the task is completed or everyone in the crew has died.";
|
||||||
|
|
||||||
|
new GameModePreset("Campaign", typeof(MultiplayerCampaign), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
@@ -7,14 +9,172 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
class MultiplayerCampaign : CampaignMode
|
class MultiplayerCampaign : CampaignMode
|
||||||
{
|
{
|
||||||
|
|
||||||
public MultiplayerCampaign(GameModePreset preset, object param) :
|
public MultiplayerCampaign(GameModePreset preset, object param) :
|
||||||
base(preset, param)
|
base(preset, param)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CLIENT
|
||||||
|
public static void StartCampaignSetup()
|
||||||
|
{
|
||||||
|
var setupBox = new GUIMessageBox("Campaign Setup", "", new string [0], 500, 500);
|
||||||
|
setupBox.InnerFrame.Padding = new Vector4(20.0f, 80.0f, 20.0f, 20.0f);
|
||||||
|
|
||||||
|
var newCampaignContainer = new GUIFrame(new Rectangle(0,40,0,0), null, setupBox.InnerFrame);
|
||||||
|
var loadCampaignContainer = new GUIFrame(new Rectangle(0, 40, 0, 0), null, setupBox.InnerFrame);
|
||||||
|
|
||||||
|
var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer);
|
||||||
|
|
||||||
|
var newCampaignButton = new GUIButton(new Rectangle(0,0,120,20), "New campaign", "", setupBox.InnerFrame);
|
||||||
|
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.InnerFrame);
|
||||||
|
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(sub, saveName, GameModePreset.list.Find(g => g.Name == "Campaign"));
|
||||||
|
var campaign = ((MultiplayerCampaign)GameMain.GameSession.GameMode);
|
||||||
|
campaign.GenerateMap(mapSeed);
|
||||||
|
setupBox.Close();
|
||||||
|
|
||||||
|
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
campaignSetupUI.LoadGame = (string fileName) =>
|
||||||
|
{
|
||||||
|
SaveUtil.LoadGame(fileName);
|
||||||
|
setupBox.Close();
|
||||||
|
|
||||||
|
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
public override void End(string endMessage = "")
|
||||||
|
{
|
||||||
|
isRunning = false;
|
||||||
|
|
||||||
|
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 (subsToLeaveBehind == null || leavingSub == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Leaving submarine not selected -> selecting the closest one");
|
||||||
|
|
||||||
|
leavingSub = GetLeavingSub();
|
||||||
|
|
||||||
|
subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
GameMain.GameSession.EndRound("");
|
||||||
|
|
||||||
|
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.SaveFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
/* 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; };
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = Character.CharacterList.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Character.CharacterList[i].Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
Submarine.Unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MultiplayerCampaign Load(XElement element)
|
||||||
|
{
|
||||||
|
MultiplayerCampaign campaign = new MultiplayerCampaign(GameModePreset.list.Find(gm => gm.Name == "Campaign"), null);
|
||||||
|
|
||||||
|
foreach (XElement subElement in element.Elements())
|
||||||
|
{
|
||||||
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case "map":
|
||||||
|
campaign.map = 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.savedOnStart = true;
|
||||||
|
return campaign;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Save(XElement element)
|
public override void Save(XElement element)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
XElement modeElement = new XElement("MultiPlayerCampaign");
|
||||||
|
modeElement.Add(new XAttribute("money", Money));
|
||||||
|
Map.Save(modeElement);
|
||||||
|
element.Add(modeElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -112,14 +113,23 @@ namespace Barotrauma
|
|||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
CrewManager = new CrewManager();
|
CrewManager = new CrewManager();
|
||||||
|
#endif
|
||||||
foreach (XElement subElement in doc.Root.Elements())
|
foreach (XElement subElement in doc.Root.Elements())
|
||||||
{
|
{
|
||||||
if (subElement.Name.ToString().ToLowerInvariant() != "gamemode") continue;
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
|
{
|
||||||
GameMode = SinglePlayerCampaign.Load(subElement);
|
#if CLIENT
|
||||||
}
|
case "gamemode": //legacy support
|
||||||
|
case "singleplayercampaign":
|
||||||
|
GameMode = SinglePlayerCampaign.Load(subElement);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case "multiplayercampaign":
|
||||||
|
GameMode = MultiplayerCampaign.Load(subElement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateDummyLocations()
|
private void CreateDummyLocations()
|
||||||
@@ -255,5 +265,32 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Save(string filePath)
|
||||||
|
{
|
||||||
|
if (!(GameMode is CampaignMode))
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("GameSessions can only be saved when playing in a campaign mode.");
|
||||||
|
}
|
||||||
|
|
||||||
|
XDocument doc = new XDocument(
|
||||||
|
new XElement("Gamesession"));
|
||||||
|
|
||||||
|
var now = DateTime.Now;
|
||||||
|
doc.Root.Add(new XAttribute("savetime", now.ToShortTimeString() + ", " + now.ToShortDateString()));
|
||||||
|
doc.Root.Add(new XAttribute("submarine", submarine == null ? "" : submarine.Name));
|
||||||
|
doc.Root.Add(new XAttribute("mapseed", Map.Seed));
|
||||||
|
|
||||||
|
((CampaignMode)GameMode).Save(doc.Root);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
doc.Save(filePath);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Saving gamesession to \"" + filePath + "\" failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -351,6 +351,31 @@ namespace Barotrauma
|
|||||||
currentLocation = locations[index];
|
currentLocation = locations[index];
|
||||||
currentLocation.Discovered = true;
|
currentLocation.Discovered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Save(XElement element)
|
||||||
|
{
|
||||||
|
XElement mapElement = new XElement("map");
|
||||||
|
|
||||||
|
mapElement.Add(new XAttribute("currentlocation", CurrentLocationIndex));
|
||||||
|
mapElement.Add(new XAttribute("seed", Seed));
|
||||||
|
mapElement.Add(new XAttribute("size", size));
|
||||||
|
|
||||||
|
List<int> discoveredLocations = new List<int>();
|
||||||
|
for (int i = 0; i < locations.Count; i++)
|
||||||
|
{
|
||||||
|
if (locations[i].Discovered) discoveredLocations.Add(i);
|
||||||
|
}
|
||||||
|
mapElement.Add(new XAttribute("discovered", string.Join(",", discoveredLocations)));
|
||||||
|
|
||||||
|
List<int> passedConnections = new List<int>();
|
||||||
|
for (int i = 0; i < connections.Count; i++)
|
||||||
|
{
|
||||||
|
if (connections[i].Passed) passedConnections.Add(i);
|
||||||
|
}
|
||||||
|
mapElement.Add(new XAttribute("passed", string.Join(",", passedConnections)));
|
||||||
|
|
||||||
|
element.Add(mapElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1128,8 +1128,16 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
int teamCount = 1;
|
int teamCount = 1;
|
||||||
byte hostTeam = 1;
|
byte hostTeam = 1;
|
||||||
|
|
||||||
|
string levelSeed = GameMain.NetLobbyScreen.LevelSeed;
|
||||||
|
|
||||||
|
MultiplayerCampaign campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
|
||||||
|
|
||||||
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
|
//don't instantiate a new gamesession if we're playing a campaign
|
||||||
|
if (campaign == null || GameMain.GameSession == null)
|
||||||
|
{
|
||||||
|
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
if (GameMain.GameSession.GameMode.Mission != null &&
|
if (GameMain.GameSession.GameMode.Mission != null &&
|
||||||
GameMain.GameSession.GameMode.Mission.AssignTeamIDs(connectedClients, out hostTeam))
|
GameMain.GameSession.GameMode.Mission.AssignTeamIDs(connectedClients, out hostTeam))
|
||||||
@@ -1141,7 +1149,14 @@ namespace Barotrauma.Networking
|
|||||||
connectedClients.ForEach(c => c.TeamID = hostTeam);
|
connectedClients.ForEach(c => c.TeamID = hostTeam);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameMain.GameSession.StartRound(GameMain.NetLobbyScreen.LevelSeed, teamCount > 1);
|
if (campaign != null)
|
||||||
|
{
|
||||||
|
GameMain.GameSession.StartRound(campaign.Map.SelectedConnection.Level, true, teamCount > 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameMain.GameSession.StartRound(GameMain.NetLobbyScreen.LevelSeed, teamCount > 1);
|
||||||
|
}
|
||||||
|
|
||||||
GameServer.Log("Starting a new round...", ServerLog.MessageType.ServerMessage);
|
GameServer.Log("Starting a new round...", ServerLog.MessageType.ServerMessage);
|
||||||
GameServer.Log("Submarine: " + selectedSub.Name, ServerLog.MessageType.ServerMessage);
|
GameServer.Log("Submarine: " + selectedSub.Name, ServerLog.MessageType.ServerMessage);
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
public partial class SaveUtil
|
public partial class SaveUtil
|
||||||
{
|
{
|
||||||
public static string SaveFolder = "Data"+Path.DirectorySeparatorChar+"Saves";
|
public static string SaveFolder = "Data" + Path.DirectorySeparatorChar + "Saves";
|
||||||
|
public static string MultiplayerSaveFolder = "Data" + Path.DirectorySeparatorChar + "Saves" + Path.DirectorySeparatorChar + "Multiplayer";
|
||||||
|
|
||||||
public delegate void ProgressDelegate(string sMessage);
|
public delegate void ProgressDelegate(string sMessage);
|
||||||
|
|
||||||
@@ -16,26 +18,225 @@ namespace Barotrauma
|
|||||||
get { return Path.Combine(SaveFolder, "temp"); }
|
get { return Path.Combine(SaveFolder, "temp"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SaveType
|
||||||
|
{
|
||||||
|
Singleplayer,
|
||||||
|
Multiplayer
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveGame(string filePath)
|
||||||
|
{
|
||||||
|
string tempPath = Path.Combine(SaveFolder, "temp");
|
||||||
|
|
||||||
|
Directory.CreateDirectory(tempPath);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ClearFolder(tempPath, new string[] { GameMain.GameSession.Submarine.FilePath });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Submarine.MainSub != null && Submarine.Loaded.Contains(Submarine.MainSub))
|
||||||
|
{
|
||||||
|
Submarine.MainSub.FilePath = Path.Combine(tempPath, Submarine.MainSub.Name + ".sub");
|
||||||
|
Submarine.MainSub.SaveAs(Submarine.MainSub.FilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error saving submarine", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GameMain.GameSession.Save(Path.Combine(tempPath, "gamesession.xml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error saving gamesession", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CompressDirectory(tempPath, filePath, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error compressing save file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LoadGame(string filePath)
|
||||||
|
{
|
||||||
|
DecompressToDirectory(filePath, TempPath, null);
|
||||||
|
|
||||||
|
XDocument doc = ToolBox.TryLoadXml(Path.Combine(TempPath, "gamesession.xml"));
|
||||||
|
|
||||||
|
string subPath = Path.Combine(TempPath, ToolBox.GetAttributeString(doc.Root, "submarine", "")) + ".sub";
|
||||||
|
Submarine selectedMap = new Submarine(subPath, "");
|
||||||
|
GameMain.GameSession = new GameSession(selectedMap, filePath, doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static XDocument LoadGameSessionDoc(string filePath)
|
||||||
|
{
|
||||||
|
string tempPath = Path.Combine(SaveFolder, "temp");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DecompressToDirectory(filePath, tempPath, null);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ToolBox.TryLoadXml(Path.Combine(tempPath, "gamesession.xml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteSave(string filePath)
|
||||||
|
{
|
||||||
|
//filePath = Path.Combine(SaveFolder, filePath + ".save");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("ERROR: deleting save file \"" + filePath + " failed.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] GetSaveFiles(SaveType saveType)
|
||||||
|
{
|
||||||
|
string folder = saveType == SaveType.Singleplayer ? SaveFolder : MultiplayerSaveFolder;
|
||||||
|
|
||||||
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Save folder \"" + folder + " not found! Attempting to create a new folder");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(folder);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Failed to create the folder \"" + folder + "\"!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] files = Directory.GetFiles(folder, "*.save");
|
||||||
|
|
||||||
|
/*for (int i = 0; i < files.Length; i++)
|
||||||
|
{
|
||||||
|
files[i] = Path.GetFileNameWithoutExtension(files[i]);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string CreateSavePath(string fileName = "Save")
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(SaveFolder))
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Save folder \"" + SaveFolder + "\" not found. Created new folder");
|
||||||
|
Directory.CreateDirectory(SaveFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
string extension = ".save";
|
||||||
|
string pathWithoutExtension = Path.Combine(SaveFolder, fileName);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (File.Exists(pathWithoutExtension + " " + i + extension))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathWithoutExtension + " " + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CompressStringToFile(string fileName, string value)
|
||||||
|
{
|
||||||
|
// A.
|
||||||
|
// Write string to temporary file.
|
||||||
|
string temp = Path.GetTempFileName();
|
||||||
|
File.WriteAllText(temp, value);
|
||||||
|
|
||||||
|
// B.
|
||||||
|
// Read file into byte array buffer.
|
||||||
|
byte[] b;
|
||||||
|
using (FileStream f = new FileStream(temp, FileMode.Open))
|
||||||
|
{
|
||||||
|
b = new byte[f.Length];
|
||||||
|
f.Read(b, 0, (int)f.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// C.
|
||||||
|
// Use GZipStream to write compressed bytes to target file.
|
||||||
|
using (FileStream f2 = new FileStream(fileName, FileMode.Create))
|
||||||
|
using (GZipStream gz = new GZipStream(f2, CompressionMode.Compress, false))
|
||||||
|
{
|
||||||
|
gz.Write(b, 0, b.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CompressFile(string sDir, string sRelativePath, GZipStream zipStream)
|
||||||
|
{
|
||||||
|
//Compress file name
|
||||||
|
char[] chars = sRelativePath.ToCharArray();
|
||||||
|
zipStream.Write(BitConverter.GetBytes(chars.Length), 0, sizeof(int));
|
||||||
|
foreach (char c in chars)
|
||||||
|
zipStream.Write(BitConverter.GetBytes(c), 0, sizeof(char));
|
||||||
|
|
||||||
|
//Compress file content
|
||||||
|
byte[] bytes = File.ReadAllBytes(Path.Combine(sDir, sRelativePath));
|
||||||
|
zipStream.Write(BitConverter.GetBytes(bytes.Length), 0, sizeof(int));
|
||||||
|
zipStream.Write(bytes, 0, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CompressDirectory(string sInDir, string sOutFile, ProgressDelegate progress)
|
||||||
|
{
|
||||||
|
string[] sFiles = Directory.GetFiles(sInDir, "*.*", SearchOption.AllDirectories);
|
||||||
|
int iDirLen = sInDir[sInDir.Length - 1] == Path.DirectorySeparatorChar ? sInDir.Length : sInDir.Length + 1;
|
||||||
|
|
||||||
|
using (FileStream outFile = new FileStream(sOutFile, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
|
using (GZipStream str = new GZipStream(outFile, CompressionMode.Compress))
|
||||||
|
foreach (string sFilePath in sFiles)
|
||||||
|
{
|
||||||
|
string sRelativePath = sFilePath.Substring(iDirLen);
|
||||||
|
if (progress != null)
|
||||||
|
progress(sRelativePath);
|
||||||
|
CompressFile(sInDir, sRelativePath, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Stream DecompressFiletoStream(string fileName)
|
public static Stream DecompressFiletoStream(string fileName)
|
||||||
{
|
{
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("File \""+fileName+" doesn't exist!");
|
DebugConsole.ThrowError("File \"" + fileName + " doesn't exist!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (FileStream originalFileStream = new FileStream(fileName, FileMode.Open))
|
using (FileStream originalFileStream = new FileStream(fileName, FileMode.Open))
|
||||||
{
|
{
|
||||||
MemoryStream decompressedFileStream = new MemoryStream();
|
MemoryStream decompressedFileStream = new MemoryStream();
|
||||||
|
|
||||||
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
|
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
|
||||||
{
|
{
|
||||||
decompressionStream.CopyTo(decompressedFileStream);
|
decompressionStream.CopyTo(decompressedFileStream);
|
||||||
return decompressedFileStream;
|
return decompressedFileStream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool DecompressFile(string sDir, GZipStream zipStream, ProgressDelegate progress)
|
public static bool DecompressFile(string sDir, GZipStream zipStream, ProgressDelegate progress)
|
||||||
{
|
{
|
||||||
//Decompress file name
|
//Decompress file name
|
||||||
@@ -75,12 +276,41 @@ namespace Barotrauma
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DecompressToDirectory(string sCompressedFile, string sDir, ProgressDelegate progress)
|
public static void DecompressToDirectory(string sCompressedFile, string sDir, ProgressDelegate progress)
|
||||||
{
|
{
|
||||||
using (FileStream inFile = new FileStream(sCompressedFile, FileMode.Open, FileAccess.Read, FileShare.None))
|
using (FileStream inFile = new FileStream(sCompressedFile, FileMode.Open, FileAccess.Read, FileShare.None))
|
||||||
using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true))
|
using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true))
|
||||||
while (DecompressFile(sDir, zipStream, progress)) ;
|
while (DecompressFile(sDir, zipStream, progress)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ClearFolder(string FolderName, string[] ignoredFiles = null)
|
||||||
|
{
|
||||||
|
DirectoryInfo dir = new DirectoryInfo(FolderName);
|
||||||
|
|
||||||
|
foreach (FileInfo fi in dir.GetFiles())
|
||||||
|
{
|
||||||
|
bool ignore = false;
|
||||||
|
foreach (string ignoredFile in ignoredFiles)
|
||||||
|
{
|
||||||
|
if (Path.GetFullPath(fi.FullName).Equals(Path.GetFullPath(ignoredFile)))
|
||||||
|
{
|
||||||
|
ignore = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignore) continue;
|
||||||
|
|
||||||
|
fi.IsReadOnly = false;
|
||||||
|
fi.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (DirectoryInfo di in dir.GetDirectories())
|
||||||
|
{
|
||||||
|
ClearFolder(di.FullName, ignoredFiles);
|
||||||
|
di.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user