Mid-round chat messages have a limited range, headset item which can be used to communicate with players further away, new inventory slot for items like masks and headsets

This commit is contained in:
Regalis
2016-04-20 17:19:38 +03:00
parent a45f58cd08
commit e33f30dad1
21 changed files with 597 additions and 177 deletions

View File

@@ -0,0 +1,136 @@
using Barotrauma.Items.Components;
using Barotrauma.Networking.ReliableMessages;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Barotrauma.Networking
{
enum ChatMessageType
{
Default, Error, Dead, Server, Radio
}
class ChatMessage
{
public const float SpeakRange = 2000.0f;
public static Color[] MessageColor = { Color.White, Color.Red, new Color(63, 72, 204), Color.LightGreen, Color.Yellow };
public readonly string Text;
public ChatMessageType Type;
public readonly Character Sender;
public readonly string SenderName;
public Color Color
{
get { return MessageColor[(int)Type]; }
}
public string TextWithSender
{
get;
private set;
}
private ChatMessage(string senderName, string text, ChatMessageType type, Character sender)
{
Text = text;
Type = type;
Sender = sender;
SenderName = senderName;
TextWithSender = string.IsNullOrWhiteSpace(senderName) ? text : senderName + ": " + text;
}
public static ChatMessage Create(string senderName, string text, ChatMessageType type, Character sender)
{
return new ChatMessage(senderName, text, type, sender);
}
public static string GetChatMessageCommand(string message, out string messageWithoutCommand)
{
messageWithoutCommand = message;
int separatorIndex = message.IndexOf(";");
if (separatorIndex == -1) return "";
//int colonIndex = message.IndexOf(":");
string command = "";
try
{
command = message.Substring(0, separatorIndex);
command = command.Trim();
}
catch
{
return command;
}
messageWithoutCommand = message.Substring(separatorIndex + 1, message.Length - separatorIndex - 1).TrimStart();
return command;
}
public string ApplyDistanceEffect(Character listener)
{
if (Sender == null) return Text;
return ApplyDistanceEffect(listener, Sender, Text, SpeakRange);
}
public static string ApplyDistanceEffect(Entity listener, Entity Sender, string text, float range)
{
if (listener.WorldPosition == Sender.WorldPosition) return text;
float dist = Vector2.Distance(listener.WorldPosition, Sender.WorldPosition);
if (dist > range) return "";
if (Submarine.CheckVisibility(listener.SimPosition, Sender.SimPosition) != null) dist *= 2.0f;
if (dist > range) return "";
float garbleAmount = dist / range;
if (garbleAmount < 0.5f) return text;
int startIndex = Math.Max(text.IndexOf(':') + 1, 1);
StringBuilder sb = new StringBuilder(text.Length);
for (int i = 0; i < text.Length; i++)
{
sb.Append((i>startIndex && Rand.Range(0.0f, 1.0f) < garbleAmount) ? '-' : text[i]);
}
return sb.ToString();
}
public void WriteNetworkMessage(NetOutgoingMessage msg)
{
msg.WriteRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length, (byte)Type);
msg.Write(Sender == null ? (ushort)0 : Sender.ID);
msg.Write(SenderName);
msg.Write(Text);
}
public static ChatMessage ReadNetworkMessage(NetBuffer msg)
{
ChatMessageType type = (ChatMessageType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length);
ushort senderId = msg.ReadUInt16();
string senderName = msg.ReadString();
string text = msg.ReadString();
return new ChatMessage(senderName, text, type, Entity.FindEntityByID(senderId) as Character);
}
}
}

View File

