diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs index 0f1bca9ea..033538684 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameServerSettings.cs @@ -245,30 +245,31 @@ namespace Barotrauma.Networking ((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible; return true; }; - - + foreach (MapEntityPrefab pf in MapEntityPrefab.List) { - if (!(pf is ItemPrefab) || (pf.Price <= 0.0f && !pf.Tags.Contains("smallitem"))) continue; + ItemPrefab ip = pf as ItemPrefab; + if (ip == null || (ip.Price <= 0.0f && !ip.Tags.Contains("smallitem"))) continue; + GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 260, 25), - pf.Name, "", + ip.Name, "", Alignment.Left, Alignment.CenterLeft, cargoFrame, false, GUI.SmallFont); textBlock.Padding = new Vector4(40.0f, 3.0f, 0.0f, 0.0f); textBlock.UserData = cargoFrame; textBlock.CanBeFocused = false; - if (pf.sprite != null) + if (ip.sprite != null) { - float scale = Math.Min(Math.Min(30.0f / pf.sprite.SourceRect.Width, 30.0f / pf.sprite.SourceRect.Height), 1.0f); - GUIImage img = new GUIImage(new Rectangle(-20 - (int)(pf.sprite.SourceRect.Width * scale * 0.5f), 12 - (int)(pf.sprite.SourceRect.Height * scale * 0.5f), 40, 40), pf.sprite, Alignment.Left, textBlock); - img.Color = pf.SpriteColor; + float scale = Math.Min(Math.Min(30.0f / ip.sprite.SourceRect.Width, 30.0f / ip.sprite.SourceRect.Height), 1.0f); + GUIImage img = new GUIImage(new Rectangle(-20 - (int)(ip.sprite.SourceRect.Width * scale * 0.5f), 12 - (int)(ip.sprite.SourceRect.Height * scale * 0.5f), 40, 40), ip.sprite, Alignment.Left, textBlock); + img.Color = ip.SpriteColor; img.Scale = scale; } int cargoVal = 0; - extraCargo.TryGetValue(pf.Name, out cargoVal); + extraCargo.TryGetValue(ip, out cargoVal); var amountInput = new GUINumberInput(new Rectangle(160, 0, 50, 20), "", GUINumberInput.NumberType.Int, textBlock); amountInput.MinValueInt = 0; amountInput.MaxValueInt = 100; @@ -276,13 +277,13 @@ namespace Barotrauma.Networking amountInput.OnValueChanged += (numberInput) => { - if (extraCargo.ContainsKey(pf.Name)) + if (extraCargo.ContainsKey(ip)) { - extraCargo[pf.Name] = numberInput.IntValue; + extraCargo[ip] = numberInput.IntValue; } else { - extraCargo.Add(pf.Name, numberInput.IntValue); + extraCargo.Add(ip, numberInput.IntValue); } }; } diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs b/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs index d9d60b1af..e07c7e124 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/CargoManager.cs @@ -1,4 +1,5 @@ -using Microsoft.Xna.Framework; +using Barotrauma.Items.Components; +using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; @@ -54,6 +55,11 @@ namespace Barotrauma } public void CreateItems() + { + CreateItems(purchasedItems); + } + + public static void CreateItems(List itemsToSpawn) { WayPoint wp = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub); @@ -71,24 +77,82 @@ namespace Barotrauma return; } - foreach (ItemPrefab prefab in purchasedItems) + Dictionary availableContainers = new Dictionary(); + foreach (ItemPrefab prefab in itemsToSpawn) { Vector2 position = new Vector2( Rand.Range(cargoRoom.Rect.X + 20, cargoRoom.Rect.Right - 20), - cargoRoom.Rect.Y - cargoRoom.Rect.Height + prefab.Size.Y/2); + cargoRoom.Rect.Y - cargoRoom.Rect.Height + prefab.Size.Y / 2); - if (GameMain.Server != null) + ItemContainer itemContainer = null; + if (!string.IsNullOrEmpty(prefab.CargoContainerName)) { - Entity.Spawner.AddToSpawnQueue(prefab, position, wp.Submarine); + itemContainer = availableContainers.Keys.ToList().Find(ac => + ac.Item.Prefab.NameMatches(prefab.CargoContainerName) || + ac.Item.Prefab.Tags.Contains(prefab.CargoContainerName.ToLowerInvariant())); + + if (itemContainer == null) + { + var containerPrefab = MapEntityPrefab.List.Find(ep => + ep.NameMatches(prefab.CargoContainerName) || + (ep.Tags != null && ep.Tags.Contains(prefab.CargoContainerName.ToLowerInvariant()))) as ItemPrefab; + + if (containerPrefab == null) + { + DebugConsole.ThrowError("Cargo spawning failed - could not find the item prefab for container \"" + containerPrefab.Name + "\"!"); + continue; + } + + Item containerItem = new Item(containerPrefab, position, wp.Submarine); + itemContainer = containerItem.GetComponent(); + if (itemContainer == null) + { + DebugConsole.ThrowError("Cargo spawning failed - container \"" + containerItem.Name + "\" does not have an ItemContainer component!"); + continue; + } + availableContainers.Add(itemContainer, itemContainer.Capacity); + if (GameMain.Server != null) + { + Entity.Spawner.CreateNetworkEvent(itemContainer.Item, false); + } + } + } + + if (itemContainer == null) + { + //no container, place at the waypoint + if (GameMain.Server != null) + { + Entity.Spawner.AddToSpawnQueue(prefab, position, wp.Submarine); + } + else + { + new Item(prefab, position, wp.Submarine); + } } else { - new Item(prefab, position, wp.Submarine); - } + //place in the container + if (GameMain.Server != null) + { + Entity.Spawner.AddToSpawnQueue(prefab, itemContainer.Inventory); + } + else + { + var item = new Item(prefab, position, wp.Submarine); + itemContainer.Inventory.TryPutItem(item, null); + } + //reduce the number of available slots in the container + availableContainers[itemContainer]--; + if (availableContainers[itemContainer] <= 0) + { + availableContainers.Remove(itemContainer); + } + } } - purchasedItems.Clear(); + itemsToSpawn.Clear(); } } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs index bf19c6c0a..6d014de7d 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs @@ -145,6 +145,13 @@ namespace Barotrauma private set; } + [Serialize("", false)] + public string CargoContainerName + { + get; + private set; + } + public bool CanSpriteFlipX { get { return canSpriteFlipX; } diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 4d7ebcc4b..02233f50c 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -1303,29 +1303,16 @@ namespace Barotrauma.Networking { if (sub == null) continue; - WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, sub); - - if (cargoSpawnPos?.CurrentHull == null) + List spawnList = new List(); + foreach (KeyValuePair kvp in extraCargo) { - DebugConsole.ThrowError("Couldn't spawn additional cargo (no cargo spawnpoint inside any of the hulls)"); - continue; - } - - var cargoRoom = cargoSpawnPos.CurrentHull; - Vector2 position = new Vector2( - cargoSpawnPos.Position.X, - cargoRoom.Rect.Y - cargoRoom.Rect.Height); - - foreach (string s in extraCargo.Keys) - { - ItemPrefab itemPrefab = MapEntityPrefab.Find(s) as ItemPrefab; - if (itemPrefab == null) continue; - - for (int i = 0; i < extraCargo[s]; i++) + for (int i = 0; i < kvp.Value; i++) { - Entity.Spawner.AddToSpawnQueue(itemPrefab, position + new Vector2(Rand.Range(-20.0f, 20.0f), itemPrefab.Size.Y / 2), sub); + spawnList.Add(kvp.Key); } } + + CargoManager.CreateItems(spawnList); } TraitorManager = null; diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs index 2d8560cae..060ff18ba 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs @@ -49,7 +49,7 @@ namespace Barotrauma.Networking private set; } - public Dictionary extraCargo; + public Dictionary extraCargo; public bool ShowNetStats; @@ -345,7 +345,7 @@ namespace Barotrauma.Networking { monsterEnabled.Add(s, true); } - extraCargo = new Dictionary(); + extraCargo = new Dictionary(); } public void LoadClientPermissions()