Unstable v0.1300.0.1

This commit is contained in:
Markus Isberg
2021-03-05 17:00:56 +02:00
parent 64cdb32078
commit cb969c959f
199 changed files with 6043 additions and 3911 deletions
@@ -1,5 +1,7 @@
using Barotrauma.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
@@ -8,38 +10,33 @@ namespace Barotrauma
{
private readonly XElement characterConfig;
private readonly List<Character> characters = new List<Character>();
protected readonly List<Character> characters = new List<Character>();
private readonly Dictionary<Character, List<Item>> characterItems = new Dictionary<Character, List<Item>>();
protected readonly HashSet<Character> requireKill = new HashSet<Character>();
protected readonly HashSet<Character> requireRescue = new HashSet<Character>();
private readonly string itemTag;
public override bool AllowRespawn => false;
private Item itemToDestroy;
protected bool wasDocked;
public AbandonedOutpostMission(MissionPrefab prefab, Location[] locations) :
base(prefab, locations)
{
characterConfig = prefab.ConfigElement.Element("Characters");
itemTag = prefab.ConfigElement.GetAttributeString("targetitem", "");
if (string.IsNullOrEmpty(itemTag))
{
DebugConsole.ThrowError($"Error in mission prefab \"{prefab.Identifier}\". Target item not defined.");
}
}
protected override void StartMissionSpecific(Level level)
{
itemToDestroy = null;
itemToDestroy = Item.ItemList.Find(it => it.Submarine?.Info.Type != SubmarineType.Player && it.HasTag(itemTag));
if (itemToDestroy == null)
{
DebugConsole.ThrowError($"Error in mission \"{Prefab.Identifier}\". Could not find an item with the tag \"{itemTag}\".");
}
characters.Clear();
characterItems.Clear();
requireKill.Clear();
requireRescue.Clear();
if (!IsClient)
{
InitCharacters();
}
wasDocked = Submarine.MainSub.DockedTo.Contains(Level.Loaded.StartOutpost);
}
private void InitCharacters()
@@ -57,48 +54,139 @@ namespace Barotrauma
foreach (XElement element in characterConfig.Elements())
{
string characterIdentifier = element.GetAttributeString("identifier", "");
string characterFrom = element.GetAttributeString("from", "");
HumanPrefab humanPrefab = NPCSet.Get(characterFrom, characterIdentifier);
if (humanPrefab == null)
{
DebugConsole.ThrowError("Couldn't spawn character for abandoned outpost mission: character prefab \"" + characterIdentifier + "\" not found");
return;
}
if (GameMain.NetworkMember == null && element.GetAttributeBool("multiplayeronly", false)) { continue; }
string[] moduleFlags = element.GetAttributeStringArray("moduleflags", null);
string[] spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null);
ISpatialEntity spawnPos = SpawnAction.GetSpawnPos(
SpawnAction.SpawnLocationType.Outpost, SpawnType.Human,
moduleFlags ?? humanPrefab.GetModuleFlags(),
spawnPointTags ?? humanPrefab.GetSpawnPointTags());
if (spawnPos == null)
int defaultCount = element.GetAttributeInt("count", -1);
if (defaultCount < 0)
{
spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom();
defaultCount = element.GetAttributeInt("amount", 1);
}
int min = Math.Min(element.GetAttributeInt("min", defaultCount), 255);
int max = Math.Min(Math.Max(min, element.GetAttributeInt("max", defaultCount)), 255);
int count = Rand.Range(min, max + 1);
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: humanPrefab.GetJobPrefab(Rand.RandSync.Server), randSync: Rand.RandSync.Server);
Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, spawnPos.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);
if (element.Attribute("identifier") != null && element.Attribute("from") != null)
{
string characterIdentifier = element.GetAttributeString("identifier", "");
string characterFrom = element.GetAttributeString("from", "");
HumanPrefab humanPrefab = NPCSet.Get(characterFrom, characterIdentifier);
if (humanPrefab == null)
{
DebugConsole.ThrowError("Couldn't spawn a character for abandoned outpost mission: character prefab \"" + characterIdentifier + "\" not found");
continue;
}
for (int i = 0; i < count; i++)
{
LoadHuman(humanPrefab, element, submarine);
}
}
else
{
string speciesName = element.GetAttributeString("character", element.GetAttributeString("identifier", ""));
var characterPrefab = CharacterPrefab.FindBySpeciesName(speciesName);
if (characterPrefab == null)
{
DebugConsole.ThrowError("Couldn't spawn a character for abandoned outpost mission: character prefab \"" + speciesName + "\" not found");
continue;
}
for (int i = 0; i < count; i++)
{
LoadMonster(characterPrefab, element, submarine);
}
}
}
}
private void LoadHuman(HumanPrefab humanPrefab, XElement element, Submarine submarine)
{
string[] moduleFlags = element.GetAttributeStringArray("moduleflags", null);
string[] spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null);
ISpatialEntity spawnPos = SpawnAction.GetSpawnPos(
SpawnAction.SpawnLocationType.Outpost, SpawnType.Human,
moduleFlags ?? humanPrefab.GetModuleFlags(),
spawnPointTags ?? humanPrefab.GetSpawnPointTags(),
element.GetAttributeBool("asfaraspossible", false));
if (spawnPos == null)
{
spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom();
}
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: humanPrefab.GetJobPrefab(Rand.RandSync.Server), randSync: Rand.RandSync.Server);
Character spawnedCharacter = Character.Create(characterInfo.SpeciesName, spawnPos.WorldPosition, ToolBox.RandomSeed(8), characterInfo, createNetworkEvent: false);
if (element.GetAttributeBool("requirerescue", false))
{
requireRescue.Add(spawnedCharacter);
spawnedCharacter.TeamID = CharacterTeamType.FriendlyNPC;
#if CLIENT
GameMain.GameSession.CrewManager.AddCharacterToCrewList(spawnedCharacter);
#endif
}
else
{
spawnedCharacter.TeamID = CharacterTeamType.None;
humanPrefab.InitializeCharacter(spawnedCharacter, spawnPos);
humanPrefab.GiveItems(spawnedCharacter, Submarine.MainSub, Rand.RandSync.Server, createNetworkEvents: false);
}
humanPrefab.InitializeCharacter(spawnedCharacter, spawnPos);
humanPrefab.GiveItems(spawnedCharacter, Submarine.MainSub, Rand.RandSync.Server, createNetworkEvents: false);
if (element.GetAttributeBool("requirekill", false))
{
requireKill.Add(spawnedCharacter);
}
characters.Add(spawnedCharacter);
characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true));
}
characters.Add(spawnedCharacter);
private void LoadMonster(CharacterPrefab monsterPrefab, XElement element, Submarine submarine)
{
string[] moduleFlags = element.GetAttributeStringArray("moduleflags", null);
string[] spawnPointTags = element.GetAttributeStringArray("spawnpointtags", null);
ISpatialEntity spawnPos = SpawnAction.GetSpawnPos(SpawnAction.SpawnLocationType.Outpost, SpawnType.Enemy, moduleFlags, spawnPointTags, element.GetAttributeBool("asfaraspossible", false));
if (spawnPos == null)
{
spawnPos = submarine.GetHulls(alsoFromConnectedSubs: false).GetRandom();
}
Character spawnedCharacter = Character.Create(monsterPrefab.Identifier, spawnPos.WorldPosition, ToolBox.RandomSeed(8), createNetworkEvent: false);
characters.Add(spawnedCharacter);
if (element.GetAttributeBool("requirekill", false))
{
requireKill.Add(spawnedCharacter);
}
if (spawnedCharacter.Inventory != null)
{
characterItems.Add(spawnedCharacter, spawnedCharacter.Inventory.FindAllItems(recursive: true));
}
}
public override void Update(float deltaTime)
{
if (State == 0 && itemToDestroy != null && itemToDestroy.Condition <= 0.0f)
switch (state)
{
State = 1;
case 0:
if (requireKill.All(c => c.Removed || c.IsDead) &&
requireRescue.All(c => c.Submarine?.Info.Type == SubmarineType.Player))
{
State = 1;
}
break;
#if SERVER
case 1:
if (!(GameMain.GameSession.GameMode is CampaignMode) && GameMain.Server != null)
{
if (!Submarine.MainSub.AtStartPosition || (wasDocked && !Submarine.MainSub.DockedTo.Contains(Level.Loaded.StartOutpost)))
{
GameMain.Server.EndGame();
State = 2;
}
}
break;
#endif
}
}
public override void End()
{
completed = itemToDestroy == null || itemToDestroy.Condition <= 0.0f;
completed = State > 0;
if (completed)
{
if (Prefab.LocationTypeChangeOnCompleted != null)
@@ -43,21 +43,21 @@ namespace Barotrauma
public virtual string SuccessMessage
{
get { return successMessage; }
private set { successMessage = value; }
//private set { successMessage = value; }
}
private string failureMessage;
public virtual string FailureMessage
{
get { return failureMessage; }
private set { failureMessage = value; }
//private set { failureMessage = value; }
}
protected string description;
public virtual string Description
{
get { return description; }
private set { description = value; }
//private set { description = value; }
}
public int Reward
@@ -110,7 +110,7 @@ namespace Barotrauma
description = prefab.Description;
successMessage = prefab.SuccessMessage;
FailureMessage = prefab.FailureMessage;
failureMessage = prefab.FailureMessage;
Headers = new List<string>(prefab.Headers);
Messages = new List<string>(prefab.Messages);
@@ -118,12 +118,13 @@ namespace Barotrauma
for (int n = 0; n < 2; n++)
{
if (description != null) description = description.Replace("[location" + (n + 1) + "]", locations[n].Name);
if (successMessage != null) successMessage = successMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
if (failureMessage != null) failureMessage = failureMessage.Replace("[location" + (n + 1) + "]", locations[n].Name);
string locationName = $"‖color:gui.orange‖{locations[n].Name}‖end‖";
if (description != null) description = description.Replace("[location" + (n + 1) + "]", locationName);
if (successMessage != null) successMessage = successMessage.Replace("[location" + (n + 1) + "]", locationName);
if (failureMessage != null) failureMessage = failureMessage.Replace("[location" + (n + 1) + "]", locationName);
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) + "]", locationName);
}
}
if (description != null) description = description.Replace("[reward]", Reward.ToString("N0"));
@@ -180,7 +181,7 @@ namespace Barotrauma
{
foreach (string categoryToShow in Prefab.UnhideEntitySubCategories)
{
foreach (MapEntity entityToShow in MapEntity.mapEntityList.Where(me => me.prefab.HasSubCategory(categoryToShow)))
foreach (MapEntity entityToShow in MapEntity.mapEntityList.Where(me => me.prefab?.HasSubCategory(categoryToShow) ?? false))
{
entityToShow.HiddenInGame = false;
}
@@ -18,9 +18,10 @@ namespace Barotrauma
Nest = 0x10,
Mineral = 0x20,
Combat = 0x40,
AbandonedOutpost = 0x80,
OutpostDestroy = 0x80,
OutpostRescue = 0x100,
All = Salvage | Monster | Cargo | Beacon | Nest | Mineral | AbandonedOutpost
All = Salvage | Monster | Cargo | Beacon | Nest | Mineral | Combat | OutpostDestroy | OutpostRescue
}
partial class MissionPrefab
@@ -35,7 +36,8 @@ namespace Barotrauma
{ MissionType.Beacon, typeof(BeaconMission) },
{ MissionType.Nest, typeof(NestMission) },
{ MissionType.Mineral, typeof(MineralMission) },
{ MissionType.AbandonedOutpost, typeof(AbandonedOutpostMission) },
{ MissionType.OutpostDestroy, typeof(OutpostDestroyMission) },
{ MissionType.OutpostRescue, typeof(AbandonedOutpostMission) },
};
public static readonly Dictionary<MissionType, Type> PvPMissionClasses = new Dictionary<MissionType, Type>()
{
@@ -166,7 +168,10 @@ namespace Barotrauma
FailureMessage = element.GetAttributeString("failuremessage", "");
}
SonarLabel = TextManager.Get("MissionSonarLabel." + TextIdentifier, true) ?? element.GetAttributeString("sonarlabel", "");
SonarLabel =
TextManager.Get("MissionSonarLabel." + TextIdentifier, true) ??
TextManager.Get("MissionSonarLabel." + element.GetAttributeString("sonarlabel", ""), true) ??
element.GetAttributeString("sonarlabel", "");
SonarIconIdentifier = element.GetAttributeString("sonaricon", "");
MultiplayerOnly = element.GetAttributeBool("multiplayeronly", false);
@@ -8,7 +8,7 @@ namespace Barotrauma
partial class MonsterMission : Mission
{
//string = filename, point = min,max
private readonly HashSet<Tuple<CharacterPrefab, Point>> monsterPrefabs = new HashSet<Tuple<CharacterPrefab, Point>>();
private readonly HashSet<(CharacterPrefab character, Point amountRange)> monsterPrefabs = new HashSet<(CharacterPrefab character, Point amountRange)>();
private readonly List<Character> monsters = new List<Character>();
private readonly List<Vector2> sonarPositions = new List<Vector2>();
@@ -43,7 +43,7 @@ namespace Barotrauma
if (characterPrefab != null)
{
int monsterCount = Math.Min(prefab.ConfigElement.GetAttributeInt("monstercount", 1), 255);
monsterPrefabs.Add(new Tuple<CharacterPrefab, Point>(characterPrefab, new Point(monsterCount)));
monsterPrefabs.Add((characterPrefab, new Point(monsterCount)));
}
else
{
@@ -73,7 +73,7 @@ namespace Barotrauma
var characterPrefab = CharacterPrefab.FindBySpeciesName(speciesName);
if (characterPrefab != null)
{
monsterPrefabs.Add(new Tuple<CharacterPrefab, Point>(characterPrefab, new Point(min, max)));
monsterPrefabs.Add((characterPrefab, new Point(min, max)));
}
else
{
@@ -83,7 +83,7 @@ namespace Barotrauma
if (monsterPrefabs.Any())
{
var characterParams = new CharacterParams(monsterPrefabs.First().Item1.FilePath);
var characterParams = new CharacterParams(monsterPrefabs.First().character.FilePath);
description = description.Replace("[monster]",
TextManager.Get("character." + characterParams.SpeciesTranslationOverride, returnNull: true) ??
TextManager.Get("character." + characterParams.SpeciesName));
@@ -115,12 +115,12 @@ namespace Barotrauma
if (!IsClient)
{
Level.Loaded.TryGetInterestingPosition(true, spawnPosType, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos);
foreach (var monster in monsterPrefabs)
foreach (var (character, amountRange) in monsterPrefabs)
{
int amount = Rand.Range(monster.Item2.X, monster.Item2.Y + 1);
int amount = Rand.Range(amountRange.X, amountRange.Y + 1);
for (int i = 0; i < amount; i++)
{
monsters.Add(Character.Create(monster.Item1.Identifier, spawnPos, ToolBox.RandomSeed(8), createNetworkEvent: false));
monsters.Add(Character.Create(character.Identifier, spawnPos, ToolBox.RandomSeed(8), createNetworkEvent: false));
}
}