diff --git a/Launcher2/LauncherMain.cs b/Launcher2/LauncherMain.cs
index b8d166735..ea862f64d 100644
--- a/Launcher2/LauncherMain.cs
+++ b/Launcher2/LauncherMain.cs
@@ -202,6 +202,10 @@ namespace Launcher2
}
}
+ GUIComponent.ClearUpdateList();
+ guiRoot.AddToGUIUpdateList();
+ GUIComponent.UpdateMouseOn();
+
guiRoot.Update(deltaTime);
}
@@ -296,24 +300,30 @@ namespace Launcher2
{
updateInfoBox.ClearChildren();
- //string wrappedText = ToolBox.WrapText(text, updateInfoBox.Rect.Width, GUI.SmallFont);
-
- //int lineHeight = (int)GUI.SmallFont.MeasureString(" ").Y;
-
string[] lines = text.Split('\n');
foreach (string line in lines)
{
- if (string.IsNullOrWhiteSpace(line)) continue;
-
+ int indent = 10;
+ int heigth = 0;
+ if (!string.IsNullOrWhiteSpace(line))
+ {
+ if (line[0] == '-')
+ indent = 20;
+ }
+ else
+ {
+ heigth = 5;
+ }
+
GUITextBlock textBlock = new GUITextBlock(
- new Rectangle(0,0,0,0),
+ new Rectangle(indent, 0, 0, heigth),
line, GUI.Style,
Alignment.TopLeft, Alignment.TopLeft,
updateInfoBox, true, GUI.SmallFont);
+ textBlock.Padding = new Vector4(indent, 0, 0, 0);
+ textBlock.TextColor = indent > 10 ? Color.LightGray : Color.White;
textBlock.CanBeFocused = false;
}
-
-
}
private bool CheckForUpdates()
@@ -410,7 +420,7 @@ namespace Launcher2
if (currentVersion.CompareTo(latestVersion) >= 0)
{
- updateInfoText.Text = "Game is up to date!";
+ updateInfoText.Text = "Your game is up to date!";
return false;
}
@@ -439,9 +449,14 @@ namespace Launcher2
string innerText = ToolBox.ElementInnerText(patchNote);
innerText = innerText.Replace("\r\n", "\n");
- sb.Append(innerText+"\n");
+ innerText = innerText.Replace("\t", "");
+
+ sb.AppendLine("================================");
+ sb.AppendLine(patchNumber);
+ sb.AppendLine("================================\n");
+
+ sb.AppendLine(innerText);
- sb.AppendLine("----------------------------\n");
}
SetUpdateInfoBox(sb.ToString());
@@ -577,7 +592,7 @@ namespace Launcher2
private void Completed(object sender, AsyncCompletedEventArgs e)
{
- if (e.Error!=null)
+ if (e.Error != null)
{
string errorMsg = "Error while downloading: " + e.Error;
diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 81cae3f08..f0091efe5 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -92,6 +92,7 @@
+
@@ -367,6 +368,13 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ Designer
+ PreserveNewest
+
PreserveNewest
@@ -1092,9 +1100,33 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -1116,6 +1148,12 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -1131,6 +1169,21 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -1152,6 +1205,33 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -1284,6 +1364,57 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -1332,6 +1463,24 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
@@ -1383,6 +1532,21 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Subsurface/Content/Characters/Carrier/alarm1.ogg b/Subsurface/Content/Characters/Carrier/alarm1.ogg
new file mode 100644
index 000000000..f0d9d3b4d
Binary files /dev/null and b/Subsurface/Content/Characters/Carrier/alarm1.ogg differ
diff --git a/Subsurface/Content/Characters/Carrier/carrier.png b/Subsurface/Content/Characters/Carrier/carrier.png
new file mode 100644
index 000000000..78c957814
Binary files /dev/null and b/Subsurface/Content/Characters/Carrier/carrier.png differ
diff --git a/Subsurface/Content/Characters/Carrier/carrier.xml b/Subsurface/Content/Characters/Carrier/carrier.xml
new file mode 100644
index 000000000..4ff3312d2
--- /dev/null
+++ b/Subsurface/Content/Characters/Carrier/carrier.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Subsurface/Content/Characters/Carrier/carrier1.ogg b/Subsurface/Content/Characters/Carrier/carrier1.ogg
new file mode 100644
index 000000000..fb049225a
Binary files /dev/null and b/Subsurface/Content/Characters/Carrier/carrier1.ogg differ
diff --git a/Subsurface/Content/Characters/Carrier/carrier2.ogg b/Subsurface/Content/Characters/Carrier/carrier2.ogg
new file mode 100644
index 000000000..990eadd5f
Binary files /dev/null and b/Subsurface/Content/Characters/Carrier/carrier2.ogg differ
diff --git a/Subsurface/Content/Characters/Carrier/carrier3.ogg b/Subsurface/Content/Characters/Carrier/carrier3.ogg
new file mode 100644
index 000000000..71c5fc00c
Binary files /dev/null and b/Subsurface/Content/Characters/Carrier/carrier3.ogg differ
diff --git a/Subsurface/Content/Characters/Carrier/ping.ogg b/Subsurface/Content/Characters/Carrier/ping.ogg
new file mode 100644
index 000000000..ce361a7aa
Binary files /dev/null and b/Subsurface/Content/Characters/Carrier/ping.ogg differ
diff --git a/Subsurface/Content/Characters/Coelanth/attack1.ogg b/Subsurface/Content/Characters/Coelanth/attack1.ogg
new file mode 100644
index 000000000..8985861ab
Binary files /dev/null and b/Subsurface/Content/Characters/Coelanth/attack1.ogg differ
diff --git a/Subsurface/Content/Characters/Coelanth/coelanth.xml b/Subsurface/Content/Characters/Coelanth/coelanth.xml
index 369627839..4e820b397 100644
--- a/Subsurface/Content/Characters/Coelanth/coelanth.xml
+++ b/Subsurface/Content/Characters/Coelanth/coelanth.xml
@@ -1,9 +1,9 @@
-
-
-
+
+
+
diff --git a/Subsurface/Content/Characters/Coelanth/idle1.ogg b/Subsurface/Content/Characters/Coelanth/idle1.ogg
new file mode 100644
index 000000000..079231c03
Binary files /dev/null and b/Subsurface/Content/Characters/Coelanth/idle1.ogg differ
diff --git a/Subsurface/Content/Characters/Coelanth/idle2.ogg b/Subsurface/Content/Characters/Coelanth/idle2.ogg
new file mode 100644
index 000000000..998f7769b
Binary files /dev/null and b/Subsurface/Content/Characters/Coelanth/idle2.ogg differ
diff --git a/Subsurface/Content/Characters/Fractalguardian/Die1.ogg b/Subsurface/Content/Characters/Fractalguardian/Die1.ogg
new file mode 100644
index 000000000..a3786d9bc
Binary files /dev/null and b/Subsurface/Content/Characters/Fractalguardian/Die1.ogg differ
diff --git a/Subsurface/Content/Characters/Fractalguardian/Die2.ogg b/Subsurface/Content/Characters/Fractalguardian/Die2.ogg
new file mode 100644
index 000000000..4e24f4425
Binary files /dev/null and b/Subsurface/Content/Characters/Fractalguardian/Die2.ogg differ
diff --git a/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml b/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml
index 86c561a70..69ad89036 100644
--- a/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml
+++ b/Subsurface/Content/Characters/Fractalguardian/fractalguardian.xml
@@ -3,6 +3,8 @@
+
+
diff --git a/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml b/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml
index e1d743557..9f45de877 100644
--- a/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml
+++ b/Subsurface/Content/Characters/Fractalguardian2/fractalguardian2.xml
@@ -3,6 +3,8 @@
+
+
diff --git a/Subsurface/Content/Characters/Mantis/attack1.ogg b/Subsurface/Content/Characters/Mantis/attack1.ogg
new file mode 100644
index 000000000..46084f03a
Binary files /dev/null and b/Subsurface/Content/Characters/Mantis/attack1.ogg differ
diff --git a/Subsurface/Content/Characters/Mantis/attack2.ogg b/Subsurface/Content/Characters/Mantis/attack2.ogg
new file mode 100644
index 000000000..72de2e2e7
Binary files /dev/null and b/Subsurface/Content/Characters/Mantis/attack2.ogg differ
diff --git a/Subsurface/Content/Characters/Mantis/idle1.ogg b/Subsurface/Content/Characters/Mantis/idle1.ogg
new file mode 100644
index 000000000..261360518
Binary files /dev/null and b/Subsurface/Content/Characters/Mantis/idle1.ogg differ
diff --git a/Subsurface/Content/Characters/Mantis/idle2.ogg b/Subsurface/Content/Characters/Mantis/idle2.ogg
new file mode 100644
index 000000000..d1f349935
Binary files /dev/null and b/Subsurface/Content/Characters/Mantis/idle2.ogg differ
diff --git a/Subsurface/Content/Characters/Mantis/idle3.ogg b/Subsurface/Content/Characters/Mantis/idle3.ogg
new file mode 100644
index 000000000..03d2bd9bc
Binary files /dev/null and b/Subsurface/Content/Characters/Mantis/idle3.ogg differ
diff --git a/Subsurface/Content/Characters/Mantis/mantis.xml b/Subsurface/Content/Characters/Mantis/mantis.xml
index 669325144..298d4c9e6 100644
--- a/Subsurface/Content/Characters/Mantis/mantis.xml
+++ b/Subsurface/Content/Characters/Mantis/mantis.xml
@@ -1,12 +1,13 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Subsurface/Content/Items/Artifacts/artifacts.xml b/Subsurface/Content/Items/Artifacts/artifacts.xml
index 3a6b3ee62..2d7145c9a 100644
--- a/Subsurface/Content/Items/Artifacts/artifacts.xml
+++ b/Subsurface/Content/Items/Artifacts/artifacts.xml
@@ -227,11 +227,9 @@
-
+
-
-
-
+
diff --git a/Subsurface/Content/Items/Button/button.xml b/Subsurface/Content/Items/Button/button.xml
index 87a5401bd..35954a92c 100644
--- a/Subsurface/Content/Items/Button/button.xml
+++ b/Subsurface/Content/Items/Button/button.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/Subsurface/Content/Items/Electricity/poweritems.xml b/Subsurface/Content/Items/Electricity/poweritems.xml
index 744d114e0..3a63ab3ef 100644
--- a/Subsurface/Content/Items/Electricity/poweritems.xml
+++ b/Subsurface/Content/Items/Electricity/poweritems.xml
@@ -50,7 +50,7 @@
-
+
@@ -59,7 +59,7 @@
-
+
diff --git a/Subsurface/Content/Items/Reactor/reactor.xml b/Subsurface/Content/Items/Reactor/reactor.xml
index 7561565af..5d2d99079 100644
--- a/Subsurface/Content/Items/Reactor/reactor.xml
+++ b/Subsurface/Content/Items/Reactor/reactor.xml
@@ -39,7 +39,7 @@
-
+
diff --git a/Subsurface/Content/Items/Weapons/depthcharge.xml b/Subsurface/Content/Items/Weapons/depthcharge.xml
index 31e9a2016..c3c31176c 100644
--- a/Subsurface/Content/Items/Weapons/depthcharge.xml
+++ b/Subsurface/Content/Items/Weapons/depthcharge.xml
@@ -45,7 +45,7 @@
-
+
diff --git a/Subsurface/Content/Items/Weapons/explosives.xml b/Subsurface/Content/Items/Weapons/explosives.xml
index 8fd7dc4dc..57c683c19 100644
--- a/Subsurface/Content/Items/Weapons/explosives.xml
+++ b/Subsurface/Content/Items/Weapons/explosives.xml
@@ -91,7 +91,7 @@
-
+
diff --git a/Subsurface/Content/Items/Weapons/railgun.ogg b/Subsurface/Content/Items/Weapons/railgun.ogg
index ea3128b57..8ff5c558c 100644
Binary files a/Subsurface/Content/Items/Weapons/railgun.ogg and b/Subsurface/Content/Items/Weapons/railgun.ogg differ
diff --git a/Subsurface/Content/Items/Weapons/railgun.xml b/Subsurface/Content/Items/Weapons/railgun.xml
index 5d5922029..2a6ee0ab8 100644
--- a/Subsurface/Content/Items/Weapons/railgun.xml
+++ b/Subsurface/Content/Items/Weapons/railgun.xml
@@ -34,8 +34,9 @@
-
+
+
@@ -74,7 +75,7 @@
-
+
@@ -106,7 +107,7 @@
-
+
diff --git a/Subsurface/Content/Items/warningSiren.ogg b/Subsurface/Content/Items/warningSiren.ogg
index bd8cb29d3..7f89d7239 100644
Binary files a/Subsurface/Content/Items/warningSiren.ogg and b/Subsurface/Content/Items/warningSiren.ogg differ
diff --git a/Subsurface/Content/Map/StructurePrefabs.xml b/Subsurface/Content/Map/StructurePrefabs.xml
index 92442cdf6..02a982966 100644
--- a/Subsurface/Content/Map/StructurePrefabs.xml
+++ b/Subsurface/Content/Map/StructurePrefabs.xml
@@ -108,22 +108,22 @@
-
+
-
+
-
+
-
+
diff --git a/Subsurface/Content/Map/background.png b/Subsurface/Content/Map/background.png
index 3a0044f6b..923b03581 100644
Binary files a/Subsurface/Content/Map/background.png and b/Subsurface/Content/Map/background.png differ
diff --git a/Subsurface/Content/Map/background2.png b/Subsurface/Content/Map/background2.png
index 71a7675c7..9a5d8f8e3 100644
Binary files a/Subsurface/Content/Map/background2.png and b/Subsurface/Content/Map/background2.png differ
diff --git a/Subsurface/Content/Missions.xml b/Subsurface/Content/Missions.xml
index 6a615bd06..26d82d1f0 100644
--- a/Subsurface/Content/Missions.xml
+++ b/Subsurface/Content/Missions.xml
@@ -68,6 +68,17 @@
successmessage="It turns out the signal was emitted by a Moloch. The researchers of [location1] have agreed to pay you the reward nevertheless for getting rid of the Moloch."
monsterfile="Content/Characters/Moloch/moloch.xml">
+
+
+
+
-
+
+
+
+
+
+
+
+
@@ -30,16 +37,38 @@
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Subsurface/Source/Camera.cs b/Subsurface/Source/Camera.cs
index 1dca560a4..6f6c7aa6d 100644
--- a/Subsurface/Source/Camera.cs
+++ b/Subsurface/Source/Camera.cs
@@ -165,7 +165,7 @@ namespace Barotrauma
}
}
- public void MoveCamera(float deltaTime)
+ public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true)
{
prevPosition = position;
prevZoom = zoom;
@@ -175,7 +175,7 @@ namespace Barotrauma
Vector2 moveCam = Vector2.Zero;
if (targetPos == Vector2.Zero)
{
- if (GUIComponent.KeyboardDispatcher.Subscriber == null)
+ if (allowMove && GUIComponent.KeyboardDispatcher.Subscriber == null)
{
if (PlayerInput.KeyDown(Keys.LeftShift)) moveSpeed *= 2.0f;
if (PlayerInput.KeyDown(Keys.LeftControl)) moveSpeed *= 0.5f;
@@ -197,11 +197,14 @@ namespace Barotrauma
moveCam = moveCam * deltaTime * 60.0f;
- Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
- Vector2 diffViewCenter;
- diffViewCenter = ((mouseInWorld - Position) * Zoom);
- Zoom = MathHelper.Clamp(zoom + (PlayerInput.ScrollWheelSpeed / 1000.0f) * zoom, GameMain.DebugDraw ? 0.01f : 0.1f, 2.0f);
- if (!PlayerInput.KeyDown(Keys.F)) Position = mouseInWorld - (diffViewCenter / Zoom);
+ if (allowZoom)
+ {
+ Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
+ Vector2 diffViewCenter;
+ diffViewCenter = ((mouseInWorld - Position) * Zoom);
+ Zoom = MathHelper.Clamp(zoom + (PlayerInput.ScrollWheelSpeed / 1000.0f) * zoom, GameMain.DebugDraw ? 0.01f : 0.1f, 2.0f);
+ if (!PlayerInput.KeyDown(Keys.F)) Position = mouseInWorld - (diffViewCenter / Zoom);
+ }
}
else
{
diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs
index 8cd751d30..f653789b8 100644
--- a/Subsurface/Source/Characters/AICharacter.cs
+++ b/Subsurface/Source/Characters/AICharacter.cs
@@ -57,7 +57,15 @@ namespace Barotrauma
}
else
{
- PlaySound((aiController == null) ? AIController.AiState.None : aiController.State);
+ switch (aiController.State)
+ {
+ case AIController.AiState.Attack:
+ PlaySound(CharacterSound.SoundType.Attack);
+ break;
+ default:
+ PlaySound(CharacterSound.SoundType.Idle);
+ break;
+ }
soundTimer = soundInterval;
}
diff --git a/Subsurface/Source/Characters/Animation/FishAnimController.cs b/Subsurface/Source/Characters/Animation/FishAnimController.cs
index ee420f416..543339e16 100644
--- a/Subsurface/Source/Characters/Animation/FishAnimController.cs
+++ b/Subsurface/Source/Characters/Animation/FishAnimController.cs
@@ -205,15 +205,15 @@ namespace Barotrauma
if (Limbs[i].SteerForce <= 0.0f) continue;
Vector2 pullPos = Limbs[i].pullJoint == null ? Limbs[i].SimPosition : Limbs[i].pullJoint.WorldAnchorA;
- Limbs[i].body.ApplyForce(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
+ Limbs[i].body.ApplyForce(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos);
- if (Limbs[i] == MainLimb) continue;
+ /*if (Limbs[i] == MainLimb) continue;
float dist = (MainLimb.SimPosition - Limbs[i].SimPosition).Length();
Vector2 limbPos = MainLimb.SimPosition - Vector2.Normalize(movement) * dist;
- Limbs[i].body.ApplyForce(((limbPos - Limbs[i].SimPosition) * 3.0f - Limbs[i].LinearVelocity * 3.0f) * Limbs[i].Mass);
+ Limbs[i].body.ApplyForce(((limbPos - Limbs[i].SimPosition) * 3.0f - Limbs[i].LinearVelocity * 3.0f) * Limbs[i].Mass);*/
}
Collider.LinearVelocity = Vector2.Lerp(Collider.LinearVelocity, movement, 0.5f);
diff --git a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs
index e2fdb3ab2..84a864c36 100644
--- a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs
+++ b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs
@@ -173,12 +173,10 @@ namespace Barotrauma
levitatingCollider = false;
UpdateClimbing();
break;
- case Animation.UsingConstruction:
- UpdateStanding();
- break;
case Animation.CPR:
UpdateCPR(deltaTime);
break;
+ case Animation.UsingConstruction:
default:
if (character.SelectedCharacter != null) DragCharacter(character.SelectedCharacter);
@@ -260,9 +258,9 @@ namespace Barotrauma
float slowdownAmount = 0.0f;
if (currentHull != null)
{
- //full slowdown (1.0f) when water is up to the torso
+ //full slowdown (1.5f) when water is up to the torso
surfaceY = ConvertUnits.ToSimUnits(currentHull.Surface);
- slowdownAmount = MathHelper.Clamp((surfaceY - colliderPos.Y) / torsoPosition, 0.0f, 1.0f);
+ slowdownAmount = MathHelper.Clamp((surfaceY - colliderPos.Y) / torsoPosition, 0.0f, 1.0f) * 1.5f;
}
float maxSpeed = Math.Max(TargetMovement.Length() - slowdownAmount, 1.0f);
@@ -272,7 +270,7 @@ namespace Barotrauma
float walkPosX = (float)Math.Cos(walkPos);
float walkPosY = (float)Math.Sin(walkPos);
float runningModifier = (float)Math.Max(Math.Min(Math.Abs(TargetMovement.X), 3.0f) / 1.5f, 1.0);
-
+
Vector2 stepSize = new Vector2(
this.stepSize.X * walkPosX * runningModifier,
this.stepSize.Y * walkPosY * runningModifier * runningModifier);
@@ -567,7 +565,7 @@ namespace Barotrauma
rotation = MathHelper.ToDegrees(rotation);
if (rotation < 0.0f) rotation += 360;
- if (!character.IsRemotePlayer && !aiming)
+ if (!character.IsRemotePlayer && !aiming && Anim != Animation.UsingConstruction)
{
if (rotation > 20 && rotation < 170)
TargetDir = Direction.Left;
@@ -751,9 +749,9 @@ namespace Barotrauma
ladderSimPos += character.SelectedConstruction.Submarine.SimPosition - currentHull.Submarine.SimPosition;
}
- MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y + 0.7f - colliderHeightFromFloor), 10.5f);
- MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y + 0.5f - colliderHeightFromFloor), 10.5f);
- MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, Collider.SimPosition.Y + 0.4f - colliderHeightFromFloor), 10.5f);
+ MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y + 0.9f - colliderHeightFromFloor), 10.5f);
+ MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y + 0.7f - colliderHeightFromFloor), 10.5f);
+ MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, Collider.SimPosition.Y + 0.6f - colliderHeightFromFloor), 10.5f);
Collider.MoveToPos(new Vector2(ladderSimPos.X - 0.2f * Dir, Collider.SimPosition.Y), 10.5f);
@@ -761,9 +759,9 @@ namespace Barotrauma
Vector2 handPos = new Vector2(
ladderSimPos.X,
- Collider.SimPosition.Y + 0.6f + movement.Y * 0.1f - ladderSimPos.Y);
+ Collider.SimPosition.Y + 0.8f + movement.Y * 0.1f - ladderSimPos.Y);
- handPos.Y = Math.Min(-0.5f, handPos.Y) - colliderHeightFromFloor;
+ handPos.Y = Math.Min(-0.2f, handPos.Y) - colliderHeightFromFloor;
MoveLimb(leftHand,
new Vector2(handPos.X,
@@ -780,7 +778,7 @@ namespace Barotrauma
Vector2 footPos = new Vector2(
handPos.X - Dir * 0.05f,
- Collider.SimPosition.Y + 0.7f - colliderHeightFromFloor - stepHeight * 2.7f - ladderSimPos.Y - 0.7f);
+ Collider.SimPosition.Y + 0.9f - colliderHeightFromFloor - stepHeight * 2.7f - ladderSimPos.Y - 0.7f);
//if (movement.Y < 0) footPos.Y += 0.05f;
diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs
index 39ee92af7..1edafad57 100644
--- a/Subsurface/Source/Characters/Animation/Ragdoll.cs
+++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs
@@ -372,7 +372,8 @@ namespace Barotrauma
foreach (Limb limb in Limbs)
{
- limb.sprite.Depth = startDepth + limb.sprite.Depth * 0.0001f;
+ if (limb.sprite != null)
+ limb.sprite.Depth = startDepth + limb.sprite.Depth * 0.0001f;
}
Limb torso = GetLimb(LimbType.Torso);
@@ -638,27 +639,31 @@ namespace Barotrauma
}
- for (int i = 0; i < Limbs.Length; i++)
+ foreach (Limb limb in Limbs)
{
- if (Limbs[i] == null) continue;
+ if (limb == null) continue;
- Vector2 spriteOrigin = Limbs[i].sprite.Origin;
- spriteOrigin.X = Limbs[i].sprite.SourceRect.Width - spriteOrigin.X;
- Limbs[i].sprite.Origin = spriteOrigin;
-
- Limbs[i].Dir = Dir;
-
- if (Limbs[i].LightSource != null)
+ if (limb.sprite != null)
{
- Limbs[i].LightSource.SpriteEffect = (dir == Direction.Left) ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
+ Vector2 spriteOrigin = limb.sprite.Origin;
+ spriteOrigin.X = limb.sprite.SourceRect.Width - spriteOrigin.X;
+ limb.sprite.Origin = spriteOrigin;
}
- if (Limbs[i].pullJoint == null) continue;
+ limb.Dir = Dir;
- Limbs[i].pullJoint.LocalAnchorA =
- new Vector2(
- -Limbs[i].pullJoint.LocalAnchorA.X,
- Limbs[i].pullJoint.LocalAnchorA.Y);
+ if (limb.LightSource != null)
+ {
+ limb.LightSource.FlipX();
+ }
+
+ if (limb.pullJoint != null)
+ {
+ limb.pullJoint.LocalAnchorA =
+ new Vector2(
+ -limb.pullJoint.LocalAnchorA.X,
+ limb.pullJoint.LocalAnchorA.Y);
+ }
}
}
@@ -864,6 +869,7 @@ namespace Barotrauma
{
//limb isn't in any room -> it's in the water
limb.inWater = true;
+ if (limb.type == LimbType.Head) headInWater = true;
}
else if (limbHull.Volume > 0.0f && Submarine.RectContains(limbHull.Rect, limb.Position))
{
diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs
index 994dad171..ad4138a84 100644
--- a/Subsurface/Source/Characters/Character.cs
+++ b/Subsurface/Source/Characters/Character.cs
@@ -144,10 +144,7 @@ namespace Barotrauma
private float bleeding;
- private Sound[] sounds;
- private float[] soundRange;
- //which AIstate each sound is for
- private AIController.AiState[] soundStates;
+ private List sounds;
private float attackCoolDown;
@@ -603,28 +600,13 @@ namespace Barotrauma
soundInterval = ToolBox.GetAttributeFloat(doc.Root, "soundinterval", 10.0f);
var soundElements = doc.Root.Elements("sound").ToList();
- if (soundElements.Any())
+
+ sounds = new List();
+ foreach (XElement soundElement in soundElements)
{
- sounds = new Sound[soundElements.Count];
- soundStates = new AIController.AiState[soundElements.Count];
- soundRange = new float[soundElements.Count];
- int i = 0;
- foreach (XElement soundElement in soundElements)
- {
- sounds[i] = Sound.Load(soundElement.Attribute("file").Value);
- soundRange[i] = ToolBox.GetAttributeFloat(soundElement, "range", 1000.0f);
- if (soundElement.Attribute("state") == null)
- {
- soundStates[i] = AIController.AiState.None;
- }
- else
- {
- soundStates[i] = (AIController.AiState)Enum.Parse(
- typeof(AIController.AiState), soundElement.Attribute("state").Value, true);
- }
- i++;
- }
+ sounds.Add(new CharacterSound(soundElement));
}
+
if (file == humanConfigFile)
{
@@ -1536,8 +1518,14 @@ namespace Barotrauma
private void UpdateOxygen(float deltaTime)
{
+ float prevOxygen = oxygen;
Oxygen += deltaTime * (oxygenAvailable < 30.0f ? -5.0f : 10.0f);
+ if (prevOxygen > 0.0f && Oxygen <= 0.0f && controlled == this)
+ {
+ SoundPlayer.PlaySound("drown");
+ }
+
PressureProtection -= deltaTime * 100.0f;
float hullAvailableOxygen = 0.0f;
@@ -1678,6 +1666,8 @@ namespace Barotrauma
///
public HUDProgressBar UpdateHUDProgressBar(object linkedObject, Vector2 worldPosition, float progress, Color emptyColor, Color fullColor)
{
+ if (controlled != this) return null;
+
HUDProgressBar progressBar = null;
if (!hudProgressBars.TryGetValue(linkedObject, out progressBar))
{
@@ -1692,24 +1682,15 @@ namespace Barotrauma
return progressBar;
}
- public void PlaySound(AIController.AiState state)
+ public void PlaySound(CharacterSound.SoundType soundType)
{
- if (sounds == null || !sounds.Any()) return;
- var matchingSoundStates = soundStates.Where(x => x == state).ToList();
+ if (sounds == null || sounds.Count == 0) return;
- int selectedSound = Rand.Int(matchingSoundStates.Count);
+ var matchingSounds = sounds.FindAll(s => s.Type == soundType);
+ if (matchingSounds.Count == 0) return;
- int n = 0;
- for (int i = 0; i < sounds.Length; i++)
- {
- if (soundStates[i] != state) continue;
- if (n == selectedSound && sounds[i]!=null)
- {
- sounds[i].Play(1.0f, soundRange[i], AnimController.Limbs[0].WorldPosition);
- return;
- }
- n++;
- }
+ var selectedSound = matchingSounds[Rand.Int(matchingSounds.Count)];
+ selectedSound.Sound.Play(1.0f, selectedSound.Range, AnimController.WorldPosition);
}
public virtual void AddDamage(CauseOfDeath causeOfDeath, float amount, IDamageable attacker)
@@ -1810,7 +1791,7 @@ namespace Barotrauma
// limb.Damage = 100.0f;
}
- SoundPlayer.PlayDamageSound(DamageSoundType.Implode, 50.0f, AnimController.Collider);
+ SoundPlayer.PlaySound("implode", 1.0f, 150.0f, WorldPosition);
for (int i = 0; i < 10; i++)
{
@@ -1861,11 +1842,9 @@ namespace Barotrauma
GameServer.Log(Name+" has died (Cause of death: "+causeOfDeath+")", Color.Red);
if (OnDeath != null) OnDeath(this, causeOfDeath);
-
- //CoroutineManager.StartCoroutine(DeathAnim(GameMain.GameScreen.Cam));
-
- //health = 0.0f;
-
+
+ PlaySound(CharacterSound.SoundType.Die);
+
isDead = true;
this.causeOfDeath = causeOfDeath;
AnimController.movement = Vector2.Zero;
@@ -1876,7 +1855,7 @@ namespace Barotrauma
if (selectedItems[i] != null) selectedItems[i].Drop(this);
}
- if (aiTarget!=null)
+ if (aiTarget != null)
{
aiTarget.Remove();
aiTarget = null;
diff --git a/Subsurface/Source/Characters/CharacterHUD.cs b/Subsurface/Source/Characters/CharacterHUD.cs
index 442fc6341..aa5c11ef8 100644
--- a/Subsurface/Source/Characters/CharacterHUD.cs
+++ b/Subsurface/Source/Characters/CharacterHUD.cs
@@ -138,6 +138,7 @@ namespace Barotrauma
{
if (character.Inventory != null && !character.LockHands && character.Stun >= -0.1f)
{
+ character.Inventory.DrawOffset = Vector2.Zero;
character.Inventory.DrawOwn(spriteBatch);
}
diff --git a/Subsurface/Source/Characters/CharacterSound.cs b/Subsurface/Source/Characters/CharacterSound.cs
new file mode 100644
index 000000000..fac222550
--- /dev/null
+++ b/Subsurface/Source/Characters/CharacterSound.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+
+namespace Barotrauma
+{
+ class CharacterSound
+ {
+ public enum SoundType
+ {
+ Idle, Attack, Die
+ }
+
+ public readonly Sound Sound;
+
+ public readonly SoundType Type;
+
+ public readonly float Range;
+
+ public CharacterSound(XElement element)
+ {
+ Sound = Sound.Load(element.Attribute("file").Value);
+ Range = ToolBox.GetAttributeFloat(element, "range", 1000.0f);
+
+ Enum.TryParse(ToolBox.GetAttributeString(element, "state", "Idle"), true, out Type);
+ }
+ }
+}
diff --git a/Subsurface/Source/Characters/Limb.cs b/Subsurface/Source/Characters/Limb.cs
index 95445a17f..9116143dd 100644
--- a/Subsurface/Source/Characters/Limb.cs
+++ b/Subsurface/Source/Characters/Limb.cs
@@ -423,7 +423,6 @@ namespace Barotrauma
if (LightSource != null)
{
LightSource.ParentSub = body.Submarine;
- LightSource.Position = Position;
}
if (!character.IsDead) damage = Math.Max(0.0f, damage-deltaTime*0.1f);
@@ -504,6 +503,12 @@ namespace Barotrauma
body.UpdateDrawPosition();
}
+ if (LightSource != null)
+ {
+ LightSource.Position = body.DrawPosition;
+ LightSource.Rotation = body.DrawRotation;
+ }
+
foreach (WearableSprite wearable in wearingItems)
{
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
@@ -528,36 +533,37 @@ namespace Barotrauma
-body.DrawRotation,
scale, spriteEffect, depth);
}
-
- if (damage>0.0f && damagedSprite!=null && !hideLimb)
+
+ if (damage > 0.0f && damagedSprite != null && !hideLimb)
{
SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
-
+
float depth = sprite.Depth - 0.0000015f;
-
+
damagedSprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
- color*Math.Min(damage/50.0f,1.0f), sprite.Origin,
+ color * Math.Min(damage / 50.0f, 1.0f), sprite.Origin,
-body.DrawRotation,
1.0f, spriteEffect, depth);
}
-
+
if (!GameMain.DebugDraw) return;
- if (pullJoint!=null)
+ if (pullJoint != null)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true);
- }
-
-
+ }
}
public void Remove()
{
- sprite.Remove();
- sprite = null;
+ if (sprite != null)
+ {
+ sprite.Remove();
+ sprite = null;
+ }
if (LightSource != null)
{
diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs
index 4328191d5..2e5a022f0 100644
--- a/Subsurface/Source/DebugConsole.cs
+++ b/Subsurface/Source/DebugConsole.cs
@@ -95,6 +95,7 @@ namespace Barotrauma
if (isOpen)
{
textBox.Select();
+ AddToGUIUpdateList();
}
else
{
@@ -426,6 +427,14 @@ namespace Barotrauma
case "mainmenuscreen":
case "mainmenu":
case "menu":
+ GameMain.GameSession = null;
+
+ List characters = new List(Character.CharacterList);
+ foreach (Character c in characters)
+ {
+ c.Remove();
+ }
+
GameMain.MainMenuScreen.Select();
break;
case "gamescreen":
diff --git a/Subsurface/Source/Events/Missions/SalvageMission.cs b/Subsurface/Source/Events/Missions/SalvageMission.cs
index 358f52cf9..f12232250 100644
--- a/Subsurface/Source/Events/Missions/SalvageMission.cs
+++ b/Subsurface/Source/Events/Missions/SalvageMission.cs
@@ -54,6 +54,24 @@ namespace Barotrauma
item = new Item(itemPrefab, position, null);
item.MoveWithLevel = true;
item.body.FarseerBody.IsKinematic = true;
+
+ if (item.HasTag("alien"))
+ {
+ //try to find a nearby artifact holder (or any alien itemcontainer) and place the artifact inside it
+ foreach (Item it in Item.ItemList)
+ {
+ if (it.Submarine != null || !it.HasTag("alien")) continue;
+
+ if (Math.Abs(item.WorldPosition.X - it.WorldPosition.X) > 2000.0f) continue;
+ if (Math.Abs(item.WorldPosition.Y - it.WorldPosition.Y) > 2000.0f) continue;
+
+ var itemContainer = it.GetComponent();
+ if (itemContainer == null) continue;
+
+ itemContainer.Combine(item);
+ break;
+ }
+ }
}
public override void Update(float deltaTime)
diff --git a/Subsurface/Source/GUI/GUIComponent.cs b/Subsurface/Source/GUI/GUIComponent.cs
index dc8e9d7cc..f48325221 100644
--- a/Subsurface/Source/GUI/GUIComponent.cs
+++ b/Subsurface/Source/GUI/GUIComponent.cs
@@ -33,6 +33,13 @@ namespace Barotrauma
public static void ClearUpdateList()
{
+ if (keyboardDispatcher != null &&
+ KeyboardDispatcher.Subscriber is GUIComponent &&
+ !ComponentsToUpdate.Contains((GUIComponent)KeyboardDispatcher.Subscriber))
+ {
+ KeyboardDispatcher.Subscriber = null;
+ }
+
ComponentsToUpdate.Clear();
}
diff --git a/Subsurface/Source/GUI/GUIDropDown.cs b/Subsurface/Source/GUI/GUIDropDown.cs
index a3fc5d5d3..177616007 100644
--- a/Subsurface/Source/GUI/GUIDropDown.cs
+++ b/Subsurface/Source/GUI/GUIDropDown.cs
@@ -103,14 +103,11 @@ namespace Barotrauma
{
GUITextBlock textBlock = new GUITextBlock(new Rectangle(0,0,0,20), text, GUI.Style, listBox);
textBlock.UserData = userData;
+ }
- //int totalHeight = 0;
- //foreach (GUIComponent child in listBox.children)
- //{
- // totalHeight += child.Rect.Height;
- //}
-
- //listBox.Rect = new Rectangle(listBox.Rect.X,listBox.Rect.Y,listBox.Rect.Width,totalHeight);
+ public override void ClearChildren()
+ {
+ listBox.ClearChildren();
}
public List GetChildren()
diff --git a/Subsurface/Source/GUI/GUIListBox.cs b/Subsurface/Source/GUI/GUIListBox.cs
index 1d235d7e9..44f0fd17a 100644
--- a/Subsurface/Source/GUI/GUIListBox.cs
+++ b/Subsurface/Source/GUI/GUIListBox.cs
@@ -147,7 +147,8 @@ namespace Barotrauma
scrollBar = new GUIScrollBar(
new Rectangle(this.rect.Right - 20, this.rect.Y, 20, this.rect.Height), null, 1.0f, GUI.Style);
}
-
+
+ scrollBar.IsHorizontal = isHorizontal;
frame = new GUIFrame(Rectangle.Empty, style, this);
if (style != null) style.Apply(frame, this);
diff --git a/Subsurface/Source/GUI/GUIScrollBar.cs b/Subsurface/Source/GUI/GUIScrollBar.cs
index 60bb9d1ed..4e21592df 100644
--- a/Subsurface/Source/GUI/GUIScrollBar.cs
+++ b/Subsurface/Source/GUI/GUIScrollBar.cs
@@ -25,6 +25,12 @@ namespace Barotrauma
public bool IsHorizontal
{
get { return isHorizontal; }
+ set
+ {
+ if (isHorizontal == value) return;
+ isHorizontal = value;
+ UpdateRect();
+ }
}
public bool Enabled
diff --git a/Subsurface/Source/GameMain.cs b/Subsurface/Source/GameMain.cs
index d0c7fc0a4..346f2cbbb 100644
--- a/Subsurface/Source/GameMain.cs
+++ b/Subsurface/Source/GameMain.cs
@@ -250,7 +250,7 @@ namespace Barotrauma
GameModePreset.Init();
- Submarine.Preload();
+ Submarine.RefreshSavedSubs();
TitleScreen.LoadState = 80.0f;
yield return CoroutineStatus.Running;
diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs
index f4f5bfd89..cbfe29e10 100644
--- a/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs
+++ b/Subsurface/Source/GameSession/GameModes/Tutorials/BasicTutorial.cs
@@ -283,7 +283,7 @@ namespace Barotrauma.Tutorials
infoBox = CreateInfoFrame("Steer the submarine downwards, heading further into the cavern.");
- while (Submarine.MainSub.WorldPosition.Y > 36500.0f)
+ while (Submarine.MainSub.WorldPosition.Y > 40000.0f)
{
yield return CoroutineStatus.Running;
}
@@ -293,7 +293,7 @@ namespace Barotrauma.Tutorials
"Content/Characters/Moloch/moloch.xml",
steering.Item.WorldPosition + new Vector2(3000.0f, -500.0f));
- moloch.PlaySound(AIController.AiState.Attack);
+ moloch.PlaySound(CharacterSound.SoundType.Attack);
yield return new WaitForSeconds(1.0f);
@@ -349,7 +349,7 @@ namespace Barotrauma.Tutorials
if (isWindow)
{
//decrease window damage to slow down the leaking
- w.AddDamage(i, -w.SectionDamage(i) * 0.495f);
+ w.AddDamage(i, -w.SectionDamage(i) * 0.48f);
}
else
{
diff --git a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs
index a46777f2a..2cfe573aa 100644
--- a/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs
+++ b/Subsurface/Source/GameSession/GameModes/Tutorials/TutorialType.cs
@@ -39,7 +39,7 @@ namespace Barotrauma.Tutorials
GameMain.GameSession = new GameSession(Submarine.MainSub, "", GameModePreset.list.Find(gm => gm.Name.ToLowerInvariant() == "tutorial"));
(GameMain.GameSession.gameMode as TutorialMode).tutorialType = this;
- GameMain.GameSession.StartShift("tuto2");
+ GameMain.GameSession.StartShift("tuto");
GameMain.GameSession.TaskManager.Tasks.Clear();
diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs
index 6f4bf4cf9..a78996803 100644
--- a/Subsurface/Source/GameSession/GameSession.cs
+++ b/Subsurface/Source/GameSession/GameSession.cs
@@ -202,7 +202,7 @@ namespace Barotrauma
{
level.Generate();
- submarine.SetPosition(level.StartPosition - new Vector2(0.0f, 2000.0f));
+ submarine.SetPosition(submarine.FindSpawnPos(level.StartPosition - new Vector2(0.0f, 2000.0f)));
//secondSub.SetPosition(level.EndPosition - new Vector2(0.0f, 2000.0f));
diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs
index 2e66fd529..1217cd4fa 100644
--- a/Subsurface/Source/Items/Components/DockingPort.cs
+++ b/Subsurface/Source/Items/Components/DockingPort.cs
@@ -44,6 +44,12 @@ namespace Barotrauma.Items.Components
private bool docked;
+ public int DockingDir
+ {
+ get { return dockingDir; }
+ set { dockingDir = value; }
+ }
+
[HasDefaultValue("32.0,32.0", false)]
public string DistanceTolerance
{
@@ -150,7 +156,8 @@ namespace Barotrauma.Items.Components
if (target.item.Submarine == item.Submarine)
{
- DebugConsole.ThrowError("Error - tried to a submarine to itself");
+ DebugConsole.ThrowError("Error - tried to dock a submarine to itself");
+ dockingTarget = null;
return;
}
@@ -176,8 +183,9 @@ namespace Barotrauma.Items.Components
dockingDir = IsHorizontal ?
Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
- Math.Sign(item.WorldPosition.Y - dockingTarget.item.WorldPosition.Y);
+ Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y);
dockingTarget.dockingDir = -dockingDir;
+
foreach (WayPoint wp in WayPoint.WayPointList)
{
@@ -199,12 +207,46 @@ namespace Barotrauma.Items.Components
CreateJoint(false);
}
+ public void Lock()
+ {
+ if (dockingTarget==null)
+ {
+ DebugConsole.ThrowError("Error - attempted to lock a docking port that's not connected to anything");
+ return;
+ }
+ else if (joint is WeldJoint)
+ {
+ DebugConsole.ThrowError("Error - attempted to lock a docking port that's already locked");
+ return;
+ }
+
+ dockingDir = IsHorizontal ?
+ Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
+ Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y);
+ dockingTarget.dockingDir = -dockingDir;
+
+ GameMain.World.RemoveJoint(joint);
+
+ PlaySound(ActionType.OnSecondaryUse, item.WorldPosition);
+
+ ConnectWireBetweenPorts();
+
+ CreateJoint(true);
+
+ if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull))
+ {
+ CreateHull();
+
+ //item.NewComponentEvent(this, false, true);
+ }
+ }
+
private void CreateJoint(bool useWeldJoint)
{
Vector2 offset = (IsHorizontal ?
- Vector2.UnitX * Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
- Vector2.UnitY * Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y));
+ Vector2.UnitX * dockingDir :
+ Vector2.UnitY * dockingDir);
offset *= DockedDistance * 0.5f;
Vector2 pos1 = item.WorldPosition + offset;
@@ -491,28 +533,18 @@ namespace Barotrauma.Items.Components
if (!docked)
{
Dock(dockingTarget);
+ if (dockingTarget == null) return;
}
if (joint is DistanceJoint)
{
item.SendSignal(0, "0", "state_out");
+ dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f);
if (Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f)
{
- GameMain.World.RemoveJoint(joint);
-
- PlaySound(ActionType.OnSecondaryUse, item.WorldPosition);
-
- ConnectWireBetweenPorts();
-
- CreateJoint(true);
-
- if (!item.linkedTo.Any(e => e is Hull) && !dockingTarget.item.linkedTo.Any(e => e is Hull))
- {
- CreateHull();
- }
+ Lock();
}
- dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f);
}
else
{
@@ -606,12 +638,14 @@ namespace Barotrauma.Items.Components
if (!item.linkedTo.Any()) return;
- foreach (MapEntity entity in item.linkedTo)
+ List linked = new List(item.linkedTo);
+ foreach (MapEntity entity in linked)
{
var hull = entity as Hull;
if (hull != null)
{
hull.Remove();
+ item.linkedTo.Remove(hull);
continue;
}
@@ -619,6 +653,7 @@ namespace Barotrauma.Items.Components
if (gap != null)
{
gap.Remove();
+ gap.linkedTo.Remove(hull);
continue;
}
@@ -626,10 +661,11 @@ namespace Barotrauma.Items.Components
if (linkedItem == null) continue;
var dockingPort = linkedItem.GetComponent();
- if (dockingPort != null) dockingTarget = dockingPort;
+ if (dockingPort != null)
+ {
+ Dock(dockingPort);
+ }
}
-
- item.linkedTo.Clear();
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f)
diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs
index edb85ccd6..03bb4d26d 100644
--- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs
+++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs
@@ -177,7 +177,7 @@ namespace Barotrauma.Items.Components
Item targetItem;
if ((targetStructure = (targetBody.UserData as Structure)) != null)
{
- if (!fixableEntities.Contains(targetStructure.Name)) return;
+ if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Name)) return;
if (targetStructure.IsPlatform) return;
int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition));
@@ -195,7 +195,7 @@ namespace Barotrauma.Items.Components
1.0f - targetStructure.SectionDamage(sectionIndex) / targetStructure.Health,
Color.Red, Color.Green);
- progressBar.Size = new Vector2(60.0f, 20.0f);
+ if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f);
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess);
diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs
index 964c6edd6..d3ba798bf 100644
--- a/Subsurface/Source/Items/Components/ItemComponent.cs
+++ b/Subsurface/Source/Items/Components/ItemComponent.cs
@@ -544,11 +544,28 @@ namespace Barotrauma.Items.Components
RemoveComponentSpecific();
}
- protected virtual void RemoveComponentSpecific()
+ ///
+ /// Remove the component so that it doesn't appear to exist in the game world (stop sounds, remove bodies etc)
+ /// but don't reset anything that's required for cloning the item
+ ///
+ public void ShallowRemove()
{
+ if (loopingSound != null)
+ {
+ Sounds.SoundManager.Stop(loopingSoundIndex);
+ }
+ ShallowRemoveComponentSpecific();
}
+ protected virtual void ShallowRemoveComponentSpecific()
+ {
+ RemoveComponentSpecific();
+ }
+
+ protected virtual void RemoveComponentSpecific()
+ { }
+
public bool HasRequiredSkills(Character character)
{
Skill temp;
diff --git a/Subsurface/Source/Items/Components/Machines/Controller.cs b/Subsurface/Source/Items/Components/Machines/Controller.cs
index ae10f6b79..65a7530b0 100644
--- a/Subsurface/Source/Items/Components/Machines/Controller.cs
+++ b/Subsurface/Source/Items/Components/Machines/Controller.cs
@@ -26,15 +26,15 @@ namespace Barotrauma.Items.Components
private Direction dir;
- //the x-position where the user walks to when using the controller
- private float userPos;
+ //the position where the user walks to when using the controller
+ //(relative to the position of the item)
+ private Vector2 userPos;
private Camera cam;
private Character character;
- [HasDefaultValue(0.0f, false)]
- public float UserPos
+ public Vector2 UserPos
{
get { return userPos; }
set { userPos = value; }
@@ -45,13 +45,16 @@ namespace Barotrauma.Items.Components
{
limbPositions = new List();
- dir = (Direction)Enum.Parse(typeof(Direction), ToolBox.GetAttributeString(element, "direction", "None"), true);
+ userPos = ToolBox.GetAttributeVector2(element, "UserPos", Vector2.Zero);
+ Enum.TryParse(ToolBox.GetAttributeString(element, "direction", "None"), out dir);
+
foreach (XElement el in element.Elements())
{
if (el.Name != "limbposition") continue;
LimbPos lp = new LimbPos();
+
try
{
lp.limbType = (LimbType)Enum.Parse(typeof(LimbType), el.Attribute("limb").Value, true);
@@ -90,23 +93,34 @@ namespace Barotrauma.Items.Components
character.AnimController.Anim = AnimController.Animation.UsingConstruction;
- if (userPos != 0.0f)
+ if (userPos != Vector2.Zero)
{
float torsoX = character.Position.X;
- Vector2 diff = new Vector2(item.Rect.X + UserPos - torsoX, 0.0f);
+ Vector2 diff = (item.WorldPosition + userPos) - character.WorldPosition;
- if (diff!= Vector2.Zero && diff.Length() > 10.0f)
+ if (character.AnimController.InWater)
{
- //character.AnimController.Anim = AnimController.Animation.None;
-
- character.AnimController.TargetMovement = new Vector2(Math.Sign(diff.X), 0.0f);
- character.AnimController.TargetDir = (Math.Sign(diff.X) == 1) ? Direction.Right : Direction.Left;
- return;
+ if (diff.Length() > 30.0f)
+ {
+ character.AnimController.TargetMovement = Vector2.Clamp(diff*0.01f, -Vector2.One, Vector2.One);
+ character.AnimController.TargetDir = diff.X > 0.0f ? Direction.Right : Direction.Left;
+ }
+ else
+ {
+ character.AnimController.TargetMovement = Vector2.Zero;
+ }
}
else
{
- character.AnimController.TargetMovement = Vector2.Zero;
+ diff.Y = 0.0f;
+ if (diff != Vector2.Zero && diff.Length() > 10.0f)
+ {
+ character.AnimController.TargetMovement = Vector2.Normalize(diff);
+ character.AnimController.TargetDir = diff.X > 0.0f ? Direction.Right : Direction.Left;
+ return;
+ }
+ character.AnimController.TargetMovement = Vector2.Zero;
}
}
@@ -115,6 +129,7 @@ namespace Barotrauma.Items.Components
if (limbPositions.Count == 0) return;
character.AnimController.Anim = AnimController.Animation.UsingConstruction;
+
character.AnimController.ResetPullJoints();
if (dir != 0) character.AnimController.TargetDir = dir;
@@ -256,10 +271,10 @@ namespace Barotrauma.Items.Components
dir = dir == Direction.Left ? Direction.Right : Direction.Left;
}
- if (userPos != 0.0f)
+ if (userPos.X != 0.0f)
{
- float diff = (item.Rect.X + UserPos) - item.Rect.Center.X;
- userPos = item.Rect.Center.X - diff - item.Rect.X;
+ float diff = (item.Rect.X + UserPos.X) - item.Rect.Center.X;
+ userPos.X = item.Rect.Center.X - diff - item.Rect.X;
}
for (int i = 0; i < limbPositions.Count; i++)
diff --git a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
index e8bae85b8..9fa4d9b2c 100644
--- a/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
+++ b/Subsurface/Source/Items/Components/Power/PowerTransfer.cs
@@ -125,6 +125,8 @@ namespace Barotrauma.Items.Components
Item it = recipient.Item;
if (it == null) continue;
+ if (it.Condition <= 0.0f) continue;
+
Powered powered = it.GetComponent();
if (powered == null || !powered.IsActive) continue;
diff --git a/Subsurface/Source/Items/Components/Signal/Connection.cs b/Subsurface/Source/Items/Components/Signal/Connection.cs
index 1b9d048ac..c259ba04b 100644
--- a/Subsurface/Source/Items/Components/Signal/Connection.cs
+++ b/Subsurface/Source/Items/Components/Signal/Connection.cs
@@ -21,7 +21,7 @@ namespace Barotrauma.Items.Components
public Wire[] Wires;
- private Item item;
+ private Item item;
public readonly bool IsOutput;
@@ -30,7 +30,7 @@ namespace Barotrauma.Items.Components
private List effects;
public readonly ushort[] wireId;
-
+
public bool IsPower
{
get;
@@ -64,17 +64,17 @@ namespace Barotrauma.Items.Components
{
panelTexture = Sprite.LoadTexture("Content/Items/connectionpanel.png");
- connector = new Sprite(panelTexture, new Rectangle(470, 102, 19,43), Vector2.Zero, 0.0f);
+ connector = new Sprite(panelTexture, new Rectangle(470, 102, 19, 43), Vector2.Zero, 0.0f);
connector.Origin = new Vector2(9.5f, 10.0f);
- wireVertical = new Sprite(panelTexture, new Rectangle(408, 1, 11, 102), Vector2.Zero, 0.0f);
+ wireVertical = new Sprite(panelTexture, new Rectangle(408, 1, 11, 102), Vector2.Zero, 0.0f);
}
this.item = item;
//recipient = new Connection[MaxLinked];
Wires = new Wire[MaxLinked];
-
+
IsOutput = (element.Name.ToString() == "output");
Name = ToolBox.GetAttributeString(element, "name", (IsOutput) ? "output" : "input");
@@ -92,12 +92,12 @@ namespace Barotrauma.Items.Components
int index = -1;
for (int i = 0; i < MaxLinked; i++)
{
- if (wireId[i]<1) index = i;
+ if (wireId[i] < 1) index = i;
}
if (index == -1) break;
int id = ToolBox.GetAttributeInt(subElement, "w", 0);
- if (id<0) id = 0;
+ if (id < 0) id = 0;
wireId[index] = (ushort)id;
break;
@@ -113,7 +113,7 @@ namespace Barotrauma.Items.Components
{
for (int i = 0; i < MaxLinked; i++)
{
- if (Wires[i]==null) return i;
+ if (Wires[i] == null) return i;
}
return -1;
}
@@ -150,7 +150,7 @@ namespace Barotrauma.Items.Components
}
}
}
-
+
public void AddLink(int index, Wire wire)
{
Wires[index] = wire;
@@ -164,9 +164,9 @@ namespace Barotrauma.Items.Components
public void SendSignal(int stepsTaken, string signal, Item sender, float power)
{
- for (int i = 0; i-1)
+ if (linkIndex > -1)
{
Inventory.draggingItem = c.Wires[linkIndex].Item;
}
@@ -257,21 +257,21 @@ namespace Barotrauma.Items.Components
//outputs are drawn at the right side of the panel, inputs at the left
if (c.IsOutput)
{
- c.Draw(spriteBatch, panel.Item, rightPos,
- new Vector2(rightPos.X - GUI.SmallFont.MeasureString(c.Name).X - 20, rightPos.Y+3),
- rightWirePos,
- mouseInRect, equippedWire != null,
+ c.Draw(spriteBatch, panel.Item, rightPos,
+ new Vector2(rightPos.X - GUI.SmallFont.MeasureString(c.Name).X - 20, rightPos.Y + 3),
+ rightWirePos,
+ mouseInRect, equippedWire,
wireInterval);
rightPos.Y += 30;
- rightWirePos.Y += c.Wires.Count(w => w!=null) * wireInterval;
+ rightWirePos.Y += c.Wires.Count(w => w != null) * wireInterval;
}
else
{
c.Draw(spriteBatch, panel.Item, leftPos,
- new Vector2(leftPos.X + 20, leftPos.Y-12),
- leftWirePos,
- mouseInRect, equippedWire != null,
+ new Vector2(leftPos.X + 20, leftPos.Y - 12),
+ leftWirePos,
+ mouseInRect, equippedWire,
wireInterval);
leftPos.Y += 30;
@@ -279,14 +279,14 @@ namespace Barotrauma.Items.Components
//leftWireX -= wireInterval;
}
}
-
+
if (draggingConnected != null)
{
- DrawWire(spriteBatch, draggingConnected, draggingConnected.Item, PlayerInput.MousePosition, new Vector2(x + width / 2, y + height), mouseInRect, false);
+ DrawWire(spriteBatch, draggingConnected, draggingConnected.Item, PlayerInput.MousePosition, new Vector2(x + width / 2, y + height), mouseInRect, null);
if (!PlayerInput.LeftButtonHeld())
{
- //panel.Item.CreateServerEvent(panel, true, true);
+ //panel.Item.NewComponentEvent(panel, true, true);
//draggingConnected.Drop(Character);
draggingConnected = null;
}
@@ -294,61 +294,49 @@ namespace Barotrauma.Items.Components
//if the Character using the panel has a wire item equipped
//and the wire hasn't been connected yet, draw it on the panel
- if (equippedWire!=null)
+ if (equippedWire != null)
{
if (panel.Connections.Find(c => c.Wires.Contains(equippedWire)) == null)
{
DrawWire(spriteBatch, equippedWire, equippedWire.Item,
new Vector2(x + width / 2, y + height - 100),
- new Vector2(x + width / 2, y + height), mouseInRect, false);
+ new Vector2(x + width / 2, y + height), mouseInRect, null);
if (draggingConnected == equippedWire) Inventory.draggingItem = equippedWire.Item;
-
- //break;
}
}
//stop dragging a wire item if cursor is outside the panel
if (mouseInRect) Inventory.draggingItem = null;
- if (draggingConnected != null)
- {
- DrawWire(spriteBatch, draggingConnected, draggingConnected.Item, PlayerInput.MousePosition, new Vector2(x + width / 2, y + height), mouseInRect, false);
-
- if (!PlayerInput.LeftButtonHeld())
- {
- //draggingConnected.Drop(Character);
- draggingConnected = null;
- }
- }
spriteBatch.Draw(panelTexture, panelRect, new Rectangle(0, 0, width, height), Color.White);
}
- private void Draw(SpriteBatch spriteBatch, Item item, Vector2 position, Vector2 labelPos, Vector2 wirePosition, bool mouseIn, bool wireEquipped, float wireInterval)
+ private void Draw(SpriteBatch spriteBatch, Item item, Vector2 position, Vector2 labelPos, Vector2 wirePosition, bool mouseIn, Wire equippedWire, float wireInterval)
{
//spriteBatch.DrawString(GUI.SmallFont, Name, new Vector2(labelPos.X, labelPos.Y-10), Color.White);
- GUI.DrawString(spriteBatch, labelPos, Name, IsPower ? Color.Red : Color.White, Color.Black,0, GUI.SmallFont);
+ GUI.DrawString(spriteBatch, labelPos, Name, IsPower ? Color.Red : Color.White, Color.Black, 0, GUI.SmallFont);
- GUI.DrawRectangle(spriteBatch, new Rectangle((int)position.X-10, (int)position.Y-10, 20, 20), Color.White);
+ GUI.DrawRectangle(spriteBatch, new Rectangle((int)position.X - 10, (int)position.Y - 10, 20, 20), Color.White);
spriteBatch.Draw(panelTexture, position - new Vector2(16.0f, 16.0f), new Rectangle(64, 256, 32, 32), Color.White);
-
- for (int i = 0; i w != null && w != draggingConnected))
{
- spriteBatch.Draw(panelTexture, position - new Vector2(16.0f, 16.0f), new Rectangle(screwIndex*32, 256, 32, 32), Color.White);
+ spriteBatch.Draw(panelTexture, position - new Vector2(16.0f, 16.0f), new Rectangle(screwIndex * 32, 256, 32, 32), Color.White);
}
-
+
}
- private static void DrawWire(SpriteBatch spriteBatch, Wire wire, Item item, Vector2 end, Vector2 start, bool mouseIn, bool wireEquipped)
+ private static void DrawWire(SpriteBatch spriteBatch, Wire wire, Item item, Vector2 end, Vector2 start, bool mouseIn, Wire equippedWire)
{
if (draggingConnected == wire)
{
if (!mouseIn) return;
end = PlayerInput.MousePosition;
- start.X = (start.X+end.X)/2.0f;
+ start.X = (start.X + end.X) / 2.0f;
}
int textX = (int)start.X;
@@ -389,28 +377,30 @@ namespace Barotrauma.Items.Components
else
textX += 10;
- float alpha = wireEquipped ? 0.5f : 1.0f;
+ bool canDrag = equippedWire == null || equippedWire == wire;
- bool mouseOn =
- !wireEquipped &&
+ float alpha = canDrag ? 1.0f : 0.5f;
+
+ bool mouseOn =
+ canDrag &&
((PlayerInput.MousePosition.X > Math.Min(start.X, end.X) &&
PlayerInput.MousePosition.X < Math.Max(start.X, end.X) &&
MathUtils.LineToPointDistance(start, end, PlayerInput.MousePosition) < 6) ||
- Vector2.Distance(end, PlayerInput.MousePosition)<20.0f ||
- new Rectangle((start.X < end.X) ? textX-100 : textX, (int)start.Y-5, 100, 14).Contains(PlayerInput.MousePosition));
+ Vector2.Distance(end, PlayerInput.MousePosition) < 20.0f ||
+ new Rectangle((start.X < end.X) ? textX - 100 : textX, (int)start.Y - 5, 100, 14).Contains(PlayerInput.MousePosition));
- string label = wire.Locked ? item.Name +"\n(Locked)" : item.Name;
+ string label = wire.Locked ? item.Name + "\n(Locked)" : item.Name;
- GUI.DrawString(spriteBatch,
- new Vector2(start.X < end.X ? textX-GUI.SmallFont.MeasureString(label).X : textX,start.Y -5.0f),
- label,
- (mouseOn ? Color.Gold : Color.White) * (wire.Locked ? 0.6f : 1.0f), Color.Black * 0.8f,
+ GUI.DrawString(spriteBatch,
+ new Vector2(start.X < end.X ? textX - GUI.SmallFont.MeasureString(label).X : textX, start.Y - 5.0f),
+ label,
+ (mouseOn ? Color.Gold : Color.White) * (wire.Locked ? 0.6f : 1.0f), Color.Black * 0.8f,
3, GUI.SmallFont);
var wireEnd = end + Vector2.Normalize(start - end) * 30.0f;
float dist = Vector2.Distance(start, wireEnd);
-
+
if (mouseOn)
{
spriteBatch.Draw(wireVertical.Texture, new Rectangle(wireEnd.ToPoint(), new Point(18, (int)dist)), wireVertical.SourceRect,
@@ -427,9 +417,9 @@ namespace Barotrauma.Items.Components
SpriteEffects.None,
0.0f);
- connector.Draw(spriteBatch, end, Color.White, new Vector2(10.0f, 10.0f), MathUtils.VectorToAngle(end - start)+MathHelper.PiOver2);
+ connector.Draw(spriteBatch, end, Color.White, new Vector2(10.0f, 10.0f), MathUtils.VectorToAngle(end - start) + MathHelper.PiOver2);
- if (draggingConnected == null && !wireEquipped)
+ if (draggingConnected == null && canDrag)
{
if (mouseOn)
{
@@ -438,9 +428,8 @@ namespace Barotrauma.Items.Components
if (!wire.Locked)
{
//start dragging the wire
- if (PlayerInput.LeftButtonHeld()) draggingConnected = wire;
+ if (PlayerInput.LeftButtonHeld()) draggingConnected = wire;
}
-
}
}
}
@@ -449,25 +438,25 @@ namespace Barotrauma.Items.Components
{
XElement newElement = new XElement(IsOutput ? "output" : "input", new XAttribute("name", Name));
- Array.Sort(Wires, delegate(Wire wire1, Wire wire2)
+ Array.Sort(Wires, delegate(Wire wire1, Wire wire2)
{
if (wire1 == null) return 1;
if (wire2 == null) return -1;
- return wire1.Item.ID.CompareTo(wire2.Item.ID);
+ return wire1.Item.ID.CompareTo(wire2.Item.ID);
});
- for (int i = 0; i < MaxLinked; i++ )
+ for (int i = 0; i < MaxLinked; i++)
{
if (Wires[i] == null) continue;
-
+
//Connection recipient = wires[i].OtherConnection(this);
//int connectionIndex = recipient.item.Connections.FindIndex(x => x == recipient);
- newElement.Add(new XElement("link",
- new XAttribute("w", Wires[i].Item.ID.ToString())));
+ newElement.Add(new XElement("link",
+ new XAttribute("w", Wires[i].Item.ID.ToString())));
}
-
- parentElement.Add(newElement);
+
+ parentElement.Add(newElement);
}
@@ -486,7 +475,7 @@ namespace Barotrauma.Items.Components
if (wireItem == null) continue;
Wires[i] = wireItem.GetComponent();
- if (Wires[i]!=null)
+ if (Wires[i] != null)
{
if (Wires[i].Item.body != null) Wires[i].Item.body.Enabled = false;
Wires[i].Connect(this, false, true);
@@ -499,4 +488,4 @@ namespace Barotrauma.Items.Components
}
}
-}
+}
\ No newline at end of file
diff --git a/Subsurface/Source/Items/Components/Signal/ConnectionPanel.cs b/Subsurface/Source/Items/Components/Signal/ConnectionPanel.cs
index 7566f35ad..9ca463b7e 100644
--- a/Subsurface/Source/Items/Components/Signal/ConnectionPanel.cs
+++ b/Subsurface/Source/Items/Components/Signal/ConnectionPanel.cs
@@ -156,6 +156,10 @@ namespace Barotrauma.Items.Components
}
}
}
+
+ protected override void ShallowRemoveComponentSpecific()
+ {
+ }
}
}
diff --git a/Subsurface/Source/Items/Components/Signal/Wire.cs b/Subsurface/Source/Items/Components/Signal/Wire.cs
index 75c674380..37a8d7b5c 100644
--- a/Subsurface/Source/Items/Components/Signal/Wire.cs
+++ b/Subsurface/Source/Items/Components/Signal/Wire.cs
@@ -1,5 +1,6 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -63,8 +64,11 @@ namespace Barotrauma.Items.Components
private Vector2 newNodePos;
+
+
private static Wire draggingWire;
private static int? selectedNodeIndex;
+ private static int? highlightedNodeIndex;
public bool Hidden, Locked;
@@ -89,7 +93,7 @@ namespace Barotrauma.Items.Components
IsActive = false;
}
-
+
public Connection OtherConnection(Connection connection)
{
if (connection == null) return null;
@@ -191,7 +195,14 @@ namespace Barotrauma.Items.Components
CleanNodes();
}
- Drawable = nodes.Any();
+ if (!loading)
+ {
+ //Item.NewComponentEvent(this, true, true);
+ //the wire is active if only one end has been connected
+ IsActive = connections[0] == null ^ connections[1] == null;
+ }
+
+ Drawable = IsActive || nodes.Any();
UpdateSections();
return true;
@@ -202,7 +213,6 @@ namespace Barotrauma.Items.Components
ClearConnections();
IsActive = true;
- //Drawable = true;
}
public override void Unequip(Character character)
@@ -227,7 +237,7 @@ namespace Barotrauma.Items.Components
if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine;
if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine;
- if (item.Submarine != sub && Screen.Selected != GameMain.EditMapScreen)
+ if ((item.Submarine != sub || sub == null) && Screen.Selected != GameMain.EditMapScreen)
{
ClearConnections();
return;
@@ -260,7 +270,7 @@ namespace Barotrauma.Items.Components
UpdateSections();
}
- Drawable = sections.Count > 0;
+ Drawable = IsActive || sections.Count > 0;
}
public override bool Pick(Character picker)
@@ -303,7 +313,7 @@ namespace Barotrauma.Items.Components
{
sections.Add(new WireSection(nodes[i], nodes[i + 1]));
}
- Drawable = sections.Count > 0;
+ Drawable = IsActive || sections.Count > 0;
}
private void ClearConnections()
@@ -384,7 +394,7 @@ namespace Barotrauma.Items.Components
public void Draw(SpriteBatch spriteBatch, bool editing)
{
- if (sections.Count == 0)
+ if (sections.Count == 0 && !IsActive)
{
Drawable = false;
return;
@@ -396,7 +406,7 @@ namespace Barotrauma.Items.Components
drawOffset = item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition;
}
- float depth = wireSprite.Depth + ((item.ID % 100) * 0.00001f);
+ float depth = item.IsSelected ? 0.0f : wireSprite.Depth + ((item.ID % 100) * 0.00001f);
if (item.IsHighlighted)
{
@@ -417,8 +427,8 @@ namespace Barotrauma.Items.Components
{
section.Draw(spriteBatch, item.Color, drawOffset, depth, 0.3f);
}
-
- if (IsActive && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance)
+
+ if (IsActive && nodes.Count > 0 && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance)
{
WireSection.Draw(
spriteBatch,
@@ -428,78 +438,198 @@ namespace Barotrauma.Items.Components
depth,
0.3f);
}
-
- if (!editing || !PlayerInput.MouseInsideWindow || !GameMain.EditMapScreen.WiringMode) return;
- if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null) return;
+
+ if (!editing || !GameMain.EditMapScreen.WiringMode) return;
for (int i = 0; i < nodes.Count; i++)
{
- Vector2 worldPos = nodes[i];
- if (item.Submarine != null) worldPos += item.Submarine.Position + item.Submarine.HiddenSubPosition;
- worldPos.Y = -worldPos.Y;
+ Vector2 drawPos = nodes[i];
+ if (item.Submarine != null) drawPos += item.Submarine.Position + item.Submarine.HiddenSubPosition;
+ drawPos.Y = -drawPos.Y;
- GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-3, -3), new Vector2(6, 6), item.Color, true, 0.0f);
-
- if (IsActive) continue;
-
- if (GUIComponent.MouseOn != null ||
- Vector2.Distance(GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), new Vector2(worldPos.X, -worldPos.Y)) > 10.0f)
+ if (item.IsSelected)
{
- continue;
+ GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-5, -5), new Vector2(10, 10), item.Color, true, 0.0f);
+
+ if (highlightedNodeIndex == i)
+ {
+ GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f);
+ }
}
-
- GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-10, -10), new Vector2(20, 20), Color.Red, false, 0.0f);
-
- if (selectedNodeIndex == null && draggingWire == null)// && !MapEntity.SelectedAny)
+ else
{
- if (PlayerInput.LeftButtonDown())
- {
- MapEntity.DisableSelect = true;
- MapEntity.SelectEntity(item);
- draggingWire = this;
- selectedNodeIndex = i;
- break;
- }
- else if (PlayerInput.RightButtonClicked())
- {
- nodes.RemoveAt(i);
- break;
- }
+ GUI.DrawRectangle(spriteBatch, drawPos + new Vector2(-3, -3), new Vector2(6, 6), item.Color, true, 0.0f);
}
}
+ }
- if (PlayerInput.LeftButtonHeld())
+ public static void UpdateEditing(List wires)
+ {
+ //dragging a node of some wire
+ if (draggingWire != null)
{
- if (selectedNodeIndex != null && draggingWire == this)
+ //cancel dragging
+ if (!PlayerInput.LeftButtonHeld())
+ {
+ draggingWire = null;
+ selectedNodeIndex = null;
+ }
+ //update dragging
+ else
{
MapEntity.DisableSelect = true;
- //Nodes[(int)selectedNodeIndex] = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition)-Submarine.HiddenSubPosition+Submarine.Loaded.Position;
-
Submarine sub = null;
- if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine;
- if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine;
+ if (draggingWire.connections[0] != null && draggingWire.connections[0].Item.Submarine != null) sub = draggingWire.connections[0].Item.Submarine;
+ if (draggingWire.connections[1] != null && draggingWire.connections[1].Item.Submarine != null) sub = draggingWire.connections[1].Item.Submarine;
Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - sub.HiddenSubPosition - sub.Position;// Nodes[(int)selectedNodeIndex];
nodeWorldPos.X = MathUtils.Round(nodeWorldPos.X, Submarine.GridSize.X / 2.0f);
nodeWorldPos.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f);
- //if (item.Submarine != null) nodeWorldPos += item.Submarine.Position;
+ draggingWire.nodes[(int)selectedNodeIndex] = nodeWorldPos;
+ draggingWire.UpdateSections();
- nodes[(int)selectedNodeIndex] = nodeWorldPos;
- UpdateSections();
+ MapEntity.SelectEntity(draggingWire.item);
+ }
- MapEntity.SelectEntity(item);
+ return;
+ }
+
+ //a wire has been selected -> check if we should start dragging one of the nodes
+ float nodeSelectDist = 10, sectionSelectDist = 5;
+ highlightedNodeIndex = null;
+ if (MapEntity.SelectedList.Count == 1 && MapEntity.SelectedList[0] is Item)
+ {
+ Wire selectedWire = ((Item)MapEntity.SelectedList[0]).GetComponent();
+
+ if (selectedWire != null)
+ {
+ Vector2 mousePos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
+ if (selectedWire.item.Submarine != null) mousePos -= (selectedWire.item.Submarine.Position + selectedWire.item.Submarine.HiddenSubPosition);
+
+ //left click while holding ctrl -> check if the cursor is on a wire section,
+ //and add a new node if it is
+ if (PlayerInput.KeyDown(Keys.RightControl) || PlayerInput.KeyDown(Keys.LeftControl))
+ {
+ if (PlayerInput.LeftButtonClicked())
+ {
+ float temp = 0.0f;
+ int closestSectionIndex = selectedWire.GetClosestSectionIndex(mousePos, sectionSelectDist, out temp);
+
+ if (closestSectionIndex > -1)
+ {
+ selectedWire.nodes.Insert(closestSectionIndex + 1, mousePos);
+ selectedWire.UpdateSections();
+ }
+ }
+ }
+ else
+ {
+ //check if close enough to a node
+ float temp = 0.0f;
+ int closestIndex = selectedWire.GetClosestNodeIndex(mousePos, nodeSelectDist, out temp);
+ if (closestIndex > -1)
+ {
+ highlightedNodeIndex = closestIndex;
+ //start dragging the node
+ if (PlayerInput.LeftButtonHeld())
+ {
+ draggingWire = selectedWire;
+ selectedNodeIndex = closestIndex;
+ }
+ //remove the node
+ else if (PlayerInput.RightButtonClicked() && closestIndex > 0 && closestIndex < selectedWire.nodes.Count - 1)
+ {
+ selectedWire.nodes.RemoveAt(closestIndex);
+ selectedWire.UpdateSections();
+ }
+ }
+ }
}
}
- else
+
+ //check which wire is highlighted with the cursor
+ Wire highlighted = null;
+ float closestDist = 0.0f;
+ foreach (Wire w in wires)
{
- selectedNodeIndex = null;
- draggingWire = null;
+ Vector2 mousePos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
+ if (w.item.Submarine != null) mousePos -= (w.item.Submarine.Position + w.item.Submarine.HiddenSubPosition);
+
+ float dist = 0.0f;
+ if (w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out dist) > -1)
+ {
+ highlighted = w;
+ closestDist = dist;
+ }
+
+ if (w.GetClosestSectionIndex(mousePos, highlighted == null ? sectionSelectDist : closestDist, out dist) > -1)
+ {
+ highlighted = w;
+ closestDist = dist;
+ }
+
+ }
+
+
+ if (highlighted != null)
+ {
+ highlighted.item.IsHighlighted = true;
+
+ if (PlayerInput.LeftButtonClicked())
+ {
+ MapEntity.DisableSelect = true;
+ MapEntity.SelectEntity(highlighted.item);
+ }
}
}
+ private int GetClosestNodeIndex(Vector2 pos, float maxDist, out float closestDist)
+ {
+ closestDist = 0.0f;
+ int closestIndex = -1;
+
+ for (int i = 0; i < nodes.Count; i++)
+ {
+ float dist = Vector2.Distance(nodes[i], pos);
+ if (dist > maxDist) continue;
+
+ if (closestIndex == -1 || dist < closestDist)
+ {
+ closestIndex = i;
+ closestDist = dist;
+ }
+ }
+
+ return closestIndex;
+ }
+
+ private int GetClosestSectionIndex(Vector2 mousePos, float maxDist, out float closestDist)
+ {
+ closestDist = 0.0f;
+ int closestIndex = -1;
+
+ for (int i = 0; i < nodes.Count-1; i++)
+ {
+ if ((Math.Abs(nodes[i].X - nodes[i + 1].X)<5 || Math.Sign(mousePos.X - nodes[i].X) != Math.Sign(mousePos.X - nodes[i + 1].X)) &&
+ (Math.Abs(nodes[i].Y - nodes[i + 1].Y)<5 || Math.Sign(mousePos.Y - nodes[i].Y) != Math.Sign(mousePos.Y - nodes[i + 1].Y)))
+ {
+ float dist = MathUtils.LineToPointDistance(nodes[i], nodes[i + 1], mousePos);
+ if (dist > maxDist) continue;
+
+ if (closestIndex == -1 || dist < closestDist)
+ {
+ closestIndex = i;
+ closestDist = dist;
+ }
+ }
+ }
+
+ return closestIndex;
+ }
+
public override void FlipX()
{
for (int i = 0; i < nodes.Count; i++)
@@ -555,7 +685,20 @@ namespace Barotrauma.Items.Components
}
Drawable = nodes.Any();
+ }
+ protected override void ShallowRemoveComponentSpecific()
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ if (connections[i] == null) continue;
+ int wireIndex = connections[i].FindWireIndex(item);
+
+ if (wireIndex > -1)
+ {
+ connections[i].AddLink(wireIndex, null);
+ }
+ }
}
protected override void RemoveComponentSpecific()
diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs
index 1742e6832..0967c652e 100644
--- a/Subsurface/Source/Items/Item.cs
+++ b/Subsurface/Source/Items/Item.cs
@@ -888,6 +888,11 @@ namespace Barotrauma
}
}
+ public override bool IsVisible(Rectangle worldView)
+ {
+ return drawableComponents.Count > 0 || body == null || body.Enabled;
+ }
+
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (!Visible) return;
@@ -1137,28 +1142,40 @@ namespace Barotrauma
foreach (ItemComponent ic in components)
{
- ic.DrawHUD(spriteBatch, character);
+ if (ic.CanBeSelected) ic.DrawHUD(spriteBatch, character);
}
}
public override void AddToGUIUpdateList()
{
- if (condition <= 0.0f)
- {
- FixRequirement.AddToGUIUpdateList();
- return;
- }
- if (HasInGameEditableProperties)
+ if (Screen.Selected is EditMapScreen)
{
if (editingHUD != null) editingHUD.AddToGUIUpdateList();
}
- foreach (ItemComponent ic in components)
+ else
{
- ic.AddToGUIUpdateList();
+ if (HasInGameEditableProperties)
+ {
+ if (editingHUD != null) editingHUD.AddToGUIUpdateList();
+ }
+ }
+
+ if (Character.Controlled != null && Character.Controlled.SelectedConstruction == this)
+ {
+ if (condition <= 0.0f)
+ {
+ FixRequirement.AddToGUIUpdateList();
+ return;
+ }
+
+ foreach (ItemComponent ic in components)
+ {
+ if (ic.CanBeSelected) ic.AddToGUIUpdateList();
+ }
}
- if (Screen.Selected is EditMapScreen && editingHUD != null) editingHUD.AddToGUIUpdateList();
}
+
public virtual void UpdateHUD(Camera cam, Character character)
{
if (condition <= 0.0f)
@@ -1949,16 +1966,22 @@ namespace Barotrauma
GameMain.Client.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.ComponentState, index });
}
+ ///
+ /// Remove the item so that it doesn't appear to exist in the game world (stop sounds, remove bodies etc)
+ /// but don't reset anything that's required for cloning the item
+ ///
public override void ShallowRemove()
{
base.ShallowRemove();
Removed = true;
+
foreach (ItemComponent ic in components)
{
- ic.Remove();
+ ic.ShallowRemove();
}
ItemList.Remove(this);
+
if (body != null)
{
body.Remove();
@@ -2000,4 +2023,4 @@ namespace Barotrauma
}
}
-}
+}
\ No newline at end of file
diff --git a/Subsurface/Source/Map/Explosion.cs b/Subsurface/Source/Map/Explosion.cs
index de65641be..ba3a750f3 100644
--- a/Subsurface/Source/Map/Explosion.cs
+++ b/Subsurface/Source/Map/Explosion.cs
@@ -119,15 +119,21 @@ namespace Barotrauma
foreach (Limb limb in c.AnimController.Limbs)
{
float dist = Vector2.Distance(limb.WorldPosition, worldPosition);
+
+ //calculate distance from the "outer surface" of the physics body
+ //doesn't take the rotation of the limb into account, but should be accurate enough for this purpose
+ float limbRadius = Math.Max(Math.Max(limb.body.width * 0.5f, limb.body.height * 0.5f), limb.body.radius);
+ dist = Math.Max(0.0f, dist - FarseerPhysics.ConvertUnits.ToDisplayUnits(limbRadius));
if (dist > range) continue;
float distFactor = 1.0f - dist / range;
- if (limb.WorldPosition == worldPosition) continue;
-
c.AddDamage(limb.WorldPosition, DamageType.None,
damage / c.AnimController.Limbs.Length * distFactor, 0.0f, stun * distFactor, false);
+
+ if (limb.WorldPosition == worldPosition) continue;
+
if (force > 0.0f)
{
limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.WorldPosition - worldPosition) * distFactor * force);
@@ -136,11 +142,12 @@ namespace Barotrauma
}
}
- public static void RangedStructureDamage(Vector2 worldPosition, float worldRange, float damage)
+ ///
+ /// Returns a dictionary where the keys are the structures that took damage and the values are the amount of damage taken
+ ///
+ public static Dictionary RangedStructureDamage(Vector2 worldPosition, float worldRange, float damage)
{
- List structureList = new List();
-
-
+ List structureList = new List();
float dist = 600.0f;
foreach (MapEntity entity in MapEntity.mapEntityList)
{
@@ -155,14 +162,28 @@ namespace Barotrauma
}
}
+ Dictionary damagedStructures = new Dictionary();
foreach (Structure structure in structureList)
{
for (int i = 0; i < structure.SectionCount; i++)
{
float distFactor = 1.0f - (Vector2.Distance(structure.SectionPosition(i, true), worldPosition) / worldRange);
- if (distFactor > 0.0f) structure.AddDamage(i, damage * distFactor);
- }
+ if (distFactor <= 0.0f) continue;
+
+ structure.AddDamage(i, damage * distFactor);
+
+ if (damagedStructures.ContainsKey(structure))
+ {
+ damagedStructures[structure] += damage * distFactor;
+ }
+ else
+ {
+ damagedStructures.Add(structure, damage * distFactor);
+ }
+ }
}
+
+ return damagedStructures;
}
}
}
diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs
index b99a83ddf..f7b23a11b 100644
--- a/Subsurface/Source/Map/Gap.cs
+++ b/Subsurface/Source/Map/Gap.cs
@@ -80,6 +80,14 @@ namespace Barotrauma
}
}
+ public override string Name
+ {
+ get
+ {
+ return "Gap";
+ }
+ }
+
public override bool SelectableInEditor
{
get
@@ -197,7 +205,13 @@ namespace Barotrauma
Color clr = (open == 0.0f) ? Color.Red : Color.Cyan;
if (isHighlighted) clr = Color.Gold;
- GUI.DrawRectangle(sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height), clr * 0.5f, true,0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
+ float depth = (ID % 255) * 0.000001f;
+
+ GUI.DrawRectangle(
+ sb, new Rectangle(WorldRect.X, -WorldRect.Y, rect.Width, rect.Height),
+ clr * 0.5f, true,
+ depth,
+ (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
for (int i = 0; i < linkedTo.Count; i++)
{
@@ -209,10 +223,10 @@ namespace Barotrauma
arrowPos += new Vector2(dir.X * (WorldRect.Width / 2 + 10), dir.Y * (WorldRect.Height / 2 + 10));
GUI.Arrow.Draw(sb,
- arrowPos,
- clr * 0.8f,
+ arrowPos, clr * 0.8f,
GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2,
- isHorizontal ? new Vector2(rect.Height / 16.0f, 1.0f) : new Vector2(rect.Width / 16.0f, 1.0f));
+ isHorizontal ? new Vector2(rect.Height / 16.0f, 1.0f) : new Vector2(rect.Width / 16.0f, 1.0f),
+ SpriteEffects.None, depth);
}
if (IsSelected)
@@ -222,7 +236,7 @@ namespace Barotrauma
new Vector2(rect.Width + 10, rect.Height + 10),
Color.Red,
false,
- 0,
+ depth,
(int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
}
}
diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs
index d68135eaf..95a1bf639 100644
--- a/Subsurface/Source/Map/Hull.cs
+++ b/Subsurface/Source/Map/Hull.cs
@@ -596,7 +596,7 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch,
new Vector2(drawRect.X, -drawRect.Y),
new Vector2(rect.Width, rect.Height),
- Color.Blue, false, 0, (int)Math.Max((1.5f / Screen.Selected.Cam.Zoom), 1.0f));
+ Color.Blue, false, (ID % 255) * 0.000001f, (int)Math.Max((1.5f / Screen.Selected.Cam.Zoom), 1.0f));
GUI.DrawRectangle(spriteBatch,
new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height),
@@ -607,7 +607,6 @@ namespace Barotrauma
spriteBatch.DrawString(GUI.SmallFont, "Pressure: " + ((int)pressure - rect.Y).ToString() +
" - Oxygen: " + ((int)OxygenPercentage), new Vector2(drawRect.X + 5, -drawRect.Y + 5), Color.White);
spriteBatch.DrawString(GUI.SmallFont, volume + " / " + FullVolume, new Vector2(drawRect.X + 5, -drawRect.Y + 20), Color.White);
-
}
if ((IsSelected || isHighlighted) && editing)
diff --git a/Subsurface/Source/Map/Levels/CaveGenerator.cs b/Subsurface/Source/Map/Levels/CaveGenerator.cs
index 539cb595c..542ba571c 100644
--- a/Subsurface/Source/Map/Levels/CaveGenerator.cs
+++ b/Subsurface/Source/Map/Levels/CaveGenerator.cs
@@ -348,9 +348,9 @@ namespace Barotrauma
return pathCells;
}
- public static List GeneratePolygons(List cells, out List verticeList, bool setSolid=true)
+ public static List GeneratePolygons(List cells, out List verticeList, bool setSolid=true)
{
- verticeList = new List();
+ verticeList = new List();
var bodies = new List();
List tempVertices = new List();
@@ -388,7 +388,12 @@ namespace Barotrauma
{
foreach (Vector2 vertex in triangles[i])
{
- verticeList.Add(new VertexPositionColor(new Vector3(vertex, 0.0f), Color.Black));
+ //shift the coordinates around a bit to make the texture repetition less obvious
+ Vector2 uvCoords = new Vector2(
+ vertex.X / 2000.0f + (float)Math.Sin(vertex.X / 500.0f) * 0.15f,
+ vertex.Y / 2000.0f + (float)Math.Sin(vertex.Y / 700.0f) * 0.15f);
+
+ verticeList.Add(new VertexPositionTexture(new Vector3(vertex, 1.0f), uvCoords));
}
}
diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs
index a48a4ca3d..03496ccdc 100644
--- a/Subsurface/Source/Map/Levels/Level.cs
+++ b/Subsurface/Source/Map/Levels/Level.cs
@@ -183,8 +183,12 @@ namespace Barotrauma
float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3;
GameMain.LightManager.AmbientLight = new Color(backgroundColor * (10.0f / avgValue), 1.0f);
- float minWidth = Submarine.MainSub == null ? 0.0f : Math.Max(Submarine.MainSub.Borders.Width, Submarine.MainSub.Borders.Height);
- minWidth = Math.Max(minWidth, 6500.0f);
+ float minWidth = 6500.0f;
+ if (Submarine.MainSub != null)
+ {
+ Rectangle dockedSubBorders = Submarine.MainSub.GetDockedBorders();
+ minWidth = Math.Max(minWidth, Math.Max(dockedSubBorders.Width, dockedSubBorders.Height));
+ }
startPosition = new Vector2(
Rand.Range(minWidth, minWidth * 2, false),
@@ -437,7 +441,7 @@ namespace Barotrauma
List cellsWithBody = new List(cells);
- List bodyVertices;
+ List bodyVertices;
bodies = CaveGenerator.GeneratePolygons(cellsWithBody, out bodyVertices);
renderer.SetBodyVertices(bodyVertices.ToArray());
@@ -692,6 +696,8 @@ namespace Barotrauma
int iter = 0;
+ ruinPos.Y = Math.Min(borders.Y + borders.Height - ruinSize.Y/2, ruinPos.Y);
+
while (mainPath.Any(p => Vector2.Distance(ruinPos, p.Center) < ruinRadius * 2.0f))
{
Vector2 weighedPathPos = ruinPos;
@@ -711,6 +717,7 @@ namespace Barotrauma
//}
weighedPathPos += moveAmount;
+ weighedPathPos.Y = Math.Min(borders.Y + borders.Height - ruinSize.Y / 2, weighedPathPos.Y);
}
ruinPos = weighedPathPos;
@@ -743,10 +750,18 @@ namespace Barotrauma
{
var tooClose = GetTooCloseCells(ruinShape.Rect.Center.ToVector2(), Math.Max(ruinShape.Rect.Width, ruinShape.Rect.Height));
- tooClose.ForEach(c =>
+ foreach (VoronoiCell cell in tooClose)
{
- if (c.edges.Any(e => ruinShape.Rect.Contains(e.point1) || ruinShape.Rect.Contains(e.point2))) c.CellType = CellType.Empty;
- });
+ if (cell.CellType == CellType.Empty) continue;
+ foreach (GraphEdge e in cell.edges)
+ {
+ if (MathUtils.GetLineRectangleIntersection(e.point1, e.point2, ruinShape.Rect) != null)
+ {
+ cell.CellType = CellType.Empty;
+ break;
+ }
+ }
+ }
}
}
diff --git a/Subsurface/Source/Map/Levels/LevelRenderer.cs b/Subsurface/Source/Map/Levels/LevelRenderer.cs
index 0910925c2..3c1cb824a 100644
--- a/Subsurface/Source/Map/Levels/LevelRenderer.cs
+++ b/Subsurface/Source/Map/Levels/LevelRenderer.cs
@@ -11,7 +11,7 @@ namespace Barotrauma
{
class LevelRenderer : IDisposable
{
- private static BasicEffect basicEffect;
+ private static BasicEffect wallEdgeEffect, wallCenterEffect;
private static Sprite background, backgroundTop;
private static Sprite dustParticles;
@@ -39,14 +39,29 @@ namespace Barotrauma
dustParticles = new Sprite("Content/Map/dustparticles.png", Vector2.Zero);
}
- if (basicEffect == null)
+ if (wallEdgeEffect == null)
{
- basicEffect = new BasicEffect(GameMain.CurrGraphicsDevice);
- basicEffect.VertexColorEnabled = false;
-
- basicEffect.TextureEnabled = true;
- basicEffect.Texture = TextureLoader.FromFile("Content/Map/iceWall.png");
+ wallEdgeEffect = new BasicEffect(GameMain.CurrGraphicsDevice)
+ {
+ DiffuseColor = new Vector3(0.8f, 0.8f, 0.8f),
+ VertexColorEnabled = false,
+ TextureEnabled = true,
+ Texture = shaftTexture
+ };
+ wallEdgeEffect.CurrentTechnique = wallEdgeEffect.Techniques["BasicEffect_Texture"];
}
+
+ if (wallCenterEffect == null)
+ {
+ wallCenterEffect = new BasicEffect(GameMain.CurrGraphicsDevice)
+ {
+ VertexColorEnabled = false,
+ TextureEnabled = true,
+ Texture = backgroundTop.Texture
+ };
+ wallCenterEffect.CurrentTechnique = wallCenterEffect.Techniques["BasicEffect_Texture"];
+ }
+
if (backgroundSpriteManager==null)
{
@@ -79,9 +94,9 @@ namespace Barotrauma
wallVertices.SetData(vertices);
}
- public void SetBodyVertices(VertexPositionColor[] vertices)
+ public void SetBodyVertices(VertexPositionTexture[] vertices)
{
- bodyVertices = new VertexBuffer(GameMain.CurrGraphicsDevice, VertexPositionColor.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
+ bodyVertices = new VertexBuffer(GameMain.CurrGraphicsDevice, VertexPositionTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
bodyVertices.SetData(vertices);
}
@@ -96,21 +111,20 @@ namespace Barotrauma
if (backgroundPos.Y < 1024)
{
- if (backgroundPos.Y > -1024)
- {
- background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024);
- background.DrawTiled(spriteBatch,
- (backgroundPos.Y < 0) ? new Vector2(0.0f, -backgroundPos.Y) : Vector2.Zero,
- new Vector2(GameMain.GraphicsWidth, 1024 - backgroundPos.Y),
- Vector2.Zero, level.BackgroundColor);
- }
-
if (backgroundPos.Y < 0)
{
backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, 1024, (int)Math.Min(-backgroundPos.Y, 1024));
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
Vector2.Zero, level.BackgroundColor);
}
+ if (backgroundPos.Y > -1024)
+ {
+ background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), 1024, 1024);
+ background.DrawTiled(spriteBatch,
+ (backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
+ new Vector2(GameMain.GraphicsWidth, (int)Math.Ceiling(1024 - backgroundPos.Y)),
+ Vector2.Zero, level.BackgroundColor);
+ }
}
spriteBatch.End();
@@ -165,12 +179,12 @@ namespace Barotrauma
GUI.DrawLine(spriteBatch,
new Vector2(cell.edges[0].point1.X, -cell.edges[0].point1.Y),
new Vector2(cell.Center.X, -cell.Center.Y),
- Color.White);
+ Color.Blue*0.5f);
foreach (GraphEdge edge in cell.edges)
{
GUI.DrawLine(spriteBatch, new Vector2(edge.point1.X, -edge.point1.Y),
- new Vector2(edge.point2.X, -edge.point2.Y), cell.body==null ? Color.Gray : Color.White);
+ new Vector2(edge.point2.X, -edge.point2.Y), cell.body==null ? Color.Cyan*0.5f : Color.White);
}
foreach (Vector2 point in cell.bodyVertices)
@@ -205,64 +219,21 @@ namespace Barotrauma
{
if (wallVertices == null) return;
- basicEffect.World = cam.ShaderTransform
- * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
+ wallEdgeEffect.World = cam.ShaderTransform
+ * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 100) * 0.5f;
+ wallCenterEffect.World = wallEdgeEffect.World;
+ //render the solid center of the wall cells
graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
- graphicsDevice.BlendState = BlendState.AlphaBlend;
graphicsDevice.SetVertexBuffer(bodyVertices);
-
- basicEffect.VertexColorEnabled = true;
- basicEffect.TextureEnabled = false;
- basicEffect.CurrentTechnique = basicEffect.Techniques["BasicEffect_VertexColor"];
- basicEffect.CurrentTechnique.Passes[0].Apply();
+ wallCenterEffect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(bodyVertices.VertexCount / 3.0f));
-
- /*
- for (int side = 0; side < 2; side++)
- {
- for (int i = 0; i < 2; i++)
- {
- basicEffect.World = Matrix.CreateTranslation(new Vector3(level.WrappingWalls[side, i].Offset, 0.0f)) * cam.ShaderTransform
- * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
- basicEffect.CurrentTechnique.Passes[0].Apply();
-
-
- graphicsDevice.SetVertexBuffer(level.WrappingWalls[side, i].BodyVertices);
-
- graphicsDevice.DrawPrimitives(
- PrimitiveType.TriangleList, 0,
- (int)Math.Floor(level.WrappingWalls[side, i].BodyVertices.VertexCount / 3.0f));
- }
- }*/
-
-
- graphicsDevice.SetVertexBuffer(wallVertices);
- basicEffect.VertexColorEnabled = false;
- basicEffect.TextureEnabled = true;
- basicEffect.CurrentTechnique = basicEffect.Techniques["BasicEffect_Texture"];
- basicEffect.CurrentTechnique.Passes[0].Apply();
- graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wallVertices.VertexCount / 3.0f));
- /*
- for (int side = 0; side < 2; side++)
- {
- for (int i = 0; i < 2; i++)
- {
-
- basicEffect.World = Matrix.CreateTranslation(new Vector3(level.WrappingWalls[side,i].Offset, 0.0f)) * cam.ShaderTransform
- * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
- basicEffect.CurrentTechnique.Passes[0].Apply();
-
- graphicsDevice.SetVertexBuffer(level.WrappingWalls[side, i].WallVertices);
-
- graphicsDevice.DrawPrimitives(
- PrimitiveType.TriangleList, 0,
- (int)Math.Floor(level.WrappingWalls[side, i].WallVertices.VertexCount / 3.0f));
-
- }
- }*/
+ //render the edges of the wall cells
+ graphicsDevice.SetVertexBuffer(wallVertices);
+ wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
+ graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wallVertices.VertexCount / 3.0f));
}
public void Dispose()
diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs
index 770d25443..f6d21525d 100644
--- a/Subsurface/Source/Map/Lights/LightSource.cs
+++ b/Subsurface/Source/Map/Lights/LightSource.cs
@@ -185,7 +185,8 @@ namespace Barotrauma.Lights
if (NeedsHullUpdate)
{
var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub);
- chList.List = fullChList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox));
+ if (fullChList != null)
+ chList.List = fullChList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox));
}
}
//light is outside, convexhull inside a sub
@@ -299,7 +300,7 @@ namespace Barotrauma.Lights
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
drawPos.Y = -drawPos.Y;
-
+
if (range > 1.0f)
{
if (overrideLightTexture == null)
@@ -326,6 +327,24 @@ namespace Barotrauma.Lights
}
}
+ public void FlipX()
+ {
+ SpriteEffect = SpriteEffect == SpriteEffects.None ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
+ if (LightSprite != null)
+ {
+ Vector2 lightOrigin = LightSprite.Origin;
+ lightOrigin.X = LightSprite.SourceRect.Width - lightOrigin.X;
+ LightSprite.Origin = lightOrigin;
+ }
+
+ if (overrideLightTexture != null)
+ {
+ Vector2 lightOrigin = overrideLightTexture.Origin;
+ lightOrigin.X = overrideLightTexture.SourceRect.Width - lightOrigin.X;
+ overrideLightTexture.Origin = lightOrigin;
+ }
+ }
+
public void Remove()
{
if (LightSprite != null) LightSprite.Remove();
diff --git a/Subsurface/Source/Map/LinkedSubmarine.cs b/Subsurface/Source/Map/LinkedSubmarine.cs
index 856a65f65..631f76248 100644
--- a/Subsurface/Source/Map/LinkedSubmarine.cs
+++ b/Subsurface/Source/Map/LinkedSubmarine.cs
@@ -405,19 +405,29 @@ namespace Barotrauma
}
else
{
- sub.SetPosition(WorldPosition - Submarine.WorldPosition);
- sub.Submarine = Submarine;
+ sub.SetPosition(WorldPosition);
}
-
- var linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null);
- if (linkedItem == null) return;
-
- var linkedPort = ((Item)linkedItem).GetComponent();
+ DockingPort linkedPort = null;
DockingPort myPort = null;
- float closestDistance = 0.0f;
+
+ MapEntity linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent() != null);
+ if (linkedItem == null)
+ {
+ linkedPort = DockingPort.list.Find(dp => dp.DockingTarget != null && dp.DockingTarget.Item.Submarine == sub);
+ }
+ else
+ {
+ linkedPort = ((Item)linkedItem).GetComponent();
+ }
+ if (linkedPort == null)
+ {
+ return;
+ }
+
+ float closestDistance = 0.0f;
foreach (DockingPort port in DockingPort.list)
{
if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal) continue;
@@ -432,8 +442,23 @@ namespace Barotrauma
if (myPort != null)
{
- myPort.DockingTarget = linkedPort;
- }
+ Vector2 portDiff = myPort.Item.WorldPosition - sub.WorldPosition;
+ Vector2 offset = (myPort.IsHorizontal ?
+ Vector2.UnitX * Math.Sign(linkedPort.Item.WorldPosition.X - myPort.Item.WorldPosition.X) :
+ Vector2.UnitY * Math.Sign(linkedPort.Item.WorldPosition.Y - myPort.Item.WorldPosition.Y));
+ offset *= myPort.DockedDistance;
+
+ sub.SetPosition(
+ (linkedPort.Item.WorldPosition - portDiff)
+ - offset);
+
+
+ myPort.Dock(linkedPort);
+ myPort.Lock();
+ }
+
+ sub.SetPosition(sub.WorldPosition - Submarine.WorldPosition);
+ sub.Submarine = Submarine;
}
}
}
diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs
index 0ad25bb11..97d97536c 100644
--- a/Subsurface/Source/Map/MapEntity.cs
+++ b/Subsurface/Source/Map/MapEntity.cs
@@ -26,7 +26,18 @@ namespace Barotrauma
}
}
private static List copiedList = new List();
-
+
+ private static List highlightedList = new List();
+
+ private static float highlightTimer;
+
+ private static GUIListBox highlightedListBox;
+ public static GUIListBox HighlightedListBox
+ {
+ get { return highlightedListBox; }
+ }
+
+
protected static GUIComponent editingHUD;
public static GUIComponent EditingHUD
{
@@ -243,6 +254,7 @@ namespace Barotrauma
//clone links between the entities
for (int i = 0; i < clones.Count; i++)
{
+ if (entitiesToClone[i].linkedTo == null) continue;
foreach (MapEntity linked in entitiesToClone[i].linkedTo)
{
if (!entitiesToClone.Contains(linked)) continue;
@@ -307,6 +319,11 @@ namespace Barotrauma
mapEntityList.Insert(i, this);
}
+ public virtual bool IsVisible(Rectangle worldView)
+ {
+ return true;
+ }
+
public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back=true) {}
public virtual void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect) {}
@@ -329,6 +346,11 @@ namespace Barotrauma
mapEntityList.Remove(this);
+ if (selectedList.Contains(this))
+ {
+ selectedList = selectedList.FindAll(e => e != this);
+ }
+
if (aiTarget != null) aiTarget.Remove();
if (linkedTo != null)
@@ -369,7 +391,7 @@ namespace Barotrauma
public virtual void Update(Camera cam, float deltaTime) { }
///
- /// Update the selection logic in editmap-screen
+ /// Update the selection logic in submarine editor
///
public static void UpdateSelecting(Camera cam)
{
@@ -390,7 +412,15 @@ namespace Barotrauma
return;
}
- if (GUIComponent.MouseOn != null || !PlayerInput.MouseInsideWindow) return;
+ if (GUIComponent.MouseOn != null || !PlayerInput.MouseInsideWindow)
+ {
+ if (highlightedListBox == null ||
+ (GUIComponent.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUIComponent.MouseOn)))
+ {
+ UpdateHighlightedListBox(null);
+ return;
+ }
+ }
if (MapEntityPrefab.Selected != null)
{
@@ -428,10 +458,12 @@ namespace Barotrauma
Vector2 center = Vector2.Zero;
clones.ForEach(c => center += c.WorldPosition);
- center /= clones.Count;
+ center = Submarine.VectorToWorldGrid(center / clones.Count);
+
+ Vector2 moveAmount = Submarine.VectorToWorldGrid(cam.WorldViewCenter - center);
selectedList = new List(clones);
- selectedList.ForEach(c => c.Move(cam.WorldViewCenter - center));
+ selectedList.ForEach(c => c.Move(moveAmount));
}
}
@@ -441,19 +473,62 @@ namespace Barotrauma
if (startMovingPos == Vector2.Zero)
{
- foreach (MapEntity e in mapEntityList)
+ List highlightedEntities = new List();
+ if (highlightedListBox != null && highlightedListBox.IsParentOf(GUIComponent.MouseOn))
{
- if (!e.SelectableInEditor) continue;
-
- if (highLightedEntity == null || e.Sprite == null ||
- (highLightedEntity.Sprite != null && e.Sprite.Depth < highLightedEntity.Sprite.Depth))
+ highLightedEntity = GUIComponent.MouseOn.UserData as MapEntity;
+ }
+ else
+ {
+ foreach (MapEntity e in mapEntityList)
{
- if (e.IsMouseOn(position)) highLightedEntity = e;
+ if (!e.SelectableInEditor) continue;
+
+ if (e.IsMouseOn(position))
+ {
+ int i = 0;
+ while (i < highlightedEntities.Count &&
+ e.Sprite != null &&
+ (highlightedEntities[i].Sprite == null || highlightedEntities[i].Sprite.Depth < e.Sprite.Depth))
+ {
+ i++;
+ }
+
+ highlightedEntities.Insert(i, e);
+
+ if (i == 0) highLightedEntity = e;
+ }
+ }
+
+ if (PlayerInput.MouseSpeed.LengthSquared() > 10)
+ {
+ highlightTimer = 0.0f;
+ }
+ else
+ {
+ bool mouseNearHighlightBox = false;
+
+ if (highlightedListBox != null)
+ {
+ Rectangle expandedRect = highlightedListBox.Rect;
+ expandedRect.Inflate(20, 20);
+ mouseNearHighlightBox = expandedRect.Contains(PlayerInput.MousePosition);
+ if (!mouseNearHighlightBox) highlightedListBox = null;
+ }
+
+ highlightTimer += (float)Timing.Step;
+ if (highlightTimer > 1.0f)
+ {
+ if (!mouseNearHighlightBox)
+ {
+ UpdateHighlightedListBox(highlightedEntities);
+ highlightTimer = 0.0f;
+ }
+ }
}
}
if (highLightedEntity != null) highLightedEntity.isHighlighted = true;
-
}
//started moving selected entities
@@ -501,11 +576,6 @@ namespace Barotrauma
if (highLightedEntity != null) newSelection.Add(highLightedEntity);
}
- foreach (MapEntity e in newSelection)
- {
- e.isHighlighted = true;
- }
-
if (PlayerInput.LeftButtonReleased())
{
if (PlayerInput.KeyDown(Keys.LeftControl) ||
@@ -513,14 +583,7 @@ namespace Barotrauma
{
foreach (MapEntity e in newSelection)
{
- bool alreadySelected = false;
-
- foreach (MapEntity e2 in selectedList)
- {
- if (e.ID == e2.ID) alreadySelected = true;
- }
-
- if (alreadySelected)
+ if (selectedList.Contains(e))
selectedList.Remove(e);
else
selectedList.Add(e);
@@ -558,7 +621,8 @@ namespace Barotrauma
else
{
if (PlayerInput.LeftButtonHeld() &&
- PlayerInput.KeyUp(Keys.Space))
+ PlayerInput.KeyUp(Keys.Space) &&
+ (highlightedListBox == null || (GUIComponent.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUIComponent.MouseOn))))
{
//if clicking a selected entity, start moving it
foreach (MapEntity e in selectedList)
@@ -571,6 +635,57 @@ namespace Barotrauma
}
}
+ private static void UpdateHighlightedListBox(List highlightedEntities)
+ {
+ if (highlightedEntities == null || highlightedEntities.Count < 2)
+ {
+ highlightedListBox = null;
+ return;
+ }
+ if (highlightedListBox != null)
+ {
+ if (GUIComponent.MouseOn == highlightedListBox || highlightedListBox.IsParentOf(GUIComponent.MouseOn)) return;
+ if (highlightedEntities.SequenceEqual(highlightedList)) return;
+ }
+
+ highlightedList = highlightedEntities;
+
+ highlightedListBox = new GUIListBox(
+ new Rectangle((int)PlayerInput.MousePosition.X+15, (int)PlayerInput.MousePosition.Y+15, 150, highlightedEntities.Count * 15),
+ null, Alignment.TopLeft, GUI.Style, null, false);
+
+ highlightedListBox.Color = Color.Black * 0.6f;
+
+ foreach (MapEntity entity in highlightedEntities)
+ {
+ var textBlock = new GUITextBlock(
+ new Rectangle(0,0,0,15),
+ ToolBox.LimitString(entity.Name, GUI.SmallFont, 140), GUI.Style, highlightedListBox, GUI.SmallFont);
+
+ textBlock.UserData = entity;
+ }
+
+ highlightedListBox.OnSelected = (GUIComponent component, object obj) =>
+ {
+ MapEntity entity = obj as MapEntity;
+
+ if (PlayerInput.KeyDown(Keys.LeftControl) ||
+ PlayerInput.KeyDown(Keys.RightControl))
+ {
+ if (selectedList.Contains(entity))
+ selectedList.Remove(entity);
+ else
+ selectedList.Add(entity);
+ }
+ else
+ {
+ SelectEntity(entity);
+ }
+
+ return true;
+ };
+ }
+
///
/// Draw the "selection rectangle" and outlines of entities that are being dragged (if any)
@@ -608,6 +723,8 @@ namespace Barotrauma
public static void UpdateEditor(Camera cam)
{
+ if (highlightedListBox != null) highlightedListBox.Update((float)Timing.Step);
+
if (selectedList.Count == 1)
{
selectedList[0].UpdateEditing(cam);
@@ -617,19 +734,21 @@ namespace Barotrauma
selectedList[0].UpdateResizing(cam);
}
}
- else
+
+ if (editingHUD != null)
{
- if (editingHUD == null) return;
-
- foreach (GUIComponent component in editingHUD.children)
+ if (selectedList.Count == 0 || editingHUD.UserData != selectedList[0])
{
- var textBox = component as GUITextBox;
- if (textBox == null) continue;
+ foreach (GUIComponent component in editingHUD.children)
+ {
+ var textBox = component as GUITextBox;
+ if (textBox == null) continue;
- textBox.Deselect();
+ textBox.Deselect();
+ }
+
+ editingHUD = null;
}
-
- editingHUD = null;
}
}
@@ -644,6 +763,11 @@ namespace Barotrauma
selectedList[0].DrawResizing(spriteBatch, cam);
}
}
+
+ if (highlightedListBox != null)
+ {
+ highlightedListBox.Draw(spriteBatch);
+ }
}
public static void DeselectAll()
@@ -658,8 +782,7 @@ namespace Barotrauma
selectedList.Add(entity);
}
-
-
+
///
/// copies a list of entities to the "clipboard" (copiedList)
///
@@ -693,7 +816,7 @@ namespace Barotrauma
public virtual void AddToGUIUpdateList()
{
- if (editingHUD != null) editingHUD.AddToGUIUpdateList();
+ if (editingHUD != null && editingHUD.UserData == this) editingHUD.AddToGUIUpdateList();
}
public virtual void UpdateEditing(Camera cam) { }
diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs
index 8f35e98ab..775b66e72 100644
--- a/Subsurface/Source/Map/Structure.cs
+++ b/Subsurface/Source/Map/Structure.cs
@@ -101,7 +101,7 @@ namespace Barotrauma
public override string Name
{
- get { return "structure"; }
+ get { return prefab.Name; }
}
public bool HasBody
@@ -153,6 +153,11 @@ namespace Barotrauma
}
}
+ public List Tags
+ {
+ get { return prefab.tags; }
+ }
+
public override Rectangle Rect
{
get
@@ -477,6 +482,15 @@ namespace Barotrauma
if (convexHulls != null) convexHulls.ForEach(x => x.Remove());
}
+ public override bool IsVisible(Rectangle WorldView)
+ {
+ Rectangle worldRect = WorldRect;
+
+ if (worldRect.X > WorldView.Right || worldRect.Right < WorldView.X) return false;
+ if (worldRect.Y < WorldView.Y - WorldView.Height || worldRect.Y - worldRect.Height > WorldView.Y) return false;
+
+ return true;
+ }
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
@@ -505,6 +519,9 @@ namespace Barotrauma
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
+ float depth = prefab.sprite.Depth;
+ depth -= (ID % 255) * 0.000001f;
+
if (back && damageEffect == null)
{
if (prefab.BackgroundSprite != null)
@@ -513,7 +530,7 @@ namespace Barotrauma
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
new Vector2(rect.Width, rect.Height),
- Vector2.Zero, color, Point.Zero);
+ color, Point.Zero);
}
}
@@ -552,8 +569,8 @@ namespace Barotrauma
spriteBatch,
new Vector2(sections[i].rect.X + drawOffset.X, -(sections[i].rect.Y + drawOffset.Y)),
new Vector2(sections[i].rect.Width, sections[i].rect.Height),
- Vector2.Zero, color,
- textureOffset);
+ color,
+ textureOffset, depth);
}
}
diff --git a/Subsurface/Source/Map/StructurePrefab.cs b/Subsurface/Source/Map/StructurePrefab.cs
index 3492fad31..b99087775 100644
--- a/Subsurface/Source/Map/StructurePrefab.cs
+++ b/Subsurface/Source/Map/StructurePrefab.cs
@@ -85,22 +85,9 @@ namespace Barotrauma
{
StructurePrefab sp = new StructurePrefab();
sp.name = element.Name.ToString();
-
- //Vector4 sourceVector = ToolBox.GetAttributeVector4(element, "sourcerect", new Vector4(0,0,1,1));
- //Rectangle sourceRect = new Rectangle(
- // (int)sourceVector.X,
- // (int)sourceVector.Y,
- // (int)sourceVector.Z,
- // (int)sourceVector.W);
-
- //if (element.Attribute("sprite") != null)
- //{
- // sp.sprite = new Sprite(element.Attribute("sprite").Value, sourceRect, Vector2.Zero);
-
- // sp.sprite.Depth = ToolBox.GetAttributeFloat(element, "depth", 0.0f);
-
- //}
+ sp.tags = new List();
+ sp.tags.AddRange(ToolBox.GetAttributeString(element, "tags", "").Split(','));
foreach (XElement subElement in element.Elements())
{
diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs
index 213c30924..e48cb5169 100644
--- a/Subsurface/Source/Map/Submarine.cs
+++ b/Subsurface/Source/Map/Submarine.cs
@@ -12,6 +12,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
+using Voronoi2;
namespace Barotrauma
{
@@ -298,11 +299,96 @@ namespace Barotrauma
tags &= ~tag;
}
- //drawing ----------------------------------------------------
+ ///
+ /// Returns a rect that contains the borders of this sub and all subs docked to it
+ ///
+ public Rectangle GetDockedBorders()
+ {
+ Rectangle dockedBorders = Borders;
+ dockedBorders.Y -= dockedBorders.Height;
+
+ foreach (Submarine dockedSub in DockedTo)
+ {
+ Vector2 diff = dockedSub.Submarine == this ? dockedSub.WorldPosition : dockedSub.WorldPosition - WorldPosition;
+
+
+ Rectangle dockedSubBorders = dockedSub.Borders;
+ dockedSubBorders.Y -= dockedSubBorders.Height;
+ dockedSubBorders.Location += diff.ToPoint();
+
+ dockedBorders = Rectangle.Union(dockedBorders, dockedSubBorders);
+ }
+
+ dockedBorders.Y += dockedBorders.Height;
+ return dockedBorders;
+ }
+
+ 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.Height);
+
+ wallTooClose = false;
+
+ var nearbyCells = Level.Loaded.GetCells(
+ spawnPos, (int)Math.Ceiling(Math.Max(dockedBorders.Width, dockedBorders.Height) / (float)Level.GridCellSize));
+
+ foreach (VoronoiCell cell in nearbyCells)
+ {
+ if (cell.CellType == CellType.Empty) continue;
+
+ foreach (GraphEdge e in cell.edges)
+ {
+ List intersections = MathUtils.GetLineRectangleIntersections(e.point1, e.point2, worldBorders);
+ foreach (Vector2 intersection in intersections)
+ {
+ wallTooClose = true;
+
+ if (intersection.X < spawnPos.X)
+ {
+ spawnPos.X += intersection.X - worldBorders.X;
+ }
+ else
+ {
+ spawnPos.X += intersection.X - worldBorders.Right;
+ }
+
+ if (intersection.Y < spawnPos.Y)
+ {
+ spawnPos.Y += intersection.Y - (worldBorders.Y - worldBorders.Height);
+ }
+ else
+ {
+ spawnPos.Y += intersection.Y - worldBorders.Y;
+ }
+
+ spawnPos.Y = Math.Min(spawnPos.Y, Level.Loaded.Size.Y - dockedBorders.Height / 2);
+ }
+ }
+ }
+
+ iterations++;
+ } while (wallTooClose && iterations < 10);
+
+ return spawnPos;
+
+ }
+
+ //drawing ----------------------------------------------------
+
public static void CullEntities(Camera cam)
{
- List visibleSubs = new List();
+ HashSet visibleSubs = new HashSet();
foreach (Submarine sub in Submarine.Loaded)
{
Rectangle worldBorders = new Rectangle(
@@ -311,19 +397,20 @@ namespace Barotrauma
sub.Borders.Width + 1000,
sub.Borders.Height + 1000);
-
if (Submarine.RectsOverlap(worldBorders, cam.WorldView))
{
visibleSubs.Add(sub);
}
}
+ Rectangle worldView = cam.WorldView;
+
visibleEntities = new List();
foreach (MapEntity me in MapEntity.mapEntityList)
{
if (me.Submarine == null || visibleSubs.Contains(me.Submarine))
{
- visibleEntities.Add(me);
+ if (me.IsVisible(worldView)) visibleEntities.Add(me);
}
}
}
@@ -827,11 +914,8 @@ namespace Barotrauma
}
}
- public static void Preload()
+ public static void RefreshSavedSubs()
{
-
- //string[] mapFilePaths;
- //Unload();
SavedSubmarines.Clear();
if (!Directory.Exists(SavePath))
diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs
index 6a0f6906b..b882e5865 100644
--- a/Subsurface/Source/Map/SubmarineBody.cs
+++ b/Subsurface/Source/Map/SubmarineBody.cs
@@ -484,8 +484,6 @@ namespace Barotrauma
Vector2 lastContactPoint = worldPoints[0];
- SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, impact * 10.0f, ConvertUnits.ToDisplayUnits(lastContactPoint));
-
if (Character.Controlled != null && Character.Controlled.Submarine == submarine)
{
GameMain.GameScreen.Cam.Shake = impact * 2.0f;
@@ -518,7 +516,29 @@ namespace Barotrauma
item.body.ApplyLinearImpulse(item.body.Mass * impulse);
}
- Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits(lastContactPoint), impact * 50.0f, impact * DamageMultiplier);
+ var damagedStructures = Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits(lastContactPoint), impact * 50.0f, impact * DamageMultiplier);
+
+ //play a damage sound for the structure that took the most damage
+ float maxDamage = 0.0f;
+ Structure maxDamageStructure = null;
+ foreach (KeyValuePair structureDamage in damagedStructures)
+ {
+ if (maxDamageStructure == null || structureDamage.Value > maxDamage)
+ {
+ maxDamage = structureDamage.Value;
+ maxDamageStructure = structureDamage.Key;
+ }
+ }
+
+ if (maxDamageStructure != null)
+ {
+ SoundPlayer.PlayDamageSound(
+ DamageSoundType.StructureBlunt,
+ impact * 10.0f,
+ ConvertUnits.ToDisplayUnits(lastContactPoint),
+ MathHelper.Clamp(maxDamage * 4.0f, 1000.0f, 4000.0f),
+ maxDamageStructure.Tags);
+ }
}
}
diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs
index 769a655bd..6575a5ff0 100644
--- a/Subsurface/Source/Map/WayPoint.cs
+++ b/Subsurface/Source/Map/WayPoint.cs
@@ -54,13 +54,13 @@ namespace Barotrauma
set { spawnType = value; }
}
- //public override string Name
- //{
- // get
- // {
- // return spawnType == SpawnType.Path ? "WayPoint" : "SpawnPoint";
- // }
- //}
+ public override string Name
+ {
+ get
+ {
+ return spawnType == SpawnType.Path ? "WayPoint" : "SpawnPoint";
+ }
+ }
public string[] IdCardTags
{
diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs
index 06e419976..7bb5526dd 100644
--- a/Subsurface/Source/Networking/GameServer.cs
+++ b/Subsurface/Source/Networking/GameServer.cs
@@ -901,6 +901,8 @@ namespace Barotrauma.Networking
if (autoRestart) AutoRestartTimer = Math.Max(AutoRestartInterval, 5.0f);
GameMain.NetLobbyScreen.StartButton.Enabled = true;
+ UpdateNetLobby(null, null);
+
couldNotStart = true;
}
diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs
index 495b12425..037a62454 100644
--- a/Subsurface/Source/Physics/PhysicsBody.cs
+++ b/Subsurface/Source/Physics/PhysicsBody.cs
@@ -384,24 +384,16 @@ namespace Barotrauma
//buoyancy
Vector2 buoyancy = new Vector2(0, Mass * 9.6f);
- //drag
- Vector2 velDir = Vector2.Normalize(LinearVelocity);
-
- Vector2 line = new Vector2((float)Math.Cos(body.Rotation), (float)Math.Sin(body.Rotation));
- line *= Math.Max(height + radius*2, height);
-
- Vector2 normal = new Vector2(-line.Y, line.X);
- normal = Vector2.Normalize(-normal);
-
- float dragDot = Math.Abs(Vector2.Dot(normal, velDir));
Vector2 dragForce = Vector2.Zero;
- if (dragDot > 0)
+
+ if (LinearVelocity.LengthSquared() > 0.00001f)
{
+ //drag
+ Vector2 velDir = Vector2.Normalize(LinearVelocity);
+
float vel = LinearVelocity.Length() * 2.0f;
- float drag = dragDot * vel * vel
- * Math.Max(height + radius * 2, height);
- dragForce = Math.Min(drag, Mass * 1000.0f) * -velDir;
- //if (dragForce.Length() > 100.0f) { }
+ float drag = vel * vel * Math.Max(height + radius * 2, height);
+ dragForce = Math.Min(drag, Mass * 500.0f) * -velDir;
}
body.ApplyForce(dragForce + buoyancy);
@@ -435,6 +427,8 @@ namespace Barotrauma
UpdateDrawPosition();
+ if (sprite == null) return;
+
SpriteEffects spriteEffect = (dir == 1.0f) ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
if (GameMain.DebugDraw && !body.Awake)
diff --git a/Subsurface/Source/Program.cs b/Subsurface/Source/Program.cs
index ebda383c2..201d399c6 100644
--- a/Subsurface/Source/Program.cs
+++ b/Subsurface/Source/Program.cs
@@ -53,6 +53,7 @@ namespace Barotrauma
else
{
CrashDump(game, "crashreport.txt", e);
+ attemptRestart = false;
}
}
diff --git a/Subsurface/Source/Screens/EditCharacterScreen.cs b/Subsurface/Source/Screens/EditCharacterScreen.cs
index 3ef825e77..64e309ed3 100644
--- a/Subsurface/Source/Screens/EditCharacterScreen.cs
+++ b/Subsurface/Source/Screens/EditCharacterScreen.cs
@@ -85,7 +85,7 @@ namespace Barotrauma
texturePaths = new List();
foreach (Limb limb in editingCharacter.AnimController.Limbs)
{
- if (texturePaths.Contains(limb.sprite.FilePath)) continue;
+ if (limb.sprite==null || texturePaths.Contains(limb.sprite.FilePath)) continue;
textures.Add(limb.sprite.Texture);
texturePaths.Add(limb.sprite.FilePath);
}
@@ -160,7 +160,7 @@ namespace Barotrauma
foreach (Limb limb in editingCharacter.AnimController.Limbs)
{
- if (limb.sprite.FilePath != texturePaths[i]) continue;
+ if (limb.sprite == null || limb.sprite.FilePath != texturePaths[i]) continue;
Rectangle rect = limb.sprite.SourceRect;
rect.X += x;
rect.Y += y;
diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs
index 7e341b409..f3d687559 100644
--- a/Subsurface/Source/Screens/EditMapScreen.cs
+++ b/Subsurface/Source/Screens/EditMapScreen.cs
@@ -1,4 +1,5 @@
-using Microsoft.Xna.Framework;
+using Barotrauma.Items.Components;
+using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
@@ -30,6 +31,8 @@ namespace Barotrauma
const int PreviouslyUsedCount = 10;
private GUIListBox previouslyUsedList;
+ GUIDropDown linkedSubBox;
+
//a Character used for picking up and manipulating items
private Character dummyCharacter;
@@ -150,7 +153,7 @@ namespace Barotrauma
var nameLabel = new GUITextBlock(new Rectangle(170, -4, 150, 20), "", GUI.Style, topPanel, GUI.LargeFont);
nameLabel.TextGetter = GetSubName;
- var linkedSubBox = new GUIDropDown(new Rectangle(750,0,200,20), "Add submarine", GUI.Style, topPanel);
+ linkedSubBox = new GUIDropDown(new Rectangle(750,0,200,20), "Add submarine", GUI.Style, topPanel);
linkedSubBox.ToolTip =
"Places another submarine into the current submarine file. "+
"Can be used for adding things such as smaller vessels, "+
@@ -191,7 +194,6 @@ namespace Barotrauma
GUITextBox searchBox = new GUITextBox(new Rectangle(-20, 0, 180, 15), Alignment.TopRight, GUI.Style, GUItabs[i]);
searchBox.Font = GUI.SmallFont;
searchBox.OnTextChanged = FilterMessages;
- GUIComponent.KeyboardDispatcher.Subscriber = searchBox;
var clearButton = new GUIButton(new Rectangle(0, 0, 15, 15), "x", Alignment.TopRight, GUI.Style, GUItabs[i]);
clearButton.OnClicked = ClearFilter;
@@ -304,19 +306,25 @@ namespace Barotrauma
if (Submarine.MainSub != null)
{
cam.Position = Submarine.MainSub.Position + Submarine.MainSub.HiddenSubPosition;
- //nameBox.Text = Submarine.MainSub.Name;
- //descriptionBox.Text = ToolBox.LimitString(Submarine.MainSub.Description, 15);
}
else
{
cam.Position = Submarine.HiddenSubStartPosition;
- //if (nameBox != null) nameBox.Text = "";
- //descriptionBox.Text = "";
Submarine.MainSub = new Submarine(Path.Combine(Submarine.SavePath, "Unnamed.sub"), "", false);
}
- //nameBox.Deselect();
+ SoundPlayer.OverrideMusicType = "none";
+ for (int i = 0; i < Sounds.SoundManager.DefaultSourceCount; i++)
+ {
+ Sounds.SoundManager.Pause(i);
+ }
+
+ linkedSubBox.ClearChildren();
+ foreach (Submarine sub in Submarine.SavedSubmarines)
+ {
+ linkedSubBox.AddItem(sub.Name, sub);
+ }
cam.UpdateTransform();
}
@@ -335,6 +343,12 @@ namespace Barotrauma
if (wiringMode) ToggleWiringMode();
+ SoundPlayer.OverrideMusicType = null;
+ for (int i = 0; i < Sounds.SoundManager.DefaultSourceCount; i++)
+ {
+ Sounds.SoundManager.Resume(i);
+ }
+
if (dummyCharacter != null)
{
dummyCharacter.Remove();
@@ -391,6 +405,13 @@ namespace Barotrauma
GUI.AddMessage("Submarine saved to " + Submarine.MainSub.FilePath, Color.Green, 3.0f);
+ Submarine.RefreshSavedSubs();
+ linkedSubBox.ClearChildren();
+ foreach (Submarine sub in Submarine.SavedSubmarines)
+ {
+ linkedSubBox.AddItem(sub.Name, sub);
+ }
+
saveFrame = null;
return false;
@@ -482,7 +503,7 @@ namespace Barotrauma
private bool CreateLoadScreen(GUIButton button, object obj)
{
- Submarine.Preload();
+ Submarine.RefreshSavedSubs();
int width = 300, height = 400;
loadFrame = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style, null);
@@ -579,9 +600,11 @@ namespace Barotrauma
{
selectedTab = (int)obj;
- ClearFilter(GUItabs[selectedTab].GetChild(), null);
-
- GUIComponent.KeyboardDispatcher.Subscriber = GUItabs[selectedTab].GetChild();
+ var searchBox = GUItabs[selectedTab].GetChild();
+ ClearFilter(searchBox, null);
+
+ searchBox.AddToGUIUpdateList();
+ searchBox.Select();
return true;
}
@@ -650,6 +673,8 @@ namespace Barotrauma
{
me.IsHighlighted = false;
}
+
+ MapEntity.DeselectAll();
return true;
}
@@ -665,7 +690,6 @@ namespace Barotrauma
characterMode = false;
-
if (wiringMode)
{
CreateDummyCharacter();
@@ -682,6 +706,8 @@ namespace Barotrauma
{
RemoveDummyCharacter();
}
+
+ MapEntity.DeselectAll();
return true;
}
@@ -843,7 +869,11 @@ namespace Barotrauma
string name = ToolBox.LimitString(mapEntityPrefab.Name,15);
- var textBlock = new GUITextBlock(new Rectangle(0,0,0,15), name, GUI.Style, previouslyUsedList);
+ var textBlock = new GUITextBlock(
+ new Rectangle(0,0,0,10),
+ ToolBox.LimitString(name, GUI.SmallFont, previouslyUsedList.Rect.Width),
+ GUI.Style, previouslyUsedList, GUI.SmallFont);
+
textBlock.UserData = mapEntityPrefab;
previouslyUsedList.RemoveChild(textBlock);
@@ -858,6 +888,10 @@ namespace Barotrauma
{
MapEntity.SelectedList[0].AddToGUIUpdateList();
}
+ if (MapEntity.HighlightedListBox != null)
+ {
+ MapEntity.HighlightedListBox.AddToGUIUpdateList();
+ }
leftPanel.AddToGUIUpdateList();
topPanel.AddToGUIUpdateList();
@@ -899,10 +933,7 @@ namespace Barotrauma
hullVolumeFrame.Visible = MapEntity.SelectedList.Any(s => s is Hull);
- if (GUIComponent.MouseOn == null)
- {
- cam.MoveCamera((float)deltaTime);
- }
+ cam.MoveCamera((float)deltaTime, true, GUIComponent.MouseOn == null);
if (characterMode || wiringMode)
{
@@ -917,6 +948,17 @@ namespace Barotrauma
me.IsHighlighted = false;
}
+ if (wiringMode && dummyCharacter.SelectedConstruction==null)
+ {
+ List wires = new List();
+ foreach (Item item in Item.ItemList)
+ {
+ var wire = item.GetComponent();
+ if (wire != null) wires.Add(wire);
+ }
+ Wire.UpdateEditing(wires);
+ }
+
if (dummyCharacter.SelectedConstruction==null)
{
Vector2 mouseSimPos = FarseerPhysics.ConvertUnits.ToSimUnits(dummyCharacter.CursorPosition);
diff --git a/Subsurface/Source/Screens/MainMenuScreen.cs b/Subsurface/Source/Screens/MainMenuScreen.cs
index d94a3a92d..740eb7935 100644
--- a/Subsurface/Source/Screens/MainMenuScreen.cs
+++ b/Subsurface/Source/Screens/MainMenuScreen.cs
@@ -92,30 +92,7 @@ namespace Barotrauma
new GUITextBlock(new Rectangle(0, 0, 0, 30), "Selected submarine:", null, null, Alignment.Left, GUI.Style, menuTabs[(int)Tab.NewGame]);
subList = new GUIListBox(new Rectangle(0, 30, 230, panelRect.Height-100), GUI.Style, menuTabs[(int)Tab.NewGame]);
- var subsToShow = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
-
- foreach (Submarine sub in subsToShow)
- {
- var textBlock = new GUITextBlock(
- new Rectangle(0, 0, 0, 25),
- ToolBox.LimitString(sub.Name, GUI.Font, subList.Rect.Width-65), GUI.Style,
- Alignment.Left, Alignment.Left, subList)
- {
- Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f),
- ToolTip = sub.Description,
- UserData = sub
- };
-
- if (sub.HasTag(SubmarineTag.Shuttle))
- {
- textBlock.TextColor = textBlock.TextColor * 0.85f;
-
- var shuttleText = new GUITextBlock(new Rectangle(0, 0, 0, 25), "Shuttle", GUI.Style, Alignment.Left, Alignment.CenterY | Alignment.Right, textBlock, false, GUI.SmallFont);
- shuttleText.TextColor = textBlock.TextColor * 0.8f;
- shuttleText.ToolTip = textBlock.ToolTip;
- }
- }
- if (Submarine.SavedSubmarines.Count > 0) subList.Select(Submarine.SavedSubmarines[0]);
+ UpdateSubList();
new GUITextBlock(new Rectangle((int)(subList.Rect.Width + 20), 0, 100, 20),
"Save name: ", GUI.Style, Alignment.Left, Alignment.Left, menuTabs[(int)Tab.NewGame]);
@@ -218,9 +195,41 @@ namespace Barotrauma
Submarine.Unload();
+ UpdateSubList();
+
SelectTab(null, 0);
//selectedTab = 0;
}
+
+ private void UpdateSubList()
+ {
+ var subsToShow = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
+
+ subList.ClearChildren();
+
+ foreach (Submarine sub in subsToShow)
+ {
+ var textBlock = new GUITextBlock(
+ new Rectangle(0, 0, 0, 25),
+ ToolBox.LimitString(sub.Name, GUI.Font, subList.Rect.Width - 65), GUI.Style,
+ Alignment.Left, Alignment.Left, subList)
+ {
+ Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f),
+ ToolTip = sub.Description,
+ UserData = sub
+ };
+
+ if (sub.HasTag(SubmarineTag.Shuttle))
+ {
+ textBlock.TextColor = textBlock.TextColor * 0.85f;
+
+ var shuttleText = new GUITextBlock(new Rectangle(0, 0, 0, 25), "Shuttle", GUI.Style, Alignment.Left, Alignment.CenterY | Alignment.Right, textBlock, false, GUI.SmallFont);
+ shuttleText.TextColor = textBlock.TextColor * 0.8f;
+ shuttleText.ToolTip = textBlock.ToolTip;
+ }
+ }
+ if (Submarine.SavedSubmarines.Count > 0) subList.Select(Submarine.SavedSubmarines[0]);
+ }
public bool SelectTab(GUIButton button, object obj)
{
diff --git a/Subsurface/Source/Sounds/OggStream.cs b/Subsurface/Source/Sounds/OggStream.cs
index d2c9a5a7a..d877cc14f 100644
--- a/Subsurface/Source/Sounds/OggStream.cs
+++ b/Subsurface/Source/Sounds/OggStream.cs
@@ -47,14 +47,15 @@ namespace Barotrauma.Sounds
public static void Check()
{
-#if !DEBUG
- return;
-#endif
-
ALError error;
if ((error = AL.GetError()) != ALError.NoError)
{
- DebugConsole.ThrowError("OpenAL error: "+AL.GetErrorString(error));
+#if DEBUG
+ DebugConsole.ThrowError("OpenAL error: " + AL.GetErrorString(error));
+#else
+
+ DebugConsole.NewMessage("OpenAL error: "+AL.GetErrorString(error), Microsoft.Xna.Framework.Color.Red);
+#endif
}
}
}
diff --git a/Subsurface/Source/Sounds/Sound.cs b/Subsurface/Source/Sounds/Sound.cs
index 5cfb62e89..867ae39f4 100644
--- a/Subsurface/Source/Sounds/Sound.cs
+++ b/Subsurface/Source/Sounds/Sound.cs
@@ -247,7 +247,8 @@ namespace Barotrauma
loadedSounds.Remove(this);
- if (alSourceId>0 && SoundManager.IsPlaying(alSourceId))
+ if (alSourceId > 0 &&
+ (SoundManager.IsPlaying(alSourceId) || SoundManager.IsPaused(alSourceId)))
{
SoundManager.Stop(alSourceId);
ALHelper.Check();
@@ -258,10 +259,10 @@ namespace Barotrauma
if (s.oggSound == oggSound) return;
}
- //System.Diagnostics.Debug.WriteLine("Removing sound " + filePath + " (buffer id" + AlBufferId + ")");
-
SoundManager.ClearAlSource(AlBufferId);
- if (oggSound!=null) oggSound.Dispose();
+ ALHelper.Check();
+
+ if (oggSound != null) oggSound.Dispose();
}
diff --git a/Subsurface/Source/Sounds/SoundManager.cs b/Subsurface/Source/Sounds/SoundManager.cs
index 3c28bc280..86607bc00 100644
--- a/Subsurface/Source/Sounds/SoundManager.cs
+++ b/Subsurface/Source/Sounds/SoundManager.cs
@@ -149,12 +149,18 @@ namespace Barotrauma.Sounds
return soundsPlaying[sourceIndex];
}
-
public static bool IsPlaying(int sourceIndex)
{
if (sourceIndex < 1 || sourceIndex>alSources.Count-1) return false;
- var state = AL.GetSourceState(alSources[sourceIndex]);
- return (state == ALSourceState.Playing);
+
+ return AL.GetSourceState(alSources[sourceIndex]) == ALSourceState.Playing;
+ }
+
+ public static bool IsPaused(int sourceIndex)
+ {
+ if (sourceIndex < 1 || sourceIndex > alSources.Count - 1) return false;
+
+ return AL.GetSourceState(alSources[sourceIndex]) == ALSourceState.Paused;
}
public static bool IsLooping(int sourceIndex)
diff --git a/Subsurface/Source/Sounds/SoundPlayer.cs b/Subsurface/Source/Sounds/SoundPlayer.cs
index 9053d899e..a25b40c00 100644
--- a/Subsurface/Source/Sounds/SoundPlayer.cs
+++ b/Subsurface/Source/Sounds/SoundPlayer.cs
@@ -15,8 +15,7 @@ namespace Barotrauma
{
None,
StructureBlunt, StructureSlash,
- LimbBlunt, LimbSlash, LimbArmor,
- Implode, Pressure
+ LimbBlunt, LimbSlash, LimbArmor
}
public struct DamageSound
@@ -29,11 +28,15 @@ namespace Barotrauma
public readonly Sound sound;
- public DamageSound(Sound sound, Vector2 damageRange, DamageSoundType damageType)
+ public readonly string requiredTag;
+
+ public DamageSound(Sound sound, Vector2 damageRange, DamageSoundType damageType, string requiredTag = "")
{
this.sound = sound;
this.damageRange = damageRange;
this.damageType = damageType;
+
+ this.requiredTag = requiredTag;
}
}
@@ -54,25 +57,30 @@ namespace Barotrauma
static class SoundPlayer
{
- public static Sound[] flowSounds = new Sound[3];
-
- public static Sound[] SplashSounds = new Sound[10];
+ private static ILookup miscSounds;
+ //music
public static float MusicVolume = 1.0f;
-
private const float MusicLerpSpeed = 0.1f;
- private static Sound[] waterAmbiences = new Sound[2];
- private static int[] waterAmbienceIndexes = new int[2];
-
-
- private static DamageSound[] damageSounds;
-
private static BackgroundMusic currentMusic;
private static BackgroundMusic targetMusic;
private static BackgroundMusic[] musicClips;
private static float currMusicVolume;
+ //ambience
+ private static Sound[] waterAmbiences = new Sound[2];
+ private static int[] waterAmbienceIndexes = new int[2];
+
+ private static float ambientSoundTimer;
+ private static Vector2 ambientSoundInterval = new Vector2(20.0f, 40.0f); //x = min, y = max
+
+ //misc
+ public static Sound[] flowSounds = new Sound[3];
+ public static Sound[] SplashSounds = new Sound[10];
+
+ private static List damageSounds;
+
private static Sound startDrone;
public static bool Initialized;
@@ -133,39 +141,46 @@ namespace Barotrauma
i++;
}
}
+
+ List> miscSoundList = new List>();
+ damageSounds = new List();
- var xDamageSounds = doc.Root.Elements("damagesound").ToList();
-
- if (xDamageSounds.Any())
+ foreach (XElement subElement in doc.Root.Elements())
{
- damageSounds = new DamageSound[xDamageSounds.Count];
- int i = 0;
- foreach (XElement element in xDamageSounds)
+ yield return CoroutineStatus.Running;
+
+ switch (subElement.Name.ToString().ToLowerInvariant())
{
- yield return CoroutineStatus.Running;
-
- Sound sound = Sound.Load(ToolBox.GetAttributeString(element, "file", ""), false);
- if (sound == null) continue;
+ case "music":
+ continue;
+ case "damagesound":
+ Sound damageSound = Sound.Load(ToolBox.GetAttributeString(subElement, "file", ""), false);
+ if (damageSound == null) continue;
- DamageSoundType damageSoundType = DamageSoundType.None;
+ DamageSoundType damageSoundType = DamageSoundType.None;
+ Enum.TryParse(ToolBox.GetAttributeString(subElement, "damagesoundtype", "None"), false, out damageSoundType);
- try
- {
- damageSoundType = (DamageSoundType)Enum.Parse(typeof(DamageSoundType),
- ToolBox.GetAttributeString(element, "damagesoundtype", "None"));
- }
- catch
- {
- damageSoundType = DamageSoundType.None;
- }
+ damageSounds.Add(new DamageSound(
+ damageSound,
+ ToolBox.GetAttributeVector2(subElement, "damagerange", new Vector2(0.0f, 100.0f)),
+ damageSoundType,
+ ToolBox.GetAttributeString(subElement, "requiredtag", "")));
+ break;
+ default:
+ Sound sound = Sound.Load(ToolBox.GetAttributeString(subElement, "file", ""), false);
+ if (sound != null)
+ {
+ miscSoundList.Add(new KeyValuePair(subElement.Name.ToString().ToLowerInvariant(), sound));
+ }
- damageSounds[i] = new DamageSound(
- sound, ToolBox.GetAttributeVector2(element, "damagerange", new Vector2(0.0f,100.0f)), damageSoundType);
- i++;
+ break;
}
}
+ miscSounds = miscSoundList.ToLookup(kvp => kvp.Key, kvp => kvp.Value);
+
+
Initialized = true;
yield return CoroutineStatus.Success;
@@ -177,7 +192,7 @@ namespace Barotrauma
{
UpdateMusic();
- if (startDrone!=null && !startDrone.IsPlaying)
+ if (startDrone != null && !startDrone.IsPlaying)
{
startDrone.Remove();
startDrone = null;
@@ -229,11 +244,20 @@ namespace Barotrauma
movementSoundVolume = Math.Max(movementSoundVolume, movementFactor);
}
- //if (Submarine.MainSub != null)
- //{
- // movementFactor = (Submarine.MainSub.Velocity == Vector2.Zero) ? 0.0f : Submarine.MainSub.Velocity.Length() / 5.0f;
- // movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f);
- //}
+ if (ambientSoundTimer > 0.0f)
+ {
+ ambientSoundTimer -= (float)Timing.Step;
+ }
+ else
+ {
+ PlaySound(
+ "ambient",
+ Rand.Range(0.5f, 1.0f),
+ 1000.0f,
+ new Vector2(Sound.CameraPos.X, Sound.CameraPos.Y) + Rand.Vector(100.0f));
+
+ ambientSoundTimer = Rand.Range(ambientSoundInterval.X, ambientSoundInterval.Y);
+ }
SoundManager.LowPassHFGain = lowpassHFGain;
waterAmbienceIndexes[0] = waterAmbiences[0].Loop(waterAmbienceIndexes[0], ambienceVolume * (1.0f - movementSoundVolume));
@@ -241,13 +265,37 @@ namespace Barotrauma
}
+ public static Sound GetSound(string soundTag)
+ {
+ var matchingSounds = miscSounds[soundTag].ToList();
+ if (matchingSounds.Count == 0) return null;
+
+ return matchingSounds[Rand.Int(matchingSounds.Count)];
+ }
+
+ public static void PlaySound(string soundTag, float volume = 1.0f)
+ {
+ var sound = GetSound(soundTag);
+ if (sound != null) sound.Play(volume);
+ }
+
+ public static void PlaySound(string soundTag, float volume, float range, Vector2 position)
+ {
+ var sound = GetSound(soundTag);
+ if (sound != null) sound.Play(volume, range, position);
+ }
+
private static void UpdateMusic()
{
if (musicClips == null) return;
List suitableMusic = GetSuitableMusicClips();
- if (suitableMusic.Count > 0 && !suitableMusic.Contains(currentMusic))
+ if (suitableMusic.Count == 0)
+ {
+ targetMusic = null;
+ }
+ else if (!suitableMusic.Contains(currentMusic))
{
int index = Rand.Int(suitableMusic.Count);
@@ -272,7 +320,7 @@ namespace Barotrauma
}
catch (FileNotFoundException e)
{
- DebugConsole.ThrowError("Music clip " + targetMusic.file + " not found!");
+ DebugConsole.ThrowError("Music clip " + targetMusic.file + " not found!", e);
}
currentMusic = targetMusic;
@@ -349,10 +397,15 @@ namespace Barotrauma
PlayDamageSound(damageType, damage, bodyPosition, 800.0f);
}
- public static void PlayDamageSound(DamageSoundType damageType, float damage, Vector2 position, float range = 2000.0f)
+ public static void PlayDamageSound(DamageSoundType damageType, float damage, Vector2 position, float range = 2000.0f, List tags = null)
{
damage = MathHelper.Clamp(damage+Rand.Range(-10.0f, 10.0f), 0.0f, 100.0f);
- var sounds = damageSounds.Where(x => damage >= x.damageRange.X && damage <= x.damageRange.Y && x.damageType == damageType).ToList();
+ var sounds = damageSounds.FindAll(s =>
+ damage >= s.damageRange.X &&
+ damage <= s.damageRange.Y &&
+ s.damageType == damageType &&
+ (string.IsNullOrEmpty(s.requiredTag) || (tags != null && tags.Contains(s.requiredTag))));
+
if (!sounds.Any()) return;
int selectedSound = Rand.Int(sounds.Count);
diff --git a/Subsurface/Source/Sprite.cs b/Subsurface/Source/Sprite.cs
index 2f377e951..0788538fd 100644
--- a/Subsurface/Source/Sprite.cs
+++ b/Subsurface/Source/Sprite.cs
@@ -223,77 +223,79 @@ namespace Barotrauma
DrawTiled(spriteBatch, pos, targetSize, Vector2.Zero, color);
}
- public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Vector2 startOffset, Color color, Point offset)
+ public void DrawTiled(SpriteBatch spriteBatch, Vector2 pos, Vector2 targetSize, Color color, Point offset, float? overrideDepth = null)
{
//how many times the texture needs to be drawn on the x-axis
- int xTiles = (int)Math.Ceiling((targetSize.X + startOffset.X) / sourceRect.Width);
+ int xTiles = (int)Math.Ceiling(targetSize.X / sourceRect.Width);
//how many times the texture needs to be drawn on the y-axis
- int yTiles = (int)Math.Ceiling((targetSize.Y + startOffset.Y) / sourceRect.Height);
-
+ int yTiles = (int)Math.Ceiling(targetSize.Y / sourceRect.Height);
+
+ float depth = overrideDepth == null ? this.depth : (float)overrideDepth;
+
Rectangle texPerspective = sourceRect;
texPerspective.Location += offset;
- while (texPerspective.Location.X >= sourceRect.X + sourceRect.Width)
- texPerspective.X = sourceRect.X + (texPerspective.Location.X - (sourceRect.X + sourceRect.Width));
- while (texPerspective.Location.Y >= sourceRect.Y + sourceRect.Height)
- texPerspective.Y = sourceRect.Y + (texPerspective.Location.Y - (sourceRect.Y + sourceRect.Height));
+ while (texPerspective.X >= sourceRect.Right)
+ texPerspective.X = sourceRect.X + (texPerspective.X - sourceRect.Right);
+ while (texPerspective.Y >= sourceRect.Bottom)
+ texPerspective.Y = sourceRect.Y + (texPerspective.Y - sourceRect.Bottom);
- texPerspective.Width = (int)Math.Min(targetSize.X, sourceRect.Width);
+ float top = pos.Y;
texPerspective.Height = (int)Math.Min(targetSize.Y, sourceRect.Height);
+
for (int y = 0; y < yTiles; y++)
{
+ var movementY = texPerspective.Height;
+ texPerspective.Height = Math.Min((int)(targetSize.Y - texPerspective.Height * y), texPerspective.Height);
+
+ float left = pos.X;
texPerspective.Width = (int)Math.Min(targetSize.X, sourceRect.Width);
- texPerspective.Height = (int)Math.Min(targetSize.Y, sourceRect.Height);
- float top = pos.Y + texPerspective.Height * y;
+
for (int x = 0; x < xTiles; x++)
{
- float left = pos.X + texPerspective.Width * x;
- texPerspective.Width = Math.Min((int)(targetSize.X - texPerspective.Width * x), texPerspective.Width);
- texPerspective.Height = Math.Min((int)(targetSize.Y - texPerspective.Height * y), texPerspective.Height);
-
var movementX = texPerspective.Width;
- var movementY = texPerspective.Height;
+ texPerspective.Width = Math.Min((int)(targetSize.X - texPerspective.Width * x), texPerspective.Width);
+
if (texPerspective.Right > sourceRect.Right)
{
+ int diff = texPerspective.Right - sourceRect.Right;
if (effects.HasFlag(SpriteEffects.FlipHorizontally))
{
- int diff = (texPerspective.X + texPerspective.Width) - (sourceRect.Right);
-
- spriteBatch.Draw(texture,
- new Vector2(left, top),
- new Rectangle(sourceRect.X, texPerspective.Y, diff, texPerspective.Height),
+ spriteBatch.Draw(texture,
+ new Vector2(left, top),
+ new Rectangle(sourceRect.X, texPerspective.Y, diff, texPerspective.Height),
color, rotation, Vector2.Zero, 1.0f, effects, depth);
-
+
texPerspective.Width -= diff;
left += diff;
}
else
{
- float diff = (texPerspective.X + texPerspective.Width) - (sourceRect.X + sourceRect.Width);
texPerspective.Width -= (int)diff;
- spriteBatch.Draw(texture,
- new Vector2(left + texPerspective.Width, top),
- new Rectangle(sourceRect.X, texPerspective.Y, (int)diff, texPerspective.Height),
- color, rotation, Vector2.Zero, 1.0f, effects, depth);
+ spriteBatch.Draw(texture,
+ new Vector2(left + texPerspective.Width, top),
+ new Rectangle(sourceRect.X, texPerspective.Y, (int)diff, texPerspective.Height),
+ color, rotation, Vector2.Zero, 1.0f, effects, depth);
}
}
else if (texPerspective.Bottom > sourceRect.Bottom)
{
- int diff = (texPerspective.Bottom) - (sourceRect.Bottom);
+ int diff = texPerspective.Bottom - sourceRect.Bottom;
texPerspective.Height -= diff;
- spriteBatch.Draw(texture,
- new Vector2(left, top + texPerspective.Height),
- new Rectangle(texPerspective.X, sourceRect.Y, texPerspective.Width, diff),
+ spriteBatch.Draw(texture,
+ new Vector2(left, top + texPerspective.Height),
+ new Rectangle(texPerspective.X, sourceRect.Y, texPerspective.Width, diff),
color, rotation, Vector2.Zero, 1.0f, effects, depth);
}
spriteBatch.Draw(texture, new Vector2(left, top), texPerspective, color, rotation, Vector2.Zero, 1.0f, effects, depth);
- if (texPerspective.X + movementX >= sourceRect.Right)
- texPerspective.X = sourceRect.X;
- if (texPerspective.Y + movementY >= sourceRect.Y + sourceRect.Height)
- texPerspective.Y = sourceRect.Y;
+ if (texPerspective.X + movementX >= sourceRect.Right) texPerspective.X = sourceRect.X;
+ left += movementX;
}
+
+ if (texPerspective.Y + movementY >= sourceRect.Bottom) texPerspective.Y = sourceRect.Y;
+ top += movementY;
}
}
diff --git a/Subsurface/Source/Utils/MathUtils.cs b/Subsurface/Source/Utils/MathUtils.cs
index 695be7904..ccdf61cc5 100644
--- a/Subsurface/Source/Utils/MathUtils.cs
+++ b/Subsurface/Source/Utils/MathUtils.cs
@@ -233,10 +233,44 @@ namespace Barotrauma
new Vector2(rect.Right, rect.Y - rect.Height));
}
+ public static List GetLineRectangleIntersections(Vector2 a1, Vector2 a2, Rectangle rect)
+ {
+ List intersections = new List();
+
+ Vector2? intersection = GetLineIntersection(a1, a2,
+ new Vector2(rect.X, rect.Y),
+ new Vector2(rect.Right, rect.Y));
+
+ if (intersection != null) intersections.Add((Vector2)intersection);
+
+ intersection = GetLineIntersection(a1, a2,
+ new Vector2(rect.X, rect.Y - rect.Height),
+ new Vector2(rect.Right, rect.Y - rect.Height));
+
+ if (intersection != null) intersections.Add((Vector2)intersection);
+
+ intersection = GetLineIntersection(a1, a2,
+ new Vector2(rect.X, rect.Y),
+ new Vector2(rect.X, rect.Y - rect.Height));
+
+ if (intersection != null) intersections.Add((Vector2)intersection);
+
+ intersection = GetLineIntersection(a1, a2,
+ new Vector2(rect.Right, rect.Y),
+ new Vector2(rect.Right, rect.Y - rect.Height));
+
+ if (intersection != null) intersections.Add((Vector2)intersection);
+
+ return intersections;
+ }
+
public static float LineToPointDistance(Vector2 lineA, Vector2 lineB, Vector2 point)
{
- return (float)(Math.Abs((lineB.X-lineA.X)*(lineA.Y - point.Y) - (lineA.X - point.X)*(lineB.Y-lineA.Y)) /
- Math.Sqrt(Math.Pow(lineB.X - lineA.X, 2) + Math.Pow(lineB.Y - lineA.Y, 2)));
+ float xDiff = lineB.X - lineA.X;
+ float yDiff = lineB.Y - lineA.Y;
+
+ return (float)(Math.Abs(xDiff * (lineA.Y - point.Y) - yDiff * (lineA.X - point.X)) /
+ Math.Sqrt(xDiff * xDiff + yDiff * yDiff));
}
public static bool CircleIntersectsRectangle(Vector2 circlePos, float radius, Rectangle rect)
diff --git a/Subsurface/Source/Utils/SaveUtil.cs b/Subsurface/Source/Utils/SaveUtil.cs
index 3a4a3a5bb..b78fee054 100644
--- a/Subsurface/Source/Utils/SaveUtil.cs
+++ b/Subsurface/Source/Utils/SaveUtil.cs
@@ -22,9 +22,19 @@ namespace Barotrauma
fileName = Path.Combine(SaveFolder, fileName);
string tempPath = Path.Combine(SaveFolder, "temp");
-
- Directory.CreateDirectory(tempPath);
+ DirectoryInfo dir = new DirectoryInfo(tempPath);
+
+ Directory.CreateDirectory(tempPath);
+ try
+ {
+ ClearFolder(tempPath);
+ }
+ catch
+ {
+
+ }
+
try
{
if (Submarine.MainSub != null)
@@ -274,5 +284,22 @@ namespace Barotrauma
using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true))
while (DecompressFile(sDir, zipStream, progress)) ;
}
+
+ private static void ClearFolder(string FolderName)
+ {
+ DirectoryInfo dir = new DirectoryInfo(FolderName);
+
+ foreach (FileInfo fi in dir.GetFiles())
+ {
+ fi.IsReadOnly = false;
+ fi.Delete();
+ }
+
+ foreach (DirectoryInfo di in dir.GetDirectories())
+ {
+ ClearFolder(di.FullName);
+ di.Delete();
+ }
+ }
}
}
diff --git a/Subsurface/Submarines/Aegir Mark III.sub b/Subsurface/Submarines/Aegir Mark III.sub
index 6cab2cb69..da7dc9ada 100644
Binary files a/Subsurface/Submarines/Aegir Mark III.sub and b/Subsurface/Submarines/Aegir Mark III.sub differ
diff --git a/Subsurface/Submarines/Nehalennia.sub b/Subsurface/Submarines/Nehalennia.sub
index 1a8b8aa01..512b0e158 100644
Binary files a/Subsurface/Submarines/Nehalennia.sub and b/Subsurface/Submarines/Nehalennia.sub differ
diff --git a/Subsurface/Submarines/Vellamo.sub b/Subsurface/Submarines/Vellamo.sub
index 6d35b7f4d..90cb4f5a0 100644
Binary files a/Subsurface/Submarines/Vellamo.sub and b/Subsurface/Submarines/Vellamo.sub differ
diff --git a/Subsurface/changelog.txt b/Subsurface/changelog.txt
index b13ee2981..759fcc61e 100644
--- a/Subsurface/changelog.txt
+++ b/Subsurface/changelog.txt
@@ -1,3 +1,55 @@
+---------------------------------------------------------------------------------------------------------
+v0.5.4.2
+---------------------------------------------------------------------------------------------------------
+
+- fixed crashes when removing nodes from a wire (i.e. right clicking with a wire equipped)
+- fixed inventory not being drawn in the correct position if switching to a character who's been
+dragged/grabbed by some other character
+- fixed wires becoming disconnected when copypasting them
+- wire nodes can't be moved when connecting wires to a connection panel
+- fixed repeating crash messageboxes if the game fails to resolve a SharpDX exception on startup
+- fixed crashing when switching to wiring mode while editing some value of an item
+- fixed keyboard focus staying in textboxes after the textbox has been hidden (for example,
+the input fields in the submarine saving prompt)
+- fixed error message spam if a docking port is linked to another port in the same sub
+- submarine lists in the editor, main menu and server menu are updated when new subs are saved/received
+- fixed item editing menu staying on the screen when loading another sub in the editor
+- ruins cant span above the top of the level anymore
+- the size of the docked subs is taken into account when generating the level
+- fixed autorestart timer not resetting at the clients' end if the server fails to start a shift and
+resets the timer
+- docked subs are forced to correct positions during loading (subs won't get stuck inside each other
+even if the submarines are slightly overlapping in the editor)
+
+- all sounds are paused when switching to submarine editor
+- replaced the solid black color inside ice walls with a proper texture
+- the background ice texture loops better
+
+---------------------------------------------------------------------------------------------------------
+v0.5.4.1
+---------------------------------------------------------------------------------------------------------
+
+Bugfixes:
+ - copypasted items are now correctly aligned to the "grid"
+ - cabinets can be copypasted from a sub to another without the items inside disappearing
+ - placing explosives inside an item and that item inside another item doesn't prevent explosions
+ - fixed a bug that occasionally caused crashing when the game happens to generate a very small level
+
+Sub editor:
+ - structures/items that are behind something else can be selected using a listbox that appears
+ when hovering the cursor over them
+ - wires have to be selected by clicking before any of the points can be moved (makes it possible
+ to move the correct wire even if it's overlapping with other wires)
+ - the selected wire is renderer over all structures
+ - points can be added to wires by clicking while holding ctrl
+ - disabled music
+
+Misc:
+ - some rendering optimization
+ - pathfinding and waypoint generation improvements
+ - made mantises more aggressive
+ - water flows more slowly through partially damaged walls
+
---------------------------------------------------------------------------------------------------------
v0.5.4.0
---------------------------------------------------------------------------------------------------------