Update WifiComponent.cs
This commit is contained in:
+218
-241
@@ -1,4 +1,4 @@
|
|||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -8,219 +8,196 @@ using System.Xml.Linq;
|
|||||||
|
|
||||||
namespace Barotrauma.Items.Components
|
namespace Barotrauma.Items.Components
|
||||||
{
|
{
|
||||||
partial class WifiComponent : ItemComponent
|
partial class WifiComponent : ItemComponent
|
||||||
{
|
{
|
||||||
private static readonly List<WifiComponent> list = new List<WifiComponent>();
|
private static readonly List<WifiComponent> list = new List<WifiComponent>();
|
||||||
|
|
||||||
const int ChannelMemorySize = 10;
|
const int ChannelMemorySize = 10;
|
||||||
|
|
||||||
private float range;
|
private float range;
|
||||||
|
|
||||||
private int channel;
|
private int channel;
|
||||||
|
|
||||||
|
private float chatMsgCooldown;
|
||||||
|
|
||||||
private float chatMsgCooldown;
|
private string prevSignal;
|
||||||
|
|
||||||
private string prevSignal;
|
private int[] channelMemory = new int[ChannelMemorySize];
|
||||||
|
|
||||||
private int[] channelMemory = new int[ChannelMemorySize];
|
[Serialize(CharacterTeamType.None, true, description: "WiFi components can only communicate with components that have the same Team ID.", alwaysUseInstanceValues: true)]
|
||||||
|
public CharacterTeamType TeamID { get; set; }
|
||||||
|
|
||||||
[Serialize(CharacterTeamType.None, true, description: "WiFi components can only communicate with components that have the same Team ID.", alwaysUseInstanceValues: true)]
|
[Editable, Serialize(20000.0f, false, description: "How close the recipient has to be to receive a signal from this WiFi component.", alwaysUseInstanceValues: true)]
|
||||||
public CharacterTeamType TeamID { get; set; }
|
public float Range
|
||||||
|
{
|
||||||
[Editable, Serialize(20000.0f, false, description: "How close the recipient has to be to receive a signal from this WiFi component.", alwaysUseInstanceValues: true)]
|
get { return range; }
|
||||||
public float Range
|
set
|
||||||
{
|
{
|
||||||
get { return range; }
|
range = Math.Max(value, 0.0f);
|
||||||
set
|
|
||||||
{
|
|
||||||
range = Math.Max(value, 0.0f);
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
item.ResetCachedVisibleSize();
|
item.ResetCachedVisibleSize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[InGameEditable, Serialize(0, true, description: "WiFi components can only communicate with components that use the same channel.", alwaysUseInstanceValues: true)]
|
[InGameEditable, Serialize(0, true, description: "WiFi components can only communicate with components that use the same channel.", alwaysUseInstanceValues: true)]
|
||||||
public int Channel
|
public int Channel
|
||||||
{
|
{
|
||||||
get { return channel; }
|
get { return channel; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
channel = MathHelper.Clamp(value, 0, 10000);
|
channel = MathHelper.Clamp(value, 0, 10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Editable, Serialize(false, true, description: "Can the component communicate with wifi components in another team's submarine (e.g. enemy sub in Combat missions, respawn shuttle). Needs to be enabled on both the component transmitting the signal and the component receiving it.", alwaysUseInstanceValues: true)]
|
[Editable, Serialize(false, true, description: "Can the component communicate with wifi components in another team's submarine (e.g. enemy sub in Combat missions, respawn shuttle). Needs to be enabled on both the component transmitting the signal and the component receiving it.", alwaysUseInstanceValues: true)]
|
||||||
public bool AllowCrossTeamCommunication
|
public bool AllowCrossTeamCommunication
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionallyEditable(ConditionallyEditable.ConditionType.AllowLinkingWifiToChat)]
|
||||||
|
[Serialize(false, false, description: "If enabled, any signals received from another chat-linked wifi component are displayed " +
|
||||||
|
"as chat messages in the chatbox of the player holding the item.", alwaysUseInstanceValues: true)]
|
||||||
|
public bool LinkToChat
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Editable, Serialize(1.0f, true, description: "How many seconds have to pass between signals for a message to be displayed in the chatbox. " +
|
||||||
|
"Setting this to a very low value is not recommended, because it may cause an excessive amount of chat messages to be created " +
|
||||||
|
"if there are chat-linked wifi components that transmit a continuous signal.")]
|
||||||
|
public float MinChatMessageInterval
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
[Editable, Serialize(false, false, description: "If enabled, any signals received from another chat-linked wifi component are displayed " +
|
[Editable, Serialize(false, true, description: "If set to true, the component will only create chat messages when the received signal changes.")]
|
||||||
"as chat messages in the chatbox of the player holding the item.", alwaysUseInstanceValues: true)]
|
public bool DiscardDuplicateChatMessages
|
||||||
public bool LinkToChat
|
{
|
||||||
{
|
get;
|
||||||
get
|
set;
|
||||||
{
|
}
|
||||||
#if SERVER
|
|
||||||
return GameMain.Lua.game.allowWifiChat;
|
public WifiComponent(Item item, XElement element)
|
||||||
#endif
|
: base (item, element)
|
||||||
#if CLIENT
|
{
|
||||||
|
list.Add(this);
|
||||||
|
IsActive = true;
|
||||||
|
channelMemory = element.GetAttributeIntArray("channelmemory", new int[ChannelMemorySize]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnItemLoaded()
|
||||||
|
{
|
||||||
|
if (channelMemory.All(m => m == 0))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < channelMemory.Length; i++)
|
||||||
|
{
|
||||||
|
channelMemory[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanTransmit()
|
||||||
|
{
|
||||||
|
return HasRequiredContainedItems(user: null, addMessage: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<WifiComponent> GetReceiversInRange()
|
||||||
|
{
|
||||||
|
return list.Where(w => w != this && w.CanReceive(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanReceive(WifiComponent sender)
|
||||||
|
{
|
||||||
|
if (sender == null || sender.channel != channel) { return false; }
|
||||||
|
|
||||||
|
if (sender.TeamID != TeamID && !AllowCrossTeamCommunication)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
#endif
|
}
|
||||||
}
|
|
||||||
set { }
|
|
||||||
}
|
|
||||||
|
|
||||||
[Editable, Serialize(1.0f, true, description: "How many seconds have to pass between signals for a message to be displayed in the chatbox. " +
|
if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) { return false; }
|
||||||
"Setting this to a very low value is not recommended, because it may cause an excessive amount of chat messages to be created " +
|
|
||||||
"if there are chat-linked wifi components that transmit a continuous signal.")]
|
|
||||||
public float MinChatMessageInterval
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Editable, Serialize(false, true, description: "If set to true, the component will only create chat messages when the received signal changes.")]
|
return HasRequiredContainedItems(user: null, addMessage: false);
|
||||||
public bool DiscardDuplicateChatMessages
|
}
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WifiComponent(Item item, XElement element)
|
public override void Update(float deltaTime, Camera cam)
|
||||||
: base(item, element)
|
{
|
||||||
{
|
chatMsgCooldown -= deltaTime;
|
||||||
list.Add(this);
|
if (chatMsgCooldown <= 0.0f)
|
||||||
IsActive = true;
|
{
|
||||||
channelMemory = element.GetAttributeIntArray("channelmemory", new int[ChannelMemorySize]);
|
IsActive = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnItemLoaded()
|
public int GetChannelMemory(int index)
|
||||||
{
|
{
|
||||||
if (channelMemory.All(m => m == 0))
|
if (index < 0 || index >= ChannelMemorySize)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < channelMemory.Length; i++)
|
return 0;
|
||||||
{
|
}
|
||||||
channelMemory[i] = i;
|
return channelMemory[index];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanTransmit()
|
public void SetChannelMemory(int index, int value)
|
||||||
{
|
{
|
||||||
return HasRequiredContainedItems(user: null, addMessage: false);
|
if (index < 0 || index >= ChannelMemorySize)
|
||||||
}
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channelMemory[index] = MathHelper.Clamp(value, 0, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<WifiComponent> GetReceiversInRange()
|
public void TransmitSignal(Signal signal, bool sentFromChat)
|
||||||
{
|
{
|
||||||
return list.Where(w => w != this && w.CanReceive(this));
|
var senderComponent = signal.source?.GetComponent<WifiComponent>();
|
||||||
}
|
if (senderComponent != null && !CanReceive(senderComponent)) { return; }
|
||||||
|
|
||||||
public bool CanReceive(WifiComponent sender)
|
bool chatMsgSent = false;
|
||||||
{
|
|
||||||
if (sender == null || sender.channel != channel) { return false; }
|
|
||||||
|
|
||||||
if (sender.TeamID != TeamID && !AllowCrossTeamCommunication)
|
var receivers = GetReceiversInRange();
|
||||||
{
|
foreach (WifiComponent wifiComp in receivers)
|
||||||
return false;
|
{
|
||||||
}
|
if (sentFromChat && !wifiComp.LinkToChat) { continue; }
|
||||||
|
|
||||||
if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) { return false; }
|
//signal strength diminishes by distance
|
||||||
|
float sentSignalStrength = signal.strength *
|
||||||
|
MathHelper.Clamp(1.0f - (Vector2.Distance(item.WorldPosition, wifiComp.item.WorldPosition) / wifiComp.range), 0.0f, 1.0f);
|
||||||
|
Signal s = new Signal(signal.value, signal.stepsTaken, sender: signal.sender, source: signal.source,
|
||||||
|
power: 0.0f, strength: sentSignalStrength);
|
||||||
|
wifiComp.item.SendSignal(s, "signal_out");
|
||||||
|
|
||||||
|
if (signal.source != null)
|
||||||
|
{
|
||||||
|
foreach (Connection receiver in wifiComp.item.LastSentSignalRecipients)
|
||||||
|
{
|
||||||
|
if (!signal.source.LastSentSignalRecipients.Contains(receiver))
|
||||||
|
{
|
||||||
|
signal.source.LastSentSignalRecipients.Add(receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return HasRequiredContainedItems(user: null, addMessage: false);
|
if (DiscardDuplicateChatMessages && signal.value == prevSignal) { continue; }
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(float deltaTime, Camera cam)
|
//create a chat message
|
||||||
{
|
if (LinkToChat && wifiComp.LinkToChat && chatMsgCooldown <= 0.0f && !sentFromChat)
|
||||||
chatMsgCooldown -= deltaTime;
|
{
|
||||||
if (chatMsgCooldown <= 0.0f)
|
if (wifiComp.item.ParentInventory != null &&
|
||||||
{
|
wifiComp.item.ParentInventory.Owner != null)
|
||||||
IsActive = false;
|
{
|
||||||
}
|
string chatMsg = signal.value;
|
||||||
}
|
if (senderComponent != null)
|
||||||
|
{
|
||||||
public int GetChannelMemory(int index)
|
chatMsg = ChatMessage.ApplyDistanceEffect(chatMsg, 1.0f - sentSignalStrength);
|
||||||
{
|
}
|
||||||
if (index < 0 || index >= ChannelMemorySize)
|
if (chatMsg.Length > ChatMessage.MaxLength) { chatMsg = chatMsg.Substring(0, ChatMessage.MaxLength); }
|
||||||
{
|
if (string.IsNullOrEmpty(chatMsg)) { continue; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return channelMemory[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetChannelMemory(int index, int value)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= ChannelMemorySize)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
channelMemory[index] = MathHelper.Clamp(value, 0, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TransmitSignal(Signal signal, bool sentFromChat)
|
|
||||||
{
|
|
||||||
var senderComponent = signal.source?.GetComponent<WifiComponent>();
|
|
||||||
if (senderComponent != null && !CanReceive(senderComponent)) { return; }
|
|
||||||
|
|
||||||
bool chatMsgSent = false;
|
|
||||||
|
|
||||||
var receivers = GetReceiversInRange();
|
|
||||||
foreach (WifiComponent wifiComp in receivers)
|
|
||||||
{
|
|
||||||
if (sentFromChat && !wifiComp.LinkToChat) { continue; }
|
|
||||||
|
|
||||||
//signal strength diminishes by distance
|
|
||||||
float sentSignalStrength = signal.strength *
|
|
||||||
MathHelper.Clamp(1.0f - (Vector2.Distance(item.WorldPosition, wifiComp.item.WorldPosition) / wifiComp.range), 0.0f, 1.0f);
|
|
||||||
|
|
||||||
if (sentFromChat && wifiComp.LinkToChat)
|
|
||||||
{
|
|
||||||
|
|
||||||
//Signal s = new Signal(signal.value, signal.stepsTaken, sender: null, source: null, power: 0.0f, strength: sentSignalStrength);
|
|
||||||
|
|
||||||
signal.source = null;
|
|
||||||
|
|
||||||
wifiComp.item.SendSignal(signal, "signal_out");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Signal s = new Signal(signal.value, signal.stepsTaken, sender: signal.sender, source: signal.source, power: 0.0f, strength: sentSignalStrength);
|
|
||||||
|
|
||||||
wifiComp.item.SendSignal(s, "signal_out");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signal.source != null)
|
|
||||||
{
|
|
||||||
foreach (Connection receiver in wifiComp.item.LastSentSignalRecipients)
|
|
||||||
{
|
|
||||||
if (!signal.source.LastSentSignalRecipients.Contains(receiver))
|
|
||||||
{
|
|
||||||
signal.source.LastSentSignalRecipients.Add(receiver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DiscardDuplicateChatMessages && signal.value == prevSignal) { continue; }
|
|
||||||
|
|
||||||
//create a chat message
|
|
||||||
if (LinkToChat && wifiComp.LinkToChat && chatMsgCooldown <= 0.0f && !sentFromChat)
|
|
||||||
{
|
|
||||||
if (wifiComp.item.ParentInventory != null &&
|
|
||||||
wifiComp.item.ParentInventory.Owner != null)
|
|
||||||
{
|
|
||||||
string chatMsg = signal.value;
|
|
||||||
if (senderComponent != null)
|
|
||||||
{
|
|
||||||
chatMsg = ChatMessage.ApplyDistanceEffect(chatMsg, 1.0f - sentSignalStrength);
|
|
||||||
}
|
|
||||||
if (chatMsg.Length > ChatMessage.MaxLength) { chatMsg = chatMsg.Substring(0, ChatMessage.MaxLength); }
|
|
||||||
if (string.IsNullOrEmpty(chatMsg)) { continue; }
|
|
||||||
|
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (wifiComp.item.ParentInventory.Owner == Character.Controlled)
|
if (wifiComp.item.ParentInventory.Owner == Character.Controlled)
|
||||||
@@ -231,64 +208,64 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif SERVER
|
#elif SERVER
|
||||||
if (GameMain.Server != null)
|
if (GameMain.Server != null)
|
||||||
{
|
{
|
||||||
Client recipientClient = GameMain.Server.ConnectedClients.Find(c => c.Character == wifiComp.item.ParentInventory.Owner);
|
Client recipientClient = GameMain.Server.ConnectedClients.Find(c => c.Character == wifiComp.item.ParentInventory.Owner);
|
||||||
if (recipientClient != null)
|
if (recipientClient != null)
|
||||||
{
|
{
|
||||||
GameMain.Server.SendDirectChatMessage(
|
GameMain.Server.SendDirectChatMessage(
|
||||||
ChatMessage.Create(signal.source?.Name ?? "", chatMsg, ChatMessageType.Radio, null), recipientClient);
|
ChatMessage.Create(signal.source?.Name ?? "", chatMsg, ChatMessageType.Radio, null), recipientClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
chatMsgSent = true;
|
chatMsgSent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chatMsgSent)
|
if (chatMsgSent)
|
||||||
{
|
{
|
||||||
chatMsgCooldown = MinChatMessageInterval;
|
chatMsgCooldown = MinChatMessageInterval;
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevSignal = signal.value;
|
prevSignal = signal.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ReceiveSignal(Signal signal, Connection connection)
|
||||||
|
{
|
||||||
|
if (connection == null) { return; }
|
||||||
|
|
||||||
public override void ReceiveSignal(Signal signal, Connection connection)
|
switch (connection.Name)
|
||||||
{
|
{
|
||||||
if (connection == null) { return; }
|
case "signal_in":
|
||||||
|
TransmitSignal(signal, false);
|
||||||
|
break;
|
||||||
|
case "set_channel":
|
||||||
|
if (int.TryParse(signal.value, out int newChannel))
|
||||||
|
{
|
||||||
|
Channel = newChannel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "set_range":
|
||||||
|
if (float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newRange))
|
||||||
|
{
|
||||||
|
Range = newRange;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (connection.Name)
|
protected override void RemoveComponentSpecific()
|
||||||
{
|
{
|
||||||
case "signal_in":
|
base.RemoveComponentSpecific();
|
||||||
TransmitSignal(signal, false);
|
list.Remove(this);
|
||||||
break;
|
}
|
||||||
case "set_channel":
|
|
||||||
if (int.TryParse(signal.value, out int newChannel))
|
|
||||||
{
|
|
||||||
Channel = newChannel;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "set_range":
|
|
||||||
if (float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out float newRange))
|
|
||||||
{
|
|
||||||
Range = newRange;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void RemoveComponentSpecific()
|
public override XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
base.RemoveComponentSpecific();
|
var element = base.Save(parentElement);
|
||||||
list.Remove(this);
|
element.Add(new XAttribute("channelmemory", string.Join(',', channelMemory)));
|
||||||
}
|
return element;
|
||||||
|
}
|
||||||
public override XElement Save(XElement parentElement)
|
}
|
||||||
{
|
|
||||||
var element = base.Save(parentElement);
|
|
||||||
element.Add(new XAttribute("channelmemory", string.Join(',', channelMemory)));
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user