Unstable 1.8.4.0

This commit is contained in:
Markus Isberg
2025-03-12 12:56:27 +00:00
parent a4c3e868e4
commit a4a3427e4e
627 changed files with 29860 additions and 10018 deletions
@@ -1,4 +1,5 @@
using Barotrauma.Networking;
using Barotrauma.Extensions;
using Barotrauma.Networking;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -16,9 +17,15 @@ namespace Barotrauma
private static readonly Dictionary<Client, ConversationAction> lastActiveAction = new Dictionary<Client, ConversationAction>();
/// <summary>
/// Clients who this Conversation prompt is being currently shown to
/// </summary>
private readonly HashSet<Client> targetClients = new HashSet<Client>();
private readonly Dictionary<Client, DateTime> ignoredClients = new Dictionary<Client, DateTime>();
/// <summary>
/// Clients who this Conversation prompt is being currently shown to
/// </summary>
public IEnumerable<Client> TargetClients
{
get
@@ -51,29 +58,59 @@ namespace Barotrauma
}
}
public bool CanClientStartConversation(Client client)
{
if (!TargetTag.IsEmpty)
{
var targets = ParentEvent.GetTargets(TargetTag).Where(e => IsValidTarget(e));
return targets.Contains(client.Character);
}
return true;
}
public void IgnoreClient(Client c, float seconds)
{
if (!ignoredClients.ContainsKey(c)) { ignoredClients.Add(c, DateTime.Now); }
ignoredClients[c] = DateTime.Now + TimeSpan.FromSeconds(seconds);
//this action is not active for the client if they decided to ignore it
if (lastActiveAction.TryGetValue(c, out ConversationAction lastActive) && lastActive == this)
{
lastActiveAction.Remove(c);
}
Reset();
}
private bool IsBlockedByAnotherConversation(IEnumerable<Entity> targets, float duration)
{
foreach (Entity e in targets)
if (targets == null || targets.None())
{
if (e is not Character character || !character.IsRemotePlayer) { continue; }
Client targetClient = GameMain.Server.ConnectedClients.Find(c => c.Character == character);
if (targetClient != null)
//if the action doesn't target anyone in specific, it's shown to every client
foreach (var client in GameMain.Server.ConnectedClients)
{
if (lastActiveAction.ContainsKey(targetClient) &&
lastActiveAction[targetClient].ParentEvent != ParentEvent &&
Timing.TotalTime < lastActiveAction[targetClient].lastActiveTime + duration)
{
return true;
}
if (IsBlockedByAnotherConversation(client, duration)) { return true; }
}
}
else
{
foreach (Entity e in targets)
{
if (e is not Character character || !character.IsRemotePlayer) { continue; }
Client targetClient = GameMain.Server.ConnectedClients.Find(c => c.Character == character);
if (targetClient != null && IsBlockedByAnotherConversation(targetClient, duration)) { return true; }
}
}
return false;
}
private bool IsBlockedByAnotherConversation(Client targetClient, float duration)
{
if (lastActiveAction.ContainsKey(targetClient) &&
!lastActiveAction[targetClient].ParentEvent.IsFinished &&
lastActiveAction[targetClient].ParentEvent != ParentEvent &&
Timing.TotalTime < lastActiveAction[targetClient].lastActiveTime + duration)
{
return true;
}
return false;
}
@@ -91,6 +128,7 @@ namespace Barotrauma
{
targetClients.Add(targetClient);
lastActiveAction[targetClient] = this;
lastActiveTime = Timing.TotalTime;
ServerWrite(speaker, targetClient, interrupt);
}
}
@@ -99,12 +137,14 @@ namespace Barotrauma
{
foreach (Client c in GameMain.Server.ConnectedClients)
{
if (c.InGame && c.Character != null)
if (CanClientReceive(c))
{
if (targetCharacter == null || targetCharacter == c.Character)
{
targetClients.Add(c);
lastActiveAction[c] = this;
lastActiveTime = Timing.TotalTime;
DebugConsole.Log($"Sending conversationaction {ParentEvent.Prefab.Identifier} to client...");
ServerWrite(speaker, c, interrupt);
}
}
@@ -112,6 +152,18 @@ namespace Barotrauma
}
}
/// <summary>
/// Is it possible for the client to receive ConversationActions
/// (just checking if they're in game, controlling a character and not marked as ignoring the action,
/// but not accounting for whether this action targets them or not).
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
private bool CanClientReceive(Client c)
{
return c != null && c.InGame && c.Character != null && !ignoredClients.ContainsKey(c);
}
public void ServerWrite(Character speaker, Client client, bool interrupt)
{
IWriteMessage outmsg = new WriteOnlyMessage();