Unstable 0.17.0.0
This commit is contained in:
@@ -20,7 +20,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public string Name => LimbType.ToString();
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties => null;
|
||||
public Dictionary<Identifier, SerializableProperty> SerializableProperties => null;
|
||||
|
||||
public LimbPos(LimbType limbType, Vector2 position, bool allowUsingLimb)
|
||||
{
|
||||
@@ -61,21 +61,21 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public IEnumerable<LimbPos> LimbPositions { get { return limbPositions; } }
|
||||
|
||||
[Editable, Serialize(false, false, description: "When enabled, the item will continuously send out a 0/1 signal and interacting with it will flip the signal (making the item behave like a switch). When disabled, the item will simply send out 1 when interacted with.", alwaysUseInstanceValues: true)]
|
||||
[Editable, Serialize(false, IsPropertySaveable.No, description: "When enabled, the item will continuously send out a 0/1 signal and interacting with it will flip the signal (making the item behave like a switch). When disabled, the item will simply send out 1 when interacted with.", alwaysUseInstanceValues: true)]
|
||||
public bool IsToggle
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, false, description: "Whether the item is toggled on/off. Only valid if IsToggle is set to true.", alwaysUseInstanceValues: true)]
|
||||
[Editable, Serialize(false, IsPropertySaveable.No, description: "Whether the item is toggled on/off. Only valid if IsToggle is set to true.", alwaysUseInstanceValues: true)]
|
||||
public bool State
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, false, description: "Should the HUD (inventory, health bar, etc) be hidden when this item is selected.")]
|
||||
[Serialize(true, IsPropertySaveable.No, description: "Should the HUD (inventory, health bar, etc) be hidden when this item is selected.")]
|
||||
public bool HideHUD
|
||||
{
|
||||
get;
|
||||
@@ -87,10 +87,10 @@ namespace Barotrauma.Items.Components
|
||||
Air, Water, Both
|
||||
};
|
||||
|
||||
[Serialize(UseEnvironment.Both, false, description: "Can the item be selected in air, underwater or both.")]
|
||||
[Serialize(UseEnvironment.Both, IsPropertySaveable.No, description: "Can the item be selected in air, underwater or both.")]
|
||||
public UseEnvironment UsableIn { get; set; }
|
||||
|
||||
[Serialize(false, false, description: "Should the character using the item be drawn behind the item.")]
|
||||
[Serialize(false, IsPropertySaveable.No, description: "Should the character using the item be drawn behind the item.")]
|
||||
public bool DrawUserBehind
|
||||
{
|
||||
get;
|
||||
@@ -114,7 +114,7 @@ namespace Barotrauma.Items.Components
|
||||
private set;
|
||||
} = true;
|
||||
|
||||
public Controller(Item item, XElement element)
|
||||
public Controller(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
limbPositions = new List<LimbPos>();
|
||||
@@ -123,7 +123,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Enum.TryParse(element.GetAttributeString("direction", "None"), out dir);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name != "limbposition") { continue; }
|
||||
string limbStr = subElement.GetAttributeString("limb", "");
|
||||
|
||||
+19
-20
@@ -33,15 +33,15 @@ namespace Barotrauma.Items.Components
|
||||
get { return outputContainer; }
|
||||
}
|
||||
|
||||
[Serialize(false, true)]
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool DeconstructItemsSimultaneously { get; set; }
|
||||
|
||||
[Editable, Serialize(1.0f, true)]
|
||||
[Editable, Serialize(1.0f, IsPropertySaveable.Yes)]
|
||||
public float DeconstructionSpeed { get; set; }
|
||||
|
||||
public override bool RecreateGUIOnResolutionChange => true;
|
||||
|
||||
public Deconstructor(Item item, XElement element)
|
||||
public Deconstructor(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
InitProjSpecific(element);
|
||||
@@ -88,8 +88,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
if (powerConsumption <= 0.0f) { Voltage = 1.0f; }
|
||||
progressTimer += deltaTime * Math.Min(Voltage, 1.0f);
|
||||
progressTimer += deltaTime * Math.Min(powerConsumption <= 0.0f ? 1 : Voltage, 1.0f);
|
||||
|
||||
float tinkeringStrength = 0f;
|
||||
if (repairable.IsTinkering)
|
||||
@@ -114,9 +113,9 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Item targetItem in items)
|
||||
{
|
||||
if ((Entity.Spawner?.IsInRemoveQueue(targetItem) ?? false) || !inputContainer.Inventory.AllItems.Contains(targetItem)) { continue; }
|
||||
var validDeconstructItems = targetItem.Prefab.DeconstructItems.FindAll(it =>
|
||||
(it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))) &&
|
||||
(it.RequiredOtherItem.Length == 0 || it.RequiredOtherItem.Any(r => items.Any(it => it != targetItem && (it.HasTag(r) || it.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))))));
|
||||
var validDeconstructItems = targetItem.Prefab.DeconstructItems.Where(it =>
|
||||
(it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier == r)) &&
|
||||
(it.RequiredOtherItem.Length == 0 || it.RequiredOtherItem.Any(r => items.Any(it => it != targetItem && (it.HasTag(r) || it.Prefab.Identifier == r))))).ToList();
|
||||
|
||||
ProcessItem(targetItem, items, validDeconstructItems, allowRemove: validDeconstructItems.Any() || !targetItem.Prefab.DeconstructItems.Any());
|
||||
}
|
||||
@@ -133,8 +132,8 @@ namespace Barotrauma.Items.Components
|
||||
var targetItem = inputContainer.Inventory.LastOrDefault();
|
||||
if (targetItem == null) { return; }
|
||||
|
||||
var validDeconstructItems = targetItem.Prefab.DeconstructItems.FindAll(it =>
|
||||
it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase)));
|
||||
var validDeconstructItems = targetItem.Prefab.DeconstructItems.Where(it =>
|
||||
it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier == r)).ToList();
|
||||
|
||||
float deconstructTime = validDeconstructItems.Any() ? targetItem.Prefab.DeconstructTime / (DeconstructionSpeed * deconstructionSpeedModifier) : 1.0f;
|
||||
|
||||
@@ -230,7 +229,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Item otherItem in inputItems)
|
||||
{
|
||||
if (targetItem == otherItem) { continue; }
|
||||
if (deconstructProduct.RequiredOtherItem.Any(r => otherItem.HasTag(r) || r.Equals(otherItem.Prefab.Identifier, StringComparison.OrdinalIgnoreCase)))
|
||||
if (deconstructProduct.RequiredOtherItem.Any(r => otherItem.HasTag(r) || r == otherItem.Prefab.Identifier))
|
||||
{
|
||||
user?.CheckTalents(AbilityEffectType.OnGeneticMaterialCombinedOrRefined);
|
||||
foreach (Character character in Character.GetFriendlyCrew(user))
|
||||
@@ -246,14 +245,14 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
inputContainer.Inventory.RemoveItem(otherItem);
|
||||
OutputContainer.Inventory.RemoveItem(otherItem);
|
||||
Entity.Spawner.AddToRemoveQueue(otherItem);
|
||||
Entity.Spawner.AddItemToRemoveQueue(otherItem);
|
||||
}
|
||||
allowRemove = false;
|
||||
return;
|
||||
}
|
||||
inputContainer.Inventory.RemoveItem(otherItem);
|
||||
OutputContainer.Inventory.RemoveItem(otherItem);
|
||||
Entity.Spawner.AddToRemoveQueue(otherItem);
|
||||
Entity.Spawner.AddItemToRemoveQueue(otherItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,7 +267,7 @@ namespace Barotrauma.Items.Components
|
||||
int amount = (int)amountMultiplier;
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
Entity.Spawner.AddToSpawnQueue(itemPrefab, outputContainer.Inventory, condition, onSpawned: (Item spawnedItem) =>
|
||||
Entity.Spawner.AddItemToSpawnQueue(itemPrefab, outputContainer.Inventory, condition, onSpawned: (Item spawnedItem) =>
|
||||
{
|
||||
spawnedItem.StolenDuringRound = targetItem.StolenDuringRound;
|
||||
spawnedItem.AllowStealing = targetItem.AllowStealing;
|
||||
@@ -300,7 +299,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none") + ":" + targetItem.prefab.Identifier);
|
||||
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Preset.Identifier.Value ?? "none") + ":" + targetItem.Prefab.Identifier);
|
||||
|
||||
if (targetItem.AllowDeconstruct && allowRemove)
|
||||
{
|
||||
@@ -314,7 +313,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
inputContainer.Inventory.RemoveItem(targetItem);
|
||||
Entity.Spawner.AddToRemoveQueue(targetItem);
|
||||
Entity.Spawner.AddItemToRemoveQueue(targetItem);
|
||||
MoveInputQueue();
|
||||
PutItemsToLinkedContainer();
|
||||
}
|
||||
@@ -392,16 +391,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (deconstructItem.RequiredDeconstructor.Length > 0)
|
||||
{
|
||||
if (!deconstructItem.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))) { continue; }
|
||||
if (!deconstructItem.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier == r)) { continue; }
|
||||
}
|
||||
if (deconstructItem.RequiredOtherItem.Length > 0 && checkRequiredOtherItems)
|
||||
{
|
||||
if (!deconstructItem.RequiredOtherItem.Any(r => items.Any(it => it.HasTag(r) || it.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase)))) { continue; }
|
||||
if (!deconstructItem.RequiredOtherItem.Any(r => items.Any(it => it.HasTag(r) || it.Prefab.Identifier == r))) { continue; }
|
||||
bool validOtherItemFound = false;
|
||||
foreach (Item otherInputItem in items)
|
||||
{
|
||||
if (otherInputItem == inputItem) { continue; }
|
||||
if (!deconstructItem.RequiredOtherItem.Any(r => otherInputItem.HasTag(r) || otherInputItem.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))) { continue; }
|
||||
if (!deconstructItem.RequiredOtherItem.Any(r => otherInputItem.HasTag(r) || otherInputItem.Prefab.Identifier == r)) { continue; }
|
||||
|
||||
var geneticMaterial1 = inputItem.GetComponent<GeneticMaterial>();
|
||||
var geneticMaterial2 = otherInputItem.GetComponent<GeneticMaterial>();
|
||||
@@ -427,7 +426,7 @@ namespace Barotrauma.Items.Components
|
||||
if (inputContainer.Inventory.IsEmpty()) { active = false; }
|
||||
|
||||
IsActive = active;
|
||||
currPowerConsumption = IsActive ? powerConsumption : 0.0f;
|
||||
//currPowerConsumption = IsActive ? powerConsumption : 0.0f;
|
||||
userDeconstructorSpeedMultiplier = user != null ? 1f + user.GetStatValue(StatTypes.DeconstructorSpeedMultiplier) : 1f;
|
||||
|
||||
#if SERVER
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Barotrauma.Items.Components
|
||||
public Character User;
|
||||
|
||||
[Editable(0.0f, 10000000.0f),
|
||||
Serialize(500.0f, true, description: "The amount of force exerted on the submarine when the engine is operating at full power.")]
|
||||
Serialize(500.0f, IsPropertySaveable.Yes, description: "The amount of force exerted on the submarine when the engine is operating at full power.")]
|
||||
public float MaxForce
|
||||
{
|
||||
get { return maxForce; }
|
||||
@@ -37,7 +37,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable, Serialize("0.0,0.0", true,
|
||||
[Editable, Serialize("0.0,0.0", IsPropertySaveable.Yes,
|
||||
description: "The position of the propeller as an offset from the item's center (in pixels)."+
|
||||
" Determines where the particles spawn and the position that causes characters to take damage from the engine if the PropellerDamage is defined.")]
|
||||
public Vector2 PropellerPos
|
||||
@@ -46,7 +46,7 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, true)]
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool DisablePropellerDamage
|
||||
{
|
||||
get;
|
||||
@@ -75,12 +75,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private const float TinkeringForceIncrease = 1.5f;
|
||||
|
||||
public Engine(Item item, XElement element)
|
||||
public Engine(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
@@ -93,7 +93,7 @@ namespace Barotrauma.Items.Components
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
partial void InitProjSpecific(ContentXElement element);
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
@@ -103,14 +103,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
controlLockTimer -= deltaTime;
|
||||
|
||||
currPowerConsumption = Math.Abs(targetForce) / 100.0f * powerConsumption;
|
||||
//engines consume more power when in a bad condition
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref currPowerConsumption);
|
||||
if (powerConsumption == 0.0f)
|
||||
{
|
||||
prevVoltage = 1;
|
||||
hasPower = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasPower = Voltage > MinVoltage;
|
||||
}
|
||||
|
||||
if (powerConsumption == 0.0f) { Voltage = 1.0f; }
|
||||
|
||||
prevVoltage = Voltage;
|
||||
hasPower = Voltage > MinVoltage;
|
||||
|
||||
Force = MathHelper.Lerp(force, (Voltage < MinVoltage) ? 0.0f : targetForce, deltaTime * 10.0f);
|
||||
if (Math.Abs(Force) > 1.0f)
|
||||
@@ -154,6 +156,33 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Power consumption of the engine. Only consume power when active and adjust consumption based on condition and target force.
|
||||
/// </summary>
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
if (connection != this.powerIn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
currPowerConsumption = Math.Abs(targetForce) / 100.0f * powerConsumption;
|
||||
//engines consume more power when in a bad condition
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref currPowerConsumption);
|
||||
return currPowerConsumption;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When grid is resolved update the previous voltage
|
||||
/// </summary>
|
||||
public override void GridResolved(Connection connection)
|
||||
{
|
||||
if (connection == powerIn)
|
||||
{
|
||||
prevVoltage = Voltage;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAITargets(float noise)
|
||||
{
|
||||
if (item.AiTarget != null)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
@@ -11,7 +13,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Fabricator : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private readonly List<FabricationRecipe> fabricationRecipes = new List<FabricationRecipe>();
|
||||
private ImmutableDictionary<uint, FabricationRecipe> fabricationRecipes; //this is not readonly because tutorials fuck this up!!!!
|
||||
|
||||
private FabricationRecipe fabricatedItem;
|
||||
private float timeUntilReady;
|
||||
@@ -20,7 +22,7 @@ namespace Barotrauma.Items.Components
|
||||
private string savedFabricatedItem;
|
||||
private float savedTimeUntilReady, savedRequiredTime;
|
||||
|
||||
private readonly Dictionary<string, List<Item>> availableIngredients = new Dictionary<string, List<Item>>();
|
||||
private readonly Dictionary<Identifier, List<Item>> availableIngredients = new Dictionary<Identifier, List<Item>>();
|
||||
|
||||
const float RefreshIngredientsInterval = 1.0f;
|
||||
private float refreshIngredientsTimer;
|
||||
@@ -31,10 +33,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private ItemContainer inputContainer, outputContainer;
|
||||
|
||||
[Serialize(1.0f, true)]
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes)]
|
||||
public float FabricationSpeed { get; set; }
|
||||
|
||||
[Serialize(1.0f, true)]
|
||||
[Serialize(1.0f, IsPropertySaveable.Yes)]
|
||||
public float SkillRequirementMultiplier { get; set; }
|
||||
|
||||
private const float TinkeringSpeedIncrease = 2.5f;
|
||||
@@ -78,10 +80,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float progressState;
|
||||
|
||||
public Fabricator(Item item, XElement element)
|
||||
public Fabricator(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
foreach (XElement subElement in element.Elements())
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name.ToString().Equals("fabricableitem", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -90,26 +92,22 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
var fabricationRecipes = new Dictionary<uint, FabricationRecipe>();
|
||||
foreach (ItemPrefab itemPrefab in ItemPrefab.Prefabs)
|
||||
{
|
||||
foreach (FabricationRecipe recipe in itemPrefab.FabricationRecipes)
|
||||
foreach (FabricationRecipe recipe in itemPrefab.FabricationRecipes.Values)
|
||||
{
|
||||
if (recipe.SuitableFabricatorIdentifiers.Length > 0)
|
||||
{
|
||||
if (!recipe.SuitableFabricatorIdentifiers.Any(i => item.prefab.Identifier == i || item.HasTag(i)))
|
||||
if (!recipe.SuitableFabricatorIdentifiers.Any(i => item.Prefab.Identifier == i || item.HasTag(i)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fabricationRecipes.Add(recipe);
|
||||
fabricationRecipes.Add(recipe.RecipeHash, recipe);
|
||||
}
|
||||
}
|
||||
fabricationRecipes.Sort((r1, r2) =>
|
||||
{
|
||||
int hash1 = (int)r1.TargetItem.UIntIdentifier;
|
||||
int hash2 = (int)r2.TargetItem.UIntIdentifier;
|
||||
return hash1 - hash2;
|
||||
});
|
||||
this.fabricationRecipes = fabricationRecipes.ToImmutableDictionary();
|
||||
|
||||
state = FabricatorState.Stopped;
|
||||
|
||||
@@ -129,9 +127,9 @@ namespace Barotrauma.Items.Components
|
||||
inputContainer = containers[0];
|
||||
outputContainer = containers[1];
|
||||
|
||||
foreach (var recipe in fabricationRecipes)
|
||||
foreach (var recipe in fabricationRecipes.Values)
|
||||
{
|
||||
if (recipe.RequiredItems.Count > inputContainer.Capacity)
|
||||
if (recipe.RequiredItems.Length > inputContainer.Capacity)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in item \"" + item.Name + "\": There's not enough room in the input inventory for the ingredients of \"" + recipe.TargetItem.Name + "\"!");
|
||||
}
|
||||
@@ -158,16 +156,11 @@ namespace Barotrauma.Items.Components
|
||||
return picker != null;
|
||||
}
|
||||
|
||||
public void RemoveFabricationRecipes(List<string> allowedIdentifiers)
|
||||
public void RemoveFabricationRecipes(IEnumerable<Identifier> allowedIdentifiers)
|
||||
{
|
||||
for (int i = 0; i < fabricationRecipes.Count; i++)
|
||||
{
|
||||
if (!allowedIdentifiers.Contains(fabricationRecipes[i].TargetItem.Identifier))
|
||||
{
|
||||
fabricationRecipes.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
fabricationRecipes = fabricationRecipes
|
||||
.Where(kvp => allowedIdentifiers.Contains(kvp.Value.TargetItemPrefabIdentifier))
|
||||
.ToImmutableDictionary();
|
||||
|
||||
CreateRecipes();
|
||||
}
|
||||
@@ -201,9 +194,6 @@ namespace Barotrauma.Items.Components
|
||||
inputContainer.Inventory.Locked = true;
|
||||
outputContainer.Inventory.Locked = true;
|
||||
|
||||
currPowerConsumption = powerConsumption;
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref currPowerConsumption);
|
||||
|
||||
if (GameMain.NetworkMember?.IsServer ?? true)
|
||||
{
|
||||
State = FabricatorState.Active;
|
||||
@@ -211,7 +201,7 @@ namespace Barotrauma.Items.Components
|
||||
#if SERVER
|
||||
if (user != null && addToServerLog)
|
||||
{
|
||||
GameServer.Log(GameServer.CharacterLogName(user) + " started fabricating " + selectedItem.DisplayName + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
GameServer.Log(GameServer.CharacterLogName(user) + " started fabricating " + selectedItem.DisplayName.Value + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -237,7 +227,7 @@ namespace Barotrauma.Items.Components
|
||||
#if SERVER
|
||||
if (user != null)
|
||||
{
|
||||
GameServer.Log(GameServer.CharacterLogName(user) + " cancelled the fabrication of " + fabricatedItem.DisplayName + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
GameServer.Log(GameServer.CharacterLogName(user) + " cancelled the fabrication of " + fabricatedItem.DisplayName.Value + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
#elif CLIENT
|
||||
itemList.Enabled = true;
|
||||
@@ -304,11 +294,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
if (powerConsumption <= 0) { Voltage = 1.0f; }
|
||||
|
||||
float fabricationSpeedIncrease = 1f + tinkeringStrength * TinkeringSpeedIncrease;
|
||||
|
||||
timeUntilReady -= deltaTime * fabricationSpeedIncrease * Math.Min(Voltage, 1.0f);
|
||||
timeUntilReady -= deltaTime * fabricationSpeedIncrease * Math.Min(powerConsumption <= 0 ? 1 : Voltage, 1.0f);
|
||||
|
||||
UpdateRequiredTimeProjSpecific();
|
||||
|
||||
@@ -370,7 +359,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
availableItems.Remove(availableItem);
|
||||
Entity.Spawner.AddToRemoveQueue(availableItem);
|
||||
Entity.Spawner.AddItemToRemoveQueue(availableItem);
|
||||
inputContainer.Inventory.RemoveItem(availableItem);
|
||||
break;
|
||||
}
|
||||
@@ -389,7 +378,7 @@ namespace Barotrauma.Items.Components
|
||||
character.CheckTalents(AbilityEffectType.OnAllyItemFabricatedAmount, fabricationitemAmount);
|
||||
}
|
||||
user.CheckTalents(AbilityEffectType.OnItemFabricatedAmount, fabricationitemAmount);
|
||||
|
||||
|
||||
quality = GetFabricatedItemQuality(fabricatedItem, user);
|
||||
}
|
||||
|
||||
@@ -397,10 +386,10 @@ namespace Barotrauma.Items.Components
|
||||
for (int i = 0; i < (int)fabricationitemAmount.Value; i++)
|
||||
{
|
||||
float outCondition = fabricatedItem.OutCondition;
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none") + ":" + fabricatedItem.TargetItem.Identifier);
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier.Value ?? "none") + ":" + fabricatedItem.TargetItem.Identifier);
|
||||
if (i < amountFittingContainer)
|
||||
{
|
||||
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, outputContainer.Inventory, fabricatedItem.TargetItem.Health * outCondition, quality,
|
||||
Entity.Spawner.AddItemToSpawnQueue(fabricatedItem.TargetItem, outputContainer.Inventory, fabricatedItem.TargetItem.Health * outCondition, quality,
|
||||
onSpawned: (Item spawnedItem) =>
|
||||
{
|
||||
onItemSpawned(spawnedItem, tempUser);
|
||||
@@ -413,7 +402,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
Entity.Spawner.AddToSpawnQueue(fabricatedItem.TargetItem, item.Position, item.Submarine, fabricatedItem.TargetItem.Health * outCondition, quality,
|
||||
Entity.Spawner.AddItemToSpawnQueue(fabricatedItem.TargetItem, item.Position, item.Submarine, fabricatedItem.TargetItem.Health * outCondition, quality,
|
||||
onSpawned: (Item spawnedItem) =>
|
||||
{
|
||||
onItemSpawned(spawnedItem, tempUser);
|
||||
@@ -469,13 +458,30 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Power consumption of the fabricator. Only consume power when active and adjust consumption based on condition.
|
||||
/// </summary>
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
//No consumption if not powerin or is off
|
||||
if (connection != this.powerIn || !IsActive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
currPowerConsumption = PowerConsumption;
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref currPowerConsumption);
|
||||
|
||||
return currPowerConsumption;
|
||||
}
|
||||
|
||||
private int GetFabricatedItemQuality(FabricationRecipe fabricatedItem, Character user)
|
||||
{
|
||||
if (user == null) { return 0; }
|
||||
if (fabricatedItem.TargetItem.ConfigElement.GetChildElement("Quality") == null) { return 0; }
|
||||
int quality = 0;
|
||||
float floatQuality = 0.0f;
|
||||
foreach (string tag in fabricatedItem.TargetItem.Tags)
|
||||
foreach (var tag in fabricatedItem.TargetItem.Tags)
|
||||
{
|
||||
floatQuality += user.Info.GetSavedStatValue(StatTypes.IncreaseFabricationQuality, tag);
|
||||
}
|
||||
@@ -489,8 +495,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
partial void UpdateRequiredTimeProjSpecific();
|
||||
|
||||
private bool CanBeFabricated(FabricationRecipe fabricableItem, Dictionary<string, List<Item>> availableIngredients, Character character)
|
||||
|
||||
private bool CanBeFabricated(FabricationRecipe fabricableItem, IReadOnlyDictionary<Identifier, List<Item>> availableIngredients, Character character)
|
||||
{
|
||||
if (fabricableItem == null) { return false; }
|
||||
if (fabricableItem.RequiresRecipe && (character == null || !character.HasRecipeForItem(fabricableItem.TargetItem.Identifier))) { return false; }
|
||||
@@ -533,13 +539,13 @@ namespace Barotrauma.Items.Components
|
||||
return fabricableItem.RequiredTime / FabricationSpeed / MathHelper.Clamp(t, 0.01f, 2.0f);
|
||||
}
|
||||
|
||||
public float FabricationDegreeOfSuccess(Character character, List<Skill> skills)
|
||||
public float FabricationDegreeOfSuccess(Character character, ImmutableArray<Skill> skills)
|
||||
{
|
||||
if (skills.Count == 0) { return 1.0f; }
|
||||
if (skills.Length == 0) { return 1.0f; }
|
||||
if (character == null) { return 0.0f; }
|
||||
|
||||
float skillSum = (from t in skills let characterLevel = character.GetSkillLevel(t.Identifier) select (characterLevel - (t.Level * SkillRequirementMultiplier))).Sum();
|
||||
float average = skillSum / skills.Count;
|
||||
float average = skillSum / skills.Length;
|
||||
|
||||
return (average + 100.0f) / 2.0f / 100.0f;
|
||||
}
|
||||
@@ -593,7 +599,7 @@ namespace Barotrauma.Items.Components
|
||||
availableIngredients.Clear();
|
||||
foreach (Item item in itemList)
|
||||
{
|
||||
var itemIdentifier = item.prefab.Identifier;
|
||||
var itemIdentifier = item.Prefab.Identifier;
|
||||
if (!availableIngredients.ContainsKey(itemIdentifier))
|
||||
{
|
||||
availableIngredients[itemIdentifier] = new List<Item>(itemList.Count);
|
||||
@@ -663,7 +669,7 @@ namespace Barotrauma.Items.Components
|
||||
return componentElement;
|
||||
}
|
||||
|
||||
public override void Load(XElement componentElement, bool usePrefabValues, IdRemap idRemap)
|
||||
public override void Load(ContentXElement componentElement, bool usePrefabValues, IdRemap idRemap)
|
||||
{
|
||||
base.Load(componentElement, usePrefabValues, idRemap);
|
||||
savedFabricatedItem = componentElement.GetAttributeString("fabricateditemidentifier", "");
|
||||
@@ -678,7 +684,7 @@ namespace Barotrauma.Items.Components
|
||||
inputContainer?.OnMapLoaded();
|
||||
outputContainer?.OnMapLoaded();
|
||||
|
||||
var recipe = fabricationRecipes.Find(r => r.TargetItem.Identifier == savedFabricatedItem);
|
||||
var recipe = fabricationRecipes.Values.FirstOrDefault(r => r.TargetItem.Identifier == savedFabricatedItem);
|
||||
if (recipe == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while loading a fabricator. Can't continue fabricating \"" + savedFabricatedItem + "\" (matching recipe not found).");
|
||||
@@ -696,13 +702,13 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
class AbilityFabricatorSkillGain : AbilityObject, IAbilityValue, IAbilitySkillIdentifier
|
||||
{
|
||||
public AbilityFabricatorSkillGain(string skillIdentifier, float skillAmount)
|
||||
public AbilityFabricatorSkillGain(Identifier skillIdentifier, float skillAmount)
|
||||
{
|
||||
SkillIdentifier = skillIdentifier;
|
||||
Value = skillAmount;
|
||||
}
|
||||
public float Value { get; set; }
|
||||
public string SkillIdentifier { get; set; }
|
||||
public Identifier SkillIdentifier { get; set; }
|
||||
}
|
||||
|
||||
class AbilityFabricationItemAmount : AbilityObject, IAbilityValue, IAbilityItemPrefab
|
||||
|
||||
@@ -29,49 +29,49 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private readonly Dictionary<Hull, HullData> hullDatas;
|
||||
|
||||
[Editable, Serialize(false, true, description: "Does the machine require inputs from water detectors in order to show the water levels inside rooms.")]
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes, description: "Does the machine require inputs from water detectors in order to show the water levels inside rooms.")]
|
||||
public bool RequireWaterDetectors
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(true, true, description: "Does the machine require inputs from oxygen detectors in order to show the oxygen levels inside rooms.")]
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Does the machine require inputs from oxygen detectors in order to show the oxygen levels inside rooms.")]
|
||||
public bool RequireOxygenDetectors
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(true, true, description: "Should damaged walls be displayed by the machine.")]
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Should damaged walls be displayed by the machine.")]
|
||||
public bool ShowHullIntegrity
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(true, true, description: "Enable hull status mode.")]
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Enable hull status mode.")]
|
||||
public bool EnableHullStatus
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(true, true, description: "Enable electrical view mode.")]
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Enable electrical view mode.")]
|
||||
public bool EnableElectricalView
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(true, true, description: "Enable item finder mode.")]
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Enable item finder mode.")]
|
||||
public bool EnableItemFinder
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public MiniMap(Item item, XElement element)
|
||||
public MiniMap(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
@@ -114,9 +114,6 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
#endif
|
||||
|
||||
currPowerConsumption = powerConsumption;
|
||||
currPowerConsumption *= MathHelper.Lerp(1.5f, 1.0f, item.Condition / item.MaxCondition);
|
||||
|
||||
hasPower = Voltage > MinVoltage;
|
||||
if (hasPower)
|
||||
{
|
||||
@@ -124,6 +121,19 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Power consumption of the MiniMap. Only consume power when active and adjust consumption based on condition.
|
||||
/// </summary>
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
if (connection != powerIn || !IsActive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PowerConsumption * MathHelper.Lerp(1.5f, 1.0f, item.Condition / item.MaxCondition);
|
||||
}
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
return picker != null;
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class OutpostTerminal : ItemComponent
|
||||
{
|
||||
public OutpostTerminal(Item item, XElement element) : base(item, element)
|
||||
public OutpostTerminal(Item item, ContentXElement element) : base(item, element)
|
||||
{
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
+22
-15
@@ -24,14 +24,14 @@ namespace Barotrauma.Items.Components
|
||||
private set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(400.0f, true, description: "How much oxygen the machine generates when operating at full power.", alwaysUseInstanceValues: true)]
|
||||
[Editable, Serialize(400.0f, IsPropertySaveable.Yes, description: "How much oxygen the machine generates when operating at full power.", alwaysUseInstanceValues: true)]
|
||||
public float GeneratedAmount
|
||||
{
|
||||
get { return generatedAmount; }
|
||||
set { generatedAmount = MathHelper.Clamp(value, -10000.0f, 10000.0f); }
|
||||
}
|
||||
|
||||
public OxygenGenerator(Item item, XElement element)
|
||||
public OxygenGenerator(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
//randomize update timer so all oxygen generators don't update at the same time
|
||||
@@ -44,25 +44,15 @@ namespace Barotrauma.Items.Components
|
||||
UpdateOnActiveEffects(deltaTime);
|
||||
|
||||
CurrFlow = 0.0f;
|
||||
currPowerConsumption = powerConsumption;
|
||||
//consume more power when in a bad condition
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref currPowerConsumption);
|
||||
|
||||
if (powerConsumption <= 0.0f)
|
||||
{
|
||||
Voltage = 1.0f;
|
||||
}
|
||||
|
||||
if (item.CurrentHull == null) { return; }
|
||||
|
||||
if (Voltage < MinVoltage)
|
||||
|
||||
if (Voltage < MinVoltage && PowerConsumption > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrFlow = Math.Min(Voltage, 1.0f) * generatedAmount * 100.0f;
|
||||
|
||||
//less effective when in bad condition
|
||||
CurrFlow = Math.Min(PowerConsumption > 0 ? Voltage : 1.0f, 1.0f) * generatedAmount * 100.0f;
|
||||
float conditionMult = item.Condition / item.MaxCondition;
|
||||
//100% condition = 100% oxygen
|
||||
//50% condition = 25% oxygen
|
||||
@@ -72,6 +62,23 @@ namespace Barotrauma.Items.Components
|
||||
UpdateVents(CurrFlow, deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Power consumption of the Oxygen Generator. Only consume power when active and adjust consumption based on condition.
|
||||
/// </summary>
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
if (connection != this.powerIn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float consumption = powerConsumption;
|
||||
|
||||
//consume more power when in a bad condition
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref consumption);
|
||||
return consumption;
|
||||
}
|
||||
|
||||
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||
{
|
||||
base.UpdateBroken(deltaTime, cam);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float pumpSpeedLockTimer, isActiveLockTimer;
|
||||
|
||||
[Serialize(0.0f, true, description: "How fast the item is currently pumping water (-100 = full speed out, 100 = full speed in). Intended to be used by StatusEffect conditionals (setting this value in XML has no effect).")]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "How fast the item is currently pumping water (-100 = full speed out, 100 = full speed in). Intended to be used by StatusEffect conditionals (setting this value in XML has no effect).")]
|
||||
public float FlowPercentage
|
||||
{
|
||||
get { return flowPercentage; }
|
||||
@@ -48,18 +48,18 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (!MathUtils.IsValid(flowPercentage)) { return; }
|
||||
flowPercentage = MathHelper.Clamp(value, -100.0f, 100.0f);
|
||||
flowPercentage = MathUtils.Round(flowPercentage, 1.0f);
|
||||
flowPercentage = MathF.Round(flowPercentage);
|
||||
}
|
||||
}
|
||||
|
||||
[Editable, Serialize(80.0f, false, description: "How fast the item pumps water in/out when operating at 100%.", alwaysUseInstanceValues: true)]
|
||||
[Editable, Serialize(80.0f, IsPropertySaveable.No, description: "How fast the item pumps water in/out when operating at 100%.", alwaysUseInstanceValues: true)]
|
||||
public float MaxFlow
|
||||
{
|
||||
get { return maxFlow; }
|
||||
set { maxFlow = value; }
|
||||
}
|
||||
|
||||
[Editable, Serialize(true, true, alwaysUseInstanceValues: true)]
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes, alwaysUseInstanceValues: true)]
|
||||
public bool IsOn
|
||||
{
|
||||
get { return IsActive; }
|
||||
@@ -83,13 +83,13 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool UpdateWhenInactive => true;
|
||||
|
||||
public Pump(Item item, XElement element)
|
||||
public Pump(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
partial void InitProjSpecific(ContentXElement element);
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
@@ -120,10 +120,6 @@ namespace Barotrauma.Items.Components
|
||||
FlowPercentage = ((float)TargetLevel - hullPercentage) * 10.0f;
|
||||
}
|
||||
|
||||
currPowerConsumption = powerConsumption * Math.Abs(flowPercentage / 100.0f);
|
||||
//pumps consume more power when in a bad condition
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref currPowerConsumption);
|
||||
|
||||
if (!HasPower) { return; }
|
||||
|
||||
UpdateProjSpecific(deltaTime);
|
||||
@@ -147,10 +143,9 @@ namespace Barotrauma.Items.Components
|
||||
item.CurrentHull.WaterVolume += currFlow * deltaTime * Timing.FixedUpdateRate;
|
||||
if (item.CurrentHull.WaterVolume > item.CurrentHull.Volume) { item.CurrentHull.Pressure += 30.0f * deltaTime; }
|
||||
|
||||
Voltage -= deltaTime;
|
||||
}
|
||||
|
||||
public void InfectBallast(string identifier, bool allowMultiplePerShip = false)
|
||||
public void InfectBallast(Identifier identifier, bool allowMultiplePerShip = false)
|
||||
{
|
||||
Hull hull = item.CurrentHull;
|
||||
if (hull == null) { return; }
|
||||
@@ -158,7 +153,7 @@ namespace Barotrauma.Items.Components
|
||||
if (!allowMultiplePerShip)
|
||||
{
|
||||
// if the ship is already infected then do nothing
|
||||
if (Hull.hullList.Where(h => h.Submarine == hull.Submarine).Any(h => h.BallastFlora != null)) { return; }
|
||||
if (Hull.HullList.Where(h => h.Submarine == hull.Submarine).Any(h => h.BallastFlora != null)) { return; }
|
||||
}
|
||||
|
||||
if (hull.BallastFlora != null) { return; }
|
||||
@@ -178,6 +173,24 @@ namespace Barotrauma.Items.Components
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Power consumption of the Pump. Only consume power when active and adjust consumption based on condition.
|
||||
/// </summary>
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
//There shouldn't be other power connections to this
|
||||
if (connection != this.powerIn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
currPowerConsumption = powerConsumption * Math.Abs(flowPercentage / 100.0f);
|
||||
//pumps consume more power when in a bad condition
|
||||
item.GetComponent<Repairable>()?.AdjustPowerConsumption(ref currPowerConsumption);
|
||||
|
||||
return currPowerConsumption;
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime);
|
||||
|
||||
public override void ReceiveSignal(Signal signal, Connection connection)
|
||||
@@ -218,7 +231,8 @@ namespace Barotrauma.Items.Components
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) { return false; }
|
||||
#endif
|
||||
switch (objective.Option.ToLowerInvariant())
|
||||
|
||||
switch (objective.Option.Value.ToLowerInvariant())
|
||||
{
|
||||
case "pumpout":
|
||||
#if SERVER
|
||||
|
||||
@@ -36,8 +36,8 @@ namespace Barotrauma.Items.Components
|
||||
private float fireTimer, fireDelay;
|
||||
|
||||
private float maxPowerOutput;
|
||||
|
||||
private readonly Queue<float> loadQueue = new Queue<float>();
|
||||
private float minUpdatePowerOut;
|
||||
private float maxUpdatePowerOut;
|
||||
|
||||
private bool unsentChanges;
|
||||
private float sendUpdateTimer;
|
||||
@@ -50,7 +50,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool _powerOn;
|
||||
|
||||
[Serialize(defaultValue: false, isSaveable: true)]
|
||||
[Serialize(defaultValue: false, isSaveable: IsPropertySaveable.Yes)]
|
||||
public bool PowerOn
|
||||
{
|
||||
get { return _powerOn; }
|
||||
@@ -63,9 +63,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
protected override PowerPriority Priority { get { return PowerPriority.Reactor; } }
|
||||
|
||||
public Character LastAIUser { get; private set; }
|
||||
|
||||
[Serialize(defaultValue: false, isSaveable: true)]
|
||||
[Serialize(defaultValue: false, isSaveable: IsPropertySaveable.Yes)]
|
||||
public bool LastUserWasPlayer { get; private set; }
|
||||
|
||||
private Character lastUser;
|
||||
@@ -81,7 +83,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(0.0f, float.MaxValue), Serialize(10000.0f, true, description: "How much power (kW) the reactor generates when operating at full capacity.", alwaysUseInstanceValues: true)]
|
||||
[Editable(0.0f, float.MaxValue), Serialize(10000.0f, IsPropertySaveable.Yes, description: "How much power (kW) the reactor generates when operating at full capacity.", alwaysUseInstanceValues: true)]
|
||||
public float MaxPowerOutput
|
||||
{
|
||||
get { return maxPowerOutput; }
|
||||
@@ -91,21 +93,21 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Editable(0.0f, float.MaxValue), Serialize(120.0f, true, description: "How long the temperature has to stay critical until a meltdown occurs.")]
|
||||
[Editable(0.0f, float.MaxValue), Serialize(120.0f, IsPropertySaveable.Yes, description: "How long the temperature has to stay critical until a meltdown occurs.")]
|
||||
public float MeltdownDelay
|
||||
{
|
||||
get { return meltDownDelay; }
|
||||
set { meltDownDelay = Math.Max(value, 0.0f); }
|
||||
}
|
||||
|
||||
[Editable(0.0f, float.MaxValue), Serialize(30.0f, true, description: "How long the temperature has to stay critical until the reactor catches fire.")]
|
||||
[Editable(0.0f, float.MaxValue), Serialize(30.0f, IsPropertySaveable.Yes, description: "How long the temperature has to stay critical until the reactor catches fire.")]
|
||||
public float FireDelay
|
||||
{
|
||||
get { return fireDelay; }
|
||||
set { fireDelay = Math.Max(value, 0.0f); }
|
||||
}
|
||||
|
||||
[Serialize(0.0f, true, description: "Current temperature of the reactor (0% - 100%). Indended to be used by StatusEffect conditionals.")]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "Current temperature of the reactor (0% - 100%). Indended to be used by StatusEffect conditionals.")]
|
||||
public float Temperature
|
||||
{
|
||||
get { return temperature; }
|
||||
@@ -116,7 +118,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(0.0f, true, description: "Current fission rate of the reactor (0% - 100%). Intended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "Current fission rate of the reactor (0% - 100%). Intended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
|
||||
public float FissionRate
|
||||
{
|
||||
get { return fissionRate; }
|
||||
@@ -127,7 +129,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(0.0f, true, description: "Current turbine output of the reactor (0% - 100%). Intended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes, description: "Current turbine output of the reactor (0% - 100%). Intended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
|
||||
public float TurbineOutput
|
||||
{
|
||||
get { return turbineOutput; }
|
||||
@@ -138,7 +140,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(0.2f, true, description: "How fast the condition of the contained fuel rods deteriorates per second."), Editable(0.0f, 1000.0f, decimals: 3)]
|
||||
[Serialize(0.2f, IsPropertySaveable.Yes, description: "How fast the condition of the contained fuel rods deteriorates per second."), Editable(0.0f, 1000.0f, decimals: 3)]
|
||||
public float FuelConsumptionRate
|
||||
{
|
||||
get { return fuelConsumptionRate; }
|
||||
@@ -149,14 +151,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(false, true, description: "Is the temperature currently critical. Intended to be used by StatusEffect conditionals (setting the value from XML has no effect).")]
|
||||
[Serialize(false, IsPropertySaveable.Yes, description: "Is the temperature currently critical. Intended to be used by StatusEffect conditionals (setting the value from XML has no effect).")]
|
||||
public bool TemperatureCritical
|
||||
{
|
||||
get { return temperature > allowedTemperature.Y; }
|
||||
set { /*do nothing*/ }
|
||||
}
|
||||
|
||||
[Serialize(false, true, description: "Is the automatic temperature control currently on. Indended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
|
||||
[Serialize(false, IsPropertySaveable.Yes, description: "Is the automatic temperature control currently on. Indended to be used by StatusEffect conditionals (setting the value from XML is not recommended).")]
|
||||
public bool AutoTemp
|
||||
{
|
||||
get { return autoTemp; }
|
||||
@@ -171,36 +173,36 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float prevAvailableFuel;
|
||||
|
||||
[Serialize(0.0f, true)]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes)]
|
||||
public float AvailableFuel { get; set; }
|
||||
|
||||
[Serialize(0.0f, true)]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes)]
|
||||
public new float Load { get; private set; }
|
||||
|
||||
[Serialize(0.0f, true)]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes)]
|
||||
public float TargetFissionRate { get; set; }
|
||||
|
||||
[Serialize(0.0f, true)]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes)]
|
||||
public float TargetTurbineOutput { get; set; }
|
||||
|
||||
[Serialize(0.0f, true)]
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes)]
|
||||
public float CorrectTurbineOutput { get; set; }
|
||||
|
||||
[Editable, Serialize(true, true)]
|
||||
[Editable, Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool ExplosionDamagesOtherSubs
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Reactor(Item item, XElement element)
|
||||
public Reactor(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
partial void InitProjSpecific(ContentXElement element);
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
@@ -248,7 +250,7 @@ namespace Barotrauma.Items.Components
|
||||
//so the player doesn't have to keep adjusting the rate impossibly fast when the load fluctuates heavily
|
||||
if (!MathUtils.NearlyEqual(MaxPowerOutput, 0.0f))
|
||||
{
|
||||
CorrectTurbineOutput += MathHelper.Clamp((Load / MaxPowerOutput * 100.0f) - CorrectTurbineOutput, -10.0f, 10.0f) * deltaTime;
|
||||
CorrectTurbineOutput += MathHelper.Clamp((Load / MaxPowerOutput * 100.0f) - CorrectTurbineOutput, -20.0f, 20.0f) * deltaTime;
|
||||
}
|
||||
|
||||
//calculate tolerances of the meters based on the skills of the user
|
||||
@@ -277,25 +279,6 @@ namespace Barotrauma.Items.Components
|
||||
TurbineOutput = MathHelper.Lerp(turbineOutput, TargetTurbineOutput, deltaTime);
|
||||
|
||||
float temperatureFactor = Math.Min(temperature / 50.0f, 1.0f);
|
||||
currPowerConsumption = -MaxPowerOutput * Math.Min(turbineOutput / 100.0f, temperatureFactor);
|
||||
|
||||
//if the turbine output and coolant flow are the optimal range,
|
||||
//make the generated power slightly adjust according to the load
|
||||
// (-> the reactor can automatically handle small changes in load as long as the values are roughly correct)
|
||||
if (turbineOutput > optimalTurbineOutput.X && turbineOutput < optimalTurbineOutput.Y &&
|
||||
temperature > optimalTemperature.X && temperature < optimalTemperature.Y)
|
||||
{
|
||||
float maxAutoAdjust = maxPowerOutput * 0.1f;
|
||||
autoAdjustAmount = MathHelper.Lerp(
|
||||
autoAdjustAmount,
|
||||
MathHelper.Clamp(-Load - currPowerConsumption, -maxAutoAdjust, maxAutoAdjust),
|
||||
deltaTime * 10.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
autoAdjustAmount = MathHelper.Lerp(autoAdjustAmount, 0.0f, deltaTime * 10.0f);
|
||||
}
|
||||
currPowerConsumption += autoAdjustAmount;
|
||||
|
||||
if (!PowerOn)
|
||||
{
|
||||
@@ -304,37 +287,9 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (autoTemp)
|
||||
{
|
||||
UpdateAutoTemp(2.0f, deltaTime);
|
||||
}
|
||||
float currentLoad = 0.0f;
|
||||
List<Connection> connections = item.Connections;
|
||||
if (connections != null && connections.Count > 0)
|
||||
{
|
||||
foreach (Connection connection in connections)
|
||||
{
|
||||
if (!connection.IsPower) { continue; }
|
||||
foreach (Connection recipient in connection.Recipients)
|
||||
{
|
||||
if (!(recipient.Item is Item it)) { continue; }
|
||||
|
||||
PowerTransfer pt = it.GetComponent<PowerTransfer>();
|
||||
if (pt == null) { continue; }
|
||||
|
||||
//calculate how much external power there is in the grid
|
||||
//(power coming from somewhere else than this reactor, e.g. batteries)
|
||||
float externalPower = Math.Max(CurrPowerConsumption - pt.CurrPowerConsumption, 0) * 0.95f;
|
||||
//reduce the external power from the load to prevent overloading the grid
|
||||
currentLoad = Math.Max(currentLoad, pt.PowerLoad - externalPower);
|
||||
}
|
||||
}
|
||||
UpdateAutoTemp(10.0f, deltaTime * 2f);
|
||||
}
|
||||
|
||||
loadQueue.Enqueue(currentLoad);
|
||||
while (loadQueue.Count() > 60.0f)
|
||||
{
|
||||
Load = loadQueue.Average();
|
||||
loadQueue.Dequeue();
|
||||
}
|
||||
|
||||
float fuelLeft = 0.0f;
|
||||
var containedItems = item.OwnInventory?.AllItems;
|
||||
@@ -405,6 +360,77 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a negative value (indicating the reactor generates power) when querying the power output connection.
|
||||
/// </summary>
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
return connection != null && connection.IsPower && connection.IsOutput ? -1 : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Min and Max power output of the reactor based on tolerance
|
||||
/// </summary>
|
||||
public override PowerRange MinMaxPowerOut(Connection conn, float load)
|
||||
{
|
||||
float tolerance = 1f;
|
||||
|
||||
//If within the optimal output allow for slight output adjustments
|
||||
if (turbineOutput > optimalTurbineOutput.X && turbineOutput < optimalTurbineOutput.Y &&
|
||||
temperature > optimalTemperature.X && temperature < optimalTemperature.Y)
|
||||
{
|
||||
tolerance = 3f;
|
||||
}
|
||||
|
||||
float temperatureFactor = Math.Min(temperature / 50.0f, 1.0f);
|
||||
float minOutput = MaxPowerOutput * Math.Clamp(Math.Min((turbineOutput - tolerance) / 100.0f, temperatureFactor), 0, 1);
|
||||
float maxOutput = MaxPowerOutput * Math.Min((turbineOutput + tolerance) / 100.0f, temperatureFactor);
|
||||
|
||||
minUpdatePowerOut = minOutput;
|
||||
maxUpdatePowerOut = maxOutput;
|
||||
|
||||
float reactorMax = PowerOn ? MaxPowerOutput : maxUpdatePowerOut;
|
||||
|
||||
return new PowerRange(minOutput, maxOutput, reactorMax);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine how much power to output based on the load. The load is divided between reactors according to their maximum output in multi-reactor setups.
|
||||
/// </summary>
|
||||
public override float GetConnectionPowerOut(Connection conn, float power, PowerRange minMaxPower, float load)
|
||||
{
|
||||
//Load must be calculated at this stage instead of at gridResolved to remove influence of lower priority devices
|
||||
float loadLeft = MathHelper.Max(load - power,0);
|
||||
float expectedPower = MathHelper.Clamp(loadLeft, minMaxPower.Min, minMaxPower.Max);
|
||||
|
||||
//Delta ratio of Min and Max power output capability of the grid
|
||||
float ratio = MathHelper.Max((loadLeft - minMaxPower.Min) / (minMaxPower.Max - minMaxPower.Min), 0);
|
||||
if (float.IsInfinity(ratio))
|
||||
{
|
||||
ratio = 0;
|
||||
}
|
||||
|
||||
float output = MathHelper.Clamp(ratio * (maxUpdatePowerOut - minUpdatePowerOut) + minUpdatePowerOut, minUpdatePowerOut, maxUpdatePowerOut);
|
||||
float newLoad = loadLeft;
|
||||
|
||||
//Adjust behaviour for multi reactor setup
|
||||
if (MaxPowerOutput != minMaxPower.ReactorMaxOutput)
|
||||
{
|
||||
float idealLoad = MaxPowerOutput / minMaxPower.ReactorMaxOutput * loadLeft;
|
||||
float loadAdjust = MathHelper.Clamp((ratio - 0.5f) * 25 + idealLoad - (turbineOutput / 100 * MaxPowerOutput), -MaxPowerOutput / 100, MaxPowerOutput / 100);
|
||||
newLoad = MathHelper.Clamp(loadLeft - (expectedPower + output) + loadAdjust, 0, loadLeft);
|
||||
}
|
||||
|
||||
if (float.IsNegative(newLoad))
|
||||
{
|
||||
newLoad = 0.0f;
|
||||
}
|
||||
|
||||
Load = newLoad;
|
||||
currPowerConsumption = -output;
|
||||
return output;
|
||||
}
|
||||
|
||||
private float GetGeneratedHeat(float fissionRate)
|
||||
{
|
||||
return fissionRate * (prevAvailableFuel / 100.0f) * 2.0f;
|
||||
@@ -595,7 +621,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; }
|
||||
character.AIController.SteeringManager.Reset();
|
||||
bool shutDown = objective.Option.Equals("shutdown", StringComparison.OrdinalIgnoreCase);
|
||||
bool shutDown = objective.Option == "shutdown";
|
||||
|
||||
IsActive = true;
|
||||
|
||||
@@ -624,7 +650,7 @@ namespace Barotrauma.Items.Components
|
||||
var containObjective = AIContainItems<Reactor>(container, character, objective, itemCount: 1, equip: true, removeEmpty: true, spawnItemIfNotFound: !character.IsOnPlayerTeam, dropItemOnDeselected: true);
|
||||
containObjective.Completed += ReportFuelRodCount;
|
||||
containObjective.Abandoned += ReportFuelRodCount;
|
||||
character.Speak(TextManager.Get("DialogReactorFuel"), null, 0.0f, "reactorfuel", 30.0f);
|
||||
character.Speak(TextManager.Get("DialogReactorFuel").Value, null, 0.0f, "reactorfuel".ToIdentifier(), 30.0f);
|
||||
|
||||
void ReportFuelRodCount()
|
||||
{
|
||||
@@ -633,12 +659,12 @@ namespace Barotrauma.Items.Components
|
||||
int remainingFuelRods = Submarine.MainSub.GetItems(false).Count(i => i.HasTag("reactorfuel") && i.Condition > 1);
|
||||
if (remainingFuelRods == 0)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogOutOfFuelRods"), null, 0.0f, "outoffuelrods", 30.0f);
|
||||
character.Speak(TextManager.Get("DialogOutOfFuelRods").Value, null, 0.0f, "outoffuelrods".ToIdentifier(), 30.0f);
|
||||
outOfFuel = true;
|
||||
}
|
||||
else if (remainingFuelRods < 3)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogLowOnFuelRods"), null, 0.0f, "lowonfuelrods", 30.0f);
|
||||
character.Speak(TextManager.Get("DialogLowOnFuelRods").Value, null, 0.0f, "lowonfuelrods".ToIdentifier(), 30.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -655,7 +681,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogReactorIsBroken"), identifier: "reactorisbroken", minDurationBetweenSimilar: 30.0f);
|
||||
character.Speak(TextManager.Get("DialogReactorIsBroken").Value, identifier: "reactorisbroken".ToIdentifier(), minDurationBetweenSimilar: 30.0f);
|
||||
}
|
||||
}
|
||||
if (TooMuchFuel())
|
||||
@@ -676,7 +702,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (lastUser.SelectedConstruction == item && character.IsOnPlayerTeam)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogReactorTaken"), null, 0.0f, "reactortaken", 10.0f);
|
||||
character.Speak(TextManager.Get("DialogReactorTaken").Value, null, 0.0f, "reactortaken".ToIdentifier(), 10.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Barotrauma.Items.Components
|
||||
get { return connectedTransducers.Select(t => t.Transducer); }
|
||||
}
|
||||
|
||||
[Serialize(DefaultSonarRange, false, description: "The maximum range of the sonar.")]
|
||||
[Serialize(DefaultSonarRange, IsPropertySaveable.No, description: "The maximum range of the sonar.")]
|
||||
public float Range
|
||||
{
|
||||
get { return range; }
|
||||
@@ -92,29 +92,29 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(false, false, description: "Should the sonar display the walls of the submarine it is inside.")]
|
||||
[Serialize(false, IsPropertySaveable.No, description: "Should the sonar display the walls of the submarine it is inside.")]
|
||||
public bool DetectSubmarineWalls
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, false, description: "Does the sonar have to be connected to external transducers to work.")]
|
||||
[Editable, Serialize(false, IsPropertySaveable.No, description: "Does the sonar have to be connected to external transducers to work.")]
|
||||
public bool UseTransducers
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, false, description: "Should the sonar view be centered on the transducers or the submarine's center of mass. Only has an effect if UseTransducers is enabled.")]
|
||||
[Editable, Serialize(false, IsPropertySaveable.No, description: "Should the sonar view be centered on the transducers or the submarine's center of mass. Only has an effect if UseTransducers is enabled.")]
|
||||
public bool CenterOnTransducers
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Editable, Serialize(false, false, description: "Does the sonar have mineral scanning mode. " +
|
||||
"Only available in-game when the Item has no Steering component.")]
|
||||
[Editable, Serialize(false, IsPropertySaveable.No, description: "Does the sonar have mineral scanning mode. " +
|
||||
"Only available in-game when the Item has no Steering component.")]
|
||||
public bool HasMineralScanner { get; set; }
|
||||
|
||||
public float Zoom
|
||||
@@ -146,7 +146,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override bool RecreateGUIOnResolutionChange => true;
|
||||
|
||||
public Sonar(Item item, XElement element)
|
||||
public Sonar(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
connectedTransducers = new List<ConnectedTransducer>();
|
||||
@@ -155,12 +155,10 @@ namespace Barotrauma.Items.Components
|
||||
CurrentMode = Mode.Passive;
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
partial void InitProjSpecific(ContentXElement element);
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
currPowerConsumption = (currentMode == Mode.Active) ? powerConsumption : powerConsumption * PassivePowerConsumption;
|
||||
|
||||
UpdateOnActiveEffects(deltaTime);
|
||||
|
||||
if (UseTransducers)
|
||||
@@ -240,8 +238,19 @@ namespace Barotrauma.Items.Components
|
||||
++pingIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Voltage -= deltaTime;
|
||||
/// <summary>
|
||||
/// Power consumption of the sonar. Only consume power when active and adjust the consumption based on the sonar mode.
|
||||
/// </summary>
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
if (connection != powerIn || !IsActive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (currentMode == Mode.Active) ? powerConsumption : powerConsumption * PassivePowerConsumption;
|
||||
}
|
||||
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
@@ -266,7 +275,8 @@ namespace Barotrauma.Items.Components
|
||||
if (DetectSubmarineWalls && c.AnimController.CurrentHull == null && item.CurrentHull != null) { continue; }
|
||||
if (Vector2.DistanceSquared(c.WorldPosition, item.WorldPosition) > range * range) { continue; }
|
||||
|
||||
string directionName = GetDirectionName(c.WorldPosition - item.WorldPosition);
|
||||
#warning This is not the best key for a dictionary.
|
||||
string directionName = GetDirectionName(c.WorldPosition - item.WorldPosition).Value;
|
||||
if (!targetGroups.ContainsKey(directionName))
|
||||
{
|
||||
targetGroups.Add(directionName, new List<Character>());
|
||||
@@ -289,9 +299,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (character.IsOnPlayerTeam)
|
||||
{
|
||||
character.Speak(TextManager.GetWithVariables(dialogTag, new string[2] { "[direction]", "[count]" },
|
||||
new string[2] { targetGroup.Key.ToString(), targetGroup.Value.Count.ToString() },
|
||||
new bool[2] { true, false }), null, 0, "sonartarget" + targetGroup.Value[0].ID, 60);
|
||||
character.Speak(TextManager.GetWithVariables(dialogTag,
|
||||
("[direction]", targetGroup.Key.ToString(), FormatCapitals.Yes),
|
||||
("[count]", targetGroup.Value.Count.ToString(), FormatCapitals.No)).Value,
|
||||
null, 0, $"sonartarget{targetGroup.Value[0].ID}".ToIdentifier(), 60);
|
||||
}
|
||||
|
||||
//prevent the character from reporting other targets in the group
|
||||
@@ -304,7 +315,7 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
private string GetDirectionName(Vector2 dir)
|
||||
private LocalizedString GetDirectionName(Vector2 dir)
|
||||
{
|
||||
float angle = MathUtils.WrapAngleTwoPi((float)-Math.Atan2(dir.Y, dir.X) + MathHelper.PiOver2);
|
||||
|
||||
|
||||
+11
-3
@@ -10,7 +10,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public Sonar ConnectedSonar;
|
||||
|
||||
public SonarTransducer(Item item, XElement element) : base(item, element)
|
||||
public SonarTransducer(Item item, ContentXElement element) : base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
@@ -19,8 +19,6 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
UpdateOnActiveEffects(deltaTime);
|
||||
|
||||
CurrPowerConsumption = powerConsumption * (ConnectedSonar?.CurrentMode == Sonar.Mode.Active ? 1.0f : Sonar.PassivePowerConsumption);
|
||||
|
||||
if (Voltage >= MinVoltage)
|
||||
{
|
||||
sendSignalTimer += deltaTime;
|
||||
@@ -31,5 +29,15 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetCurrentPowerConsumption(Connection connection = null)
|
||||
{
|
||||
if (connection != powerIn || !IsActive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PowerConsumption * (ConnectedSonar?.CurrentMode == Sonar.Mode.Active ? 1.0f : Sonar.PassivePowerConsumption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
@@ -106,7 +106,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
[Editable(0.0f, 1.0f, decimals: 4),
|
||||
Serialize(0.5f, true, description: "How full the ballast tanks should be when the submarine is not being steered upwards/downwards."
|
||||
Serialize(0.5f, IsPropertySaveable.Yes, description: "How full the ballast tanks should be when the submarine is not being steered upwards/downwards."
|
||||
+ " Can be used to compensate if the ballast tanks are too large/small relative to the size of the submarine.")]
|
||||
public float NeutralBallastLevel
|
||||
{
|
||||
@@ -117,7 +117,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(1000.0f, true, description: "How close the docking port has to be to another docking port for the docking mode to become active.")]
|
||||
[Serialize(1000.0f, IsPropertySaveable.Yes, description: "How close the docking port has to be to another docking port for the docking mode to become active.")]
|
||||
public float DockingAssistThreshold
|
||||
{
|
||||
get;
|
||||
@@ -231,14 +231,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Steering(Item item, XElement element)
|
||||
public Steering(Item item, ContentXElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
InitProjSpecific(element);
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element);
|
||||
partial void InitProjSpecific(ContentXElement element);
|
||||
|
||||
public override void OnItemLoaded()
|
||||
{
|
||||
@@ -292,8 +292,6 @@ namespace Barotrauma.Items.Components
|
||||
controlledSub = sonar.ConnectedTransducers.Any() ? sonar.ConnectedTransducers.First().Item.Submarine : null;
|
||||
}
|
||||
|
||||
currPowerConsumption = powerConsumption;
|
||||
|
||||
if (Voltage < MinVoltage) { return; }
|
||||
|
||||
if (user != null && user.Removed)
|
||||
@@ -405,7 +403,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float userSkill = Math.Max(user.GetSkillLevel("helm"), 1.0f) / 100.0f;
|
||||
user.Info.IncreaseSkillLevel(
|
||||
"helm",
|
||||
"helm".ToIdentifier(),
|
||||
SkillSettings.Current.SkillIncreasePerSecondWhenSteering / userSkill * deltaTime);
|
||||
}
|
||||
|
||||
@@ -724,7 +722,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (user != character && user != null && user.SelectedConstruction == item && character.IsOnPlayerTeam)
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogSteeringTaken"), null, 0.0f, "steeringtaken", 10.0f);
|
||||
character.Speak(TextManager.Get("DialogSteeringTaken").Value, null, 0.0f, "steeringtaken".ToIdentifier(), 10.0f);
|
||||
}
|
||||
}
|
||||
user = character;
|
||||
@@ -738,7 +736,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
character.Speak(TextManager.Get("DialogNavTerminalIsBroken"), identifier: "navterminalisbroken", minDurationBetweenSimilar: 30.0f);
|
||||
character.Speak(TextManager.Get("DialogNavTerminalIsBroken").Value, identifier: "navterminalisbroken".ToIdentifier(), minDurationBetweenSimilar: 30.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,64 +746,72 @@ namespace Barotrauma.Items.Components
|
||||
AutoPilot = true;
|
||||
}
|
||||
IncreaseSkillLevel(user, deltaTime);
|
||||
switch (objective.Option.ToLowerInvariant())
|
||||
if (objective.Option == "maintainposition")
|
||||
{
|
||||
case "maintainposition":
|
||||
if (objective.Override)
|
||||
{
|
||||
SetMaintainPosition();
|
||||
}
|
||||
break;
|
||||
case "navigateback":
|
||||
if (Level.IsLoadedOutpost) { break; }
|
||||
if (objective.Override)
|
||||
{
|
||||
SetMaintainPosition();
|
||||
}
|
||||
}
|
||||
else if (!Level.IsLoadedOutpost)
|
||||
{
|
||||
if (objective.Option == "navigateback")
|
||||
{
|
||||
if (DockingSources.Any(d => d.Docked))
|
||||
{
|
||||
item.SendSignal("1", "toggle_docking");
|
||||
}
|
||||
|
||||
if (objective.Override)
|
||||
{
|
||||
if (MaintainPos || LevelEndSelected || !LevelStartSelected || navigateTactically)
|
||||
{
|
||||
unsentChanges = true;
|
||||
}
|
||||
|
||||
SetDestinationLevelStart();
|
||||
}
|
||||
break;
|
||||
case "navigatetodestination":
|
||||
if (Level.IsLoadedOutpost) { break; }
|
||||
}
|
||||
else if (objective.Option == "navigatetodestination")
|
||||
{
|
||||
if (DockingSources.Any(d => d.Docked))
|
||||
{
|
||||
item.SendSignal("1", "toggle_docking");
|
||||
}
|
||||
|
||||
if (objective.Override)
|
||||
{
|
||||
if (MaintainPos || !LevelEndSelected || LevelStartSelected || navigateTactically)
|
||||
{
|
||||
unsentChanges = true;
|
||||
}
|
||||
|
||||
SetDestinationLevelEnd();
|
||||
}
|
||||
break;
|
||||
case "navigatetactical":
|
||||
if (Level.IsLoadedOutpost) { break; }
|
||||
}
|
||||
else if (objective.Option == "navigatetactical")
|
||||
{
|
||||
if (DockingSources.Any(d => d.Docked))
|
||||
{
|
||||
item.SendSignal("1", "toggle_docking");
|
||||
}
|
||||
|
||||
if (objective.Override)
|
||||
{
|
||||
if (MaintainPos || LevelEndSelected || LevelStartSelected || !navigateTactically)
|
||||
{
|
||||
unsentChanges = true;
|
||||
}
|
||||
|
||||
SetDestinationTactical();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sonar?.AIOperate(deltaTime, character, objective);
|
||||
if (!MaintainPos && showIceSpireWarning && character.IsOnPlayerTeam)
|
||||
{
|
||||
character.Speak(TextManager.Get("dialogicespirespottedsonar"), null, 0.0f, "icespirespottedsonar", 60.0f);
|
||||
character.Speak(TextManager.Get("dialogicespirespottedsonar").Value, null, 0.0f, "icespirespottedsonar".ToIdentifier(), 60.0f);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Barotrauma.Items.Components
|
||||
set { oxygenFlow = Math.Max(value, 0.0f); }
|
||||
}
|
||||
|
||||
public Vent (Item item, XElement element) : base(item, element) { }
|
||||
public Vent (Item item, ContentXElement element) : base(item, element) { }
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user