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).
This commit is contained in:
Joonas Rikkonen
2017-06-21 20:45:33 +03:00
parent db9a77fb25
commit de00eb2ab4
5 changed files with 111 additions and 42 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
<Body width="32" height="32" density="40"/>
<Controller direction ="None" canbepicked = "true" msg="Open [E]">
<Controller direction ="None" canbepicked = "true" msg="Press [E]">
<RequiredItem name="ID Card" type="Picked" msg="UNAUTHORIZED ACCESS"/>
<sound file="beep.ogg" type="OnUse" range="500.0"/>
</Controller>
@@ -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<RelatedItem> 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<RelatedItem>(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<RelatedItem>(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();
}
}
}
}
@@ -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))
{
@@ -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)]
@@ -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;