38f1ddb...178a853: v0.8.9.1, removed content folder

This commit is contained in:
Joonas Rikkonen
2019-03-18 19:46:58 +02:00
parent 38f1ddb6fe
commit 6c0679c297
1054 changed files with 151673 additions and 144931 deletions
@@ -1,6 +1,7 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
@@ -9,7 +10,15 @@ namespace Barotrauma
{
public readonly CargoManager CargoManager;
const int InitialMoney = 10000;
public bool CheatsEnabled;
const int InitialMoney = 4500;
private bool watchmenSpawned;
private Character startWatchman, endWatchman;
//key = dialog flag, double = Timing.TotalTime when the line was last said
private Dictionary<string, double> dialogLastSpoken = new Dictionary<string, double>();
protected Map map;
public Map Map
@@ -21,7 +30,7 @@ namespace Barotrauma
{
get
{
return Map.SelectedConnection.Mission;
return Map.CurrentLocation?.SelectedMission;
}
}
@@ -41,7 +50,7 @@ namespace Barotrauma
public void GenerateMap(string seed)
{
map = new Map(seed, 1000);
map = new Map(seed);
}
protected List<Submarine> GetSubsToLeaveBehind(Submarine leavingSub)
@@ -50,17 +59,98 @@ namespace Barotrauma
return Submarine.Loaded.FindAll(s =>
s != leavingSub &&
!leavingSub.DockedTo.Contains(s) &&
s != Level.Loaded.StartOutpost && s != Level.Loaded.EndOutpost &&
(s.AtEndPosition != leavingSub.AtEndPosition || s.AtStartPosition != leavingSub.AtStartPosition));
}
public override void End(string endMessage = "")
public override void Start()
{
base.End(endMessage);
base.Start();
dialogLastSpoken.Clear();
watchmenSpawned = false;
startWatchman = null;
endWatchman = null;
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
if (GameMain.Client != null || !IsRunning) { return; }
if (!watchmenSpawned)
{
if (Level.Loaded.StartOutpost != null) { startWatchman = SpawnWatchman(Level.Loaded.StartOutpost); }
if (Level.Loaded.EndOutpost != null) { endWatchman = SpawnWatchman(Level.Loaded.EndOutpost); }
watchmenSpawned = true;
}
else
{
foreach (Character character in Character.CharacterList)
{
#if SERVER
if (string.IsNullOrEmpty(character.OwnerClientIP)) { continue; }
#else
if (!CrewManager.GetCharacters().Contains(character)) { continue; }
#endif
if (character.Submarine == Level.Loaded.StartOutpost && character.CurrentHull == startWatchman.CurrentHull)
{
CreateDialog(new List<Character> { startWatchman }, "EnterStartOutpost", 5 * 60.0f);
}
else if (character.Submarine == Level.Loaded.EndOutpost && character.CurrentHull == endWatchman.CurrentHull)
{
CreateDialog(new List<Character> { endWatchman }, "EnterEndOutpost", 5 * 60.0f);
}
}
}
}
protected void CreateDialog(List<Character> speakers, string conversationTag, float minInterval)
{
if (dialogLastSpoken.TryGetValue(conversationTag, out double lastTime))
{
if (Timing.TotalTime - lastTime < minInterval) { return; }
}
CrewManager.AddConversation(
NPCConversation.CreateRandom(speakers, new List<string>() { conversationTag }));
dialogLastSpoken[conversationTag] = Timing.TotalTime;
}
private Character SpawnWatchman(Submarine outpost)
{
WayPoint watchmanSpawnpoint = WayPoint.WayPointList.Find(wp => wp.Submarine == outpost);
if (watchmanSpawnpoint == null)
{
DebugConsole.ThrowError("Failed to spawn a watchman at the outpost. No spawnpoints found inside the outpost.");
return null;
}
string seed = outpost == Level.Loaded.StartOutpost ? map.SelectedLocation.Name : map.CurrentLocation.Name;
Rand.SetSyncedSeed(ToolBox.StringToInt(seed));
JobPrefab watchmanJob = JobPrefab.List.Find(jp => jp.Identifier == "watchman");
CharacterInfo characterInfo = new CharacterInfo(Character.HumanConfigFile, jobPrefab: watchmanJob);
var spawnedCharacter = Character.Create(characterInfo, watchmanSpawnpoint.WorldPosition,
Level.Loaded.Seed + (outpost == Level.Loaded.StartOutpost ? "start" : "end"));
spawnedCharacter.CharacterHealth.Unkillable = true;
spawnedCharacter.CharacterHealth.UseHealthWindow = false;
spawnedCharacter.SetCustomInteract(
WatchmanInteract,
hudText: TextManager.Get("TalkHint").Replace("[key]", GameMain.Config.KeyBind(InputType.Select).ToString()));
(spawnedCharacter.AIController as HumanAIController)?.ObjectiveManager.SetOrder(
new AIObjectiveGoTo(watchmanSpawnpoint, spawnedCharacter, repeat: true, getDivingGearIfNeeded: false));
if (watchmanJob != null)
{
spawnedCharacter.GiveJobItems();
}
return spawnedCharacter;
}
protected abstract void WatchmanInteract(Character watchman, Character interactor);
public abstract void Save(XElement element);
public void LogState()
{
DebugConsole.NewMessage("********* CAMPAIGN STATUS *********", Color.White);
@@ -81,11 +171,18 @@ namespace Barotrauma
}
}
if (map.SelectedConnection?.Mission != null)
if (map.CurrentLocation?.SelectedMission != null)
{
DebugConsole.NewMessage(" Selected mission: " + map.SelectedConnection.Mission.Name, Color.White);
DebugConsole.NewMessage("\n" + map.SelectedConnection.Mission.Description, Color.White);
DebugConsole.NewMessage(" Selected mission: " + map.CurrentLocation.SelectedMission.Name, Color.White);
DebugConsole.NewMessage("\n" + map.CurrentLocation.SelectedMission.Description, Color.White);
}
}
public override void Remove()
{
base.Remove();
map?.Remove();
map = null;
}
}
}
@@ -0,0 +1,124 @@
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using Lidgren.Network;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Barotrauma
{
class CharacterCampaignData
{
public readonly CharacterInfo CharacterInfo;
public readonly string Name;
public readonly bool IsHostCharacter;
public readonly string ClientIP;
public readonly ulong SteamID;
private XElement itemData;
public CharacterCampaignData(Client client)
{
Name = client.Name;
ClientIP = client.Connection.RemoteEndPoint.Address.ToString();
SteamID = client.SteamID;
CharacterInfo = client.CharacterInfo;
if (client.Character.Inventory != null)
{
itemData = new XElement("inventory");
client.Character.SaveInventory(client.Character.Inventory, itemData);
}
}
public CharacterCampaignData(GameServer server)
{
Name = server.Character.Name;
CharacterInfo = server.Character.Info;
IsHostCharacter = true;
if (server.Character.Inventory != null)
{
itemData = new XElement("inventory");
server.Character.SaveInventory(server.Character.Inventory, itemData);
}
}
public CharacterCampaignData(XElement element)
{
Name = element.GetAttributeString("name", "Unnamed");
IsHostCharacter = element.GetAttributeBool("host", false);
if (!IsHostCharacter)
{
ClientIP = element.GetAttributeString("ip", "");
string steamID = element.GetAttributeString("steamid", "");
if (!string.IsNullOrEmpty(steamID))
{
ulong.TryParse(steamID, out SteamID);
}
}
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "character":
case "characterinfo":
CharacterInfo = new CharacterInfo(subElement);
break;
case "inventory":
itemData = subElement;
break;
}
}
}
public bool MatchesClient(Client client)
{
if (IsHostCharacter) return false;
if (SteamID > 0)
{
return SteamID == client.SteamID;
}
else
{
return ClientIP == client.Connection.RemoteEndPoint.Address.ToString();
}
}
public XElement Save()
{
XElement element = new XElement("CharacterCampaignData",
new XAttribute("name", Name));
if (IsHostCharacter)
{
element.Add(new XAttribute("host", true));
}
else
{
element.Add(new XAttribute("ip", ClientIP));
element.Add(new XAttribute("steamid", SteamID));
}
CharacterInfo?.Save(element);
if (itemData != null)
{
element.Add(itemData);
}
return element;
}
public void SpawnInventoryItems(CharacterInfo characterInfo, Inventory inventory)
{
characterInfo.SpawnInventoryItems(inventory, itemData);
}
}
}
@@ -14,6 +14,11 @@ namespace Barotrauma
protected GameModePreset preset;
private string endMessage;
protected CrewManager CrewManager
{
get { return GameMain.GameSession?.CrewManager; }
}
public virtual Mission Mission
{
@@ -60,10 +65,20 @@ namespace Barotrauma
}
public virtual void MsgBox() { }
public virtual void AddToGUIUpdateList()
{
#if CLIENT
if (!isRunning) return;
GameMain.GameSession?.CrewManager.AddToGUIUpdateList();
#endif
}
public virtual void AddToGUIUpdateList() { }
public virtual void Update(float deltaTime) { }
public virtual void Update(float deltaTime)
{
CrewManager?.Update(deltaTime);
}
public virtual void End(string endMessage = "")
{
@@ -74,6 +89,6 @@ namespace Barotrauma
GameMain.GameSession.EndRound(endMessage);
}
public virtual void Remove() { }
}
}
@@ -6,10 +6,25 @@ namespace Barotrauma
{
class GameModePreset
{
public static List<GameModePreset> list = new List<GameModePreset>();
public static List<GameModePreset> List = new List<GameModePreset>();
public ConstructorInfo Constructor
{
get;
private set;
}
public ConstructorInfo Constructor;
public string Name;
public string Name
{
get;
private set;
}
public string Identifier
{
get;
private set;
}
public bool IsSinglePlayer
{
@@ -30,16 +45,17 @@ namespace Barotrauma
private set;
}
public GameModePreset(string name, Type type, bool isSinglePlayer = false, bool votable = true)
public GameModePreset(string identifier, Type type, bool isSinglePlayer = false, bool votable = true)
{
this.Name = name;
Name = TextManager.Get("GameMode." + identifier);
Identifier = identifier;
Constructor = type.GetConstructor(new Type[] { typeof(GameModePreset), typeof(object) });
IsSinglePlayer = isSinglePlayer;
Votable = votable;
list.Add(this);
List.Add(this);
}
public GameMode Instantiate(object param)
@@ -51,19 +67,27 @@ namespace Barotrauma
public static void Init()
{
#if CLIENT
new GameModePreset("Single Player", typeof(SinglePlayerCampaign), true);
new GameModePreset("Tutorial", typeof(TutorialMode), true);
new GameModePreset("singleplayercampaign", typeof(SinglePlayerCampaign), true);
new GameModePreset("tutorial", typeof(TutorialMode), true);
#endif
new GameModePreset("devsandbox", typeof(GameMode), true)
{
Description = "Single player sandbox mode for debugging."
};
var mode = new GameModePreset("SandBox", typeof(GameMode), false);
mode.Description = "A game mode with no specific objectives.";
mode = new GameModePreset("Mission", typeof(MissionMode), false);
mode.Description = "The crew must work together to complete a specific task, such as retrieving "
new GameModePreset("sandbox", typeof(GameMode), false)
{
Description = "A game mode with no specific objectives."
};
new GameModePreset("mission", typeof(MissionMode), false)
{
Description = "The crew must work together to complete a specific task, such as retrieving "
+ "an alien artifact or killing a creature that's terrorizing nearby outposts. The game ends "
+ "when the task is completed or everyone in the crew has died.";
+ "when the task is completed or everyone in the crew has died."
};
new GameModePreset("Campaign", typeof(MultiPlayerCampaign), false, false);
//new GameModePreset("multiplayercampaign", typeof(MultiPlayerCampaign), false, false);
}
}
}
@@ -16,13 +16,13 @@
: base(preset, param)
{
Location[] locations = { GameMain.GameSession.StartLocation, GameMain.GameSession.EndLocation };
if (param is string)
if (param is MissionType missionType)
{
mission = Mission.LoadRandom(locations, GameMain.NetLobbyScreen.LevelSeed, (string)param);
mission = Mission.LoadRandom(locations, GameMain.NetLobbyScreen.LevelSeed, false, missionType);
}
else if (param is MissionPrefab)
else if (param is MissionPrefab missionPrefab)
{
mission = ((MissionPrefab)param).Instantiate(locations);
mission = missionPrefab.Instantiate(locations);
}
else if (param is Mission)
{
@@ -5,6 +5,7 @@ using System.Linq;
using System.Xml.Linq;
using Lidgren.Network;
using System.Collections.Generic;
using System.IO;
namespace Barotrauma
{
@@ -32,6 +33,8 @@ namespace Barotrauma
private static byte currentCampaignID;
private List<CharacterCampaignData> characterData = new List<CharacterCampaignData>();
public byte CampaignID
{
get; private set;
@@ -50,9 +53,55 @@ namespace Barotrauma
{
CargoManager.OnItemsChanged += () => { LastUpdateID++; };
Map.OnLocationSelected += (loc, connection) => { LastUpdateID++; };
Map.OnMissionSelected += (loc, mission) => { LastUpdateID++; };
}
}
public void DiscardClientCharacterData(Client client)
{
characterData.RemoveAll(cd => cd.MatchesClient(client));
}
public CharacterCampaignData GetClientCharacterData(Client client)
{
return characterData.Find(cd => cd.MatchesClient(client));
}
public CharacterCampaignData GetHostCharacterData()
{
return characterData.Find(cd => cd.IsHostCharacter);
}
public void AssignPlayerCharacterInfos(IEnumerable<Client> connectedClients, bool assignHost)
{
foreach (Client client in connectedClients)
{
if (client.SpectateOnly && GameMain.Server.AllowSpectating) continue;
var matchingData = GetClientCharacterData(client);
if (matchingData != null) client.CharacterInfo = matchingData.CharacterInfo;
}
if (assignHost)
{
var hostCharacterData = GetHostCharacterData();
if (hostCharacterData?.CharacterInfo != null)
{
GameMain.Server.CharacterInfo = hostCharacterData.CharacterInfo;
}
}
}
public Dictionary<Client, Job> GetAssignedJobs(IEnumerable<Client> connectedClients)
{
var assignedJobs = new Dictionary<Client, Job>();
foreach (Client client in connectedClients)
{
var matchingData = GetClientCharacterData(client);
if (matchingData != null) assignedJobs.Add(client, matchingData.CharacterInfo.Job);
}
return assignedJobs;
}
public override void Start()
{
base.Start();
@@ -60,6 +109,44 @@ namespace Barotrauma
}
protected override void WatchmanInteract(Character watchman, Character interactor)
{
if ((watchman.Submarine == Level.Loaded.StartOutpost && !Submarine.MainSub.AtStartPosition) ||
(watchman.Submarine == Level.Loaded.EndOutpost && !Submarine.MainSub.AtEndPosition))
{
if (GameMain.Server != null)
{
CreateDialog(new List<Character> { watchman }, "WatchmanInteractNoLeavingSub", 5.0f);
}
return;
}
bool hasPermissions = true;
if (GameMain.Server != null)
{
var client = GameMain.Server.ConnectedClients.Find(c => c.Character == interactor);
hasPermissions = client != null &&
(client.HasPermission(ClientPermissions.EndRound) || client.HasPermission(ClientPermissions.ManageCampaign));
CreateDialog(new List<Character> { watchman }, hasPermissions ? "WatchmanInteract" : "WatchmanInteractNotAllowed", 1.0f);
}
#if CLIENT
else if (GameMain.Client != null && interactor == Character.Controlled && hasPermissions)
{
var msgBox = new GUIMessageBox("", TextManager.Get("CampaignEnterOutpostPrompt")
.Replace("[locationname]", Submarine.MainSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
{
GameMain.Client.RequestRoundEnd();
return true;
};
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += msgBox.Close;
}
#endif
}
public override void End(string endMessage = "")
{
isRunning = false;
@@ -92,17 +179,42 @@ namespace Barotrauma
}*/
GameMain.GameSession.EndRound("");
foreach (Client c in GameMain.Server.ConnectedClients)
{
if (c.HasSpawned)
{
//client has spawned this round -> remove old data (and replace with new one if the client still has an alive character)
characterData.RemoveAll(cd => cd.MatchesClient(c));
}
if (c.Character?.Info != null && !c.Character.IsDead)
{
characterData.Add(new CharacterCampaignData(c));
}
}
//TODO: save player inventories between mp campaign rounds
#if CLIENT
GameMain.NetLobbyScreen.SetCampaignCharacterInfo(null);
#endif
if (GameMain.Server.Character != null)
{
characterData.RemoveAll(cd => cd.IsHostCharacter);
if (!GameMain.Server.Character.IsDead)
{
var hostCharacterData = new CharacterCampaignData(GameMain.Server);
characterData.Add(hostCharacterData);
#if CLIENT
GameMain.NetLobbyScreen.SetCampaignCharacterInfo(hostCharacterData.CharacterInfo);
#endif
}
}
//remove all items that are in someone's inventory
foreach (Character c in Character.CharacterList)
{
if (c.Inventory == null) continue;
foreach (Item item in c.Inventory.Items)
{
if (item != null) item.Remove();
}
c.Inventory?.DeleteAllItems();
}
#if CLIENT
@@ -128,29 +240,54 @@ namespace Barotrauma
if (atEndPosition)
{
Map.MoveToNextLocation();
map.MoveToNextLocation();
//select a random location to make sure we've got some destination
//to head towards even if the host/clients don't select anything
map.SelectRandomLocation(true);
}
map.ProgressWorld();
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
}
}
public static MultiPlayerCampaign LoadNew(XElement element)
{
MultiPlayerCampaign campaign = new MultiPlayerCampaign(GameModePreset.list.Find(gm => gm.Name == "Campaign"), null);
campaign.Load(element);
MultiPlayerCampaign campaign = new MultiPlayerCampaign(GameModePreset.List.Find(gm => gm.Identifier == "multiplayercampaign"), null);
campaign.Load(element);
campaign.SetDelegates();
return campaign;
}
public static string GetCharacterDataSavePath(string savePath)
{
return Path.Combine(SaveUtil.MultiplayerSaveFolder, Path.GetFileNameWithoutExtension(savePath) + "_CharacterData.xml");
}
public string GetCharacterDataSavePath()
{
return GetCharacterDataSavePath(GameMain.GameSession.SavePath);
}
public void Load(XElement element)
{
Money = element.GetAttributeInt("money", 0);
CheatsEnabled = element.GetAttributeBool("cheatsenabled", false);
if (CheatsEnabled)
{
DebugConsole.CheatsEnabled = true;
if (GameMain.Config.UseSteam && !SteamAchievementManager.CheatsEnabled)
{
SteamAchievementManager.CheatsEnabled = true;
#if CLIENT
new GUIMessageBox("Cheats enabled", "Cheat commands have been enabled on the server. You will not receive Steam Achievements until you restart the game.");
#else
DebugConsole.NewMessage("Cheat commands have been enabled.", Color.Red);
#endif
}
}
foreach (XElement subElement in element.Elements())
{
@@ -159,24 +296,64 @@ namespace Barotrauma
case "map":
if (map == null)
{
//map not created yet, loading this campaign for the first time
map = Map.LoadNew(subElement);
}
else
{
map.Load(subElement);
//map already created, update it
//if we're not downloading the initial save file (LastSaveID > 0),
//show notifications about location type changes
map.Load(subElement, LastSaveID > 0);
}
break;
}
}
if (GameMain.Server != null)
{
characterData.Clear();
string characterDataPath = GetCharacterDataSavePath();
var characterDataDoc = XMLExtensions.TryLoadXml(characterDataPath);
if (characterDataDoc?.Root == null) return;
foreach (XElement subElement in characterDataDoc.Root.Elements())
{
characterData.Add(new CharacterCampaignData(subElement));
}
#if CLIENT
var hostCharacterData = GetHostCharacterData();
if (hostCharacterData?.CharacterInfo != null)
{
GameMain.NetLobbyScreen.SetCampaignCharacterInfo(hostCharacterData.CharacterInfo);
}
#endif
}
}
public override void Save(XElement element)
{
XElement modeElement = new XElement("MultiPlayerCampaign");
modeElement.Add(new XAttribute("money", Money));
XElement modeElement = new XElement("MultiPlayerCampaign",
new XAttribute("money", Money),
new XAttribute("cheatsenabled", CheatsEnabled));
Map.Save(modeElement);
element.Add(modeElement);
//save character data to a separate file
string characterDataPath = GetCharacterDataSavePath();
XDocument characterDataDoc = new XDocument(new XElement("CharacterData"));
foreach (CharacterCampaignData cd in characterData)
{
characterDataDoc.Root.Add(cd.Save());
}
try
{
characterDataDoc.Save(characterDataPath);
}
catch (Exception e)
{
DebugConsole.ThrowError("Saving multiplayer campaign characters to \"" + characterDataPath + "\" failed!", e);
}
lastSaveID++;
}
@@ -190,20 +367,33 @@ namespace Barotrauma
msg.Write(map.Seed);
msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex);
msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex);
msg.Write(map.SelectedMissionIndex == -1 ? byte.MaxValue : (byte)map.SelectedMissionIndex);
msg.Write(Money);
msg.Write((UInt16)CargoManager.PurchasedItems.Count);
foreach (PurchasedItem pi in CargoManager.PurchasedItems)
{
msg.Write((UInt16)MapEntityPrefab.List.IndexOf(pi.itemPrefab));
msg.Write((UInt16)pi.quantity);
msg.Write((UInt16)MapEntityPrefab.List.IndexOf(pi.ItemPrefab));
msg.Write((UInt16)pi.Quantity);
}
var characterData = GetClientCharacterData(c);
if (characterData?.CharacterInfo == null)
{
msg.Write(false);
}
else
{
msg.Write(true);
characterData.CharacterInfo.ServerWrite(msg);
}
}
public void ServerRead(NetBuffer msg, Client sender)
{
UInt16 selectedLocIndex = msg.ReadUInt16();
byte selectedMissionIndex = msg.ReadByte();
UInt16 purchasedItemCount = msg.ReadUInt16();
List<PurchasedItem> purchasedItems = new List<PurchasedItem>();
@@ -216,21 +406,25 @@ namespace Barotrauma
if (!sender.HasPermission(ClientPermissions.ManageCampaign))
{
DebugConsole.ThrowError("Client \""+sender.Name+"\" does not have a permission to manage the campaign");
DebugConsole.ThrowError("Client \"" + sender.Name + "\" does not have a permission to manage the campaign");
return;
}
Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
if (Map.SelectedConnection != null)
{
Map.SelectMission(selectedMissionIndex);
}
List<PurchasedItem> currentItems = new List<PurchasedItem>(CargoManager.PurchasedItems);
foreach (PurchasedItem pi in currentItems)
{
CargoManager.SellItem(pi.itemPrefab, pi.quantity);
CargoManager.SellItem(pi, pi.Quantity);
}
foreach (PurchasedItem pi in purchasedItems)
{
CargoManager.PurchaseItem(pi.itemPrefab, pi.quantity);
CargoManager.PurchaseItem(pi.ItemPrefab, pi.Quantity);
}
}
}
@@ -30,10 +30,10 @@ namespace Barotrauma
var moreAgentsMsgBox = ChatMessage.Create(null, moreAgentsMessage, ChatMessageType.MessageBox, null);
Client client = server.ConnectedClients.Find(c => c.Character == Character);
GameMain.Server.SendChatMessage(greetingChatMsg, client);
GameMain.Server.SendChatMessage(moreAgentsChatMsg, client);
GameMain.Server.SendChatMessage(greetingMsgBox, client);
GameMain.Server.SendChatMessage(moreAgentsMsgBox, client);
GameMain.Server.SendDirectChatMessage(greetingChatMsg, client);
GameMain.Server.SendDirectChatMessage(moreAgentsChatMsg, client);
GameMain.Server.SendDirectChatMessage(greetingMsgBox, client);
GameMain.Server.SendDirectChatMessage(moreAgentsMsgBox, client);
}
#if CLIENT