- camera follows the closest sub

- WIP "respawn shuttle"
- submarine size affects its mass
- electricity fixes
This commit is contained in:
Regalis
2016-06-18 14:46:40 +03:00
parent cf822cfae6
commit dc7956274c
23 changed files with 413 additions and 99 deletions

2
.gitignore vendored
View File

@@ -10,6 +10,8 @@ bld/
[Bb]in/
[Oo]bj/
*.suo
#performance reports & sessions
*.vsp
*.psess

View File

@@ -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

View File

@@ -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"

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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++)
{

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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())
{

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View 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));
}
}
}

View File

@@ -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;
}

View File

@@ -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);

Binary file not shown.