v0.1
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Subsurface.Items.Components
|
||||
{
|
||||
class PowerContainer : Powered
|
||||
{
|
||||
//[power/min]
|
||||
float capacity;
|
||||
|
||||
float charge;
|
||||
|
||||
//how fast the battery can be recharged
|
||||
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)
|
||||
float rechargeSpeed;
|
||||
|
||||
float maxOutput;
|
||||
|
||||
[Editable, HasDefaultValue(10.0f, true)]
|
||||
public float MaxOutPut
|
||||
{
|
||||
set { maxOutput = value; }
|
||||
get { return maxOutput; }
|
||||
}
|
||||
|
||||
[HasDefaultValue(0.0f, true)]
|
||||
public float Charge
|
||||
{
|
||||
get { return charge; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value)) return;
|
||||
charge = MathHelper.Clamp(value, 0.0f, capacity);
|
||||
}
|
||||
}
|
||||
|
||||
[HasDefaultValue(10.0f, false), Editable]
|
||||
public float Capacity
|
||||
{
|
||||
get { return capacity; }
|
||||
set { capacity = Math.Max(value, 1.0f); }
|
||||
}
|
||||
|
||||
[HasDefaultValue(10.0f, false), Editable]
|
||||
public float RechargeSpeed
|
||||
{
|
||||
get { return rechargeSpeed; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value)) return;
|
||||
rechargeSpeed = MathHelper.Clamp(value, 0.0f, maxRechargeSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
[HasDefaultValue(10.0f, false), Editable]
|
||||
public float MaxRechargeSpeed
|
||||
{
|
||||
get { return maxRechargeSpeed; }
|
||||
set { maxRechargeSpeed = Math.Max(value, 1.0f); }
|
||||
}
|
||||
|
||||
public PowerContainer(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
//capacity = ToolBox.GetAttributeFloat(element, "capacity", 10.0f);
|
||||
//maxRechargeSpeed = ToolBox.GetAttributeFloat(element, "maxinput", 10.0f);
|
||||
//maxOutput = ToolBox.GetAttributeFloat(element, "maxoutput", 10.0f);
|
||||
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
if (picker == null) return false;
|
||||
|
||||
//picker.SelectedConstruction = (picker.SelectedConstruction == item) ? null : item;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
float chargeRate = (float)(Math.Sqrt(charge / capacity));
|
||||
//float gridPower = 0.0f;
|
||||
float gridLoad = 0.0f;
|
||||
|
||||
//if (item.linkedTo.Count == 0) return;
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
|
||||
foreach (Connection c in item.Connections)
|
||||
{
|
||||
foreach (Connection c2 in c.Recipients)
|
||||
{
|
||||
PowerTransfer pt = c2.Item.GetComponent<PowerTransfer>();
|
||||
if (pt == null) continue;
|
||||
|
||||
gridLoad += pt.PowerLoad;
|
||||
}
|
||||
}
|
||||
|
||||
//foreach (MapEntity e in item.linkedTo)
|
||||
//{
|
||||
// Item it = e as Item;
|
||||
// if (it == null) continue;
|
||||
|
||||
// PowerTransfer pt = it.GetComponent<PowerTransfer>();
|
||||
// if (pt==null) continue;
|
||||
// //gridPower -= pt.PowerConsumption;
|
||||
// gridLoad += pt.PowerLoad;
|
||||
|
||||
// //gridPower = -jb.PowerConsumption;
|
||||
// //gridLoad = jb.load;
|
||||
// break;
|
||||
//}
|
||||
|
||||
float gridRate = voltage;
|
||||
|
||||
//recharge
|
||||
if (gridRate >= chargeRate)
|
||||
{
|
||||
if (charge >= capacity)
|
||||
{
|
||||
currPowerConsumption = 0.0f;
|
||||
charge = capacity;
|
||||
return;
|
||||
}
|
||||
|
||||
currPowerConsumption = MathHelper.Lerp(currPowerConsumption, rechargeSpeed, 0.05f);
|
||||
charge += currPowerConsumption*voltage / 3600.0f;
|
||||
}
|
||||
//provide power to the grid
|
||||
else if (gridLoad > 0.0f)
|
||||
{
|
||||
if (charge <= 0.0f)
|
||||
{
|
||||
currPowerConsumption = 0.0f;
|
||||
charge = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
//currPowerConsumption = MathHelper.Lerp(
|
||||
// currPowerConsumption,
|
||||
// -maxOutput * chargeRate,
|
||||
// 0.1f);
|
||||
|
||||
currPowerConsumption = MathHelper.Lerp(
|
||||
currPowerConsumption,
|
||||
-Math.Min(maxOutput * chargeRate, gridLoad - (gridLoad * voltage)),
|
||||
0.05f);
|
||||
|
||||
//powerConsumption = MathHelper.Lerp(
|
||||
// powerConsumption,
|
||||
// -Math.Min(maxOutput * chargeRate, gridLoad - (power)),
|
||||
// 0.1f);
|
||||
|
||||
//powerConsumption = Math.Min(powerConsumption, 0.0f);
|
||||
charge -= -currPowerConsumption / chargeRate / 3600.0f;
|
||||
}
|
||||
|
||||
voltage = 0.0f;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing)
|
||||
{
|
||||
base.Draw(spriteBatch);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(item.Rect.X + item.Rect.Width / 2 - 4, -item.Rect.Y + 9),
|
||||
new Vector2(8, 22), Color.Black);
|
||||
|
||||
if (charge > 0)
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Vector2(item.Rect.X + item.Rect.Width / 2 - 3, -item.Rect.Y + 10 + (20.0f * (1.0f - charge / capacity))),
|
||||
new Vector2(6, 20 * (charge / capacity)), Color.Green, true);
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
int width = 300, height = 200;
|
||||
int x = Game1.GraphicsWidth / 2 - width / 2;
|
||||
int y = Game1.GraphicsHeight / 2 - height / 2;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
|
||||
spriteBatch.DrawString(GUI.Font,
|
||||
"Charge: " + (int)charge + "/" + (int)capacity + " (" + (int)((charge / capacity) * 100.0f) + " %)",
|
||||
new Vector2(x + 30, y + 30), Color.White);
|
||||
|
||||
spriteBatch.DrawString(GUI.Font, "Recharge rate: " + (rechargeSpeed / maxRechargeSpeed), new Vector2(x + 30, y + 100), Color.White);
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 50, y + 150, 40, 40), "+", true))
|
||||
{
|
||||
item.NewComponentEvent(this, true);
|
||||
rechargeSpeed = Math.Min(rechargeSpeed + 10.0f, maxRechargeSpeed);
|
||||
}
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 150, 40, 40), "-", true))
|
||||
{
|
||||
rechargeSpeed = Math.Max(rechargeSpeed - 10.0f, 0.0f);
|
||||
item.NewComponentEvent(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
|
||||
{
|
||||
message.Write(rechargeSpeed);
|
||||
message.Write(charge);
|
||||
}
|
||||
|
||||
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
|
||||
{
|
||||
float newRechargeSpeed = 0.0f;
|
||||
float newCharge = 0.0f;
|
||||
|
||||
try
|
||||
{
|
||||
newRechargeSpeed = message.ReadFloat();
|
||||
newCharge = message.ReadFloat();
|
||||
}
|
||||
catch { }
|
||||
|
||||
RechargeSpeed = newRechargeSpeed;
|
||||
Charge = newCharge;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Subsurface.Items.Components
|
||||
{
|
||||
class PowerTransfer : Powered
|
||||
{
|
||||
static float fullPower;
|
||||
static float fullLoad;
|
||||
|
||||
//affects how fast changes in power/load are carried over the grid
|
||||
static float inertia = 5.0f;
|
||||
|
||||
static List<Powered> connectedList = new List<Powered>();
|
||||
|
||||
private float powerLoad;
|
||||
|
||||
public float PowerLoad
|
||||
{
|
||||
get { return powerLoad; }
|
||||
}
|
||||
|
||||
public PowerTransfer(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
//reset and recalculate the power generated/consumed
|
||||
//by the constructions connected to the grid
|
||||
fullPower = 0.0f;
|
||||
fullLoad = 0.0f;
|
||||
connectedList.Clear();
|
||||
|
||||
if (updated) return;
|
||||
|
||||
CheckJunctions(deltaTime);
|
||||
|
||||
foreach (Powered p in connectedList)
|
||||
{
|
||||
PowerTransfer pt = p as PowerTransfer;
|
||||
if (pt!=null)
|
||||
{
|
||||
pt.powerLoad += (fullLoad - pt.powerLoad) / inertia;
|
||||
pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia;
|
||||
pt.Item.SendSignal("", "power", fullPower / Math.Max(fullLoad, 1.0f));
|
||||
if (-pt.currPowerConsumption > Math.Max(pt.powerLoad * 2.0f, 200.0f)) pt.item.Condition -= deltaTime*10.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override bool Pick(Character picker)
|
||||
{
|
||||
if (picker == null) return false;
|
||||
|
||||
//picker.SelectedConstruction = (picker.SelectedConstruction == item) ? null : item;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//a recursive function that goes through all the junctions and adds up
|
||||
//all the generated/consumed power of the constructions connected to the grid
|
||||
private void CheckJunctions(float deltaTime)
|
||||
{
|
||||
updated = true;
|
||||
connectedList.Add(this);
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
List<Connection> connections = item.Connections;
|
||||
if (connections == null) return;
|
||||
|
||||
foreach (Connection c in connections)
|
||||
{
|
||||
foreach (Connection recipient in c.Recipients)
|
||||
{
|
||||
if (recipient == null) continue;
|
||||
|
||||
Item it = recipient.Item;
|
||||
if (it == null) continue;
|
||||
|
||||
//if (it.Updated) continue;
|
||||
|
||||
Powered powered = it.GetComponent<Powered>();
|
||||
if (powered == null || powered.Updated) continue;
|
||||
|
||||
PowerTransfer powerTransfer = powered as PowerTransfer;
|
||||
if (powerTransfer != null)
|
||||
{
|
||||
powerTransfer.CheckJunctions(deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectedList.Add(powered);
|
||||
//positive power consumption = the construction requires power -> increase load
|
||||
if (powered.CurrPowerConsumption > 0.0f)
|
||||
{
|
||||
fullLoad += powered.CurrPowerConsumption;
|
||||
}
|
||||
else if (powered.CurrPowerConsumption < 0.0f)
|
||||
//negative power consumption = the construction is a
|
||||
//generator/battery or another junction box
|
||||
{
|
||||
fullPower -= powered.CurrPowerConsumption;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
|
||||
GuiFrame.Draw(spriteBatch);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
|
||||
spriteBatch.DrawString(GUI.Font, "Power: " + (int)(-currPowerConsumption), new Vector2(x + 30, y + 30), Color.White);
|
||||
spriteBatch.DrawString(GUI.Font, "Load: " + (int)powerLoad, new Vector2(x + 30, y + 100), Color.White);
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power)
|
||||
{
|
||||
base.ReceiveSignal(signal, connection, sender, power);
|
||||
|
||||
if (connection.Name == "signal")
|
||||
{
|
||||
connection.SendSignal(signal, sender, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Subsurface.Items.Components
|
||||
{
|
||||
class Powered : ItemComponent
|
||||
{
|
||||
//the amount of power CURRENTLY consumed by the item
|
||||
//negative values mean that the item is providing power to connected items
|
||||
protected float currPowerConsumption;
|
||||
|
||||
//current voltage of the item (load / power)
|
||||
protected float voltage;
|
||||
|
||||
//the minimum voltage required for the item to work
|
||||
protected float minVoltage;
|
||||
|
||||
//the maximum amount of power the item can draw from connected items
|
||||
protected float powerConsumption;
|
||||
|
||||
private bool powerOnSoundPlayed;
|
||||
|
||||
private static Sound powerOnSound;
|
||||
|
||||
[Editable, HasDefaultValue(0.5f, true)]
|
||||
public float MinVoltage
|
||||
{
|
||||
get { return minVoltage; }
|
||||
set { minVoltage = value; }
|
||||
}
|
||||
|
||||
[Editable, HasDefaultValue(0.0f, true)]
|
||||
public float PowerConsumption
|
||||
{
|
||||
get { return powerConsumption; }
|
||||
set { powerConsumption = value; }
|
||||
}
|
||||
|
||||
|
||||
[HasDefaultValue(false,true)]
|
||||
public override bool IsActive
|
||||
{
|
||||
get { return isActive; }
|
||||
set
|
||||
{
|
||||
isActive = value;
|
||||
if (!isActive) currPowerConsumption = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
[HasDefaultValue(0.0f, true)]
|
||||
public float CurrPowerConsumption
|
||||
{
|
||||
get {return currPowerConsumption; }
|
||||
set { currPowerConsumption = value; }
|
||||
}
|
||||
|
||||
[HasDefaultValue(0.0f, true)]
|
||||
public float Voltage
|
||||
{
|
||||
get { return voltage; }
|
||||
set { voltage = Math.Max(0.0f, value); }
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power)
|
||||
{
|
||||
if (currPowerConsumption == 0.0f) voltage = 0.0f;
|
||||
if (connection.Name == "power_in" || connection.Name == "power") voltage = power;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (currPowerConsumption == 0.0f) return;
|
||||
if (voltage > minVoltage)
|
||||
{
|
||||
if (!powerOnSoundPlayed)
|
||||
{
|
||||
powerOnSound.Play(1.0f, 600.0f, item.Position);
|
||||
powerOnSoundPlayed = true;
|
||||
}
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime);
|
||||
}
|
||||
else if (voltage < 0.1f)
|
||||
{
|
||||
powerOnSoundPlayed = false;
|
||||
}
|
||||
}
|
||||
|
||||
public Powered(Item item, XElement element)
|
||||
: base(item, element)
|
||||
{
|
||||
if (powerOnSound==null)
|
||||
{
|
||||
powerOnSound = Sound.Load("Content/Items/Electricity/powerOn.ogg");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user