(a410fd46c) Trying to help the merge script through a jungle of merges

This commit is contained in:
Joonas Rikkonen
2019-06-04 16:19:53 +03:00
parent 5208b922d8
commit bea7b58ff3
84 changed files with 1720 additions and 929 deletions
@@ -22,6 +22,11 @@ namespace Barotrauma
private float soundRange;
private float sightRange;
/// <summary>
/// How long does it take for the ai target to fade out if not kept alive.
/// </summary>
public float FadeOutTime { get; private set; } = 3;
public float SoundRange
{
@@ -121,6 +126,7 @@ namespace Barotrauma
MinSoundRange = element.GetAttributeFloat("minsoundrange", SoundRange);
MaxSightRange = element.GetAttributeFloat("maxsightrange", SightRange);
MaxSoundRange = element.GetAttributeFloat("maxsoundrange", SoundRange);
FadeOutTime = element.GetAttributeFloat("fadeouttime", FadeOutTime);
SonarLabel = element.GetAttributeString("sonarlabel", "");
string typeString = element.GetAttributeString("type", "Any");
if (Enum.TryParse(typeString, out TargetType t))
@@ -435,7 +435,7 @@ namespace Barotrauma
{
if (gap.Submarine != Character.Submarine) { continue; }
if (gap.Open < 1 || gap.IsRoomToRoom) { continue; }
var path = indoorSteering.PathFinder.FindPath(Character.SimPosition, gap.SimPosition);
var path = indoorSteering.PathFinder.FindPath(Character.SimPosition, gap.SimPosition, Character.Submarine);
if (!path.Unreachable)
{
if (escapePoint != Vector2.Zero)
@@ -1182,7 +1182,7 @@ namespace Barotrauma
}
else if (target.Entity != null)
{
//skip the target if it's a room and the character is already inside a sub
// Ignore the target if it's a room and the character is already inside a sub
if (character.CurrentHull != null && target.Entity is Hull) { continue; }
Door door = null;
@@ -1203,6 +1203,12 @@ namespace Barotrauma
break;
}
}
// Ignore the target if it's a decoy and the character is already inside a sub
if (character.CurrentHull != null && targetingTag == "decoy")
{
continue;
}
}
else if (target.Entity is Structure s)
{
@@ -154,6 +154,7 @@ namespace Barotrauma
currentTarget = target;
Vector2 pos = host.SimPosition;
// TODO: remove this and handle differently?
if (character != null && character.Submarine == null)
{
var targetHull = Hull.FindHull(FarseerPhysics.ConvertUnits.ToDisplayUnits(target), null, false);
@@ -163,7 +164,7 @@ namespace Barotrauma
}
}
var newPath = pathFinder.FindPath(pos, target, "(Character: " + character.Name + ")");
var newPath = pathFinder.FindPath(pos, target, character.Submarine, "(Character: " + character.Name + ")");
bool useNewPath = currentPath == null || needsNewPath;
if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
{
@@ -448,7 +449,8 @@ namespace Barotrauma
private float? GetNodePenalty(PathNode node, PathNode nextNode)
{
if (character == null) { return 0.0f; }
if (character == null) { return 0.0f; }
if (nextNode.Waypoint.isObstructed) { return null; }
float penalty = 0.0f;
if (nextNode.Waypoint.ConnectedGap != null && nextNode.Waypoint.ConnectedGap.Open < 0.9f)
{
@@ -215,11 +215,12 @@ namespace Barotrauma
protected virtual void OnCompleted()
{
if (Completed != null)
{
Completed();
Completed = null;
}
Completed?.Invoke();
//if (Completed != null)
//{
// Completed();
// Completed = null;
//}
}
public virtual void Reset() { }
@@ -181,8 +181,7 @@ namespace Barotrauma
{
if (closeEnough)
{
character.AIController.SteeringManager.Reset();
character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
OnCompleted();
}
return false;
}
@@ -204,11 +203,6 @@ namespace Barotrauma
}
}
}
if (isCompleted)
{
character.AIController.SteeringManager.Reset();
character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
}
return isCompleted;
}
@@ -223,5 +217,15 @@ namespace Barotrauma
float interactionDistance = Target is Item i ? i.InteractDistance * 0.9f : 0;
CloseEnough = Math.Max(interactionDistance, CloseEnough);
}
protected override void OnCompleted()
{
character.AIController.SteeringManager.Reset();
if (Target != null)
{
character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
}
base.OnCompleted();
}
}
}
@@ -156,7 +156,7 @@ namespace Barotrauma
bool isRoomNameFound = currentTarget.DisplayName != null;
errorMsg = "(Character " + character.Name + " idling, target " + (isRoomNameFound ? currentTarget.DisplayName : currentTarget.ToString()) + ")";
#endif
var path = PathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition, errorMsg);
var path = PathSteering.PathFinder.FindPath(character.SimPosition, currentTarget.SimPosition, errorMsgStr: errorMsg);
PathSteering.SetPath(path);
}
@@ -173,7 +173,7 @@ namespace Barotrauma
if (targetCharacterName == null) targetCharacterName = "";
if (targetRoomName == null) targetRoomName = "";
string msg = TextManager.GetWithVariables(messageTag, new string[2] { "[name]", "[roomname]" }, new string[2] { targetCharacterName, targetRoomName }, new bool[2] { false, true });
string msg = TextManager.GetWithVariables(messageTag, new string[2] { "[name]", "[roomname]" }, new string[2] { targetCharacterName, targetRoomName }, new bool[2] { false, true }, true);
if (msg == null) return "";
return msg;
@@ -157,13 +157,18 @@ namespace Barotrauma
}
}
public SteeringPath FindPath(Vector2 start, Vector2 end, string errorMsgStr = null)
public SteeringPath FindPath(Vector2 start, Vector2 end, Submarine hostSub = null, string errorMsgStr = null)
{
float closestDist = 0.0f;
PathNode startNode = null;
foreach (PathNode node in nodes)
{
Vector2 nodePos = node.Position;
if (hostSub != null)
{
Vector2 diff = hostSub.SimPosition - node.Waypoint.Submarine.SimPosition;
nodePos -= diff;
}
float xDiff = Math.Abs(start.X - nodePos.X);
float yDiff = Math.Abs(start.Y - nodePos.Y);
@@ -185,7 +190,7 @@ namespace Barotrauma
if (insideSubmarine)
{
var body = Submarine.PickBody(
start, node.Waypoint.SimPosition, null,
start, nodePos, null,
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs);
if (body != null)
@@ -215,7 +220,11 @@ namespace Barotrauma
foreach (PathNode node in nodes)
{
Vector2 nodePos = node.Position;
if (hostSub != null)
{
Vector2 diff = hostSub.SimPosition - node.Waypoint.Submarine.SimPosition;
nodePos -= diff;
}
float dist = Vector2.DistanceSquared(end, nodePos);
if (insideSubmarine)
{
@@ -229,7 +238,7 @@ namespace Barotrauma
//if searching for a path inside the sub, make sure the waypoint is visible
if (insideSubmarine)
{
var body = Submarine.PickBody(end, node.Waypoint.SimPosition, null,
var body = Submarine.PickBody(end, nodePos, null,
Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionStairs );
if (body != null)
@@ -237,7 +246,6 @@ namespace Barotrauma
//if (body.UserData is Submarine) continue;
if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue;
if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue;
}
}
@@ -2030,6 +2030,11 @@ namespace Barotrauma
//Do ragdoll shenanigans before Stun because it's still technically a stun, innit? Less network updates for us!
bool allowRagdoll = GameMain.NetworkMember != null ? GameMain.NetworkMember.ServerSettings.AllowRagdollButton : true;
bool tooFastToUnragdoll = AnimController.Collider.LinearVelocity.LengthSquared() > 1f;
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
{
tooFastToUnragdoll = false;
}
if (IsForceRagdolled)
{
IsRagdolled = IsForceRagdolled;
@@ -2039,7 +2044,7 @@ namespace Barotrauma
IsRagdolled = IsKeyDown(InputType.Ragdoll);
}
//Keep us ragdolled if we were forced or we're too speedy to unragdoll
else if (allowRagdoll && (!IsRagdolled || AnimController.Collider.LinearVelocity.LengthSquared() < 1f))
else if (allowRagdoll && (!IsRagdolled || !tooFastToUnragdoll))
{
if (ragdollingLockTimer > 0.0f)
{
@@ -2589,7 +2594,7 @@ namespace Barotrauma
if (info != null) { info.Remove(); }
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
GameMain.GameSession?.CrewManager?.KillCharacter(this);
#endif
CharacterList.Remove(this);
@@ -89,6 +89,14 @@ namespace Barotrauma
public static void StopCoroutines(string name)
{
Coroutines.ForEach(c =>
{
if (c.Name == name)
{
c.Thread?.Abort();
c.Thread?.Join();
}
});
Coroutines.RemoveAll(c => c.Name == name);
}
@@ -99,31 +107,42 @@ namespace Barotrauma
public static void ExecuteCoroutineThread(CoroutineHandle handle)
{
while (true)
try
{
if (handle.Coroutine.Current != null)
while (true)
{
WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
if (wfs != null)
if (handle.Coroutine.Current != null)
{
Thread.Sleep((int)(wfs.TotalTime * 1000));
}
else
{
switch ((CoroutineStatus)handle.Coroutine.Current)
WaitForSeconds wfs = handle.Coroutine.Current as WaitForSeconds;
if (wfs != null)
{
case CoroutineStatus.Success:
return;
Thread.Sleep((int)(wfs.TotalTime * 1000));
}
else
{
switch ((CoroutineStatus)handle.Coroutine.Current)
{
case CoroutineStatus.Success:
return;
case CoroutineStatus.Failure:
DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has failed");
return;
case CoroutineStatus.Failure:
DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has failed");
return;
}
}
}
}
Thread.Yield();
if (!handle.Coroutine.MoveNext()) return;
Thread.Yield();
if (!handle.Coroutine.MoveNext()) return;
}
}
catch (ThreadAbortException tae)
{
//not an error, don't worry about it
}
catch (Exception e)
{
DebugConsole.ThrowError("Coroutine \"" + handle.Name + "\" has thrown an exception", e);
}
}
@@ -112,6 +112,7 @@ namespace Barotrauma
List<Vector2> positions = new List<Vector2>();
foreach (var allowedPosition in availablePositions)
{
if (Level.Loaded.ExtraWalls.Any(w => w.Cells.Any(c => c.IsPointInside(allowedPosition.Position.ToVector2())))) { continue; }
positions.Add(allowedPosition.Position.ToVector2());
}
@@ -42,7 +42,7 @@ namespace Barotrauma
public float GetAverageElapsedMillisecs(string identifier)
{
if (!avgTicksPerFrame.ContainsKey(identifier)) return 0.0f;
return avgTicksPerFrame[identifier] / TimeSpan.TicksPerMillisecond;
return avgTicksPerFrame[identifier] / (float)TimeSpan.TicksPerMillisecond;
}
public bool Update(double deltaTime)
@@ -98,7 +98,7 @@ namespace Barotrauma
{
if (item.GetComponent<Items.Components.Repairable>() != null)
{
item.Condition = item.Health;
item.Condition = item.Prefab.Health;
}
}
}
@@ -176,7 +176,16 @@ namespace Barotrauma
Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end"));
InitializeWatchman(spawnedCharacter);
var objectiveManager = (spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager;
objectiveManager?.SetOrder(new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, objectiveManager, repeat: true, getDivingGearIfNeeded: false));
if (objectiveManager != null)
{
var moveOrder = new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, objectiveManager, repeat: true, getDivingGearIfNeeded: false);
moveOrder.Completed += () =>
{
// Turn towards the center of the sub. Doesn't work in all possible cases, but this is the simplest solution for now.
spawnedCharacter.AnimController.TargetDir = spawnedCharacter.Submarine.WorldPosition.X > spawnedCharacter.WorldPosition.X ? Direction.Right : Direction.Left;
};
objectiveManager.SetOrder(moveOrder);
}
if (watchmanJob != null)
{
spawnedCharacter.GiveJobItems();
@@ -241,6 +241,14 @@ namespace Barotrauma
}
}
foreach (var sub in Submarine.Loaded)
{
if (sub.IsOutpost)
{
sub.DisableObstructedWayPoints();
}
}
Entity.Spawner = new EntitySpawner();
if (GameMode.Mission != null) Mission = GameMode.Mission;
+239 -325
View File
@@ -25,7 +25,7 @@ namespace Barotrauma
}
public partial class GameSettings
{
{
const string savePath = "config.xml";
const string playerSavePath = "config_player.xml";
const string vanillaContentPackagePath = "Data/ContentPackages/Vanilla";
@@ -43,9 +43,9 @@ namespace Barotrauma
public bool SpecularityEnabled { get; set; }
public bool ChromaticAberrationEnabled { get; set; }
public bool PauseOnFocusLost { get; set; } = true;
public bool PauseOnFocusLost { get; set; }
public bool MuteOnFocusLost { get; set; }
public bool UseDirectionalVoiceChat { get; set; } = true;
public bool UseDirectionalVoiceChat { get; set; }
public enum VoiceMode
{
@@ -57,7 +57,7 @@ namespace Barotrauma
public VoiceMode VoiceSetting { get; set; }
public string VoiceCaptureDevice { get; set; }
public float NoiseGateThreshold { get; set; } = -45;
public float NoiseGateThreshold { get; set; }
private KeyOrMouse[] keyMapping;
@@ -69,12 +69,7 @@ namespace Barotrauma
private bool useSteamMatchmaking;
private bool requireSteamAuthentication;
public string QuickStartSubmarineName
{
get;
set;
}
public string QuickStartSubmarineName;
#if DEBUG
//steam functionality can be enabled/disabled in debug builds
@@ -126,7 +121,7 @@ namespace Barotrauma
set { jobPreferences = value; }
}
public int CharacterHeadIndex { get; set; } = 1;
public int CharacterHeadIndex { get; set; }
public int CharacterHairIndex { get; set; }
public int CharacterBeardIndex { get; set; }
public int CharacterMoustacheIndex { get; set; }
@@ -160,7 +155,6 @@ namespace Barotrauma
#if CLIENT
if (applyButton != null)
{
//applyButton.Selected = unsavedSettings;
applyButton.Enabled = unsavedSettings;
applyButton.Text = TextManager.Get(unsavedSettings ? "ApplySettingsButtonUnsavedChanges" : "ApplySettingsButton");
}
@@ -168,7 +162,7 @@ namespace Barotrauma
}
}
private float soundVolume = 0.5f, musicVolume = 0.3f, voiceChatVolume = 0.5f, microphoneVolume = 1.0f;
private float soundVolume, musicVolume, voiceChatVolume, microphoneVolume;
public float SoundVolume
{
@@ -229,9 +223,9 @@ namespace Barotrauma
private HashSet<string> selectedContentPackagePaths = new HashSet<string>();
public string MasterServerUrl { get; set; }
public bool AutoCheckUpdates { get; set; }
public bool WasGameUpdated { get; set; }
public string MasterServerUrl { get; set; }
public bool AutoCheckUpdates { get; set; }
public bool WasGameUpdated { get; set; }
private string defaultPlayerName;
public string DefaultPlayerName
@@ -256,9 +250,9 @@ namespace Barotrauma
}
private const float MinHUDScale = 0.75f, MaxHUDScale = 1.25f;
public static float HUDScale { get; set; } = 1.0f;
public static float HUDScale { get; set; }
private const float MinInventoryScale = 0.75f, MaxInventoryScale = 1.25f;
public static float InventoryScale { get; set; } = 1.0f;
public static float InventoryScale { get; set; }
public List<string> CompletedTutorialNames { get; private set; }
@@ -267,7 +261,7 @@ namespace Barotrauma
public bool CampaignDisclaimerShown, EditorDisclaimerShown;
private static bool sendUserStatistics;
private static bool sendUserStatistics = true;
public static bool SendUserStatistics
{
get { return sendUserStatistics; }
@@ -353,13 +347,7 @@ namespace Barotrauma
}
if (doc != null)
{
foreach (XElement subElement in doc.Root.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() == "keymapping")
{
LoadKeyBinds(subElement);
}
}
LoadControls(doc);
}
}
@@ -415,35 +403,15 @@ namespace Barotrauma
}
}
#region Load DefaultConfig
private void LoadDefaultConfig(bool setLanguage = true)
{
XDocument doc = XMLExtensions.TryLoadXml(savePath);
if (setLanguage || string.IsNullOrEmpty(Language))
{
Language = doc.Root.GetAttributeString("language", "English");
}
MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", "");
AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", true);
WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", false);
VerboseLogging = doc.Root.GetAttributeBool("verboselogging", false);
SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", false);
QuickStartSubmarineName = doc.Root.GetAttributeString("quickstartsub", "");
if (doc == null)
{
GraphicsWidth = 1024;
GraphicsHeight = 678;
GraphicsHeight = 768;
MasterServerUrl = "";
SelectedContentPackages.Add(ContentPackage.List.Any() ? ContentPackage.List[0] : new ContentPackage(""));
jobPreferences = new List<string>();
foreach (JobPrefab job in JobPrefab.List)
{
@@ -452,158 +420,24 @@ namespace Barotrauma
return;
}
XElement graphicsMode = doc.Root.Element("graphicsmode");
GraphicsWidth = 0;
GraphicsHeight = 0;
VSyncEnabled = graphicsMode.GetAttributeBool("vsync", true);
XElement graphicsSettings = doc.Root.Element("graphicssettings");
ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", 1500);
LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", 0.5f), 0.1f, 1.0f);
SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", true);
ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", true);
HUDScale = graphicsSettings.GetAttributeFloat("hudscale", 1.0f);
InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", 1.0f);
var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent");
if (!Enum.TryParse(losModeStr, out losMode))
{
losMode = LosMode.Transparent;
}
#if CLIENT
if (GraphicsWidth == 0 || GraphicsHeight == 0)
{
GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
}
#endif
var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen");
if (!Enum.TryParse(windowModeStr, out WindowMode wm))
{
wm = WindowMode.Fullscreen;
}
WindowMode = wm;
useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", true);
requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", true);
AutoUpdateWorkshopItems = doc.Root.GetAttributeBool("autoupdateworkshopitems", true);
#if DEBUG
EnableSplashScreen = false;
#else
EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", true);
#endif
AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f);
bool resetLanguage = setLanguage || string.IsNullOrEmpty(Language);
SetDefaultValues(resetLanguage);
SetDefaultBindings(doc, legacy: false);
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "keymapping":
LoadKeyBinds(subElement);
break;
case "gameplay":
jobPreferences = new List<string>();
foreach (XElement ele in subElement.Element("jobpreferences").Elements("job"))
{
string jobIdentifier = ele.GetAttributeString("identifier", "");
if (string.IsNullOrEmpty(jobIdentifier)) continue;
jobPreferences.Add(jobIdentifier);
}
break;
case "player":
defaultPlayerName = subElement.GetAttributeString("name", "");
CharacterHeadIndex = subElement.GetAttributeInt("headindex", CharacterHeadIndex);
if (Enum.TryParse(subElement.GetAttributeString("gender", "none"), true, out Gender g))
{
CharacterGender = g;
}
if (Enum.TryParse(subElement.GetAttributeString("race", "white"), true, out Race r))
{
CharacterRace = r;
}
else
{
CharacterRace = Race.White;
}
CharacterHairIndex = subElement.GetAttributeInt("hairindex", -1);
CharacterBeardIndex = subElement.GetAttributeInt("beardindex", -1);
CharacterMoustacheIndex = subElement.GetAttributeInt("moustacheindex", -1);
CharacterFaceAttachmentIndex = subElement.GetAttributeInt("faceattachmentindex", -1);
break;
}
}
MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", MasterServerUrl);
WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", WasGameUpdated);
VerboseLogging = doc.Root.GetAttributeBool("verboselogging", VerboseLogging);
SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", SaveDebugConsoleLogs);
AutoUpdateWorkshopItems = doc.Root.GetAttributeBool("autoupdateworkshopitems", AutoUpdateWorkshopItems);
List<string> missingPackagePaths = new List<string>();
List<ContentPackage> incompatiblePackages = new List<ContentPackage>();
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "contentpackage":
string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", ""));
var matchingContentPackage = ContentPackage.List.Find(cp => System.IO.Path.GetFullPath(cp.Path) == path);
if (matchingContentPackage == null)
{
missingPackagePaths.Add(path);
}
else if (!matchingContentPackage.IsCompatible())
{
incompatiblePackages.Add(matchingContentPackage);
}
else
{
SelectedContentPackages.Add(matchingContentPackage);
}
break;
}
}
TextManager.LoadTextPacks(SelectedContentPackages);
//display error messages after all content packages have been loaded
//to make sure the package that contains text files has been loaded before we attempt to use TextManager
foreach (string missingPackagePath in missingPackagePaths)
{
DebugConsole.ThrowError(TextManager.GetWithVariable("ContentPackageNotFound", "[packagepath]", missingPackagePath));
}
foreach (ContentPackage incompatiblePackage in incompatiblePackages)
{
DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { incompatiblePackage.Name, incompatiblePackage.GameVersion.ToString(), GameMain.Version.ToString() }));
}
foreach (ContentPackage contentPackage in SelectedContentPackages)
{
bool packageOk = contentPackage.VerifyFiles(out List<string> errorMessages);
if (!packageOk)
{
DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\":\n" + string.Join("\n", errorMessages));
continue;
}
foreach (ContentFile file in contentPackage.Files)
{
ToolBox.IsProperFilenameCase(file.Path);
}
}
if (!SelectedContentPackages.Any())
{
var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage);
if (availablePackage != null)
{
SelectedContentPackages.Add(availablePackage);
}
}
//save to get rid of the invalid selected packages in the config file
if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); }
LoadGeneralSettings(doc, resetLanguage);
LoadGraphicSettings(doc);
LoadAudioSettings(doc);
LoadControls(doc);
LoadContentPackages(doc);
UnsavedSettings = false;
}
#endregion
#region Save DefaultConfig
private void SaveNewDefaultConfig()
{
XDocument doc = new XDocument();
@@ -619,6 +453,7 @@ namespace Barotrauma
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
new XAttribute("microphonevolume", microphoneVolume),
new XAttribute("voicechatvolume", voiceChatVolume),
new XAttribute("verboselogging", VerboseLogging),
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
@@ -637,7 +472,7 @@ namespace Barotrauma
{
doc.Root.Add(new XAttribute("wasgameupdated", true));
}
XElement gMode = doc.Root.Element("graphicsmode");
if (gMode == null)
{
@@ -738,7 +573,6 @@ namespace Barotrauma
"Saving game settings failed.\n" + e.Message + "\n" + e.StackTrace);
}
}
#endregion
#region Load PlayerConfig
public void LoadPlayerConfig()
@@ -760,143 +594,27 @@ namespace Barotrauma
private bool LoadPlayerConfigInternal()
{
XDocument doc = XMLExtensions.LoadXml(playerSavePath);
if (doc == null || doc.Root == null)
{
ShowUserStatisticsPrompt = true;
return false;
}
LoadGeneralSettings(doc);
LoadGraphicSettings(doc);
LoadAudioSettings(doc);
LoadControls(doc);
LoadContentPackages(doc);
Language = doc.Root.GetAttributeString("language", Language);
AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates);
sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", true);
XElement graphicsMode = doc.Root.Element("graphicsmode");
GraphicsWidth = graphicsMode.GetAttributeInt("width", GraphicsWidth);
GraphicsHeight = graphicsMode.GetAttributeInt("height", GraphicsHeight);
VSyncEnabled = graphicsMode.GetAttributeBool("vsync", VSyncEnabled);
XElement graphicsSettings = doc.Root.Element("graphicssettings");
ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", ParticleLimit);
LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", LightMapScale), 0.1f, 1.0f);
SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", SpecularityEnabled);
ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", ChromaticAberrationEnabled);
HUDScale = graphicsSettings.GetAttributeFloat("hudscale", HUDScale);
InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", InventoryScale);
var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent");
if (!Enum.TryParse(losModeStr, out losMode))
XElement tutorialsElement = doc.Root.Element("tutorials");
if (tutorialsElement != null)
{
losMode = LosMode.Transparent;
}
#if CLIENT
if (GraphicsWidth == 0 || GraphicsHeight == 0)
{
GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
}
#endif
var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen");
if (!Enum.TryParse(windowModeStr, out windowMode))
{
windowMode = WindowMode.Fullscreen;
}
XElement audioSettings = doc.Root.Element("audio");
if (audioSettings != null)
{
SoundVolume = audioSettings.GetAttributeFloat("soundvolume", SoundVolume);
MusicVolume = audioSettings.GetAttributeFloat("musicvolume", MusicVolume);
VoiceChatVolume = audioSettings.GetAttributeFloat("voicechatvolume", VoiceChatVolume);
MuteOnFocusLost = audioSettings.GetAttributeBool("muteonfocuslost", false);
UseDirectionalVoiceChat = audioSettings.GetAttributeBool("usedirectionalvoicechat", true);
string voiceSettingStr = audioSettings.GetAttributeString("voicesetting", "Disabled");
VoiceCaptureDevice = audioSettings.GetAttributeString("voicecapturedevice", "");
NoiseGateThreshold = audioSettings.GetAttributeFloat("noisegatethreshold", -45);
var voiceSetting = VoiceMode.Disabled;
if (Enum.TryParse(voiceSettingStr, out voiceSetting))
foreach (XElement element in tutorialsElement.Elements())
{
VoiceSetting = voiceSetting;
}
}
useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking);
requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication);
EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen);
PauseOnFocusLost = doc.Root.GetAttributeBool("pauseonfocuslost", PauseOnFocusLost);
AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount);
EnableMouseLook = doc.Root.GetAttributeBool("enablemouselook", EnableMouseLook);
CrewMenuOpen = doc.Root.GetAttributeBool("crewmenuopen", CrewMenuOpen);
ChatOpen = doc.Root.GetAttributeBool("chatopen", ChatOpen);
CampaignDisclaimerShown = doc.Root.GetAttributeBool("campaigndisclaimershown", false);
EditorDisclaimerShown = doc.Root.GetAttributeBool("editordisclaimershown", false);
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "keymapping":
LoadKeyBinds(subElement);
break;
case "gameplay":
jobPreferences = new List<string>();
foreach (XElement ele in subElement.Element("jobpreferences").Elements("job"))
{
string jobIdentifier = ele.GetAttributeString("identifier", "");
if (string.IsNullOrEmpty(jobIdentifier)) continue;
jobPreferences.Add(jobIdentifier);
}
break;
case "player":
defaultPlayerName = subElement.GetAttributeString("name", defaultPlayerName);
CharacterHeadIndex = subElement.GetAttributeInt("headindex", CharacterHeadIndex);
if (Enum.TryParse(subElement.GetAttributeString("gender", "none"), true, out Gender g))
{
CharacterGender = g;
}
if (Enum.TryParse(subElement.GetAttributeString("race", "white"), true, out Race r))
{
CharacterRace = r;
}
else
{
CharacterRace = Race.White;
}
CharacterHairIndex = subElement.GetAttributeInt("hairindex", CharacterHairIndex);
CharacterBeardIndex = subElement.GetAttributeInt("beardindex", CharacterBeardIndex);
CharacterMoustacheIndex = subElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex);
CharacterFaceAttachmentIndex = subElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex);
break;
case "tutorials":
foreach (XElement tutorialElement in subElement.Elements())
{
CompletedTutorialNames.Add(tutorialElement.GetAttributeString("name", ""));
}
break;
CompletedTutorialNames.Add(element.GetAttributeString("name", ""));
}
}
UnsavedSettings = false;
selectedContentPackagePaths = new HashSet<string>();
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "contentpackage":
string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", ""));
selectedContentPackagePaths.Add(path);
break;
}
}
LoadContentPackages(selectedContentPackagePaths);
return true;
}
@@ -957,7 +675,7 @@ namespace Barotrauma
}
foreach (ContentPackage incompatiblePackage in incompatiblePackages)
{
DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { incompatiblePackage.Name, incompatiblePackage.GameVersion.ToString(), GameMain.Version.ToString() }));
}
}
@@ -1038,7 +756,7 @@ namespace Barotrauma
new XAttribute("vsync", VSyncEnabled),
new XAttribute("displaymode", windowMode));
}
XElement audio = doc.Root.Element("audio");
if (audio == null)
{
@@ -1048,6 +766,8 @@ namespace Barotrauma
audio.ReplaceAttributes(
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
new XAttribute("voicechatvolume", voiceChatVolume),
new XAttribute("microphonevolume", microphoneVolume),
new XAttribute("muteonfocuslost", MuteOnFocusLost),
new XAttribute("usedirectionalvoicechat", UseDirectionalVoiceChat),
new XAttribute("voicesetting", VoiceSetting),
@@ -1153,12 +873,149 @@ namespace Barotrauma
}
#endregion
#region Loading Configs
private void LoadGeneralSettings(XDocument doc, bool setLanguage = true)
{
if (setLanguage)
{
Language = doc.Root.GetAttributeString("language", Language);
}
AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates);
sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", sendUserStatistics);
QuickStartSubmarineName = doc.Root.GetAttributeString("quickstartsubmarine", "");
useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking);
requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication);
EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen);
PauseOnFocusLost = doc.Root.GetAttributeBool("pauseonfocuslost", PauseOnFocusLost);
AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount);
EnableMouseLook = doc.Root.GetAttributeBool("enablemouselook", EnableMouseLook);
CrewMenuOpen = doc.Root.GetAttributeBool("crewmenuopen", CrewMenuOpen);
ChatOpen = doc.Root.GetAttributeBool("chatopen", ChatOpen);
CampaignDisclaimerShown = doc.Root.GetAttributeBool("campaigndisclaimershown", CampaignDisclaimerShown);
EditorDisclaimerShown = doc.Root.GetAttributeBool("editordisclaimershown", EditorDisclaimerShown);
XElement gameplayElement = doc.Root.Element("gameplay");
if (gameplayElement != null)
{
jobPreferences = new List<string>();
foreach (XElement ele in gameplayElement.Element("jobpreferences").Elements("job"))
{
string jobIdentifier = ele.GetAttributeString("identifier", "");
if (string.IsNullOrEmpty(jobIdentifier)) continue;
jobPreferences.Add(jobIdentifier);
}
}
XElement playerElement = doc.Root.Element("player");
if (playerElement != null)
{
defaultPlayerName = playerElement.GetAttributeString("name", defaultPlayerName);
CharacterHeadIndex = playerElement.GetAttributeInt("headindex", CharacterHeadIndex);
if (Enum.TryParse(playerElement.GetAttributeString("gender", "none"), true, out Gender g))
{
CharacterGender = g;
}
if (Enum.TryParse(playerElement.GetAttributeString("race", "white"), true, out Race r))
{
CharacterRace = r;
}
else
{
CharacterRace = Race.White;
}
CharacterHairIndex = playerElement.GetAttributeInt("hairindex", CharacterHairIndex);
CharacterBeardIndex = playerElement.GetAttributeInt("beardindex", CharacterBeardIndex);
CharacterMoustacheIndex = playerElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex);
CharacterFaceAttachmentIndex = playerElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex);
}
}
private void LoadGraphicSettings(XDocument doc)
{
XElement graphicsMode = doc.Root.Element("graphicsmode");
GraphicsWidth = graphicsMode.GetAttributeInt("width", GraphicsWidth);
GraphicsHeight = graphicsMode.GetAttributeInt("height", GraphicsHeight);
VSyncEnabled = graphicsMode.GetAttributeBool("vsync", VSyncEnabled);
XElement graphicsSettings = doc.Root.Element("graphicssettings");
ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", ParticleLimit);
LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", LightMapScale), 0.1f, 1.0f);
SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", SpecularityEnabled);
ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", ChromaticAberrationEnabled);
HUDScale = graphicsSettings.GetAttributeFloat("hudscale", HUDScale);
InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", InventoryScale);
var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent");
if (!Enum.TryParse(losModeStr, out losMode))
{
losMode = LosMode.Transparent;
}
#if CLIENT
if (GraphicsWidth == 0 || GraphicsHeight == 0)
{
GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
}
#endif
var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen");
if (!Enum.TryParse(windowModeStr, out windowMode))
{
windowMode = WindowMode.Fullscreen;
}
}
private void LoadAudioSettings(XDocument doc)
{
XElement audioSettings = doc.Root.Element("audio");
if (audioSettings != null)
{
SoundVolume = audioSettings.GetAttributeFloat("soundvolume", SoundVolume);
MusicVolume = audioSettings.GetAttributeFloat("musicvolume", MusicVolume);
VoiceChatVolume = audioSettings.GetAttributeFloat("voicechatvolume", VoiceChatVolume);
MuteOnFocusLost = audioSettings.GetAttributeBool("muteonfocuslost", MuteOnFocusLost);
UseDirectionalVoiceChat = audioSettings.GetAttributeBool("usedirectionalvoicechat", UseDirectionalVoiceChat);
VoiceCaptureDevice = audioSettings.GetAttributeString("voicecapturedevice", VoiceCaptureDevice);
NoiseGateThreshold = audioSettings.GetAttributeFloat("noisegatethreshold", NoiseGateThreshold);
MicrophoneVolume = audioSettings.GetAttributeFloat("microphonevolume", MicrophoneVolume);
var voiceSetting = VoiceMode.Disabled;
string voiceSettingStr = audioSettings.GetAttributeString("voicesetting", "");
if (Enum.TryParse(voiceSettingStr, out voiceSetting))
{
VoiceSetting = voiceSetting;
}
}
}
private void LoadControls(XDocument doc)
{
XElement keyMapping = doc.Root.Element("keymapping");
if (keyMapping != null)
{
LoadKeyBinds(keyMapping);
}
}
private void LoadContentPackages(XDocument doc)
{
selectedContentPackagePaths = new HashSet<string>();
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "contentpackage":
string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", ""));
selectedContentPackagePaths.Add(path);
break;
}
}
LoadContentPackages(selectedContentPackagePaths);
}
#endregion
private void LoadKeyBinds(XElement element)
{
foreach (XAttribute attribute in element.Attributes())
{
if (!Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) { continue; }
if (int.TryParse(attribute.Value.ToString(), out int mouseButton))
{
keyMapping[(int)inputType] = new KeyOrMouse(mouseButton);
@@ -1169,7 +1026,7 @@ namespace Barotrauma
{
keyMapping[(int)inputType] = new KeyOrMouse(key);
}
}
}
}
}
@@ -1184,5 +1041,62 @@ namespace Barotrauma
{
return keyMapping[(int)inputType];
}
private void SetDefaultValues(bool resetLanguage = true)
{
GraphicsWidth = 0;
GraphicsHeight = 0;
VSyncEnabled = true;
#if DEBUG
EnableSplashScreen = false;
#else
EnableSplashScreen = true;
#endif
ParticleLimit = 1500;
LightMapScale = 0.5f;
SpecularityEnabled = false;
ChromaticAberrationEnabled = true;
PauseOnFocusLost = true;
MuteOnFocusLost = false;
UseDirectionalVoiceChat = true;
VoiceSetting = VoiceMode.Disabled;
VoiceCaptureDevice = null;
NoiseGateThreshold = -45;
windowMode = WindowMode.Fullscreen;
losMode = LosMode.Transparent;
useSteamMatchmaking = true;
requireSteamAuthentication = true;
QuickStartSubmarineName = string.Empty;
CharacterHeadIndex = 1;
CharacterHairIndex = -1;
CharacterBeardIndex = -1;
CharacterMoustacheIndex = -1;
CharacterFaceAttachmentIndex = -1;
CharacterGender = Gender.None;
CharacterRace = Race.White;
aimAssistAmount = 0.5f;
EnableMouseLook = true;
CrewMenuOpen = true;
ChatOpen = true;
soundVolume = 0.5f;
musicVolume = 0.3f;
voiceChatVolume = 0.5f;
microphoneVolume = 1.0f;
AutoCheckUpdates = true;
defaultPlayerName = string.Empty;
HUDScale = 1;
InventoryScale = 1;
AutoUpdateWorkshopItems = true;
CampaignDisclaimerShown = false;
if (resetLanguage)
{
Language = "English";
}
MasterServerUrl = "http://www.undertowgames.com/baromaster";
WasGameUpdated = false;
VerboseLogging = false;
SaveDebugConsoleLogs = false;
AutoUpdateWorkshopItems = true;
}
}
}
@@ -33,6 +33,7 @@ namespace Barotrauma.Items.Components
private Body doorBody;
private bool docked;
private bool obstructedWayPointsDisabled;
private float forceLockTimer;
//if the submarine isn't in the correct position to lock within this time after docking has been activated,
@@ -732,6 +733,9 @@ namespace Barotrauma.Items.Components
bodies = null;
}
Item.Submarine.EnableObstructedWaypoints();
obstructedWayPointsDisabled = false;
#if SERVER
if (GameMain.Server != null)
{
@@ -813,6 +817,11 @@ namespace Barotrauma.Items.Components
dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f);
}
}
if (!obstructedWayPointsDisabled && dockingState >= 0.99f)
{
Item.Submarine.DisableObstructedWayPoints(DockingTarget?.Item.Submarine);
obstructedWayPointsDisabled = true;
}
}
protected override void RemoveComponentSpecific()
@@ -983,6 +992,5 @@ namespace Barotrauma.Items.Components
Undock();
}
}
}
}
@@ -413,7 +413,7 @@ namespace Barotrauma.Items.Components
{
target = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition);
}
steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(controlledSub == null ? item.WorldPosition : controlledSub.WorldPosition), target, "(Autopilot, target: " + target + ")");
steeringPath = pathFinder.FindPath(ConvertUnits.ToSimUnits(controlledSub == null ? item.WorldPosition : controlledSub.WorldPosition), target, errorMsgStr: "(Autopilot, target: " + target + ")");
}
public void SetDestinationLevelStart()
@@ -174,6 +174,12 @@ namespace Barotrauma.Items.Components
private void Launch(Vector2 impulse)
{
if (item.AiTarget != null)
{
item.AiTarget.SightRange = item.AiTarget.MaxSightRange;
item.AiTarget.SoundRange = item.AiTarget.MaxSoundRange;
}
item.Drop(null);
item.body.Enabled = true;
@@ -122,6 +122,16 @@ namespace Barotrauma.Items.Components
Update(deltaTime, cam);
}
public void ResetDeterioration()
{
deteriorationTimer = Rand.Range(MinDeteriorationDelay, MaxDeteriorationDelay);
item.Condition = item.Prefab.Health;
#if SERVER
//let the clients know the initial deterioration delay
item.CreateServerEvent(this);
#endif
}
public override void Update(float deltaTime, Camera cam)
{
UpdateProjSpecific(deltaTime);
@@ -338,9 +338,15 @@ namespace Barotrauma.Items.Components
canPlaceNode = true;
}
Vector2 relativeNodePos = newNodePos - item.Position;
if (sub != null)
{
relativeNodePos += sub.HiddenSubPosition;
}
sectionExtents = new Vector2(
Math.Max(Math.Abs((newNodePos.X + sub.HiddenSubPosition.X) - item.Position.X), sectionExtents.X),
Math.Max(Math.Abs((newNodePos.Y + sub.HiddenSubPosition.Y) - item.Position.Y), sectionExtents.Y));
Math.Max(Math.Abs(relativeNodePos.X), sectionExtents.X),
Math.Max(Math.Abs(relativeNodePos.Y), sectionExtents.Y));
}
public override bool Use(float deltaTime, Character character = null)
@@ -286,6 +286,23 @@ namespace Barotrauma.Items.Components
if (!equipLimb.WearingItems.Contains(wearableSprite))
{
equipLimb.WearingItems.Add(wearableSprite);
equipLimb.WearingItems.Sort((i1, i2) => { return i2.Sprite.Depth.CompareTo(i1.Sprite.Depth); });
equipLimb.WearingItems.Sort((i1, i2) =>
{
if (i1?.WearableComponent == null && i2?.WearableComponent == null)
{
return 0;
}
else if (i1?.WearableComponent == null)
{
return -1;
}
else if (i2?.WearableComponent == null)
{
return 1;
}
return i1.WearableComponent.AllowedSlots.Contains(InvSlotType.OuterClothes).CompareTo(i2.WearableComponent.AllowedSlots.Contains(InvSlotType.OuterClothes));
});
}
}
}
@@ -1042,8 +1042,8 @@ namespace Barotrauma
//aitarget goes silent/invisible if the components don't keep it active
if (aiTarget != null)
{
aiTarget.SightRange -= deltaTime * 1000.0f;
aiTarget.SoundRange -= deltaTime * 1000.0f;
aiTarget.SightRange -= deltaTime * (aiTarget.MaxSightRange / aiTarget.FadeOutTime);
aiTarget.SoundRange -= deltaTime * (aiTarget.MaxSoundRange / aiTarget.FadeOutTime);
}
bool broken = condition <= 0.0f;
@@ -2017,6 +2017,8 @@ namespace Barotrauma
if (element.GetAttributeBool("flippedy", false)) item.FlipY(false);
item.condition = element.GetAttributeFloat("condition", item.Prefab.Health);
item.lastSentCondition = item.condition;
item.SetActiveSprite();
foreach (ItemComponent component in item.components)
@@ -1366,6 +1366,11 @@ namespace Barotrauma
}
List<InterestingPosition> suitablePositions = positionsOfInterest.FindAll(p => positionType.HasFlag(p.PositionType));
//avoid floating ice chunks on the main path
if (positionType == PositionType.MainPath)
{
suitablePositions.RemoveAll(p => extraWalls.Any(w => w.Cells.Any(c => c.IsPointInside(p.Position.ToVector2()))));
}
if (!suitablePositions.Any())
{
string errorMsg = "Could not find a suitable position of interest. (PositionType: " + positionType + ", minDistFromSubs: " + minDistFromSubs + ")\n" + Environment.StackTrace;
@@ -1433,7 +1433,7 @@ namespace Barotrauma
Submarine sub = new Submarine(path);
sub.Load(unloadPrevious);
return sub;
}
@@ -1564,6 +1564,94 @@ namespace Barotrauma
PreviewImage = null;
#endif
}
private List<PathNode> outdoorNodes;
private List<PathNode> OutdoorNodes
{
get
{
if (outdoorNodes == null)
{
outdoorNodes = PathNode.GenerateNodes(WayPoint.WayPointList.FindAll(wp => wp.SpawnType == SpawnType.Path && wp.Submarine == this && wp.CurrentHull == null));
}
return outdoorNodes;
}
}
private HashSet<PathNode> obstructedNodes = new HashSet<PathNode>();
/// <summary>
/// Permanently disables obstructed waypoints obstructed by the level.
/// </summary>
public void DisableObstructedWayPoints()
{
// Check collisions to level
foreach (var node in OutdoorNodes)
{
if (node == null || node.Waypoint == null) { continue; }
var wp = node.Waypoint;
if (wp.isObstructed) { continue; }
foreach (var connection in node.connections)
{
bool isObstructed = false;
var connectedWp = connection.Waypoint;
if (connectedWp.isObstructed) { continue; }
Vector2 start = ConvertUnits.ToSimUnits(wp.WorldPosition);
Vector2 end = ConvertUnits.ToSimUnits(connectedWp.WorldPosition);
var body = Submarine.PickBody(start, end, null, Physics.CollisionLevel, allowInsideFixture: false);
if (body != null)
{
connectedWp.isObstructed = true;
wp.isObstructed = true;
break;
}
}
}
}
/// <summary>
/// Temporarily disables waypoints obstructed by the other sub.
/// </summary>
public void DisableObstructedWayPoints(Submarine otherSub)
{
if (otherSub == null) { return; }
if (otherSub == this) { return; }
// Check collisions to other subs. Currently only walls are taken into account.
foreach (var node in OutdoorNodes)
{
if (node == null || node.Waypoint == null) { continue; }
var wp = node.Waypoint;
if (wp.isObstructed) { continue; }
foreach (var connection in node.connections)
{
bool isObstructed = false;
var connectedWp = connection.Waypoint;
if (connectedWp.isObstructed) { continue; }
Vector2 start = ConvertUnits.ToSimUnits(wp.WorldPosition) - otherSub.SimPosition;
Vector2 end = ConvertUnits.ToSimUnits(connectedWp.WorldPosition) - otherSub.SimPosition;
var body = Submarine.PickBody(start, end, null, Physics.CollisionWall, allowInsideFixture: false);
if (body != null && body.UserData is Structure && !((Structure)body.UserData).IsPlatform)
{
connectedWp.isObstructed = true;
wp.isObstructed = true;
obstructedNodes.Add(node);
obstructedNodes.Add(connection);
break;
}
}
}
}
/// <summary>
/// Only affects temporarily disabled waypoints.
/// </summary>
public void EnableObstructedWaypoints()
{
foreach (var node in obstructedNodes)
{
node.Waypoint.isObstructed = false;
}
obstructedNodes.Clear();
}
}
}
@@ -32,6 +32,8 @@ namespace Barotrauma
public Ladder Ladders;
public Structure Stairs;
public bool isObstructed;
private ushort gapId;
public Gap ConnectedGap
{
@@ -7,6 +7,8 @@ namespace Barotrauma.Networking
{
partial class Client : IDisposable
{
public const int MaxNameLength = 20;
public string Name;
public byte ID;
@@ -205,6 +207,21 @@ namespace Barotrauma.Networking
SetPermissions(permissions, permittedCommands);
}
public static string SanitizeName(string name)
{
name = name.Trim();
if (name.Length > MaxNameLength)
{
name = name.Substring(0, MaxNameLength);
}
string rName = "";
for (int i = 0; i < name.Length; i++)
{
rName += name[i] < 32 ? '?' : name[i];
}
return rName;
}
public void Dispose()
{
DisposeProjSpecific();
@@ -174,8 +174,8 @@ namespace Barotrauma.Networking
get { return name; }
set
{
if (string.IsNullOrEmpty(value)) return;
name = value;
if (string.IsNullOrEmpty(value)) { return; }
name = value.Replace(":", "").Replace(";", "");
}
}
@@ -158,41 +158,11 @@ namespace Barotrauma.Networking
shuttleTransportTimer -= deltaTime;
#if CLIENT
GameClient nClient = networkMember as GameClient;
if (shuttleTransportTimer + deltaTime > 15.0f && shuttleTransportTimer <= 15.0f &&
nClient.Character != null &&
nClient.Character.Submarine == respawnShuttle)
{
nClient.AddChatMessage("ServerMessage.ShuttleLeaving", ChatMessageType.Server);
}
#endif
#if SERVER
var server = networkMember as GameServer;
if (server == null) return;
//if there are no living chracters inside, transporting can be stopped immediately
if (!Character.CharacterList.Any(c => c.Submarine == respawnShuttle && !c.IsDead))
{
shuttleTransportTimer = 0.0f;
}
if (shuttleTransportTimer <= 0.0f)
{
GameServer.Log("The respawn shuttle is leaving.", ServerLog.MessageType.ServerMessage);
state = State.Returning;
server.CreateEntityEvent(this);
CountdownStarted = false;
maxTransportTime = server.ServerSettings.MaxTransportTime;
shuttleReturnTimer = maxTransportTime;
shuttleTransportTimer = maxTransportTime;
}
#endif
UpdateTransportingProjSpecific(deltaTime);
}
partial void UpdateTransportingProjSpecific(float deltaTime);
private void UpdateReturning(float deltaTime)
{
//if (shuttleReturnTimer == maxTransportTime &&
@@ -216,56 +186,13 @@ namespace Barotrauma.Networking
{
shuttleSteering.SetDestinationLevelStart();
}
#if SERVER
var server = networkMember as GameServer;
if (server == null) return;
foreach (Door door in shuttleDoors)
{
if (door.IsOpen) door.TrySetState(false, false, true);
}
var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == respawnShuttle && g.ConnectedWall != null);
shuttleGaps.ForEach(g => Spawner.AddToRemoveQueue(g));
var dockingPorts = Item.ItemList.FindAll(i => i.Submarine == respawnShuttle && i.GetComponent<DockingPort>() != null);
dockingPorts.ForEach(d => d.GetComponent<DockingPort>().Undock());
//shuttle has returned if the path has been traversed or the shuttle is close enough to the exit
if (!CoroutineManager.IsCoroutineRunning("forcepos"))
{
if ((shuttleSteering?.SteeringPath != null && shuttleSteering.SteeringPath.Finished)
|| (respawnShuttle.WorldPosition.Y + respawnShuttle.Borders.Y > Level.Loaded.StartPosition.Y - Level.ShaftHeight &&
Math.Abs(Level.Loaded.StartPosition.X - respawnShuttle.WorldPosition.X) < 1000.0f))
{
CoroutineManager.StopCoroutines("forcepos");
CoroutineManager.StartCoroutine(
ForceShuttleToPos(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f), 100.0f), "forcepos");
}
}
if (respawnShuttle.WorldPosition.Y > Level.Loaded.Size.Y || shuttleReturnTimer <= 0.0f)
{
CoroutineManager.StopCoroutines("forcepos");
ResetShuttle();
state = State.Waiting;
GameServer.Log("The respawn shuttle has left.", ServerLog.MessageType.Spawning);
server.CreateEntityEvent(this);
respawnTimer = server.ServerSettings.RespawnInterval;
CountdownStarted = false;
}
#endif
UpdateReturningProjSpecific();
}
}
partial void DispatchShuttle();
partial void UpdateReturningProjSpecific();
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
{
@@ -314,6 +241,7 @@ namespace Barotrauma.Networking
//restore other items to full condition and recharge batteries
item.Condition = item.Prefab.Health;
item.GetComponent<Repairable>()?.ResetDeterioration();
var powerContainer = item.GetComponent<PowerContainer>();
if (powerContainer != null)
{