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
@@ -13,8 +13,6 @@ namespace Barotrauma.Items.Components
private float charge;
//private float rechargeVoltage;
//how fast the battery can be recharged
private float maxRechargeSpeed;
@@ -27,45 +25,52 @@ namespace Barotrauma.Items.Components
protected Vector2 indicatorPosition, indicatorSize;
protected bool isHorizontal;
protected override PowerPriority Priority { get { return PowerPriority.Battery; } }
private float currPowerOutput;
public float CurrPowerOutput
{
get;
private set;
get { return currPowerOutput; }
private set
{
System.Diagnostics.Debug.Assert(value >= 0.0f);
currPowerOutput = Math.Max(0, value);
}
}
[Serialize("0,0", true, description: "The position of the progress bar indicating the charge of the item. In pixels as an offset from the upper left corner of the sprite.")]
[Serialize("0,0", IsPropertySaveable.Yes, description: "The position of the progress bar indicating the charge of the item. In pixels as an offset from the upper left corner of the sprite.")]
public Vector2 IndicatorPosition
{
get { return indicatorPosition; }
set { indicatorPosition = value; }
}
[Serialize("0,0", true, description: "The size of the progress bar indicating the charge of the item (in pixels).")]
[Serialize("0,0", IsPropertySaveable.Yes, description: "The size of the progress bar indicating the charge of the item (in pixels).")]
public Vector2 IndicatorSize
{
get { return indicatorSize; }
set { indicatorSize = value; }
}
[Serialize(false, true, description: "Should the progress bar indicating the charge of the item fill up horizontally or vertically.")]
[Serialize(false, IsPropertySaveable.Yes, description: "Should the progress bar indicating the charge of the item fill up horizontally or vertically.")]
public bool IsHorizontal
{
get { return isHorizontal; }
set { isHorizontal = value; }
}
[Editable, Serialize(10.0f, true, description: "Maximum output of the device when fully charged (kW).")]
[Editable, Serialize(10.0f, IsPropertySaveable.Yes, description: "Maximum output of the device when fully charged (kW).")]
public float MaxOutPut { set; get; }
[Editable, Serialize(10.0f, true, description: "The maximum capacity of the device (kW * min). For example, a value of 1000 means the device can output 100 kilowatts of power for 10 minutes, or 1000 kilowatts for 1 minute.")]
[Editable, Serialize(10.0f, IsPropertySaveable.Yes, description: "The maximum capacity of the device (kW * min). For example, a value of 1000 means the device can output 100 kilowatts of power for 10 minutes, or 1000 kilowatts for 1 minute.")]
public float Capacity
{
get { return capacity; }
set { capacity = Math.Max(value, 1.0f); }
}
[Editable, Serialize(0.0f, true, description: "The current charge of the device.")]
[Editable, Serialize(0.0f, IsPropertySaveable.Yes, description: "The current charge of the device.")]
public float Charge
{
get { return charge; }
@@ -87,14 +92,14 @@ namespace Barotrauma.Items.Components
public float ChargePercentage => MathUtils.Percentage(Charge, Capacity);
[Editable, Serialize(10.0f, true, description: "How fast the device can be recharged. For example, a recharge speed of 100 kW and a capacity of 1000 kW*min would mean it takes 10 minutes to fully charge the device.")]
[Editable, Serialize(10.0f, IsPropertySaveable.Yes, description: "How fast the device can be recharged. For example, a recharge speed of 100 kW and a capacity of 1000 kW*min would mean it takes 10 minutes to fully charge the device.")]
public float MaxRechargeSpeed
{
get { return maxRechargeSpeed; }
set { maxRechargeSpeed = Math.Max(value, 1.0f); }
}
[Editable, Serialize(10.0f, true, description: "The current recharge speed of the device.")]
[Editable, Serialize(10.0f, IsPropertySaveable.Yes, description: "The current recharge speed of the device.")]
public float RechargeSpeed
{
get { return rechargeSpeed; }
@@ -110,14 +115,14 @@ namespace Barotrauma.Items.Components
}
}
[Serialize(false, true, description: "If true, the recharge speed (and power consumption) of the device goes up exponentially as the recharge rate is increased.")]
[Serialize(false, IsPropertySaveable.Yes, description: "If true, the recharge speed (and power consumption) of the device goes up exponentially as the recharge rate is increased.")]
public bool ExponentialRechargeSpeed { get; set; }
[Editable(minValue: 0.0f, maxValue: 10.0f, decimals: 2), Serialize(0.5f, true)]
[Editable(minValue: 0.0f, maxValue: 10.0f, decimals: 2), Serialize(0.5f, IsPropertySaveable.Yes)]
public float RechargeAdjustSpeed { get; set; }
private float efficiency;
[Editable(minValue: 0.0f, maxValue: 1.0f, decimals: 2), Serialize(0.95f, true, description: "The amount of power you can get out of a item relative to the amount of power that's put into it.")]
[Editable(minValue: 0.0f, maxValue: 1.0f, decimals: 2), Serialize(0.95f, IsPropertySaveable.Yes, description: "The amount of power you can get out of a item relative to the amount of power that's put into it.")]
public float Efficiency
{
get { return efficiency; }
@@ -130,7 +135,7 @@ namespace Barotrauma.Items.Components
private bool isRunning;
public bool HasBeenTuned { get; private set; }
public PowerContainer(Item item, XElement element)
public PowerContainer(Item item, ContentXElement element)
: base(item, element)
{
IsActive = true;
@@ -154,92 +159,142 @@ namespace Barotrauma.Items.Components
isRunning = true;
float chargeRatio = charge / capacity;
float gridPower = 0.0f;
float gridLoad = 0.0f;
foreach (Connection c in item.Connections)
{
if (!c.IsPower || !c.IsOutput) { continue; }
foreach (Connection c2 in c.Recipients)
{
if (c2.Item.Condition <= 0.0f) { continue; }
PowerTransfer pt = c2.Item.GetComponent<PowerTransfer>();
if (pt == null)
{
foreach (Powered powered in c2.Item.GetComponents<Powered>())
{
if (!powered.IsActive) continue;
gridLoad += powered.CurrPowerConsumption;
}
continue;
}
if (!pt.IsActive || !pt.CanTransfer) { continue; }
gridPower -= pt.CurrPowerConsumption;
gridLoad += pt.PowerLoad;
}
}
if (chargeRatio > 0.0f)
{
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
}
if (charge >= capacity)
float loadReading = 0;
if (powerOut != null && powerOut.Grid != null)
{
//rechargeVoltage = 0.0f;
charge = capacity;
CurrPowerConsumption = 0.0f;
}
else
{
float missingCharge = capacity - charge;
float targetRechargeSpeed = rechargeSpeed;
if (ExponentialRechargeSpeed)
{
targetRechargeSpeed = MathF.Pow(rechargeSpeed / maxRechargeSpeed, 2) * maxRechargeSpeed;
}
if (missingCharge < 1.0f)
{
targetRechargeSpeed *= missingCharge;
}
if (currPowerConsumption < targetRechargeSpeed)
{
currPowerConsumption = Math.Min(currPowerConsumption + deltaTime * maxRechargeSpeed * RechargeAdjustSpeed, targetRechargeSpeed);
}
else
{
currPowerConsumption = Math.Max(currPowerConsumption - deltaTime * maxRechargeSpeed * RechargeAdjustSpeed, targetRechargeSpeed);
}
Charge += currPowerConsumption * Math.Min(Voltage, 1.0f) / 3600.0f * efficiency;
}
if (charge <= 0.0f)
{
CurrPowerOutput = 0.0f;
charge = 0.0f;
return;
}
else
{
//output starts dropping when the charge is less than 10%
float maxOutputRatio = 1.0f;
if (chargeRatio < 0.1f)
{
maxOutputRatio = Math.Max(chargeRatio * 10.0f, 0.0f);
}
CurrPowerOutput += (gridLoad - gridPower) * deltaTime;
float maxOutput = Math.Min(MaxOutPut * maxOutputRatio, gridLoad);
CurrPowerOutput = MathHelper.Clamp(CurrPowerOutput, 0.0f, maxOutput);
Charge -= CurrPowerOutput / 3600.0f;
loadReading = powerOut.Grid.Load;
}
item.SendSignal(((int)Math.Round(-CurrPowerOutput)).ToString(), "power_value_out");
item.SendSignal(((int)Math.Round(loadReading)).ToString(), "load_value_out");
item.SendSignal(((int)Math.Round(Charge)).ToString(), "charge");
item.SendSignal(((int)Math.Round(Charge / capacity * 100)).ToString(), "charge_%");
item.SendSignal(((int)Math.Round(RechargeSpeed / maxRechargeSpeed * 100)).ToString(), "charge_rate");
}
/// <summary>
/// Returns the power consumption if checking the powerIn connection, or a negative value if the output can provide power when checking powerOut.
/// Power consumption is proportional to set recharge speed and if there is less than max charge.
/// </summary>
public override float GetCurrentPowerConsumption(Connection connection = null)
{
if (connection == powerIn)
{
//Don't draw power if fully charged
if (charge >= capacity)
{
charge = capacity;
return 0;
}
else
{
float missingCharge = capacity - charge;
float targetRechargeSpeed = rechargeSpeed;
if (ExponentialRechargeSpeed)
{
targetRechargeSpeed = MathF.Pow(rechargeSpeed / maxRechargeSpeed, 2) * maxRechargeSpeed;
}
//For the last kwMin scale the recharge rate linearly to prevent overcharging and to have a smooth cutoff
if (missingCharge < 1.0f)
{
targetRechargeSpeed *= missingCharge;
}
return MathHelper.Clamp(targetRechargeSpeed, 0, MaxRechargeSpeed);
}
}
else
{
CurrPowerOutput = 0;
return charge > 0 ? -1 : 0;
}
}
/// <summary>
/// Minimum and maximum output for the queried connection.
/// Powerin min max equals CurrPowerConsumption as its abnormal for there to be power out.
/// PowerOut min power out is zero and max is the maxout unless below 10% charge where
/// the output is scaled relative to the 10% charge.
/// </summary>
/// <param name="connection">Connection being queried</param>
/// <param name="load">Current grid load</param>
/// <returns>Minimum and maximum power output for the connection</returns>
public override PowerRange MinMaxPowerOut(Connection connection, float load = 0)
{
if (connection == powerOut)
{
float maxOutput;
float chargeRatio = charge / capacity;
if (chargeRatio < 0.1f)
{
maxOutput = Math.Max(chargeRatio * 10.0f, 0.0f) * MaxOutPut;
}
else
{
maxOutput = MaxOutPut;
}
//Limit max power out to not exceed the charge of the container
maxOutput = Math.Min(maxOutput, charge * 60 / UpdateInterval);
return new PowerRange(0.0f, maxOutput);
}
return PowerRange.Zero;
}
/// <summary>
/// Finalized power out from the container for the connection, provided the given grid information
/// Output power based on the maxpower all batteries can output. So all batteries can
/// equally share powerout based on their output capabilities.
/// </summary>
/// <param name="connection"></param>
/// <param name="power"></param>
/// <param name="minMaxPower"></param>
/// <param name="load"></param>
/// <returns></returns>
public override float GetConnectionPowerOut(Connection connection, float power, PowerRange minMaxPower, float load)
{
if (connection == powerOut)
{
//Calculate the max power the container can output
float maxPowerOutput = MaxOutPut;
float chargeRatio = charge / capacity;
if (chargeRatio < 0.1f)
{
maxPowerOutput *= Math.Max(chargeRatio * 10.0f, 0.0f);
}
//Set power output based on the relative max power output capabilities and load demand
CurrPowerOutput = MathHelper.Clamp((load - power) / minMaxPower.Max, 0, 1) * maxPowerOutput;
return CurrPowerOutput;
}
return 0.0f;
}
/// <summary>
/// When the corresponding grid connection is resolved, adjust the container's charge.
/// </summary>
public override void GridResolved(Connection conn)
{
if (conn == powerIn)
{
//Increase charge based on how much power came in from the grid
Charge += (CurrPowerConsumption * Voltage) / 60 * UpdateInterval * efficiency;
}
else
{
//Decrease charge based on how much power is leaving the device
Charge = Math.Clamp(Charge - CurrPowerOutput / 60 * UpdateInterval, 0, Capacity);
}
}
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return false; }
@@ -250,8 +305,8 @@ namespace Barotrauma.Items.Components
}
if (HasBeenTuned) { return true; }
float targetRatio = string.IsNullOrEmpty(objective.Option) || objective.Option.Equals("charge", StringComparison.OrdinalIgnoreCase) ? aiRechargeTargetRatio : -1;
if (targetRatio > 0 || float.TryParse(objective.Option, out targetRatio))
float targetRatio = objective.Option.IsEmpty || objective.Option == "charge" ? aiRechargeTargetRatio : -1;
if (targetRatio > 0 || float.TryParse(objective.Option.Value, out targetRatio))
{
if (Math.Abs(rechargeSpeed - maxRechargeSpeed * targetRatio) > 0.05f)
{
@@ -267,9 +322,10 @@ namespace Barotrauma.Items.Components
#endif
if (character.IsOnPlayerTeam)
{
character.Speak(TextManager.GetWithVariables("DialogChargeBatteries", new string[2] { "[itemname]", "[rate]" },
new string[2] { item.Name, ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString() },
new bool[2] { true, false }), null, 1.0f, "chargebattery", 10.0f);
character.Speak(TextManager.GetWithVariables("DialogChargeBatteries",
("[itemname]", item.Name, FormatCapitals.Yes),
("[rate]", ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString(), FormatCapitals.No)).Value,
null, 1.0f, "chargebattery".ToIdentifier(), 10.0f);
}
}
}
@@ -289,9 +345,10 @@ namespace Barotrauma.Items.Components
#endif
if (character.IsOnPlayerTeam)
{
character.Speak(TextManager.GetWithVariables("DialogStopChargingBatteries", new string[2] { "[itemname]", "[rate]" },
new string[2] { item.Name, ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString() },
new bool[2] { true, false }), null, 1.0f, "chargebattery", 10.0f);
character.Speak(TextManager.GetWithVariables("DialogStopChargingBatteries",
("[itemname]", item.Name, FormatCapitals.Yes),
("[rate]", ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString(), FormatCapitals.No)).Value,
null, 1.0f, "chargebattery".ToIdentifier(), 10.0f);
}
}
}