@@ -5,6 +5,8 @@ using System.Collections.Generic;
using Barotrauma.Networking.ReliableMessages;
using FarseerPhysics;
using System.IO;
using System.Linq;
using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
@@ -555,9 +557,9 @@ namespace Barotrauma.Networking
break;
case (byte)PacketTypes.Chatmessage:
ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
//ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
AddChatMessage(inc.ReadString(), messageType);
AddChatMessage(ChatMessage.ReadNetworkMessage(inc));
break;
case (byte)PacketTypes.NetworkEvent:
//read the data from the message and update client state accordingly
@@ -958,19 +960,33 @@ namespace Barotrauma.Networking
return character;
}
public override void SendChatMessage(string message, ChatMessageType type = ChatMessageType.Default)
public override void SendChatMessage(string message)
{
//AddChatMessage(message);
if (client.ServerConnection == null) return;
type = (Screen.Selected == GameMain.GameScreen &&
(myCharacter == null || myCharacter.IsDead)) ? ChatMessageType.Dead : ChatMessageType.Default;
var type = ChatMessageType.Default;
if (Screen.Selected == GameMain.GameScreen && (myCharacter == null || myCharacter.IsDead))
{
type = ChatMessageType.Dead;
}
else
{
string command = ChatMessage.GetChatMessageCommand(message, out message).ToLower();
if (CanUseRadio(Character.Controlled)) type = ChatMessageType.Radio;
}
var chatMessage = ChatMessage.Create(
gameStarted && myCharacter != null ? myCharacter.Name : name,
message, type, gameStarted ? myCharacter : null);
ReliableMessage msg = reliableChannel.CreateMessage();
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
msg.InnerMessage.Write((byte)type);
msg.InnerMessage.Write(message);
chatMessage.WriteNetworkMessage(msg.InnerMessage);
reliableChannel.SendMessage(msg, client.ServerConnection);
}

View File

