Renamed project folders from Subsurface to Barotrauma

This commit is contained in:
Regalis
2017-06-04 15:00:53 +03:00
parent ad03c8bf0d
commit 94c6a8ea1b
697 changed files with 157 additions and 211 deletions
+79
View File
@@ -0,0 +1,79 @@
using Microsoft.Xna.Framework;
using System;
using System.Xml.Linq;
namespace Barotrauma
{
class ArtifactEvent : ScriptedEvent
{
private ItemPrefab itemPrefab;
private Item item;
private int state;
public override string ToString()
{
return "ScriptedEvent (" + (itemPrefab==null ? "null" : itemPrefab.Name) + ")";
}
public ArtifactEvent(XElement element)
: base(element)
{
string itemName = ToolBox.GetAttributeString(element, "itemname", "");
itemPrefab = ItemPrefab.list.Find(ip => ip.Name == itemName) as ItemPrefab;
if (itemPrefab == null)
{
DebugConsole.ThrowError("Error in SalvageMission: couldn't find an item prefab with the name "+itemName);
}
}
public override void Init()
{
base.Init();
Vector2 position = Level.Loaded.GetRandomItemPos(
Level.PositionType.Cave | Level.PositionType.MainPath | Level.PositionType.Ruin, 500.0f, 30.0f);
item = new Item(itemPrefab, position, null);
item.MoveWithLevel = true;
item.body.FarseerBody.IsKinematic = true;
//try to find a nearby artifact holder (or any alien itemcontainer) and place the artifact inside it
foreach (Item it in Item.ItemList)
{
if (it.Submarine != null || !it.HasTag("alien")) continue;
if (Math.Abs(item.WorldPosition.X - it.WorldPosition.X) > 2000.0f) continue;
if (Math.Abs(item.WorldPosition.Y - it.WorldPosition.Y) > 2000.0f) continue;
var itemContainer = it.GetComponent<Items.Components.ItemContainer>();
if (itemContainer == null) continue;
itemContainer.Combine(item);
break;
}
}
public override void Update(float deltaTime)
{
switch (state)
{
case 0:
if (item.ParentInventory!=null) item.body.FarseerBody.IsKinematic = false;
if (item.CurrentHull == null) return;
state = 1;
break;
case 1:
if (!Submarine.MainSub.AtEndPosition && !Submarine.MainSub.AtStartPosition) return;
Finished();
state = 2;
break;
}
}
}
}
@@ -0,0 +1,115 @@
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
class CargoMission : Mission
{
private XElement itemConfig;
private List<Item> items;
private int requiredDeliveryAmount;
public CargoMission(XElement element, Location[] locations)
: base(element, locations)
{
itemConfig = element.Element("Items");
requiredDeliveryAmount = ToolBox.GetAttributeInt(element, "requireddeliveryamount", 0);
}
private void InitItems()
{
items = new List<Item>();
if (itemConfig==null)
{
DebugConsole.ThrowError("Failed to initialize items for cargo mission (itemConfig == null)");
return;
}
foreach (XElement subElement in itemConfig.Elements())
{
LoadItemAsChild(subElement, null);
}
if (requiredDeliveryAmount == 0) requiredDeliveryAmount = items.Count;
}
private void LoadItemAsChild(XElement element, Item parent)
{
string itemName = ToolBox.GetAttributeString(element, "name", "");
ItemPrefab itemPrefab = ItemPrefab.list.Find(ip => ip.Name == itemName) as ItemPrefab;
if (itemPrefab==null)
{
DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \""+element.Name.ToString()+"\" not found");
return;
}
WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, true);
if (cargoSpawnPos==null)
{
DebugConsole.ThrowError("Couldn't spawn items for cargo mission, cargo spawnpoint not found");
return;
}
var cargoRoom = cargoSpawnPos.CurrentHull;
if (cargoRoom == null)
{
DebugConsole.ThrowError("A waypoint marked as Cargo must be placed inside a room!");
return;
}
Vector2 position = new Vector2(
cargoSpawnPos.Position.X + Rand.Range(-20.0f, 20.0f, false),
cargoRoom.Rect.Y - cargoRoom.Rect.Height + itemPrefab.Size.Y / 2);
var item = new Item(itemPrefab, position, cargoRoom.Submarine);
item.FindHull();
items.Add(item);
if (parent != null) parent.Combine(item);
foreach (XElement subElement in element.Elements())
{
int amount = ToolBox.GetAttributeInt(subElement, "amount", 1);
for (int i = 0; i < amount; i++)
{
LoadItemAsChild(subElement, item);
}
}
}
public override void Start(Level level)
{
InitItems();
}
public override void End()
{
if (Submarine.MainSub != null && Submarine.MainSub.AtEndPosition)
{
int deliveredItemCount = items.Count(i => i.CurrentHull != null && i.Condition > 0.0f);
if (deliveredItemCount >= requiredDeliveryAmount)
{
GiveReward();
completed = true;
}
}
items.ForEach(i => i.Remove());
}
}
}
@@ -0,0 +1,235 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Xml.Linq;
namespace Barotrauma
{
class CombatMission : Mission
{
private Submarine[] subs;
private List<Character>[] crews;
private int state = 0;
private int winner = -1;
private string[] descriptions;
private static string[] teamNames = { "Team A", "Team B" };
private bool initialized = false;
public override bool AllowRespawn
{
get { return false; }
}
public override string Description
{
get
{
if (GameMain.NetworkMember==null || GameMain.NetworkMember.Character==null)
{
//non-team-specific description
return descriptions[0];
}
//team specific
return descriptions[GameMain.NetworkMember.Character.TeamID];
}
}
public override string SuccessMessage
{
get
{
if (winner == -1) return "";
return successMessage
.Replace("[loser]", teamNames[1 - winner])
.Replace("[winner]", teamNames[winner]);
}
}
public CombatMission(XElement element, Location[] locations)
: base(element, locations)
{
descriptions = new string[]
{
ToolBox.GetAttributeString(element, "descriptionneutral", ""),
ToolBox.GetAttributeString(element, "description1", ""),
ToolBox.GetAttributeString(element, "description2", "")
};
for (int i = 0; i < descriptions.Length; i++)
{
for (int n = 0; n < 2; n++)
{
descriptions[i] = descriptions[i].Replace("[location" + (n + 1) + "]", locations[n].Name);
}
}
teamNames = new string[]
{
ToolBox.GetAttributeString(element, "teamname1", "Team A"),
ToolBox.GetAttributeString(element, "teamname2", "Team B")
};
}
public static string GetTeamName(int teamID)
{
//team IDs start from 1, while teamName array starts from 0
teamID--;
if (teamID < 0 || teamID >= teamNames.Length)
{
return "Team " + teamID;
}
return teamNames[teamID];
}
public override bool AssignTeamIDs(List<Client> clients, out byte hostTeam)
{
List<Client> randList = new List<Client>(clients);
for (int i = 0; i < randList.Count; i++)
{
Client a = randList[i];
int oi = Rand.Range(0, randList.Count - 1);
Client b = randList[oi];
randList[i] = b;
randList[oi] = a;
}
int halfPlayers = randList.Count / 2;
for (int i = 0; i < randList.Count; i++)
{
if (i < halfPlayers)
{
randList[i].TeamID = 1;
}
else
{
randList[i].TeamID = 2;
}
}
if (halfPlayers * 2 == randList.Count)
{
hostTeam = (byte)Rand.Range(1, 2);
}
else if (halfPlayers * 2 < randList.Count)
{
hostTeam = 1;
}
else
{
hostTeam = 2;
}
return true;
}
public override void Start(Level level)
{
if (GameMain.NetworkMember == null)
{
DebugConsole.ThrowError("Combat missions cannot be played in the single player mode.");
return;
}
subs = new Submarine[] { Submarine.MainSubs[0], Submarine.MainSubs[1] };
subs[1].SetPosition(Level.Loaded.EndPosition - new Vector2(0.0f, 2000.0f));
subs[1].FlipX();
crews = new List<Character>[] { new List<Character>(), new List<Character>() };
foreach (Submarine submarine in Submarine.Loaded)
{
//hide all subs from radar to make sneak attacks possible
submarine.OnRadar = false;
}
}
public override void Update(float deltaTime)
{
if (!initialized)
{
crews[0].Clear();
crews[1].Clear();
foreach (Character character in Character.CharacterList)
{
if (character.TeamID == 1)
{
crews[0].Add(character);
}
else if (character.TeamID == 2)
{
crews[1].Add(character);
}
}
if (GameMain.Client != null)
{
//no characters in one of the teams, the client may not have received all spawn messages yet
if (crews[0].Count == 0 || crews[1].Count == 0) return;
}
initialized = true;
}
bool[] teamDead =
{
crews[0].All(c => c.IsDead || c.IsUnconscious),
crews[1].All(c => c.IsDead || c.IsUnconscious)
};
if (state == 0)
{
for (int i = 0; i < teamDead.Length; i++)
{
if (!teamDead[i] && teamDead[1-i])
{
//make sure nobody in the other team can be revived because that would be pretty weird
crews[1-i].ForEach(c => { if (!c.IsDead) c.Kill(CauseOfDeath.Damage); });
winner = i;
ShowMessage(i);
state = 1;
break;
}
}
}
else
{
if (winner>=0 && subs[winner] != null &&
(winner == 0 && subs[winner].AtStartPosition) || (winner == 1 && subs[winner].AtEndPosition) &&
crews[winner].Any(c => !c.IsDead && c.Submarine == subs[winner]))
{
GameMain.GameSession.CrewManager.WinningTeam = winner+1;
if (GameMain.Server != null) GameMain.Server.EndGame();
}
}
if (teamDead[0] && teamDead[1])
{
GameMain.GameSession.CrewManager.WinningTeam = 0;
winner = -1;
if (GameMain.Server != null) GameMain.Server.EndGame();
}
}
public override void End()
{
if (GameMain.NetworkMember == null) return;
if (winner > -1)
{
GiveReward();
completed = true;
}
}
}
}
@@ -0,0 +1,270 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace Barotrauma
{
class Mission
{
public static List<string> MissionTypes = new List<string>() { "Random" };
private string name;
private string description;
protected bool completed;
protected string successMessage;
protected string failureMessage;
protected string radarLabel;
protected List<string> headers;
protected List<string> messages;
private int reward;
public string Name
{
get { return name; }
}
public virtual string Description
{
get { return description; }
}
public int Reward
{
get { return reward; }
}
public bool Completed
{
get { return completed; }
set { completed = value; }
}
public virtual bool AllowRespawn
{
get { return true; }
}
public virtual string RadarLabel
{
get { return radarLabel; }
}
public virtual Vector2 RadarPosition
{
get { return Vector2.Zero; }
}
virtual public string SuccessMessage
{
get { return successMessage; }
}
public string FailureMessage
{
get { return failureMessage; }
}
public static void Init()
{
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
foreach (string file in files)
{
XDocument doc = ToolBox.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)
{
name = ToolBox.GetAttributeString(element, "name", "");
description = ToolBox.GetAttributeString(element, "description", "");
reward = ToolBox.GetAttributeInt(element, "reward", 1);
successMessage = ToolBox.GetAttributeString(element, "successmessage",
"Mission completed successfully");
failureMessage = ToolBox.GetAttributeString(element, "failuremessage",
"Mission failed");
radarLabel = ToolBox.GetAttributeString(element, "radarlabel", "");
messages = new List<string>();
headers = new List<string>();
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() != "message") continue;
headers.Add(ToolBox.GetAttributeString(subElement, "header", ""));
messages.Add(ToolBox.GetAttributeString(subElement, "text", ""));
}
for (int n = 0; n < 2; n++)
{
description = description.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);
for (int m = 0; m < messages.Count; m++)
{
messages[m] = messages[m].Replace("[location" + (n + 1) + "]", locations[n].Name);
}
}
}
public static Mission LoadRandom(Location[] locations, MTRandom rand, string missionType = "", bool isSinglePlayer = false)
{
missionType = missionType.ToLowerInvariant();
var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.Missions);
string configFile = files[rand.Next(files.Count)];
XDocument doc = ToolBox.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")
{
matchingElements = doc.Root.Elements().ToList();
}
else if (missionType == "none")
{
return null;
}
else if (string.IsNullOrWhiteSpace(missionType))
{
matchingElements = doc.Root.Elements().ToList();
}
else
{
matchingElements = doc.Root.Elements().ToList().FindAll(m => m.Name.ToString().ToLowerInvariant().Replace("mission", "") == missionType);
}
if (isSinglePlayer)
{
matchingElements.RemoveAll(m => ToolBox.GetAttributeBool(m, "multiplayeronly", false));
}
else
{
matchingElements.RemoveAll(m => ToolBox.GetAttributeBool(m, "singleplayeronly", false));
}
int i = 0;
foreach (XElement element in matchingElements)
{
eventProbability[i] = ToolBox.GetAttributeInt(element, "commonness", 1);
probabilitySum += eventProbability[i];
i++;
}
float randomNumber = (float)rand.NextDouble() * probabilitySum;
i = 0;
foreach (XElement element in matchingElements)
{
if (randomNumber <= eventProbability[i])
{
Type t;
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 -= eventProbability[i];
i++;
}
return null;
}
public virtual void Start(Level level) { }
public virtual void Update(float deltaTime) { }
public virtual bool AssignTeamIDs(List<Networking.Client> clients, out byte hostTeam)
{
clients.ForEach(c => c.TeamID = 1);
hostTeam = 1;
return false;
}
public void ShowMessage(int index)
{
if (index >= headers.Count && index >= messages.Count) return;
string header = index < headers.Count ? headers[index] : "";
string message = index < messages.Count ? messages[index] : "";
GameServer.Log("Mission info: " + header + " - " + message, ServerLog.MessageType.ServerMessage);
new GUIMessageBox(header, message);
}
/// <summary>
/// End the mission and give a reward if it was completed successfully
/// </summary>
public virtual void End()
{
completed = true;
GiveReward();
}
public void GiveReward()
{
var mode = GameMain.GameSession.gameMode as SinglePlayerMode;
if (mode == null) return;
mode.Money += reward;
}
}
}
@@ -0,0 +1,64 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Xml.Linq;
namespace Barotrauma
{
class MonsterMission : Mission
{
private string monsterFile;
private int state;
private Character monster;
private Vector2 radarPosition;
public override Vector2 RadarPosition
{
get { return monster != null && !monster.IsDead ? radarPosition : Vector2.Zero; }
}
public MonsterMission(XElement element, Location[] locations)
: base(element, locations)
{
monsterFile = ToolBox.GetAttributeString(element, "monsterfile", "");
}
public override void Start(Level level)
{
Vector2 spawnPos = Level.Loaded.GetRandomInterestingPosition(true, Level.PositionType.MainPath, true);
monster = Character.Create(monsterFile, spawnPos, null, GameMain.Client != null);
monster.Enabled = false;
radarPosition = spawnPos;
}
public override void Update(float deltaTime)
{
switch (state)
{
case 0:
if (monster.Enabled)
{
radarPosition = monster.Position;
}
if (!monster.IsDead) return;
ShowMessage(state);
state = 1;
break;
}
}
public override void End()
{
if (!monster.IsDead) return;
GiveReward();
completed = true;
}
}
}
@@ -0,0 +1,107 @@
using FarseerPhysics;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
class SalvageMission : Mission
{
private ItemPrefab itemPrefab;
private Item item;
private Level.PositionType spawnPositionType;
private int state;
public override Vector2 RadarPosition
{
get
{
return state>0 ? Vector2.Zero : ConvertUnits.ToDisplayUnits(item.SimPosition);
}
}
public SalvageMission(XElement element, Location[] locations)
: base(element, locations)
{
string itemName = ToolBox.GetAttributeString(element, "itemname", "");
itemPrefab = ItemPrefab.list.Find(ip => ip.Name == itemName) as ItemPrefab;
string spawnPositionTypeStr = ToolBox.GetAttributeString(element, "spawntype", "");
if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
!Enum.TryParse<Level.PositionType>(spawnPositionTypeStr, true, out spawnPositionType))
{
spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
}
if (itemPrefab == null)
{
DebugConsole.ThrowError("Error in SalvageMission: couldn't find an item prefab with the name "+itemName);
}
}
public override void Start(Level level)
{
Vector2 position = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, 30.0f);
item = new Item(itemPrefab, position, null);
item.MoveWithLevel = true;
item.body.FarseerBody.IsKinematic = true;
if (item.HasTag("alien"))
{
//try to find a nearby artifact holder (or any alien itemcontainer) and place the artifact inside it
foreach (Item it in Item.ItemList)
{
if (it.Submarine != null || !it.HasTag("alien")) continue;
if (Math.Abs(item.WorldPosition.X - it.WorldPosition.X) > 2000.0f) continue;
if (Math.Abs(item.WorldPosition.Y - it.WorldPosition.Y) > 2000.0f) continue;
var itemContainer = it.GetComponent<Items.Components.ItemContainer>();
if (itemContainer == null) continue;
itemContainer.Combine(item);
break;
}
}
}
public override void Update(float deltaTime)
{
switch (state)
{
case 0:
//item.body.LinearVelocity = Vector2.Zero;
if (item.ParentInventory!=null) item.body.FarseerBody.IsKinematic = false;
if (item.CurrentHull == null) return;
ShowMessage(state);
state = 1;
break;
case 1:
if (!Submarine.MainSub.AtEndPosition && !Submarine.MainSub.AtStartPosition) return;
ShowMessage(state);
state = 2;
break;
}
}
public override void End()
{
if (item.CurrentHull == null || !item.CurrentHull.Submarine.AtEndPosition || item.Removed) return;
item.Remove();
GiveReward();
completed = true;
}
}
}
+134
View File
@@ -0,0 +1,134 @@
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
class MonsterEvent : ScriptedEvent
{
private string characterFile;
private int minAmount, maxAmount;
private Character[] monsters;
private bool spawnDeep;
private bool disallowed;
private Level.PositionType spawnPosType;
public override string ToString()
{
return "ScriptedEvent (" + characterFile + ")";
}
private bool isActive;
public override bool IsActive
{
get
{
return isActive;
}
}
public MonsterEvent(XElement element)
: base (element)
{
characterFile = ToolBox.GetAttributeString(element, "characterfile", "");
minAmount = ToolBox.GetAttributeInt(element, "minamount", 1);
maxAmount = Math.Max(ToolBox.GetAttributeInt(element, "maxamount", 1), minAmount);
var spawnPosTypeStr = ToolBox.GetAttributeString(element, "spawntype", "");
if (string.IsNullOrWhiteSpace(spawnPosTypeStr) ||
!Enum.TryParse<Level.PositionType>(spawnPosTypeStr, true, out spawnPosType))
{
spawnPosType = Level.PositionType.MainPath;
}
spawnDeep = ToolBox.GetAttributeBool(element, "spawndeep", false);
if (GameMain.NetworkMember != null)
{
List<string> monsterNames = GameMain.NetworkMember.monsterEnabled.Keys.ToList();
string tryKey = monsterNames.Find(s => characterFile.ToLower().Contains(s.ToLower()));
if (!string.IsNullOrWhiteSpace(tryKey))
{
if (!GameMain.NetworkMember.monsterEnabled[tryKey]) disallowed = true; //spawn was disallowed by host
}
}
}
public override void Init()
{
base.Init();
SpawnMonsters();
}
private void SpawnMonsters()
{
if (disallowed) return;
Vector2 spawnPos = Level.Loaded.GetRandomInterestingPosition(true, spawnPosType, true);
int amount = Rand.Range(minAmount, maxAmount, false);
monsters = new Character[amount];
if (spawnDeep) spawnPos.Y -= Level.Loaded.Size.Y;
for (int i = 0; i < amount; i++)
{
spawnPos.X += Rand.Range(-0.5f, 0.5f, false);
spawnPos.Y += Rand.Range(-0.5f, 0.5f, false);
monsters[i] = Character.Create(characterFile, spawnPos, null, GameMain.Client != null);
}
}
public override void Update(float deltaTime)
{
if (disallowed)
{
Finished();
return;
}
if (monsters == null) SpawnMonsters();
if (isFinished) return;
isActive = false;
Entity targetEntity = null;
if (Character.Controlled != null)
{
targetEntity = Character.Controlled;
}
else
{
targetEntity = Submarine.FindClosest(GameMain.GameScreen.Cam.WorldViewCenter);
}
bool monstersDead = true;
foreach (Character monster in monsters)
{
if (!monster.IsDead)
{
monstersDead = false;
if (targetEntity != null && Vector2.DistanceSquared(monster.WorldPosition, targetEntity.WorldPosition) < 5000.0f * 5000.0f)
{
isActive = true;
break;
}
}
}
if (monstersDead) Finished();
}
}
}
+28
View File
@@ -0,0 +1,28 @@
namespace Barotrauma
{
class PropertyTask : Task
{
Item item;
public delegate bool IsFinishedHandler();
private IsFinishedHandler IsFinishedChecker;
public PropertyTask(Item item, IsFinishedHandler isFinished, float priority, string name)
: base(priority, name)
{
if (taskManager == null) return;
this.item = item;
IsFinishedChecker = isFinished;
}
public override void Update(float deltaTime)
{
if (IsFinishedChecker())
{
Finished();
}
}
}
}
+20
View File
@@ -0,0 +1,20 @@
namespace Barotrauma
{
class RepairTask : Task
{
Item item;
public RepairTask(Item item, float priority, string name)
: base(priority, name)
{
if (taskManager == null) return;
this.item = item;
}
public override void Update(float deltaTime)
{
if (item.Condition > 50.0f) Finished();
}
}
}
+176
View File
@@ -0,0 +1,176 @@
using System;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace Barotrauma
{
class ScriptedEvent
{
protected string name;
protected string description;
protected int commonness;
protected int difficulty;
protected bool isFinished;
public string Name
{
get { return name; }
}
public string Description
{
get { return description; }
}
public int Commonness
{
get { return commonness; }
}
public string MusicType
{
get;
set;
}
public virtual bool IsActive
{
get { return true; }
}
public bool IsFinished
{
get { return isFinished; }
}
public int Difficulty
{
get { return difficulty; }
}
public override string ToString()
{
return "ScriptedEvent ("+name+")";
}
public ScriptedEvent(XElement element)
{
name = ToolBox.GetAttributeString(element, "name", "");
description = ToolBox.GetAttributeString(element, "description", "");
difficulty = ToolBox.GetAttributeInt(element, "difficulty", 1);
commonness = ToolBox.GetAttributeInt(element, "commonness", 1);
MusicType = ToolBox.GetAttributeString(element, "musictype", "default");
}
public static ScriptedEvent LoadRandom(Random rand)
{
var configFiles = GameMain.Config.SelectedContentPackage.GetFilesOfType(ContentType.RandomEvents);
if (!configFiles.Any())
{
DebugConsole.ThrowError("No config files for random events found in the selected content package");
return null;
}
string configFile = configFiles[0];
XDocument doc = ToolBox.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;
int i = 0;
foreach (XElement element in doc.Root.Elements())
{
eventProbability[i] = ToolBox.GetAttributeInt(element, "commonness", 1);
//if the event has been previously selected, it's less likely to be selected now
//int previousEventIndex = previousEvents.FindIndex(x => x == i);
//if (previousEventIndex >= 0)
//{
// //how many shifts ago was the event last selected
// int eventDist = eventCount - previousEventIndex;
// float weighting = (1.0f / eventDist) * PreviouslyUsedWeight;
// eventProbability[i] *= weighting;
//}
probabilitySum += eventProbability[i];
i++;
}
float randomNumber = (float)rand.NextDouble() * probabilitySum;
i = 0;
foreach (XElement element in doc.Root.Elements())
{
if (randomNumber <= eventProbability[i])
{
Type t;
string type = element.Name.ToString();
try
{
t = Type.GetType("Barotrauma." + type, true, true);
if (t == null)
{
DebugConsole.ThrowError("Error in " + configFile + "! Could not find an event class of the type \"" + type + "\".");
continue;
}
}
catch
{
DebugConsole.ThrowError("Error in " + configFile + "! Could not find an event class of the type \"" + type + "\".");
continue;
}
ConstructorInfo constructor = t.GetConstructor(new[] { typeof(XElement) });
object instance = null;
try
{
instance = constructor.Invoke(new object[] { element });
}
catch (Exception ex)
{
DebugConsole.ThrowError(ex.InnerException!=null ? ex.InnerException.ToString() : ex.ToString());
}
//previousEvents.Add(i);
return (ScriptedEvent)instance;
}
randomNumber -= eventProbability[i];
i++;
}
return null;
}
public virtual void Init()
{
isFinished = false;
}
public virtual void Update(float deltaTime)
{
}
public virtual void Finished()
{
isFinished = true;
}
}
}
+32
View File
@@ -0,0 +1,32 @@
namespace Barotrauma
{
class ScriptedTask : Task
{
private ScriptedEvent scriptedEvent;
public override bool IsStarted
{
get
{
return scriptedEvent.IsActive;
}
}
public ScriptedTask(ScriptedEvent scriptedEvent)
: base(scriptedEvent.Difficulty, scriptedEvent.Name)
{
if (taskManager == null) return;
this.musicType = scriptedEvent.MusicType;
this.scriptedEvent = scriptedEvent;
scriptedEvent.Init();
}
public override void Update(float deltaTime)
{
scriptedEvent.Update(deltaTime);
if (scriptedEvent.IsFinished) Finished();
}
}
}
+64
View File
@@ -0,0 +1,64 @@
namespace Barotrauma
{
class Task
{
protected string name;
private float priority;
protected string musicType;
protected TaskManager taskManager;
protected bool isFinished;
public string Name
{
get { return name; }
}
public float Priority
{
get { return priority; }
}
public string MusicType
{
get { return musicType; }
}
public bool IsFinished
{
get { return isFinished; }
}
public virtual bool IsStarted
{
get { return true; }
}
public Task(float priority, string name)
{
if (GameMain.GameSession==null || GameMain.GameSession.TaskManager == null) return;
taskManager = GameMain.GameSession.TaskManager;
musicType = "repair";
this.priority = priority;
this.name = name;
taskManager.AddTask(this);
}
public virtual void Update(float deltaTime)
{
}
protected virtual void Finished()
{
isFinished = true;
}
}
}
+87
View File
@@ -0,0 +1,87 @@
using System.Collections.Generic;
using System;
using System.Linq;
namespace Barotrauma
{
class TaskManager
{
const float CriticalPriority = 50.0f;
private List<Task> tasks;
public List<Task> Tasks
{
get { return tasks; }
}
public bool CriticalTasks
{
get
{
return tasks.Any(task => task.Priority >= CriticalPriority);
}
}
public TaskManager(GameSession session)
{
tasks = new List<Task>();
}
public void AddTask(Task newTask)
{
if (tasks.Contains(newTask)) return;
tasks.Add(newTask);
}
public void StartShift(Level level)
{
CreateScriptedEvents(level);
}
public void EndShift()
{
tasks.Clear();
}
private void CreateScriptedEvents(Level level)
{
MTRandom rand = new MTRandom(ToolBox.StringToInt(level.Seed));
float totalDifficulty = level.Difficulty;
int tries = 0;
while (tries < 5)
{
ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(rand);
if (scriptedEvent==null || scriptedEvent.Difficulty > totalDifficulty)
{
tries++;
continue;
}
DebugConsole.Log("Created scripted event " + scriptedEvent.ToString());
AddTask(new ScriptedTask(scriptedEvent));
totalDifficulty -= scriptedEvent.Difficulty;
tries = 0;
}
}
public void Update(float deltaTime)
{
foreach (Task task in tasks)
{
if (!task.IsFinished)
{
task.Update(deltaTime);
}
}
tasks.RemoveAll(t => t.IsFinished);
}
}
}