- camera follows the closest sub
- WIP "respawn shuttle" - submarine size affects its mass - electricity fixes
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,6 +10,8 @@ bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
*.suo
|
||||
|
||||
#performance reports & sessions
|
||||
*.vsp
|
||||
*.psess
|
||||
|
||||
@@ -152,6 +152,7 @@
|
||||
<Compile Include="Source\Networking\NetConfig.cs" />
|
||||
<Compile Include="Source\Networking\NetStats.cs" />
|
||||
<Compile Include="Source\Networking\ReliableSender.cs" />
|
||||
<Compile Include="Source\Networking\RespawnManager.cs" />
|
||||
<Compile Include="Source\Networking\ServerLog.cs" />
|
||||
<Compile Include="Source\Particles\ParticleEmitter.cs" />
|
||||
<Compile Include="Source\Networking\GameServerSettings.cs" />
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 90 KiB |
@@ -8,7 +8,7 @@
|
||||
pickthroughwalls="true"
|
||||
pickdistance="150">
|
||||
|
||||
<Sprite texture ="engine.png" depth="0.8"/>
|
||||
<Sprite texture ="engine.png" depth="0.8" sourcerect="0,0,373,113"/>
|
||||
|
||||
<fixrequirement name="Mechanical repairs">
|
||||
<skill name="Construction" level="40"/>
|
||||
@@ -29,6 +29,34 @@
|
||||
</ConnectionPanel>
|
||||
</Item>
|
||||
|
||||
<Item
|
||||
name="Shuttle Engine"
|
||||
linkable="true"
|
||||
category="Machine"
|
||||
pickthroughwalls="true"
|
||||
pickdistance="150">
|
||||
|
||||
<Sprite texture ="engine.png" depth="0.8" sourcerect="0,115,224,73"/>
|
||||
|
||||
<fixrequirement name="Mechanical repairs">
|
||||
<skill name="Construction" level="30"/>
|
||||
<item name="Welding Tool"/>
|
||||
<item name="Wrench"/>
|
||||
</fixrequirement>
|
||||
|
||||
<Engine minvoltage="0.5" powerconsumption="500.0" maxforce="500" canbeselected = "true">
|
||||
<StatusEffect type="InWater" target="This" condition="-2.0"/>
|
||||
<GuiFrame rect="0,0,350,160" alignment="Center" color="0.0,0.0,0.0,0.6"/>
|
||||
<sound file="engine.ogg" type="OnActive" range="3000.0" volume="CurrentVolume" loop="true"/>
|
||||
</Engine>
|
||||
|
||||
<ConnectionPanel selectkey="Action" canbeselected = "true" msg="Rewire [Screwdriver]">
|
||||
<requireditem name="Screwdriver" type="Equipped"/>
|
||||
<input name="power_in"/>
|
||||
<input name="set_force"/>
|
||||
</ConnectionPanel>
|
||||
</Item>
|
||||
|
||||
<Item
|
||||
name="Navigation Terminal"
|
||||
linkable="true"
|
||||
|
||||
@@ -125,11 +125,17 @@ namespace Barotrauma
|
||||
public void Translate(Vector2 amount)
|
||||
{
|
||||
position += amount;
|
||||
//UpdateTransform();
|
||||
}
|
||||
|
||||
public void UpdateTransform(bool interpolate = true)
|
||||
public void UpdateTransform(bool interpolate = true, bool clampPos = false)
|
||||
{
|
||||
|
||||
if (clampPos && Level.Loaded != null)
|
||||
{
|
||||
position.Y -= Math.Max(worldView.Y - Level.Loaded.Size.Y, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
Vector2 interpolatedPosition = interpolate ? Physics.Interpolate(prevPosition, position) : position;
|
||||
|
||||
float interpolatedZoom = interpolate ? Physics.Interpolate(prevZoom, zoom) : zoom;
|
||||
@@ -179,11 +185,13 @@ namespace Barotrauma
|
||||
if (GameMain.Config.KeyBind(InputType.Up).IsDown()) moveCam.Y += moveSpeed;
|
||||
}
|
||||
|
||||
if (Submarine.MainSub != null && Screen.Selected == GameMain.GameScreen)
|
||||
if (Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
|
||||
|
||||
moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(Submarine.MainSub.Velocity*deltaTime);
|
||||
var closestSub = Submarine.GetClosest(WorldViewCenter);
|
||||
if (closestSub != null)
|
||||
{
|
||||
moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(closestSub.Velocity * deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
moveCam = moveCam * deltaTime * 60.0f;
|
||||
|
||||
@@ -109,10 +109,10 @@ namespace Barotrauma
|
||||
{
|
||||
|
||||
Vector2 pos2 = host.SimPosition;
|
||||
if (character != null && character.Submarine == null)
|
||||
if (character != null && character.Submarine == null && CurrentPath.Nodes.Last().Submarine != null)
|
||||
{
|
||||
//todo: take multiple subs into account
|
||||
pos2 -= Submarine.MainSub.SimPosition;
|
||||
pos2 -= CurrentPath.Nodes.Last().Submarine.SimPosition;
|
||||
}
|
||||
return currentTarget-pos2;
|
||||
}
|
||||
@@ -123,10 +123,11 @@ namespace Barotrauma
|
||||
if (currentPath.CurrentNode!=null && currentPath.CurrentNode.SimPosition.Y > character.SimPosition.Y+1.0f) allowedDistance*=0.5f;
|
||||
|
||||
Vector2 pos = host.SimPosition;
|
||||
if (character != null && character.Submarine == null)
|
||||
if (character != null && character.Submarine == null &&
|
||||
CurrentPath.CurrentNode != null && CurrentPath.CurrentNode.Submarine != null)
|
||||
{
|
||||
//todo: take multiple subs into account
|
||||
pos -= Submarine.MainSub.SimPosition;
|
||||
pos -= CurrentPath.CurrentNode.Submarine.SimPosition;
|
||||
}
|
||||
|
||||
if (currentPath.CurrentNode!= null && currentPath.CurrentNode.Ladders!=null)
|
||||
|
||||
@@ -83,12 +83,11 @@ namespace Barotrauma
|
||||
if (state == ComponentState.Hover) currColor = hoverColor;
|
||||
if (state == ComponentState.Selected) currColor = selectedColor;
|
||||
|
||||
if (sprite!=null)
|
||||
if (sprite != null && sprite.Texture != null)
|
||||
{
|
||||
spriteBatch.Draw(sprite.Texture, new Vector2(rect.X, rect.Y), sourceRect, currColor * (currColor.A / 255.0f), 0.0f, Vector2.Zero,
|
||||
Scale, SpriteEffects.None, 0.0f);
|
||||
}
|
||||
|
||||
Scale, SpriteEffects.None, 0.0f);
|
||||
}
|
||||
|
||||
DrawChildren(spriteBatch);
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace Barotrauma
|
||||
listBox.ClearChildren();
|
||||
characters.Clear();
|
||||
|
||||
WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos);
|
||||
WayPoint[] waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
|
||||
|
||||
for (int i = 0; i < waypoints.Length; i++)
|
||||
{
|
||||
|
||||
@@ -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,7 +166,7 @@ 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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 - item.Submarine.HiddenSubPosition) break;
|
||||
if (Nodes.Count > 1 && Nodes[Nodes.Count-1] == newConnection.Item.Position - item.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 - item.Submarine.HiddenSubPosition);
|
||||
Nodes.Insert(0, newConnection.Item.Position - newConnection.Item.Submarine.HiddenSubPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
Nodes.Add(newConnection.Item.Position - item.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) - item.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)
|
||||
//{
|
||||
@@ -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) - item.Submarine.HiddenSubPosition - item.Submarine.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);
|
||||
|
||||
@@ -523,7 +523,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
CurrentHull = Hull.FindHull(WorldPosition, CurrentHull);
|
||||
if (body != null)
|
||||
if (body != null && body.Enabled)
|
||||
{
|
||||
Submarine = CurrentHull == null ? null : CurrentHull.Submarine;
|
||||
body.Submarine = Submarine;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Barotrauma
|
||||
{
|
||||
public static string SavePath = "Submarines";
|
||||
|
||||
private static readonly Vector2 HiddenSubStartPosition = new Vector2(-50000.0f, 80000.0f);
|
||||
public static readonly Vector2 HiddenSubStartPosition = new Vector2(-50000.0f, 80000.0f);
|
||||
//position of the "actual submarine" which is rendered wherever the SubmarineBody is
|
||||
//should be in an unreachable place
|
||||
public Vector2 HiddenSubPosition
|
||||
@@ -113,6 +113,11 @@ namespace Barotrauma
|
||||
get { return loaded; }
|
||||
}
|
||||
|
||||
public SubmarineBody SubBody
|
||||
{
|
||||
get { return subBody; }
|
||||
}
|
||||
|
||||
public Rectangle Borders
|
||||
{
|
||||
get
|
||||
|
||||
@@ -33,11 +33,11 @@ namespace Barotrauma
|
||||
|
||||
private readonly Submarine submarine;
|
||||
|
||||
private readonly Body body;
|
||||
public readonly Body Body;
|
||||
|
||||
private Vector2? targetPosition;
|
||||
|
||||
private float mass = 10000.0f;
|
||||
//private float mass = 10000.0f;
|
||||
|
||||
public Rectangle Borders
|
||||
{
|
||||
@@ -47,11 +47,11 @@ namespace Barotrauma
|
||||
|
||||
public Vector2 Velocity
|
||||
{
|
||||
get { return body.LinearVelocity; }
|
||||
get { return Body.LinearVelocity; }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
body.LinearVelocity = value;
|
||||
Body.LinearVelocity = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Barotrauma
|
||||
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(body.Position); }
|
||||
get { return ConvertUnits.ToDisplayUnits(Body.Position); }
|
||||
}
|
||||
|
||||
public bool AtDamageDepth
|
||||
@@ -82,7 +82,7 @@ namespace Barotrauma
|
||||
if (!Hull.hullList.Any())
|
||||
{
|
||||
|
||||
body = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f);
|
||||
Body = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f);
|
||||
DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed.");
|
||||
}
|
||||
else
|
||||
@@ -110,7 +110,7 @@ namespace Barotrauma
|
||||
|
||||
//var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit);
|
||||
|
||||
body = BodyFactory.CreateBody(GameMain.World, this);
|
||||
Body = BodyFactory.CreateBody(GameMain.World, this);
|
||||
|
||||
foreach (Structure wall in Structure.WallList)
|
||||
{
|
||||
@@ -118,9 +118,9 @@ namespace Barotrauma
|
||||
FixtureFactory.AttachRectangle(
|
||||
ConvertUnits.ToSimUnits(rect.Width),
|
||||
ConvertUnits.ToSimUnits(rect.Height),
|
||||
5.0f,
|
||||
50.0f,
|
||||
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
|
||||
body, this);
|
||||
Body, this);
|
||||
}
|
||||
|
||||
//foreach (Hull hull in Hull.hullList)
|
||||
@@ -151,24 +151,24 @@ namespace Barotrauma
|
||||
|
||||
|
||||
|
||||
body.BodyType = BodyType.Dynamic;
|
||||
body.CollisionCategories = Physics.CollisionWall;
|
||||
body.CollidesWith =
|
||||
Body.BodyType = BodyType.Dynamic;
|
||||
Body.CollisionCategories = Physics.CollisionWall;
|
||||
Body.CollidesWith =
|
||||
Physics.CollisionItem |
|
||||
Physics.CollisionLevel |
|
||||
Physics.CollisionCharacter |
|
||||
Physics.CollisionProjectile |
|
||||
Physics.CollisionWall;
|
||||
|
||||
body.Restitution = Restitution;
|
||||
body.Friction = Friction;
|
||||
body.FixedRotation = true;
|
||||
body.Mass = mass;
|
||||
body.Awake = true;
|
||||
body.SleepingAllowed = false;
|
||||
body.IgnoreGravity = true;
|
||||
body.OnCollision += OnCollision;
|
||||
body.UserData = submarine;
|
||||
Body.Restitution = Restitution;
|
||||
Body.Friction = Friction;
|
||||
Body.FixedRotation = true;
|
||||
//mass = Body.Mass;
|
||||
Body.Awake = true;
|
||||
Body.SleepingAllowed = false;
|
||||
Body.IgnoreGravity = true;
|
||||
Body.OnCollision += OnCollision;
|
||||
Body.UserData = submarine;
|
||||
}
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace Barotrauma
|
||||
|
||||
if (dist > 1000.0f) //immediately snap the sub to the target position if more than 1000.0f units away
|
||||
{
|
||||
Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(body.Position);
|
||||
Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(Body.Position);
|
||||
|
||||
ForceTranslate(moveAmount);
|
||||
|
||||
@@ -270,14 +270,14 @@ namespace Barotrauma
|
||||
|
||||
Vector2 totalForce = CalculateBuoyancy();
|
||||
|
||||
if (body.LinearVelocity.LengthSquared() > 0.000001f)
|
||||
if (Body.LinearVelocity.LengthSquared() > 0.000001f)
|
||||
{
|
||||
float dragCoefficient = 0.01f;
|
||||
|
||||
float speedLength = (body.LinearVelocity == Vector2.Zero) ? 0.0f : body.LinearVelocity.Length();
|
||||
float drag = speedLength * speedLength * dragCoefficient * mass;
|
||||
float speedLength = (Body.LinearVelocity == Vector2.Zero) ? 0.0f : Body.LinearVelocity.Length();
|
||||
float drag = speedLength * speedLength * dragCoefficient * Body.Mass;
|
||||
|
||||
totalForce += -Vector2.Normalize(body.LinearVelocity) * drag;
|
||||
totalForce += -Vector2.Normalize(Body.LinearVelocity) * drag;
|
||||
}
|
||||
|
||||
ApplyForce(totalForce);
|
||||
@@ -292,11 +292,15 @@ namespace Barotrauma
|
||||
/// <param name="amount">Amount to move in display units</param>
|
||||
private void ForceTranslate(Vector2 amount)
|
||||
{
|
||||
body.SetTransform(body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
|
||||
Body.SetTransform(Body.Position + ConvertUnits.ToSimUnits(amount), 0.0f);
|
||||
if (Character.Controlled != null) Character.Controlled.CursorPosition += amount;
|
||||
|
||||
GameMain.GameScreen.Cam.Position += amount;
|
||||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount;
|
||||
if ((Character.Controlled != null && Character.Controlled.Submarine == submarine) ||
|
||||
Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == submarine)
|
||||
{
|
||||
GameMain.GameScreen.Cam.Position += amount;
|
||||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +312,7 @@ namespace Barotrauma
|
||||
private void DisplaceCharacters(Vector2 subTranslation)
|
||||
{
|
||||
Rectangle worldBorders = Borders;
|
||||
worldBorders.Location += ConvertUnits.ToDisplayUnits(body.Position).ToPoint();
|
||||
worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.Position).ToPoint();
|
||||
|
||||
Vector2 translateDir = Vector2.Normalize(subTranslation);
|
||||
|
||||
@@ -355,19 +359,19 @@ namespace Barotrauma
|
||||
float neutralPercentage = 0.07f;
|
||||
|
||||
float buoyancy = Math.Max(neutralPercentage - waterPercentage, -neutralPercentage*2.0f);
|
||||
buoyancy *= mass;
|
||||
buoyancy *= Body.Mass;
|
||||
|
||||
return new Vector2(0.0f, buoyancy*10.0f);
|
||||
}
|
||||
|
||||
public void ApplyForce(Vector2 force)
|
||||
{
|
||||
body.ApplyForce(force);
|
||||
Body.ApplyForce(force);
|
||||
}
|
||||
|
||||
public void SetPosition(Vector2 position)
|
||||
{
|
||||
body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f);
|
||||
Body.SetTransform(ConvertUnits.ToSimUnits(position), 0.0f);
|
||||
}
|
||||
|
||||
private void UpdateDepthDamage(float deltaTime)
|
||||
@@ -423,7 +427,7 @@ namespace Barotrauma
|
||||
|
||||
if (collision && limb.Mass > 100.0f)
|
||||
{
|
||||
Vector2 normal = Vector2.Normalize(body.Position - limb.SimPosition);
|
||||
Vector2 normal = Vector2.Normalize(Body.Position - limb.SimPosition);
|
||||
|
||||
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 5.0f);
|
||||
|
||||
@@ -436,7 +440,7 @@ namespace Barotrauma
|
||||
VoronoiCell cell = f2.Body.UserData as VoronoiCell;
|
||||
if (cell != null)
|
||||
{
|
||||
var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(body.Position) - cell.Center);
|
||||
var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.Position) - cell.Center);
|
||||
|
||||
float wallImpact = Vector2.Dot(Velocity, -collisionNormal);
|
||||
|
||||
@@ -525,7 +529,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.AnimController.CurrentHull == null) continue;
|
||||
if (c.Submarine != submarine) continue;
|
||||
|
||||
if (impact > 2.0f) c.StartStun((impact - 2.0f) * 0.1f);
|
||||
|
||||
|
||||
@@ -641,13 +641,11 @@ namespace Barotrauma
|
||||
return wayPoints[Rand.Int(wayPoints.Count(), false)];
|
||||
}
|
||||
|
||||
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew)
|
||||
public static WayPoint[] SelectCrewSpawnPoints(List<CharacterInfo> crew, Submarine submarine)
|
||||
{
|
||||
List<WayPoint> unassignedWayPoints = new List<WayPoint>();
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
{
|
||||
if (wp.spawnType == SpawnType.Human) unassignedWayPoints.Add(wp);
|
||||
}
|
||||
List<WayPoint> subWayPoints = WayPointList.FindAll(wp => wp.Submarine == submarine);
|
||||
|
||||
List<WayPoint> unassignedWayPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human);
|
||||
|
||||
WayPoint[] assignedWayPoints = new WayPoint[crew.Count];
|
||||
|
||||
@@ -670,7 +668,7 @@ namespace Barotrauma
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
|
||||
//try to assign a spawnpoint that matches the job, even if the spawnpoint is already assigned to someone else
|
||||
foreach (WayPoint wp in WayPointList)
|
||||
foreach (WayPoint wp in subWayPoints)
|
||||
{
|
||||
if (wp.spawnType != SpawnType.Human || wp.assignedJob != crew[i].Job.Prefab) continue;
|
||||
|
||||
@@ -681,7 +679,7 @@ namespace Barotrauma
|
||||
if (assignedWayPoints[i] != null) continue;
|
||||
|
||||
//try to assign a spawnpoint that isn't meant for any specific job
|
||||
var nonJobSpecificPoints = WayPointList.FindAll(wp => wp.spawnType == SpawnType.Human && wp.assignedJob == null);
|
||||
var nonJobSpecificPoints = subWayPoints.FindAll(wp => wp.spawnType == SpawnType.Human && wp.assignedJob == null);
|
||||
|
||||
if (nonJobSpecificPoints.Any())
|
||||
{
|
||||
|
||||
@@ -518,6 +518,9 @@ namespace Barotrauma.Networking
|
||||
string endMessage = inc.ReadString();
|
||||
CoroutineManager.StartCoroutine(EndGame(endMessage));
|
||||
break;
|
||||
case (byte)PacketTypes.Respawn:
|
||||
if (gameStarted && respawnManager != null) respawnManager.ReadNetworkEvent(inc);
|
||||
break;
|
||||
case (byte)PacketTypes.PlayerJoined:
|
||||
|
||||
Client otherClient = new Client(inc.ReadString(), inc.ReadByte());
|
||||
@@ -672,7 +675,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
|
||||
GameMain.GameSession.StartShift(levelSeed);
|
||||
|
||||
|
||||
respawnManager = new RespawnManager(this);
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
//myCharacter = ReadCharacterData(inc);
|
||||
@@ -1023,7 +1028,7 @@ namespace Barotrauma.Networking
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
}
|
||||
|
||||
private Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter)
|
||||
public Character ReadCharacterData(NetIncomingMessage inc, bool isMyCharacter)
|
||||
{
|
||||
string newName = inc.ReadString();
|
||||
ushort ID = inc.ReadUInt16();
|
||||
|
||||
@@ -282,6 +282,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
inGameHUD.Update((float)Physics.step);
|
||||
|
||||
respawnManager.Update(deltaTime);
|
||||
|
||||
bool isCrewDead =
|
||||
connectedClients.Find(c => c.Character != null && !c.Character.IsDead)==null &&
|
||||
(myCharacter == null || myCharacter.IsDead);
|
||||
@@ -949,6 +951,8 @@ namespace Barotrauma.Networking
|
||||
GameServer.Log("Game mode: " + selectedMode.Name, Color.Cyan);
|
||||
GameServer.Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, Color.Cyan);
|
||||
|
||||
respawnManager = new RespawnManager(this);
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
List<CharacterInfo> characterInfos = new List<CharacterInfo>();
|
||||
@@ -972,7 +976,7 @@ namespace Barotrauma.Networking
|
||||
characterInfos.Add(characterInfo);
|
||||
}
|
||||
|
||||
WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos);
|
||||
WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
|
||||
|
||||
for (int i = 0; i < connectedClients.Count; i++)
|
||||
{
|
||||
@@ -1140,6 +1144,14 @@ namespace Barotrauma.Networking
|
||||
|
||||
}
|
||||
|
||||
public void RespawnClients()
|
||||
{
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
respawnManager.WriteNetworkEvent(msg);
|
||||
|
||||
SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
}
|
||||
|
||||
private void DisconnectClient(NetConnection senderConnection, string msg = "", string targetmsg = "")
|
||||
{
|
||||
Client client = connectedClients.Find(x => x.Connection == senderConnection);
|
||||
@@ -1611,7 +1623,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteCharacterData(NetOutgoingMessage message, string name, Character character)
|
||||
public void WriteCharacterData(NetOutgoingMessage message, string name, Character character)
|
||||
{
|
||||
message.Write(name);
|
||||
message.Write(character.ID);
|
||||
|
||||
@@ -39,7 +39,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
RequestFile, FileStream,
|
||||
|
||||
SpectateRequest
|
||||
SpectateRequest,
|
||||
|
||||
Respawn
|
||||
}
|
||||
|
||||
enum VoteType
|
||||
@@ -74,6 +76,9 @@ namespace Barotrauma.Networking
|
||||
protected Character myCharacter;
|
||||
protected CharacterInfo characterInfo;
|
||||
|
||||
|
||||
protected RespawnManager respawnManager;
|
||||
|
||||
public Voting Voting;
|
||||
|
||||
public Character Character
|
||||
|
||||
226
Subsurface/Source/Networking/RespawnManager.cs
Normal file
226
Subsurface/Source/Networking/RespawnManager.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using FarseerPhysics;
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
class RespawnManager
|
||||
{
|
||||
const int MinCharactersToRespawn = 1;
|
||||
|
||||
const float RespawnInterval = 20.0f;
|
||||
|
||||
enum State
|
||||
{
|
||||
Waiting,
|
||||
Transporting,
|
||||
Returning
|
||||
}
|
||||
|
||||
private NetworkMember networkMember;
|
||||
|
||||
private State state;
|
||||
|
||||
private Submarine respawnShuttle;
|
||||
private Steering shuttleSteering;
|
||||
private List<Door> shuttleDoors;
|
||||
|
||||
private float respawnTimer, shuttleReturnTimer;
|
||||
|
||||
public RespawnManager(NetworkMember server)
|
||||
{
|
||||
this.networkMember = server;
|
||||
|
||||
respawnShuttle = new Submarine("Submarines/Shuttle Mark I.sub");
|
||||
respawnShuttle.Load(false);
|
||||
|
||||
ResetShuttlePos();
|
||||
|
||||
respawnShuttle.GodMode = true;
|
||||
|
||||
shuttleDoors = new List<Door>();
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine != respawnShuttle) continue;
|
||||
|
||||
var steering = item.GetComponent<Steering>();
|
||||
if (steering != null) shuttleSteering = steering;
|
||||
|
||||
var door = item.GetComponent<Door>();
|
||||
if (door != null) shuttleDoors.Add(door);
|
||||
}
|
||||
|
||||
shuttleSteering.TargetPosition = ConvertUnits.ToSimUnits(Level.Loaded.StartPosition);
|
||||
|
||||
respawnTimer = RespawnInterval;
|
||||
}
|
||||
|
||||
private List<Client> GetClientsToRespawn()
|
||||
{
|
||||
return networkMember.ConnectedClients.FindAll(c => c.inGame && (c.Character == null || c.Character.IsDead));
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case State.Waiting:
|
||||
UpdateWaiting(deltaTime);
|
||||
break;
|
||||
case State.Transporting:
|
||||
UpdateTransporting(deltaTime);
|
||||
break;
|
||||
case State.Returning:
|
||||
UpdateReturning(deltaTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateWaiting(float deltaTime)
|
||||
{
|
||||
var server = networkMember as GameServer;
|
||||
if (server == null) return;
|
||||
|
||||
respawnShuttle.Velocity = Vector2.Zero;
|
||||
|
||||
shuttleSteering.AutoPilot = false;
|
||||
shuttleSteering.MaintainPos = false;
|
||||
|
||||
if (GetClientsToRespawn().Count < MinCharactersToRespawn) return;
|
||||
|
||||
if (respawnTimer % 10.0f < 5.0f && (respawnTimer - deltaTime) % 10.0f > 5.0f)
|
||||
{
|
||||
string time = respawnTimer <= 60.0f ?
|
||||
(int)respawnTimer + " seconds" :
|
||||
(int)Math.Floor(respawnTimer / 60.0f) + " minutes";
|
||||
|
||||
server.SendChatMessage("Transportation shuttle dispatching in " + time, ChatMessageType.Server);
|
||||
}
|
||||
|
||||
respawnTimer -= deltaTime;
|
||||
if (respawnTimer <= 0.0f)
|
||||
{
|
||||
Respawn();
|
||||
|
||||
respawnTimer = RespawnInterval;
|
||||
state = State.Transporting;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTransporting(float deltaTime)
|
||||
{
|
||||
if (Character.CharacterList.Any(c => c.Submarine == respawnShuttle && !c.IsDead)) return;
|
||||
|
||||
shuttleReturnTimer += deltaTime;
|
||||
if (shuttleReturnTimer > 10.0f)
|
||||
{
|
||||
state = State.Returning;
|
||||
shuttleReturnTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateReturning(float deltaTime)
|
||||
{
|
||||
shuttleReturnTimer += deltaTime;
|
||||
|
||||
if (shuttleReturnTimer > 1.0f)
|
||||
{
|
||||
shuttleSteering.AutoPilot = true;
|
||||
shuttleSteering.MaintainPos = false;
|
||||
|
||||
shuttleDoors.ForEach(s => s.IsOpen = false);
|
||||
|
||||
if (shuttleSteering.SteeringPath != null && shuttleSteering.SteeringPath.CurrentIndex == shuttleSteering.SteeringPath.Nodes.Count-1)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(
|
||||
ForceShuttleToPos(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f), 100.0f));
|
||||
|
||||
state = State.Waiting;
|
||||
}
|
||||
|
||||
shuttleReturnTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void Respawn()
|
||||
{
|
||||
var server = networkMember as GameServer;
|
||||
if (server == null) return;
|
||||
|
||||
ResetShuttlePos();
|
||||
|
||||
server.SendChatMessage("Transportation shuttle dispatched");
|
||||
|
||||
server.RespawnClients();
|
||||
|
||||
CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition, 100.0f));
|
||||
}
|
||||
|
||||
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
|
||||
{
|
||||
respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBodies[0]);
|
||||
|
||||
while (Math.Abs(position.Y - respawnShuttle.WorldPosition.Y) > 100.0f)
|
||||
{
|
||||
Vector2 displayVel = Vector2.Normalize(position - respawnShuttle.WorldPosition) * speed;
|
||||
respawnShuttle.SubBody.Body.LinearVelocity = ConvertUnits.ToSimUnits(displayVel);
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBodies[0]);
|
||||
|
||||
}
|
||||
|
||||
private void ResetShuttlePos()
|
||||
{
|
||||
respawnShuttle.SetPosition(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + 1000.0f));
|
||||
|
||||
respawnShuttle.Velocity = Vector2.Zero;
|
||||
}
|
||||
|
||||
public void WriteNetworkEvent(NetOutgoingMessage msg)
|
||||
{
|
||||
var server = networkMember as GameServer;
|
||||
var clients = GetClientsToRespawn();
|
||||
|
||||
msg.Write((byte)PacketTypes.Respawn);
|
||||
|
||||
var waypoints = WayPoint.SelectCrewSpawnPoints(clients.Select(c => c.characterInfo).ToList(), respawnShuttle);
|
||||
|
||||
msg.Write((byte)clients.Count);
|
||||
for (int i = 0; i < clients.Count; i++)
|
||||
{
|
||||
msg.Write((byte)clients[i].ID);
|
||||
clients[i].Character = Character.Create(clients[i].characterInfo, waypoints[i].WorldPosition, true, false);
|
||||
clients[i].Character.GiveJobItems(waypoints[i]);
|
||||
|
||||
GameMain.GameSession.CrewManager.characters.Add(clients[i].Character);
|
||||
|
||||
server.WriteCharacterData(msg, clients[i].Character.Name, clients[i].Character);
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadNetworkEvent(NetIncomingMessage inc)
|
||||
{
|
||||
ResetShuttlePos();
|
||||
|
||||
var client = networkMember as GameClient;
|
||||
|
||||
int clientCount = inc.ReadByte();
|
||||
for (int i = 0; i<clientCount; i++)
|
||||
{
|
||||
byte clientId = inc.ReadByte();
|
||||
|
||||
client.ReadCharacterData(inc, clientId == client.ID);
|
||||
}
|
||||
|
||||
CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition, 100.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
cam.Position = Vector2.Zero;
|
||||
cam.Position = Submarine.HiddenSubStartPosition;
|
||||
nameBox.Text = "";
|
||||
descriptionBox.Text = "";
|
||||
|
||||
@@ -401,6 +401,7 @@ namespace Barotrauma
|
||||
|
||||
if (selectedSub == null) return false;
|
||||
|
||||
Submarine.MainSub = selectedSub;
|
||||
selectedSub.Load(true);
|
||||
|
||||
nameBox.Text = selectedSub.Name;
|
||||
@@ -688,6 +689,9 @@ namespace Barotrauma
|
||||
|
||||
dummyCharacter.ControlLocalPlayer((float)deltaTime, cam, false);
|
||||
dummyCharacter.Control((float)deltaTime, cam);
|
||||
|
||||
dummyCharacter.Submarine = Submarine.MainSub;
|
||||
|
||||
cam.TargetPos = Vector2.Zero;
|
||||
|
||||
}
|
||||
|
||||
@@ -155,8 +155,8 @@ namespace Barotrauma
|
||||
|
||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||
{
|
||||
cam.UpdateTransform();
|
||||
|
||||
cam.UpdateTransform(true, true);
|
||||
|
||||
DrawMap(graphics, spriteBatch);
|
||||
|
||||
spriteBatch.Begin();
|
||||
@@ -177,7 +177,7 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch);
|
||||
|
||||
if (Character.Controlled == null && Submarine.Loaded != null) DrawSubmarineIndicator(spriteBatch, Submarine.MainSub);
|
||||
if (Character.Controlled == null && Submarine.MainSub != null) DrawSubmarineIndicator(spriteBatch, Submarine.MainSub);
|
||||
|
||||
GUI.Draw((float)deltaTime, spriteBatch, cam);
|
||||
|
||||
|
||||
BIN
Subsurface/Submarines/Shuttle Mark I.sub
Normal file
BIN
Subsurface/Submarines/Shuttle Mark I.sub
Normal file
Binary file not shown.
Reference in New Issue
Block a user