Unstable 0.17.0.0

This commit is contained in:
Markus Isberg
2022-02-26 02:43:01 +09:00
parent a83f375681
commit 3974067915
913 changed files with 32472 additions and 32364 deletions
@@ -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);
}
}
}