ItemComponent GUIFrames, functional steering, radar, separate power and signals, improved d.gz, tweak swimming

This commit is contained in:
Regalis
2015-06-29 23:51:01 +03:00
parent 004608acd8
commit b493ed2b39
42 changed files with 473 additions and 182 deletions
@@ -0,0 +1,203 @@
using System;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Subsurface.Items.Components
{
class PowerContainer : Powered
{
float capacity;
//[power/min]
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;
//public override float Charge
//{
// get { return charge; }
// set { Math.Max(Math.Min(charge = value, capacity), 0.0f); }
//}
[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 { charge = MathHelper.Clamp(value, 0.0f, capacity); }
}
[HasDefaultValue(10.0f, false)]
public float Capacity
{
get { return capacity; }
set { capacity = Math.Max(value,1.0f); }
}
//[HasDefaultValue(10.0f, false)]
//public float MaxInput
//{
// get { return maxInput; }
// set { maxInput = value; }
//}
[HasDefaultValue(10.0f, false)]
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, maxRechargeSpeed*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)
{
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))
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);
}
}
}
@@ -0,0 +1,151 @@
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));
}
else
{
//p.Power = fullPower;
}
}
}
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, item, 0.0f);
}
}
}
}
@@ -0,0 +1,80 @@
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;
//the amount of power available for the item through connected items
protected float voltage;
//the amount of power required for the item to work
protected float minVoltage;
//the maximum amount of power the item can draw from connected items
protected float powerConsumption;
[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 (connection.name=="power_in") voltage = power;
}
public override void Update(float deltaTime, Camera cam)
{
if (currPowerConsumption == 0.0f) return;
if (voltage > minVoltage) ApplyStatusEffects(ActionType.OnActive, deltaTime);
}
public Powered(Item item, XElement element)
: base(item, element)
{
//minVoltage = ToolBox.GetAttributeFloat(element, "minvoltage", 10.0f);
//powerConsumption = ToolBox.GetAttributeFloat(element, "powerconsumption", 15.0f);
}
}
}