Improved submarine movement (buoyancy & drag), engine and "navigation terminal", new map, optimized levels (less vertices and physics bodies)

This commit is contained in:
Regalis
2015-06-29 02:00:27 +03:00
parent 9237a9efe2
commit 004608acd8
43 changed files with 1199 additions and 527 deletions
+108
View File
@@ -0,0 +1,108 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Subsurface.Items.Components
{
class Engine : Powered
{
float force;
float targetForce;
float maxForce;
float powerPerForce;
[Editable, HasDefaultValue(1.0f, true)]
public float PowerPerForce
{
get { return powerPerForce; }
set
{
powerPerForce = Math.Max(0.0f, value);
}
}
[Editable, HasDefaultValue(50000.0f, true)]
public float MaxForce
{
get { return maxForce; }
set
{
maxForce = Math.Max(0.0f, value);
}
}
public float Force
{
get { return force;}
set { force = MathHelper.Clamp(value, -100.0f, 100.0f); }
}
public Engine(Item item, XElement element)
: base(item, element)
{
isActive = true;
}
public override void Update(float deltaTime, Camera cam)
{
base.Update(deltaTime, cam);
currPowerConsumption = Math.Abs(targetForce) * powerPerForce;
Force = MathHelper.Lerp(force, (voltage < minVoltage) ? 0.0f : targetForce, 0.1f);
if (Force != 0.0f)
{
Submarine.Loaded.ApplyForce(new Vector2((force / 100.0f) * maxForce * (voltage / minVoltage), 0.0f));
}
voltage = 0.0f;
}
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
{
//isActive = true;
int width = 300, height = 300;
int x = Game1.GraphicsWidth / 2 - width / 2;
int y = Game1.GraphicsHeight / 2 - height / 2 - 50;
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
spriteBatch.DrawString(GUI.font, "Force: " + (int)targetForce+" %", new Vector2(x + 30, y + 30), Color.White);
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 30, 40, 40), "+", true)) targetForce += 1.0f;
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 80, 40, 40), "-", true)) targetForce -= 1.0f;
item.NewComponentEvent(this, true);
}
public override void UpdateBroken(float deltaTime, Camera cam)
{
force = MathHelper.Lerp(force, 0.0f, 0.1f);
}
public override void ReceiveSignal(string signal, Connection connection, Item sender)
{
base.ReceiveSignal(signal, connection, sender);
if (connection.name == "set_force")
{
float tempForce;
if (float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out tempForce))
{
Force = tempForce;
}
}
}
}
}
+20 -8
View File
@@ -1,14 +1,16 @@
using System.Collections.Specialized;
using Microsoft.Xna.Framework;
using System.Collections.Specialized;
using System.Globalization;
using System.Xml.Linq;
namespace Subsurface.Items.Components
{
class Pump : Powered
{
float flow;
float flowPercentage;
float maxFlow;
bool flowIn;
//bool flowIn;
Hull hull1, hull2;
@@ -37,9 +39,9 @@ namespace Subsurface.Items.Components
if (hull2 == null && hull1 == null) return;
float powerFactor = (currPowerConsumption==0.0f) ? 1.0f : voltage;
flow = maxFlow * powerFactor;
//flowPercentage = maxFlow * powerFactor;
float deltaVolume = flow * ((flowIn) ? 1.0f : -1.0f);
float deltaVolume = (flowPercentage/100.0f) * maxFlow * powerFactor;
hull1.Volume += deltaVolume;
if (hull2 != null) hull2.Volume -= deltaVolume;
@@ -139,21 +141,31 @@ namespace Subsurface.Items.Components
{
isActive = !isActive;
}
else if (connection.name == "set_state")
else if (connection.name == "set_active")
{
isActive = (signal != "0");
}
else if (connection.name == "set_speed")
{
float tempSpeed;
if (float.TryParse(signal, NumberStyles.Float, CultureInfo.InvariantCulture, out tempSpeed))
{
flowPercentage = MathHelper.Clamp(flowPercentage, -100.0f, 100.0f);
}
}
}
public override void FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetOutgoingMessage message)
{
message.Write(flowIn);
message.Write(flowPercentage);
message.Write(isActive);
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message)
{
flowIn = message.ReadBoolean();
flowPercentage = message.ReadFloat();
isActive = message.ReadBoolean();
}
}
+25 -9
View File
@@ -141,16 +141,34 @@ namespace Subsurface.Items.Components
}
else if (autoTemp)
{
float load = 0.0f;
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;
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;
@@ -319,8 +337,6 @@ namespace Subsurface.Items.Components
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 450, y + 180, 40, 40), "-", true)) shutDownTemp -= 100.0f;
item.NewComponentEvent(this, true);
}
static void UpdateGraph<T>(IList<T> graph, T newValue)
+1 -1
View File
@@ -269,7 +269,7 @@ namespace Subsurface.Items.Components
spriteBatch.Draw(sprite.Texture,
ConvertUnits.ToDisplayUnits(start), null, Color.White,
ToolBox.VectorToAngle(end - start),
MathUtils.VectorToAngle(end - start),
new Vector2(0.0f, sprite.size.Y / 2.0f),
new Vector2((ConvertUnits.ToDisplayUnits(Vector2.Distance(start, end))) / sprite.Texture.Width, 1.0f),
SpriteEffects.None,
@@ -175,9 +175,22 @@ namespace Subsurface.Items.Components
bool mouseInRect = panelRect.Contains(PlayerInput.MousePosition);
Wire equippedWire = null;
//if the character using the panel has a wire item equipped
//and the wire hasn't been connected yet, draw it on the panel
for (int i = 0; i < character.SelectedItems.Length; i++)
{
Item selectedItem = character.SelectedItems[i];
if (selectedItem == null) continue;
Wire wireComponent = selectedItem.GetComponent<Wire>();
if (wireComponent != null) equippedWire = wireComponent;
}
Vector2 rightPos = new Vector2(x + width - 110, y + 20);
Vector2 leftPos = new Vector2(x + 110, y + 20);
float wireInterval = 10.0f;
float rightWireX = x+width / 2 + wireInterval;
@@ -199,8 +212,9 @@ namespace Subsurface.Items.Components
if (c.isOutput)
{
c.Draw(spriteBatch, panel.Item, rightPos,
new Vector2(rightPos.X + 20, rightPos.Y),
new Vector2(rightWireX, y + height), mouseInRect);
new Vector2(rightPos.X + 20, rightPos.Y),
new Vector2(rightWireX, y + height),
mouseInRect, equippedWire != null);
rightPos.Y += 30;
rightWireX += wireInterval;
@@ -209,59 +223,41 @@ namespace Subsurface.Items.Components
{
c.Draw(spriteBatch, panel.Item, leftPos,
new Vector2(leftPos.X - 100, leftPos.Y),
new Vector2(leftWireX, y + height), mouseInRect);
new Vector2(leftWireX, y + height),
mouseInRect, equippedWire != null);
leftPos.Y += 30;
leftWireX -= wireInterval;
}
}
//draw a wire for all the items that are linked to this item, but not to any of the signal connections
//foreach (MapEntity entity in panel.Item.linkedTo)
//{
// Item linked = entity as Item;
// if (linked == null) continue;
// //if the item is already connected, don't draw it again
// if (panel.connections.Find(c => c.linked.Contains()) != null) continue;
// DrawWire(spriteBatch, false, linked,
// new Vector2(leftPos.X + (leftPos.Y - y), y + height- 50),
// new Vector2(leftPos.X + (leftPos.Y - y), y + height), mouseInRect);
// leftPos.Y += 30.0f;
//}
//if the character using the panel has a wire item equipped
//and the wire hasn't been connected yet, draw it on the panel
for (int i = 0; i < character.SelectedItems.Length; i++ )
if (equippedWire!=null)
{
Item selectedItem = character.SelectedItems[i];
if (selectedItem == null) continue;
Wire wireComponent = selectedItem.GetComponent<Wire>();
if (wireComponent != null &&
panel.connections.Find(c => c.wires.Contains(wireComponent)) == null)
if (panel.connections.Find(c => c.wires.Contains(equippedWire)) == null)
{
DrawWire(spriteBatch, selectedItem, selectedItem,
DrawWire(spriteBatch, equippedWire.Item, equippedWire.Item,
new Vector2(x + width / 2, y + height - 100),
new Vector2(x + width / 2, y + height), mouseInRect);
new Vector2(x + width / 2, y + height), mouseInRect, false);
if (draggingConnected == selectedItem) Inventory.draggingItem = selectedItem;
if (draggingConnected == equippedWire.Item) Inventory.draggingItem = equippedWire.Item;
break;
//break;
}
}
//for (int i = 0; i < character.SelectedItems.Length; i++ )
//{
// Item selectedItem = character.SelectedItems[i];
// if (selectedItem == null) continue;
// Wire wireComponent = selectedItem.GetComponent<Wire>();
//}
//stop dragging a wire item if cursor is outside the panel
if (mouseInRect) Inventory.draggingItem = null;
@@ -275,7 +271,7 @@ namespace Subsurface.Items.Components
}
}
private void Draw(SpriteBatch spriteBatch, Item item, Vector2 position, Vector2 labelPos, Vector2 wirePosition, bool mouseIn)
private void Draw(SpriteBatch spriteBatch, Item item, Vector2 position, Vector2 labelPos, Vector2 wirePosition, bool mouseIn, bool wireEquipped)
{
spriteBatch.DrawString(GUI.font, name, new Vector2(labelPos.X, labelPos.Y-10), Color.White);
@@ -289,7 +285,7 @@ namespace Subsurface.Items.Components
Connection recipient = wires[i].OtherConnection(this);
DrawWire(spriteBatch, wires[i].Item, (recipient == null) ? wires[i].Item : recipient.item, position, wirePosition, mouseIn);
DrawWire(spriteBatch, wires[i].Item, (recipient == null) ? wires[i].Item : recipient.item, position, wirePosition, mouseIn, wireEquipped);
wirePosition.X += (isOutput) ? -20 : 20;
}
@@ -318,6 +314,9 @@ namespace Subsurface.Items.Components
if (index>-1)
{
wires[index].RemoveConnection(this);
wires[index].Item.SetTransform(item.SimPosition, 0.0f);
wires[index].Item.Drop();
wires[index].Item.body.Enabled = true;
wires[index] = null;
}
}
@@ -326,7 +325,7 @@ namespace Subsurface.Items.Components
}
private static void DrawWire(SpriteBatch spriteBatch, Item wireItem, Item item, Vector2 end, Vector2 start, bool mouseIn)
private static void DrawWire(SpriteBatch spriteBatch, Item wireItem, Item item, Vector2 end, Vector2 start, bool mouseIn, bool wireEquipped)
{
if (draggingConnected == wireItem)
{
@@ -339,27 +338,29 @@ namespace Subsurface.Items.Components
int textX = (int)start.X;
float connLength = 10.0f;
Color color = (wireEquipped) ? Color.Gray : Color.White;
if (Math.Abs(end.X-start.X)<connLength*6.0f)
{
wireVertical.DrawTiled(spriteBatch,
new Vector2(end.X - wireVertical.size.X / 2, end.Y + connLength),
new Vector2(wireVertical.size.X, (float)Math.Abs(end.Y - start.Y)), Color.White);
new Vector2(wireVertical.size.X, (float)Math.Abs(end.Y - start.Y)), color);
textX = (int)end.X;
connector.Draw(spriteBatch, end);
connector.Draw(spriteBatch, end, color);
}
else
{
Vector2 pos = new Vector2(start.X, end.Y + wireCorner.size.Y) - wireVertical.size / 2;
Vector2 size = new Vector2(wireVertical.size.X, (float)Math.Abs((end.Y + wireCorner.size.Y) - start.Y));
wireVertical.DrawTiled(spriteBatch, pos, size, Color.White);
wireVertical.DrawTiled(spriteBatch, pos, size, color);
Rectangle rect = new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
if (rect.Contains(PlayerInput.MousePosition)) mouseOn = true;
if (!wireEquipped && rect.Contains(PlayerInput.MousePosition)) mouseOn = true;
float dir = (end.X > start.X) ? -1.0f : 1.0f;
wireCorner.Draw(spriteBatch,
new Vector2(start.X, end.Y), 0.0f, 1.0f,
new Vector2(start.X, end.Y), color, 0.0f, 1.0f,
(end.X > start.X) ? SpriteEffects.None : SpriteEffects.FlipHorizontally);
float wireStartX = start.X - wireCorner.size.X / 2 * dir;
@@ -368,14 +369,14 @@ namespace Subsurface.Items.Components
pos = new Vector2(Math.Min(wireStartX,wireEndX), end.Y - wireVertical.size.Y / 2);
size = new Vector2(Math.Abs(wireStartX - wireEndX), wireHorizontal.size.Y);
wireHorizontal.DrawTiled(spriteBatch, pos, size, Color.White);
wireHorizontal.DrawTiled(spriteBatch, pos, size, color);
rect = new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
if (rect.Contains(PlayerInput.MousePosition)) mouseOn = true;
if (!wireEquipped && rect.Contains(PlayerInput.MousePosition)) mouseOn = true;
connector.Draw(spriteBatch, end, -MathHelper.PiOver2*dir);
connector.Draw(spriteBatch, end, color, -MathHelper.PiOver2*dir);
}
if (draggingConnected == null)
if (draggingConnected == null && !wireEquipped)
{
if (mouseOn || Vector2.Distance(end, PlayerInput.MousePosition)<20.0f)
{
@@ -387,7 +388,7 @@ namespace Subsurface.Items.Components
spriteBatch.DrawString(GUI.font, item.Name,
new Vector2(textX, start.Y-30),
mouseOn ? Color.Gold : Color.White,
(mouseOn && !wireEquipped) ? Color.Gold : Color.White,
MathHelper.PiOver2,
GUI.font.MeasureString(item.Name)*0.5f,
1.0f, SpriteEffects.None, 0.0f);
@@ -431,7 +432,6 @@ namespace Subsurface.Items.Components
Item wireItem = MapEntity.FindEntityByID(wireId[i]) as Item;
if (wireItem == null) continue;
wires[i] = wireItem.GetComponent<Wire>();
if (wires[i]!=null)
+4 -4
View File
@@ -122,15 +122,15 @@ namespace Subsurface.Items.Components
item.FindHull();
Vector2 position = item.Position;
position.X = ToolBox.Round(item.Position.X, nodeDistance);
position.X = MathUtils.Round(item.Position.X, nodeDistance);
if (item.currentHull == null)
{
position.Y = ToolBox.Round(item.Position.Y, nodeDistance);
position.Y = MathUtils.Round(item.Position.Y, nodeDistance);
}
else
{
position.Y -= item.currentHull.Rect.Y - item.currentHull.Rect.Height;
position.Y = Math.Max(ToolBox.Round(position.Y, nodeDistance), heightFromFloor);
position.Y = Math.Max(MathUtils.Round(position.Y, nodeDistance), heightFromFloor);
position.Y += item.currentHull.Rect.Y - item.currentHull.Rect.Height;
}
@@ -258,7 +258,7 @@ namespace Subsurface.Items.Components
spriteBatch.Draw(wireSprite.Texture,
start, null, color,
ToolBox.VectorToAngle(end - start),
MathUtils.VectorToAngle(end - start),
new Vector2(0.0f, wireSprite.size.Y / 2.0f),
new Vector2((Vector2.Distance(start, end)) / wireSprite.Texture.Width, 0.3f),
SpriteEffects.None,
+84
View File
@@ -0,0 +1,84 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Subsurface.Items.Components
{
class Steering : ItemComponent
{
Vector2 currVelocity;
Vector2 targetVelocity;
public Steering(Item item, XElement element)
: base(item, element)
{
isActive = true;
}
public override void Update(float deltaTime, Camera cam)
{
base.Update(deltaTime, cam);
item.SendSignal(targetVelocity.X.ToString(), "velocity_x_out", item);
item.SendSignal(targetVelocity.Y.ToString(), "velocity_y_out", item);
}
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
{
//isActive = true;
int width = 300, height = 300;
int x = Game1.GraphicsWidth / 2 - width / 2;
int y = Game1.GraphicsHeight / 2 - height / 2 - 50;
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
Rectangle velRect = new Rectangle(x+20, y+20, 100, 100);
GUI.DrawRectangle(spriteBatch, velRect, Color.White, false);
GUI.DrawLine(spriteBatch,
new Vector2(velRect.Center.X,velRect.Center.Y),
new Vector2(velRect.Center.X + currVelocity.X, velRect.Center.Y - currVelocity.Y),
Color.Gray);
Vector2 targetVelPos = new Vector2(velRect.Center.X + targetVelocity.X, velRect.Center.Y - targetVelocity.Y);
GUI.DrawLine(spriteBatch,
new Vector2(velRect.Center.X, velRect.Center.Y),
targetVelPos,
Color.LightGray);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)targetVelPos.X - 5, (int)targetVelPos.Y - 5, 10, 10), Color.White);
if (Vector2.Distance(PlayerInput.MousePosition, targetVelPos)<10.0f)
{
GUI.DrawRectangle(spriteBatch, new Rectangle((int)targetVelPos.X -10, (int)targetVelPos.Y - 10, 20, 20), Color.Red);
if (PlayerInput.LeftButtonDown())
{
targetVelocity = PlayerInput.MousePosition - new Vector2(velRect.Center.X, velRect.Center.Y);
targetVelocity.Y = -targetVelocity.Y;
}
}
//spriteBatch.DrawString(GUI.font, "Force: " + (int)force + " %", new Vector2(x + 30, y + 30), Color.White);
//if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 30, 40, 40), "+", true)) targetForce += 1.0f;
//if (GUI.DrawButton(spriteBatch, new Rectangle(x + 280, y + 80, 40, 40), "-", true)) targetForce -= 1.0f;
item.NewComponentEvent(this, true);
}
public override void ReceiveSignal(string signal, Connection connection, Item sender)
{
if (connection.name == "velocity_in")
{
currVelocity = ToolBox.ParseToVector2(signal, false);
}
}
}
}
+3 -3
View File
@@ -112,11 +112,11 @@ namespace Subsurface.Items.Components
if (targetRotation < minRotation || targetRotation > maxRotation)
{
float diff = ToolBox.WrapAngleTwoPi(targetRotation - (minRotation + maxRotation) / 2.0f);
float diff = MathUtils.WrapAngleTwoPi(targetRotation - (minRotation + maxRotation) / 2.0f);
targetRotation = (diff > Math.PI) ? minRotation : maxRotation;
}
rotation = ToolBox.CurveAngle(rotation, targetRotation, 0.05f);
rotation = MathUtils.CurveAngle(rotation, targetRotation, 0.05f);
//if (!prefab.FocusOnSelected) return;
@@ -131,7 +131,7 @@ namespace Subsurface.Items.Components
Vector2 offset = character.CursorPosition - centerPos;
offset.Y = -offset.Y;
targetRotation = ToolBox.WrapAngleTwoPi(ToolBox.VectorToAngle(offset));
targetRotation = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(offset));
isActive = true;