(3dc4135ce) v0.9.5.1
This commit is contained in:
@@ -92,9 +92,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (XElement connectionElement in subElement.Elements())
|
||||
{
|
||||
if (connectionElement.Name.ToString() != element.Name.ToString()) { continue; }
|
||||
|
||||
string prefabConnectionName = element.GetAttributeString("name", IsOutput ? "output" : "input");
|
||||
string prefabConnectionName = element.GetAttributeString("name", null);
|
||||
if (prefabConnectionName == Name)
|
||||
{
|
||||
displayNameTag = connectionElement.GetAttributeString("displayname", "");
|
||||
@@ -245,31 +243,38 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (wires[i] == null) continue;
|
||||
if (wires[i] == null) { continue; }
|
||||
|
||||
Connection recipient = wires[i].OtherConnection(this);
|
||||
if (recipient == null) continue;
|
||||
if (recipient.item == this.item || recipient.item == source) continue;
|
||||
if (recipient == null) { continue; }
|
||||
if (recipient.item == this.item || recipient.item == source) { continue; }
|
||||
|
||||
if (source != null && !source.LastSentSignalRecipients.Contains(recipient.item))
|
||||
{
|
||||
source.LastSentSignalRecipients.Add(recipient.item);
|
||||
}
|
||||
source?.LastSentSignalRecipients.Add(recipient.item);
|
||||
|
||||
foreach (ItemComponent ic in recipient.item.Components)
|
||||
{
|
||||
ic.ReceiveSignal(stepsTaken, signal, recipient, source, sender, power, signalStrength);
|
||||
}
|
||||
|
||||
bool broken = recipient.Item.Condition <= 0.0f;
|
||||
foreach (StatusEffect effect in recipient.Effects)
|
||||
{
|
||||
if (broken && effect.type != ActionType.OnBroken) continue;
|
||||
recipient.Item.ApplyStatusEffect(effect, ActionType.OnUse, (float)Timing.Step, null, null, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendPowerProbeSignal(Item source, float power)
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
{
|
||||
if (wires[i] == null) { continue; }
|
||||
|
||||
Connection recipient = wires[i].OtherConnection(this);
|
||||
if (recipient == null) { continue; }
|
||||
|
||||
recipient.item.GetComponent<Powered>()?.ReceivePowerProbeSignal(recipient, source, power);
|
||||
}
|
||||
}
|
||||
public void ClearConnections()
|
||||
{
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class FunctionComponent : ItemComponent
|
||||
{
|
||||
public enum FunctionType
|
||||
{
|
||||
Round,
|
||||
Ceil,
|
||||
Floor,
|
||||
Factorial
|
||||
}
|
||||
|
||||
[Serialize(FunctionType.Round, false, description: "Which kind of function to run the input through.")]
|
||||
public FunctionType Function
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public FunctionComponent(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
|
||||
{
|
||||
float.TryParse(signal, out float value);
|
||||
switch (Function)
|
||||
{
|
||||
case FunctionType.Round:
|
||||
item.SendSignal(0, Math.Round(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
break;
|
||||
case FunctionType.Ceil:
|
||||
item.SendSignal(0, Math.Ceiling(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
break;
|
||||
case FunctionType.Floor:
|
||||
item.SendSignal(0, Math.Floor(value).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
break;
|
||||
case FunctionType.Factorial:
|
||||
int intVal = (int)Math.Min(value, 20);
|
||||
ulong factorial = 1;
|
||||
for (int i = intVal; i > 0; i--)
|
||||
{
|
||||
factorial *= (ulong)i;
|
||||
}
|
||||
item.SendSignal(0, factorial.ToString(), "signal_out", null);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException($"Function {Function} has not been implemented.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,19 +216,12 @@ namespace Barotrauma.Items.Components
|
||||
#endif
|
||||
}
|
||||
|
||||
if (powerConsumption == 0.0f)
|
||||
{
|
||||
voltage = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
currPowerConsumption = powerConsumption;
|
||||
}
|
||||
currPowerConsumption = powerConsumption;
|
||||
|
||||
if (Rand.Range(0.0f, 1.0f) < 0.05f && voltage < Rand.Range(0.0f, minVoltage))
|
||||
if (Rand.Range(0.0f, 1.0f) < 0.05f && Voltage < Rand.Range(0.0f, MinVoltage))
|
||||
{
|
||||
#if CLIENT
|
||||
if (voltage > 0.1f)
|
||||
if (Voltage > 0.1f)
|
||||
{
|
||||
SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: item.CurrentHull);
|
||||
}
|
||||
@@ -237,7 +230,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
lightBrightness = MathHelper.Lerp(lightBrightness, Math.Min(voltage, 1.0f), 0.1f);
|
||||
lightBrightness = MathHelper.Lerp(lightBrightness, Math.Min(Voltage, 1.0f), 0.1f);
|
||||
}
|
||||
|
||||
if (blinkFrequency > 0.0f)
|
||||
@@ -262,8 +255,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
UpdateAITarget(item.AiTarget);
|
||||
}
|
||||
|
||||
voltage -= deltaTime;
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class ModuloComponent : ItemComponent
|
||||
{
|
||||
private float modulus;
|
||||
[InGameEditable, Serialize(1.0f, false, description: "The modulus of the operation. Must be non-zero.")]
|
||||
public float Modulus
|
||||
{
|
||||
get { return modulus; }
|
||||
set
|
||||
{
|
||||
modulus = MathUtils.NearlyEqual(value, 0.0f) ? 1.0f : value;
|
||||
}
|
||||
}
|
||||
|
||||
public ModuloComponent(Item item, XElement element) : base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
|
||||
{
|
||||
switch (connection.Name)
|
||||
{
|
||||
case "set_modulus":
|
||||
case "modulus":
|
||||
float.TryParse(signal, out float newModulus);
|
||||
Modulus = newModulus;
|
||||
break;
|
||||
case "signal_in":
|
||||
float.TryParse(signal, out float value);
|
||||
item.SendSignal(0, (value % modulus).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,14 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, true, description: "Should the sensor ignore the bodies of dead characters?")]
|
||||
public bool IgnoreDead
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
[InGameEditable, Serialize(0.0f, true, description: "Horizontal detection range.")]
|
||||
public float RangeX
|
||||
{
|
||||
@@ -109,6 +117,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (IgnoreDead && c.IsDead) { continue; }
|
||||
if (OnlyHumans && !c.IsHuman) { continue; }
|
||||
|
||||
//do a rough check based on the position of the character's collider first
|
||||
@@ -138,5 +147,15 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
detectOffset.Y = -detectOffset.Y;
|
||||
}
|
||||
public override XElement Save(XElement parentElement)
|
||||
{
|
||||
Vector2 prevDetectOffset = detectOffset;
|
||||
//undo flipping before saving
|
||||
if (item.FlippedX) { detectOffset.X = -detectOffset.X; }
|
||||
if (item.FlippedY) { detectOffset.Y = -detectOffset.Y; }
|
||||
XElement element = base.Save(parentElement);
|
||||
detectOffset = prevDetectOffset;
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
@@ -8,9 +9,11 @@ namespace Barotrauma.Items.Components
|
||||
class RelayComponent : PowerTransfer, IServerSerializable
|
||||
{
|
||||
private float maxPower;
|
||||
|
||||
|
||||
private bool isOn;
|
||||
|
||||
private float throttlePowerOutput;
|
||||
|
||||
private static readonly Dictionary<string, string> connectionPairs = new Dictionary<string, string>
|
||||
{
|
||||
{ "power_in", "power_out"},
|
||||
@@ -21,6 +24,7 @@ namespace Barotrauma.Items.Components
|
||||
{ "signal_in4", "signal_out4" },
|
||||
{ "signal_in5", "signal_out5" }
|
||||
};
|
||||
public float DisplayLoad { get; set; }
|
||||
|
||||
[Editable, Serialize(1000.0f, true, description: "The maximum amount of power that can pass through the item.")]
|
||||
public float MaxPower
|
||||
@@ -31,7 +35,7 @@ namespace Barotrauma.Items.Components
|
||||
maxPower = Math.Max(0.0f, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Editable, Serialize(false, true, description: "Can the relay currently pass power and signals through it.")]
|
||||
public bool IsOn
|
||||
{
|
||||
@@ -49,18 +53,46 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RelayComponent(Item item, XElement element)
|
||||
: base (item, element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
throttlePowerOutput = MaxPower;
|
||||
}
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
base.Update(deltaTime, cam);
|
||||
RefreshConnections();
|
||||
|
||||
item.SendSignal(0, IsOn ? "1" : "0", "state_out", null);
|
||||
|
||||
if (!CanTransfer) { Voltage = 0.0f; return; }
|
||||
|
||||
if (isBroken)
|
||||
{
|
||||
SetAllConnectionsDirty();
|
||||
isBroken = false;
|
||||
}
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
if (powerOut != null)
|
||||
{
|
||||
bool overloaded = false;
|
||||
foreach (Connection recipient in powerOut.Recipients)
|
||||
{
|
||||
var pt = recipient.Item.GetComponent<PowerTransfer>();
|
||||
if (pt != null)
|
||||
{
|
||||
float overload = -pt.CurrPowerConsumption - pt.PowerLoad;
|
||||
throttlePowerOutput += overload * deltaTime * 0.5f;
|
||||
overloaded = overload > 1.0f;
|
||||
}
|
||||
}
|
||||
throttlePowerOutput = overloaded ?
|
||||
MathHelper.Clamp(throttlePowerOutput, 0.0f, MaxPower):
|
||||
Math.Max(throttlePowerOutput - MaxPower * 0.1f * deltaTime, 0.0f);
|
||||
}
|
||||
|
||||
if (Math.Min(-currPowerConsumption, PowerLoad) > maxPower && CanBeOverloaded)
|
||||
{
|
||||
@@ -68,9 +100,56 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceivePowerProbeSignal(Connection connection, Item source, float power)
|
||||
{
|
||||
if (!IsOn) { return; }
|
||||
|
||||
//we've already received this signal
|
||||
if (lastPowerProbeRecipients.Contains(this)) { return; }
|
||||
lastPowerProbeRecipients.Add(this);
|
||||
|
||||
if (power < 0.0f)
|
||||
{
|
||||
if (!connection.IsOutput || powerIn == null) { return; }
|
||||
|
||||
//power being drawn from the power_out connection
|
||||
DisplayLoad -= Math.Min(power, 0.0f);
|
||||
powerLoad -= Math.Min(power + throttlePowerOutput, 0.0f);
|
||||
|
||||
//pass the load to items connected to the input
|
||||
powerIn.SendPowerProbeSignal(source, Math.Max(power, -MaxPower));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (connection.IsOutput || powerOut == null) { return; }
|
||||
//power being supplied to the power_in connection
|
||||
if (currPowerConsumption - power < -MaxPower)
|
||||
{
|
||||
power += MaxPower + (currPowerConsumption - power);
|
||||
}
|
||||
|
||||
currPowerConsumption -= power;
|
||||
|
||||
foreach (Connection recipient in powerOut.Recipients)
|
||||
{
|
||||
if (!recipient.IsPower) { continue; }
|
||||
var powered = recipient.Item.GetComponent<Powered>();
|
||||
if (powered == null) { continue; }
|
||||
|
||||
float load = powered.CurrPowerConsumption;
|
||||
var powerTransfer = powered as PowerTransfer;
|
||||
if (powerTransfer != null) { load = powerTransfer.PowerLoad; }
|
||||
|
||||
float powerOut = power * (load / Math.Max(powerLoad + throttlePowerOutput, 0.01f));
|
||||
powered.ReceivePowerProbeSignal(recipient, source, Math.Min(powerOut, power));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0.0f, float signalStrength = 1.0f)
|
||||
{
|
||||
if (connection.IsPower || item.Condition <= 0.0f) { return; }
|
||||
if (item.Condition <= 0.0f || connection.IsPower) { return; }
|
||||
|
||||
if (connectionPairs.TryGetValue(connection.Name, out string outConnection))
|
||||
{
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
class TrigonometricFunctionComponent : ItemComponent
|
||||
{
|
||||
public enum FunctionType
|
||||
{
|
||||
Sin,
|
||||
Cos,
|
||||
Tan,
|
||||
Asin,
|
||||
Acos,
|
||||
Atan,
|
||||
}
|
||||
|
||||
protected float[] receivedSignal = new float[2];
|
||||
|
||||
[Serialize(FunctionType.Sin, false, description: "Which kind of function to run the input through.")]
|
||||
public FunctionType Function
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
|
||||
[InGameEditable, Serialize(false, true, description: "If set to true, the trigonometric function uses radians instead of degrees.")]
|
||||
public bool UseRadians
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
|
||||
public TrigonometricFunctionComponent(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
//reset received signals
|
||||
receivedSignal[0] = float.NaN;
|
||||
receivedSignal[1] = float.NaN;
|
||||
}
|
||||
|
||||
|
||||
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power = 0, float signalStrength = 1)
|
||||
{
|
||||
float.TryParse(signal, out float value);
|
||||
switch (Function)
|
||||
{
|
||||
case FunctionType.Sin:
|
||||
if (!UseRadians) { value = MathHelper.ToRadians(value); }
|
||||
item.SendSignal(0, ((float)Math.Sin(value)).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
break;
|
||||
case FunctionType.Cos:
|
||||
if (!UseRadians) { value = MathHelper.ToRadians(value); }
|
||||
item.SendSignal(0, ((float)Math.Cos(value)).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
break;
|
||||
case FunctionType.Tan:
|
||||
if (!UseRadians) { value = MathHelper.ToRadians(value); }
|
||||
item.SendSignal(0, ((float)Math.Tan(value)).ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
break;
|
||||
case FunctionType.Asin:
|
||||
{
|
||||
float angle = (float)Math.Asin(value);
|
||||
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
|
||||
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
}
|
||||
break;
|
||||
case FunctionType.Acos:
|
||||
{
|
||||
float angle = (float)Math.Acos(value);
|
||||
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
|
||||
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
}
|
||||
break;
|
||||
case FunctionType.Atan:
|
||||
if (connection.Name == "signal_in_x")
|
||||
{
|
||||
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
|
||||
}
|
||||
else if (connection.Name == "signal_in_y")
|
||||
{
|
||||
float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
|
||||
if (!float.IsNaN(receivedSignal[0]) && !float.IsNaN(receivedSignal[1]))
|
||||
{
|
||||
float angle = (float)Math.Atan2(receivedSignal[1], receivedSignal[0]);
|
||||
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
|
||||
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float angle = (float)Math.Atan(value);
|
||||
if (!UseRadians) { angle = MathHelper.ToDegrees(angle); }
|
||||
item.SendSignal(0, angle.ToString("G", CultureInfo.InvariantCulture), "signal_out", null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException($"Function {Function} has not been implemented.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(Character.TeamType.None, false, description: "WiFi components can only communicate with components that have the same Team ID.")]
|
||||
public Character.TeamType TeamID { get; set; }
|
||||
|
||||
[Serialize(20000.0f, false, description: "How close the recipient has to be to receive a signal from this WiFi component.")]
|
||||
[Editable, Serialize(20000.0f, false, description: "How close the recipient has to be to receive a signal from this WiFi component.")]
|
||||
public float Range
|
||||
{
|
||||
get { return range; }
|
||||
@@ -174,8 +174,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
{
|
||||
base.RemoveComponentSpecific();
|
||||
|
||||
list.Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,22 +83,16 @@ namespace Barotrauma.Items.Components
|
||||
public Wire(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
#if CLIENT
|
||||
if (wireSprite == null)
|
||||
{
|
||||
wireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f))
|
||||
{
|
||||
Depth = 0.85f
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
nodes = new List<Vector2>();
|
||||
sections = new List<WireSection>();
|
||||
connections = new Connection[2];
|
||||
IsActive = false;
|
||||
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
|
||||
public Connection OtherConnection(Connection connection)
|
||||
{
|
||||
if (connection == connections[0]) { return connections[1]; }
|
||||
@@ -728,6 +722,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
ClearConnections();
|
||||
base.RemoveComponentSpecific();
|
||||
#if CLIENT
|
||||
overrideSprite?.Remove();
|
||||
overrideSprite = null;
|
||||
wireSprite = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
|
||||
Reference in New Issue
Block a user