diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Door.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Door.cs
index 193ce722a..90c3e8bbc 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Door.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Door.cs
@@ -87,11 +87,7 @@ namespace Barotrauma.Items.Components
public void Draw(SpriteBatch spriteBatch, bool editing)
{
Color color = (item.IsSelected) ? Color.Green : Color.White;
- color = color * (item.Condition / item.Prefab.Health);
- color.A = 255;
-
- //prefab.sprite.Draw(spriteBatch, new Vector2(rect.X, -rect.Y), new Vector2(rect.Width, rect.Height), color);
-
+
if (stuck > 0.0f && weldedSprite != null)
{
Vector2 weldSpritePos = new Vector2(item.Rect.Center.X, item.Rect.Y - item.Rect.Height / 2.0f);
@@ -114,10 +110,25 @@ namespace Barotrauma.Items.Components
if (item.Submarine != null) pos += item.Submarine.DrawPosition;
pos.Y = -pos.Y;
- spriteBatch.Draw(doorSprite.Texture, pos,
- new Rectangle((int)(doorSprite.SourceRect.X + doorSprite.size.X * openState), (int)doorSprite.SourceRect.Y,
- (int)(doorSprite.size.X * (1.0f - openState)), (int)doorSprite.size.Y),
- color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
+ if (brokenSprite == null || item.Health > 0.0f)
+ {
+ spriteBatch.Draw(doorSprite.Texture, pos,
+ new Rectangle((int) (doorSprite.SourceRect.X + doorSprite.size.X * openState),
+ (int) doorSprite.SourceRect.Y,
+ (int) (doorSprite.size.X * (1.0f - openState)), (int) doorSprite.size.Y),
+ color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
+ }
+
+ if (brokenSprite != null && item.Health < item.Prefab.Health)
+ {
+ Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f, 1.0f - item.Health / item.Prefab.Health) : Vector2.One;
+ float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.Prefab.Health : 1.0f;
+ spriteBatch.Draw(brokenSprite.Texture, pos,
+ new Rectangle((int)(brokenSprite.SourceRect.X + brokenSprite.size.X * openState), brokenSprite.SourceRect.Y,
+ (int)(brokenSprite.size.X * (1.0f - openState)), (int)brokenSprite.size.Y),
+ color * alpha, 0.0f, brokenSprite.Origin, scale, SpriteEffects.None,
+ brokenSprite.Depth);
+ }
}
else
{
@@ -125,10 +136,25 @@ namespace Barotrauma.Items.Components
if (item.Submarine != null) pos += item.Submarine.DrawPosition;
pos.Y = -pos.Y;
- spriteBatch.Draw(doorSprite.Texture, pos,
- new Rectangle(doorSprite.SourceRect.X, (int)(doorSprite.SourceRect.Y + doorSprite.size.Y * openState),
- (int)doorSprite.size.X, (int)(doorSprite.size.Y * (1.0f - openState))),
- color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
+ if (brokenSprite == null || item.Health > 0.0f)
+ {
+ spriteBatch.Draw(doorSprite.Texture, pos,
+ new Rectangle(doorSprite.SourceRect.X,
+ (int) (doorSprite.SourceRect.Y + doorSprite.size.Y * openState),
+ (int) doorSprite.size.X, (int) (doorSprite.size.Y * (1.0f - openState))),
+ color, 0.0f, doorSprite.Origin, 1.0f, SpriteEffects.None, doorSprite.Depth);
+ }
+
+ if (brokenSprite != null && item.Health < item.Prefab.Health)
+ {
+ Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f - item.Health / item.Prefab.Health, 1.0f) : Vector2.One;
+ float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.Prefab.Health : 1.0f;
+ spriteBatch.Draw(brokenSprite.Texture, pos,
+ new Rectangle(brokenSprite.SourceRect.X, (int)(brokenSprite.SourceRect.Y + brokenSprite.size.Y * openState),
+ (int)brokenSprite.size.X, (int)(brokenSprite.size.Y * (1.0f - openState))),
+ color * alpha, 0.0f, brokenSprite.Origin, scale, SpriteEffects.None, brokenSprite.Depth);
+ }
+
}
}
diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems
index 2691ec529..8f03bf746 100644
--- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems
+++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems
@@ -289,6 +289,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Barotrauma/BarotraumaShared/Content/Items/Door/door.png b/Barotrauma/BarotraumaShared/Content/Items/Door/door.png
index 435e2a5bf..2b15f795a 100644
Binary files a/Barotrauma/BarotraumaShared/Content/Items/Door/door.png and b/Barotrauma/BarotraumaShared/Content/Items/Door/door.png differ
diff --git a/Barotrauma/BarotraumaShared/Content/Items/Door/doors.xml b/Barotrauma/BarotraumaShared/Content/Items/Door/doors.xml
index a90974cfa..120365d6c 100644
--- a/Barotrauma/BarotraumaShared/Content/Items/Door/doors.xml
+++ b/Barotrauma/BarotraumaShared/Content/Items/Door/doors.xml
@@ -9,6 +9,7 @@
+
@@ -32,11 +33,12 @@
linkable="true"
>
-
+
-
-
+
+
+
@@ -60,11 +62,12 @@
linkable="true"
>
-
+
-
-
+
+
+
diff --git a/Barotrauma/BarotraumaShared/Content/Items/Door/hatch.png b/Barotrauma/BarotraumaShared/Content/Items/Door/hatch.png
new file mode 100644
index 000000000..73fa437cc
Binary files /dev/null and b/Barotrauma/BarotraumaShared/Content/Items/Door/hatch.png differ
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs
index 7d3123786..eb68e1949 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs
@@ -25,7 +25,8 @@ namespace Barotrauma.Items.Components
private PhysicsBody body;
- private Sprite doorSprite, weldedSprite;
+ private Sprite doorSprite, weldedSprite, brokenSprite;
+ private bool scaleBrokenSprite, fadeBrokenSprite;
private bool isHorizontal;
@@ -34,6 +35,28 @@ namespace Barotrauma.Items.Components
private bool? predictedState;
private float resetPredictionTimer;
+ private Rectangle doorRect;
+
+ private bool isBroken;
+
+ public bool IsBroken
+ {
+ get { return isBroken; }
+ set
+ {
+ if (isBroken == value) return;
+ isBroken = value;
+ if (isBroken)
+ {
+ DisableBody();
+ }
+ else
+ {
+ EnableBody();
+ }
+ }
+ }
+
public PhysicsBody Body
{
get { return body; }
@@ -45,7 +68,7 @@ namespace Barotrauma.Items.Components
get { return stuck; }
set
{
- if (isOpen) return;
+ if (isOpen || isBroken) return;
stuck = MathHelper.Clamp(value, 0.0f, 100.0f);
if (stuck == 0.0f) isStuck = false;
if (stuck == 100.0f) isStuck = true;
@@ -117,8 +140,6 @@ namespace Barotrauma.Items.Components
OpenState = (isOpen) ? 1.0f : 0.0f;
}
}
-
- private Rectangle doorRect;
public float OpenState
{
@@ -139,11 +160,8 @@ namespace Barotrauma.Items.Components
public Door(Item item, XElement element)
: base(item, element)
{
- //Vector2 position = new Vector2(newRect.X, newRect.Y);
-
isHorizontal = element.GetAttributeBool("horizontal", false);
-
- // isOpen = false;
+
foreach (XElement subElement in element.Elements())
{
string texturePath = subElement.GetAttributeString("texture", "");
@@ -155,6 +173,11 @@ namespace Barotrauma.Items.Components
case "weldedsprite":
weldedSprite = new Sprite(subElement, texturePath.Contains("/") ? "" : Path.GetDirectoryName(item.Prefab.ConfigFile));
break;
+ case "brokensprite":
+ brokenSprite = new Sprite(subElement, texturePath.Contains("/") ? "" : Path.GetDirectoryName(item.Prefab.ConfigFile));
+ scaleBrokenSprite = subElement.GetAttributeBool("scale", false);
+ fadeBrokenSprite = subElement.GetAttributeBool("fade", false);
+ break;
}
}
@@ -177,9 +200,6 @@ namespace Barotrauma.Items.Components
ConvertUnits.ToSimUnits(new Vector2(doorRect.Center.X, doorRect.Y - doorRect.Height / 2)),
0.0f);
body.Friction = 0.5f;
-
-
- //string spritePath = Path.GetDirectoryName(item.Prefab.ConfigFile) + "\\"+ ToolBox.GetAttributeString(element, "sprite", "");
IsActive = true;
}
@@ -187,17 +207,12 @@ namespace Barotrauma.Items.Components
public override void Move(Vector2 amount)
{
base.Move(amount);
-
- //LinkedGap.Move(amount);
-
+
body.SetTransform(body.SimPosition + ConvertUnits.ToSimUnits(amount), 0.0f);
#if CLIENT
UpdateConvexHulls();
#endif
-
- //convexHull.Move(amount);
- //if (convexHull2 != null) convexHull2.Move(amount);
}
@@ -216,17 +231,27 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
+ if (isBroken)
+ {
+ //the door has to be restored to 50% health before collision detection on the body is re-enabled
+ if (item.Condition > 50.0f)
+ {
+ IsBroken = false;
+ }
+ return;
+ }
+
bool isClosing = false;
if (!isStuck)
{
if (predictedState == null)
{
- OpenState += deltaTime * ((isOpen) ? 2.0f : -2.0f);
+ OpenState += deltaTime * (isOpen ? 2.0f : -2.0f);
isClosing = openState > 0.0f && openState < 1.0f && !isOpen;
}
else
{
- OpenState += deltaTime * (((bool)predictedState) ? 2.0f : -2.0f);
+ OpenState += deltaTime * ((bool)predictedState ? 2.0f : -2.0f);
isClosing = openState > 0.0f && openState < 1.0f && !(bool)predictedState;
resetPredictionTimer -= deltaTime;
@@ -252,14 +277,34 @@ namespace Barotrauma.Items.Components
//other items to an incorrect state if the prediction is wrong
item.SendSignal(0, (isOpen) ? "1" : "0", "state_out", null);
}
-
+
public override void UpdateBroken(float deltaTime, Camera cam)
{
- body.Enabled = false;
-
- linkedGap.Open = 1.0f;
+ IsBroken = true;
}
-
+
+ private void EnableBody()
+ {
+ body.FarseerBody.IsSensor = false;
+#if CLIENT
+ UpdateConvexHulls();
+#endif
+ isBroken = false;
+ }
+
+ private void DisableBody()
+ {
+ //change the body to a sensor instead of disabling it completely,
+ //because otherwise repairtool raycasts won't hit it
+ body.FarseerBody.IsSensor = true;
+ linkedGap.Open = 1.0f;
+ IsOpen = false;
+#if CLIENT
+ if (convexHull != null) convexHull.Enabled = false;
+ if (convexHull2 != null) convexHull2.Enabled = false;
+#endif
+ }
+
public override void OnMapLoaded()
{
LinkedGap.ConnectedDoor = this;
@@ -280,19 +325,19 @@ namespace Barotrauma.Items.Components
base.RemoveComponentSpecific();
if (body != null)
- {
+ {
body.Remove();
body = null;
}
- if (linkedGap!=null) linkedGap.Remove();
+ if (linkedGap != null) linkedGap.Remove();
doorSprite.Remove();
if (weldedSprite != null) weldedSprite.Remove();
#if CLIENT
- if (convexHull!=null) convexHull.Remove();
+ if (convexHull != null) convexHull.Remove();
if (convexHull2 != null) convexHull2.Remove();
#endif
}
@@ -398,8 +443,8 @@ namespace Barotrauma.Items.Components
{
//clients can "predict" that the door opens/closes when a signal is received
-//the prediction will be reset after 1 second, setting the door to a state
-//sent by the server, or reverting it back to its old state if no msg from server was received
+ //the prediction will be reset after 1 second, setting the door to a state
+ //sent by the server, or reverting it back to its old state if no msg from server was received
#if CLIENT
if (open != predictedState) PlaySound(ActionType.OnUse, item.WorldPosition);
@@ -437,7 +482,7 @@ namespace Barotrauma.Items.Components
{
SetState(msg.ReadBoolean(), true);
Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
-
+
predictedState = null;
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs
index f80b113ab..4d385c36d 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs
@@ -176,7 +176,7 @@ namespace Barotrauma.Items.Components
}
Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies,
- Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel);
+ Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel, false);
if (targetBody == null || targetBody.UserData == null) return;
diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs
index dd5318715..fb36727a2 100644
--- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs
+++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs
@@ -509,7 +509,7 @@ namespace Barotrauma
}
}
- public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List
ignoredBodies = null, Category? collisionCategory = null)
+ public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true)
{
if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.00001f)
{
@@ -521,7 +521,7 @@ namespace Barotrauma
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
if (fixture == null ||
- fixture.IsSensor ||
+ (ignoreSensors && fixture.IsSensor) ||
fixture.CollisionCategories == Category.None ||
fixture.CollisionCategories == Physics.CollisionItem) return -1;
@@ -556,7 +556,7 @@ namespace Barotrauma
/// check visibility between two points (in sim units)
///
/// a physics body that was between the points (or null)
- public static Body CheckVisibility(Vector2 rayStart, Vector2 rayEnd, bool ignoreLevel = false, bool ignoreSubs = false)
+ public static Body CheckVisibility(Vector2 rayStart, Vector2 rayEnd, bool ignoreLevel = false, bool ignoreSubs = false, bool ignoreSensors = true)
{
Body closestBody = null;
float closestFraction = 1.0f;
@@ -569,7 +569,8 @@ namespace Barotrauma
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
- if (fixture == null || fixture.IsSensor ||
+ if (fixture == null ||
+ (ignoreSensors && fixture.IsSensor) ||
(!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) && !fixture.CollisionCategories.HasFlag(Physics.CollisionLevel))) return -1;
if (ignoreLevel && fixture.CollisionCategories == Physics.CollisionLevel) return -1;