80ab27df22
commit 409d4d96ead69028a164274637d23e350acb73fb Merge: 95169f539 26e89c63d Author: EdusFF <pitkanen.eetu@gmail.com> Date: Mon Mar 11 15:13:27 2019 +0200 Merge branch 'dev' of github.com:Regalis11/Barotrauma into dev commit 95169f53937f9a7e168a884171eaa21ae7f08023 Author: EdusFF <pitkanen.eetu@gmail.com> Date: Mon Mar 11 15:13:11 2019 +0200 Modified: ServerMessage structure to allow _ ; in player & submarine names commit 26e89c63dc8da771aea9f09978a630a6cff60a6f Merge: b7646d06d fb0b821bc Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Mon Mar 11 14:42:44 2019 +0200 Merge branch 'kuraiookami-logicExpantion' into dev # Conflicts: # Barotrauma/BarotraumaShared/SharedContent.projitems commit fb0b821bc97891cdeec8f2c740a12119696393ea Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Mon Mar 11 14:41:21 2019 +0200 Use invariant culture when parsing floats or converting them to strings in signal components commit f0c8afba934b41358cf5d59a22b87caf33f98a61 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Mon Mar 11 14:00:44 2019 +0200 Update new signal components to use identifiers & added names and descriptions to the text file, use invariant culture in equalscomponent, memorycomponent doesn't require the signals to be floats commit 674d9ec804fc4770b602d4b09240b08cafc8ccec Merge: 3ea33fb54 242e2429f Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Mon Mar 11 12:01:27 2019 +0200 Merge branch 'logicExpantion' of https://github.com/kuraiookami/Barotrauma into kuraiookami-logicExpantion # Conflicts: # Barotrauma/BarotraumaShared/BarotraumaShared.projitems # Barotrauma/BarotraumaShared/Content/Items/Electricity/poweritems.xml # Barotrauma/BarotraumaShared/Content/Items/Electricity/signalitems.xml # Barotrauma/BarotraumaShared/Source/Items/Components/Power/PowerContainer.cs # Barotrauma/BarotraumaShared/Source/Items/Components/Signal/AdderComponent.cs commit b7646d06d53fb05227276e6286d0e15da5dc9080 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Mon Mar 11 11:37:33 2019 +0200 Re-enabled multiplayer campaign commit cf7258f6410a5995c881ec6e95eb9def5cd90ad4 Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Mon Mar 11 11:28:48 2019 +0200 Fixed item interfaces getting repositioned every frame when the editing HUD is open. Closes #1212 commit e8906239c779cf71de694bc65c81058e5cae16ef Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Mon Mar 11 11:12:05 2019 +0200 Fixed VoipCapture creating new "could not start voice capture" popups constantly if there's no suitable capture device. Closes #1262 commit a30f47fbe47fde4fccb0453c1773a76d730d226b Author: Joonas Rikkonen <poe.regalis@gmail.com> Date: Sun Mar 10 19:04:59 2019 +0200 Disable audio instead of crashing if no audio device is found. Closes #1214 commit 242e2429fd2c3ed199ac26b55e2cbdc8636e73f9 Author: Darkwolf <Darkwolf0101@gmail.com> Date: Mon Jan 21 21:26:57 2019 -0600 Expansion of Barotrauma's logic system. Changed: - AdderComponent and children can clamp their output - Powercontainer signals for charge,charge% and charge rate Added: - ColorComponent: Dynamic signals for light set_color inputs - MemoryComponent: Stores and sends a signal that is edge latched - DivideComponent: Standard division - MultiplyComponent: Standard multiplication - SubtractComponent: Standard subtraction - XorComponent: Exclusive or - EqualsComponent: Equals comparison - GreaterComponent: Greater than comparison
294 lines
10 KiB
C#
294 lines
10 KiB
C#
using Barotrauma.Networking;
|
|
using Lidgren.Network;
|
|
using Microsoft.Xna.Framework;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Xml.Linq;
|
|
|
|
namespace Barotrauma.Items.Components
|
|
{
|
|
partial class PowerContainer : Powered, IDrawableComponent, IServerSerializable, IClientSerializable
|
|
{
|
|
//[power/min]
|
|
private float capacity;
|
|
|
|
private float charge;
|
|
|
|
private float rechargeVoltage, outputVoltage;
|
|
|
|
//how fast the battery can be recharged
|
|
private float maxRechargeSpeed;
|
|
|
|
//how fast it's currently being recharged (can be changed, so that
|
|
//charging can be slowed down or disabled if there's a shortage of power)
|
|
private float rechargeSpeed;
|
|
private float lastSentCharge;
|
|
|
|
//charge indicator description
|
|
protected Vector2 indicatorPosition, indicatorSize;
|
|
|
|
protected bool isHorizontal;
|
|
|
|
//a list of powered devices connected directly to this item
|
|
private readonly List<Pair<Powered, Connection>> directlyConnected = new List<Pair<Powered, Connection>>(10);
|
|
|
|
public float CurrPowerOutput
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
[Serialize("0,0", true)]
|
|
public Vector2 IndicatorPosition
|
|
{
|
|
get { return indicatorPosition; }
|
|
set { indicatorPosition = value; }
|
|
}
|
|
|
|
[Serialize("0,0", true)]
|
|
public Vector2 IndicatorSize
|
|
{
|
|
get { return indicatorSize; }
|
|
set { indicatorSize = value; }
|
|
}
|
|
|
|
[Serialize(false, true)]
|
|
public bool IsHorizontal
|
|
{
|
|
get { return isHorizontal; }
|
|
set { isHorizontal = value; }
|
|
}
|
|
|
|
[Editable(ToolTip = "Maximum output of the device when fully charged (kW)."), Serialize(10.0f, true)]
|
|
public float MaxOutPut { set; get; }
|
|
|
|
[Serialize(10.0f, true), Editable(ToolTip = "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)]
|
|
public float Charge
|
|
{
|
|
get { return charge; }
|
|
set
|
|
{
|
|
if (!MathUtils.IsValid(value)) return;
|
|
charge = MathHelper.Clamp(value, 0.0f, capacity);
|
|
|
|
//send a network event if the charge has changed by more than 5%
|
|
if (Math.Abs(charge - lastSentCharge) / capacity > 0.05f)
|
|
{
|
|
#if SERVER
|
|
if (GameMain.Server != null) item.CreateServerEvent(this);
|
|
#endif
|
|
lastSentCharge = charge;
|
|
}
|
|
}
|
|
}
|
|
|
|
[Serialize(10.0f, true), Editable(ToolTip = "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); }
|
|
}
|
|
|
|
[Serialize(10.0f, true), Editable]
|
|
public float RechargeSpeed
|
|
{
|
|
get { return rechargeSpeed; }
|
|
set
|
|
{
|
|
if (!MathUtils.IsValid(value)) return;
|
|
rechargeSpeed = MathHelper.Clamp(value, 0.0f, maxRechargeSpeed);
|
|
rechargeSpeed = MathUtils.RoundTowardsClosest(rechargeSpeed, Math.Max(maxRechargeSpeed * 0.1f, 1.0f));
|
|
}
|
|
}
|
|
|
|
public PowerContainer(Item item, XElement element)
|
|
: base(item, element)
|
|
{
|
|
IsActive = true;
|
|
|
|
InitProjSpecific();
|
|
}
|
|
|
|
partial void InitProjSpecific();
|
|
|
|
public override bool Pick(Character picker)
|
|
{
|
|
return picker != null;
|
|
}
|
|
|
|
public override void Update(float deltaTime, Camera cam)
|
|
{
|
|
float chargeRatio = charge / capacity;
|
|
float gridPower = 0.0f;
|
|
float gridLoad = 0.0f;
|
|
directlyConnected.Clear();
|
|
|
|
foreach (Connection c in item.Connections)
|
|
{
|
|
if (c.Name == "power_in") continue;
|
|
foreach (Connection c2 in c.Recipients)
|
|
{
|
|
PowerTransfer pt = c2.Item.GetComponent<PowerTransfer>();
|
|
if (pt == null)
|
|
{
|
|
foreach (Powered powered in c2.Item.GetComponents<Powered>())
|
|
{
|
|
if (!powered.IsActive) continue;
|
|
directlyConnected.Add(new Pair<Powered, Connection>(powered, c2));
|
|
gridLoad += powered.CurrPowerConsumption;
|
|
}
|
|
continue;
|
|
}
|
|
if (!pt.IsActive) { continue; }
|
|
|
|
gridLoad += pt.PowerLoad;
|
|
gridPower -= pt.CurrPowerConsumption;
|
|
}
|
|
}
|
|
|
|
if (chargeRatio > 0.0f)
|
|
{
|
|
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
|
}
|
|
|
|
if (charge >= capacity)
|
|
{
|
|
rechargeVoltage = 0.0f;
|
|
charge = capacity;
|
|
|
|
CurrPowerConsumption = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
currPowerConsumption = MathHelper.Lerp(currPowerConsumption, rechargeSpeed, 0.05f);
|
|
Charge += currPowerConsumption * rechargeVoltage / 3600.0f;
|
|
}
|
|
|
|
//provide power to the grid
|
|
if (gridLoad > 0.0f)
|
|
{
|
|
if (charge <= 0.0f)
|
|
{
|
|
CurrPowerOutput = 0.0f;
|
|
charge = 0.0f;
|
|
return;
|
|
}
|
|
|
|
if (gridPower < gridLoad)
|
|
{
|
|
//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 = MathHelper.Lerp(
|
|
CurrPowerOutput,
|
|
Math.Min(MaxOutPut * maxOutputRatio, gridLoad),
|
|
deltaTime * 10.0f);
|
|
}
|
|
else
|
|
{
|
|
CurrPowerOutput = MathHelper.Lerp(CurrPowerOutput, 0.0f, deltaTime * 10.0f);
|
|
}
|
|
|
|
Charge -= CurrPowerOutput / 3600.0f;
|
|
}
|
|
item.SendSignal(0, Charge.ToString(), "charge", null);
|
|
item.SendSignal(0, ((Charge / capacity) * 100).ToString(), "charge_%", null);
|
|
item.SendSignal(0, ((RechargeSpeed / maxRechargeSpeed) * 100).ToString(), "charge_rate", null);
|
|
|
|
foreach (Pair<Powered, Connection> connected in directlyConnected)
|
|
{
|
|
connected.First.ReceiveSignal(0, "", connected.Second, source: item, sender: null,
|
|
power: gridLoad <= 0.0f ? 1.0f : CurrPowerOutput / gridLoad);
|
|
}
|
|
|
|
foreach (Pair<Powered, Connection> connected in directlyConnected)
|
|
{
|
|
connected.First.ReceiveSignal(0, "", connected.Second, source: item, sender: null,
|
|
power: gridLoad <= 0.0f ? 1.0f : CurrPowerOutput / gridLoad);
|
|
}
|
|
|
|
rechargeVoltage = 0.0f;
|
|
outputVoltage = 0.0f;
|
|
}
|
|
|
|
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
|
|
{
|
|
#if CLIENT
|
|
if (GameMain.Client != null) return false;
|
|
#endif
|
|
|
|
if (string.IsNullOrEmpty(objective.Option) || objective.Option.ToLowerInvariant() == "charge")
|
|
{
|
|
if (Math.Abs(rechargeSpeed - maxRechargeSpeed * 0.5f) > 0.05f)
|
|
{
|
|
#if SERVER
|
|
item.CreateServerEvent(this);
|
|
#endif
|
|
RechargeSpeed = maxRechargeSpeed * 0.5f;
|
|
#if CLIENT
|
|
rechargeSpeedSlider.BarScroll = RechargeSpeed / Math.Max(maxRechargeSpeed, 1.0f);
|
|
#endif
|
|
character.Speak(TextManager.Get("DialogChargeBatteries")
|
|
.Replace("[itemname]", item.Name)
|
|
.Replace("[rate]", ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString()), null, 1.0f, "chargebattery", 10.0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (rechargeSpeed > 0.0f)
|
|
{
|
|
#if SERVER
|
|
item.CreateServerEvent(this);
|
|
#endif
|
|
RechargeSpeed = 0.0f;
|
|
#if CLIENT
|
|
rechargeSpeedSlider.BarScroll = RechargeSpeed / Math.Max(maxRechargeSpeed, 1.0f);
|
|
#endif
|
|
character.Speak(TextManager.Get("DialogStopChargingBatteries")
|
|
.Replace("[itemname]", item.Name)
|
|
.Replace("[rate]", ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString()), null, 1.0f, "chargebattery", 10.0f);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item source, Character sender, float power, float signalStrength = 1.0f)
|
|
{
|
|
if (connection.Name == "set_rate")
|
|
{
|
|
float tempSpeed;
|
|
if (float.TryParse(signal, NumberStyles.Any, CultureInfo.InvariantCulture, out tempSpeed))
|
|
{
|
|
if (!MathUtils.IsValid(tempSpeed)) return;
|
|
RechargeSpeed = MathHelper.Clamp(tempSpeed / 100.0f, 0.0f, 1.0f) * MaxRechargeSpeed;
|
|
}
|
|
}
|
|
if (!connection.IsPower) return;
|
|
|
|
if (connection.Name == "power_in")
|
|
{
|
|
rechargeVoltage = Math.Min(power, 1.0f);
|
|
}
|
|
else
|
|
{
|
|
outputVoltage = power;
|
|
}
|
|
}
|
|
}
|
|
}
|