2f107db...5202af9

This commit is contained in:
Joonas Rikkonen
2019-03-18 21:42:26 +02:00
parent 58c92888b7
commit 044fd3344b
395 changed files with 27417 additions and 19754 deletions
@@ -180,7 +180,7 @@ namespace Barotrauma.Items.Components
source.LastSentSignalRecipients.Add(recipient.item);
}
foreach (ItemComponent ic in recipient.item.components)
foreach (ItemComponent ic in recipient.item.Components)
{
ic.ReceiveSignal(stepsTaken, signal, recipient, source, sender, power, signalStrength);
}
@@ -220,144 +220,5 @@ namespace Barotrauma.Items.Components
}
}
}
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
{
List<Wire>[] wires = new List<Wire>[Connections.Count];
//read wire IDs for each connection
for (int i = 0; i < Connections.Count; i++)
{
wires[i] = new List<Wire>();
for (int j = 0; j < Connection.MaxLinked; j++)
{
ushort wireId = msg.ReadUInt16();
Item wireItem = Entity.FindEntityByID(wireId) as Item;
if (wireItem == null) continue;
Wire wireComponent = wireItem.GetComponent<Wire>();
if (wireComponent != null)
{
wires[i].Add(wireComponent);
}
}
}
//don't allow rewiring locked panels
if (Locked) return;
item.CreateServerEvent(this);
//check if the character can access this connectionpanel
//and all the wires they're trying to connect
if (!item.CanClientAccess(c)) return;
for (int i = 0; i < Connections.Count; i++)
{
foreach (Wire wire in wires[i])
{
//wire not found in any of the connections yet (client is trying to connect a new wire)
// -> we need to check if the client has access to it
if (!Connections.Any(connection => connection.Wires.Contains(wire)))
{
if (!wire.Item.CanClientAccess(c)) return;
}
}
}
//go through existing wire links
for (int i = 0; i < Connections.Count; i++)
{
int j = -1;
foreach (Wire existingWire in Connections[i].Wires)
{
j++;
if (existingWire == null) continue;
//existing wire not in the list of new wires -> disconnect it
if (!wires[i].Contains(existingWire))
{
if (existingWire.Locked)
{
//this should not be possible unless the client is running a modified version of the game
GameServer.Log(c.Character.LogName + " attempted to disconnect a locked wire from " +
Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Error);
continue;
}
existingWire.RemoveConnection(item);
if (existingWire.Connections[0] == null && existingWire.Connections[1] == null)
{
GameServer.Log(c.Character.LogName + " disconnected a wire from " +
Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.ItemInteraction);
}
else if (existingWire.Connections[0] != null)
{
GameServer.Log(c.Character.LogName + " disconnected a wire from " +
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[0].Item.Name + " (" + existingWire.Connections[0].Name + ")", ServerLog.MessageType.ItemInteraction);
//wires that are not in anyone's inventory (i.e. not currently being rewired)
//can never be connected to only one connection
// -> the client must have dropped the wire from the connection panel
if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire)))
{
//let other clients know the item was also disconnected from the other connection
existingWire.Connections[0].Item.CreateServerEvent(existingWire.Connections[0].Item.GetComponent<ConnectionPanel>());
existingWire.Item.Drop(c.Character);
}
}
else if (existingWire.Connections[1] != null)
{
GameServer.Log(c.Character.LogName + " disconnected a wire from " +
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[1].Item.Name + " (" + existingWire.Connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire)))
{
//let other clients know the item was also disconnected from the other connection
existingWire.Connections[1].Item.CreateServerEvent(existingWire.Connections[1].Item.GetComponent<ConnectionPanel>());
existingWire.Item.Drop(c.Character);
}
}
Connections[i].SetWire(j, null);
}
}
}
//go through new wires
for (int i = 0; i < Connections.Count; i++)
{
foreach (Wire newWire in wires[i])
{
//already connected, no need to do anything
if (Connections[i].Wires.Contains(newWire)) continue;
Connections[i].TryAddLink(newWire);
newWire.Connect(Connections[i], true, true);
var otherConnection = newWire.OtherConnection(Connections[i]);
if (otherConnection == null)
{
GameServer.Log(c.Character.LogName + " connected a wire to " +
Connections[i].Item.Name + " (" + Connections[i].Name + ")",
ServerLog.MessageType.ItemInteraction);
}
else
{
GameServer.Log(c.Character.LogName + " connected a wire from " +
Connections[i].Item.Name + " (" + Connections[i].Name + ") to " +
(otherConnection == null ? "none" : otherConnection.Item.Name + " (" + (otherConnection.Name) + ")"),
ServerLog.MessageType.ItemInteraction);
}
}
}
}
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
{
ClientWrite(msg, extraData);
}
}
}
@@ -137,57 +137,5 @@ namespace Barotrauma.Items.Components
item.SendSignal(0, ciElement.State ? ciElement.Signal : "0", ciElement.Connection, sender: null, source: item);
}
}
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
{
bool[] elementStates = new bool[customInterfaceElementList.Count];
for (int i = 0; i < customInterfaceElementList.Count; i++)
{
elementStates[i] = msg.ReadBoolean();
}
CustomInterfaceElement clickedButton = null;
if (item.CanClientAccess(c))
{
for (int i = 0; i < customInterfaceElementList.Count; i++)
{
if (customInterfaceElementList[i].ContinuousSignal)
{
TickBoxToggled(customInterfaceElementList[i], elementStates[i]);
}
else if (elementStates[i])
{
clickedButton = customInterfaceElementList[i];
ButtonClicked(customInterfaceElementList[i]);
}
}
}
//notify all clients of the new state
GameMain.Server.CreateEntityEvent(item, new object[]
{
NetEntityEvent.Type.ComponentState,
item.components.IndexOf(this),
clickedButton
});
item.CreateServerEvent(this);
}
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
{
//extradata contains an array of buttons clicked by a client (or nothing if nothing was clicked)
for (int i = 0; i < customInterfaceElementList.Count; i++)
{
if (customInterfaceElementList[i].ContinuousSignal)
{
msg.Write(customInterfaceElementList[i].State);
}
else
{
msg.Write(extraData != null && extraData.Any(d => d as CustomInterfaceElement == customInterfaceElementList[i]));
}
}
}
}
}
@@ -76,7 +76,9 @@ namespace Barotrauma.Items.Components
if (IsActive == value) return;
IsActive = value;
#if SERVER
if (GameMain.Server != null) item.CreateServerEvent(this);
#endif
}
}
@@ -152,6 +154,7 @@ namespace Barotrauma.Items.Components
#endif
IsActive = IsOn;
item.AddTag("light");
}
public override void Update(float deltaTime, Camera cam)
@@ -174,7 +177,7 @@ namespace Barotrauma.Items.Components
if (body != null)
{
#if CLIENT
light.Rotation = body.Dir > 0.0f ? body.Rotation : body.Rotation - MathHelper.Pi;
light.Rotation = body.Dir > 0.0f ? body.DrawRotation : body.DrawRotation - MathHelper.Pi;
light.LightSpriteEffect = (body.Dir > 0.0f) ? SpriteEffects.None : SpriteEffects.FlipVertically;
#endif
if (!body.Enabled)
@@ -234,9 +237,16 @@ namespace Barotrauma.Items.Components
light.Color = lightColor * lightBrightness * (1.0f - Rand.Range(0.0f, Flicker));
light.Range = range;
#endif
item.SightRange = Math.Max(range * (float)Math.Sqrt(lightBrightness), item.SightRange);
}
if (AITarget != null)
{
UpdateAITarget(AITarget);
}
if (item.AiTarget != null)
{
UpdateAITarget(item.AiTarget);
}
voltage = 0.0f;
}
@@ -279,5 +289,16 @@ namespace Barotrauma.Items.Components
{
msg.Write(IsOn);
}
private void UpdateAITarget(AITarget target)
{
//voltage > minVoltage || powerConsumption <= 0.0f; <- ?
target.Enabled = IsActive;
if (target.MaxSightRange <= 0)
{
target.MaxSightRange = Range * 5;
}
target.SightRange = IsActive ? target.MaxSightRange * lightBrightness : 0;
}
}
}
@@ -79,6 +79,13 @@ namespace Barotrauma.Items.Components
set { falseOutput = value; }
}
[Editable(ToolTip = "How fast the objects within the detector's range have to be moving (in m/s).", DecimalCount = 3), Serialize(0.01f, true)]
public float MinimumVelocity
{
get;
set;
}
public MotionSensor(Item item, XElement element)
: base (item, element)
@@ -106,7 +113,7 @@ namespace Barotrauma.Items.Components
if (item.body != null && item.body.Enabled)
{
if (Math.Abs(item.body.LinearVelocity.X) > 0.01f || Math.Abs(item.body.LinearVelocity.Y) > 0.1f)
if (Math.Abs(item.body.LinearVelocity.X) > MinimumVelocity || Math.Abs(item.body.LinearVelocity.Y) > MinimumVelocity)
{
motionDetected = true;
}
@@ -130,7 +137,7 @@ namespace Barotrauma.Items.Components
foreach (Limb limb in c.AnimController.Limbs)
{
if (limb.LinearVelocity.LengthSquared() <= 0.001f) continue;
if (limb.LinearVelocity.LengthSquared() <= MinimumVelocity * MinimumVelocity) continue;
if (MathUtils.CircleIntersectsRectangle(limb.WorldPosition, ConvertUnits.ToDisplayUnits(limb.body.GetMaxExtent()), detectRect))
{
motionDetected = true;
@@ -51,7 +51,10 @@ namespace Barotrauma.Items.Components
item.SendSignal(0, IsOn ? "1" : "0", "state_out", null);
if (Math.Min(-currPowerConsumption, PowerLoad) > maxPower) item.Condition = 0.0f;
if (Math.Min(-currPowerConsumption, PowerLoad) > maxPower && CanBeOverloaded)
{
item.Condition = 0.0f;
}
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
@@ -81,12 +84,16 @@ namespace Barotrauma.Items.Components
public void SetState(bool on, bool isNetworkMessage)
{
#if CLIENT
if (GameMain.Client != null && !isNetworkMessage) return;
#endif
#if SERVER
if (on != IsOn && GameMain.Server != null)
{
item.CreateServerEvent(this);
}
#endif
IsOn = on;
}
@@ -6,6 +6,12 @@ namespace Barotrauma.Items.Components
{
private string output, falseOutput;
//how often the detector can switch from state to another
const float StateSwitchInterval = 1.0f;
private bool isInWater;
private float stateSwitchDelay;
[InGameEditable, Serialize("1", true)]
public string Output
{
@@ -28,22 +34,37 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
string signalOut = falseOutput;
if (item.InWater)
if (stateSwitchDelay > 0.0f)
{
//item in water -> we definitely want to send the True output
signalOut = Output;
stateSwitchDelay -= deltaTime;
}
else if (item.CurrentHull != null)
else
{
//item in not water -> check if there's water anywhere within the rect of the item
if (item.CurrentHull.Surface > item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height + 1 &&
item.CurrentHull.Surface > item.Rect.Y - item.Rect.Height)
bool prevState = isInWater;
isInWater = false;
if (item.InWater)
{
signalOut = output;
//item in water -> we definitely want to send the True output
isInWater = true;
}
else if (item.CurrentHull != null)
{
//item in not water -> check if there's water anywhere within the rect of the item
if (item.CurrentHull.Surface > item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height + 1 &&
item.CurrentHull.Surface > item.Rect.Y - item.Rect.Height)
{
isInWater = true;
}
}
if (prevState != isInWater)
{
stateSwitchDelay = StateSwitchInterval;
}
}
string signalOut = isInWater ? output : falseOutput;
if (!string.IsNullOrEmpty(signalOut))
{
item.SendSignal(0, signalOut, "signal_out", null);
@@ -18,7 +18,7 @@ namespace Barotrauma.Items.Components
private string prevSignal;
public byte TeamID;
public Character.TeamType TeamID;
[Serialize(20000.0f, false)]
public float Range
@@ -134,12 +134,16 @@ namespace Barotrauma.Items.Components
if (chatMsg.Length > ChatMessage.MaxLength) chatMsg = chatMsg.Substring(0, ChatMessage.MaxLength);
if (string.IsNullOrEmpty(chatMsg)) continue;
#if CLIENT
if (wifiComp.item.ParentInventory.Owner == Character.Controlled)
{
if (GameMain.Client == null)
GameMain.NetworkMember.AddChatMessage(signal, ChatMessageType.Radio, source == null ? "" : source.Name);
}
else if (GameMain.Server != null)
#endif
#if SERVER
if (GameMain.Server != null)
{
Client recipientClient = GameMain.Server.ConnectedClients.Find(c => c.Character == wifiComp.item.ParentInventory.Owner);
if (recipientClient != null)
@@ -148,6 +152,7 @@ namespace Barotrauma.Items.Components
ChatMessage.Create(source == null ? "" : source.Name, chatMsg, ChatMessageType.Radio, null), recipientClient);
}
}
#endif
chatMsgSent = true;
}
}
@@ -14,13 +14,24 @@ namespace Barotrauma.Items.Components
partial class WireSection
{
private Vector2 start;
private Vector2 end;
private float angle;
private float length;
public Vector2 Start
{
get { return start; }
}
public Vector2 End
{
get { return end; }
}
public WireSection(Vector2 start, Vector2 end)
{
this.start = start;
this.end = end;
angle = MathUtils.VectorToAngle(end - start);
length = Vector2.Distance(start, end);
@@ -41,6 +52,8 @@ namespace Barotrauma.Items.Components
private bool canPlaceNode;
private Vector2 newNodePos;
private Vector2 sectionExtents;
public bool Hidden;
private bool locked;
@@ -185,7 +198,7 @@ namespace Barotrauma.Items.Components
if (connections[0] != null && connections[1] != null)
{
foreach (ItemComponent ic in item.components)
foreach (ItemComponent ic in item.Components)
{
if (ic == this) continue;
ic.Drop(null);
@@ -202,10 +215,12 @@ namespace Barotrauma.Items.Components
if (sendNetworkEvent)
{
#if SERVER
if (GameMain.Server != null)
{
CreateNetworkEvent();
}
#endif
//the wire is active if only one end has been connected
IsActive = connections[0] == null ^ connections[1] == null;
}
@@ -274,8 +289,7 @@ namespace Barotrauma.Items.Components
//prevent the wire from extending too far when rewiring
if (nodes.Count > 0)
{
Character user = item.ParentInventory?.Owner as Character;
if (user == null) return;
if (!(item.ParentInventory?.Owner is Character user)) return;
Vector2 prevNodePos = nodes[nodes.Count - 1];
if (sub != null) { prevNodePos += sub.HiddenSubPosition; }
@@ -294,11 +308,17 @@ namespace Barotrauma.Items.Components
user.AnimController.Collider.ApplyForce(pullBackDir * user.Mass * 50.0f);
user.AnimController.UpdateUseItem(true, user.WorldPosition + pullBackDir * 200.0f);
if (currLength > MaxLength * 1.5f && GameMain.Client == null)
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
{
ClearConnections();
CreateNetworkEvent();
return;
if (currLength > MaxLength * 1.5f)
{
ClearConnections();
#if SERVER
CreateNetworkEvent();
#endif
return;
}
}
}
}
@@ -308,12 +328,18 @@ namespace Barotrauma.Items.Components
newNodePos = RoundNode(item.Position, item.CurrentHull) - sub.HiddenSubPosition;
canPlaceNode = true;
}
sectionExtents = new Vector2(
Math.Max(Math.Abs((newNodePos.X + sub.HiddenSubPosition.X) - item.Position.X), sectionExtents.X),
Math.Max(Math.Abs((newNodePos.Y + sub.HiddenSubPosition.Y) - item.Position.Y), sectionExtents.Y));
}
public override bool Use(float deltaTime, Character character = null)
{
if (character == null) return false;
#if CLIENT
if (character == Character.Controlled && character.SelectedConstruction != null) return false;
#endif
if (newNodePos != Vector2.Zero && canPlaceNode && nodes.Count > 0 && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance)
{
@@ -328,10 +354,12 @@ namespace Barotrauma.Items.Components
Drawable = true;
newNodePos = Vector2.Zero;
#if SERVER
if (GameMain.Server != null)
{
CreateNetworkEvent();
}
#endif
}
return true;
}
@@ -393,18 +421,33 @@ namespace Barotrauma.Items.Components
{
sections.Clear();
for (int i = 0; i < nodes.Count-1; i++)
for (int i = 0; i < nodes.Count - 1; i++)
{
sections.Add(new WireSection(nodes[i], nodes[i + 1]));
}
Drawable = IsActive || sections.Count > 0;
CalculateExtents();
}
private void CalculateExtents()
{
sectionExtents = Vector2.Zero;
if (sections.Count > 0)
{
for (int i = 0; i < nodes.Count; i++)
{
sectionExtents.X = Math.Max(Math.Abs(nodes[i].X - item.Position.X), sectionExtents.X);
sectionExtents.Y = Math.Max(Math.Abs(nodes[i].Y - item.Position.Y), sectionExtents.Y);
}
}
}
private void ClearConnections(Character user = null)
{
nodes.Clear();
sections.Clear();
#if SERVER
if (user != null)
{
if (connections[0] != null && connections[1] != null)
@@ -424,6 +467,7 @@ namespace Barotrauma.Items.Components
connections[1].Item.Name + " (" + connections[1].Name + ")", ServerLog.MessageType.ItemInteraction);
}
}
#endif
SetConnectedDirty();
@@ -627,33 +671,6 @@ namespace Barotrauma.Items.Components
base.RemoveComponentSpecific();
}
private void CreateNetworkEvent()
{
if (GameMain.Server == null) return;
//split into multiple events because one might not be enough to fit all the nodes
int eventCount = Math.Max((int)Math.Ceiling(nodes.Count / (float)MaxNodesPerNetworkEvent), 1);
for (int i = 0; i < eventCount; i++)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, item.components.IndexOf(this), i });
}
}
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
{
int eventIndex = (int)extraData[2];
int nodeStartIndex = eventIndex * MaxNodesPerNetworkEvent;
int nodeCount = MathHelper.Clamp(nodes.Count - nodeStartIndex, 0, MaxNodesPerNetworkEvent);
msg.WriteRangedInteger(0, (int)Math.Ceiling(MaxNodeCount / (float)MaxNodesPerNetworkEvent), eventIndex);
msg.WriteRangedInteger(0, MaxNodesPerNetworkEvent, nodeCount);
for (int i = nodeStartIndex; i < nodeStartIndex + nodeCount; i++)
{
msg.Write(nodes[i].X);
msg.Write(nodes[i].Y);
}
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
int eventIndex = msg.ReadRangedInteger(0, (int)Math.Ceiling(MaxNodeCount / (float)MaxNodesPerNetworkEvent));