Merge branch 'multisub'

Conflicts:
	.gitignore
	Subsurface/Source/Characters/Animation/HumanoidAnimController.cs
	Subsurface/Source/Items/Components/Holdable/RepairTool.cs
	Subsurface_Solution.v12.suo
This commit is contained in:
Regalis
2016-07-04 17:42:31 +03:00
87 changed files with 2496 additions and 750 deletions
@@ -0,0 +1,471 @@
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Joints;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
class DockingPort : ItemComponent, IDrawableComponent
{
public static List<DockingPort> list = new List<DockingPort>();
private Sprite overlaySprite;
private Vector2 distanceTolerance;
private DockingPort dockingTarget;
private float dockingState;
private int dockingDir;
private Joint joint;
private Hull[] hulls;
private Body[] bodies;
private Gap gap;
private bool docked;
[HasDefaultValue("32.0,32.0", false)]
public string DistanceTolerance
{
get { return ToolBox.Vector2ToString(distanceTolerance); }
set { distanceTolerance = ToolBox.ParseToVector2(value); }
}
[HasDefaultValue(32.0f, false)]
public float DockedDistance
{
get;
set;
}
[HasDefaultValue(true, false)]
public bool IsHorizontal
{
get;
set;
}
public bool Docked
{
get
{
return docked;
}
set
{
if (!docked && value)
{
if (dockingTarget == null) AttemptDock();
if (dockingTarget == null) return;
docked = true;
}
else if (docked && !value)
{
Undock();
}
//base.IsActive = value;
}
}
public DockingPort(Item item, XElement element)
: base(item, element)
{
// isOpen = false;
foreach (XElement subElement in element.Elements())
{
string texturePath = ToolBox.GetAttributeString(subElement, "texture", "");
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "sprite":
overlaySprite = new Sprite(subElement, texturePath.Contains("/") ? "" : Path.GetDirectoryName(item.Prefab.ConfigFile));
break;
}
}
IsActive = true;
list.Add(this);
}
private DockingPort FindAdjacentPort()
{
foreach (DockingPort port in list)
{
if (port == this || port.item.Submarine == item.Submarine) continue;
if (Math.Abs(port.item.WorldPosition.X - item.WorldPosition.X) > distanceTolerance.X) continue;
if (Math.Abs(port.item.WorldPosition.Y - item.WorldPosition.Y) > distanceTolerance.Y) continue;
return port;
}
return null;
}
private void AttemptDock()
{
var adjacentPort = FindAdjacentPort();
if (adjacentPort != null) Dock(adjacentPort);
}
public void Dock(DockingPort target)
{
if (dockingTarget != null)
{
Undock();
}
PlaySound(ActionType.OnUse, item.WorldPosition);
item.linkedTo.Add(target.item);
if (!target.item.Submarine.DockedTo.Contains(item.Submarine)) target.item.Submarine.DockedTo.Add(item.Submarine);
if (!item.Submarine.DockedTo.Contains(target.item.Submarine)) item.Submarine.DockedTo.Add(target.item.Submarine);
dockingTarget = target;
dockingTarget.dockingTarget = this;
docked = true;
dockingTarget.Docked = true;
if (Character.Controlled != null &&
(Character.Controlled.Submarine == dockingTarget.item.Submarine || Character.Controlled.Submarine == item.Submarine))
{
GameMain.GameScreen.Cam.Shake = Vector2.Distance(dockingTarget.item.Submarine.Velocity, item.Submarine.Velocity);
}
dockingDir = IsHorizontal ?
Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
Math.Sign(item.WorldPosition.Y - dockingTarget.item.WorldPosition.Y);
dockingTarget.dockingDir = -dockingDir;
CreateJoint(false);
}
private void CreateJoint(bool useWeldJoint)
{
Vector2 offset = (IsHorizontal ?
Vector2.UnitX * Math.Sign(dockingTarget.item.WorldPosition.X - item.WorldPosition.X) :
Vector2.UnitY * Math.Sign(dockingTarget.item.WorldPosition.Y - item.WorldPosition.Y));
offset *= DockedDistance * 0.5f;
Vector2 pos1 = item.WorldPosition + offset;
Vector2 pos2 = dockingTarget.item.WorldPosition - offset;
if (useWeldJoint)
{
joint = JointFactory.CreateWeldJoint(GameMain.World,
item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body,
ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
((WeldJoint)joint).FrequencyHz = 1.0f;
}
else
{
var distanceJoint = JointFactory.CreateDistanceJoint(GameMain.World,
item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body,
ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true);
distanceJoint.Length = 0.01f;
distanceJoint.Frequency = 1.0f;
distanceJoint.DampingRatio = 0.8f;
joint = distanceJoint;
}
joint.CollideConnected = true;
}
private void CreateHull()
{
var hullRects = new Rectangle[] { item.WorldRect, dockingTarget.item.WorldRect };
var subs = new Submarine[] { item.Submarine, dockingTarget.item.Submarine };
hulls = new Hull[2];
bodies = new Body[4];
if (IsHorizontal)
{
if (hullRects[0].Center.X > hullRects[1].Center.X)
{
hullRects = new Rectangle[] { dockingTarget.item.WorldRect, item.WorldRect };
subs = new Submarine[] { dockingTarget.item.Submarine,item.Submarine };
}
hullRects[0] = new Rectangle(hullRects[0].Center.X, hullRects[0].Y, ((int)DockedDistance / 2), hullRects[0].Height);
hullRects[1] = new Rectangle(hullRects[1].Center.X - ((int)DockedDistance / 2), hullRects[1].Y, ((int)DockedDistance / 2), hullRects[1].Height);
for (int i = 0; i < 2;i++ )
{
hullRects[i].Location -= (subs[i].WorldPosition - subs[i].HiddenSubPosition).ToPoint();
hulls[i] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRects[i], subs[i]);
hulls[i].AddToGrid(subs[i]);
for (int j = 0; j < 2; j++)
{
bodies[i + j * 2] = BodyFactory.CreateEdge(GameMain.World,
ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X, hullRects[i].Y - hullRects[i].Height * j)),
ConvertUnits.ToSimUnits(new Vector2(hullRects[i].Right, hullRects[i].Y - hullRects[i].Height * j)));
}
}
gap = new Gap(new Rectangle(hullRects[0].Right - 2, hullRects[0].Y, 4, hullRects[0].Height), true, subs[0]);
gap.linkedTo.Clear();
if (hulls[0].WorldRect.X < hulls[1].WorldRect.X)
{
gap.linkedTo.Add(hulls[0]);
gap.linkedTo.Add(hulls[1]);
}
else
{
gap.linkedTo.Add(hulls[1]);
gap.linkedTo.Add(hulls[0]);
}
}
else
{
if (hullRects[0].Center.Y > hullRects[1].Center.Y)
{
hullRects = new Rectangle[] { dockingTarget.item.WorldRect, item.WorldRect };
subs = new Submarine[] { dockingTarget.item.Submarine, item.Submarine };
}
hullRects[0] = new Rectangle(hullRects[0].X, hullRects[0].Y + (int)(-hullRects[0].Height+DockedDistance)/2, hullRects[0].Width, ((int)DockedDistance / 2));
hullRects[1] = new Rectangle(hullRects[1].X, hullRects[1].Y - hullRects[1].Height/2, hullRects[1].Width, ((int)DockedDistance / 2));
for (int i = 0; i < 2; i++)
{
hullRects[i].Location -= (subs[i].WorldPosition - subs[i].HiddenSubPosition).ToPoint();
hulls[i] = new Hull(MapEntityPrefab.list.Find(m => m.Name == "Hull"), hullRects[i], subs[i]);
hulls[i].AddToGrid(subs[i]);
//for (int j = 0; j < 2; j++)
//{
// bodies[i + j * 2] = BodyFactory.CreateEdge(GameMain.World,
// ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X + hullRects[i].Width * j, hullRects[i].Y)),
// ConvertUnits.ToSimUnits(new Vector2(hullRects[i].X + hullRects[i].Width * j, hullRects[i].Y-hullRects[i].Height)));
//}
}
gap = new Gap(new Rectangle(hullRects[0].X, hullRects[0].Y+2, hullRects[0].Width, 4), false, subs[0]);
gap.linkedTo.Clear();
if (hulls[0].WorldRect.Y > hulls[1].WorldRect.Y)
{
gap.linkedTo.Add(hulls[0]);
gap.linkedTo.Add(hulls[1]);
}
else
{
gap.linkedTo.Add(hulls[1]);
gap.linkedTo.Add(hulls[0]);
}
}
foreach (Body body in bodies)
{
if (body == null) continue;
body.BodyType = BodyType.Static;
body.Friction = 0.5f;
body.CollisionCategories = Physics.CollisionWall;
}
}
private void Undock()
{
if (dockingTarget == null || !docked) return;
PlaySound(ActionType.OnUse, item.WorldPosition);
dockingTarget.item.Submarine.DockedTo.Remove(item.Submarine);
item.Submarine.DockedTo.Remove(dockingTarget.item.Submarine);
item.linkedTo.Clear();
docked = false;
dockingTarget.Undock();
dockingTarget = null;
if (joint != null)
{
GameMain.World.RemoveJoint(joint);
joint = null;
}
if (hulls != null)
{
hulls[0].Remove();
hulls[1].Remove();
hulls = null;
}
if (gap != null)
{
gap.Remove();
gap = null;
}
if (bodies!=null)
{
foreach (Body body in bodies)
{
if (body == null) continue;
GameMain.World.RemoveBody(body);
}
bodies = null;
}
}
public override void Update(float deltaTime, Camera cam)
{
if (dockingTarget == null)
{
dockingState = MathHelper.Lerp(dockingState, 0.0f, deltaTime * 10.0f);
if (dockingState < 0.01f) docked = false;
item.SendSignal(0, "0", "state_out");
item.SendSignal(0, (FindAdjacentPort() != null) ? "1" : "0", "proximity_sensor");
}
else
{
if (joint is DistanceJoint)
{
item.SendSignal(0, "0", "state_out");
if (Vector2.Distance(joint.WorldAnchorA, joint.WorldAnchorB) < 0.05f)
{
GameMain.World.RemoveJoint(joint);
PlaySound(ActionType.OnSecondaryUse, item.WorldPosition);
CreateJoint(true);
CreateHull();
}
dockingState = MathHelper.Lerp(dockingState, 0.5f, deltaTime * 10.0f);
}
else
{
item.SendSignal(0, "1", "state_out");
dockingState = MathHelper.Lerp(dockingState, 1.0f, deltaTime * 10.0f);
}
}
}
public void Draw(SpriteBatch spriteBatch, bool editing)
{
if (dockingState == 0.0f) return;
Vector2 drawPos = item.DrawPosition;
drawPos.Y = -drawPos.Y;
var rect = overlaySprite.SourceRect;
if (IsHorizontal)
{
drawPos.Y -= rect.Height / 2;
if (dockingDir == 1)
{
spriteBatch.Draw(overlaySprite.Texture,
drawPos,
new Rectangle(
rect.Center.X + (int)(rect.Width / 2 * (1.0f - dockingState)), rect.Y,
(int)(rect.Width / 2 * dockingState), rect.Height), Color.White);
}
else
{
spriteBatch.Draw(overlaySprite.Texture,
drawPos - Vector2.UnitX * (rect.Width / 2 * dockingState),
new Rectangle(
rect.X, rect.Y,
(int)(rect.Width / 2 * dockingState), rect.Height), Color.Red);
}
}
else
{
drawPos.X -= rect.Width / 2;
if (dockingDir == 1)
{
spriteBatch.Draw(overlaySprite.Texture,
drawPos,
new Rectangle(
rect.X, rect.Y + rect.Height/2 + (int)(rect.Height / 2 * (1.0f - dockingState)),
rect.Width, (int)(rect.Height / 2 * dockingState)), Color.White);
}
else
{
spriteBatch.Draw(overlaySprite.Texture,
drawPos - Vector2.UnitY * (rect.Height / 2 * dockingState),
new Rectangle(
rect.X, rect.Y,
rect.Width, (int)(rect.Height / 2 * dockingState)), Color.Red);
}
}
}
protected override void RemoveComponentSpecific()
{
list.Remove(this);
}
public override void OnMapLoaded()
{
if (!item.linkedTo.Any()) return;
Item linkedItem = item.linkedTo.First() as Item;
if (linkedItem == null) return;
DockingPort port = linkedItem.GetComponent<DockingPort>();
if (port != null) Dock(port);
}
public override void ReceiveSignal(int stepsTaken, string signal, Connection connection, Item sender, float power = 0.0f)
{
switch (connection.Name)
{
case "toggle":
Docked = !docked;
break;
case "set_active":
case "set_state":
Docked = signal != "0";
break;
}
}
}
}
+11 -8
View File
@@ -444,28 +444,31 @@ namespace Barotrauma.Items.Components
if (connection.Name=="toggle")
{
SetState(!isOpen, false);
SetState(!isOpen, false, true);
}
else if (connection.Name == "set_state")
{
SetState(signal != "0", false);
SetState(signal != "0", false, true);
}
item.NewComponentEvent(this, false, true);
}
private void SetState(bool state, bool isNetWorkMessage)
public void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage = false)
{
if (GameMain.Client != null && !isNetWorkMessage) return;
if (GameMain.Client != null && !isNetworkMessage) return;
if (isStuck || isOpen == state) return;
if (isStuck || isOpen == open) return;
PlaySound(ActionType.OnUse, item.WorldPosition);
isOpen = state;
isOpen = open;
//opening a partially stuck door makes it less stuck
if (isOpen) stuck = MathHelper.Clamp(stuck - 30.0f, 0.0f, 100.0f);
if (sendNetworkMessage)
{
item.NewComponentEvent(this, false, true);
}
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
@@ -101,7 +101,7 @@ namespace Barotrauma.Items.Components
Msg = "";
}
if (attachedByDefault || (Screen.Selected == GameMain.EditMapScreen && Submarine.Loaded != null)) Use(1.0f);
if (attachedByDefault || (Screen.Selected == GameMain.EditMapScreen)) Use(1.0f);
//holdAngle = ToolBox.GetAttributeFloat(element, "holdangle", 0.0f);
@@ -132,83 +132,19 @@ namespace Barotrauma.Items.Components
IsActive = true;
activeTimer = 0.1f;
Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition);
Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition);
for (int n = 0; n < 2; n++)
if (character.Submarine == null)
{
Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition);
Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition);
if (n == 0)
foreach (Submarine sub in Submarine.Loaded)
{
//do a raycast in "submarine coordinates"
rayStart -= Submarine.Loaded.SimPosition;
rayEnd -= Submarine.Loaded.SimPosition;
Repair(rayStart - sub.SimPosition, rayEnd - sub.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies);
}
else
{
//do a raycast outside the sub if the character is outside
if (character.AnimController.CurrentHull != null) continue;
}
Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies);
pickedPosition = Submarine.LastPickedPosition;
if (ExtinquishAmount > 0.0f && item.CurrentHull != null)
{
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f);
displayPos += item.CurrentHull.Submarine.Position;
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos);
}
if (targetBody == null || targetBody.UserData == null) continue;
Structure targetStructure;
Limb targetLimb;
Item targetItem;
if ((targetStructure = (targetBody.UserData as Structure)) != null)
{
if (!fixableEntities.Contains(targetStructure.Name)) continue;
int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition));
if (sectionIndex < 0) continue;
targetStructure.HighLightSection(sectionIndex);
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess);
//if the next section is small enough, apply the effect to it as well
//(to make it easier to fix a small "left-over" section)
for (int i = -1; i < 2; i += 2)
{
int nextSectionLength = targetStructure.SectionLength(sectionIndex + i);
if ((sectionIndex == 1 && i == -1) ||
(sectionIndex == targetStructure.SectionCount - 2 && i == 1) ||
(nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f))
{
targetStructure.HighLightSection(sectionIndex + i);
targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess);
}
}
}
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
{
if (character.IsKeyDown(InputType.Aim))
{
targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, character);
}
}
else if ((targetItem = (targetBody.UserData as Item)) != null)
{
targetItem.IsHighlighted = true;
ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime);
}
}
else
{
Repair(rayStart - character.Submarine.SimPosition, rayEnd - character.Submarine.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies);
}
GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition + TransformedBarrelPos,
@@ -217,6 +153,64 @@ namespace Barotrauma.Items.Components
return true;
}
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
{
if (ExtinquishAmount > 0.0f && item.CurrentHull != null)
{
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f);
displayPos += item.CurrentHull.Submarine.Position;
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos);
}
Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies);
if (targetBody == null || targetBody.UserData == null) return;
Structure targetStructure;
Limb targetLimb;
Item targetItem;
if ((targetStructure = (targetBody.UserData as Structure)) != null)
{
if (!fixableEntities.Contains(targetStructure.Name)) return;
int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition));
if (sectionIndex < 0) return;
targetStructure.HighLightSection(sectionIndex);
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess);
//if the next section is small enough, apply the effect to it as well
//(to make it easier to fix a small "left-over" section)
for (int i = -1; i < 2; i += 2)
{
int nextSectionLength = targetStructure.SectionLength(sectionIndex + i);
if ((sectionIndex == 1 && i == -1) ||
(sectionIndex == targetStructure.SectionCount - 2 && i == 1) ||
(nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f))
{
targetStructure.HighLightSection(sectionIndex + i);
targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess);
}
}
}
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
{
targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user);
}
else if ((targetItem = (targetBody.UserData as Item)) != null)
{
targetItem.IsHighlighted = true;
ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime);
}
}
public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective)
{
Gap leak = objective.OperateTarget as Gap;
@@ -86,7 +86,7 @@ namespace Barotrauma.Items.Components
{
Vector2 currForce = new Vector2((force / 100.0f) * maxForce * (voltage / minVoltage), 0.0f);
Submarine.Loaded.ApplyForce(currForce);
item.Submarine.ApplyForce(currForce);
if (item.CurrentHull != null)
{
@@ -36,6 +36,8 @@ namespace Barotrauma.Items.Components
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
{
if (item.Submarine == null) return;
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
int x = GuiFrame.Rect.X;
int y = GuiFrame.Rect.Y;
@@ -48,12 +50,12 @@ namespace Barotrauma.Items.Components
Rectangle miniMap = new Rectangle(x + 20, y + 40, width - 40, height - 60);
float size = Math.Min((float)miniMap.Width / (float)Submarine.Borders.Width, (float)miniMap.Height / (float)Submarine.Borders.Height);
float size = Math.Min((float)miniMap.Width / (float)item.Submarine.Borders.Width, (float)miniMap.Height / (float)item.Submarine.Borders.Height);
foreach (Hull hull in Hull.hullList)
{
Rectangle hullRect = new Rectangle(
miniMap.X + (int)((hull.Rect.X - Submarine.HiddenSubPosition.X - Submarine.Borders.X) * size),
miniMap.Y - (int)((hull.Rect.Y - Submarine.HiddenSubPosition.Y - Submarine.Borders.Y) * size),
miniMap.X + (int)((hull.Rect.X - item.Submarine.HiddenSubPosition.X - item.Submarine.Borders.X) * size),
miniMap.Y - (int)((hull.Rect.Y - item.Submarine.HiddenSubPosition.Y - item.Submarine.Borders.Y) * size),
(int)(hull.Rect.Width * size),
(int)(hull.Rect.Height * size));
@@ -124,38 +124,41 @@ namespace Barotrauma.Items.Components
float radius = rect.Width / 2.0f;
float displayScale = radius / range;
if (DetectSubmarineWalls)
foreach (Submarine submarine in Submarine.Loaded)
{
for (int i = 0; i < Submarine.Loaded.HullVertices.Count; i++)
{
Vector2 start = ConvertUnits.ToDisplayUnits(Submarine.Loaded.HullVertices[i]);
Vector2 end = ConvertUnits.ToDisplayUnits(Submarine.Loaded.HullVertices[(i + 1) % Submarine.Loaded.HullVertices.Count]);
if (item.Submarine == submarine && !DetectSubmarineWalls) continue;
if (item.CurrentHull!=null)
for (int i = 0; i < submarine.HullVertices.Count; i++)
{
Vector2 start = ConvertUnits.ToDisplayUnits(submarine.HullVertices[i]);
Vector2 end = ConvertUnits.ToDisplayUnits(submarine.HullVertices[(i + 1) % submarine.HullVertices.Count]);
if (item.Submarine == submarine)
{
start += Rand.Vector(500.0f);
end += Rand.Vector(500.0f);
}
CreateBlipsForLine(
start + Submarine.Loaded.WorldPosition,
end + Submarine.Loaded.WorldPosition,
start + submarine.WorldPosition,
end + submarine.WorldPosition,
radius, displayScale, 200.0f, 2.0f);
}
}
else
if (item.Submarine != null && !DetectSubmarineWalls)
{
float simScale = displayScale * Physics.DisplayToSimRation;
Vector2 offset = ConvertUnits.ToSimUnits(Submarine.Loaded.WorldPosition - item.WorldPosition);
Vector2 offset = ConvertUnits.ToSimUnits(item.Submarine.WorldPosition - item.WorldPosition);
for (int i = 0; i < Submarine.Loaded.HullVertices.Count; i++)
for (int i = 0; i < item.Submarine.HullVertices.Count; i++)
{
Vector2 start = (Submarine.Loaded.HullVertices[i] + offset) * simScale;
Vector2 start = (item.Submarine.HullVertices[i] + offset) * simScale;
start.Y = -start.Y;
Vector2 end = (Submarine.Loaded.HullVertices[(i + 1) % Submarine.Loaded.HullVertices.Count] + offset) * simScale;
Vector2 end = (item.Submarine.HullVertices[(i + 1) % item.Submarine.HullVertices.Count] + offset) * simScale;
end.Y = -end.Y;
GUI.DrawLine(spriteBatch, center + start, center + end, Color.Green);
@@ -33,8 +33,10 @@ namespace Barotrauma.Items.Components
private float autopilotRayCastTimer;
private float neutralBallastLevel;
public Vector2? TargetPosition;
bool AutoPilot
public bool AutoPilot
{
get { return autoPilot; }
set
@@ -52,7 +54,7 @@ namespace Barotrauma.Items.Components
if (pathFinder==null) pathFinder = new PathFinder(WayPoint.WayPointList, false);
steeringPath = pathFinder.FindPath(
ConvertUnits.ToSimUnits(item.WorldPosition),
ConvertUnits.ToSimUnits(Level.Loaded.EndPosition));
TargetPosition == null ? ConvertUnits.ToSimUnits(Level.Loaded.EndPosition) : (Vector2)TargetPosition);
}
else
{
@@ -62,6 +64,12 @@ namespace Barotrauma.Items.Components
}
}
public bool MaintainPos
{
get { return maintainPosTickBox.Selected; }
set { maintainPosTickBox.Selected = value; }
}
[Editable, HasDefaultValue(0.5f, true)]
public float NeutralBallastLevel
@@ -128,7 +136,7 @@ namespace Barotrauma.Items.Components
}
}
if (voltage < minVoltage) return;
if (voltage < minVoltage && powerConsumption > 0.0f) return;
if (autoPilot)
{
@@ -158,15 +166,15 @@ namespace Barotrauma.Items.Components
GuiFrame.Update(1.0f / 60.0f);
GuiFrame.Draw(spriteBatch);
if (voltage < minVoltage) return;
if (voltage < minVoltage && powerConsumption > 0.0f) return;
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
//GUI.DrawRectangle(spriteBatch, velRect, Color.White, false);
if (Submarine.Loaded != null && Level.Loaded != null)
if (item.Submarine != null && Level.Loaded != null)
{
Vector2 realWorldVelocity = ConvertUnits.ToDisplayUnits(Submarine.Loaded.Velocity * Physics.DisplayToRealWorldRatio) * 3.6f;
float realWorldDepth = Math.Abs(Submarine.Loaded.Position.Y - Level.Loaded.Size.Y) * Physics.DisplayToRealWorldRatio;
Vector2 realWorldVelocity = ConvertUnits.ToDisplayUnits(item.Submarine.Velocity * Physics.DisplayToRealWorldRatio) * 3.6f;
float realWorldDepth = Math.Abs(item.Submarine.Position.Y - Level.Loaded.Size.Y) * Physics.DisplayToRealWorldRatio;
GUI.DrawString(spriteBatch, new Vector2(x + 20, y + height - 65),
"Velocity: " + (int)realWorldVelocity.X + " km/h", Color.LightGreen, null, 0, GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(x + 20, y + height - 50),
@@ -220,7 +228,7 @@ namespace Barotrauma.Items.Components
if (autopilotRayCastTimer <= 0.0f && steeringPath.NextNode != null)
{
Vector2 diff = Vector2.Normalize(ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - Submarine.Loaded.WorldPosition));
Vector2 diff = Vector2.Normalize(ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - item.Submarine.WorldPosition));
bool nextVisible = true;
for (int x = -1; x < 2; x += 2)
@@ -228,9 +236,9 @@ namespace Barotrauma.Items.Components
for (int y = -1; y < 2; y += 2)
{
Vector2 cornerPos =
new Vector2(Submarine.Borders.Width * x, Submarine.Borders.Height * y) / 2.0f;
new Vector2(item.Submarine.Borders.Width * x, item.Submarine.Borders.Height * y) / 2.0f;
cornerPos = ConvertUnits.ToSimUnits(cornerPos * 1.2f + Submarine.Loaded.WorldPosition);
cornerPos = ConvertUnits.ToSimUnits(cornerPos * 1.2f + item.Submarine.WorldPosition);
float dist = Vector2.Distance(cornerPos, steeringPath.NextNode.SimPosition);
@@ -113,7 +113,7 @@ namespace Barotrauma.Items.Components
public override void Update(float deltaTime, Camera cam)
{
float chargeRate = (float)(Math.Sqrt(charge / capacity));
//float gridPower = 0.0f;
float gridPower = 0.0f;
float gridLoad = 0.0f;
//if (item.linkedTo.Count == 0) return;
@@ -126,7 +126,8 @@ namespace Barotrauma.Items.Components
PowerTransfer pt = c2.Item.GetComponent<PowerTransfer>();
if (pt == null || !pt.IsActive) continue;
gridLoad += pt.PowerLoad;
gridLoad += pt.PowerLoad;
gridPower -= pt.CurrPowerConsumption;
}
}
@@ -171,27 +172,21 @@ namespace Barotrauma.Items.Components
// -maxOutput * chargeRate,
// 0.1f);
if (outputVoltage < 1.0f)
if (gridPower < gridLoad)
{
// CurrPowerOutput = MathHelper.Lerp(
//CurrPowerOutput, Math.Min(maxOutput * chargeRate, gridLoad), 0.05f);
CurrPowerOutput = MathHelper.Lerp(
CurrPowerOutput, Math.Min(maxOutput * chargeRate, gridLoad), 0.05f);
CurrPowerOutput,
Math.Min(maxOutput * chargeRate, gridLoad - (gridLoad * outputVoltage)),
0.05f);
}
else
{
CurrPowerOutput = MathHelper.Lerp(CurrPowerOutput, 0.0f, 0.05f);
}
CurrPowerOutput = MathHelper.Lerp(
CurrPowerOutput,
Math.Min(maxOutput * chargeRate, gridLoad - (gridLoad * outputVoltage)),
0.05f);
//powerConsumption = MathHelper.Lerp(
// powerConsumption,
// -Math.Min(maxOutput * chargeRate, gridLoad - (power)),
// 0.1f);
//powerConsumption = Math.Min(powerConsumption, 0.0f);
Charge -= CurrPowerOutput / 3600.0f;
@@ -62,6 +62,7 @@ namespace Barotrauma.Items.Components
pt.powerLoad += (fullLoad - pt.powerLoad) / inertia;
pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia;
pt.Item.SendSignal(0, "", "power", fullPower / Math.Max(fullLoad, 1.0f));
pt.Item.SendSignal(0, "", "power_out", fullPower / Math.Max(fullLoad, 1.0f));
//damage the item if voltage is too high
//(except if running as a client)
@@ -117,7 +118,6 @@ namespace Barotrauma.Items.Components
{
if (!c.IsPower) continue;
var recipients = c.Recipients;
foreach (Connection recipient in recipients)
@@ -138,7 +138,7 @@ namespace Barotrauma.Items.Components
PowerContainer powerContainer = powered as PowerContainer;
if (powerTransfer != null)
{
if (powerTransfer.updateTimer>0) continue;
//if (powerTransfer.updateTimer>0) continue;
powerTransfer.CheckJunctions(deltaTime);
}
else if (powerContainer != null)
@@ -102,7 +102,7 @@ namespace Barotrauma.Items.Components
: base (item, element)
{
light = new LightSource(element);
light.Submarine = item.CurrentHull == null ? null : item.CurrentHull.Submarine;
light.ParentSub = item.CurrentHull == null ? null : item.CurrentHull.Submarine;
light.Position = item.Position;
light.CastShadows = castShadows;
@@ -121,7 +121,7 @@ namespace Barotrauma.Items.Components
{
base.Update(deltaTime, cam);
light.Submarine = item.Submarine;
light.ParentSub = item.Submarine;
ApplyStatusEffects(ActionType.OnActive, deltaTime);
@@ -4,7 +4,7 @@ namespace Barotrauma.Items.Components
{
class SignalCheckComponent : ItemComponent
{
private string output;
private string output, falseOutput;
private string targetSignal;
@@ -14,6 +14,12 @@ namespace Barotrauma.Items.Components
get { return output; }
set { output = value; }
}
[InGameEditable, HasDefaultValue("0", true)]
public string FalseOutput
{
get { return falseOutput; }
set { falseOutput = value; }
}
[InGameEditable, HasDefaultValue("", true)]
public string TargetSignal
@@ -32,7 +38,10 @@ namespace Barotrauma.Items.Components
switch (connection.Name)
{
case "signal_in":
item.SendSignal(stepsTaken, (signal == targetSignal) ? output : "0", "signal_out");
string signalOut = (signal == targetSignal) ? output : falseOutput;
if (string.IsNullOrWhiteSpace(signalOut)) return;
item.SendSignal(stepsTaken, signalOut, "signal_out");
break;
case "set_output":
@@ -109,6 +109,8 @@ namespace Barotrauma.Items.Components
}
}
item.Submarine = newConnection.Item.Submarine;
for (int i = 0; i < 2; i++)
{
if (connections[i] != null) continue;
@@ -117,16 +119,18 @@ namespace Barotrauma.Items.Components
if (!addNode) break;
if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - Submarine.HiddenSubPosition) break;
if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - Submarine.HiddenSubPosition) break;
if (Nodes.Count > 0 && Nodes[0] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break;
if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition) break;
if (i == 0)
{
Nodes.Insert(0, newConnection.Item.Position - Submarine.HiddenSubPosition);
Nodes.Insert(0, newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
}
else
{
Nodes.Add(newConnection.Item.Position - Submarine.HiddenSubPosition);
Nodes.Add(newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
}
@@ -184,7 +188,7 @@ namespace Barotrauma.Items.Components
{
if (Nodes.Count == 0) return;
item.FindHull();
//item.FindHull();
//Vector2 position = item.Position;
@@ -200,7 +204,11 @@ namespace Barotrauma.Items.Components
// position.Y += item.CurrentHull.Rect.Y - item.CurrentHull.Rect.Height;
//}
newNodePos = RoundNode(item.Position, item.CurrentHull)-Submarine.HiddenSubPosition;
Submarine sub = null;
if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine;
if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine;
newNodePos = RoundNode(item.Position, item.CurrentHull) - sub.HiddenSubPosition;
//if (Vector2.Distance(position, nodes[nodes.Count - 1]) > nodeDistance*10)
//{
@@ -366,7 +374,7 @@ namespace Barotrauma.Items.Components
for (int i = 0; i < Nodes.Count; i++)
{
Vector2 worldPos = Nodes[i];
if (Submarine.Loaded != null) worldPos += Submarine.Loaded.Position + Submarine.HiddenSubPosition;
if (item.Submarine != null) worldPos += item.Submarine.Position + item.Submarine.HiddenSubPosition;
worldPos.Y = -worldPos.Y;
GUI.DrawRectangle(spriteBatch, worldPos + new Vector2(-3, -3), new Vector2(6, 6), item.Color, true, 0.0f);
@@ -407,7 +415,12 @@ namespace Barotrauma.Items.Components
MapEntity.DisableSelect = true;
//Nodes[(int)selectedNodeIndex] = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition)-Submarine.HiddenSubPosition+Submarine.Loaded.Position;
Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - Submarine.HiddenSubPosition - Submarine.Loaded.Position;// Nodes[(int)selectedNodeIndex];
Submarine sub = null;
if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine;
if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine;
Vector2 nodeWorldPos = GameMain.EditMapScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - sub.HiddenSubPosition - sub.Position;// Nodes[(int)selectedNodeIndex];
nodeWorldPos.X = MathUtils.Round(nodeWorldPos.X, Submarine.GridSize.X / 2.0f);
nodeWorldPos.Y = MathUtils.Round(nodeWorldPos.Y, Submarine.GridSize.Y / 2.0f);
@@ -428,10 +441,10 @@ namespace Barotrauma.Items.Components
private void DrawSection(SpriteBatch spriteBatch, Vector2 start, Vector2 end, Color color, float width = 0.3f)
{
if (Submarine.Loaded!=null)
if (item.Submarine != null)
{
start += Submarine.Loaded.DrawPosition + Submarine.HiddenSubPosition;
end += Submarine.Loaded.DrawPosition + Submarine.HiddenSubPosition;
start += item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition;
end += item.Submarine.DrawPosition + item.Submarine.HiddenSubPosition;
}
start.Y = -start.Y;