diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs index c139e00e1..12a8d9e90 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs @@ -1,7 +1,5 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using System; -using System.Xml.Linq; namespace Barotrauma { diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/ShiftSummary.cs b/Barotrauma/BarotraumaClient/Source/GameSession/ShiftSummary.cs index c49037c77..fae21d73e 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/ShiftSummary.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/ShiftSummary.cs @@ -29,7 +29,7 @@ namespace Barotrauma bool gameOver = gameSession.CrewManager.characters.All(c => c.IsDead); bool progress = Submarine.MainSub.AtEndPosition; - GUIFrame frame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.8f); + GUIFrame frame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.8f, null); int width = 760, height = 400; GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, width, height), null, Alignment.Center, "", frame); diff --git a/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs index d29d96b9b..c2a04f8f1 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs @@ -44,9 +44,13 @@ namespace Barotrauma { selectedConnection = connection; selectedLocation = highlightedLocation; - - OnLocationSelected?.Invoke(selectedLocation, selectedConnection); - //GameMain.LobbyScreen.SelectLocation(highlightedLocation, connection); + + //clients aren't allowed to select the location without a permission + if (GameMain.Client == null || GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign)) + { + OnLocationSelected?.Invoke(selectedLocation, selectedConnection); + GameMain.Client?.SendCampaignState(); + } } } @@ -54,6 +58,7 @@ namespace Barotrauma if (PlayerInput.DoubleClicked() && highlightedLocation != null) { currentLocation = highlightedLocation; + OnLocationChanged?.Invoke(currentLocation); } #endif } diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 113464deb..fed309c87 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -1312,6 +1312,24 @@ namespace Barotrauma.Networking client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); } + public void SendCampaignState() + { + MultiplayerCampaign campaign = GameMain.GameSession.GameMode as MultiplayerCampaign; + if (campaign == null) + { + DebugConsole.ThrowError("Failed send campaign state to the server (no campaign active).\n" + Environment.StackTrace); + return; + } + + NetOutgoingMessage msg = client.CreateMessage(); + msg.Write((byte)ClientPacketHeader.SERVER_COMMAND); + msg.Write((byte)ClientPermissions.ManageCampaign); + campaign.ClientWrite(msg); + msg.Write((byte)ServerNetObject.END_OF_MESSAGE); + + client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); + } + public void RequestRoundEnd() { NetOutgoingMessage msg = client.CreateMessage(); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs index 4d6ccf230..efea67feb 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs @@ -24,10 +24,8 @@ namespace Barotrauma private CampaignMode campaign; - private GUIFrame previewFrame; - - private GUIButton buyButton; - + private GUIFrame characterPreviewFrame; + private Level selectedLevel; private float mapZoom = 3.0f; @@ -44,27 +42,7 @@ namespace Barotrauma { get { return campaign; } } - - private string CostTextGetter() - { - return "Cost: " + selectedItemCost.ToString() + " credits"; - } - - private int selectedItemCost - { - get - { - int cost = 0; - foreach (GUIComponent child in selectedItemList.children) - { - MapEntityPrefab ep = child.UserData as MapEntityPrefab; - if (ep == null) continue; - cost += ep.Price; - } - return cost; - } - } - + public CampaignUI(CampaignMode campaign, GUIFrame container) { this.campaign = campaign; @@ -107,16 +85,10 @@ namespace Barotrauma int sellColumnWidth = (tabs[(int)Tab.Store].Rect.Width - 40) / 2 - 20; selectedItemList = new GUIListBox(new Rectangle(0, 30, sellColumnWidth, tabs[(int)Tab.Store].Rect.Height - 80), Color.White * 0.7f, "", tabs[(int)Tab.Store]); - selectedItemList.OnSelected = DeselectItem; - - var costText = new GUITextBlock(new Rectangle(0, 0, 100, 25), "Cost: ", "", Alignment.BottomLeft, Alignment.TopLeft, tabs[(int)Tab.Store]); - costText.TextGetter = CostTextGetter; - - buyButton = new GUIButton(new Rectangle(selectedItemList.Rect.Width - 100, 0, 100, 25), "Buy", Alignment.Bottom, "", tabs[(int)Tab.Store]); - buyButton.OnClicked = BuyItems; - + selectedItemList.OnSelected = SellItem; + storeItemList = new GUIListBox(new Rectangle(0, 30, sellColumnWidth, tabs[(int)Tab.Store].Rect.Height - 80), Color.White * 0.7f, Alignment.TopRight, "", tabs[(int)Tab.Store]); - storeItemList.OnSelected = SelectItem; + storeItemList.OnSelected = BuyItem; int x = storeItemList.Rect.X - storeItemList.Parent.Rect.X; @@ -140,11 +112,21 @@ namespace Barotrauma SelectTab(Tab.Map); - GameMain.GameSession.Map.OnLocationSelected += SelectLocation; + UpdateLocationTab(campaign.Map.CurrentLocation); + + campaign.Map.OnLocationSelected += SelectLocation; + campaign.Map.OnLocationChanged += (location) => UpdateLocationTab(location); + campaign.CargoManager.OnItemsChanged += RefreshItemTab; } private void UpdateLocationTab(Location location) { + if (characterPreviewFrame != null) + { + characterPreviewFrame.Parent.RemoveChild(characterPreviewFrame); + characterPreviewFrame = null; + } + if (location.HireManager == null) { hireList.ClearChildren(); @@ -173,7 +155,7 @@ namespace Barotrauma { mapZoom += PlayerInput.ScrollWheelSpeed / 1000.0f; mapZoom = MathHelper.Clamp(mapZoom, 1.0f, 4.0f); - + if (GameMain.GameSession?.Map != null) { GameMain.GameSession.Map.Update(deltaTime, new Rectangle( @@ -186,29 +168,14 @@ namespace Barotrauma public void Draw(SpriteBatch spriteBatch) { - /*if (characterList.CountChildren != CrewManager.CharacterInfos.Count) + if (selectedTab == Tab.Map && GameMain.GameSession?.Map != null) { - UpdateCharacterLists(); + GameMain.GameSession.Map.Draw(spriteBatch, new Rectangle( + tabs[(int)selectedTab].Rect.X + 20, + tabs[(int)selectedTab].Rect.Y + 20, + tabs[(int)selectedTab].Rect.Width - 310, + tabs[(int)selectedTab].Rect.Height - 40), mapZoom); } - - spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, GameMain.ScissorTestEnable); - */ - if (selectedTab == Tab.Map && GameMain.GameSession?.Map != null) - { - GameMain.GameSession.Map.Draw(spriteBatch, new Rectangle( - tabs[(int)selectedTab].Rect.X + 20, - tabs[(int)selectedTab].Rect.Y + 20, - tabs[(int)selectedTab].Rect.Width - 310, - tabs[(int)selectedTab].Rect.Height - 40), mapZoom); - } - - /*if (topPanel.UserData as Location != GameMain.GameSession.Map.CurrentLocation) - { - UpdateLocationTab(GameMain.GameSession.Map.CurrentLocation); - } - - spriteBatch.End();*/ - } public void UpdateCharacterLists() @@ -220,6 +187,34 @@ namespace Barotrauma } } + public void SelectLocation(Location location, LocationConnection connection) + { + GUIComponent locationPanel = tabs[(int)Tab.Map].GetChild("selectedlocation"); + + if (locationPanel != null) tabs[(int)Tab.Map].RemoveChild(locationPanel); + + locationPanel = new GUIFrame(new Rectangle(0, 0, 250, 190), Color.Transparent, Alignment.TopRight, null, tabs[(int)Tab.Map]); + locationPanel.UserData = "selectedlocation"; + + if (location == null) return; + + var titleText = new GUITextBlock(new Rectangle(0, 0, 250, 0), location.Name, "", Alignment.TopLeft, Alignment.TopCenter, locationPanel, true, GUI.LargeFont); + + if (GameMain.GameSession.Map.SelectedConnection != null && GameMain.GameSession.Map.SelectedConnection.Mission != null) + { + var mission = GameMain.GameSession.Map.SelectedConnection.Mission; + + new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 20, 0, 20), "Mission: " + mission.Name, "", locationPanel); + new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 40, 0, 20), "Reward: " + mission.Reward + " credits", "", locationPanel); + new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 70, 0, 0), mission.Description, "", Alignment.TopLeft, Alignment.TopLeft, locationPanel, true, GUI.SmallFont); + } + + if (startButton != null) startButton.Enabled = true; + + selectedLevel = connection.Level; + + OnLocationSelected?.Invoke(location, connection); + } private void CreateItemFrame(MapEntityPrefab ep, GUIListBox listBox, int width) { @@ -255,82 +250,49 @@ namespace Barotrauma Alignment.TopLeft, "", frame); textBlock.Font = font; textBlock.ToolTip = ep.Description; - } - private bool SelectItem(GUIComponent component, object obj) + private bool BuyItem(GUIComponent component, object obj) { - MapEntityPrefab prefab = obj as MapEntityPrefab; + ItemPrefab prefab = obj as ItemPrefab; if (prefab == null) return false; - CreateItemFrame(prefab, selectedItemList, selectedItemList.Rect.Width); + if (GameMain.Client != null && !GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign)) + { + return false; + } - buyButton.Enabled = campaign.Money >= selectedItemCost; + if (prefab.Price > campaign.Money) return false; + + campaign.CargoManager.PurchaseItem(prefab); + GameMain.Client?.SendCampaignState(); return false; } - private bool DeselectItem(GUIComponent component, object obj) + private bool SellItem(GUIComponent component, object obj) { - MapEntityPrefab prefab = obj as MapEntityPrefab; + ItemPrefab prefab = obj as ItemPrefab; if (prefab == null) return false; - selectedItemList.RemoveChild(selectedItemList.children.Find(c => c.UserData == obj)); + if (GameMain.Client != null && !GameMain.Client.HasPermission(Networking.ClientPermissions.ManageCampaign)) + { + return false; + } + + campaign.CargoManager.SellItem(prefab); + GameMain.Client?.SendCampaignState(); return false; } - - public void SelectLocation(Location location, LocationConnection connection) + private void RefreshItemTab() { - GUIComponent locationPanel = tabs[(int)Tab.Map].GetChild("selectedlocation"); - - if (locationPanel != null) tabs[(int)Tab.Map].RemoveChild(locationPanel); - - locationPanel = new GUIFrame(new Rectangle(0, 0, 250, 190), Color.Transparent, Alignment.TopRight, null, tabs[(int)Tab.Map]); - locationPanel.UserData = "selectedlocation"; - - if (location == null) return; - - var titleText = new GUITextBlock(new Rectangle(0, 0, 250, 0), location.Name, "", Alignment.TopLeft, Alignment.TopCenter, locationPanel, true, GUI.LargeFont); - - if (GameMain.GameSession.Map.SelectedConnection != null && GameMain.GameSession.Map.SelectedConnection.Mission != null) + selectedItemList.ClearChildren(); + foreach (ItemPrefab ip in campaign.CargoManager.PurchasedItems) { - var mission = GameMain.GameSession.Map.SelectedConnection.Mission; - - new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 20, 0, 20), "Mission: " + mission.Name, "", locationPanel); - new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 40, 0, 20), "Reward: " + mission.Reward + " credits", "", locationPanel); - new GUITextBlock(new Rectangle(0, titleText.Rect.Height + 70, 0, 0), mission.Description, "", Alignment.TopLeft, Alignment.TopLeft, locationPanel, true, GUI.SmallFont); + CreateItemFrame(ip, selectedItemList, selectedItemList.Rect.Width); } - - if (startButton != null) startButton.Enabled = true; - - selectedLevel = connection.Level; - - OnLocationSelected?.Invoke(location, connection); - } - - private bool BuyItems(GUIButton button, object obj) - { - int cost = selectedItemCost; - - if (campaign.Money < cost) return false; - - campaign.Money -= cost; - - for (int i = selectedItemList.children.Count - 1; i >= 0; i--) - { - GUIComponent child = selectedItemList.children[i]; - - ItemPrefab ip = child.UserData as ItemPrefab; - if (ip == null) continue; - - campaign.CargoManager.AddItem(ip); - - selectedItemList.RemoveChild(child); - } - - return false; } public void SelectTab(Tab tab) @@ -373,7 +335,7 @@ namespace Barotrauma return true; } - private string GetMoney() + public string GetMoney() { return "Money: " + ((GameMain.GameSession == null) ? "0" : string.Format(CultureInfo.InvariantCulture, "{0:N0}", campaign.Money)) + " credits"; } @@ -398,22 +360,23 @@ namespace Barotrauma if (Character.Controlled != null && characterInfo == Character.Controlled.Info) return false; - if (previewFrame == null || previewFrame.UserData != characterInfo) + if (characterPreviewFrame == null || characterPreviewFrame.UserData != characterInfo) { int width = Math.Min(300, tabs[(int)Tab.Crew].Rect.Width - hireList.Rect.Width - characterList.Rect.Width - 50); - previewFrame = new GUIFrame(new Rectangle(0, 60, width, 300), + characterPreviewFrame = new GUIFrame(new Rectangle(0, 60, width, 300), new Color(0.0f, 0.0f, 0.0f, 0.8f), Alignment.TopCenter, "", tabs[(int)selectedTab]); - previewFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); - previewFrame.UserData = characterInfo; + characterPreviewFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); + characterPreviewFrame.UserData = characterInfo; - characterInfo.CreateInfoFrame(previewFrame); + characterInfo.CreateInfoFrame(characterPreviewFrame); } if (component.Parent == hireList) { - GUIButton hireButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Hire", Alignment.BottomCenter, "", previewFrame); + GUIButton hireButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Hire", Alignment.BottomCenter, "", characterPreviewFrame); + hireButton.Enabled = campaign.Money >= characterInfo.Salary; hireButton.UserData = characterInfo; hireButton.OnClicked = HireCharacter; } @@ -423,15 +386,22 @@ namespace Barotrauma private bool HireCharacter(GUIButton button, object selection) { - /*CharacterInfo characterInfo = selection as CharacterInfo; + CharacterInfo characterInfo = selection as CharacterInfo; if (characterInfo == null) return false; - if (campaign.TryHireCharacter(GameMain.GameSession.Map.CurrentLocation.HireManager, characterInfo)) + SinglePlayerCampaign spCampaign = campaign as SinglePlayerCampaign; + if (spCampaign == null) + { + DebugConsole.ThrowError("Characters can only be hired in the single player campaign.\n" + Environment.StackTrace); + return false; + } + + if (spCampaign.TryHireCharacter(GameMain.GameSession.Map.CurrentLocation.HireManager, characterInfo)) { UpdateLocationTab(GameMain.GameSession.Map.CurrentLocation); - SelectCharacter(null, null); - }*/ + UpdateCharacterLists(); + } return false; } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/LobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/LobbyScreen.cs index ced3193f8..fcd34bed1 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/LobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/LobbyScreen.cs @@ -20,6 +20,11 @@ namespace Barotrauma get { return GameMain.GameSession.CrewManager; } } + public string GetMoney() + { + return campaignUI == null ? "" : campaignUI.GetMoney(); + } + public LobbyScreen() { Rectangle panelRect = new Rectangle( @@ -37,7 +42,7 @@ namespace Barotrauma GUITextBlock moneyText = new GUITextBlock(new Rectangle(0, 0, 0, 25), "", "", Alignment.BottomLeft, Alignment.BottomLeft, topPanel); - //moneyText.TextGetter = GetMoney; + moneyText.TextGetter = GetMoney; GUIButton button = new GUIButton(new Rectangle(-240, 0, 100, 30), "Map", null, Alignment.BottomRight, "", topPanel); button.UserData = CampaignUI.Tab.Map; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs index 698a73999..3b0b72e9d 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs @@ -1022,16 +1022,14 @@ namespace Barotrauma menu.Draw(spriteBatch); if (jobInfoFrame != null) jobInfoFrame.Draw(spriteBatch); - - //if (previewPlayer!=null) previewPlayer.Draw(spriteBatch); - - if (playerFrame != null) playerFrame.Draw(spriteBatch); - + if (campaignContainer.Visible && campaignUI != null) { campaignUI.Draw(spriteBatch); } + if (playerFrame != null) playerFrame.Draw(spriteBatch); + GUI.Draw((float)deltaTime, spriteBatch, null); spriteBatch.End(); @@ -1180,6 +1178,9 @@ namespace Barotrauma }; buttonX += 110; } + + var moneyText = new GUITextBlock(new Rectangle(120,0,200,20), "Money", "", Alignment.BottomLeft, Alignment.TopLeft, campaignContainer); + moneyText.TextGetter = campaignUI.GetMoney; } modeList.Select(2, true); } diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs index e65961e6f..d9d60b1af 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs @@ -1,20 +1,56 @@ using Microsoft.Xna.Framework; +using System; using System.Collections.Generic; +using System.Linq; namespace Barotrauma { class CargoManager { - private List purchasedItems; + private readonly List purchasedItems; + + private readonly CampaignMode campaign; + + public Action OnItemsChanged; + + public List PurchasedItems + { + get { return purchasedItems; } + } - public CargoManager() + public CargoManager(CampaignMode campaign) { purchasedItems = new List(); + this.campaign = campaign; } - public void AddItem(ItemPrefab item) + public void SetPurchasedItems(List items) { + purchasedItems.Clear(); + purchasedItems.AddRange(items); + + OnItemsChanged?.Invoke(); + } + + public void PurchaseItem(ItemPrefab item) + { + campaign.Money -= item.Price; purchasedItems.Add(item); + + OnItemsChanged?.Invoke(); + } + + public void SellItem(ItemPrefab item) + { + campaign.Money += item.Price; + purchasedItems.Remove(item); + + OnItemsChanged?.Invoke(); + } + + public int GetTotalItemCost() + { + return purchasedItems.Sum(i => i.Price); } public void CreateItems() diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs index 097a01a1b..aaa05009f 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/CampaignMode.cs @@ -35,7 +35,7 @@ namespace Barotrauma : base(preset, param) { Money = InitialMoney; - CargoManager = new CargoManager(); + CargoManager = new CargoManager(this); } public void GenerateMap(string seed) diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs index 69dee9eb4..57d384b02 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs @@ -69,12 +69,11 @@ namespace Barotrauma GameMain.GameSession = new GameSession(new Submarine(sub.FilePath, ""), saveName, GameModePreset.list.Find(g => g.Name == "Campaign")); var campaign = ((MultiplayerCampaign)GameMain.GameSession.GameMode); campaign.GenerateMap(mapSeed); - campaign.map.OnLocationSelected += (loc, connection) => { campaign.LastUpdateID++; }; + campaign.SetDelegates(); setupBox.Close(); GameMain.NetLobbyScreen.ToggleCampaignMode(true); - SaveUtil.SaveGame(GameMain.GameSession.SavePath); campaign.LastSaveID++; }; @@ -105,9 +104,17 @@ namespace Barotrauma return true; }; } - #endif + private void SetDelegates() + { + if (GameMain.Server != null) + { + CargoManager.OnItemsChanged += () => { LastUpdateID++; }; + Map.OnLocationSelected += (loc, connection) => { LastUpdateID++; }; + } + } + public override void Start() { base.Start(); @@ -186,6 +193,7 @@ namespace Barotrauma if (!success) { +#if CLIENT var summaryScreen = GUIMessageBox.VisibleBox; if (summaryScreen != null) { @@ -200,6 +208,7 @@ namespace Barotrauma quitButton.OnClicked += GameMain.LobbyScreen.QuitToMainMenu; quitButton.OnClicked += (GUIButton button, object obj) => { GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox); return true; }; } +#endif } } else @@ -232,9 +241,8 @@ namespace Barotrauma campaign.map.SetLocation(ToolBox.GetAttributeInt(element, "currentlocation", 0)); } - campaign.map.OnLocationSelected += (loc, connection) => { campaign.LastUpdateID++; }; - - //campaign.savedOnStart = true; + campaign.SetDelegates(); + return campaign; } @@ -258,8 +266,15 @@ namespace Barotrauma msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex); msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex); - } + msg.Write(Money); + msg.Write((UInt16)CargoManager.PurchasedItems.Count); + foreach (ItemPrefab ip in CargoManager.PurchasedItems) + { + msg.Write((UInt16)MapEntityPrefab.list.IndexOf(ip)); + } + } + #if CLIENT public static void ClientRead(NetBuffer msg) { @@ -271,6 +286,16 @@ namespace Barotrauma UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); + int money = msg.ReadInt32(); + + UInt16 purchasedItemCount = msg.ReadUInt16(); + List purchasedItems = new List(); + for (int i = 0; i purchasedItems = new List(); + for (int i = 0; i < purchasedItemCount; i++) + { + UInt16 itemPrefabIndex = msg.ReadUInt16(); + purchasedItems.Add(MapEntityPrefab.list[itemPrefabIndex] as ItemPrefab); + } + + if (!sender.HasPermission(ClientPermissions.ManageCampaign)) + { + DebugConsole.ThrowError("Client \""+sender.name+"\" does not have a permission to manage the campaign"); + return; + } + + Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); + + List currentItems = new List(CargoManager.PurchasedItems); + foreach (ItemPrefab ip in currentItems) + { + CargoManager.SellItem(ip); + } + + foreach (ItemPrefab ip in purchasedItems) + { + CargoManager.PurchaseItem(ip); + } + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs index bb9e15242..17a76154f 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs @@ -29,6 +29,7 @@ namespace Barotrauma private LocationConnection selectedConnection; public Action OnLocationSelected; + public Action OnLocationChanged; public Location CurrentLocation { @@ -350,6 +351,8 @@ namespace Barotrauma currentLocation = selectedLocation; currentLocation.Discovered = true; selectedLocation = null; + + OnLocationChanged?.Invoke(currentLocation); } public void SetLocation(int index) @@ -368,6 +371,8 @@ namespace Barotrauma currentLocation = locations[index]; currentLocation.Discovered = true; + + OnLocationChanged?.Invoke(currentLocation); } public void SelectLocation(int index) diff --git a/Barotrauma/BarotraumaShared/Source/Networking/Client.cs b/Barotrauma/BarotraumaShared/Source/Networking/Client.cs index 8289c2aff..5bf7d3cf4 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/Client.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/Client.cs @@ -15,7 +15,9 @@ namespace Barotrauma.Networking [Description("Kick")] Kick = 2, [Description("Ban")] - Ban = 4 + Ban = 4, + [Description("Manage campaign")] + ManageCampaign = 8 } class Client diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index a9f1e9103..fa3bac2b8 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -748,7 +748,7 @@ namespace Barotrauma.Networking if (!sender.HasPermission(command)) { - Log("Client \""+sender.name+"\" sent a server command \""+command+"\". Permission denied.", ServerLog.MessageType.ServerMessage); + Log("Client \"" + sender.name + "\" sent a server command \"" + command + "\". Permission denied.", ServerLog.MessageType.ServerMessage); return; } @@ -781,6 +781,13 @@ namespace Barotrauma.Networking EndGame(); } break; + case ClientPermissions.ManageCampaign: + MultiplayerCampaign campaign = GameMain.GameSession.GameMode as MultiplayerCampaign; + if (campaign != null) + { + campaign.ServerRead(inc, sender); + } + break; } inc.ReadPadBits();