Mission refactoring (mission prefabs) and option to select which types of missions can be selected when mission type is set to random (TODO: a way to set the allowed types from the UI).
This commit is contained in:
@@ -6,10 +6,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public void ShowMessage(int index)
|
public void ShowMessage(int index)
|
||||||
{
|
{
|
||||||
if (index >= headers.Count && index >= messages.Count) return;
|
if (index >= Headers.Count && index >= Messages.Count) return;
|
||||||
|
|
||||||
string header = index < headers.Count ? headers[index] : "";
|
string header = index < Headers.Count ? Headers[index] : "";
|
||||||
string message = index < messages.Count ? messages[index] : "";
|
string message = index < Messages.Count ? Messages[index] : "";
|
||||||
|
|
||||||
GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
|
GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
|
||||||
|
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ namespace Barotrauma
|
|||||||
TitleScreen.LoadState = 2.0f;
|
TitleScreen.LoadState = 2.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
Mission.Init();
|
MissionPrefab.Init();
|
||||||
MapEntityPrefab.Init();
|
MapEntityPrefab.Init();
|
||||||
LevelGenerationParams.LoadPresets();
|
LevelGenerationParams.LoadPresets();
|
||||||
TitleScreen.LoadState = 10.0f;
|
TitleScreen.LoadState = 10.0f;
|
||||||
|
|||||||
@@ -691,6 +691,7 @@ namespace Barotrauma.Networking
|
|||||||
string shuttleHash = inc.ReadString();
|
string shuttleHash = inc.ReadString();
|
||||||
|
|
||||||
string modeName = inc.ReadString();
|
string modeName = inc.ReadString();
|
||||||
|
int missionIndex = inc.ReadInt16();
|
||||||
|
|
||||||
bool respawnAllowed = inc.ReadBoolean();
|
bool respawnAllowed = inc.ReadBoolean();
|
||||||
bool loadSecondSub = inc.ReadBoolean();
|
bool loadSecondSub = inc.ReadBoolean();
|
||||||
@@ -750,7 +751,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (campaign == null)
|
if (campaign == null)
|
||||||
{
|
{
|
||||||
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
|
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, missionIndex < 0 ? null : MissionPrefab.List[missionIndex]);
|
||||||
GameMain.GameSession.StartRound(levelSeed, loadSecondSub);
|
GameMain.GameSession.StartRound(levelSeed, loadSecondSub);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -883,7 +884,7 @@ namespace Barotrauma.Networking
|
|||||||
bool allowSpectating = inc.ReadBoolean();
|
bool allowSpectating = inc.ReadBoolean();
|
||||||
|
|
||||||
YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2);
|
YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2);
|
||||||
int missionTypeIndex = inc.ReadRangedInteger(0, Mission.MissionTypes.Count - 1);
|
int missionTypeIndex = inc.ReadRangedInteger(0, MissionPrefab.MissionTypes.Count - 1);
|
||||||
int modeIndex = inc.ReadByte();
|
int modeIndex = inc.ReadByte();
|
||||||
|
|
||||||
string levelSeed = inc.ReadString();
|
string levelSeed = inc.ReadString();
|
||||||
|
|||||||
@@ -688,9 +688,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SetMissionType(int missionTypeIndex)
|
public void SetMissionType(int missionTypeIndex)
|
||||||
{
|
{
|
||||||
if (missionTypeIndex < 0 || missionTypeIndex >= Mission.MissionTypes.Count) return;
|
if (missionTypeIndex < 0 || missionTypeIndex >= MissionPrefab.MissionTypes.Count) return;
|
||||||
|
|
||||||
missionTypeBlock.GetChild<GUITextBlock>().Text = Mission.MissionTypes[missionTypeIndex];
|
missionTypeBlock.GetChild<GUITextBlock>().Text = MissionPrefab.MissionTypes[missionTypeIndex];
|
||||||
missionTypeBlock.UserData = missionTypeIndex;
|
missionTypeBlock.UserData = missionTypeIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,8 +701,8 @@ namespace Barotrauma
|
|||||||
int missionTypeIndex = (int)missionTypeBlock.UserData;
|
int missionTypeIndex = (int)missionTypeBlock.UserData;
|
||||||
missionTypeIndex += (int)userData;
|
missionTypeIndex += (int)userData;
|
||||||
|
|
||||||
if (missionTypeIndex < 0) missionTypeIndex = Mission.MissionTypes.Count - 1;
|
if (missionTypeIndex < 0) missionTypeIndex = MissionPrefab.MissionTypes.Count - 1;
|
||||||
if (missionTypeIndex >= Mission.MissionTypes.Count) missionTypeIndex = 0;
|
if (missionTypeIndex >= MissionPrefab.MissionTypes.Count) missionTypeIndex = 0;
|
||||||
|
|
||||||
SetMissionType(missionTypeIndex);
|
SetMissionType(missionTypeIndex);
|
||||||
|
|
||||||
|
|||||||
@@ -1471,6 +1471,7 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterInfo.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterInfo.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterNetworking.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\CharacterNetworking.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\DamageModifier.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\DamageModifier.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Events\Missions\MissionPrefab.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\DelayedEffect.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\StatusEffects\DelayedEffect.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\HuskInfection.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\HuskInfection.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Jobs\Job.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Source\Characters\Jobs\Job.cs" />
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private int requiredDeliveryAmount;
|
private int requiredDeliveryAmount;
|
||||||
|
|
||||||
public CargoMission(XElement element, Location[] locations)
|
public CargoMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
itemConfig = element.Element("Items");
|
itemConfig = prefab.ConfigElement.Element("Items");
|
||||||
|
|
||||||
requiredDeliveryAmount = element.GetAttributeInt("requireddeliveryamount", 0);
|
requiredDeliveryAmount = prefab.ConfigElement.GetAttributeInt("requireddeliveryamount", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitItems()
|
private void InitItems()
|
||||||
|
|||||||
@@ -47,20 +47,20 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (winner == -1) return "";
|
if (winner == -1) return "";
|
||||||
|
|
||||||
return successMessage
|
return SuccessMessage
|
||||||
.Replace("[loser]", teamNames[1 - winner])
|
.Replace("[loser]", teamNames[1 - winner])
|
||||||
.Replace("[winner]", teamNames[winner]);
|
.Replace("[winner]", teamNames[winner]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CombatMission(XElement element, Location[] locations)
|
public CombatMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
descriptions = new string[]
|
descriptions = new string[]
|
||||||
{
|
{
|
||||||
element.GetAttributeString("descriptionneutral", ""),
|
prefab.ConfigElement.GetAttributeString("descriptionneutral", ""),
|
||||||
element.GetAttributeString("description1", ""),
|
prefab.ConfigElement.GetAttributeString("description1", ""),
|
||||||
element.GetAttributeString("description2", "")
|
prefab.ConfigElement.GetAttributeString("description2", "")
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < descriptions.Length; i++)
|
for (int i = 0; i < descriptions.Length; i++)
|
||||||
@@ -73,8 +73,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
teamNames = new string[]
|
teamNames = new string[]
|
||||||
{
|
{
|
||||||
element.GetAttributeString("teamname1", "Team A"),
|
prefab.ConfigElement.GetAttributeString("teamname1", "Team A"),
|
||||||
element.GetAttributeString("teamname2", "Team B")
|
prefab.ConfigElement.GetAttributeString("teamname2", "Team B")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +1,18 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
partial class Mission
|
partial class Mission
|
||||||
{
|
{
|
||||||
public static List<string> MissionTypes = new List<string>() { "Random" };
|
|
||||||
|
|
||||||
private string name;
|
|
||||||
|
|
||||||
private string description;
|
|
||||||
|
|
||||||
protected bool completed;
|
protected bool completed;
|
||||||
|
|
||||||
protected string successMessage;
|
private readonly MissionPrefab prefab;
|
||||||
protected string failureMessage;
|
|
||||||
|
|
||||||
protected string radarLabel;
|
|
||||||
|
|
||||||
protected List<string> headers;
|
|
||||||
protected List<string> messages;
|
|
||||||
|
|
||||||
private int reward;
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return name; }
|
get { return prefab.Name; }
|
||||||
}
|
|
||||||
|
|
||||||
public virtual string Description
|
|
||||||
{
|
|
||||||
get { return description; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Reward
|
|
||||||
{
|
|
||||||
get { return reward; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Completed
|
public bool Completed
|
||||||
@@ -48,109 +21,101 @@ namespace Barotrauma
|
|||||||
set { completed = value; }
|
set { completed = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int Reward
|
||||||
|
{
|
||||||
|
get { return prefab.Reward; }
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool AllowRespawn
|
public virtual bool AllowRespawn
|
||||||
{
|
{
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string RadarLabel
|
|
||||||
{
|
|
||||||
get { return radarLabel; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Vector2 RadarPosition
|
public virtual Vector2 RadarPosition
|
||||||
{
|
{
|
||||||
get { return Vector2.Zero; }
|
get { return Vector2.Zero; }
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual public string SuccessMessage
|
public string RadarLabel
|
||||||
{
|
{
|
||||||
get { return successMessage; }
|
get { return prefab.RadarLabel; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> Headers
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> Messages
|
||||||
|
{
|
||||||
|
get; private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string SuccessMessage
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FailureMessage
|
public string FailureMessage
|
||||||
{
|
{
|
||||||
get { return failureMessage; }
|
get;
|
||||||
|
protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Init()
|
public virtual string Description
|
||||||
{
|
{
|
||||||
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
|
get;
|
||||||
foreach (string file in files)
|
protected set;
|
||||||
{
|
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(file);
|
|
||||||
if (doc == null || doc.Root == null) continue;
|
|
||||||
|
|
||||||
foreach (XElement element in doc.Root.Elements())
|
|
||||||
{
|
|
||||||
string missionTypeName = element.Name.ToString();
|
|
||||||
missionTypeName = missionTypeName.Replace("Mission", "");
|
|
||||||
|
|
||||||
if (!MissionTypes.Contains(missionTypeName)) MissionTypes.Add(missionTypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mission(XElement element, Location[] locations)
|
public MissionPrefab Prefab
|
||||||
{
|
{
|
||||||
name = element.GetAttributeString("name", "");
|
get { return prefab; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mission(MissionPrefab prefab, Location[] locations)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.Assert(locations.Length == 2);
|
||||||
|
|
||||||
description = element.GetAttributeString("description", "");
|
this.prefab = prefab;
|
||||||
|
|
||||||
reward = element.GetAttributeInt("reward", 1);
|
Description = prefab.Description;
|
||||||
|
SuccessMessage = prefab.SuccessMessage;
|
||||||
successMessage = element.GetAttributeString("successmessage",
|
FailureMessage = prefab.FailureMessage;
|
||||||
"Mission completed successfully");
|
Headers = new List<string>(prefab.Headers);
|
||||||
failureMessage = element.GetAttributeString("failuremessage",
|
Messages = new List<string>(prefab.Messages);
|
||||||
"Mission failed");
|
|
||||||
|
|
||||||
radarLabel = element.GetAttributeString("radarlabel", "");
|
|
||||||
|
|
||||||
messages = new List<string>();
|
|
||||||
headers = new List<string>();
|
|
||||||
foreach (XElement subElement in element.Elements())
|
|
||||||
{
|
|
||||||
if (subElement.Name.ToString().ToLowerInvariant() != "message") continue;
|
|
||||||
headers.Add(subElement.GetAttributeString("header", ""));
|
|
||||||
messages.Add(subElement.GetAttributeString("text", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int n = 0; n < 2; n++)
|
for (int n = 0; n < 2; n++)
|
||||||
{
|
{
|
||||||
description = description.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
Description = Description.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
|
SuccessMessage = SuccessMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
successMessage = successMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
FailureMessage = FailureMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
failureMessage = failureMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
|
for (int m = 0; m < Messages.Count; m++)
|
||||||
|
|
||||||
for (int m = 0; m < messages.Count; m++)
|
|
||||||
{
|
{
|
||||||
messages[m] = messages[m].Replace("[location" + (n + 1) + "]", locations[n].Name);
|
Messages[m] = Messages[m].Replace("[location" + (n + 1) + "]", locations[n].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Mission LoadRandom(Location[] locations, string seed, string missionType = "", bool isSinglePlayer = false)
|
||||||
|
{
|
||||||
|
return LoadRandom(locations, new MTRandom(ToolBox.StringToInt(seed)), missionType, isSinglePlayer);
|
||||||
|
}
|
||||||
|
|
||||||
public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false)
|
public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false)
|
||||||
{
|
{
|
||||||
|
//todo: use something else than strings to define the mission type
|
||||||
missionType = missionType.ToLowerInvariant();
|
missionType = missionType.ToLowerInvariant();
|
||||||
|
|
||||||
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
|
List<MissionPrefab> allowedMissions = new List<MissionPrefab>();
|
||||||
string configFile = files[rand.Next(files.Count)];
|
|
||||||
|
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(configFile);
|
|
||||||
if (doc == null) return null;
|
|
||||||
|
|
||||||
int eventCount = doc.Root.Elements().Count();
|
|
||||||
//int[] commonness = new int[eventCount];
|
|
||||||
float[] eventProbability = new float[eventCount];
|
|
||||||
|
|
||||||
float probabilitySum = 0.0f;
|
|
||||||
|
|
||||||
List<XElement> matchingElements = new List<XElement>();
|
|
||||||
|
|
||||||
if (missionType == "random")
|
if (missionType == "random")
|
||||||
{
|
{
|
||||||
matchingElements = doc.Root.Elements().ToList();
|
allowedMissions.AddRange(MissionPrefab.List);
|
||||||
|
if (GameMain.Server != null)
|
||||||
|
{
|
||||||
|
allowedMissions.RemoveAll(mission => !GameMain.Server.AllowedRandomMissionTypes.Any(a => mission.TypeMatches(a)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (missionType == "none")
|
else if (missionType == "none")
|
||||||
{
|
{
|
||||||
@@ -158,68 +123,31 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else if (string.IsNullOrWhiteSpace(missionType))
|
else if (string.IsNullOrWhiteSpace(missionType))
|
||||||
{
|
{
|
||||||
matchingElements = doc.Root.Elements().ToList();
|
allowedMissions.AddRange(MissionPrefab.List);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matchingElements = doc.Root.Elements().ToList().FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType);
|
allowedMissions = MissionPrefab.List.FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSinglePlayer)
|
if (isSinglePlayer)
|
||||||
{
|
{
|
||||||
matchingElements.RemoveAll(m => m.GetAttributeBool("multiplayeronly", false));
|
allowedMissions.RemoveAll(m => m.MultiplayerOnly);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matchingElements.RemoveAll(m => m.GetAttributeBool("singleplayeronly", false));
|
allowedMissions.RemoveAll(m => m.SingleplayerOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
float probabilitySum = allowedMissions.Sum(m => m.Commonness);
|
||||||
foreach (XElement element in matchingElements)
|
|
||||||
{
|
|
||||||
eventProbability[i] = element.GetAttributeInt("commonness", 1);
|
|
||||||
|
|
||||||
probabilitySum += eventProbability[i];
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
float randomNumber = (float)rand.NextDouble() * probabilitySum;
|
float randomNumber = (float)rand.NextDouble() * probabilitySum;
|
||||||
|
foreach (MissionPrefab missionPrefab in allowedMissions)
|
||||||
i = 0;
|
|
||||||
foreach (XElement element in matchingElements)
|
|
||||||
{
|
{
|
||||||
if (randomNumber <= eventProbability[i])
|
if (randomNumber <= missionPrefab.Commonness)
|
||||||
{
|
{
|
||||||
Type t;
|
return missionPrefab.Instantiate(locations);
|
||||||
string type = element.Name.ToString();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
t = Type.GetType("Barotrauma." + type, true, true);
|
|
||||||
if (t == null)
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\".");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Error in " + configFile + "! Could not find a mission class of the type \"" + type + "\".");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstructorInfo constructor = t.GetConstructor(new[] { typeof(XElement), typeof(Location[]) });
|
|
||||||
|
|
||||||
object instance = constructor.Invoke(new object[] { element, locations });
|
|
||||||
|
|
||||||
Mission mission = (Mission)instance;
|
|
||||||
|
|
||||||
return mission;
|
|
||||||
}
|
}
|
||||||
|
randomNumber -= missionPrefab.Commonness;
|
||||||
randomNumber -= eventProbability[i];
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -251,7 +179,7 @@ namespace Barotrauma
|
|||||||
var mode = GameMain.GameSession.GameMode as CampaignMode;
|
var mode = GameMain.GameSession.GameMode as CampaignMode;
|
||||||
if (mode == null) return;
|
if (mode == null) return;
|
||||||
|
|
||||||
mode.Money += reward;
|
mode.Money += Reward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Barotrauma
|
||||||
|
{
|
||||||
|
class MissionPrefab
|
||||||
|
{
|
||||||
|
public static List<MissionPrefab> List = new List<MissionPrefab>();
|
||||||
|
public static List<string> MissionTypes = new List<string>() { "Random" };
|
||||||
|
|
||||||
|
private string name;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type missionType;
|
||||||
|
private ConstructorInfo constructor;
|
||||||
|
|
||||||
|
public virtual string Description { get; private set; }
|
||||||
|
|
||||||
|
public bool MultiplayerOnly { get; private set; }
|
||||||
|
public bool SingleplayerOnly { get; private set; }
|
||||||
|
|
||||||
|
public float Commonness { get; private set; }
|
||||||
|
|
||||||
|
public int Reward { get; private set; }
|
||||||
|
|
||||||
|
public string RadarLabel { get; private set; }
|
||||||
|
|
||||||
|
public List<string> Headers { get; private set; }
|
||||||
|
public List<string> Messages { get; private set; }
|
||||||
|
|
||||||
|
public string SuccessMessage { get; private set; }
|
||||||
|
public string FailureMessage { get; private set; }
|
||||||
|
|
||||||
|
public XElement ConfigElement { get; private set; }
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
XDocument doc = XMLExtensions.TryLoadXml(file);
|
||||||
|
if (doc?.Root == null) continue;
|
||||||
|
|
||||||
|
foreach (XElement element in doc.Root.Elements())
|
||||||
|
{
|
||||||
|
string missionTypeName = element.Name.ToString();
|
||||||
|
missionTypeName = missionTypeName.Replace("Mission", "");
|
||||||
|
|
||||||
|
List.Add(new MissionPrefab(element));
|
||||||
|
if (!MissionTypes.Contains(missionTypeName)) MissionTypes.Add(missionTypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MissionPrefab(XElement element)
|
||||||
|
{
|
||||||
|
ConfigElement = element;
|
||||||
|
|
||||||
|
name = element.GetAttributeString("name", "");
|
||||||
|
Description = element.GetAttributeString("description", "");
|
||||||
|
Commonness = element.GetAttributeFloat("commonness", 1.0f);
|
||||||
|
SingleplayerOnly = element.GetAttributeBool("singleplayeronly", false);
|
||||||
|
MultiplayerOnly = element.GetAttributeBool("multiplayeronly", false);
|
||||||
|
|
||||||
|
Reward = element.GetAttributeInt("reward", 1);
|
||||||
|
|
||||||
|
SuccessMessage = element.GetAttributeString("successmessage", "Mission completed successfully");
|
||||||
|
FailureMessage = element.GetAttributeString("failuremessage", "Mission failed");
|
||||||
|
RadarLabel = element.GetAttributeString("radarlabel", "");
|
||||||
|
|
||||||
|
Messages = new List<string>();
|
||||||
|
Headers = new List<string>();
|
||||||
|
foreach (XElement subElement in element.Elements())
|
||||||
|
{
|
||||||
|
if (subElement.Name.ToString().ToLowerInvariant() != "message") continue;
|
||||||
|
Headers.Add(subElement.GetAttributeString("header", ""));
|
||||||
|
Messages.Add(subElement.GetAttributeString("text", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
string type = element.Name.ToString();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
missionType = Type.GetType("Barotrauma." + type, true, true);
|
||||||
|
if (missionType == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in mission prefab " + Name + "! Could not find a mission class of the type \"" + type + "\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Error in mission prefab " + Name + "! Could not find a mission class of the type \"" + type + "\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
constructor = missionType.GetConstructor(new[] { typeof(MissionPrefab), typeof(Location[]) });
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mission Instantiate(Location[] locations)
|
||||||
|
{
|
||||||
|
return constructor?.Invoke(new object[] { this, locations }) as Mission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TypeMatches(string typeName)
|
||||||
|
{
|
||||||
|
//TODO: use enums instead of strings?
|
||||||
|
typeName = typeName.ToLowerInvariant();
|
||||||
|
return missionType.Name.ToString().Replace("Mission", "").ToLowerInvariant() == typeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,10 +18,10 @@ namespace Barotrauma
|
|||||||
get { return monster != null && !monster.IsDead ? radarPosition : Vector2.Zero; }
|
get { return monster != null && !monster.IsDead ? radarPosition : Vector2.Zero; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonsterMission(XElement element, Location[] locations)
|
public MonsterMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
monsterFile = element.GetAttributeString("monsterfile", "");
|
monsterFile = prefab.ConfigElement.GetAttributeString("monsterfile", "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using FarseerPhysics;
|
using FarseerPhysics;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -23,10 +22,10 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SalvageMission(XElement element, Location[] locations)
|
public SalvageMission(MissionPrefab prefab, Location[] locations)
|
||||||
: base(element, locations)
|
: base(prefab, locations)
|
||||||
{
|
{
|
||||||
string itemName = element.GetAttributeString("itemname", "");
|
string itemName = prefab.ConfigElement.GetAttributeString("itemname", "");
|
||||||
|
|
||||||
itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
|
itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
|
||||||
if (itemPrefab == null)
|
if (itemPrefab == null)
|
||||||
@@ -35,10 +34,10 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string spawnPositionTypeStr = element.GetAttributeString("spawntype", "");
|
string spawnPositionTypeStr = prefab.ConfigElement.GetAttributeString("spawntype", "");
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
|
if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
|
||||||
!Enum.TryParse<Level.PositionType>(spawnPositionTypeStr, true, out spawnPositionType))
|
!Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType))
|
||||||
{
|
{
|
||||||
spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
|
spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,22 @@
|
|||||||
: base(preset, param)
|
: base(preset, param)
|
||||||
{
|
{
|
||||||
Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation };
|
Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation };
|
||||||
|
if (param is string)
|
||||||
MTRandom rand = new MTRandom(ToolBox.StringToInt(GameMain.NetLobbyScreen.LevelSeed));
|
{
|
||||||
mission = Mission.LoadRandom(locations, rand, param as string);
|
mission = Mission.LoadRandom(locations, GameMain.NetLobbyScreen.LevelSeed, (string)param);
|
||||||
|
}
|
||||||
|
else if (param is MissionPrefab)
|
||||||
|
{
|
||||||
|
mission = ((MissionPrefab)param).Instantiate(locations);
|
||||||
|
}
|
||||||
|
else if (param is Mission)
|
||||||
|
{
|
||||||
|
mission = (Mission)param;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new System.ArgumentException("Unrecognized MissionMode parameter \"" + param + "\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,27 +91,35 @@ namespace Barotrauma
|
|||||||
set { savePath = value; }
|
set { savePath = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset = null, string missionType = "")
|
|
||||||
|
public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset, string missionType = "")
|
||||||
|
: this(submarine, savePath)
|
||||||
|
{
|
||||||
|
GameMode = gameModePreset.Instantiate(missionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameSession(Submarine submarine, string savePath, GameModePreset gameModePreset, MissionPrefab missionPrefab)
|
||||||
|
: this(submarine, savePath)
|
||||||
|
{
|
||||||
|
GameMode = gameModePreset.Instantiate(missionPrefab);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameSession(Submarine submarine, string savePath)
|
||||||
{
|
{
|
||||||
Submarine.MainSub = submarine;
|
Submarine.MainSub = submarine;
|
||||||
|
this.submarine = submarine;
|
||||||
GameMain.GameSession = this;
|
GameMain.GameSession = this;
|
||||||
|
|
||||||
EventManager = new EventManager(this);
|
EventManager = new EventManager(this);
|
||||||
|
|
||||||
this.savePath = savePath;
|
this.savePath = savePath;
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
CrewManager = new CrewManager();
|
CrewManager = new CrewManager();
|
||||||
|
|
||||||
infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", "", null);
|
infoButton = new GUIButton(new Rectangle(10, 10, 100, 20), "Info", "", null);
|
||||||
infoButton.OnClicked = ToggleInfoFrame;
|
infoButton.OnClicked = ToggleInfoFrame;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gameModePreset != null) GameMode = gameModePreset.Instantiate(missionType);
|
|
||||||
this.submarine = submarine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public GameSession(Submarine selectedSub, string saveFile, XDocument doc)
|
public GameSession(Submarine selectedSub, string saveFile, XDocument doc)
|
||||||
: this(selectedSub, saveFile)
|
: this(selectedSub, saveFile)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -993,7 +993,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
outmsg.WriteRangedInteger(0, 2, (int)TraitorsEnabled);
|
outmsg.WriteRangedInteger(0, 2, (int)TraitorsEnabled);
|
||||||
|
|
||||||
outmsg.WriteRangedInteger(0, Mission.MissionTypes.Count - 1, (GameMain.NetLobbyScreen.MissionTypeIndex));
|
outmsg.WriteRangedInteger(0, MissionPrefab.MissionTypes.Count - 1, (GameMain.NetLobbyScreen.MissionTypeIndex));
|
||||||
|
|
||||||
outmsg.Write((byte)GameMain.NetLobbyScreen.SelectedModeIndex);
|
outmsg.Write((byte)GameMain.NetLobbyScreen.SelectedModeIndex);
|
||||||
outmsg.Write(GameMain.NetLobbyScreen.LevelSeed);
|
outmsg.Write(GameMain.NetLobbyScreen.LevelSeed);
|
||||||
@@ -1213,7 +1213,7 @@ namespace Barotrauma.Networking
|
|||||||
//don't instantiate a new gamesession if we're playing a campaign
|
//don't instantiate a new gamesession if we're playing a campaign
|
||||||
if (campaign == null || GameMain.GameSession == null)
|
if (campaign == null || GameMain.GameSession == null)
|
||||||
{
|
{
|
||||||
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
|
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, MissionPrefab.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMain.GameSession.GameMode.Mission != null &&
|
if (GameMain.GameSession.GameMode.Mission != null &&
|
||||||
@@ -1402,6 +1402,8 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash);
|
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash);
|
||||||
|
|
||||||
msg.Write(selectedMode.Name);
|
msg.Write(selectedMode.Name);
|
||||||
|
msg.Write((short)(GameMain.GameSession.GameMode?.Mission == null ?
|
||||||
|
-1 : MissionPrefab.List.IndexOf(GameMain.GameSession.GameMode.Mission.Prefab)));
|
||||||
|
|
||||||
MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,12 @@ namespace Barotrauma.Networking
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<string> AllowedRandomMissionTypes
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
[Serialize(60f, true)]
|
[Serialize(60f, true)]
|
||||||
public float AutoBanTime
|
public float AutoBanTime
|
||||||
{
|
{
|
||||||
@@ -287,6 +293,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
doc.Root.SetAttributeValue("TraitorsEnabled", TraitorsEnabled.ToString());
|
doc.Root.SetAttributeValue("TraitorsEnabled", TraitorsEnabled.ToString());
|
||||||
|
|
||||||
|
doc.Root.SetAttributeValue("AllowedRandomMissionTypes", string.Join(",", AllowedRandomMissionTypes));
|
||||||
|
|
||||||
#if SERVER
|
#if SERVER
|
||||||
doc.Root.SetAttributeValue("password", password);
|
doc.Root.SetAttributeValue("password", password);
|
||||||
#endif
|
#endif
|
||||||
@@ -334,18 +342,22 @@ namespace Barotrauma.Networking
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
subSelectionMode = SelectionMode.Manual;
|
subSelectionMode = SelectionMode.Manual;
|
||||||
Enum.TryParse<SelectionMode>(doc.Root.GetAttributeString("SubSelection", "Manual"), out subSelectionMode);
|
Enum.TryParse(doc.Root.GetAttributeString("SubSelection", "Manual"), out subSelectionMode);
|
||||||
Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote;
|
Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote;
|
||||||
|
|
||||||
modeSelectionMode = SelectionMode.Manual;
|
modeSelectionMode = SelectionMode.Manual;
|
||||||
Enum.TryParse<SelectionMode>(doc.Root.GetAttributeString("ModeSelection", "Manual"), out modeSelectionMode);
|
Enum.TryParse(doc.Root.GetAttributeString("ModeSelection", "Manual"), out modeSelectionMode);
|
||||||
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
|
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
|
||||||
|
|
||||||
var traitorsEnabled = TraitorsEnabled;
|
var traitorsEnabled = TraitorsEnabled;
|
||||||
Enum.TryParse<YesNoMaybe>(doc.Root.GetAttributeString("TraitorsEnabled", "No"), out traitorsEnabled);
|
Enum.TryParse(doc.Root.GetAttributeString("TraitorsEnabled", "No"), out traitorsEnabled);
|
||||||
TraitorsEnabled = traitorsEnabled;
|
TraitorsEnabled = traitorsEnabled;
|
||||||
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
|
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
|
||||||
|
|
||||||
|
AllowedRandomMissionTypes = doc.Root.GetAttributeStringArray(
|
||||||
|
"AllowedRandomMissionTypes",
|
||||||
|
MissionPrefab.MissionTypes.ToArray()).ToList();
|
||||||
|
|
||||||
if (GameMain.NetLobbyScreen != null
|
if (GameMain.NetLobbyScreen != null
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
&& GameMain.NetLobbyScreen.ServerMessage != null
|
&& GameMain.NetLobbyScreen.ServerMessage != null
|
||||||
|
|||||||
Reference in New Issue
Block a user