2 using Microsoft.Xna.Framework;
4 using System.Globalization;
11 private float capacity;
12 private float adjustedCapacity;
14 private float charge, prevCharge;
17 private float maxRechargeSpeed;
21 private float rechargeSpeed;
22 private float lastSentCharge;
31 private float currPowerOutput;
34 get {
return currPowerOutput; }
37 System.Diagnostics.Debug.Assert(value >= 0.0f, $
"Tried to set PowerContainer's output to a negative value ({value})");
38 currPowerOutput = Math.Max(0, value);
42 [
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.")]
49 [
Serialize(
"0,0",
IsPropertySaveable.Yes, description:
"The size of the progress bar indicating the charge of the item (in pixels).")]
52 get {
return indicatorSize; }
53 set { indicatorSize = value; }
56 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Should the progress bar indicating the charge of the item fill up horizontally or vertically.")]
66 [
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.")]
72 capacity = Math.Max(value, 1.0f);
80 get {
return charge; }
83 if (!MathUtils.IsValid(value))
return;
84 charge = MathHelper.Clamp(value, 0.0f, adjustedCapacity);
87 if (Math.Abs(charge - lastSentCharge) / adjustedCapacity > 0.05f)
92 lastSentCharge = charge;
99 [
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.")]
102 get {
return maxRechargeSpeed; }
103 set { maxRechargeSpeed = Math.Max(value, 1.0f); }
109 get {
return rechargeSpeed; }
112 if (!MathUtils.IsValid(value))
return;
113 rechargeSpeed = MathHelper.Clamp(value, 0.0f, maxRechargeSpeed);
114 rechargeSpeed = MathUtils.RoundTowardsClosest(rechargeSpeed, Math.Max(maxRechargeSpeed * 0.1f, 1.0f));
122 [
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.")]
125 private float efficiency;
126 [
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.")]
129 get {
return efficiency; }
130 set { efficiency = MathHelper.Clamp(value, 0.0f, 1.0f); }
133 private bool flipIndicator;
137 get {
return flipIndicator; }
138 set { flipIndicator = value; }
146 private bool isRunning;
151 : base(
item, element)
158 partial
void InitProjSpecific();
162 return picker !=
null;
175 float chargeRatio = charge / adjustedCapacity;
177 if (chargeRatio > 0.0f)
182 float loadReading = 0;
183 if (powerOut !=
null && powerOut.Grid !=
null)
185 loadReading = powerOut.Grid.Load;
189 item.
SendSignal(((
int)Math.Round(loadReading)).ToString(),
"load_value_out");
204 if (charge >= adjustedCapacity)
206 charge = adjustedCapacity;
213 float missingCharge = adjustedCapacity - charge;
214 float targetRechargeSpeed = rechargeSpeed;
218 targetRechargeSpeed = MathF.Pow(rechargeSpeed / maxRechargeSpeed, 2) * maxRechargeSpeed;
221 if (missingCharge < 1.0f)
223 targetRechargeSpeed *= missingCharge;
232 return charge > 0 ? -1 : 0;
248 if (connection == powerOut)
251 float chargeRatio = prevCharge / adjustedCapacity;
252 if (chargeRatio < 0.1f)
254 maxOutput = Math.
Max(chargeRatio * 10.0f, 0.0f) *
MaxOutPut;
262 maxOutput = Math.Min(maxOutput, prevCharge * 60 /
UpdateInterval);
283 if (connection == powerOut && minMaxPower.
Max > 0)
321 if (targetRatio > 0 ||
float.TryParse(objective.
Option.Value, out targetRatio))
323 if (Math.Abs(rechargeSpeed - maxRechargeSpeed * targetRatio) > 0.05f)
326 item.CreateServerEvent(
this);
330 if (rechargeSpeedSlider !=
null)
337 character.
Speak(TextManager.GetWithVariables(
"DialogChargeBatteries",
339 (
"[rate]", ((
int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString(),
FormatCapitals.No)).Value,
340 null, 1.0f,
"chargebattery".ToIdentifier(), 10.0f);
346 if (rechargeSpeed > 0.0f)
349 item.CreateServerEvent(
this);
353 if (rechargeSpeedSlider !=
null)
360 character.
Speak(TextManager.GetWithVariables(
"DialogStopChargingBatteries",
362 (
"[rate]", ((
int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString(),
FormatCapitals.No)).Value,
363 null, 1.0f,
"chargebattery".ToIdentifier(), 10.0f);
373 if (connection.
IsPower) {
return; }
374 switch (connection.
Name)
376 case "disable_output":
380 if (
float.TryParse(signal.
value, NumberStyles.Any, CultureInfo.InvariantCulture, out
float tempSpeed))
382 if (!MathUtils.IsValid(tempSpeed)) {
return; }
384 float rechargeRate = MathHelper.Clamp(tempSpeed / 100.0f, 0.0f, 1.0f);
387 if (rechargeSpeedSlider !=
null)
389 rechargeSpeedSlider.
BarScroll = rechargeRate;
readonly Identifier Option
void Speak(string message, ChatMessageType? messageType=null, float delay=0.0f, Identifier identifier=default, float minDurationBetweenSimilar=0.0f)
static NetworkMember NetworkMember
List< Connection > Connections
ItemStatManager StatManager
override string Name
Note that this is not a LocalizedString instance, just the current name of the item as a string....
void SendSignal(string signal, string connectionName)
void ApplyStatusEffects(ActionType type, float deltaTime, Character character=null, Limb targetLimb=null, Entity useTarget=null, Character user=null, Vector2? worldPosition=null, float afflictionMultiplier=1.0f)
override float GetConnectionPowerOut(Connection connection, float power, PowerRange minMaxPower, float load)
Finalized power out from the container for the connection, provided the given grid information Output...
override float GetCurrentPowerConsumption(Connection connection=null)
Returns the power consumption if checking the powerIn connection, or a negative value if the output c...
override PowerPriority Priority
bool ExponentialRechargeSpeed
override bool Pick(Character picker)
a Character has picked the item
override bool CrewAIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
true if the operation was completed
Vector2 IndicatorPosition
Vector2 indicatorPosition
override void Update(float deltaTime, Camera cam)
override void GridResolved(Connection conn)
When the corresponding grid connection is resolved, adjust the container's charge.
const float aiRechargeTargetRatio
PowerContainer(Item item, ContentXElement element)
override void ReceiveSignal(Signal signal, Connection connection)
override PowerRange MinMaxPowerOut(Connection connection, float load=0)
Minimum and maximum output for the queried connection. Powerin min max equals CurrPowerConsumption as...
float CurrPowerConsumption
const float UpdateInterval
Interface for entities that the clients can send events to the server
Interface for entities that the server can send events to the clients
PowerPriority
Order in which power sources will provide to a grid, lower number is higher priority
ActionType
ActionTypes define when a StatusEffect is executed.
static readonly PowerRange Zero