From de00eb2ab4d21b754581f6751b244d3abd2449f5 Mon Sep 17 00:00:00 2001
From: Joonas Rikkonen
Date: Wed, 21 Jun 2017 20:45:33 +0300
Subject: [PATCH] Some fixes to attachable items (buttons, signal items, etc):
- Syncing the attached/detached state of the items. This should fix the
"received a position update for an item with no physics body " errors:
midround-joining clients didn't get notified if an item had been detached,
causing the error to appear every time it receives a position update. -
Detached items can be picked up just like any other item, instead of having
to use a wrench and wait for the item to "detach". - Wires can't be connected
to items with a physics body (such as detached buttons).
---
Barotrauma/Content/Items/Button/button.xml | 2 +-
.../Items/Components/Holdable/Holdable.cs | 136 +++++++++++++-----
.../Items/Components/Holdable/Pickable.cs | 4 +-
.../Source/Items/Components/ItemComponent.cs | 4 +-
.../Components/Signal/ConnectionPanel.cs | 7 +
5 files changed, 111 insertions(+), 42 deletions(-)
diff --git a/Barotrauma/Content/Items/Button/button.xml b/Barotrauma/Content/Items/Button/button.xml
index 35954a92c..40c4df950 100644
--- a/Barotrauma/Content/Items/Button/button.xml
+++ b/Barotrauma/Content/Items/Button/button.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/Barotrauma/Source/Items/Components/Holdable/Holdable.cs b/Barotrauma/Source/Items/Components/Holdable/Holdable.cs
index cc57a1cb4..e32101497 100644
--- a/Barotrauma/Source/Items/Components/Holdable/Holdable.cs
+++ b/Barotrauma/Source/Items/Components/Holdable/Holdable.cs
@@ -2,17 +2,18 @@
using FarseerPhysics;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
+using Barotrauma.Networking;
+using Lidgren.Network;
namespace Barotrauma.Items.Components
{
- class Holdable : Pickable
+ class Holdable : Pickable, IServerSerializable
{
//the position(s) in the item that the Character grabs
protected Vector2[] handlePos;
-
- private List prevRequiredItems;
-
- string prevMsg;
+
+ private InputType prevPickKey;
+ private string prevMsg;
//the distance from the holding characters elbow to center of the physics body of the item
protected Vector2 holdPos;
@@ -94,25 +95,28 @@ namespace Barotrauma.Items.Components
if (attachable)
{
- prevRequiredItems = new List(requiredItems);
prevMsg = Msg;
+ prevPickKey = PickKey;
- requiredItems.Clear();
- Msg = "";
+ DeattachFromWall();
}
-
- if (attachedByDefault || (Screen.Selected == GameMain.EditMapScreen)) Use(1.0f);
-
-
- //holdAngle = ToolBox.GetAttributeFloat(element, "holdangle", 0.0f);
- //holdAngle = MathHelper.ToRadians(holdAngle);
+
+ if ((Screen.Selected == GameMain.EditMapScreen)) Use(1.0f);
}
public override void Drop(Character dropper)
{
DropConnectedWires(dropper);
- if (body != null) item.body = body;
+ if (attachable)
+ {
+ DeattachFromWall();
+
+ if (body != null)
+ {
+ item.body = body;
+ }
+ }
if (item.body != null) item.body.Enabled = true;
IsActive = false;
@@ -121,7 +125,6 @@ namespace Barotrauma.Items.Components
{
if (dropper == null) return;
picker = dropper;
-
}
if (picker.Inventory == null) return;
@@ -190,29 +193,36 @@ namespace Barotrauma.Items.Components
return base.Pick(picker);
}
- if (!base.Pick(picker))
+ if (Attached)
{
- return false;
+ return base.Pick(picker);
}
else
{
- requiredItems.Clear();
- Msg = "";
+ //not attached -> pick the item instantly, ignoring picking time
+ return OnPicked(picker);
}
-
- attached = false;
- if (body != null) item.body = body;
- //item.body.Enabled = true;
-
- return true;
}
- public override bool Use(float deltaTime, Character character = null)
+ protected override bool OnPicked(Character picker)
{
- if (!attachable || item.body == null) return true;
- if (character != null && !character.IsKeyDown(InputType.Aim)) return false;
+ if (base.OnPicked(picker))
+ {
+ DeattachFromWall();
- item.Drop();
+ if (GameMain.Server != null && attachable)
+ {
+ item.CreateServerEvent(this);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ private void AttachToWall()
+ {
+ if (!attachable) return;
var containedItems = item.ContainedItems;
if (containedItems != null)
@@ -226,12 +236,40 @@ namespace Barotrauma.Items.Components
item.body.Enabled = false;
item.body = null;
-
- requiredItems = new List(prevRequiredItems);
+
Msg = prevMsg;
+ PickKey = prevPickKey;
attached = true;
+ }
+
+ private void DeattachFromWall()
+ {
+ if (!attachable) return;
+
+ attached = false;
+
+ //make the item pickable with the default pick key and with no specific tools/items when it's deattached
+ requiredItems.Clear();
+ Msg = "";
+ PickKey = InputType.Select;
+ }
+
+ public override bool Use(float deltaTime, Character character = null)
+ {
+ if (!attachable || item.body == null) return true;
+ if (character != null)
+ {
+ if (!character.IsKeyDown(InputType.Aim)) return false;
+ if (character != null && GameMain.Server != null)
+ {
+ item.CreateServerEvent(this);
+ }
+ item.Drop();
+ }
+ AttachToWall();
+
return true;
}
@@ -284,13 +322,39 @@ namespace Barotrauma.Items.Components
item.body = body;
body.Enabled = false;
}
- attached = false;
}
+ attached = false;
- requiredItems.Clear();
- Msg = "";
+ DeattachFromWall();
+ }
+ }
+
+ public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
+ {
+ msg.Write(Attached);
+ }
+
+ public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
+ {
+ bool isAttached = msg.ReadBoolean();
+ if (isAttached)
+ {
+ item.Drop();
+ AttachToWall();
+ }
+ else
+ {
+ DropConnectedWires(null);
+
+ if (body != null)
+ {
+ item.body = body;
+ item.body.Enabled = true;
+ }
+ IsActive = false;
+
+ DeattachFromWall();
}
}
-
}
}
diff --git a/Barotrauma/Source/Items/Components/Holdable/Pickable.cs b/Barotrauma/Source/Items/Components/Holdable/Pickable.cs
index 589dbd8b3..7bfab6563 100644
--- a/Barotrauma/Source/Items/Components/Holdable/Pickable.cs
+++ b/Barotrauma/Source/Items/Components/Holdable/Pickable.cs
@@ -70,11 +70,9 @@ namespace Barotrauma.Items.Components
{
return OnPicked(picker);
}
-
-
}
- private bool OnPicked(Character picker)
+ protected virtual bool OnPicked(Character picker)
{
if (picker.Inventory.TryPutItem(item, allowedSlots))
{
diff --git a/Barotrauma/Source/Items/Components/ItemComponent.cs b/Barotrauma/Source/Items/Components/ItemComponent.cs
index 502832d43..c47ab83df 100644
--- a/Barotrauma/Source/Items/Components/ItemComponent.cs
+++ b/Barotrauma/Source/Items/Components/ItemComponent.cs
@@ -153,13 +153,13 @@ namespace Barotrauma.Items.Components
public InputType PickKey
{
get;
- private set;
+ protected set;
}
public InputType SelectKey
{
get;
- private set;
+ protected set;
}
[HasDefaultValue(false, false)]
diff --git a/Barotrauma/Source/Items/Components/Signal/ConnectionPanel.cs b/Barotrauma/Source/Items/Components/Signal/ConnectionPanel.cs
index 6451c3c4a..5b7aec76b 100644
--- a/Barotrauma/Source/Items/Components/Signal/ConnectionPanel.cs
+++ b/Barotrauma/Source/Items/Components/Signal/ConnectionPanel.cs
@@ -90,6 +90,13 @@ namespace Barotrauma.Items.Components
public override bool Select(Character picker)
{
+ //attaching wires to items with a body is not allowed
+ //(signal items remove their bodies when attached to a wall)
+ if (item.body != null)
+ {
+ return false;
+ }
+
user = picker;
IsActive = true;
return true;