Merge remote-tracking branch 'Regalis11/master' into vanillawork
This commit is contained in:
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.8.1.5")]
|
||||
[assembly: AssemblyFileVersion("0.8.1.5")]
|
||||
[assembly: AssemblyVersion("0.8.1.7")]
|
||||
[assembly: AssemblyFileVersion("0.8.1.7")]
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Barotrauma
|
||||
|
||||
public Camera()
|
||||
{
|
||||
zoom = 1.0f;
|
||||
zoom = prevZoom = 1.0f;
|
||||
rotation = 0.0f;
|
||||
position = Vector2.Zero;
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Barotrauma
|
||||
viewMatrix =
|
||||
Matrix.CreateTranslation(new Vector3(GameMain.GraphicsWidth / 2.0f, GameMain.GraphicsHeight / 2.0f, 0));
|
||||
|
||||
UpdateTransform();
|
||||
UpdateTransform(false);
|
||||
}
|
||||
|
||||
public Vector2 TargetPos
|
||||
|
||||
@@ -81,6 +81,9 @@ namespace Barotrauma
|
||||
if (Limbs == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to draw a ragdoll, limbs have been removed. Character: \"" + character.Name + "\", removed: " + character.Removed + "\n" + Environment.StackTrace);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Ragdoll.Draw:LimbsRemoved",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to draw a ragdoll, limbs have been removed. Character: \"" + character.Name + "\", removed: " + character.Removed + "\n" + Environment.StackTrace);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -206,8 +206,8 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.GameSession.CrewManager.RemoveCharacter(this);
|
||||
}
|
||||
|
||||
if (GameMain.Client != null && GameMain.Client.Character == this) GameMain.Client.Character = null;
|
||||
|
||||
if (GameMain.NetworkMember?.Character == this) GameMain.NetworkMember.Character = null;
|
||||
|
||||
if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Barotrauma
|
||||
|
||||
public static void TakeDamage(float amount)
|
||||
{
|
||||
healthBar.Flash();
|
||||
healthBar?.Flash();
|
||||
|
||||
damageOverlayTimer = MathHelper.Clamp(amount * 0.1f, 0.2f, 1.0f);
|
||||
}
|
||||
|
||||
@@ -188,6 +188,7 @@ namespace Barotrauma
|
||||
|
||||
controlled = this;
|
||||
IsRemotePlayer = false;
|
||||
GameMain.Client.HasSpawned = true;
|
||||
GameMain.Client.Character = this;
|
||||
GameMain.LightManager.LosEnabled = true;
|
||||
}
|
||||
@@ -286,6 +287,7 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.Client.ID == ownerId)
|
||||
{
|
||||
GameMain.Client.HasSpawned = true;
|
||||
GameMain.Client.Character = character;
|
||||
Controlled = character;
|
||||
|
||||
|
||||
@@ -438,6 +438,8 @@ namespace Barotrauma
|
||||
NewMessage("Resolution set to 0 x 0 (screen resolution will be used)", Color.Green);
|
||||
NewMessage("Fullscreen enabled", Color.Green);
|
||||
|
||||
GameSettings.ShowUserStatisticsPrompt = true;
|
||||
|
||||
GameSettings.VerboseLogging = false;
|
||||
|
||||
if (GameMain.Config.MasterServerUrl != "http://www.undertowgames.com/baromaster")
|
||||
|
||||
@@ -214,12 +214,9 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.GameSession != null)
|
||||
{
|
||||
if (GameSettings.SendUserStatistics)
|
||||
{
|
||||
Mission mission = GameMain.GameSession.Mission;
|
||||
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("QuitRound:" + (save ? "Save" : "NoSave"));
|
||||
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("EndRound:" + (mission == null ? "NoMission" : (mission.Completed ? "MissionCompleted" : "MissionFailed")));
|
||||
}
|
||||
Mission mission = GameMain.GameSession.Mission;
|
||||
GameAnalyticsManager.AddDesignEvent("QuitRound:" + (save ? "Save" : "NoSave"));
|
||||
GameAnalyticsManager.AddDesignEvent("EndRound:" + (mission == null ? "NoMission" : (mission.Completed ? "MissionCompleted" : "MissionFailed")));
|
||||
GameMain.GameSession = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace Barotrauma
|
||||
Config.WasGameUpdated = false;
|
||||
Config.Save("config.xml");
|
||||
}
|
||||
|
||||
|
||||
ApplyGraphicsSettings();
|
||||
|
||||
Content.RootDirectory = "Content";
|
||||
@@ -244,12 +244,18 @@ namespace Barotrauma
|
||||
new string[] { "Yes", "No" });
|
||||
userStatsPrompt.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
GameSettings.ShowUserStatisticsPrompt = false;
|
||||
GameSettings.SendUserStatistics = true;
|
||||
GameAnalyticsManager.Init();
|
||||
return true;
|
||||
};
|
||||
userStatsPrompt.Buttons[0].OnClicked += userStatsPrompt.Close;
|
||||
userStatsPrompt.Buttons[1].OnClicked += (btn, userdata) => { GameSettings.SendUserStatistics = false; return true; };
|
||||
userStatsPrompt.Buttons[1].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
GameSettings.ShowUserStatisticsPrompt = false;
|
||||
GameSettings.SendUserStatistics = false;
|
||||
return true;
|
||||
};
|
||||
userStatsPrompt.Buttons[1].OnClicked += userStatsPrompt.Close;
|
||||
}
|
||||
else if (GameSettings.SendUserStatistics)
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Barotrauma
|
||||
return verticeList;
|
||||
}
|
||||
|
||||
public static VertexPositionTexture[] GenerateWallShapes(List<VoronoiCell> cells)
|
||||
public static VertexPositionTexture[] GenerateWallShapes(List<VoronoiCell> cells, Level level)
|
||||
{
|
||||
float inwardThickness = 500.0f, outWardThickness = 30.0f;
|
||||
|
||||
@@ -80,6 +80,10 @@ namespace Barotrauma
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Invalid left normal");
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce("CaveGenerator.GenerateWallShapes:InvalidLeftNormal:" + level.Seed,
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
|
||||
"Invalid left normal (leftedge: " + leftEdge + ", rightedge: " + rightEdge + ", normal: " + leftNormal + ", seed: " + level.Seed + ")");
|
||||
|
||||
if (cell.body != null)
|
||||
{
|
||||
GameMain.World.RemoveBody(cell.body);
|
||||
@@ -106,6 +110,10 @@ namespace Barotrauma
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Invalid right normal");
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce("CaveGenerator.GenerateWallShapes:InvalidRightNormal:" + level.Seed,
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
|
||||
"Invalid right normal (leftedge: " + leftEdge + ", rightedge: " + rightEdge + ", normal: " + rightNormal + ", seed: " + level.Seed + ")");
|
||||
|
||||
if (cell.body != null)
|
||||
{
|
||||
GameMain.World.RemoveBody(cell.body);
|
||||
|
||||
@@ -44,6 +44,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
private FileReceiver fileReceiver;
|
||||
|
||||
//has the client been given a character to control this round
|
||||
public bool HasSpawned;
|
||||
|
||||
public byte ID
|
||||
{
|
||||
get { return myID; }
|
||||
@@ -480,7 +483,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
endVoteTickBox.Visible = Voting.AllowEndVoting && myCharacter != null;
|
||||
endVoteTickBox.Visible = Voting.AllowEndVoting && HasSpawned;
|
||||
|
||||
if (respawnManager != null)
|
||||
{
|
||||
@@ -666,6 +669,7 @@ namespace Barotrauma.Networking
|
||||
private IEnumerable<object> StartGame(NetIncomingMessage inc)
|
||||
{
|
||||
if (Character != null) Character.Remove();
|
||||
HasSpawned = false;
|
||||
|
||||
GameMain.LightManager.LightingEnabled = true;
|
||||
|
||||
@@ -815,7 +819,7 @@ namespace Barotrauma.Networking
|
||||
string subName = inc.ReadString();
|
||||
string subHash = inc.ReadString();
|
||||
|
||||
var matchingSub = Submarine.SavedSubmarines.Find(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
||||
var matchingSub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
||||
if (matchingSub != null)
|
||||
{
|
||||
submarines.Add(matchingSub);
|
||||
@@ -1016,29 +1020,32 @@ namespace Barotrauma.Networking
|
||||
ChatMessage.ClientRead(inc);
|
||||
break;
|
||||
default:
|
||||
DebugConsole.ThrowError("Error while reading update from server (unknown object header \""+objHeader+"\"!)");
|
||||
if (prevObjHeader != null)
|
||||
List<string> errorLines = new List<string>
|
||||
{
|
||||
DebugConsole.ThrowError("Previous object type: " + prevObjHeader.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Error occurred on the very first object!");
|
||||
}
|
||||
DebugConsole.ThrowError("Previous object was " + (inc.Position - prevBitPos) + " bits long (" + (inc.PositionInBytes - prevBytePos) + " bytes)");
|
||||
"Error while reading update from server (unknown object header \"" + objHeader + "\"!)",
|
||||
prevObjHeader != null ? "Previous object type: " + prevObjHeader.ToString() : "Error occurred on the very first object!",
|
||||
"Previous object was " + (inc.Position - prevBitPos) + " bits long (" + (inc.PositionInBytes - prevBytePos) + " bytes)"
|
||||
};
|
||||
if (prevObjHeader == ServerNetObject.ENTITY_EVENT || prevObjHeader == ServerNetObject.ENTITY_EVENT_INITIAL)
|
||||
{
|
||||
foreach (IServerSerializable ent in entities)
|
||||
{
|
||||
if (ent == null)
|
||||
{
|
||||
DebugConsole.ThrowError(" - NULL");
|
||||
errorLines.Add(" - NULL");
|
||||
continue;
|
||||
}
|
||||
Entity e = ent as Entity;
|
||||
DebugConsole.ThrowError(" - "+e.ToString());
|
||||
errorLines.Add(" - " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string line in errorLines)
|
||||
{
|
||||
DebugConsole.ThrowError(line);
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadInGameUpdate", GameAnalyticsSDK.Net.EGAErrorSeverity.Critical, string.Join("\n", errorLines));
|
||||
|
||||
DebugConsole.ThrowError("Writing object data to \"crashreport_object.bin\", please send this file to us at http://github.com/Regalis11/Barotrauma/issues");
|
||||
|
||||
FileStream fl = File.Open("crashreport_object.bin", FileMode.Create);
|
||||
@@ -1181,8 +1188,12 @@ namespace Barotrauma.Networking
|
||||
case FileTransferType.Submarine:
|
||||
new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully.");
|
||||
var newSub = new Submarine(transfer.FilePath);
|
||||
Submarine.SavedSubmarines.RemoveAll(s => s.Name == newSub.Name && s.MD5Hash.Hash == newSub.MD5Hash.Hash);
|
||||
Submarine.SavedSubmarines.Add(newSub);
|
||||
var existingSubs = Submarine.SavedSubmarines.Where(s => s.Name == newSub.Name && s.MD5Hash.Hash == newSub.MD5Hash.Hash).ToList();
|
||||
foreach (Submarine existingSub in existingSubs)
|
||||
{
|
||||
existingSub.Dispose();
|
||||
}
|
||||
Submarine.AddToSavedSubs(newSub);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
@@ -1277,6 +1288,23 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
if (Screen.Selected == GameMain.GameScreen && !GUI.DisableHUD)
|
||||
{
|
||||
if (EndVoteCount > 0)
|
||||
{
|
||||
if (!HasSpawned)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 180.0f, 40),
|
||||
"Votes to end the round (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 140.0f, 40),
|
||||
"Votes (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fileReceiver != null && fileReceiver.ActiveTransfers.Count > 0)
|
||||
{
|
||||
Vector2 pos = new Vector2(GameMain.NetLobbyScreen.InfoFrame.Rect.X, GameMain.GraphicsHeight - 35);
|
||||
@@ -1560,14 +1588,13 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (!gameStarted) return false;
|
||||
|
||||
if (!Voting.AllowEndVoting || myCharacter==null)
|
||||
if (!Voting.AllowEndVoting || !HasSpawned)
|
||||
{
|
||||
tickBox.Visible = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
Vote(VoteType.EndRound, tickBox.Selected);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,15 @@ namespace Barotrauma.Networking
|
||||
log.LogFrame.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
if (Screen.Selected == GameMain.GameScreen && !GUI.DisableHUD)
|
||||
{
|
||||
if (EndVoteCount > 0)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 180.0f, 40),
|
||||
"Votes to end the round (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ShowNetStats) return;
|
||||
|
||||
GUI.Font.DrawString(spriteBatch, "Unique Events: " + entityEventManager.UniqueEvents.Count, new Vector2(10, 50), Color.White);
|
||||
|
||||
@@ -191,6 +191,9 @@ namespace Barotrauma.Networking
|
||||
if (GameSettings.VerboseLogging)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to read event for entity \"" + entity.ToString() + "\"!", e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:ReadFailed" + entity.ToString(),
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to read event for entity \"" + entity.ToString() + "\"!\n" + e.StackTrace);
|
||||
}
|
||||
msg.Position = msgPosition + msgLength * 8;
|
||||
}
|
||||
|
||||
@@ -119,20 +119,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
inGameHUD.Draw(spriteBatch);
|
||||
|
||||
if (EndVoteCount > 0)
|
||||
{
|
||||
if (GameMain.NetworkMember.myCharacter == null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 180.0f, 40),
|
||||
"Votes to end the round (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 140.0f, 40),
|
||||
"Votes (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont);
|
||||
}
|
||||
}
|
||||
|
||||
if (respawnManager != null)
|
||||
{
|
||||
string respawnInfo = "";
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -151,7 +152,7 @@ namespace Barotrauma
|
||||
{
|
||||
int votes = inc.ReadByte();
|
||||
string subName = inc.ReadString();
|
||||
Submarine sub = Submarine.SavedSubmarines.Find(sm => sm.Name == subName);
|
||||
Submarine sub = Submarine.SavedSubmarines.FirstOrDefault(sm => sm.Name == subName);
|
||||
SetVoteText(GameMain.NetLobbyScreen.SubList, sub, votes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace Barotrauma
|
||||
if (GameSettings.SendUserStatistics)
|
||||
{
|
||||
CrashMessageBox( "A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers.");
|
||||
GameAnalytics.AddErrorEvent(EGAErrorSeverity.Error, crashReport);
|
||||
GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport);
|
||||
GameAnalytics.OnStop();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
}
|
||||
if (Submarine.SavedSubmarines.Count > 0) subList.Select(Submarine.SavedSubmarines[0]);
|
||||
if (Submarine.SavedSubmarines.Any()) subList.Select(Submarine.SavedSubmarines.First());
|
||||
}
|
||||
|
||||
public void UpdateLoadMenu()
|
||||
|
||||
@@ -149,6 +149,8 @@ namespace Barotrauma
|
||||
null, null,
|
||||
Alignment.TopRight, "", frame);
|
||||
}
|
||||
|
||||
RefreshItemTab();
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
@@ -293,6 +295,7 @@ namespace Barotrauma
|
||||
{
|
||||
CreateItemFrame(ip, selectedItemList, selectedItemList.Rect.Width);
|
||||
}
|
||||
selectedItemList.UpdateScrollBarSize();
|
||||
}
|
||||
|
||||
public void SelectTab(Tab tab)
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Barotrauma
|
||||
campaignUI.OnLocationSelected = SelectLocation;
|
||||
campaignUI.UpdateCharacterLists();
|
||||
|
||||
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("singleplayer");
|
||||
GameAnalyticsManager.SetCustomDimension01("singleplayer");
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Barotrauma
|
||||
|
||||
SelectTab(null, 0);
|
||||
|
||||
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("");
|
||||
GameAnalyticsManager.SetCustomDimension01("");
|
||||
}
|
||||
|
||||
public bool SelectTab(GUIButton button, object obj)
|
||||
|
||||
@@ -501,7 +501,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("multiplayer");
|
||||
GameAnalyticsManager.SetCustomDimension01("multiplayer");
|
||||
|
||||
if (GameModePreset.list.Count > 0 && modeList.Selected == null) modeList.Select(0);
|
||||
|
||||
@@ -737,8 +737,20 @@ namespace Barotrauma
|
||||
//hash will be null if opening the sub file failed -> don't select the sub
|
||||
if (string.IsNullOrWhiteSpace(hash))
|
||||
{
|
||||
(component as GUITextBlock).TextColor = Color.DarkRed * 0.8f;
|
||||
component.CanBeFocused = false;
|
||||
if (component is GUITextBlock textBlock)
|
||||
{
|
||||
textBlock.TextColor = Color.DarkRed * 0.8f;
|
||||
textBlock.CanBeFocused = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to select submarine. Selected GUIComponent was of the type \"" + (component == null ? "null" : component.GetType().ToString()) + "\".");
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"NetLobbyScreen.SelectSub:InvalidComponent",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to select submarine. Selected GUIComponent was of the type \"" + (component == null ? "null" : component.GetType().ToString()) + "\".");
|
||||
}
|
||||
|
||||
|
||||
StartButton.Enabled = false;
|
||||
|
||||
@@ -782,8 +794,8 @@ namespace Barotrauma
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
var matchingSub = Submarine.SavedSubmarines.Find(s => s.Name == sub.Name && s.MD5Hash.Hash == sub.MD5Hash.Hash);
|
||||
if (matchingSub == null) matchingSub = Submarine.SavedSubmarines.Find(s => s.Name == sub.Name);
|
||||
var matchingSub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name == sub.Name && s.MD5Hash.Hash == sub.MD5Hash.Hash);
|
||||
if (matchingSub == null) matchingSub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name == sub.Name);
|
||||
|
||||
if (matchingSub == null)
|
||||
{
|
||||
@@ -1467,8 +1479,8 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
Submarine sub = Submarine.SavedSubmarines.Find(m => m.Name == subName && m.MD5Hash.Hash == md5Hash);
|
||||
if (sub == null) sub = Submarine.SavedSubmarines.Find(m => m.Name == subName);
|
||||
Submarine sub = Submarine.SavedSubmarines.FirstOrDefault(m => m.Name == subName && m.MD5Hash.Hash == md5Hash);
|
||||
if (sub == null) sub = Submarine.SavedSubmarines.FirstOrDefault(m => m.Name == subName);
|
||||
|
||||
var matchingListSub = subList.children.Find(c => c.UserData == sub);
|
||||
if (matchingListSub != null)
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace Barotrauma
|
||||
|
||||
cam.UpdateTransform();
|
||||
|
||||
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.SetCustomDimension01("editor");
|
||||
GameAnalyticsManager.SetCustomDimension01("editor");
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Barotrauma.Sounds
|
||||
AL.BufferData(sound.alBufferId, reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, sound.castBuffer,
|
||||
readSamples * sizeof(short), reader.SampleRate);
|
||||
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(oggFile);
|
||||
}
|
||||
|
||||
//AL.Source(alSourceId, ALSourcei.Buffer, alBufferId);
|
||||
@@ -100,12 +100,12 @@ namespace Barotrauma.Sounds
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
//var state = AL.GetSourceState(alSourceId);
|
||||
//if (state == ALSourceState.Playing || state == ALSourceState.Paused)
|
||||
// Stop();
|
||||
System.Diagnostics.Debug.WriteLine(alBufferId);
|
||||
//AL.DeleteSource(alSourceId);
|
||||
AL.DeleteBuffer(alBufferId);
|
||||
if (alBufferId > 0)
|
||||
{
|
||||
AL.DeleteBuffer(alBufferId);
|
||||
alBufferId = 0;
|
||||
}
|
||||
|
||||
//if (ALHelper.Efx.IsInitialized)
|
||||
// ALHelper.Efx.DeleteFilter(alFilterId);
|
||||
|
||||
@@ -45,16 +45,24 @@ namespace Barotrauma.Sounds
|
||||
//logHandler(String.Format("Total memory : {0:0.###} {1} ", usedHeap, sizes[order]), 0, 6);
|
||||
}
|
||||
|
||||
public static void Check()
|
||||
public static void Check(string extraErrorMsg = "")
|
||||
{
|
||||
ALError error;
|
||||
if ((error = AL.GetError()) != ALError.NoError)
|
||||
{
|
||||
string errorMsg = "OpenAL error: " + AL.GetErrorString(error);
|
||||
if (!string.IsNullOrEmpty(extraErrorMsg)) errorMsg += " {" + extraErrorMsg + "} ";
|
||||
errorMsg += "\n" + Environment.StackTrace;
|
||||
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("OpenAL error: " + AL.GetErrorString(error) + "\n" + Environment.StackTrace);
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
#else
|
||||
DebugConsole.NewMessage("OpenAL error: " + AL.GetErrorString(error) + "\n" + Environment.StackTrace, Microsoft.Xna.Framework.Color.Red);
|
||||
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"OggStream.Check:" + AL.GetErrorString(error) + extraErrorMsg,
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,9 +91,17 @@ namespace Barotrauma.Sounds
|
||||
public Action<string, int, int> LogHandler;
|
||||
#endif
|
||||
|
||||
public OggStream(string filename, int bufferCount = DefaultBufferCount) : this(File.OpenRead(filename), bufferCount) { }
|
||||
public OggStream(Stream stream, int bufferCount = DefaultBufferCount)
|
||||
public string FileName
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public OggStream(string filename, int bufferCount = DefaultBufferCount) : this(File.OpenRead(filename), filename, bufferCount) { }
|
||||
public OggStream(Stream stream, string fileName, int bufferCount = DefaultBufferCount)
|
||||
{
|
||||
this.FileName = fileName;
|
||||
|
||||
BufferCount = bufferCount;
|
||||
|
||||
alBufferIds = AL.GenBuffers(bufferCount);
|
||||
@@ -94,7 +110,7 @@ namespace Barotrauma.Sounds
|
||||
if (ALHelper.XRam.IsInitialized)
|
||||
{
|
||||
ALHelper.XRam.SetBufferMode(BufferCount, ref alBufferIds[0], XRamExtension.XRamStorage.Hardware);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(fileName);
|
||||
}
|
||||
|
||||
if (ALHelper.Efx.IsInitialized)
|
||||
@@ -163,7 +179,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
AL.SourcePlay(alSourceId);
|
||||
this.Volume = volume;
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
|
||||
Preparing = false;
|
||||
|
||||
@@ -177,7 +193,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
OggStreamer.Instance.RemoveStream(this);
|
||||
AL.SourcePause(alSourceId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
@@ -187,7 +203,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
OggStreamer.Instance.AddStream(this);
|
||||
AL.SourcePlay(alSourceId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
@@ -226,7 +242,7 @@ namespace Barotrauma.Sounds
|
||||
set
|
||||
{
|
||||
AL.Source(alSourceId, ALSourcef.Gain, volume = value);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,20 +272,20 @@ namespace Barotrauma.Sounds
|
||||
/*if (ALHelper.Efx.IsInitialized)
|
||||
ALHelper.Efx.DeleteFilter(alFilterId);*/
|
||||
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
}
|
||||
|
||||
void StopPlayback()
|
||||
{
|
||||
AL.SourceStop(alSourceId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
}
|
||||
|
||||
void Empty()
|
||||
{
|
||||
int queued;
|
||||
AL.GetSource(alSourceId, ALGetSourcei.BuffersQueued, out queued);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
|
||||
if (queued > 0)
|
||||
{
|
||||
@@ -292,12 +308,12 @@ namespace Barotrauma.Sounds
|
||||
if (processed > 0)
|
||||
{
|
||||
AL.SourceUnqueueBuffers(alSourceId, processed, salvaged);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
}
|
||||
|
||||
// Try turning it off again?
|
||||
AL.SourceStop(alSourceId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
|
||||
Empty();
|
||||
}
|
||||
@@ -314,7 +330,7 @@ namespace Barotrauma.Sounds
|
||||
// Fill first buffer synchronously
|
||||
OggStreamer.Instance.FillBuffer(this, alBufferIds[0]);
|
||||
AL.SourceQueueBuffer(alSourceId, alBufferIds[0]);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(FileName);
|
||||
|
||||
// Schedule the others asynchronously
|
||||
OggStreamer.Instance.AddStream(this);
|
||||
@@ -429,7 +445,7 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
AL.BufferData(bufferId, stream.Reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, castBuffer,
|
||||
readSamples * sizeof(short), stream.Reader.SampleRate);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(stream.FileName);
|
||||
|
||||
return readSamples != BufferSize;
|
||||
}
|
||||
@@ -466,10 +482,10 @@ namespace Barotrauma.Sounds
|
||||
|
||||
int queued;
|
||||
AL.GetSource(stream.alSourceId, ALGetSourcei.BuffersQueued, out queued);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(stream.FileName);
|
||||
int processed;
|
||||
AL.GetSource(stream.alSourceId, ALGetSourcei.BuffersProcessed, out processed);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(stream.FileName);
|
||||
|
||||
if (processed == 0 && queued == stream.BufferCount) continue;
|
||||
|
||||
@@ -496,7 +512,7 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
|
||||
AL.SourceQueueBuffers(stream.alSourceId, tempBuffers.Length, tempBuffers);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(stream.FileName);
|
||||
|
||||
if (finished && !stream.IsLooped)
|
||||
continue;
|
||||
@@ -514,7 +530,7 @@ namespace Barotrauma.Sounds
|
||||
if (state == ALSourceState.Stopped)
|
||||
{
|
||||
AL.SourcePlay(stream.alSourceId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(stream.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Barotrauma
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to load sound "+file+"!", e);
|
||||
}
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(file);
|
||||
}
|
||||
|
||||
baseVolume = 1.0f;
|
||||
@@ -219,7 +219,7 @@ namespace Barotrauma
|
||||
(SoundManager.IsPlaying(alSourceId) || SoundManager.IsPaused(alSourceId)))
|
||||
{
|
||||
SoundManager.Stop(alSourceId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(filePath);
|
||||
}
|
||||
|
||||
foreach (Sound s in loadedSounds)
|
||||
@@ -228,7 +228,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
SoundManager.ClearAlSource(AlBufferId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(filePath);
|
||||
|
||||
if (oggSound != null)
|
||||
{
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Barotrauma.Sounds
|
||||
volume = 0.0f;
|
||||
}
|
||||
|
||||
if (sourceIndex<1 || soundsPlaying[sourceIndex] != sound)
|
||||
if (sourceIndex < 1 || soundsPlaying[sourceIndex] != sound)
|
||||
{
|
||||
sourceIndex = Play(sound, position, volume, 0.0f, true);
|
||||
}
|
||||
@@ -153,7 +153,7 @@ namespace Barotrauma.Sounds
|
||||
AL.Source(alSources[sourceIndex], ALSourceb.Looping, true);
|
||||
}
|
||||
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(sound?.FilePath);
|
||||
return sourceIndex;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace Barotrauma.Sounds
|
||||
return;
|
||||
|
||||
AL.SourcePause(alSources[sourceIndex]);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(soundsPlaying[sourceIndex]?.FilePath);
|
||||
}
|
||||
|
||||
public static void Resume(int sourceIndex)
|
||||
@@ -176,7 +176,7 @@ namespace Barotrauma.Sounds
|
||||
return;
|
||||
|
||||
AL.SourcePlay(alSources[sourceIndex]);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(soundsPlaying[sourceIndex]?.FilePath);
|
||||
}
|
||||
|
||||
public static void Stop(int sourceIndex)
|
||||
@@ -291,7 +291,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassHfGain = value);
|
||||
ALHelper.Efx.BindFilterToSource(alSources[i], lowpassFilterId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(soundsPlaying[i]?.FilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,7 +316,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassGain);
|
||||
ALHelper.Efx.BindFilterToSource(alSources[sourceIndex], lowpassFilterId);
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(soundsPlaying[sourceIndex]?.FilePath);
|
||||
}
|
||||
|
||||
public static OggStream StartStream(string file, float volume = 1.0f)
|
||||
@@ -331,7 +331,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
oggStream.Play(volume);
|
||||
|
||||
ALHelper.Check();
|
||||
ALHelper.Check(file);
|
||||
|
||||
return oggStream;
|
||||
}
|
||||
@@ -361,15 +361,15 @@ namespace Barotrauma.Sounds
|
||||
|
||||
for (int i = 0; i < DefaultSourceCount; i++)
|
||||
{
|
||||
string soundPath = soundsPlaying[i]?.FilePath;
|
||||
var state = OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]);
|
||||
if (state == OpenTK.Audio.OpenAL.ALSourceState.Playing || state == OpenTK.Audio.OpenAL.ALSourceState.Paused)
|
||||
{
|
||||
Stop(i);
|
||||
}
|
||||
|
||||
OpenTK.Audio.OpenAL.AL.DeleteSource(alSources[i]);
|
||||
|
||||
ALHelper.Check();
|
||||
OpenTK.Audio.OpenAL.AL.DeleteSource(alSources[i]);
|
||||
ALHelper.Check(soundPath);
|
||||
}
|
||||
|
||||
if (oggStream != null)
|
||||
|
||||
@@ -254,11 +254,14 @@ namespace Barotrauma
|
||||
partial void DisposeTexture()
|
||||
{
|
||||
//check if another sprite is using the same texture
|
||||
foreach (Sprite s in list)
|
||||
if (!string.IsNullOrEmpty(file)) //file can be empty if the sprite is created directly from a Texture2D instance
|
||||
{
|
||||
if (s.file == file) return;
|
||||
foreach (Sprite s in list)
|
||||
{
|
||||
if (s.file == file) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if not, free the texture
|
||||
if (texture != null)
|
||||
{
|
||||
@@ -267,6 +270,5 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.8.1.5")]
|
||||
[assembly: AssemblyFileVersion("0.8.1.5")]
|
||||
[assembly: AssemblyVersion("0.8.1.7")]
|
||||
[assembly: AssemblyFileVersion("0.8.1.7")]
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace Barotrauma
|
||||
|
||||
subs = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus)).ToList();
|
||||
|
||||
if (subs == null || subs.Count()==0)
|
||||
if (subs == null || subs.Count() == 0)
|
||||
{
|
||||
throw new Exception("No submarines are available.");
|
||||
}
|
||||
@@ -187,7 +187,7 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.Server.SubSelectionMode == SelectionMode.Random)
|
||||
{
|
||||
var nonShuttles = Submarine.SavedSubmarines.FindAll(c => !c.HasTag(SubmarineTag.Shuttle) && !c.HasTag(SubmarineTag.HideInMenus));
|
||||
var nonShuttles = Submarine.SavedSubmarines.Where(c => !c.HasTag(SubmarineTag.Shuttle) && !c.HasTag(SubmarineTag.HideInMenus)).ToList();
|
||||
SelectedSub = nonShuttles[Rand.Range(0, nonShuttles.Count)];
|
||||
}
|
||||
if (GameMain.Server.ModeSelectionMode == SelectionMode.Random)
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
|
||||
<Sprite texture="signalcomp.png" depth="0.8" sourcerect="48,16,16,16"/>
|
||||
|
||||
<RelayComponent canbeselected = "true">
|
||||
<RelayComponent canbeselected="true" vulnerabletoemp="false">
|
||||
<GuiFrame rect="0,0,200,160" alignment="Center" style="ItemUI"/>
|
||||
</RelayComponent>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<Sprite texture = "reactor.png" sourcerect="0,0,321,192" depth="0.8"/>
|
||||
|
||||
<Reactor canbeselected = "true">
|
||||
<Reactor canbeselected="true" vulnerabletoemp="false">
|
||||
<GuiFrame rect="0,0,760,460" alignment="Center" style="ItemUI"/>
|
||||
<RequiredSkill name="Construction" level="30"/>
|
||||
<StatusEffect type="InWater" target="This" Temperature="-500.0"/>
|
||||
|
||||
@@ -38,6 +38,9 @@ namespace Barotrauma
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Attempted to access a removed AITarget\n" + Environment.StackTrace);
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce("AITarget.WorldPosition:EntityRemoved",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Attempted to access a removed AITarget\n" + Environment.StackTrace);
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
@@ -54,6 +57,9 @@ namespace Barotrauma
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Attempted to access a removed AITarget\n" + Environment.StackTrace);
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce("AITarget.WorldPosition:EntityRemoved",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Attempted to access a removed AITarget\n" + Environment.StackTrace);
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
|
||||
@@ -274,6 +274,12 @@ namespace Barotrauma
|
||||
|
||||
private void UpdateEscape(float deltaTime)
|
||||
{
|
||||
if (selectedAiTarget == null || selectedAiTarget.Entity == null || selectedAiTarget.Entity.Removed)
|
||||
{
|
||||
state = AIState.None;
|
||||
return;
|
||||
}
|
||||
|
||||
SteeringManager.SteeringManual(deltaTime, Vector2.Normalize(SimPosition - selectedAiTarget.SimPosition) * 5);
|
||||
SteeringManager.SteeringWander(1.0f);
|
||||
SteeringManager.SteeringAvoid(deltaTime, 2f);
|
||||
|
||||
@@ -25,6 +25,11 @@ namespace Barotrauma
|
||||
if (limbs == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Attempted to access a potentially removed ragdoll. Character: " + character.Name + ", id: " + character.ID + ", removed: " + character.Removed + ", ragdoll removed: " + !list.Contains(this));
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"Ragdoll.Limbs:AccessRemoved",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Attempted to access a potentially removed ragdoll. Character: " + character.Name + ", id: " + character.ID + ", removed: " + character.Removed + ", ragdoll removed: " + !list.Contains(this) + "\n" + Environment.StackTrace);
|
||||
|
||||
return new Limb[0];
|
||||
}
|
||||
return limbs;
|
||||
@@ -87,7 +92,9 @@ namespace Barotrauma
|
||||
|
||||
protected List<PhysicsBody> collider;
|
||||
protected int colliderIndex = 0;
|
||||
|
||||
|
||||
private Category prevCollisionCategory = Category.None;
|
||||
|
||||
public PhysicsBody Collider
|
||||
{
|
||||
get
|
||||
@@ -269,11 +276,7 @@ namespace Barotrauma
|
||||
get { return ignorePlatforms; }
|
||||
set
|
||||
{
|
||||
if (ignorePlatforms == value) return;
|
||||
ignorePlatforms = value;
|
||||
|
||||
UpdateCollisionCategories();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,8 +368,8 @@ namespace Barotrauma
|
||||
|
||||
foreach (var joint in LimbJoints)
|
||||
{
|
||||
joint.BodyB.SetTransform(
|
||||
joint.BodyA.Position + (joint.LocalAnchorA - joint.LocalAnchorB)*0.1f,
|
||||
joint.LimbB?.body?.SetTransform(
|
||||
joint.BodyA.Position + (joint.LocalAnchorA - joint.LocalAnchorB) * 0.1f,
|
||||
(joint.LowerLimit + joint.UpperLimit) / 2.0f);
|
||||
}
|
||||
|
||||
@@ -391,7 +394,7 @@ namespace Barotrauma
|
||||
Limb torso = GetLimb(LimbType.Torso);
|
||||
Limb head = GetLimb(LimbType.Head);
|
||||
|
||||
MainLimb = torso == null ? head : torso;
|
||||
MainLimb = torso ?? head;
|
||||
}
|
||||
|
||||
public void AddJoint(XElement subElement, float scale = 1.0f)
|
||||
@@ -739,7 +742,15 @@ namespace Barotrauma
|
||||
|
||||
public void FindHull(Vector2? worldPosition = null, bool setSubmarine = true)
|
||||
{
|
||||
Vector2 findPos = worldPosition==null ? this.WorldPosition : (Vector2)worldPosition;
|
||||
Vector2 findPos = worldPosition == null ? this.WorldPosition : (Vector2)worldPosition;
|
||||
if (!MathUtils.IsValid(findPos))
|
||||
{
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"Ragdoll.FindHull:InvalidPosition",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Attempted to find a hull at an invalid position (" + findPos + ")\n" + Environment.StackTrace);
|
||||
return;
|
||||
}
|
||||
|
||||
Hull newHull = Hull.FindHull(findPos, currentHull);
|
||||
|
||||
@@ -799,10 +810,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
CurrentHull = newHull;
|
||||
|
||||
character.Submarine = currentHull == null ? null : currentHull.Submarine;
|
||||
|
||||
UpdateCollisionCategories();
|
||||
character.Submarine = currentHull?.Submarine;
|
||||
}
|
||||
|
||||
public void Teleport(Vector2 moveAmount, Vector2 velocityChange)
|
||||
@@ -842,7 +850,10 @@ namespace Barotrauma
|
||||
Category collisionCategory = (ignorePlatforms) ?
|
||||
wall | Physics.CollisionProjectile | Physics.CollisionStairs
|
||||
: wall | Physics.CollisionProjectile | Physics.CollisionPlatform | Physics.CollisionStairs;
|
||||
|
||||
|
||||
if (collisionCategory == prevCollisionCategory) return;
|
||||
prevCollisionCategory = collisionCategory;
|
||||
|
||||
Collider.CollidesWith = collisionCategory;
|
||||
|
||||
foreach (Limb limb in Limbs)
|
||||
@@ -868,6 +879,7 @@ namespace Barotrauma
|
||||
|
||||
UpdateNetPlayerPosition(deltaTime);
|
||||
CheckDistFromCollider();
|
||||
UpdateCollisionCategories();
|
||||
|
||||
Vector2 flowForce = Vector2.Zero;
|
||||
|
||||
@@ -1089,22 +1101,19 @@ namespace Barotrauma
|
||||
|
||||
float tfloorY = rayStart.Y + (rayEnd.Y - rayStart.Y) * closestFraction;
|
||||
float targetY = tfloorY + Collider.height * 0.5f + Collider.radius + colliderHeightFromFloor;
|
||||
|
||||
if (Math.Abs(Collider.SimPosition.Y - targetY) > 0.01f && Collider.SimPosition.Y<targetY && !forceImmediate)
|
||||
|
||||
if (Math.Abs(Collider.SimPosition.Y - targetY) > 0.01f)
|
||||
{
|
||||
Vector2 newSpeed = Collider.LinearVelocity;
|
||||
newSpeed.Y = (targetY - Collider.SimPosition.Y)*5.0f;
|
||||
Collider.LinearVelocity = newSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 newSpeed = Collider.LinearVelocity;
|
||||
newSpeed.Y = 0.0f;
|
||||
Collider.LinearVelocity = newSpeed;
|
||||
Vector2 newPos = Collider.SimPosition;
|
||||
newPos.Y = targetY;
|
||||
Collider.SetTransform(newPos, Collider.Rotation);
|
||||
}
|
||||
if (forceImmediate)
|
||||
{
|
||||
Collider.LinearVelocity = new Vector2(Collider.LinearVelocity.X, 0);
|
||||
Collider.SetTransform(new Vector2(Collider.SimPosition.X, targetY), Collider.Rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
Collider.LinearVelocity = new Vector2(Collider.LinearVelocity.X, (targetY - Collider.SimPosition.Y) * 5.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1165,6 +1174,16 @@ namespace Barotrauma
|
||||
|
||||
public void SetPosition(Vector2 simPosition, bool lerp = false)
|
||||
{
|
||||
if (!MathUtils.IsValid(simPosition))
|
||||
{
|
||||
DebugConsole.ThrowError("Attempted to move a ragdoll (" + character.Name + ") to an invalid position (" + simPosition + "). " + Environment.StackTrace);
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"Ragdoll.SetPosition:InvalidPosition",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Attempted to move a ragdoll (" + character.Name + ") to an invalid position (" + simPosition + "). " + Environment.StackTrace);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 limbMoveAmount = simPosition - MainLimb.SimPosition;
|
||||
|
||||
Collider.SetTransform(simPosition, Collider.Rotation);
|
||||
@@ -1245,8 +1264,6 @@ namespace Barotrauma
|
||||
{
|
||||
//set the position of the ragdoll to make sure limbs don't get stuck inside walls when re-enabling collisions
|
||||
SetPosition(Collider.SimPosition, true);
|
||||
|
||||
UpdateCollisionCategories();
|
||||
collisionsDisabled = false;
|
||||
}
|
||||
}
|
||||
@@ -1445,22 +1462,17 @@ namespace Barotrauma
|
||||
|
||||
private Vector2 GetFlowForce()
|
||||
{
|
||||
Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition);
|
||||
Vector2 limbPos = Limbs[0].Position;
|
||||
|
||||
Vector2 force = Vector2.Zero;
|
||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||
foreach (Gap gap in Gap.GapList)
|
||||
{
|
||||
Gap gap = e as Gap;
|
||||
if (gap == null || gap.FlowTargetHull != currentHull || gap.LerpedFlowForce == Vector2.Zero) continue;
|
||||
if (gap.Open <= 0.0f || gap.FlowTargetHull != currentHull || gap.LerpedFlowForce == Vector2.Zero) continue;
|
||||
|
||||
Vector2 gapPos = gap.SimPosition;
|
||||
|
||||
float dist = Vector2.Distance(limbPos, gapPos);
|
||||
|
||||
force += Vector2.Normalize(gap.LerpedFlowForce) * (Math.Max(gap.LerpedFlowForce.Length() - dist, 0.0f) / 500.0f);
|
||||
}
|
||||
|
||||
if (force.Length() > 20.0f) return force;
|
||||
return force;
|
||||
}
|
||||
|
||||
|
||||
@@ -1960,7 +1960,7 @@ namespace Barotrauma
|
||||
characterType = "Enemy";
|
||||
else if (AIController is HumanAIController)
|
||||
characterType = "AICrew";
|
||||
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("Kill:" + characterType + ":" + SpeciesName + ":" + causeOfDeath);
|
||||
GameAnalyticsManager.AddDesignEvent("Kill:" + characterType + ":" + SpeciesName + ":" + causeOfDeath);
|
||||
}
|
||||
|
||||
if (OnDeath != null) OnDeath(this, causeOfDeath);
|
||||
|
||||
@@ -1898,7 +1898,16 @@ namespace Barotrauma
|
||||
if (string.IsNullOrWhiteSpace(command)) return;
|
||||
|
||||
string[] splitCommand = SplitCommand(command);
|
||||
|
||||
if (splitCommand.Length == 0)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to execute command \"" + command + "\"!");
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"DebugConsole.ExecuteCommand:LengthZero",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to execute command \"" + command + "\"!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!splitCommand[0].ToLowerInvariant().Equals("admin"))
|
||||
{
|
||||
NewMessage(command, Color.White, true);
|
||||
@@ -1974,6 +1983,13 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.Server.SendConsoleMessage("Command \"" + splitCommand[0] + "\" not found.", client);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MathUtils.IsValid(cursorWorldPos))
|
||||
{
|
||||
GameMain.Server.SendConsoleMessage("Could not execute command \"" + command + "\" - invalid cursor position.", client);
|
||||
NewMessage(client.Name + " attempted to execute the console command \"" + command + "\" with invalid cursor position.", Color.White);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
@@ -1,19 +1,51 @@
|
||||
using GameAnalyticsSDK.Net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public static class GameAnalyticsManager
|
||||
{
|
||||
private static HashSet<string> sentEventIdentifiers = new HashSet<string>();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
#if DEBUG
|
||||
GameAnalytics.SetEnabledInfoLog(true);
|
||||
#endif
|
||||
GameAnalytics.ConfigureBuild(GameMain.Version.ToString());
|
||||
|
||||
string exePath = Assembly.GetEntryAssembly().Location;
|
||||
string exeName = null;
|
||||
Md5Hash exeHash = null;
|
||||
exeName = Path.GetFileNameWithoutExtension(exePath).Replace(":", "");
|
||||
var md5 = MD5.Create();
|
||||
try
|
||||
{
|
||||
using (var stream = File.OpenRead(exePath))
|
||||
{
|
||||
exeHash = new Md5Hash(stream);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while calculating MD5 hash for the executable \"" + exePath + "\"", e);
|
||||
}
|
||||
|
||||
GameAnalytics.ConfigureBuild(GameMain.Version.ToString()
|
||||
+ (string.IsNullOrEmpty(exeName) ? "Unknown" : exeName) + ":"
|
||||
+ ((exeHash?.ShortHash == null) ? "Unknown" : exeHash.ShortHash));
|
||||
|
||||
GameAnalytics.AddDesignEvent("Executable:"
|
||||
+ (string.IsNullOrEmpty(exeName) ? "Unknown" : exeName) + ":"
|
||||
+ ((exeHash?.ShortHash == null) ? "Unknown" : exeHash.ShortHash));
|
||||
|
||||
GameAnalytics.ConfigureAvailableCustomDimensions01("singleplayer", "multiplayer", "editor");
|
||||
GameAnalytics.Initialize("a3a073c20982de7c15d21e840e149122", "9010ad9a671233b8d9610d76cec8c897d9ff3ba7");
|
||||
|
||||
|
||||
string contentPackageName = GameMain.Config?.SelectedContentPackage?.Name;
|
||||
if (!string.IsNullOrEmpty(contentPackageName))
|
||||
{
|
||||
@@ -21,5 +53,47 @@ namespace Barotrauma
|
||||
contentPackageName.Replace(":", "").Substring(0, Math.Min(32, contentPackageName.Length)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an error event to GameAnalytics if an event with the same identifier has not been added yet.
|
||||
/// </summary>
|
||||
public static void AddErrorEventOnce(string identifier, EGAErrorSeverity errorSeverity, string message)
|
||||
{
|
||||
if (!GameSettings.SendUserStatistics) return;
|
||||
if (sentEventIdentifiers.Contains(identifier)) return;
|
||||
|
||||
GameAnalytics.AddErrorEvent(errorSeverity, message);
|
||||
sentEventIdentifiers.Add(identifier);
|
||||
}
|
||||
|
||||
public static void AddDesignEvent(string eventID)
|
||||
{
|
||||
if (!GameSettings.SendUserStatistics) return;
|
||||
GameAnalytics.AddDesignEvent(eventID);
|
||||
}
|
||||
|
||||
public static void AddDesignEvent(string eventID, double value)
|
||||
{
|
||||
if (!GameSettings.SendUserStatistics) return;
|
||||
GameAnalytics.AddDesignEvent(eventID, value);
|
||||
}
|
||||
|
||||
public static void AddProgressionEvent(EGAProgressionStatus progressionStatus, string progression01)
|
||||
{
|
||||
if (!GameSettings.SendUserStatistics) return;
|
||||
GameAnalytics.AddProgressionEvent(progressionStatus, progression01);
|
||||
}
|
||||
|
||||
public static void AddProgressionEvent(EGAProgressionStatus progressionStatus, string progression01, string progression02)
|
||||
{
|
||||
if (!GameSettings.SendUserStatistics) return;
|
||||
GameAnalytics.AddProgressionEvent(progressionStatus, progression01, progression02);
|
||||
}
|
||||
|
||||
public static void SetCustomDimension01(string dimension)
|
||||
{
|
||||
if (!GameSettings.SendUserStatistics) return;
|
||||
GameAnalytics.SetCustomDimension01(dimension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace Barotrauma
|
||||
public void CreateItems()
|
||||
{
|
||||
CreateItems(purchasedItems);
|
||||
OnItemsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public static void CreateItems(List<ItemPrefab> itemsToSpawn)
|
||||
|
||||
@@ -234,13 +234,12 @@ namespace Barotrauma
|
||||
campaign.CargoManager.CreateItems();
|
||||
}
|
||||
}
|
||||
|
||||
if (GameSettings.SendUserStatistics)
|
||||
{
|
||||
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("Submarine:" + submarine.Name);
|
||||
GameAnalyticsSDK.Net.GameAnalytics.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start,
|
||||
|
||||
GameAnalyticsManager.AddDesignEvent("Submarine:" + submarine.Name);
|
||||
GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level.Seed));
|
||||
GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start,
|
||||
GameMode.Name, (Mission == null ? "None" : Mission.GetType().ToString()));
|
||||
}
|
||||
|
||||
|
||||
#if CLIENT
|
||||
roundSummary = new RoundSummary(this);
|
||||
@@ -253,11 +252,10 @@ namespace Barotrauma
|
||||
public void EndRound(string endMessage)
|
||||
{
|
||||
if (Mission != null) Mission.End();
|
||||
if (GameSettings.SendUserStatistics)
|
||||
{
|
||||
GameAnalyticsSDK.Net.GameAnalytics.AddProgressionEvent((Mission == null || Mission.Completed) ? GameAnalyticsSDK.Net.EGAProgressionStatus.Complete : GameAnalyticsSDK.Net.EGAProgressionStatus.Fail,
|
||||
GameMode.Name, (Mission == null ? "None" : Mission.GetType().ToString()));
|
||||
}
|
||||
GameAnalyticsManager.AddProgressionEvent(
|
||||
(Mission == null || Mission.Completed) ? GameAnalyticsSDK.Net.EGAProgressionStatus.Complete : GameAnalyticsSDK.Net.EGAProgressionStatus.Fail,
|
||||
GameMode.Name,
|
||||
(Mission == null ? "None" : Mission.GetType().ToString()));
|
||||
|
||||
#if CLIENT
|
||||
if (roundSummary != null)
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Barotrauma
|
||||
GameMain.Config.Save("config.xml");
|
||||
}
|
||||
}
|
||||
public static bool ShowUserStatisticsPrompt { get; private set; }
|
||||
public static bool ShowUserStatisticsPrompt { get; set; }
|
||||
|
||||
public GameSettings(string filePath)
|
||||
{
|
||||
@@ -334,8 +334,12 @@ namespace Barotrauma
|
||||
new XAttribute("soundvolume", soundVolume),
|
||||
new XAttribute("verboselogging", VerboseLogging),
|
||||
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
|
||||
new XAttribute("enablesplashscreen", EnableSplashScreen),
|
||||
new XAttribute("senduserstatistics", sendUserStatistics));
|
||||
new XAttribute("enablesplashscreen", EnableSplashScreen));
|
||||
|
||||
if (!ShowUserStatisticsPrompt)
|
||||
{
|
||||
doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics));
|
||||
}
|
||||
|
||||
if (WasGameUpdated)
|
||||
{
|
||||
@@ -398,7 +402,16 @@ namespace Barotrauma
|
||||
new XAttribute("gender", characterGender));
|
||||
doc.Root.Add(playerElement);
|
||||
|
||||
doc.Save(filePath);
|
||||
try
|
||||
{
|
||||
doc.Save(filePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Saving game settings failed.", e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameSettings.Save:SaveFailed", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Saving game settings failed.\n" + e.Message + "\n" + e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<object> ApplyUnsavedChanges()
|
||||
|
||||
@@ -345,17 +345,31 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void CreateDoorBody()
|
||||
{
|
||||
Vector2 position = ConvertUnits.ToSimUnits(item.Position + (dockingTarget.door.Item.WorldPosition - item.WorldPosition));
|
||||
if (!MathUtils.IsValid(position))
|
||||
{
|
||||
string errorMsg =
|
||||
"Attempted to create a door body at an invalid position (item pos: " + item.Position
|
||||
+ ", item world pos: " + item.WorldPosition
|
||||
+ ", docking target world pos: " + DockingTarget.door.Item.WorldPosition + ")\n" + Environment.StackTrace;
|
||||
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"DockingPort.CreateDoorBody:InvalidPosition",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
errorMsg);
|
||||
position = Vector2.Zero;
|
||||
}
|
||||
|
||||
doorBody = BodyFactory.CreateRectangle(GameMain.World,
|
||||
dockingTarget.door.Body.width,
|
||||
dockingTarget.door.Body.height,
|
||||
1.0f,
|
||||
position,
|
||||
dockingTarget.door);
|
||||
|
||||
doorBody.CollisionCategories = Physics.CollisionWall;
|
||||
doorBody.BodyType = BodyType.Static;
|
||||
doorBody.SetTransform(
|
||||
ConvertUnits.ToSimUnits(item.Position + (dockingTarget.door.Item.WorldPosition - item.WorldPosition)),
|
||||
0.0f);
|
||||
}
|
||||
|
||||
private void CreateHull()
|
||||
|
||||
@@ -349,6 +349,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void PushCharactersAway()
|
||||
{
|
||||
if (!MathUtils.IsValid(item.SimPosition))
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to push a character out of a doorway - position of the door is not valid (" + item.SimPosition + ")");
|
||||
GameAnalyticsManager.AddErrorEventOnce("PushCharactersAway:DoorPosInvalid", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to push a character out of a doorway - position of the door is not valid (" + item.SimPosition + ").");
|
||||
return;
|
||||
}
|
||||
|
||||
//push characters out of the doorway when the door is closing/opening
|
||||
Vector2 simPos = ConvertUnits.ToSimUnits(new Vector2(item.Rect.X, item.Rect.Y));
|
||||
|
||||
@@ -360,6 +368,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (!c.Enabled) continue;
|
||||
if (!MathUtils.IsValid(c.SimPosition))
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to push a character out of a doorway - position of the character \"" + c.Name + "\" is not valid (" + c.SimPosition + ")");
|
||||
GameAnalyticsManager.AddErrorEventOnce("PushCharactersAway:CharacterPosInvalid", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to push a character out of a doorway - position of the character \"" + c.Name + "\" is not valid (" + c.SimPosition + ")." +
|
||||
" Removed: " + c.Removed +
|
||||
" Remoteplayer: " + c.IsRemotePlayer);
|
||||
continue;
|
||||
}
|
||||
int dir = isHorizontal ? Math.Sign(c.SimPosition.Y - item.SimPosition.Y) : Math.Sign(c.SimPosition.X - item.SimPosition.X);
|
||||
|
||||
List<PhysicsBody> bodies = c.AnimController.Limbs.Select(l => l.body).ToList();
|
||||
@@ -368,17 +386,24 @@ namespace Barotrauma.Items.Components
|
||||
foreach (PhysicsBody body in bodies)
|
||||
{
|
||||
float diff = 0.0f;
|
||||
if (!MathUtils.IsValid(body.SimPosition))
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to push a limb out of a doorway - position of the body (character \"" + c.Name + "\") is not valid (" + body.SimPosition + ")");
|
||||
GameAnalyticsManager.AddErrorEventOnce("PushCharactersAway:LimbPosInvalid", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to push a character out of a doorway - position of the character \"" + c.Name + "\" is not valid (" + body.SimPosition + ")." +
|
||||
" Removed: " + c.Removed +
|
||||
" Remoteplayer: " + c.IsRemotePlayer);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isHorizontal)
|
||||
{
|
||||
if (body.SimPosition.X < simPos.X || body.SimPosition.X > simPos.X + simSize.X) continue;
|
||||
|
||||
diff = body.SimPosition.Y - item.SimPosition.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (body.SimPosition.Y > simPos.Y || body.SimPosition.Y < simPos.Y - simSize.Y) continue;
|
||||
|
||||
diff = body.SimPosition.X - item.SimPosition.X;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,7 @@ namespace Barotrauma.Items.Components
|
||||
get { return powerConsumption; }
|
||||
set { powerConsumption = value; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Serialize(false, true)]
|
||||
public override bool IsActive
|
||||
{
|
||||
@@ -60,6 +59,13 @@ namespace Barotrauma.Items.Components
|
||||
set { voltage = Math.Max(0.0f, value); }
|
||||
}
|
||||
|
||||
[Editable(ToolTip = "Can the item be damaged by electomagnetic pulses."), Serialize(true, true)]
|
||||
public bool VulnerableToEMP
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Powered(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
|
||||
@@ -783,12 +783,6 @@ namespace Barotrauma
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (Level.Loaded != null && WorldPosition.Y < Level.MaxEntityDepth)
|
||||
{
|
||||
Spawner.AddToRemoveQueue(this);
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyStatusEffects(ActionType.Always, deltaTime, null);
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
@@ -851,6 +845,12 @@ namespace Barotrauma
|
||||
MathHelper.Clamp(body.LinearVelocity.X, -MaxVel, MaxVel),
|
||||
MathHelper.Clamp(body.LinearVelocity.Y, -MaxVel, MaxVel));
|
||||
}
|
||||
|
||||
if (CurrentHull == null && body.SimPosition.Y < ConvertUnits.ToSimUnits(Level.MaxEntityDepth))
|
||||
{
|
||||
Spawner.AddToRemoveQueue(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateNetPosition();
|
||||
@@ -1430,6 +1430,10 @@ namespace Barotrauma
|
||||
msg.Write(((Rectangle)value).Width);
|
||||
msg.Write(((Rectangle)value).Height);
|
||||
}
|
||||
else if (value is Enum)
|
||||
{
|
||||
msg.Write((int)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException("Serializing item properties of the type \"" + value.GetType() + "\" not supported");
|
||||
@@ -1487,6 +1491,24 @@ namespace Barotrauma
|
||||
{
|
||||
property.TrySetValue(new Vector4(msg.ReadInt32(), msg.ReadInt32(), msg.ReadInt32(), msg.ReadInt32()));
|
||||
}
|
||||
else if (typeof(Enum).IsAssignableFrom(type))
|
||||
{
|
||||
int intVal = msg.ReadInt32();
|
||||
try
|
||||
{
|
||||
property.TrySetValue(Enum.ToObject(type, intVal));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Failed to convert the int value \"" + intVal + "\" to " + type, e);
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"Item.ReadPropertyChange:" + Name + ":" + type,
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
|
||||
"Failed to convert the int value \"" + intVal + "\" to " + type + " (item " + Name + ")");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -78,15 +78,13 @@ namespace Barotrauma
|
||||
{
|
||||
float distSqr = Vector2.DistanceSquared(item.WorldPosition, worldPosition);
|
||||
if (distSqr > displayRangeSqr) continue;
|
||||
|
||||
//ignore reactors (don't want to blow them up)
|
||||
if (item.GetComponent<Reactor>() != null) continue;
|
||||
|
||||
|
||||
float distFactor = 1.0f - (float)Math.Sqrt(distSqr) / displayRange;
|
||||
|
||||
//damage repairable power-consuming items
|
||||
var powerTransfer = item.GetComponent<Powered>();
|
||||
if (powerTransfer != null && item.FixRequirements.Count > 0)
|
||||
var powered = item.GetComponent<Powered>();
|
||||
if (powered == null || !powered.VulnerableToEMP) continue;
|
||||
if (item.FixRequirements.Count > 0)
|
||||
{
|
||||
item.Condition -= 100 * empStrength * distFactor;
|
||||
}
|
||||
|
||||
@@ -323,18 +323,9 @@ namespace Barotrauma
|
||||
//choose random edge (ignoring ones where the adjacent cell is outside limits)
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
//if (allowedEdges.Count==0)
|
||||
//{
|
||||
// edgeIndex = Rand.Int(currentCell.edges.Count, false);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
edgeIndex = Rand.Int(allowedEdges.Count, Rand.RandSync.Server);
|
||||
if (mirror && edgeIndex > 0) edgeIndex = allowedEdges.Count - edgeIndex;
|
||||
edgeIndex = currentCell.edges.IndexOf(allowedEdges[edgeIndex]);
|
||||
//}
|
||||
}
|
||||
|
||||
currentCell = currentCell.edges[edgeIndex].AdjacentCell(currentCell);
|
||||
@@ -357,8 +348,8 @@ namespace Barotrauma
|
||||
|
||||
return pathCells;
|
||||
}
|
||||
|
||||
public static List<Body> GeneratePolygons(List<VoronoiCell> cells, out List<Vector2[]> renderTriangles, bool setSolid=true)
|
||||
|
||||
public static List<Body> GeneratePolygons(List<VoronoiCell> cells, Level level, out List<Vector2[]> renderTriangles, bool setSolid = true)
|
||||
{
|
||||
renderTriangles = new List<Vector2[]>();
|
||||
var bodies = new List<Body>();
|
||||
@@ -366,6 +357,14 @@ namespace Barotrauma
|
||||
List<Vector2> tempVertices = new List<Vector2>();
|
||||
List<Vector2> bodyPoints = new List<Vector2>();
|
||||
|
||||
Body cellBody = new Body(GameMain.World)
|
||||
{
|
||||
SleepingAllowed = false,
|
||||
BodyType = BodyType.Static,
|
||||
CollisionCategories = Physics.CollisionLevel
|
||||
};
|
||||
bodies.Add(cellBody);
|
||||
|
||||
for (int n = cells.Count - 1; n >= 0; n-- )
|
||||
{
|
||||
VoronoiCell cell = cells[n];
|
||||
@@ -412,14 +411,12 @@ namespace Barotrauma
|
||||
cell.bodyVertices.Add(bodyPoints[i]);
|
||||
bodyPoints[i] = ConvertUnits.ToSimUnits(bodyPoints[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (cell.CellType == CellType.Empty) continue;
|
||||
|
||||
cellBody.UserData = cell;
|
||||
var triangles = MathUtils.TriangulateConvexHull(bodyPoints, ConvertUnits.ToSimUnits(cell.Center));
|
||||
|
||||
Body cellBody = new Body(GameMain.World);
|
||||
|
||||
|
||||
for (int i = 0; i < triangles.Count; i++)
|
||||
{
|
||||
//don't create a triangle if any of the vertices are too close to each other
|
||||
@@ -429,16 +426,20 @@ namespace Barotrauma
|
||||
Vector2.Distance(triangles[i][1], triangles[i][2]) < 0.05f) continue;
|
||||
|
||||
Vertices bodyVertices = new Vertices(triangles[i]);
|
||||
FixtureFactory.AttachPolygon(bodyVertices, 5.0f, cellBody);
|
||||
var newFixture = FixtureFactory.AttachPolygon(bodyVertices, 5.0f, cellBody);
|
||||
newFixture.UserData = cell;
|
||||
|
||||
if (newFixture.Shape.MassData.Area < FarseerPhysics.Settings.Epsilon)
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid triangle created by CaveGenerator (" + triangles[i][0] + ", " + triangles[i][1] + ", " + triangles[i][2] + ")");
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"CaveGenerator.GeneratePolygons:InvalidTriangle",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
|
||||
"Invalid triangle created by CaveGenerator (" + triangles[i][0] + ", " + triangles[i][1] + ", " + triangles[i][2] + "). Seed: " + level.Seed);
|
||||
}
|
||||
}
|
||||
|
||||
cellBody.UserData = cell;
|
||||
cellBody.SleepingAllowed = false;
|
||||
cellBody.BodyType = BodyType.Kinematic;
|
||||
cellBody.CollisionCategories = Physics.CollisionLevel;
|
||||
|
||||
cell.body = cellBody;
|
||||
bodies.Add(cellBody);
|
||||
}
|
||||
|
||||
return bodies;
|
||||
|
||||
@@ -449,11 +449,11 @@ namespace Barotrauma
|
||||
List<VoronoiCell> cellsWithBody = new List<VoronoiCell>(cells);
|
||||
|
||||
List<Vector2[]> triangles;
|
||||
bodies = CaveGenerator.GeneratePolygons(cellsWithBody, out triangles);
|
||||
bodies = CaveGenerator.GeneratePolygons(cellsWithBody, this, out triangles);
|
||||
|
||||
#if CLIENT
|
||||
renderer.SetBodyVertices(CaveGenerator.GenerateRenderVerticeList(triangles).ToArray(), generationParams.WallColor);
|
||||
renderer.SetWallVertices(CaveGenerator.GenerateWallShapes(cells), generationParams.WallColor);
|
||||
renderer.SetWallVertices(CaveGenerator.GenerateWallShapes(cells, this), generationParams.WallColor);
|
||||
#endif
|
||||
|
||||
TopBarrier = BodyFactory.CreateEdge(GameMain.World,
|
||||
@@ -700,7 +700,7 @@ namespace Barotrauma
|
||||
|
||||
SeaFloorTopPos = bottomPositions.Max(p => p.Y);
|
||||
|
||||
extraWalls = new LevelWall[] { new LevelWall(bottomPositions, new Vector2(0.0f, -2000.0f), backgroundColor) };
|
||||
extraWalls = new LevelWall[] { new LevelWall(bottomPositions, new Vector2(0.0f, -2000.0f), backgroundColor, this) };
|
||||
|
||||
BottomBarrier = BodyFactory.CreateEdge(GameMain.World,
|
||||
ConvertUnits.ToSimUnits(new Vector2(borders.X, 0)),
|
||||
|
||||
@@ -18,10 +18,9 @@ namespace Barotrauma
|
||||
|
||||
private List<Body> bodies;
|
||||
|
||||
public LevelWall(List<Vector2> edgePositions, Vector2 extendAmount, Color color)
|
||||
public LevelWall(List<Vector2> edgePositions, Vector2 extendAmount, Color color, Level level)
|
||||
{
|
||||
cells = new List<VoronoiCell>();
|
||||
|
||||
for (int i = 0; i < edgePositions.Count - 1; i++)
|
||||
{
|
||||
Vector2[] vertices = new Vector2[4];
|
||||
@@ -47,14 +46,13 @@ namespace Barotrauma
|
||||
cells.Add(wallCell);
|
||||
}
|
||||
|
||||
List<Vector2[]> triangles;
|
||||
bodies = CaveGenerator.GeneratePolygons(cells, out triangles, false);
|
||||
bodies = CaveGenerator.GeneratePolygons(cells, level, out List<Vector2[]> triangles, false);
|
||||
|
||||
#if CLIENT
|
||||
List<VertexPositionTexture> bodyVertices = CaveGenerator.GenerateRenderVerticeList(triangles);
|
||||
|
||||
SetBodyVertices(bodyVertices.ToArray(), color);
|
||||
SetWallVertices(CaveGenerator.GenerateWallShapes(cells), color);
|
||||
SetWallVertices(CaveGenerator.GenerateWallShapes(cells, level), color);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -423,6 +423,7 @@ namespace Barotrauma.RuinGeneration
|
||||
Alignment[] alignments = new Alignment[] { Alignment.Top, Alignment.Bottom, Alignment.Right, Alignment.Left, Alignment.Center };
|
||||
|
||||
var prop = RuinStructure.GetRandom(RuinStructureType.Prop, alignments[Rand.Int(alignments.Length, Rand.RandSync.Server)]);
|
||||
if (prop == null) continue;
|
||||
|
||||
Vector2 size = (prop.Prefab is StructurePrefab) ? ((StructurePrefab)prop.Prefab).Size : Vector2.Zero;
|
||||
|
||||
|
||||
@@ -51,8 +51,12 @@ namespace Barotrauma
|
||||
|
||||
public static bool LockX, LockY;
|
||||
|
||||
public static List<Submarine> SavedSubmarines = new List<Submarine>();
|
||||
|
||||
private static List<Submarine> savedSubmarines = new List<Submarine>();
|
||||
public static IEnumerable<Submarine> SavedSubmarines
|
||||
{
|
||||
get { return savedSubmarines; }
|
||||
}
|
||||
|
||||
public static readonly Vector2 GridSize = new Vector2(16.0f, 16.0f);
|
||||
|
||||
public static Submarine[] MainSubs = new Submarine[2];
|
||||
@@ -214,10 +218,10 @@ namespace Barotrauma
|
||||
return ConvertUnits.ToSimUnits(Position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Vector2 Velocity
|
||||
{
|
||||
get { return subBody==null ? Vector2.Zero : subBody.Velocity; }
|
||||
get { return subBody == null ? Vector2.Zero : subBody.Velocity; }
|
||||
set
|
||||
{
|
||||
if (subBody == null) return;
|
||||
@@ -244,7 +248,7 @@ namespace Barotrauma
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Barotrauma.Submarine ("+name+")";
|
||||
return "Barotrauma.Submarine (" + name + ")";
|
||||
}
|
||||
|
||||
public override bool Removed
|
||||
@@ -296,9 +300,19 @@ namespace Barotrauma
|
||||
string previewImageData = doc.Root.GetAttributeString("previewimage", "");
|
||||
if (!string.IsNullOrEmpty(previewImageData))
|
||||
{
|
||||
using (MemoryStream mem = new MemoryStream(Convert.FromBase64String(previewImageData)))
|
||||
try
|
||||
{
|
||||
PreviewImage = new Sprite(TextureLoader.FromStream(mem), null, null);
|
||||
using (MemoryStream mem = new MemoryStream(Convert.FromBase64String(previewImageData)))
|
||||
{
|
||||
PreviewImage = new Sprite(TextureLoader.FromStream(mem), null, null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading the preview image of the submarine \"" + Name + "\" failed. The file may be corrupted.", e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Submarine..ctor:PreviewImageLoadingFailed", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Loading the preview image of the submarine \"" + Name + "\" failed. The file may be corrupted.");
|
||||
PreviewImage = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -344,7 +358,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (dockedSub == this) continue;
|
||||
|
||||
Vector2 diff = dockedSub.Submarine == this ? dockedSub.WorldPosition : dockedSub.WorldPosition - WorldPosition;
|
||||
Vector2 diff = dockedSub.Submarine == this ? dockedSub.WorldPosition : dockedSub.WorldPosition - WorldPosition;
|
||||
|
||||
Rectangle dockedSubBorders = dockedSub.Borders;
|
||||
dockedSubBorders.Y -= dockedSubBorders.Height;
|
||||
@@ -383,15 +397,15 @@ namespace Barotrauma
|
||||
public Vector2 FindSpawnPos(Vector2 spawnPos)
|
||||
{
|
||||
Rectangle dockedBorders = GetDockedBorders();
|
||||
|
||||
|
||||
int iterations = 0;
|
||||
bool wallTooClose = false;
|
||||
do
|
||||
{
|
||||
Rectangle worldBorders = new Rectangle(
|
||||
dockedBorders.X + (int)spawnPos.X,
|
||||
dockedBorders.Y + (int)spawnPos.Y,
|
||||
dockedBorders.Width,
|
||||
dockedBorders.Y + (int)spawnPos.Y,
|
||||
dockedBorders.Width,
|
||||
dockedBorders.Height);
|
||||
|
||||
wallTooClose = false;
|
||||
@@ -507,8 +521,8 @@ namespace Barotrauma
|
||||
|
||||
public Rectangle CalculateDimensions(bool onlyHulls = true)
|
||||
{
|
||||
List<MapEntity> entities = onlyHulls ?
|
||||
Hull.hullList.FindAll(h => h.Submarine == this).Cast<MapEntity>().ToList() :
|
||||
List<MapEntity> entities = onlyHulls ?
|
||||
Hull.hullList.FindAll(h => h.Submarine == this).Cast<MapEntity>().ToList() :
|
||||
MapEntity.mapEntityList.FindAll(me => me.Submarine == this);
|
||||
|
||||
if (entities.Count == 0) return Rectangle.Empty;
|
||||
@@ -557,7 +571,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RectsOverlap(Rectangle rect1, Rectangle rect2, bool inclusive=true)
|
||||
public static bool RectsOverlap(Rectangle rect1, Rectangle rect2, bool inclusive = true)
|
||||
{
|
||||
if (inclusive)
|
||||
{
|
||||
@@ -584,25 +598,25 @@ namespace Barotrauma
|
||||
{
|
||||
if (fixture == null ||
|
||||
(ignoreSensors && fixture.IsSensor) ||
|
||||
fixture.CollisionCategories == Category.None ||
|
||||
fixture.CollisionCategories == Category.None ||
|
||||
fixture.CollisionCategories == Physics.CollisionItem) return -1;
|
||||
|
||||
if (collisionCategory != null &&
|
||||
|
||||
if (collisionCategory != null &&
|
||||
!fixture.CollisionCategories.HasFlag((Category)collisionCategory) &&
|
||||
!((Category)collisionCategory).HasFlag(fixture.CollisionCategories)) return -1;
|
||||
|
||||
|
||||
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body)) return -1;
|
||||
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
|
||||
Structure structure = fixture.Body.UserData as Structure;
|
||||
if (structure != null)
|
||||
{
|
||||
if (structure.IsPlatform && collisionCategory != null && !((Category)collisionCategory).HasFlag(Physics.CollisionPlatform)) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
closestFraction = fraction;
|
||||
if (fixture.Body!=null) closestBody = fixture.Body;
|
||||
if (fixture.Body != null) closestBody = fixture.Body;
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
@@ -669,7 +683,7 @@ namespace Barotrauma
|
||||
get { return flippedX; }
|
||||
}
|
||||
|
||||
public void FlipX(List<Submarine> parents=null)
|
||||
public void FlipX(List<Submarine> parents = null)
|
||||
{
|
||||
if (parents == null) parents = new List<Submarine>();
|
||||
parents.Add(this);
|
||||
@@ -729,7 +743,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (bodyItems.Contains(item))
|
||||
{
|
||||
item.Submarine = this;
|
||||
item.Submarine = this;
|
||||
if (Position == Vector2.Zero) item.Move(-HiddenSubPosition);
|
||||
}
|
||||
else if (item.Submarine != this)
|
||||
@@ -751,7 +765,7 @@ namespace Barotrauma
|
||||
if (Level.Loaded == null || subBody == null) return;
|
||||
|
||||
if (WorldPosition.Y < Level.MaxEntityDepth &&
|
||||
subBody.Body.Enabled &&
|
||||
subBody.Body.Enabled &&
|
||||
(GameMain.NetworkMember?.RespawnManager == null || this != GameMain.NetworkMember.RespawnManager.RespawnShuttle))
|
||||
{
|
||||
subBody.Body.ResetDynamics();
|
||||
@@ -778,26 +792,26 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
subBody.Body.LinearVelocity = new Vector2(
|
||||
LockX ? 0.0f : subBody.Body.LinearVelocity.X,
|
||||
LockX ? 0.0f : subBody.Body.LinearVelocity.X,
|
||||
LockY ? 0.0f : subBody.Body.LinearVelocity.Y);
|
||||
|
||||
|
||||
|
||||
|
||||
subBody.Update(deltaTime);
|
||||
|
||||
for (int i = 0; i < 2; i++ )
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (MainSubs[i] == null) continue;
|
||||
if (this != MainSubs[i] && MainSubs[i].DockedTo.Contains(this)) return;
|
||||
}
|
||||
|
||||
//send updates more frequently if moving fast
|
||||
networkUpdateTimer -= MathHelper.Clamp(Velocity.Length()*10.0f, 0.1f, 5.0f) * deltaTime;
|
||||
networkUpdateTimer -= MathHelper.Clamp(Velocity.Length() * 10.0f, 0.1f, 5.0f) * deltaTime;
|
||||
|
||||
if (networkUpdateTimer < 0.0f)
|
||||
{
|
||||
networkUpdateTimer = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void ApplyForce(Vector2 force)
|
||||
@@ -867,7 +881,7 @@ namespace Barotrauma
|
||||
|
||||
subBorders.Inflate(500.0f, 500.0f);
|
||||
|
||||
if (subBorders.Contains(position)) return sub;
|
||||
if (subBorders.Contains(position)) return sub;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -875,9 +889,18 @@ namespace Barotrauma
|
||||
|
||||
//saving/loading ----------------------------------------------------
|
||||
|
||||
public static void AddToSavedSubs(Submarine sub)
|
||||
{
|
||||
savedSubmarines.Add(sub);
|
||||
}
|
||||
|
||||
public static void RefreshSavedSubs()
|
||||
{
|
||||
SavedSubmarines.Clear();
|
||||
for (int i = savedSubmarines.Count - 1; i>= 0; i--)
|
||||
{
|
||||
savedSubmarines[i].Dispose();
|
||||
}
|
||||
System.Diagnostics.Debug.Assert(savedSubmarines.Count == 0);
|
||||
|
||||
if (!Directory.Exists(SavePath))
|
||||
{
|
||||
@@ -921,7 +944,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (string path in filePaths)
|
||||
{
|
||||
SavedSubmarines.Add(new Submarine(path));
|
||||
savedSubmarines.Add(new Submarine(path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -971,7 +994,7 @@ namespace Barotrauma
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading submarine \"" + file + "\" failed! ("+e.Message+")");
|
||||
DebugConsole.ThrowError("Loading submarine \"" + file + "\" failed! (" + e.Message + ")");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1147,12 +1170,12 @@ namespace Barotrauma
|
||||
Submarine sub = new Submarine(element.GetAttributeString("name", ""), "", false);
|
||||
sub.Load(unloadPrevious, element);
|
||||
|
||||
return sub;
|
||||
return sub;
|
||||
}
|
||||
|
||||
public static Submarine Load(string fileName, bool unloadPrevious)
|
||||
{
|
||||
return Load(fileName, SavePath, unloadPrevious);
|
||||
return Load(fileName, SavePath, unloadPrevious);
|
||||
}
|
||||
|
||||
public static Submarine Load(string fileName, string folder, bool unloadPrevious)
|
||||
@@ -1285,6 +1308,15 @@ namespace Barotrauma
|
||||
DockedTo.Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
savedSubmarines.Remove(this);
|
||||
#if CLIENT
|
||||
PreviewImage?.Remove();
|
||||
PreviewImage = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
msg.Write(ID);
|
||||
|
||||
@@ -370,27 +370,22 @@ namespace Barotrauma
|
||||
|
||||
public bool OnCollision(Fixture f1, Fixture f2, Contact contact)
|
||||
{
|
||||
Limb limb = f2.Body.UserData as Limb;
|
||||
if (limb != null)
|
||||
if (f2.Body.UserData is Limb limb)
|
||||
{
|
||||
bool collision = CheckLimbCollision(contact, limb);
|
||||
if (collision) HandleLimbCollision(contact, limb);
|
||||
return collision;
|
||||
}
|
||||
|
||||
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
|
||||
if (cell != null)
|
||||
if (f2.UserData is VoronoiCell cell)
|
||||
{
|
||||
HandleLevelCollision(contact, Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center));
|
||||
return true;
|
||||
}
|
||||
|
||||
Structure structure = f2.Body.UserData as Structure;
|
||||
if (structure != null)
|
||||
if (f2.Body.UserData is Structure structure)
|
||||
{
|
||||
Vector2 normal;
|
||||
FixedArray2<Vector2> points;
|
||||
contact.GetWorldManifold(out normal, out points);
|
||||
contact.GetWorldManifold(out Vector2 normal, out FixedArray2<Vector2> points);
|
||||
if (contact.FixtureA.Body == f1.Body)
|
||||
{
|
||||
normal = -normal;
|
||||
@@ -400,8 +395,7 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
Submarine otherSub = f2.Body.UserData as Submarine;
|
||||
if (otherSub != null)
|
||||
if (f2.Body.UserData is Submarine otherSub)
|
||||
{
|
||||
HandleSubCollision(contact, otherSub);
|
||||
return true;
|
||||
@@ -486,8 +480,8 @@ namespace Barotrauma
|
||||
levelContact.GetWorldManifold(out contactNormal, out temp);
|
||||
|
||||
//if the contact normal is pointing from the limb towards the level cell it's touching, flip the normal
|
||||
VoronoiCell cell = levelContact.FixtureB.Body.UserData is VoronoiCell ?
|
||||
((VoronoiCell)levelContact.FixtureB.Body.UserData) : ((VoronoiCell)levelContact.FixtureA.Body.UserData);
|
||||
VoronoiCell cell = levelContact.FixtureB.UserData is VoronoiCell ?
|
||||
((VoronoiCell)levelContact.FixtureB.UserData) : ((VoronoiCell)levelContact.FixtureA.UserData);
|
||||
|
||||
var cellDiff = ConvertUnits.ToDisplayUnits(limb.body.SimPosition) - cell.Center;
|
||||
if (Vector2.Dot(contactNormal, cellDiff) < 0)
|
||||
@@ -603,8 +597,8 @@ namespace Barotrauma
|
||||
levelContact.GetWorldManifold(out contactNormal, out temp);
|
||||
|
||||
//if the contact normal is pointing from the sub towards the level cell we collided with, flip the normal
|
||||
VoronoiCell cell = levelContact.FixtureB.Body.UserData is VoronoiCell ?
|
||||
((VoronoiCell)levelContact.FixtureB.Body.UserData) : ((VoronoiCell)levelContact.FixtureA.Body.UserData);
|
||||
VoronoiCell cell = levelContact.FixtureB.UserData is VoronoiCell ?
|
||||
((VoronoiCell)levelContact.FixtureB.UserData) : ((VoronoiCell)levelContact.FixtureA.UserData);
|
||||
|
||||
var cellDiff = ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center;
|
||||
if (Vector2.Dot(contactNormal, cellDiff) < 0)
|
||||
|
||||
@@ -271,7 +271,7 @@ namespace Barotrauma.Networking
|
||||
case (byte)FileTransferType.Submarine:
|
||||
string fileName = inc.ReadString();
|
||||
string fileHash = inc.ReadString();
|
||||
var requestedSubmarine = Submarine.SavedSubmarines.Find(s => s.Name == fileName && s.MD5Hash.Hash == fileHash);
|
||||
var requestedSubmarine = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name == fileName && s.MD5Hash.Hash == fileHash);
|
||||
|
||||
if (requestedSubmarine != null)
|
||||
{
|
||||
|
||||
@@ -209,7 +209,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.RandomizeSettings();
|
||||
started = true;
|
||||
|
||||
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("GameServer:Start");
|
||||
GameAnalyticsManager.AddDesignEvent("GameServer:Start");
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
@@ -1370,7 +1370,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (GameSettings.SendUserStatistics) GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("Traitors:" + (TraitorManager == null ? "Disabled" : "Enabled"));
|
||||
GameAnalyticsManager.AddDesignEvent("Traitors:" + (TraitorManager == null ? "Disabled" : "Enabled"));
|
||||
|
||||
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients);
|
||||
|
||||
@@ -1583,24 +1583,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
BanClient(client, reason, range, duration);
|
||||
}
|
||||
|
||||
public void BanClient(NetConnection conn, string reason, bool range = false, TimeSpan? duration = null)
|
||||
{
|
||||
Client client = connectedClients.Find(c => c.Connection == conn);
|
||||
if (client == null)
|
||||
{
|
||||
conn.Disconnect("You have been banned from the server");
|
||||
if (!banList.IsBanned(conn.RemoteEndPoint.Address.ToString()))
|
||||
{
|
||||
banList.BanPlayer("Unnamed", conn.RemoteEndPoint.Address.ToString(), reason, duration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BanClient(client, reason, range);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void BanClient(Client client, string reason, bool range = false, TimeSpan? duration = null)
|
||||
{
|
||||
if (client == null) return;
|
||||
@@ -2266,11 +2249,8 @@ namespace Barotrauma.Networking
|
||||
Log("Shutting down the server...", ServerLog.MessageType.ServerMessage);
|
||||
log.Save();
|
||||
}
|
||||
|
||||
if (GameSettings.SendUserStatistics)
|
||||
{
|
||||
GameAnalyticsSDK.Net.GameAnalytics.AddDesignEvent("GameServer:ShutDown");
|
||||
}
|
||||
|
||||
GameAnalyticsManager.AddDesignEvent("GameServer:ShutDown");
|
||||
server.Shutdown("The server has been shut down");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,9 @@ namespace Barotrauma.Networking
|
||||
catch (Exception exception)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to write an event for the entity \"" + e.Entity + "\"", exception);
|
||||
GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:WriteFailed" + e.Entity.ToString(),
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to write an event for the entity \"" + e.Entity + "\"\n" + exception.StackTrace);
|
||||
|
||||
//write an empty event to avoid messing up IDs
|
||||
//(otherwise the clients might read the next event in the message and think its ID
|
||||
@@ -49,6 +52,9 @@ namespace Barotrauma.Networking
|
||||
if (tempEventBuffer.LengthBytes > 255)
|
||||
{
|
||||
DebugConsole.ThrowError("Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes");
|
||||
GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:TooLong" + e.Entity.ToString(),
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes");
|
||||
}
|
||||
|
||||
//the ID has been taken by another entity (the original entity has been removed) -> write an empty event
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Barotrauma
|
||||
{
|
||||
case VoteType.Sub:
|
||||
string subName = inc.ReadString();
|
||||
Submarine sub = Submarine.SavedSubmarines.Find(s => s.Name == subName);
|
||||
Submarine sub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name == subName);
|
||||
sender.SetVote(voteType, sub);
|
||||
#if CLIENT
|
||||
UpdateVoteTexts(GameMain.Server.ConnectedClients, voteType);
|
||||
|
||||
@@ -360,6 +360,44 @@ namespace Barotrauma
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
private bool IsValidValue(float value, string valueName)
|
||||
{
|
||||
if (!MathUtils.IsValid(value))
|
||||
{
|
||||
string errorMsg =
|
||||
"Attempted to apply invalid " + valueName +
|
||||
" to a physics body (userdata: " + UserData == null ? "null" : UserData.ToString() +
|
||||
"), value: " + value + "\n" + Environment.StackTrace;
|
||||
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"PhysicsBody.SetPosition:InvalidPosition",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
errorMsg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsValidValue(Vector2 value, string valueName)
|
||||
{
|
||||
if (!MathUtils.IsValid(value))
|
||||
{
|
||||
string errorMsg =
|
||||
"Attempted to apply invalid " + valueName +
|
||||
" to a physics body (userdata: " + UserData == null ? "null" : UserData.ToString() +
|
||||
"), value: " + value + "\n" + Environment.StackTrace;
|
||||
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"PhysicsBody.SetPosition:InvalidPosition",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
errorMsg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ResetDynamics()
|
||||
{
|
||||
body.ResetDynamics();
|
||||
@@ -367,6 +405,7 @@ namespace Barotrauma
|
||||
|
||||
public void ApplyLinearImpulse(Vector2 impulse)
|
||||
{
|
||||
if (!IsValidValue(impulse, "impulse")) return;
|
||||
body.ApplyLinearImpulse(impulse);
|
||||
}
|
||||
|
||||
@@ -375,6 +414,9 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public void ApplyLinearImpulse(Vector2 impulse, float maxVelocity)
|
||||
{
|
||||
if (!IsValidValue(impulse, "impulse")) return;
|
||||
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
||||
|
||||
float currSpeed = body.LinearVelocity.Length();
|
||||
Vector2 velocityAddition = impulse / Mass;
|
||||
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
||||
@@ -385,21 +427,26 @@ namespace Barotrauma
|
||||
|
||||
public void ApplyLinearImpulse(Vector2 impulse, Vector2 point)
|
||||
{
|
||||
if (!IsValidValue(impulse, "impulse")) return;
|
||||
body.ApplyLinearImpulse(impulse, point);
|
||||
}
|
||||
|
||||
public void ApplyForce(Vector2 force)
|
||||
{
|
||||
if (!IsValidValue(force, "force")) return;
|
||||
body.ApplyForce(force);
|
||||
}
|
||||
|
||||
public void ApplyForce(Vector2 force, Vector2 point)
|
||||
{
|
||||
if (!IsValidValue(force, "force")) return;
|
||||
if (!IsValidValue(point, "point")) return;
|
||||
body.ApplyForce(force, point);
|
||||
}
|
||||
|
||||
public void ApplyTorque(float torque)
|
||||
{
|
||||
if (!IsValidValue(torque, "torque")) return;
|
||||
body.ApplyTorque(torque);
|
||||
}
|
||||
|
||||
@@ -408,7 +455,10 @@ namespace Barotrauma
|
||||
System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition));
|
||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f);
|
||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f);
|
||||
|
||||
|
||||
if (!IsValidValue(simPosition, "position")) return;
|
||||
if (!IsValidValue(rotation, "rotation")) return;
|
||||
|
||||
body.SetTransform(simPosition, rotation);
|
||||
SetPrevTransform(simPosition, rotation);
|
||||
}
|
||||
@@ -418,14 +468,20 @@ namespace Barotrauma
|
||||
System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition));
|
||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f);
|
||||
System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f);
|
||||
|
||||
|
||||
if (!IsValidValue(simPosition, "position")) return;
|
||||
if (!IsValidValue(rotation, "rotation")) return;
|
||||
|
||||
body.SetTransformIgnoreContacts(ref simPosition, rotation);
|
||||
SetPrevTransform(simPosition, rotation);
|
||||
}
|
||||
|
||||
public void SetPrevTransform(Vector2 position, float rotation)
|
||||
public void SetPrevTransform(Vector2 simPosition, float rotation)
|
||||
{
|
||||
prevPosition = position;
|
||||
if (!IsValidValue(simPosition, "position")) return;
|
||||
if (!IsValidValue(rotation, "rotation")) return;
|
||||
|
||||
prevPosition = simPosition;
|
||||
prevRotation = rotation;
|
||||
}
|
||||
|
||||
@@ -440,16 +496,19 @@ namespace Barotrauma
|
||||
prevPosition = (Vector2)targetPosition;
|
||||
}
|
||||
|
||||
body.SetTransform((Vector2)targetPosition, targetRotation == null ? body.Rotation : (float)targetRotation);
|
||||
SetTransform((Vector2)targetPosition, targetRotation == null ? body.Rotation : (float)targetRotation);
|
||||
targetPosition = null;
|
||||
}
|
||||
|
||||
public void MoveToPos(Vector2 pos, float force, Vector2? pullPos = null)
|
||||
public void MoveToPos(Vector2 simPosition, float force, Vector2? pullPos = null)
|
||||
{
|
||||
if (pullPos == null) pullPos = body.Position;
|
||||
|
||||
if (!IsValidValue(simPosition, "position")) return;
|
||||
if (!IsValidValue(force, "force")) return;
|
||||
|
||||
Vector2 vel = body.LinearVelocity;
|
||||
Vector2 deltaPos = pos - (Vector2)pullPos;
|
||||
Vector2 deltaPos = simPosition - (Vector2)pullPos;
|
||||
deltaPos *= force;
|
||||
body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, (Vector2)pullPos);
|
||||
}
|
||||
@@ -474,8 +533,8 @@ namespace Barotrauma
|
||||
dragForce = Math.Min(drag, Mass * 500.0f) * -velDir;
|
||||
}
|
||||
|
||||
body.ApplyForce(dragForce + buoyancy);
|
||||
body.ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
|
||||
ApplyForce(dragForce + buoyancy);
|
||||
ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
|
||||
}
|
||||
|
||||
|
||||
@@ -559,18 +618,17 @@ namespace Barotrauma
|
||||
public void SmoothRotate(float targetRotation, float force = 10.0f)
|
||||
{
|
||||
float nextAngle = body.Rotation + body.AngularVelocity * (float)Timing.Step;
|
||||
|
||||
float angle = MathUtils.GetShortestAngle(nextAngle, targetRotation);
|
||||
|
||||
float torque = angle * 60.0f * (force/100.0f);
|
||||
float torque = angle * 60.0f * (force / 100.0f);
|
||||
|
||||
if (body.IsKinematic)
|
||||
{
|
||||
if (!IsValidValue(torque, "torque")) return;
|
||||
body.AngularVelocity = torque;
|
||||
}
|
||||
else
|
||||
{
|
||||
body.ApplyTorque(body.Mass * torque);
|
||||
ApplyTorque(body.Mass * torque);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -223,6 +223,7 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
propertyInfo.SetValue(obj, enumVal);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.8.1.7
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Fixed crashes when trying to load submarines in the sub editor.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.8.1.6
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Fixed a memory leak in submarine preview images which caused crashes in the server lobby screen and
|
||||
submarine editor.
|
||||
- Fixed clients not seeing the "vote to end the round" tickbox if they don't have a character assigned to
|
||||
them (despite the server allowing voting if the client has had a character earlier during the round).
|
||||
- Fixed clients being able to crash servers if they had the permission to use console commands that
|
||||
use the position of the client's cursor.
|
||||
- Fixed crashing if a wire is used by a statuseffect (for example if a detonator tries to trigger a wire
|
||||
contained inside it).
|
||||
- Fixed GameAnalytics being stopped if the dedicated server is restarted with the "restart" console command.-
|
||||
- Fixed wiring items outside the submarine.
|
||||
- Fixed chatbox discarding the second chat message instead of the first one when the maximum number of
|
||||
chat messages is reached.
|
||||
- Some error checking and debug logging to diagnose and prevent a crash caused by doors pushing characters away.
|
||||
- The spawnitem command doesn't require multi-word item names to be surrounded with quotes anymore.
|
||||
- Added the option to make powered items immune to electromagnetic pulses.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.8.1.5
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user