(a410fd46c) Trying to help the merge script through a jungle of merges
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user