@@ -7,6 +7,7 @@ using Lidgren.Network;
using Microsoft.Xna.Framework;
using RestSharp;
using Barotrauma.Networking.ReliableMessages;
using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
@@ -503,9 +504,10 @@ namespace Barotrauma.Networking
break;
case (byte)PacketTypes.Chatmessage:
ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
//SendChatMessage(ChatMessage.ReadNetworkMessage(inc));
//!!!!!!!!!!!
SendChatMessage(inc.ReadString(), messageType);
ReadChatMessage(inc);
break;
case (byte)PacketTypes.PlayerLeft:
@@ -953,7 +955,8 @@ namespace Barotrauma.Networking
GameMain.GameScreen.Select();
AddChatMessage("Press TAB to chat. Use ''d;'' to talk to dead players and spectators, and ''player name;'' to only send the message to a specific player.", ChatMessageType.Server);
AddChatMessage("Press TAB to chat. Use ''d;'' to talk to dead players and spectators, "
+"and ''player name;'' to only send the message to a specific player.", ChatMessageType.Server);
yield return CoroutineStatus.Success;
}
@@ -1081,7 +1084,7 @@ namespace Barotrauma.Networking
if (string.IsNullOrWhiteSpace(msg)) msg = client.name + " has left the server";
if (string.IsNullOrWhiteSpace(targetmsg)) targetmsg = "You have left the server";
Log(msg, messageColor[(int)ChatMessageType.Server]);
Log(msg, ChatMessage.MessageColor[(int)ChatMessageType.Server]);
NetOutgoingMessage outmsg = server.CreateMessage();
outmsg.Write((byte)PacketTypes.KickedOut);
@@ -1370,33 +1373,79 @@ namespace Barotrauma.Networking
}
return true;
}
public override void SendChatMessage(string message, ChatMessageType type = ChatMessageType.Server)
private void ReadChatMessage(NetIncomingMessage inc)
{
ChatMessage message = ChatMessage.ReadNetworkMessage(inc);
List<Client> recipients = new List<Client>();
foreach (Client c in ConnectedClients)
{
switch (message.Type)
{
case ChatMessageType.Dead:
if (c.Character != null && !c.Character.IsDead) continue;
break;
case ChatMessageType.Default:
if (message.Sender != null && c.Character != null && message.Sender != c.Character)
{
if (Vector2.Distance(message.Sender.WorldPosition, c.Character.WorldPosition) > ChatMessage.SpeakRange) continue;
}
break;
case ChatMessageType.Radio:
if (message.Sender == null) return;
var radio = message.Sender.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
if (radio == null) message.Type = ChatMessageType.Default;
break;
}
recipients.Add(c);
}
AddChatMessage(message);
foreach (Client c in recipients)
{
ReliableMessage msg = c.ReliableChannel.CreateMessage();
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
//msg.InnerMessage.Write((byte)type);
//msg.InnerMessage.Write(message);
message.WriteNetworkMessage(msg.InnerMessage);
c.ReliableChannel.SendMessage(msg, c.Connection);
}
}
public override void SendChatMessage(string message)
{
List<Client> recipients = new List<Client>();
Client targetClient = null;
if (type == ChatMessageType.Server)
ChatMessageType type = gameStarted && myCharacter != null ? ChatMessageType.Default : ChatMessageType.Server;
string command = ChatMessage.GetChatMessageCommand(message, out message).ToLower();
if (command=="dead" || command=="d")
{
string command = GetChatMessageCommand(message).ToLower();
type = ChatMessageType.Dead;
}
else if (command=="radio" || command=="r")
{
if (CanUseRadio(Character.Controlled)) type = ChatMessageType.Radio;
}
else if (command != "")
{
targetClient = ConnectedClients.Find(c =>
command == c.name.ToLower() ||
c.Character != null && command == c.Character.Name.ToLower());
if (command=="dead" || command=="d")
if (targetClient == null)
{
type = ChatMessageType.Dead;
}
else if (command != "")
{
targetClient = ConnectedClients.Find(c =>
command == c.name.ToLower() ||
c.Character != null && command == c.Character.Name.ToLower());
if (targetClient == null)
{
AddChatMessage("Player ''" + command + "'' not found!", ChatMessageType.Admin);
return;
}
AddChatMessage("Player ''" + command + "'' not found!", ChatMessageType.Error);
return;
}
}
@@ -1411,8 +1460,12 @@ namespace Barotrauma.Networking
if (type != ChatMessageType.Dead || (c.Character == null || c.Character.IsDead)) recipients.Add(c);
}
}
AddChatMessage(message, type);
var chatMessage = ChatMessage.Create(
gameStarted && myCharacter != null ? myCharacter.Name : name,
message, type, gameStarted ? myCharacter : null);
AddChatMessage(chatMessage);
if (!server.Connections.Any()) return;
@@ -1420,8 +1473,10 @@ namespace Barotrauma.Networking
{
ReliableMessage msg = c.ReliableChannel.CreateMessage();
msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
msg.InnerMessage.Write((byte)type);
msg.InnerMessage.Write(message);
//msg.InnerMessage.Write((byte)type);
//msg.InnerMessage.Write(message);
chatMessage.WriteNetworkMessage(msg.InnerMessage);
c.ReliableChannel.SendMessage(msg, c.Connection);
}

View File

