v0.14.6.0

This commit is contained in:
Joonas Rikkonen
2021-06-17 17:54:52 +03:00
parent 3f324b14e8
commit c27e2ea5ab
348 changed files with 13156 additions and 4266 deletions
@@ -34,6 +34,11 @@ namespace Barotrauma.Items.Components
set;
}
public bool TemporarilyLocked
{
get { return Level.IsLoadedOutpost && item.GetComponent<DockingPort>() != null; }
}
//connection panels can't be deactivated externally (by signals or status effects)
public override bool IsActive
{
@@ -95,7 +95,7 @@ namespace Barotrauma.Items.Components
}
private string[] labels;
[Serialize("", true, description: "The texts displayed on the buttons/tickboxes, separated by commas.")]
[Serialize("", true, description: "The texts displayed on the buttons/tickboxes, separated by commas.", alwaysUseInstanceValues: true)]
public string Labels
{
get { return string.Join(",", labels); }
@@ -111,7 +111,7 @@ namespace Barotrauma.Items.Components
}
private string[] signals;
[Serialize("", true, description: "The signals sent when the buttons are pressed or the tickboxes checked, separated by commas.")]
[Serialize("", true, description: "The signals sent when the buttons are pressed or the tickboxes checked, separated by commas.", alwaysUseInstanceValues: true)]
public string Signals
{
//use semicolon as a separator because comma may be needed in the signals (for color or vector values for example)
@@ -20,9 +20,10 @@ namespace Barotrauma.Items.Components
private bool castShadows;
private bool drawBehindSubs;
private double lastToggleSignalTime;
private string prevColorSignal;
public PhysicsBody ParentBody;
private Turret turret;
@@ -37,7 +38,7 @@ namespace Barotrauma.Items.Components
range = MathHelper.Clamp(value, 0.0f, 4096.0f);
#if CLIENT
item.ResetCachedVisibleSize();
if (light != null) { light.Range = range; }
if (Light != null) { Light.Range = range; }
#endif
}
}
@@ -53,7 +54,7 @@ namespace Barotrauma.Items.Components
{
castShadows = value;
#if CLIENT
if (light != null) light.CastShadows = value;
if (Light != null) Light.CastShadows = value;
#endif
}
}
@@ -67,7 +68,7 @@ namespace Barotrauma.Items.Components
{
drawBehindSubs = value;
#if CLIENT
if (light != null) light.IsBackground = drawBehindSubs;
if (Light != null) Light.IsBackground = drawBehindSubs;
#endif
}
}
@@ -93,7 +94,7 @@ namespace Barotrauma.Items.Components
{
flicker = MathHelper.Clamp(value, 0.0f, 1.0f);
#if CLIENT
if (light != null) { light.LightSourceParams.Flicker = flicker; }
if (Light != null) { Light.LightSourceParams.Flicker = flicker; }
#endif
}
}
@@ -106,7 +107,7 @@ namespace Barotrauma.Items.Components
{
flickerSpeed = value;
#if CLIENT
if (light != null) { light.LightSourceParams.FlickerSpeed = flickerSpeed; }
if (Light != null) { Light.LightSourceParams.FlickerSpeed = flickerSpeed; }
#endif
}
}
@@ -119,7 +120,7 @@ namespace Barotrauma.Items.Components
{
pulseFrequency = MathHelper.Clamp(value, 0.0f, 60.0f);
#if CLIENT
if (light != null) { light.LightSourceParams.PulseFrequency = pulseFrequency; }
if (Light != null) { Light.LightSourceParams.PulseFrequency = pulseFrequency; }
#endif
}
}
@@ -132,7 +133,7 @@ namespace Barotrauma.Items.Components
{
pulseAmount = MathHelper.Clamp(value, 0.0f, 1.0f);
#if CLIENT
if (light != null) { light.LightSourceParams.PulseAmount = pulseAmount; }
if (Light != null) { Light.LightSourceParams.PulseAmount = pulseAmount; }
#endif
}
}
@@ -145,7 +146,7 @@ namespace Barotrauma.Items.Components
{
blinkFrequency = MathHelper.Clamp(value, 0.0f, 60.0f);
#if CLIENT
if (light != null) { light.LightSourceParams.BlinkFrequency = blinkFrequency; }
if (Light != null) { Light.LightSourceParams.BlinkFrequency = blinkFrequency; }
#endif
}
}
@@ -158,7 +159,7 @@ namespace Barotrauma.Items.Components
{
lightColor = value;
#if CLIENT
if (light != null) light.Color = IsActive ? lightColor : Color.Transparent;
if (Light != null) Light.Color = IsActive ? lightColor : Color.Transparent;
#endif
}
}
@@ -173,7 +174,7 @@ namespace Barotrauma.Items.Components
public override void Move(Vector2 amount)
{
#if CLIENT
light.Position += amount;
Light.Position += amount;
#endif
}
@@ -197,7 +198,7 @@ namespace Barotrauma.Items.Components
: base(item, element)
{
#if CLIENT
light = new LightSource(element)
Light = new LightSource(element)
{
ParentSub = item.CurrentHull?.Submarine,
Position = item.Position,
@@ -206,11 +207,11 @@ namespace Barotrauma.Items.Components
SpriteScale = Vector2.One * item.Scale,
Range = range
};
light.LightSourceParams.Flicker = flicker;
light.LightSourceParams.FlickerSpeed = FlickerSpeed;
light.LightSourceParams.PulseAmount = pulseAmount;
light.LightSourceParams.PulseFrequency = pulseFrequency;
light.LightSourceParams.BlinkFrequency = blinkFrequency;
Light.LightSourceParams.Flicker = flicker;
Light.LightSourceParams.FlickerSpeed = FlickerSpeed;
Light.LightSourceParams.PulseAmount = pulseAmount;
Light.LightSourceParams.PulseFrequency = pulseFrequency;
Light.LightSourceParams.BlinkFrequency = blinkFrequency;
#endif
IsActive = IsOn;
@@ -233,7 +234,7 @@ namespace Barotrauma.Items.Components
UpdateOnActiveEffects(deltaTime);
#if CLIENT
light.ParentSub = item.Submarine;
Light.ParentSub = item.Submarine;
#endif
if (item.Container != null)
{
@@ -243,23 +244,23 @@ namespace Barotrauma.Items.Components
#if CLIENT
if (ParentBody != null)
{
light.Position = ParentBody.Position;
Light.Position = ParentBody.Position;
}
else if (turret != null)
{
light.Position = new Vector2(item.Rect.X + turret.TransformedBarrelPos.X, item.Rect.Y - turret.TransformedBarrelPos.Y);
Light.Position = new Vector2(item.Rect.X + turret.TransformedBarrelPos.X, item.Rect.Y - turret.TransformedBarrelPos.Y);
}
else
{
light.Position = item.Position;
Light.Position = item.Position;
}
#endif
PhysicsBody body = ParentBody ?? item.body;
if (body != null)
{
#if CLIENT
light.Rotation = body.Dir > 0.0f ? body.DrawRotation : body.DrawRotation - MathHelper.Pi;
light.LightSpriteEffect = (body.Dir > 0.0f) ? SpriteEffects.None : SpriteEffects.FlipVertically;
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)
{
@@ -270,8 +271,8 @@ namespace Barotrauma.Items.Components
else
{
#if CLIENT
light.Rotation = -Rotation - MathHelper.ToRadians(item.Rotation);
light.LightSpriteEffect = item.SpriteEffects;
Light.Rotation = -Rotation - MathHelper.ToRadians(item.Rotation);
Light.LightSpriteEffect = item.SpriteEffects;
#endif
}
@@ -326,7 +327,11 @@ namespace Barotrauma.Items.Components
IsOn = signal.value != "0";
break;
case "set_color":
LightColor = XMLExtensions.ParseColor(signal.value, false);
if (signal.value != prevColorSignal)
{
LightColor = XMLExtensions.ParseColor(signal.value, false);
prevColorSignal = signal.value;
}
break;
}
}
@@ -8,7 +8,6 @@ namespace Barotrauma.Items.Components
{
partial class MotionSensor : ItemComponent
{
private const float UpdateInterval = 0.1f;
private float rangeX, rangeY;
private Vector2 detectOffset;
@@ -19,7 +18,8 @@ namespace Barotrauma.Items.Components
{
Any,
Human,
Monster
Monster,
Wall
}
[Serialize(false, false, description: "Has the item currently detected movement. Intended to be used by StatusEffect conditionals (setting this value in XML has no effect).")]
@@ -74,6 +74,13 @@ namespace Barotrauma.Items.Components
}
}
[Editable(MinValueFloat = 0.1f, MaxValueFloat = 100.0f, DecimalCount = 2), Serialize(0.1f, true, description: "How often the sensor checks if there's something moving near it. Higher values are better for performance.", alwaysUseInstanceValues: true)]
public float UpdateInterval
{
get;
set;
}
private int maxOutputLength;
[Editable, Serialize(200, false, description: "The maximum length of the output strings. Warning: Large values can lead to large memory usage or networking issues.")]
public int MaxOutputLength
@@ -134,6 +141,9 @@ namespace Barotrauma.Items.Components
{
rangeX = rangeY = element.GetAttributeFloat("range", 0.0f);
}
//randomize update timer so all sensors aren't updated during the same frame
updateTimer = Rand.Range(0.0f, UpdateInterval);
}
public override void Load(XElement componentElement, bool usePrefabValues, IdRemap idRemap)
@@ -153,7 +163,7 @@ namespace Barotrauma.Items.Components
if (!string.IsNullOrEmpty(signalOut)) { item.SendSignal(new Signal(signalOut, 1), "state_out"); }
updateTimer -= deltaTime;
if (updateTimer > 0.0f) return;
if (updateTimer > 0.0f) { return; }
MotionDetected = false;
updateTimer = UpdateInterval;
@@ -163,6 +173,7 @@ namespace Barotrauma.Items.Components
if (Math.Abs(item.body.LinearVelocity.X) > MinimumVelocity || Math.Abs(item.body.LinearVelocity.Y) > MinimumVelocity)
{
MotionDetected = true;
return;
}
}
@@ -171,42 +182,94 @@ namespace Barotrauma.Items.Components
float broadRangeX = Math.Max(rangeX * 2, 500);
float broadRangeY = Math.Max(rangeY * 2, 500);
foreach (Character c in Character.CharacterList)
if (item.CurrentHull == null && item.Submarine != null && Level.Loaded != null &&
(Target == TargetType.Wall || Target == TargetType.Any))
{
if (IgnoreDead && c.IsDead) { continue; }
//ignore characters that have spawned a second or less ago
//makes it possible to detect when a spawned character moves without triggering the detector immediately as the ragdoll spawns and drops to the ground
if (c.SpawnTime > Timing.TotalTime - 1.0) { continue; }
switch (Target)
if (Math.Abs(item.Submarine.Velocity.X) > MinimumVelocity || Math.Abs(item.Submarine.Velocity.Y) > MinimumVelocity)
{
case TargetType.Human:
if (!c.IsHuman) { continue; }
break;
case TargetType.Monster:
if (c.IsHuman || c.IsPet) { continue; }
break;
var cells = Level.Loaded.GetCells(item.WorldPosition, 1);
foreach (var cell in cells)
{
if (cell.IsPointInside(item.WorldPosition))
{
MotionDetected = true;
return;
}
foreach (var edge in cell.Edges)
{
Vector2 e1 = edge.Point1 + cell.Translation;
Vector2 e2 = edge.Point2 + cell.Translation;
if (MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.Right, detectRect.Y)) ||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Bottom), new Vector2(detectRect.Right, detectRect.Bottom)) ||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.X, detectRect.Y), new Vector2(detectRect.X, detectRect.Bottom)) ||
MathUtils.LinesIntersect(e1, e2, new Vector2(detectRect.Right, detectRect.Y), new Vector2(detectRect.Right, detectRect.Bottom)))
{
MotionDetected = true;
return;
}
}
}
}
//do a rough check based on the position of the character's collider first
//before the more accurate limb-based check
if (Math.Abs(c.WorldPosition.X - detectPos.X) > broadRangeX || Math.Abs(c.WorldPosition.Y - detectPos.Y) > broadRangeY)
foreach (Submarine sub in Submarine.Loaded)
{
continue;
}
if (sub == item.Submarine) { continue; }
foreach (Limb limb in c.AnimController.Limbs)
{
if (limb.IsSevered) { continue; }
if (limb.LinearVelocity.LengthSquared() <= MinimumVelocity * MinimumVelocity) { continue; }
if (MathUtils.CircleIntersectsRectangle(limb.WorldPosition, ConvertUnits.ToDisplayUnits(limb.body.GetMaxExtent()), detectRect))
Vector2 relativeVelocity = item.Submarine.Velocity - sub.Velocity;
if (Math.Abs(relativeVelocity.X) < MinimumVelocity && Math.Abs(relativeVelocity.Y) < MinimumVelocity) { continue; }
Rectangle worldBorders = new Rectangle(
sub.Borders.X + (int)sub.WorldPosition.X,
sub.Borders.Y + (int)sub.WorldPosition.Y - sub.Borders.Height,
sub.Borders.Width,
sub.Borders.Height);
if (worldBorders.Intersects(detectRect))
{
MotionDetected = true;
break;
return;
}
}
}
if (Target != TargetType.Wall)
{
foreach (Character c in Character.CharacterList)
{
if (IgnoreDead && c.IsDead) { continue; }
//ignore characters that have spawned a second or less ago
//makes it possible to detect when a spawned character moves without triggering the detector immediately as the ragdoll spawns and drops to the ground
if (c.SpawnTime > Timing.TotalTime - 1.0) { continue; }
switch (Target)
{
case TargetType.Human:
if (!c.IsHuman) { continue; }
break;
case TargetType.Monster:
if (c.IsHuman || c.IsPet) { continue; }
break;
}
//do a rough check based on the position of the character's collider first
//before the more accurate limb-based check
if (Math.Abs(c.WorldPosition.X - detectPos.X) > broadRangeX || Math.Abs(c.WorldPosition.Y - detectPos.Y) > broadRangeY)
{
continue;
}
foreach (Limb limb in c.AnimController.Limbs)
{
if (limb.IsSevered) { continue; }
if (limb.LinearVelocity.LengthSquared() <= MinimumVelocity * MinimumVelocity) { continue; }
if (MathUtils.CircleIntersectsRectangle(limb.WorldPosition, ConvertUnits.ToDisplayUnits(limb.body.GetMaxExtent()), detectRect))
{
MotionDetected = true;
return;
}
}
}
}
}
public override void FlipX(bool relativeToSub)
@@ -19,5 +19,22 @@ namespace Barotrauma.Items.Components
this.power = power;
this.strength = strength;
}
internal Signal WithStepsTaken(int stepsTaken)
{
Signal retVal = this;
retVal.stepsTaken = stepsTaken;
return retVal;
}
public static bool operator==(Signal a, Signal b) =>
a.value == b.value &&
a.stepsTaken == b.stepsTaken &&
a.sender == b.sender &&
a.source == b.source &&
MathUtils.NearlyEqual(a.power, b.power) &&
MathUtils.NearlyEqual(a.strength, b.strength);
public static bool operator!=(Signal a, Signal b) => !(a == b);
}
}
@@ -64,6 +64,7 @@ namespace Barotrauma.Items.Components
public override void ReceiveSignal(Signal signal, Connection connection)
{
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float value);
bool sendOutputImmediately = true;
switch (Function)
{
case FunctionType.Sin:
@@ -105,11 +106,13 @@ namespace Barotrauma.Items.Components
{
timeSinceReceived[0] = 0.0f;
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[0]);
sendOutputImmediately = false;
}
else if (connection.Name == "signal_in_y")
{
timeSinceReceived[1] = 0.0f;
float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out receivedSignal[1]);
sendOutputImmediately = false;
}
else
{
@@ -121,9 +124,11 @@ namespace Barotrauma.Items.Components
default:
throw new NotImplementedException($"Function {Function} has not been implemented.");
}
signal.value = value.ToString("G", CultureInfo.InvariantCulture);
item.SendSignal(signal, "signal_out");
if (sendOutputImmediately)
{
signal.value = value.ToString("G", CultureInfo.InvariantCulture);
item.SendSignal(signal, "signal_out");
}
}
}
}
@@ -58,7 +58,8 @@ namespace Barotrauma.Items.Components
set;
}
[Editable, Serialize(false, false, description: "If enabled, any signals received from another chat-linked wifi component are displayed " +
[ConditionallyEditable(ConditionallyEditable.ConditionType.AllowLinkingWifiToChat)]
[Serialize(false, false, description: "If enabled, any signals received from another chat-linked wifi component are displayed " +
"as chat messages in the chatbox of the player holding the item.", alwaysUseInstanceValues: true)]
public bool LinkToChat
{
@@ -71,7 +71,7 @@ namespace Barotrauma.Items.Components
get
{
if (GameMain.NetworkMember?.ServerSettings != null && !GameMain.NetworkMember.ServerSettings.AllowRewiring) { return false; }
return locked || connections.Any(c => c != null && c.ConnectionPanel.Locked);
return locked || connections.Any(c => c != null && (c.ConnectionPanel.Locked || c.ConnectionPanel.TemporarilyLocked));
}
set { locked = value; }
}