Unstable 0.17.0.0
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user