@@ -1,9 +1,11 @@
using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;
using Lidgren.Network;
using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
@@ -40,11 +42,6 @@ namespace Barotrauma.Networking
SpectateRequest
}
enum ChatMessageType
{
Default, Admin, Dead, Server
}
enum VoteType
{
Unknown,
@@ -55,9 +52,6 @@ namespace Barotrauma.Networking
class NetworkMember
{
protected static Color[] messageColor = { Color.White, Color.Red, new Color(63,72,204), Color.LightGreen };
protected NetPeer netPeer;
protected string name;
@@ -139,6 +133,7 @@ namespace Barotrauma.Networking
chatMsgBox.Font = GUI.SmallFont;
chatMsgBox.Padding = Vector4.Zero;
chatMsgBox.OnEnterPressed = EnterChatMessage;
chatMsgBox.OnTextChanged = TypingChatMessage;
Voting = new Voting();
}
@@ -183,39 +178,98 @@ namespace Barotrauma.Networking
return message;
}
public bool TypingChatMessage(GUITextBox textBox, string text)
{
string tempStr;
string command = ChatMessage.GetChatMessageCommand(text, out tempStr);
switch (command)
{
case "r":
case "radio":
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Radio];
break;
case "d":
case "dead":
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Dead];
break;
default:
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
break;
}
return true;
}
public bool CanUseRadio(Character sender)
{
if (sender == null) return false;
var radio = sender.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
if (radio == null) return false;
var radioComponent = radio.GetComponent<WifiComponent>();
return radioComponent.HasRequiredContainedItems(false);
}
public bool EnterChatMessage(GUITextBox textBox, string message)
{
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
if (string.IsNullOrWhiteSpace(message)) return false;
string senderName = gameStarted && characterInfo != null ? characterInfo.Name : name;
SendChatMessage(senderName + ": " + message);
SendChatMessage(message);
textBox.Deselect();
return true;
}
public void AddChatMessage(string message, ChatMessageType messageType)
{
GameMain.NetLobbyScreen.NewChatMessage(message, messageColor[(int)messageType]);
GameServer.Log(message, messageColor[(int)messageType]);
public void AddChatMessage(string message, ChatMessageType type, string senderName="", Character senderCharacter = null)
{
AddChatMessage(ChatMessage.Create(senderName, message, type, senderCharacter));
}
public void AddChatMessage(ChatMessage message)
{
if (message.Type == ChatMessageType.Radio && message.Sender != null && message.Sender != myCharacter)
{
var radio = message.Sender.Inventory.Items.First(i => i != null && i.GetComponent<WifiComponent>() != null);
if (radio == null) return;
var radioComponent = radio.GetComponent<WifiComponent>();
radioComponent.Transmit(message.TextWithSender);
return;
}
string displayedText = message.Text;
if (message.Type == ChatMessageType.Default && myCharacter != null && message.Sender != null)
{
displayedText = message.ApplyDistanceEffect(myCharacter);
if (string.IsNullOrWhiteSpace(displayedText)) return;
}
GameMain.NetLobbyScreen.NewChatMessage(message);
GameServer.Log(message.Text, message.Color);
while (chatBox.CountChildren > 20)
{
chatBox.RemoveChild(chatBox.children[1]);
}
GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), message,
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, messageColor[(int)messageType],
if (!string.IsNullOrWhiteSpace(message.SenderName))
{
displayedText = message.SenderName + ": " + displayedText;
}
GUITextBlock msg = new GUITextBlock(new Rectangle(0, 0, 0, 20), displayedText,
((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, message.Color,
Alignment.Left, null, null, true);
msg.Font = GUI.SmallFont;
msg.Padding = new Vector4(20.0f, 0, 0, 0);
//float prevScroll = chatBox.BarScroll;
float prevSize = chatBox.BarSize;
msg.Padding = new Vector4(20, 0, 0, 0);
@@ -223,29 +277,21 @@ namespace Barotrauma.Networking
if ((prevSize == 1.0f && chatBox.BarScroll == 0.0f) || (prevSize < 1.0f && chatBox.BarScroll == 1.0f)) chatBox.BarScroll = 1.0f;
GUI.PlayUISound(GUISoundType.Message);
}
public virtual void SendChatMessage(string message, ChatMessageType type = ChatMessageType.Server) { }
protected string GetChatMessageCommand(string message)
{
int separatorIndex = message.IndexOf(";");
if (separatorIndex == -1) return "";
int colonIndex = message.IndexOf(":");
string command = "";
try
GUISoundType soundType = GUISoundType.Message;
if (message.Type == ChatMessageType.Radio)
{
command = message.Substring(colonIndex + 2, separatorIndex - colonIndex - 2);
soundType = GUISoundType.RadioMessage;
}
else if (message.Type == ChatMessageType.Dead)
{
soundType = GUISoundType.DeadMessage;
}
catch { }
return command;
GUI.PlayUISound(soundType);
}
public virtual void SendChatMessage(string message) { }
public virtual void Update(float deltaTime)
{
if (gameStarted && Screen.Selected == GameMain.GameScreen)