v1.1.19.3 (Treacherous Tides Hotfix 2)
This commit is contained in:
@@ -71,6 +71,12 @@ namespace Barotrauma.Items.Components
|
||||
protected const float CorrectionDelay = 1.0f;
|
||||
protected CoroutineHandle delayedCorrectionCoroutine;
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, the contents of the item are not transferred when the player transfers items between subs.
|
||||
/// Use this if this component uses item containers in a way where removing the item from the container via external means would cause problems.
|
||||
/// </summary>
|
||||
public virtual bool DontTransferInventoryBetweenSubs => false;
|
||||
|
||||
[Editable, Serialize(0.0f, IsPropertySaveable.No, description: "How long it takes to pick up the item (in seconds).")]
|
||||
public float PickingTime
|
||||
{
|
||||
|
||||
@@ -416,7 +416,7 @@ namespace Barotrauma.Items.Components
|
||||
if (requiredItem.UseCondition && suitableIngredient.ConditionPercentage - requiredItem.MinCondition * 100 > 0.0f)
|
||||
{
|
||||
suitableIngredient.Condition -= suitableIngredient.Prefab.Health * requiredItem.MinCondition;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (suitableIngredient.OwnInventory != null)
|
||||
{
|
||||
|
||||
@@ -82,6 +82,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private List<LightComponent>? lightComponents;
|
||||
|
||||
// We don't want the seeds to be transferred to a new submarine as seeds are not supposed to leave the container after they have been planted.
|
||||
public override bool DontTransferInventoryBetweenSubs => true;
|
||||
|
||||
public Planter(Item item, ContentXElement element) : base(item, element)
|
||||
{
|
||||
canBePicked = true;
|
||||
|
||||
@@ -26,19 +26,37 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool IsActive => true;
|
||||
|
||||
// We don't want the components and wires to transfer between subs as it would cause issues.
|
||||
public override bool DontTransferInventoryBetweenSubs => true;
|
||||
|
||||
public Option<CircuitBoxConnection> FindInputOutputConnection(Identifier connectionName)
|
||||
{
|
||||
foreach (CircuitBoxInputConnection input in Inputs)
|
||||
{
|
||||
if (input.Name != connectionName) { continue; }
|
||||
|
||||
return Option.Some<CircuitBoxConnection>(input);
|
||||
}
|
||||
|
||||
foreach (CircuitBoxOutputConnection output in Outputs)
|
||||
{
|
||||
if (output.Name != connectionName) { continue; }
|
||||
return Option.Some<CircuitBoxConnection>(output);
|
||||
}
|
||||
|
||||
return Option.None;
|
||||
}
|
||||
|
||||
public Option<CircuitBoxConnection> FindInputOutputConnection(Connection connection)
|
||||
{
|
||||
foreach (CircuitBoxInputConnection input in Inputs)
|
||||
{
|
||||
if (input.Connection != connection) { continue; }
|
||||
return Option.Some<CircuitBoxConnection>(input);
|
||||
}
|
||||
|
||||
foreach (CircuitBoxOutputConnection output in Outputs)
|
||||
{
|
||||
if (output.Connection != connection) { continue; }
|
||||
return Option.Some<CircuitBoxConnection>(output);
|
||||
}
|
||||
|
||||
@@ -338,7 +356,7 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnItem(this, prefab, WireContainer, wire =>
|
||||
SpawnItem(prefab, user: null, container: WireContainer, onSpawned: wire =>
|
||||
{
|
||||
AddWireDirect(wireId, prefab, Option.Some(wire), one, two);
|
||||
onItemSpawned(wire);
|
||||
@@ -359,7 +377,7 @@ namespace Barotrauma.Items.Components
|
||||
private void AddWireDirect(ushort id, ItemPrefab prefab, Option<Item> backingItem, CircuitBoxConnection one, CircuitBoxConnection two)
|
||||
=> Wires.Add(new CircuitBoxWire(this, id, backingItem, one, two, prefab));
|
||||
|
||||
private bool AddComponentInternal(ushort id, ItemPrefab prefab, ItemPrefab usedResource, Vector2 pos, Action<Item> onItemSpawned)
|
||||
private bool AddComponentInternal(ushort id, ItemPrefab prefab, ItemPrefab usedResource, Vector2 pos, Character? user, Action<Item>? onItemSpawned)
|
||||
{
|
||||
if (id is ICircuitBoxIdentifiable.NullComponentID)
|
||||
{
|
||||
@@ -373,10 +391,10 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
SpawnItem(this, prefab, ComponentContainer, spawnedItem =>
|
||||
SpawnItem(prefab, user, ComponentContainer, spawnedItem =>
|
||||
{
|
||||
Components.Add(new CircuitBoxComponent(id, spawnedItem, pos, this, usedResource));
|
||||
onItemSpawned(spawnedItem);
|
||||
onItemSpawned?.Invoke(spawnedItem);
|
||||
});
|
||||
|
||||
OnViewUpdateProjSpecific();
|
||||
@@ -646,7 +664,7 @@ namespace Barotrauma.Items.Components
|
||||
return Option.None;
|
||||
}
|
||||
|
||||
public static void SpawnItem(CircuitBox circuitBox, ItemPrefab prefab, ItemContainer? container, Action<Item> onSpawned)
|
||||
public static void SpawnItem(ItemPrefab prefab, Character? user, ItemContainer? container, Action<Item> onSpawned)
|
||||
{
|
||||
if (container is null)
|
||||
{
|
||||
@@ -655,13 +673,27 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (IsInGame())
|
||||
{
|
||||
Entity.Spawner?.AddItemToSpawnQueue(prefab, container.Inventory, onSpawned: onSpawned);
|
||||
Entity.Spawner?.AddItemToSpawnQueue(prefab, container.Inventory, onSpawned: it =>
|
||||
{
|
||||
AssignWifiComponentTeam(it, user);
|
||||
onSpawned(it);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Item forceSpawnedItem = new Item(prefab, Vector2.Zero, null);
|
||||
container.Inventory.TryPutItem(forceSpawnedItem, null);
|
||||
onSpawned(forceSpawnedItem);
|
||||
AssignWifiComponentTeam(forceSpawnedItem, user);
|
||||
|
||||
static void AssignWifiComponentTeam(Item item, Character? user)
|
||||
{
|
||||
if (user == null) { return; }
|
||||
foreach (WifiComponent wifiComponent in item.GetComponents<WifiComponent>())
|
||||
{
|
||||
wifiComponent.TeamID = user.TeamID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveItem(Item item)
|
||||
|
||||
@@ -98,11 +98,11 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
/// <param name="maxStackSize">Defaults to <see cref="ItemPrefab.MaxStackSize"/> if null</param>
|
||||
public int HowManyCanBePut(ItemPrefab itemPrefab, int? maxStackSize = null, float? condition = null)
|
||||
public int HowManyCanBePut(ItemPrefab itemPrefab, int? maxStackSize = null, float? condition = null, bool ignoreItemsInSlot = false)
|
||||
{
|
||||
if (itemPrefab == null) { return 0; }
|
||||
maxStackSize ??= itemPrefab.GetMaxStackSize(inventory);
|
||||
if (items.Count > 0)
|
||||
if (items.Count > 0 && !ignoreItemsInSlot)
|
||||
{
|
||||
if (condition.HasValue)
|
||||
{
|
||||
@@ -517,10 +517,10 @@ namespace Barotrauma
|
||||
return count;
|
||||
}
|
||||
|
||||
public virtual int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition)
|
||||
public virtual int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition, bool ignoreItemsInSlot = false)
|
||||
{
|
||||
if (i < 0 || i >= slots.Length) { return 0; }
|
||||
return slots[i].HowManyCanBePut(itemPrefab, condition: condition);
|
||||
return slots[i].HowManyCanBePut(itemPrefab, condition: condition, ignoreItemsInSlot: ignoreItemsInSlot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -862,7 +862,25 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
return ownInventory?.AllItems ?? Enumerable.Empty<Item>();
|
||||
if (OwnInventories.Length < 2)
|
||||
{
|
||||
if (OwnInventory == null) { yield break; }
|
||||
|
||||
foreach (var item in OwnInventory.AllItems)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var inventory in OwnInventories)
|
||||
{
|
||||
foreach (var item in inventory.AllItems)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,6 +889,8 @@ namespace Barotrauma
|
||||
get { return ownInventory; }
|
||||
}
|
||||
|
||||
public readonly ImmutableArray<ItemInventory> OwnInventories = ImmutableArray<ItemInventory>.Empty;
|
||||
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes, description:
|
||||
"Enable if you want to display the item HUD side by side with another item's HUD, when linked together. " +
|
||||
"Disclaimer: It's possible or even likely that the views block each other, if they were not designed to be viewed together!")]
|
||||
@@ -1192,6 +1212,8 @@ namespace Barotrauma
|
||||
ownInventory = itemContainer.Inventory;
|
||||
}
|
||||
|
||||
OwnInventories = GetComponents<ItemContainer>().Select(ic => ic.Inventory).ToImmutableArray();
|
||||
|
||||
qualityComponent = GetComponent<Quality>();
|
||||
|
||||
IsLadder = GetComponent<Ladder>() != null;
|
||||
@@ -2533,8 +2555,7 @@ namespace Barotrauma
|
||||
foreach (Connection c in connectionPanel.Connections)
|
||||
{
|
||||
if (connectionFilter != null && !connectionFilter.Invoke(c)) { continue; }
|
||||
var recipients = c.Recipients;
|
||||
foreach (Connection recipient in recipients)
|
||||
foreach (Connection recipient in c.Recipients)
|
||||
{
|
||||
var component = recipient.Item.GetComponent<T>();
|
||||
if (component != null && !connectedComponents.Contains(component))
|
||||
@@ -2587,9 +2608,20 @@ namespace Barotrauma
|
||||
private void GetConnectedComponentsRecursive<T>(Connection c, HashSet<Connection> alreadySearched, List<T> connectedComponents, bool ignoreInactiveRelays, bool allowTraversingBackwards = true) where T : ItemComponent
|
||||
{
|
||||
alreadySearched.Add(c);
|
||||
|
||||
var recipients = c.Recipients;
|
||||
foreach (Connection recipient in recipients)
|
||||
static IEnumerable<Connection> GetRecipients(Connection c)
|
||||
{
|
||||
foreach (Connection recipient in c.Recipients)
|
||||
{
|
||||
yield return recipient;
|
||||
}
|
||||
//check circuit box inputs/outputs this connection is connected to
|
||||
foreach (var circuitBoxConnection in c.CircuitBoxConnections)
|
||||
{
|
||||
yield return circuitBoxConnection.Connection;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Connection recipient in GetRecipients(c))
|
||||
{
|
||||
if (alreadySearched.Contains(recipient)) { continue; }
|
||||
var component = recipient.Item.GetComponent<T>();
|
||||
@@ -2598,23 +2630,53 @@ namespace Barotrauma
|
||||
connectedComponents.Add(component);
|
||||
}
|
||||
|
||||
//connected to a wifi component -> see which other wifi components it can communicate with
|
||||
var wifiComponent = recipient.Item.GetComponent<WifiComponent>();
|
||||
if (wifiComponent != null && wifiComponent.CanTransmit())
|
||||
var circuitBox = recipient.Item.GetComponent<CircuitBox>();
|
||||
if (circuitBox != null)
|
||||
{
|
||||
foreach (var wifiReceiver in wifiComponent.GetTransmittersInRange())
|
||||
//if this is a circuit box, check what the connection is connected to inside the box
|
||||
var potentialCbConnection = circuitBox.FindInputOutputConnection(recipient);
|
||||
if (potentialCbConnection.TryUnwrap(out var cbConnection))
|
||||
{
|
||||
var receiverConnections = wifiReceiver.Item.Connections;
|
||||
if (receiverConnections == null) { continue; }
|
||||
foreach (Connection wifiOutput in receiverConnections)
|
||||
if (cbConnection is CircuitBoxInputConnection inputConnection)
|
||||
{
|
||||
if ((wifiOutput.IsOutput == recipient.IsOutput) || alreadySearched.Contains(wifiOutput)) { continue; }
|
||||
GetConnectedComponentsRecursive(wifiOutput, alreadySearched, connectedComponents, ignoreInactiveRelays, allowTraversingBackwards);
|
||||
foreach (var connectedTo in inputConnection.ExternallyConnectedTo)
|
||||
{
|
||||
if (alreadySearched.Contains(connectedTo.Connection)) { continue; }
|
||||
CheckRecipient(connectedTo.Connection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var connectedFrom in cbConnection.ExternallyConnectedFrom)
|
||||
{
|
||||
if (alreadySearched.Contains(connectedFrom.Connection) || !allowTraversingBackwards) { continue; }
|
||||
CheckRecipient(connectedFrom.Connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckRecipient(recipient);
|
||||
|
||||
recipient.Item.GetConnectedComponentsRecursive(recipient, alreadySearched, connectedComponents, ignoreInactiveRelays, allowTraversingBackwards);
|
||||
void CheckRecipient(Connection recipient)
|
||||
{
|
||||
//connected to a wifi component -> see which other wifi components it can communicate with
|
||||
var wifiComponent = recipient.Item.GetComponent<WifiComponent>();
|
||||
if (wifiComponent != null && wifiComponent.CanTransmit())
|
||||
{
|
||||
foreach (var wifiReceiver in wifiComponent.GetTransmittersInRange())
|
||||
{
|
||||
var receiverConnections = wifiReceiver.Item.Connections;
|
||||
if (receiverConnections == null) { continue; }
|
||||
foreach (Connection wifiOutput in receiverConnections)
|
||||
{
|
||||
if ((wifiOutput.IsOutput == recipient.IsOutput) || alreadySearched.Contains(wifiOutput)) { continue; }
|
||||
GetConnectedComponentsRecursive(wifiOutput, alreadySearched, connectedComponents, ignoreInactiveRelays, allowTraversingBackwards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recipient.Item.GetConnectedComponentsRecursive(recipient, alreadySearched, connectedComponents, ignoreInactiveRelays, allowTraversingBackwards);
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreInactiveRelays)
|
||||
|
||||
@@ -58,12 +58,12 @@ namespace Barotrauma
|
||||
return itemPrefab != null && slots[i].CanBePut(itemPrefab, condition, quality) && slots[i].Items.Count < container.GetMaxStackSize(i);
|
||||
}
|
||||
|
||||
public override int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition)
|
||||
public override int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition, bool ignoreItemsInSlot = false)
|
||||
{
|
||||
if (itemPrefab == null) { return 0; }
|
||||
if (i < 0 || i >= slots.Length) { return 0; }
|
||||
if (!container.CanBeContained(itemPrefab, i)) { return 0; }
|
||||
return slots[i].HowManyCanBePut(itemPrefab, maxStackSize: Math.Min(itemPrefab.GetMaxStackSize(this), container.GetMaxStackSize(i)), condition);
|
||||
return slots[i].HowManyCanBePut(itemPrefab, maxStackSize: Math.Min(itemPrefab.GetMaxStackSize(this), container.GetMaxStackSize(i)), condition, ignoreItemsInSlot);
|
||||
}
|
||||
|
||||
public override bool IsFull(bool takeStacksIntoAccount = false)
|
||||
|
||||
@@ -843,7 +843,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private int maxStackSizeCharacterInventory;
|
||||
[Serialize(-1, IsPropertySaveable.No)]
|
||||
[Serialize(-1, IsPropertySaveable.No, description: "Maximum stack size when the item is in a character inventory.")]
|
||||
public int MaxStackSizeCharacterInventory
|
||||
{
|
||||
get { return maxStackSizeCharacterInventory; }
|
||||
@@ -851,7 +851,9 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private int maxStackSizeHoldableOrWearableInventory;
|
||||
[Serialize(-1, IsPropertySaveable.No)]
|
||||
[Serialize(-1, IsPropertySaveable.No, description:
|
||||
"Maximum stack size when the item is inside a holdable or wearable item. "+
|
||||
"If not set, defaults to MaxStackSizeCharacterInventory.")]
|
||||
public int MaxStackSizeHoldableOrWearableInventory
|
||||
{
|
||||
get { return maxStackSizeHoldableOrWearableInventory; }
|
||||
@@ -864,15 +866,20 @@ namespace Barotrauma
|
||||
{
|
||||
return maxStackSizeCharacterInventory;
|
||||
}
|
||||
else if (maxStackSizeHoldableOrWearableInventory > 0 &&
|
||||
inventory?.Owner is Item item && (item.GetComponent<Holdable>() != null || item.GetComponent<Wearable>() != null))
|
||||
else if (inventory?.Owner is Item item &&
|
||||
(item.GetComponent<Holdable>() is { Attachable: false } || item.GetComponent<Wearable>() != null))
|
||||
{
|
||||
return maxStackSizeHoldableOrWearableInventory;
|
||||
}
|
||||
else
|
||||
{
|
||||
return maxStackSize;
|
||||
if (maxStackSizeHoldableOrWearableInventory > 0)
|
||||
{
|
||||
return maxStackSizeHoldableOrWearableInventory;
|
||||
}
|
||||
else if (maxStackSizeCharacterInventory > 0)
|
||||
{
|
||||
//if maxStackSizeHoldableOrWearableInventory is not set, it defaults to maxStackSizeCharacterInventory
|
||||
return maxStackSizeCharacterInventory;
|
||||
}
|
||||
}
|
||||
return maxStackSize;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
@@ -880,7 +887,7 @@ namespace Barotrauma
|
||||
|
||||
public ImmutableHashSet<Identifier> AllowDroppingOnSwapWith { get; private set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
[Serialize(false, IsPropertySaveable.No, "If enabled, the item is not transferred when the player transfers items between subs.")]
|
||||
public bool DontTransferBetweenSubs { get; private set; }
|
||||
|
||||
[Serialize(true, IsPropertySaveable.No)]
|
||||
@@ -1032,6 +1039,7 @@ namespace Barotrauma
|
||||
var levelCommonness = new Dictionary<Identifier, CommonnessInfo>();
|
||||
var levelQuantity = new Dictionary<Identifier, FixedQuantityResourceInfo>();
|
||||
|
||||
List<FabricationRecipe> loadedRecipes = new List<FabricationRecipe>();
|
||||
foreach (ContentXElement subElement in ConfigElement.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -1114,9 +1122,10 @@ namespace Barotrauma
|
||||
var newRecipe = new FabricationRecipe(subElement, Identifier);
|
||||
if (fabricationRecipes.TryGetValue(newRecipe.RecipeHash, out var prevRecipe))
|
||||
{
|
||||
int prevRecipeIndex = loadedRecipes.IndexOf(prevRecipe);
|
||||
DebugConsole.ThrowError(
|
||||
$"Error in item prefab \"{ToString()}\": " +
|
||||
$"{prevRecipe.TargetItemPrefabIdentifier} has the same hash as {newRecipe.TargetItemPrefabIdentifier}. " +
|
||||
$"Fabrication recipe #{loadedRecipes.Count + 1} has the same hash as recipe #{prevRecipeIndex + 1}. This is most likely caused by identical, duplicate recipes." +
|
||||
$"This will cause issues with fabrication."
|
||||
);
|
||||
}
|
||||
@@ -1124,6 +1133,7 @@ namespace Barotrauma
|
||||
{
|
||||
fabricationRecipes.Add(newRecipe.RecipeHash, newRecipe);
|
||||
}
|
||||
loadedRecipes.Add(newRecipe);
|
||||
break;
|
||||
case "preferredcontainer":
|
||||
var preferredContainer = new PreferredContainer(subElement);
|
||||
|
||||
Reference in New Issue
Block a user