Turret rotation fix, CharacterInventory networking bugfixes, prevent limbs clipping with other colliders when mirroring, fixed mantis animations, better looking explosions, spark effect when overvoltage breaks an item

This commit is contained in:
Regalis
2015-09-04 21:56:39 +03:00
parent 2f08dcf3f9
commit 0cbcdd0b03
35 changed files with 393 additions and 262 deletions
@@ -12,36 +12,39 @@ namespace Subsurface.Items.Components
{
//the rate at which the reactor is being run un
//higher rates generate more power (and heat)
float fissionRate;
private float fissionRate;
//the rate at which the heat is being dissipated
float coolingRate;
private float coolingRate;
float temperature;
private float temperature;
//is automatic temperature control on
//(adjusts the cooling rate automatically to keep the
//amount of power generated balanced with the load)
bool autoTemp;
private bool autoTemp;
//the temperature after which fissionrate is automatically
//turned down and cooling increased
float shutDownTemp;
private float shutDownTemp;
float meltDownTemp;
private float meltDownTemp;
//how much power is provided to the grid per 1 temperature unit
float powerPerTemp;
private float powerPerTemp;
int graphSize = 25;
private int graphSize = 25;
float graphTimer;
private float graphTimer;
int updateGraphInterval = 500;
private int updateGraphInterval = 500;
float[] fissionRateGraph;
float[] coolingRateGraph;
float[] tempGraph;
private float[] fissionRateGraph;
private float[] coolingRateGraph;
private float[] tempGraph;
private float[] loadGraph;
private float load;
private PropertyTask powerUpTask;
@@ -118,9 +121,10 @@ namespace Subsurface.Items.Components
public Reactor(Item item, XElement element)
: base(item, element)
{
fissionRateGraph = new float[graphSize];
coolingRateGraph = new float[graphSize];
tempGraph = new float[graphSize];
fissionRateGraph = new float[graphSize];
coolingRateGraph = new float[graphSize];
tempGraph = new float[graphSize];
loadGraph = new float[graphSize];
meltDownTemp = 9000.0f;
@@ -155,6 +159,24 @@ namespace Subsurface.Items.Components
powerUpTask = new PropertyTask(item, IsRunning, 50.0f, "Power up the reactor");
}
}
load = 0.0f;
List<Connection> connections = item.Connections;
if (connections != null && connections.Count > 0)
{
foreach (Connection connection in connections)
{
foreach (Connection recipient in connection.Recipients)
{
Item it = recipient.Item as Item;
if (it == null) continue;
PowerTransfer pt = it.GetComponent<PowerTransfer>();
if (pt != null) load += pt.PowerLoad;
}
}
}
//item.Condition -= temperature * deltaTime * 0.00005f;
@@ -165,34 +187,6 @@ namespace Subsurface.Items.Components
}
else if (autoTemp)
{
float load = 0.0f;
List<Connection> connections = item.Connections;
if (connections!=null && connections.Count>0)
{
foreach (Connection connection in connections)
{
foreach (Connection recipient in connection.Recipients)
{
Item it = recipient.Item as Item;
if (it == null) continue;
PowerTransfer pt = it.GetComponent<PowerTransfer>();
if (pt != null) load += 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) load += pt.PowerLoad;
//}
fissionRate = Math.Min(load / 200.0f, shutDownTemp);
//float target = Math.Min(targetTemp, load);
CoolingRate = coolingRate + (temperature - Math.Min(load, shutDownTemp) + deltaTemp)*0.1f;
@@ -247,6 +241,9 @@ namespace Subsurface.Items.Components
UpdateGraph(fissionRateGraph, fissionRate);
UpdateGraph(coolingRateGraph, coolingRate);
UpdateGraph(tempGraph, temperature);
UpdateGraph(loadGraph, load);
graphTimer = 0.0f;
}
}
@@ -304,62 +301,73 @@ namespace Subsurface.Items.Components
//GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
spriteBatch.DrawString(GUI.Font, "Temperature: " + (int)temperature + " C", new Vector2(x + 30, y + 30), Color.White);
DrawGraph(tempGraph, spriteBatch, x + 30, y + 50, 10000.0f, xOffset);
spriteBatch.DrawString(GUI.Font, "Temperature: " + (int)temperature + " C",
new Vector2(x + 450, y + 30), Color.Red);
spriteBatch.DrawString(GUI.Font, "Grid load: " + (int)load + " C",
new Vector2(x + 620, y + 30), Color.Yellow);
y += 130;
DrawGraph(tempGraph, spriteBatch,
new Rectangle(x + 30, y + 30, 400, 250), 10000.0f, xOffset, Color.Red);
spriteBatch.DrawString(GUI.Font, "Fission rate: " + (int)fissionRate + " %", new Vector2(x + 30, y + 30), Color.White);
DrawGraph(fissionRateGraph, spriteBatch, x + 30, y + 50, 100.0f, xOffset);
DrawGraph(loadGraph, spriteBatch,
new Rectangle(x + 30, y + 30, 400, 250), 10000.0f, xOffset, Color.Yellow);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 30, 40, 40), "+", true))
spriteBatch.DrawString(GUI.Font, "Shutdown Temperature: " + shutDownTemp, new Vector2(x + 450, y + 80), Color.White);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 110, 40, 40), "+", true))
{
valueChanged = true;
FissionRate += 1.0f;
ShutDownTemp += 100.0f;
}
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 80, 40, 40), "-", true))
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 500, y + 110, 40, 40), "-", true))
{
valueChanged = true;
FissionRate -= 1.0f;
ShutDownTemp -= 100.0f;
}
y += 130;
spriteBatch.DrawString(GUI.Font, "Cooling rate: " + (int)coolingRate + " %", new Vector2(x + 30, y + 30), Color.White);
DrawGraph(coolingRateGraph, spriteBatch, x + 30, y + 50, 100.0f, xOffset);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 30, 40, 40), "+", true))
{
valueChanged = true;
CoolingRate += 1.0f;
}
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 80, 40, 40), "-", true))
{
valueChanged = true;
CoolingRate -= 1.0f;
}
y = y - 260;
spriteBatch.DrawString(GUI.Font, "Automatic Temperature Control: " + ((autoTemp) ? "ON" : "OFF"), new Vector2(x + 400, y + 30), Color.White);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 60, 100, 40), ((autoTemp) ? "TURN OFF" : "TURN ON")))
spriteBatch.DrawString(GUI.Font, "Automatic Temperature Control: " + ((autoTemp) ? "ON" : "OFF"), new Vector2(x + 450, y + 180), Color.White);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 210, 100, 40), ((autoTemp) ? "TURN OFF" : "TURN ON")))
{
valueChanged = true;
autoTemp = !autoTemp;
}
spriteBatch.DrawString(GUI.Font, "Shutdown Temperature: " + shutDownTemp, new Vector2(x + 400, y + 150), Color.White);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 400, y + 180, 40, 40), "+", true))
y += 300;
spriteBatch.DrawString(GUI.Font, "Fission rate: " + (int)fissionRate + " %", new Vector2(x + 30, y), Color.White);
DrawGraph(fissionRateGraph, spriteBatch,
new Rectangle(x + 30, y + 30, 200, 100), 100.0f, xOffset, Color.Orange);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 30, 40, 40), "+", true))
{
valueChanged = true;
ShutDownTemp += 100.0f;
FissionRate += 1.0f;
}
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 180, 40, 40), "-", true))
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 80, 40, 40), "-", true))
{
valueChanged = true;
ShutDownTemp -= 100.0f;
FissionRate -= 1.0f;
}
spriteBatch.DrawString(GUI.Font, "Cooling rate: " + (int)coolingRate + " %", new Vector2(x + 320, y), Color.White);
DrawGraph(coolingRateGraph, spriteBatch,
new Rectangle(x + 320, y + 30, 200, 100), 100.0f, xOffset, Color.LightBlue);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 540, y + 30, 40, 40), "+", true))
{
valueChanged = true;
CoolingRate += 1.0f;
}
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 540, y + 80, 40, 40), "-", true))
{
valueChanged = true;
CoolingRate -= 1.0f;
}
//y = y - 260;
if (valueChanged)
{
item.NewComponentEvent(this, true);
@@ -376,35 +384,32 @@ namespace Subsurface.Items.Components
graph[0] = newValue;
}
static void DrawGraph(IList<float> graph, SpriteBatch spriteBatch, int x, int y, float maxVal, float xOffset)
static void DrawGraph(IList<float> graph, SpriteBatch spriteBatch, Rectangle rect, float maxVal, float xOffset, Color color)
{
int width = 200;
int height = 100;
float lineWidth = (float)rect.Width / (float)(graph.Count - 2);
float yScale = (float)rect.Height / maxVal;
float lineWidth = (float)width / (float)(graph.Count - 2);
float yScale = (float)height / maxVal;
GUI.DrawRectangle(spriteBatch, rect, Color.White);
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.White);
Vector2 prevPoint = new Vector2(rect.Right, rect.Bottom - (graph[1] + (graph[0] - graph[1]) * xOffset) * yScale);
Vector2 prevPoint = new Vector2(x + width, y + height - (graph[1] + (graph[0] - graph[1]) * xOffset) * yScale);
float currX = x + width - ((xOffset - 1.0f) * lineWidth);
float currX = rect.Right - ((xOffset - 1.0f) * lineWidth);
for (int i = 1; i < graph.Count - 1; i++)
{
currX -= lineWidth;
Vector2 newPoint = new Vector2(currX, y + height - graph[i] * yScale);
Vector2 newPoint = new Vector2(currX, rect.Bottom - graph[i] * yScale);
GUI.DrawLine(spriteBatch, prevPoint, newPoint, Color.White);
GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color);
prevPoint = newPoint;
}
Vector2 lastPoint = new Vector2(x,
y + height - (graph[graph.Count - 1] + (graph[graph.Count - 2] - graph[graph.Count - 1]) * xOffset) * yScale);
Vector2 lastPoint = new Vector2(rect.X,
rect.Bottom - (graph[graph.Count - 1] + (graph[graph.Count - 2] - graph[graph.Count - 1]) * xOffset) * yScale);
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, Color.White);
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
}
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power)
@@ -45,13 +45,34 @@ namespace Subsurface.Items.Components
foreach (Powered p in connectedList)
{
PowerTransfer pt = p as PowerTransfer;
if (pt!=null)
if (pt == null) continue;
pt.powerLoad += (fullLoad - pt.powerLoad) / inertia;
pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia;
pt.Item.SendSignal("", "power", fullPower / Math.Max(fullLoad, 1.0f));
//damage the item if voltage is too high
if (-pt.currPowerConsumption > Math.Max(pt.powerLoad * 2.0f, 200.0f))
{
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;
float prevCondition = pt.item.Condition;
pt.item.Condition -= deltaTime * 10.0f;
if (pt.item.Condition<=0.0f && prevCondition > 0.0f)
{
sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 600.0f, item.Position);
Vector2 baseVel = Rand.Vector(3.0f);
for (int i = 0; i < 10; i++)
{
var particle = Game1.ParticleManager.CreateParticle("spark", pt.item.SimPosition,
baseVel + Rand.Vector(1.0f), 0.0f);
if (particle != null) particle.Size *= Rand.Range(0.5f,1.0f);
}
}
}
}
@@ -135,7 +156,7 @@ namespace Subsurface.Items.Components
{
base.ReceiveSignal(signal, connection, sender, power);
if (connection.Name.Length>5 && connection.Name.Substring(0, 6).ToLower() == "signal")
if (connection.Name.Length > 5 && connection.Name.Substring(0, 6).ToLower() == "signal")
{
connection.SendSignal(signal, sender, 0.0f);
}
@@ -1,11 +1,15 @@
using System;
using System.Globalization;
using System.IO;
using System.Xml.Linq;
namespace Subsurface.Items.Components
{
class Powered : ItemComponent
{
protected static Sound[] sparkSounds;
//the amount of power CURRENTLY consumed by the item
//negative values mean that the item is providing power to connected items
protected float currPowerConsumption;
@@ -63,6 +67,25 @@ namespace Subsurface.Items.Components
set { voltage = Math.Max(0.0f, value); }
}
public Powered(Item item, XElement element)
: base(item, element)
{
if (powerOnSound == null)
{
powerOnSound = Sound.Load("Content/Items/Electricity/powerOn.ogg");
}
if (sparkSounds == null)
{
sparkSounds = new Sound[4];
string dir = Path.GetDirectoryName(item.Prefab.ConfigFile) + "\\";
for (int i = 0; i < 4; i++)
{
sparkSounds[i] = Sound.Load("Content/Items/Electricity/zap" + (i + 1) + ".ogg");
}
}
}
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power)
{
if (currPowerConsumption == 0.0f) voltage = 0.0f;
@@ -87,13 +110,6 @@ namespace Subsurface.Items.Components
}
}
public Powered(Item item, XElement element)
: base(item, element)
{
if (powerOnSound==null)
{
powerOnSound = Sound.Load("Content/Items/Electricity/powerOn.ogg");
}
}
}
}
@@ -162,9 +162,11 @@ namespace Subsurface.Items.Components
ignoredBodies.Clear();
f2.Body.ApplyLinearImpulse(item.body.LinearVelocity * item.body.Mass);
if (attackResult.HitArmor)
{
item.body.LinearVelocity *= 0.5f;
item.body.LinearVelocity *= 0.1f;
}
else if (doesStick)
{
@@ -175,7 +177,10 @@ namespace Subsurface.Items.Components
if (Vector2.Dot(f1.Body.LinearVelocity, normal) < 0.0f) return StickToTarget(f2.Body, dir);
}
else
{
item.body.LinearVelocity *= 0.5f;
}
var containedItems = item.ContainedItems;
if (containedItems == null) return true;
@@ -188,7 +193,7 @@ namespace Subsurface.Items.Components
contained.Condition = 0.0f;
}
return true;
return false;
}
private bool StickToTarget(Body targetBody, Vector2 axis)
@@ -10,7 +10,6 @@ namespace Subsurface.Items.Components
{
class LightComponent : Powered
{
static Sound[] sparkSounds;
private Color lightColor;
@@ -67,16 +66,6 @@ namespace Subsurface.Items.Components
public LightComponent(Item item, XElement element)
: base (item, element)
{
if (sparkSounds==null)
{
sparkSounds = new Sound[4];
string dir = Path.GetDirectoryName(item.Prefab.ConfigFile)+"\\";
for (int i = 0; i<4; i++)
{
sparkSounds[i] = Sound.Load("Content/Items/Electricity/zap"+(i+1)+".ogg");
}
}
//foreach (XElement subElement in element.Elements())
//{
// if (subElement.Name.ToString().ToLower() != "sprite") continue;
+24 -5
View File
@@ -88,17 +88,36 @@ namespace Subsurface.Items.Components
{
this.cam = cam;
if (reload>0.0f) reload -= deltaTime;
if (reload > 0.0f) reload -= deltaTime;
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
if (targetRotation < minRotation || targetRotation > maxRotation)
float targetMidDiff = MathHelper.WrapAngle(targetRotation - (minRotation + maxRotation) / 2.0f);
float maxDist = (maxRotation - minRotation) / 2.0f;
if (Math.Abs(targetMidDiff) > maxDist)
{
float diff = MathUtils.WrapAngleTwoPi(targetRotation - (minRotation + maxRotation) / 2.0f);
targetRotation = (diff > Math.PI) ? minRotation : maxRotation;
targetRotation = (targetMidDiff < 0.0f) ? minRotation : maxRotation;
}
float deltaRotation = MathHelper.WrapAngle(targetRotation-rotation);
deltaRotation = MathHelper.Clamp(deltaRotation, -0.5f, 0.5f) * 5.0f;
rotation += deltaRotation * deltaTime;
float rotMidDiff = MathHelper.WrapAngle(rotation - (minRotation + maxRotation) / 2.0f);
if (rotMidDiff < -maxDist)
{
rotation = minRotation;
}
else if (rotMidDiff > maxDist)
{
rotation = maxRotation;
}
rotation = MathUtils.CurveAngle(rotation, targetRotation, 0.05f);
}
public override bool Use(float deltaTime, Character character = null)