Unstable 1.8.4.0
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
using Barotrauma.Networking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -24,7 +22,7 @@ namespace Barotrauma
|
||||
character.WriteSpawnData(msg, character.ID, restrictMessageSize: false);
|
||||
msg.WriteBoolean(requireKill.Contains(character));
|
||||
msg.WriteBoolean(requireRescue.Contains(character));
|
||||
msg.WriteUInt16((ushort)characterItems[character].Count());
|
||||
msg.WriteUInt16((ushort)characterItems[character].Count);
|
||||
foreach (Item item in characterItems[character])
|
||||
{
|
||||
item.WriteSpawnData(msg, item.ID, item.ParentInventory?.Owner?.ID ?? Entity.NullEntityID, 0, item.ParentInventory?.FindIndex(item) ?? -1);
|
||||
|
||||
@@ -1,20 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
#nullable enable
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class CombatMission
|
||||
{
|
||||
class KillCount
|
||||
{
|
||||
public readonly Character Victim;
|
||||
public readonly Client? VictimClient;
|
||||
public readonly Character? Killer;
|
||||
public readonly Client? KillerClient;
|
||||
public KillCount(Character victim, Character? killer)
|
||||
{
|
||||
Victim = victim;
|
||||
VictimClient = GameMain.Server.ConnectedClients.FirstOrDefault(c => victim.IsClientOwner(c));
|
||||
Killer = killer;
|
||||
if (killer != null)
|
||||
{
|
||||
KillerClient = GameMain.Server.ConnectedClients.FirstOrDefault(c => killer.IsClientOwner(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const float RoundEndDuration = 5.0f;
|
||||
|
||||
private readonly bool[] teamDead = new bool[2];
|
||||
|
||||
/// <summary>
|
||||
/// Lists of characters currently alive in the teams
|
||||
/// </summary>
|
||||
private List<Character>[] crews;
|
||||
|
||||
private bool initialized = false;
|
||||
/// <summary>
|
||||
/// List of all kills (of the characters in either team) during the round
|
||||
/// </summary>
|
||||
private readonly List<KillCount> kills = new List<KillCount>();
|
||||
|
||||
private float roundEndTimer;
|
||||
|
||||
private float timeInTargetSubmarineTimer;
|
||||
|
||||
public override LocalizedString Description
|
||||
{
|
||||
get
|
||||
@@ -28,51 +58,16 @@ namespace Barotrauma
|
||||
|
||||
protected override void UpdateMissionSpecific(float deltaTime)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
crews[0].Clear();
|
||||
crews[1].Clear();
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (character.TeamID == CharacterTeamType.Team1)
|
||||
{
|
||||
crews[0].Add(character);
|
||||
}
|
||||
else if (character.TeamID == CharacterTeamType.Team2)
|
||||
{
|
||||
crews[1].Add(character);
|
||||
}
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
if (crews[0].Count == 0 || crews[1].Count == 0)
|
||||
{
|
||||
//if there are no characters in either crew, end the round
|
||||
teamDead[0] = teamDead[1] = true;
|
||||
state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
teamDead[0] = crews[0].All(c => c.IsDead || c.IsIncapacitated);
|
||||
teamDead[1] = crews[1].All(c => c.IsDead || c.IsIncapacitated);
|
||||
if (teamDead[0] && teamDead[1]) { state = 1; }
|
||||
}
|
||||
CheckTeamCharacters();
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
CheckWinCondition(deltaTime);
|
||||
for (int i = 0; i < teamDead.Length; i++)
|
||||
{
|
||||
if (!teamDead[i] && teamDead[1 - i])
|
||||
{
|
||||
//make sure nobody in the other team can be revived because that would be pretty weird
|
||||
crews[1 - i].ForEach(c => { if (!c.IsDead) c.Kill(CauseOfDeathType.Unknown, null); });
|
||||
|
||||
GameMain.GameSession.WinningTeam = i == 0 ? CharacterTeamType.Team1 : CharacterTeamType.Team2;
|
||||
|
||||
//state 1 = team 1 won, 2 = team 2 won
|
||||
State = i + 1;
|
||||
SetWinningTeam(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -85,7 +80,7 @@ namespace Barotrauma
|
||||
if (teamDead[0] && teamDead[1])
|
||||
{
|
||||
GameMain.GameSession.WinningTeam = CharacterTeamType.None;
|
||||
if (GameMain.Server != null) { GameMain.Server.EndGame(); }
|
||||
GameMain.Server?.EndGame();
|
||||
}
|
||||
else if (GameMain.GameSession.WinningTeam != CharacterTeamType.None)
|
||||
{
|
||||
@@ -93,5 +88,180 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTeamCharacters()
|
||||
{
|
||||
for (int i = 0; i < crews.Length; i++)
|
||||
{
|
||||
foreach (var character in crews[i])
|
||||
{
|
||||
if (character.IsDead)
|
||||
{
|
||||
AddKill(character);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crews[0].Clear();
|
||||
crews[1].Clear();
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (character.IsDead) { continue; }
|
||||
if (character.TeamID == CharacterTeamType.Team1)
|
||||
{
|
||||
crews[0].Add(character);
|
||||
}
|
||||
else if (character.TeamID == CharacterTeamType.Team2)
|
||||
{
|
||||
crews[1].Add(character);
|
||||
}
|
||||
if (character.IsBot && character.AIController is HumanAIController humanAi)
|
||||
{
|
||||
if (!humanAi.ObjectiveManager.HasOrder<AIObjectiveFightIntruders>(o => o.TargetCharactersInOtherSubs) &&
|
||||
OrderPrefab.Prefabs.TryGet(Tags.AssaultEnemyOrder, out OrderPrefab? assaultOrder))
|
||||
{
|
||||
character.SetOrder(assaultOrder.CreateInstance(
|
||||
OrderPrefab.OrderTargetType.Entity, orderGiver: null).WithManualPriority(CharacterInfo.HighestManualOrderPriority),
|
||||
isNewOrder: true, speak: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckWinCondition(float deltaTime)
|
||||
{
|
||||
switch (winCondition)
|
||||
{
|
||||
case WinCondition.LastManStanding:
|
||||
if (crews[0].Count == 0 || crews[1].Count == 0)
|
||||
{
|
||||
//if there are no characters in either crew, end the round
|
||||
teamDead[0] = teamDead[1] = true;
|
||||
state = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
teamDead[0] = crews[0].All(c => c.IsDead || c.IsIncapacitated);
|
||||
teamDead[1] = crews[1].All(c => c.IsDead || c.IsIncapacitated);
|
||||
if (teamDead[0] && teamDead[1]) { state = 1; }
|
||||
}
|
||||
break;
|
||||
case WinCondition.KillCount:
|
||||
//no need to do anything, kills are counted in AddKill
|
||||
break;
|
||||
case WinCondition.ControlSubmarine:
|
||||
CheckTargetSubmarineControl(deltaTime);
|
||||
break;
|
||||
}
|
||||
CheckScore();
|
||||
}
|
||||
|
||||
private void CheckScore()
|
||||
{
|
||||
for (int i = 0; i < crews.Length; i++)
|
||||
{
|
||||
if (Scores[i] >= WinScore)
|
||||
{
|
||||
SetWinningTeam(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTargetSubmarineControl(float deltaTime)
|
||||
{
|
||||
if (targetSubmarine == null) { return; }
|
||||
|
||||
//score updates at 1 second intervals, so the score represents the time in seconds
|
||||
timeInTargetSubmarineTimer += deltaTime;
|
||||
if (timeInTargetSubmarineTimer < 1.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
timeInTargetSubmarineTimer = 0.0f;
|
||||
|
||||
bool crew1InSubmarine = crews[0].Any(c => c.Submarine == targetSubmarine);
|
||||
bool crew2InSubmarine = crews[1].Any(c => c.Submarine == targetSubmarine);
|
||||
|
||||
for (int i = 0; i < crews.Length; i++)
|
||||
{
|
||||
if (crews[i].Any(c => c.Submarine == targetSubmarine) &&
|
||||
crews[1 - i].None(c => c.Submarine == targetSubmarine))
|
||||
{
|
||||
Scores[i]++;
|
||||
GameMain.Server?.UpdateMissionState(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToScore(CharacterTeamType team, int amount)
|
||||
{
|
||||
if (!HasWinScore) { return; }
|
||||
int index;
|
||||
switch (team)
|
||||
{
|
||||
case CharacterTeamType.Team1:
|
||||
index = 0;
|
||||
break;
|
||||
case CharacterTeamType.Team2:
|
||||
index = 1;
|
||||
break;
|
||||
default:
|
||||
DebugConsole.AddSafeError($"Attempted to increase the score of an invalid team ({team}).");
|
||||
return;
|
||||
}
|
||||
Scores[index] = MathHelper.Clamp(Scores[index] + amount, 0, WinScore);
|
||||
GameMain.Server?.UpdateMissionState(this);
|
||||
}
|
||||
|
||||
private void AddKill(Character character)
|
||||
{
|
||||
kills.Add(new KillCount(character, character.CauseOfDeath?.Killer));
|
||||
if (winCondition == WinCondition.KillCount)
|
||||
{
|
||||
Scores[character.TeamID == CharacterTeamType.Team1 ? 1 : 0] += PointsPerKill;
|
||||
}
|
||||
GameMain.Server?.UpdateMissionState(this);
|
||||
}
|
||||
|
||||
private void SetWinningTeam(int teamIndex)
|
||||
{
|
||||
//state 1 = team 1 won, 2 = team 2 won
|
||||
State = teamIndex + 1;
|
||||
GameMain.GameSession.WinningTeam = teamIndex == 0 ? CharacterTeamType.Team1 : CharacterTeamType.Team2;
|
||||
}
|
||||
|
||||
public override void ServerWrite(IWriteMessage msg)
|
||||
{
|
||||
base.ServerWrite(msg);
|
||||
msg.WriteUInt16((ushort)Scores[0]);
|
||||
msg.WriteUInt16((ushort)Scores[1]);
|
||||
|
||||
IEnumerable<Client> uniqueClients = kills
|
||||
.Select(k => k.VictimClient)
|
||||
.Union(kills.Select(k => k.KillerClient))
|
||||
.NotNull();
|
||||
msg.WriteVariableUInt32((uint)uniqueClients.Count());
|
||||
foreach (Client client in uniqueClients)
|
||||
{
|
||||
msg.WriteByte(client.SessionId);
|
||||
msg.WriteVariableUInt32((uint)kills.Count(k => k.VictimClient == client));
|
||||
msg.WriteVariableUInt32((uint)kills.Count(k => k.KillerClient == client));
|
||||
}
|
||||
|
||||
IEnumerable<CharacterInfo> uniqueBots = kills
|
||||
.Select(k => k.Killer)
|
||||
.Union(kills.Select(k => k.Victim))
|
||||
.NotNull()
|
||||
.Where(c => c.Info != null && c.IsBot)
|
||||
.Select(c => c.Info);
|
||||
msg.WriteVariableUInt32((uint)uniqueBots.Count());
|
||||
foreach (CharacterInfo botInfo in uniqueBots)
|
||||
{
|
||||
msg.WriteUInt16(botInfo.ID);
|
||||
msg.WriteVariableUInt32((uint)kills.Count(k => k.Victim?.Info == botInfo));
|
||||
msg.WriteVariableUInt32((uint)kills.Count(k => k.Killer?.Info == botInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,15 +29,26 @@ namespace Barotrauma
|
||||
public override void ServerWriteInitial(IWriteMessage msg, Client c)
|
||||
{
|
||||
base.ServerWriteInitial(msg, c);
|
||||
|
||||
msg.WriteByte((byte)characters.Count);
|
||||
foreach (Character character in characters)
|
||||
{
|
||||
character.WriteSpawnData(msg, character.ID, restrictMessageSize: false);
|
||||
var items = characterItems[character];
|
||||
msg.WriteUInt16((ushort)items.Count);
|
||||
foreach (Item item in items)
|
||||
{
|
||||
item.WriteSpawnData(msg, item.ID, item.ParentInventory?.Owner?.ID ?? Entity.NullEntityID, 0, item.ParentInventory?.FindIndex(item) ?? -1);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var target in targets)
|
||||
{
|
||||
bool targetFound = spawnInfo.ContainsKey(target) && target.Item != null;
|
||||
bool targetFound = spawnInfo.TryGetValue(target, out SpawnInfo sInfo) && target.Item != null;
|
||||
msg.WriteBoolean(targetFound);
|
||||
if (!targetFound) { continue; }
|
||||
|
||||
msg.WriteBoolean(spawnInfo[target].UsedExistingItem);
|
||||
if (spawnInfo[target].UsedExistingItem)
|
||||
msg.WriteBoolean(sInfo.UsedExistingItem);
|
||||
if (sInfo.UsedExistingItem)
|
||||
{
|
||||
msg.WriteUInt16(target.Item.ID);
|
||||
}
|
||||
@@ -45,14 +56,14 @@ namespace Barotrauma
|
||||
{
|
||||
target.Item.WriteSpawnData(msg,
|
||||
target.Item.ID,
|
||||
spawnInfo[target].OriginalInventoryID,
|
||||
spawnInfo[target].OriginalItemContainerIndex,
|
||||
spawnInfo[target].OriginalSlotIndex);
|
||||
sInfo.OriginalInventoryID,
|
||||
sInfo.OriginalItemContainerIndex,
|
||||
sInfo.OriginalSlotIndex);
|
||||
msg.WriteUInt16(target.ParentTarget?.Item?.ID ?? Entity.NullEntityID);
|
||||
}
|
||||
|
||||
msg.WriteByte((byte)spawnInfo[target].ExecutedEffectIndices.Count);
|
||||
foreach ((int listIndex, int effectIndex) in spawnInfo[target].ExecutedEffectIndices)
|
||||
msg.WriteByte((byte)sInfo.ExecutedEffectIndices.Count);
|
||||
foreach ((int listIndex, int effectIndex) in sInfo.ExecutedEffectIndices)
|
||||
{
|
||||
msg.WriteByte((byte)listIndex);
|
||||
msg.WriteByte((byte)effectIndex);
|
||||
@@ -64,9 +75,9 @@ namespace Barotrauma
|
||||
{
|
||||
base.ServerWrite(msg);
|
||||
msg.WriteByte((byte)targets.Count);
|
||||
for (int i = 0; i < targets.Count; i++)
|
||||
foreach (Target t in targets)
|
||||
{
|
||||
msg.WriteByte((byte)targets[i].State);
|
||||
msg.WriteByte((byte)t.State);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -12,9 +13,9 @@ namespace Barotrauma
|
||||
{
|
||||
item.WriteSpawnData(msg,
|
||||
item.ID,
|
||||
parentInventoryIDs.ContainsKey(item) ? parentInventoryIDs[item] : Entity.NullEntityID,
|
||||
parentItemContainerIndices.ContainsKey(item) ? parentItemContainerIndices[item] : (byte)0,
|
||||
inventorySlotIndices.ContainsKey(item) ? inventorySlotIndices[item] : -1);
|
||||
parentInventoryIDs.GetValueOrDefault(item, Entity.NullEntityID),
|
||||
parentItemContainerIndices.GetValueOrDefault(item, (byte)0),
|
||||
inventorySlotIndices.GetValueOrDefault(item, -1));
|
||||
}
|
||||
ServerWriteScanTargetStatus(msg);
|
||||
}
|
||||
@@ -30,7 +31,7 @@ namespace Barotrauma
|
||||
msg.WriteByte((byte)scanTargets.Count);
|
||||
foreach (var kvp in scanTargets)
|
||||
{
|
||||
msg.WriteUInt16(kvp.Key != null ? kvp.Key.ID : Entity.NullEntityID);
|
||||
msg.WriteUInt16(kvp.Key?.ID ?? Entity.NullEntityID);
|
||||
msg.WriteBoolean(kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user