2f107db...5202af9
This commit is contained in:
@@ -8,8 +8,8 @@ using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
class RespawnManager : Entity, IServerSerializable
|
||||
{
|
||||
partial class RespawnManager : Entity, IServerSerializable
|
||||
{
|
||||
public enum State
|
||||
{
|
||||
Waiting,
|
||||
@@ -116,60 +116,15 @@ namespace Barotrauma.Networking
|
||||
respawnShuttle = null;
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
if (networkMember is GameServer server)
|
||||
{
|
||||
respawnTimer = server.RespawnInterval;
|
||||
maxTransportTime = server.MaxTransportTime;
|
||||
}
|
||||
respawnTimer = server.ServerSettings.RespawnInterval;
|
||||
maxTransportTime = server.ServerSettings.MaxTransportTime;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private List<Client> GetClientsToRespawn()
|
||||
{
|
||||
return networkMember.ConnectedClients.FindAll(c =>
|
||||
c.InGame &&
|
||||
(!c.SpectateOnly || !((GameServer)networkMember).AllowSpectating) &&
|
||||
(c.Character == null || c.Character.IsDead));
|
||||
}
|
||||
|
||||
private List<CharacterInfo> GetBotsToRespawn()
|
||||
{
|
||||
GameServer server = networkMember as GameServer;
|
||||
|
||||
if (server.BotSpawnMode == BotSpawnMode.Normal)
|
||||
{
|
||||
return Character.CharacterList
|
||||
.FindAll(c => c.TeamID == 1 && c.AIController != null && c.Info != null && c.IsDead)
|
||||
.Select(c => c.Info)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
int currPlayerCount = server.ConnectedClients.Count(c => c.InGame && (!c.SpectateOnly || !server.AllowSpectating));
|
||||
if (server.CharacterInfo != null) currPlayerCount++;
|
||||
|
||||
var existingBots = Character.CharacterList
|
||||
.FindAll(c => c.TeamID == 1 && c.AIController != null && c.Info != null);
|
||||
|
||||
int requiredBots = server.BotCount - currPlayerCount;
|
||||
requiredBots -= existingBots.Count(b => !b.IsDead);
|
||||
|
||||
List<CharacterInfo> botsToRespawn = new List<CharacterInfo>();
|
||||
for (int i = 0; i < requiredBots; i++)
|
||||
{
|
||||
CharacterInfo botToRespawn = existingBots.Find(b => b.IsDead)?.Info;
|
||||
if (botToRespawn == null)
|
||||
{
|
||||
botToRespawn = new CharacterInfo(Character.HumanConfigFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingBots.Remove(botToRespawn.Character);
|
||||
}
|
||||
botsToRespawn.Add(botToRespawn);
|
||||
}
|
||||
return botsToRespawn;
|
||||
}
|
||||
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (respawnShuttle == null)
|
||||
@@ -194,61 +149,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateWaiting(float deltaTime)
|
||||
{
|
||||
var server = networkMember as GameServer;
|
||||
if (server == null)
|
||||
{
|
||||
if (CountdownStarted)
|
||||
{
|
||||
respawnTimer = Math.Max(0.0f, respawnTimer - deltaTime);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int characterToRespawnCount = GetClientsToRespawn().Count;
|
||||
int totalCharacterCount = server.ConnectedClients.Count;
|
||||
if (server.Character != null)
|
||||
{
|
||||
totalCharacterCount++;
|
||||
if (server.Character.IsDead) characterToRespawnCount++;
|
||||
}
|
||||
bool startCountdown = (float)characterToRespawnCount >= Math.Max((float)totalCharacterCount * server.MinRespawnRatio, 1.0f);
|
||||
|
||||
if (startCountdown)
|
||||
{
|
||||
if (!CountdownStarted)
|
||||
{
|
||||
CountdownStarted = true;
|
||||
server.CreateEntityEvent(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CountdownStarted = false;
|
||||
}
|
||||
|
||||
if (!CountdownStarted) return;
|
||||
|
||||
respawnTimer -= deltaTime;
|
||||
if (respawnTimer <= 0.0f)
|
||||
{
|
||||
respawnTimer = server.RespawnInterval;
|
||||
|
||||
DispatchShuttle();
|
||||
}
|
||||
|
||||
if (respawnShuttle == null) return;
|
||||
|
||||
respawnShuttle.Velocity = Vector2.Zero;
|
||||
|
||||
if (shuttleSteering != null)
|
||||
{
|
||||
shuttleSteering.AutoPilot = false;
|
||||
shuttleSteering.MaintainPos = false;
|
||||
}
|
||||
}
|
||||
|
||||
partial void UpdateWaiting(float deltaTime);
|
||||
|
||||
private void UpdateTransporting(float deltaTime)
|
||||
{
|
||||
//infinite transport time -> shuttle wont return
|
||||
@@ -256,14 +158,17 @@ namespace Barotrauma.Networking
|
||||
|
||||
shuttleTransportTimer -= deltaTime;
|
||||
|
||||
#if CLIENT
|
||||
GameClient nClient = networkMember as GameClient;
|
||||
if (shuttleTransportTimer + deltaTime > 15.0f && shuttleTransportTimer <= 15.0f &&
|
||||
networkMember.Character != null &&
|
||||
networkMember.Character.Submarine == respawnShuttle)
|
||||
nClient.Character != null &&
|
||||
nClient.Character.Submarine == respawnShuttle)
|
||||
{
|
||||
networkMember.AddChatMessage("The shuttle will automatically return back to the outpost. Please leave the shuttle immediately.", ChatMessageType.Server);
|
||||
nClient.AddChatMessage("ServerMessage.ShuttleLeaving", ChatMessageType.Server);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if SERVER
|
||||
var server = networkMember as GameServer;
|
||||
if (server == null) return;
|
||||
|
||||
@@ -281,10 +186,11 @@ namespace Barotrauma.Networking
|
||||
server.CreateEntityEvent(this);
|
||||
|
||||
CountdownStarted = false;
|
||||
maxTransportTime = server.MaxTransportTime;
|
||||
maxTransportTime = server.ServerSettings.MaxTransportTime;
|
||||
shuttleReturnTimer = maxTransportTime;
|
||||
shuttleTransportTimer = maxTransportTime;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void UpdateReturning(float deltaTime)
|
||||
@@ -311,13 +217,15 @@ namespace Barotrauma.Networking
|
||||
shuttleSteering.SetDestinationLevelStart();
|
||||
}
|
||||
|
||||
foreach (Door door in shuttleDoors)
|
||||
{
|
||||
if (door.IsOpen) door.SetState(false,false,true);
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
var server = networkMember as GameServer;
|
||||
if (server == null) return;
|
||||
|
||||
foreach (Door door in shuttleDoors)
|
||||
{
|
||||
if (door.IsOpen) door.TrySetState(false, false, true);
|
||||
}
|
||||
|
||||
var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == respawnShuttle && g.ConnectedWall != null);
|
||||
shuttleGaps.ForEach(g => Spawner.AddToRemoveQueue(g));
|
||||
@@ -350,46 +258,15 @@ namespace Barotrauma.Networking
|
||||
GameServer.Log("The respawn shuttle has left.", ServerLog.MessageType.Spawning);
|
||||
server.CreateEntityEvent(this);
|
||||
|
||||
respawnTimer = server.RespawnInterval;
|
||||
respawnTimer = server.ServerSettings.RespawnInterval;
|
||||
CountdownStarted = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private void DispatchShuttle()
|
||||
{
|
||||
var server = networkMember as GameServer;
|
||||
if (server == null) return;
|
||||
|
||||
if (respawnShuttle != null)
|
||||
{
|
||||
state = State.Transporting;
|
||||
server.CreateEntityEvent(this);
|
||||
|
||||
ResetShuttle();
|
||||
|
||||
if (shuttleSteering != null)
|
||||
{
|
||||
shuttleSteering.TargetVelocity = Vector2.Zero;
|
||||
}
|
||||
|
||||
GameServer.Log("Dispatching the respawn shuttle.", ServerLog.MessageType.Spawning);
|
||||
|
||||
RespawnCharacters();
|
||||
|
||||
CoroutineManager.StopCoroutines("forcepos");
|
||||
CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition - Vector2.UnitY * Level.ShaftHeight, 100.0f), "forcepos");
|
||||
}
|
||||
else
|
||||
{
|
||||
state = State.Waiting;
|
||||
GameServer.Log("Respawning everyone in main sub.", ServerLog.MessageType.Spawning);
|
||||
server.CreateEntityEvent(this);
|
||||
|
||||
RespawnCharacters();
|
||||
}
|
||||
}
|
||||
|
||||
partial void DispatchShuttle();
|
||||
|
||||
private IEnumerable<object> ForceShuttleToPos(Vector2 position, float speed)
|
||||
{
|
||||
if (respawnShuttle == null)
|
||||
@@ -468,8 +345,10 @@ namespace Barotrauma.Networking
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.Submarine != respawnShuttle) continue;
|
||||
|
||||
|
||||
#if CLIENT
|
||||
if (Character.Controlled == c) Character.Controlled = null;
|
||||
#endif
|
||||
c.Kill(CauseOfDeathType.Unknown, null, true);
|
||||
c.Enabled = false;
|
||||
|
||||
@@ -492,133 +371,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
}
|
||||
|
||||
partial void RespawnCharactersProjSpecific();
|
||||
public void RespawnCharacters()
|
||||
{
|
||||
var server = networkMember as GameServer;
|
||||
if (server == null) return;
|
||||
|
||||
var respawnSub = respawnShuttle ?? Submarine.MainSub;
|
||||
|
||||
var clients = GetClientsToRespawn();
|
||||
foreach (Client c in clients)
|
||||
{
|
||||
//all characters are in Team 1 in game modes/missions with only one team.
|
||||
//if at some point we add a game mode with multiple teams where respawning is possible, this needs to be reworked
|
||||
c.TeamID = 1;
|
||||
if (c.CharacterInfo == null) c.CharacterInfo = new CharacterInfo(Character.HumanConfigFile, c.Name);
|
||||
}
|
||||
List<CharacterInfo> characterInfos = clients.Select(c => c.CharacterInfo).ToList();
|
||||
|
||||
var botsToSpawn = GetBotsToRespawn();
|
||||
characterInfos.AddRange(botsToSpawn);
|
||||
|
||||
if (server.Character != null && server.Character.IsDead)
|
||||
{
|
||||
characterInfos.Add(server.CharacterInfo);
|
||||
}
|
||||
|
||||
server.AssignJobs(clients, server.Character != null && server.Character.IsDead);
|
||||
foreach (Client c in clients)
|
||||
{
|
||||
c.CharacterInfo.Job = new Job(c.AssignedJob);
|
||||
}
|
||||
|
||||
//the spawnpoints where the characters will spawn
|
||||
var shuttleSpawnPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, respawnSub);
|
||||
//the spawnpoints where they would spawn if they were spawned inside the main sub
|
||||
//(in order to give them appropriate ID card tags)
|
||||
var mainSubSpawnPoints = WayPoint.SelectCrewSpawnPoints(characterInfos, Submarine.MainSub);
|
||||
|
||||
ItemPrefab divingSuitPrefab = MapEntityPrefab.Find(null, "divingsuit") as ItemPrefab;
|
||||
ItemPrefab oxyPrefab = MapEntityPrefab.Find(null, "oxygentank") as ItemPrefab;
|
||||
ItemPrefab scooterPrefab = MapEntityPrefab.Find(null, "underwaterscooter") as ItemPrefab;
|
||||
ItemPrefab batteryPrefab = MapEntityPrefab.Find(null, "batterycell") as ItemPrefab;
|
||||
|
||||
var cargoSp = WayPoint.WayPointList.Find(wp => wp.Submarine == respawnSub && wp.SpawnType == SpawnType.Cargo);
|
||||
|
||||
for (int i = 0; i < characterInfos.Count; i++)
|
||||
{
|
||||
bool myCharacter = false;
|
||||
#if CLIENT
|
||||
myCharacter = i >= clients.Count + botsToSpawn.Count;
|
||||
#endif
|
||||
bool bot = i >= clients.Count && !myCharacter;
|
||||
|
||||
var character = Character.Create(characterInfos[i], shuttleSpawnPoints[i].WorldPosition, characterInfos[i].Name, !myCharacter && !bot, bot);
|
||||
character.TeamID = 1;
|
||||
|
||||
#if CLIENT
|
||||
GameMain.GameSession.CrewManager.AddCharacter(character);
|
||||
|
||||
if (myCharacter)
|
||||
{
|
||||
server.Character = character;
|
||||
Character.Controlled = character;
|
||||
|
||||
GameMain.LightManager.LosEnabled = true;
|
||||
GameServer.Log(string.Format("Respawning {0} (host) as {1}", character.Name, characterInfos[i].Job.Name), ServerLog.MessageType.Spawning);
|
||||
}
|
||||
#endif
|
||||
if (!myCharacter)
|
||||
{
|
||||
if (bot)
|
||||
{
|
||||
GameServer.Log(string.Format("Respawning bot {0} as {1}", character.Info.Name, characterInfos[i].Job.Name), ServerLog.MessageType.Spawning);
|
||||
}
|
||||
else
|
||||
{
|
||||
clients[i].Character = character;
|
||||
character.OwnerClientIP = clients[i].Connection.RemoteEndPoint.Address.ToString();
|
||||
character.OwnerClientName = clients[i].Name;
|
||||
GameServer.Log(string.Format("Respawning {0} ({1}) as {2}", clients[i].Name, clients[i].Connection?.RemoteEndPoint?.Address, characterInfos[i].Job.Name), ServerLog.MessageType.Spawning);
|
||||
}
|
||||
}
|
||||
|
||||
if (divingSuitPrefab != null && oxyPrefab != null && respawnShuttle != null)
|
||||
{
|
||||
Vector2 pos = cargoSp == null ? character.Position : cargoSp.Position;
|
||||
if (divingSuitPrefab != null && oxyPrefab != null)
|
||||
{
|
||||
var divingSuit = new Item(divingSuitPrefab, pos, respawnSub);
|
||||
Spawner.CreateNetworkEvent(divingSuit, false);
|
||||
respawnItems.Add(divingSuit);
|
||||
|
||||
var oxyTank = new Item(oxyPrefab, pos, respawnSub);
|
||||
Spawner.CreateNetworkEvent(oxyTank, false);
|
||||
divingSuit.Combine(oxyTank);
|
||||
respawnItems.Add(oxyTank);
|
||||
}
|
||||
|
||||
if (scooterPrefab != null && batteryPrefab != null)
|
||||
{
|
||||
var scooter = new Item(scooterPrefab, pos, respawnSub);
|
||||
Spawner.CreateNetworkEvent(scooter, false);
|
||||
|
||||
var battery = new Item(batteryPrefab, pos, respawnSub);
|
||||
Spawner.CreateNetworkEvent(battery, false);
|
||||
|
||||
scooter.Combine(battery);
|
||||
respawnItems.Add(scooter);
|
||||
respawnItems.Add(battery);
|
||||
}
|
||||
}
|
||||
|
||||
//give the character the items they would've gotten if they had spawned in the main sub
|
||||
character.GiveJobItems(mainSubSpawnPoints[i]);
|
||||
|
||||
//add the ID card tags they should've gotten when spawning in the shuttle
|
||||
foreach (Item item in character.Inventory.Items)
|
||||
{
|
||||
if (item == null || item.Prefab.Name != "ID Card") continue;
|
||||
foreach (string s in shuttleSpawnPoints[i].IdCardTags)
|
||||
{
|
||||
item.AddTag(s);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(shuttleSpawnPoints[i].IdCardDesc))
|
||||
item.Description = shuttleSpawnPoints[i].IdCardDesc;
|
||||
}
|
||||
}
|
||||
|
||||
RespawnCharactersProjSpecific();
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
|
||||
Reference in New Issue
Block a user