Unstable 0.16.1.0

This commit is contained in:
Markus Isberg
2022-01-27 00:30:32 +09:00
parent 7d6421a548
commit b259af5911
161 changed files with 1913 additions and 638 deletions
@@ -74,7 +74,6 @@ namespace Barotrauma.Items.Components
a.Identifier.Equals(Effect, StringComparison.OrdinalIgnoreCase) ||
a.AfflictionType.Equals(Effect, StringComparison.OrdinalIgnoreCase)).GetRandom();
}
Tainted = true;
}
[Serialize(3.0f, false)]
@@ -1,13 +1,13 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Vector2 = Microsoft.Xna.Framework.Vector2;
using Vector4 = Microsoft.Xna.Framework.Vector4;
@@ -398,8 +398,6 @@ namespace Barotrauma.Items.Components
private int flowerVariants;
private int leafVariants;
private int[] flowerTiles;
private const int serverHealthUpdateDelay = 10;
private int serverHealthUpdateTimer;
public float Health
{
@@ -553,19 +551,21 @@ namespace Barotrauma.Items.Components
if (spawnProduct && ProducedItems.Any())
{
SpawnItem(ProducedItems.RandomElementByWeight(it => it.Probability), spawnPos);
SpawnItem(Item, ProducedItems.RandomElementByWeight(it => it.Probability), spawnPos);
return;
}
if (spawnSeed)
{
SpawnItem(ProducedSeed, spawnPos);
SpawnItem(Item, ProducedSeed, spawnPos);
}
static void SpawnItem(ProducedItem producedItem, Vector2 pos)
static void SpawnItem(Item thisItem, ProducedItem producedItem, Vector2 pos)
{
if (producedItem.Prefab == null) { return; }
GameAnalyticsManager.AddDesignEvent("MicroInteraction:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "null") + ":GardeningProduce:" + thisItem.prefab.Identifier + ":" + producedItem.Prefab.Identifier);
Entity.Spawner?.AddToSpawnQueue(producedItem.Prefab, pos, onSpawned: it =>
{
foreach (StatusEffect effect in producedItem.StatusEffects)
@@ -586,8 +586,13 @@ namespace Barotrauma.Items.Components
{
if (Decayed) { return true; }
if (0 >= Health)
if (Health <= 0)
{
if (!Decayed)
{
GameAnalyticsManager.AddDesignEvent("MicroInteraction:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "null") + ":GardeningDied:" + item.prefab.Identifier);
}
Decayed = true;
#if CLIENT
foreach (VineTile vine in Vines)
@@ -237,10 +237,13 @@ namespace Barotrauma.Items.Components
}
}
private bool loadedFromXml;
public override void Load(XElement componentElement, bool usePrefabValues, IdRemap idRemap)
{
base.Load(componentElement, usePrefabValues, idRemap);
loadedFromXml = true;
if (usePrefabValues)
{
//this needs to be loaded regardless
@@ -536,7 +539,16 @@ namespace Barotrauma.Items.Components
else
{
attachTargetCell = GetAttachTargetCell(150.0f);
if (attachTargetCell != null) { IsActive = true; }
if (attachTargetCell != null && attachTargetCell.IsDestructible)
{
attachTargetCell.OnDestroyed += () =>
{
if (attachTargetCell != null && attachTargetCell.CellType != Voronoi2.CellType.Solid)
{
Drop(dropConnectedWires: true, dropper: null);
}
};
}
}
}
@@ -562,7 +574,7 @@ namespace Barotrauma.Items.Components
public void DeattachFromWall()
{
if (!attachable) return;
if (!attachable) { return; }
Attached = false;
attachTargetCell = null;
@@ -733,15 +745,6 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
if (attachTargetCell != null)
{
if (attachTargetCell.CellType != Voronoi2.CellType.Solid)
{
Drop(dropConnectedWires: true, dropper: null);
}
return;
}
if (item.body == null || !item.body.Enabled) { return; }
if (picker == null || !picker.HasEquippedItem(item))
{
@@ -838,15 +841,25 @@ namespace Barotrauma.Items.Components
public override void OnItemLoaded()
{
if (item.Submarine != null && item.Submarine.Loading) return;
if (item.Submarine != null && item.Submarine.Loading) { return; }
OnMapLoaded();
item.SetActiveSprite();
}
public override void OnMapLoaded()
{
if (!attachable) return;
if (!attachable) { return; }
//a mod has overridden the item, and the base item didn't have a Holdable component = a mod made the item movable/detachable
if (item.Prefab.IsOverride && !loadedFromXml)
{
if (attachedByDefault)
{
AttachToWall();
return;
}
}
if (Attached)
{
AttachToWall();
@@ -51,7 +51,11 @@ namespace Barotrauma.Items.Components
#else
if (deattachTimer >= DeattachDuration)
{
holdable.DeattachFromWall();
if (holdable.Attached)
{
GameAnalyticsManager.AddDesignEvent("ResourceCollected:" + (GameMain.GameSession?.GameMode?.Name ?? "none") + ":" + item.Prefab.Identifier);
holdable.DeattachFromWall();
}
trigger.Enabled = false;
}
#endif
@@ -855,6 +855,10 @@ namespace Barotrauma.Items.Components
{
currentTargets.Add(structure);
}
if (character != null)
{
currentTargets.Add(character);
}
effect.Apply(actionType, deltaTime, item, currentTargets);
}
else if (effect.HasTargetType(StatusEffect.TargetType.Character))
@@ -570,6 +570,7 @@ namespace Barotrauma.Items.Components
{
GUI.RemoveFromUpdateList(GuiFrame, true);
GuiFrame.RectTransform.Parent = null;
GuiFrame = null;
}
#endif
@@ -304,7 +304,12 @@ namespace Barotrauma.Items.Components
}
}
}
}
}
if (item.GetComponent<Planter>() != null)
{
GameAnalyticsManager.AddDesignEvent("MicroInteraction:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "null") + ":GardeningPlanted:" + containedItem.prefab.Identifier);
}
//no need to Update() if this item has no statuseffects and no physics body
IsActive = activeContainedItems.Count > 0 || Inventory.AllItems.Any(it => it.body != null);
@@ -370,29 +370,18 @@ namespace Barotrauma.Items.Components
public Item GetFocusTarget()
{
Item focusTarget = null;
for (int c = 0; c < 2; c++)
{
//try finding the item to focus on using trigger_out, and if that fails, using position_out
string connectionName = c == 0 ? "trigger_out" : "position_out";
string signal = c == 0 ? "0" : MathHelper.ToDegrees(targetRotation).ToString("G", CultureInfo.InvariantCulture);
if (!item.SendSignal(new Signal(signal, sender: user), connectionName) || focusTarget != null)
{
continue;
}
item.SendSignal(new Signal(MathHelper.ToDegrees(targetRotation).ToString("G", CultureInfo.InvariantCulture), sender: user), "position_out");
for (int i = item.LastSentSignalRecipients.Count - 1; i >= 0; i--)
for (int i = item.LastSentSignalRecipients.Count - 1; i >= 0; i--)
{
if (item.LastSentSignalRecipients[i].Item.Condition <= 0.0f || item.LastSentSignalRecipients[i].IsPower) { continue; }
if (item.LastSentSignalRecipients[i].Item.Prefab.FocusOnSelected)
{
if (item.LastSentSignalRecipients[i].Item.Condition <= 0.0f || item.LastSentSignalRecipients[i].IsPower) { continue; }
if (item.LastSentSignalRecipients[i].Item.Prefab.FocusOnSelected)
{
focusTarget = item.LastSentSignalRecipients[i].Item;
break;
}
return item.LastSentSignalRecipients[i].Item;
}
}
return focusTarget;
return null;
}
public override bool Pick(Character picker)
@@ -300,6 +300,8 @@ namespace Barotrauma.Items.Components
}
}
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Name ?? "none") + ":" + targetItem.prefab.Identifier);
if (targetItem.AllowDeconstruct && allowRemove)
{
//drop all items that are inside the deconstructed item
@@ -397,6 +397,7 @@ namespace Barotrauma.Items.Components
for (int i = 0; i < (int)fabricationitemAmount.Value; i++)
{
float outCondition = fabricatedItem.OutCondition;
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Name ?? "none") + ":" + fabricatedItem.TargetItem.Identifier);
if (i < amountFittingContainer)
{
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, outputContainer.Inventory, fabricatedItem.TargetItem.Health * outCondition, quality,
@@ -314,26 +314,6 @@ namespace Barotrauma.Items.Components
return TextManager.GetWithVariable("roomname.subdiroclock", "[dir]", clockDir.ToString());
}
private Vector2 GetTransducerPos()
{
if (!UseTransducers || connectedTransducers.Count == 0)
{
//use the position of the sub if the item is static (no body) and inside a sub
return item.Submarine != null && item.body == null ? item.Submarine.WorldPosition : item.WorldPosition;
}
Vector2 transducerPosSum = Vector2.Zero;
foreach (ConnectedTransducer transducer in connectedTransducers)
{
if (transducer.Transducer.Item.Submarine != null && CenterOnTransducers)
{
return transducer.Transducer.Item.Submarine.WorldPosition;
}
transducerPosSum += transducer.Transducer.Item.WorldPosition;
}
return transducerPosSum / connectedTransducers.Count;
}
public override void ReceiveSignal(Signal signal, Connection connection)
{
base.ReceiveSignal(signal, connection);
@@ -113,6 +113,9 @@ namespace Barotrauma.Items.Components
[Serialize(false, true, description: "If true, the recharge speed (and power consumption) of the device goes up exponentially as the recharge rate is increased.")]
public bool ExponentialRechargeSpeed { get; set; }
[Editable(minValue: 0.0f, maxValue: 10.0f, decimals: 2), Serialize(0.5f, true)]
public float RechargeAdjustSpeed { get; set; }
private float efficiency;
[Editable(minValue: 0.0f, maxValue: 1.0f, decimals: 2), Serialize(0.95f, true, description: "The amount of power you can get out of a item relative to the amount of power that's put into it.")]
public float Efficiency
@@ -199,7 +202,14 @@ namespace Barotrauma.Items.Components
{
targetRechargeSpeed *= missingCharge;
}
currPowerConsumption = MathHelper.Lerp(currPowerConsumption, targetRechargeSpeed, 0.05f);
if (currPowerConsumption < targetRechargeSpeed)
{
currPowerConsumption = Math.Min(currPowerConsumption + deltaTime * maxRechargeSpeed * RechargeAdjustSpeed, targetRechargeSpeed);
}
else
{
currPowerConsumption = Math.Max(currPowerConsumption - deltaTime * maxRechargeSpeed * RechargeAdjustSpeed, targetRechargeSpeed);
}
Charge += currPowerConsumption * Math.Min(Voltage, 1.0f) / 3600.0f * efficiency;
}
@@ -244,7 +244,6 @@ namespace Barotrauma.Items.Components
return picker != null;
}
private static readonly HashSet<Connection> tempConnected = new HashSet<Connection>();
protected void RefreshConnections()
{
var connections = item.Connections;
@@ -260,41 +259,51 @@ namespace Barotrauma.Items.Components
}
//find all connections that are connected to this one (directly or via another PowerTransfer)
tempConnected.Clear();
HashSet<Connection> tempConnected;
if (!connectedRecipients.ContainsKey(c))
{
tempConnected = new HashSet<Connection>();
connectedRecipients.Add(c, tempConnected);
}
else
{
tempConnected = connectedRecipients[c];
tempConnected.Clear();
//mark all previous recipients as dirty
foreach (Connection recipient in tempConnected)
{
var pt = recipient.Item.GetComponent<PowerTransfer>();
if (pt != null) { pt.connectionDirty[recipient] = true; }
}
}
tempConnected.Add(c);
if (item.Condition > 0.0f)
{
if (!connectedRecipients.ContainsKey(c))
{
connectedRecipients.Add(c, tempConnected);
}
else
{
//mark all previous recipients as dirty
foreach (Connection recipient in connectedRecipients[c])
{
var pt = recipient.Item.GetComponent<PowerTransfer>();
if (pt != null) pt.connectionDirty[recipient] = true;
}
}
tempConnected.Add(c);
GetConnected(c, tempConnected);
}
connectedRecipients[c] = tempConnected;
//go through all the PowerTransfers that we're connected to and set their connections to match the ones we just calculated
//(no need to go through the recursive GetConnected method again)
foreach (Connection recipient in tempConnected)
{
if (recipient == c) { continue; }
var recipientPowerTransfer = recipient.Item.GetComponent<PowerTransfer>();
if (recipientPowerTransfer == null) { continue; }
if (!connectedRecipients.ContainsKey(recipient))
//go through all the PowerTransfers that we're connected to and set their connections to match the ones we just calculated
//(no need to go through the recursive GetConnected method again)
foreach (Connection recipient in tempConnected)
{
connectedRecipients.Add(recipient, tempConnected);
if (recipient == c) { continue; }
var recipientPowerTransfer = recipient.Item.GetComponent<PowerTransfer>();
if (recipientPowerTransfer == null) { continue; }
if (!recipientPowerTransfer.connectedRecipients.ContainsKey(recipient))
{
recipientPowerTransfer.connectedRecipients.Add(recipient, new HashSet<Connection>());
}
else
{
recipientPowerTransfer.connectedRecipients[recipient].Clear();
}
foreach (var connection in tempConnected)
{
recipientPowerTransfer.connectedRecipients[recipient].Add(connection);
}
recipientPowerTransfer.connectionDirty[recipient] = false;
}
recipientPowerTransfer.connectionDirty[recipient] = false;
}
connectionDirty[c] = false;
}
}
@@ -543,6 +543,7 @@ namespace Barotrauma.Items.Components
{
if (fixture.Body.UserData is VoronoiCell) { return -1; }
if (fixture.Body.UserData is Entity entity && entity.Submarine != submarine) { return -1; }
if (fixture.Body.UserData is Limb limb && limb.character?.Submarine != submarine) { return -1; }
}
//ignore level cells if the item and the point of impact are inside a sub
@@ -87,7 +87,11 @@ namespace Barotrauma.Items.Components
}
string signalOut = sendOutput ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) { return; }
if (string.IsNullOrEmpty(signalOut))
{
IsActive = false;
return;
}
item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
}
@@ -100,11 +104,13 @@ namespace Barotrauma.Items.Components
if (signal.value == "0") { return; }
timeSinceReceived[0] = 0.0f;
signalSender[0] = signal.sender;
IsActive = true;
break;
case "signal_in2":
if (signal.value == "0") { return; }
timeSinceReceived[1] = 0.0f;
signalSender[1] = signal.sender;
IsActive = true;
break;
case "set_output":
output = signal.value;
@@ -23,7 +23,6 @@ namespace Barotrauma.Items.Components
public ButtonTerminal(Item item, XElement element) : base(item, element)
{
IsActive = true;
RequiredSignalCount = element.GetChildElements("TerminalButton").Count(c => c.GetAttribute("style") != null);
if (RequiredSignalCount < 1)
{
@@ -88,13 +87,13 @@ namespace Barotrauma.Items.Components
}
}
var containers = item.GetComponents<ItemContainer>().ToList();
if (containers.Count != 1)
var containers = item.GetComponents<ItemContainer>();
if (containers.Count() != 1)
{
DebugConsole.ThrowError($"Error in item \"{item.Name}\": the ButtonTerminal component requires exactly one ItemContainer component!");
return;
}
Container = containers[0];
Container = containers.FirstOrDefault();
OnItemLoadedProjSpecific();
}
@@ -66,11 +66,16 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
if (signalQueue.Count == 0)
{
IsActive = false;
return;
}
foreach (var val in signalQueue)
{
val.SendTimer -= 1;
}
while (signalQueue.Count > 0 && signalQueue.Peek().SendTimer <= 0)
{
var signalOut = signalQueue.Peek();
@@ -114,6 +119,7 @@ namespace Barotrauma.Items.Components
SendDuration = 1
};
signalQueue.Enqueue(prevQueuedSignal);
IsActive = true;
break;
case "set_delay":
if (float.TryParse(signal.value, NumberStyles.Any, CultureInfo.InvariantCulture, out float newDelay))
@@ -26,6 +26,8 @@ namespace Barotrauma.Items.Components
public PhysicsBody ParentBody;
private bool isOn;
private Turret turret;
[Serialize(100.0f, true, description: "The range of the emitted light. Higher values are more performance-intensive.", alwaysUseInstanceValues: true),
@@ -85,12 +87,13 @@ namespace Barotrauma.Items.Components
[Editable, Serialize(false, true, description: "Is the light currently on.", alwaysUseInstanceValues: true)]
public bool IsOn
{
get { return IsActive; }
get { return isOn; }
set
{
if (IsActive == value) { return; }
if (isOn == value && IsActive == value) { return; }
IsActive = value;
IsActive = isOn = value;
SetLightSourceState(value, value ? lightBrightness : 0.0f);
OnStateChanged();
}
}
@@ -200,9 +203,8 @@ namespace Barotrauma.Items.Components
set
{
if (base.IsActive == value) { return; }
base.IsActive = value;
SetLightSourceState(value, value ? lightBrightness : 0.0f);
base.IsActive = isOn = value;
SetLightSourceState(value, value ? lightBrightness : 0.0f);
}
}
@@ -237,6 +239,23 @@ namespace Barotrauma.Items.Components
turret = item.GetComponent<Turret>();
}
public override void OnMapLoaded()
{
if (item.body == null && powerConsumption <= 0.0f && Parent == null && turret == null &&
(statusEffectLists == null || !statusEffectLists.ContainsKey(ActionType.OnActive)) &&
(IsActiveConditionals == null || IsActiveConditionals.Count == 0))
{
lightBrightness = 1.0f;
SetLightSourceState(true, lightBrightness);
SetLightSourceTransformProjSpecific();
base.IsActive = false;
isOn = true;
#if CLIENT
Light.ParentSub = item.Submarine;
#endif
}
}
public override void Update(float deltaTime, Camera cam)
{
if (item.AiTarget != null)
@@ -20,7 +20,11 @@ namespace Barotrauma.Items.Components
}
string signalOut = sendOutput ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) { return; }
if (string.IsNullOrEmpty(signalOut))
{
IsActive = false;
return;
}
item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
}
@@ -8,12 +8,15 @@ using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
partial class WifiComponent : ItemComponent
partial class WifiComponent : ItemComponent, IServerSerializable
{
private static readonly List<WifiComponent> list = new List<WifiComponent>();
const int ChannelMemorySize = 10;
private const int MinChannel = 0;
private const int MaxChannel = 10000;
private float range;
private int channel;
@@ -49,7 +52,7 @@ namespace Barotrauma.Items.Components
get { return channel; }
set
{
channel = MathHelper.Clamp(value, 0, 10000);
channel = MathHelper.Clamp(value, MinChannel, MaxChannel);
}
}
@@ -295,7 +298,14 @@ namespace Barotrauma.Items.Components
case "set_channel":
if (int.TryParse(signal.value, out int newChannel))
{
int prevChannel = Channel;
Channel = newChannel;
if (prevChannel != Channel)
{
#if SERVER
item.CreateServerEvent(this);
#endif
}
}
break;
case "set_range":
@@ -20,7 +20,11 @@ namespace Barotrauma.Items.Components
}
string signalOut = sendOutput == 1 ? output : falseOutput;
if (string.IsNullOrEmpty(signalOut)) { return; }
if (string.IsNullOrEmpty(signalOut))
{
IsActive = false;
return;
}
item.SendSignal(new Signal(signalOut, sender: signalSender[0] ?? signalSender[1]), "signal_out");
}
@@ -1442,6 +1442,11 @@ namespace Barotrauma.Items.Components
crosshairPointerSprite?.Remove(); crosshairPointerSprite = null;
moveSoundChannel?.Dispose(); moveSoundChannel = null;
WeaponIndicatorSprite?.Remove(); WeaponIndicatorSprite = null;
if (powerIndicator != null)
{
powerIndicator.RectTransform.Parent = null;
powerIndicator = null;
}
#endif
}