Unstable 1.8.4.0
This commit is contained in:
+64
-12
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user