diff --git a/Subsurface/Content/Items/Engine/engine.xml b/Subsurface/Content/Items/Engine/engine.xml index c7739754e..43d1d64a6 100644 --- a/Subsurface/Content/Items/Engine/engine.xml +++ b/Subsurface/Content/Items/Engine/engine.xml @@ -45,7 +45,6 @@ - diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index e1d0a1448..955d8c6ad 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -37,6 +37,8 @@ namespace Barotrauma public bool SpawnedMidRound; + public List SpawnItems = new List(); + private bool enabled; public bool Enabled @@ -73,11 +75,7 @@ namespace Barotrauma } protected Key[] keys; - - //protected Key selectKeyHit; - //protected Key actionKeyHit, actionKeyDown; - //protected Key secondaryKeyHit, secondaryKeyDown; - + private Item selectedConstruction; private Item[] selectedItems; @@ -160,13 +158,7 @@ namespace Barotrauma { get { return inventory; } } - - public WayPoint SpawnPoint - { - get; - set; - } - + private Color speechBubbleColor; private float speechBubbleTimer; diff --git a/Subsurface/Source/Characters/Jobs/Job.cs b/Subsurface/Source/Characters/Jobs/Job.cs index d777bae65..05e85fed7 100644 --- a/Subsurface/Source/Characters/Jobs/Job.cs +++ b/Subsurface/Source/Characters/Jobs/Job.cs @@ -127,6 +127,7 @@ namespace Barotrauma } } + character.SpawnItems.Add(item); if (parentItem != null) parentItem.Combine(item); diff --git a/Subsurface/Source/Events/Missions/CargoMission.cs b/Subsurface/Source/Events/Missions/CargoMission.cs index a612cc72b..68b2340ee 100644 --- a/Subsurface/Source/Events/Missions/CargoMission.cs +++ b/Subsurface/Source/Events/Missions/CargoMission.cs @@ -71,7 +71,7 @@ namespace Barotrauma Vector2 position = new Vector2( cargoSpawnPos.Position.X + Rand.Range(-20.0f, 20.0f, false), - cargoRoom.Rect.Y - cargoRoom.Rect.Height + 16.0f); + cargoRoom.Rect.Y - cargoRoom.Rect.Height); var item = new Item(itemPrefab, position, cargoRoom.Submarine); item.FindHull(); diff --git a/Subsurface/Source/GameMain.cs b/Subsurface/Source/GameMain.cs index cd64827ef..795cf1dbf 100644 --- a/Subsurface/Source/GameMain.cs +++ b/Subsurface/Source/GameMain.cs @@ -351,12 +351,12 @@ namespace Barotrauma } static bool waitForKeyHit = true; - public static void ShowLoading(IEnumerable loader, bool waitKeyHit = true) + public static CoroutineHandle ShowLoading(IEnumerable loader, bool waitKeyHit = true) { waitForKeyHit = waitKeyHit; titleScreenOpen = true; TitleScreen.LoadState = null; - CoroutineManager.StartCoroutine(TitleScreen.DoLoading(loader)); + return CoroutineManager.StartCoroutine(TitleScreen.DoLoading(loader)); } protected override void OnExiting(object sender, EventArgs args) diff --git a/Subsurface/Source/GameSession/CargoManager.cs b/Subsurface/Source/GameSession/CargoManager.cs index d15c43551..53ebf8cb8 100644 --- a/Subsurface/Source/GameSession/CargoManager.cs +++ b/Subsurface/Source/GameSession/CargoManager.cs @@ -39,7 +39,7 @@ namespace Barotrauma { Vector2 position = new Vector2( Rand.Range(cargoRoom.Rect.X + 20, cargoRoom.Rect.Right - 20), - Rand.Range(cargoRoom.Rect.Y - cargoRoom.Rect.Height + 20.0f, cargoRoom.Rect.Y)); + Rand.Range(cargoRoom.Rect.Y - cargoRoom.Rect.Height, cargoRoom.Rect.Y)); new Item(prefab as ItemPrefab, position, wp.Submarine); } diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 2ac67c0f4..e8a6dfc9a 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -301,7 +301,12 @@ namespace Barotrauma } public Item(ItemPrefab itemPrefab, Vector2 position, Submarine submarine) - : this(new Rectangle((int)position.X, (int)position.Y, (int)itemPrefab.sprite.size.X, (int)itemPrefab.sprite.size.Y), itemPrefab, submarine) + : this(new Rectangle( + (int)(position.X - itemPrefab.sprite.size.X / 2), + (int)(position.Y + itemPrefab.sprite.size.Y / 2), + (int)itemPrefab.sprite.size.X, + (int)itemPrefab.sprite.size.Y), + itemPrefab, submarine) { } @@ -511,6 +516,7 @@ namespace Barotrauma return CurrentHull; } + CurrentHull = Hull.FindHull(WorldPosition, CurrentHull); if (body != null && body.Enabled) { @@ -689,8 +695,7 @@ namespace Barotrauma ic.UpdateBroken(deltaTime, cam); } } - - + inWater = IsInWater(); if (inWater) ApplyStatusEffects(ActionType.InWater, deltaTime); diff --git a/Subsurface/Source/Items/ItemSpawner.cs b/Subsurface/Source/Items/ItemSpawner.cs index 793b5fdb2..3089631da 100644 --- a/Subsurface/Source/Items/ItemSpawner.cs +++ b/Subsurface/Source/Items/ItemSpawner.cs @@ -52,7 +52,7 @@ namespace Barotrauma if (!spawnQueue.Any()) return; List items = new List(); - List inventories = new List(); + //List inventories = new List(); while (spawnQueue.Count>0) { @@ -71,20 +71,25 @@ namespace Barotrauma if (itemInfo.Second is Inventory) { var item = new Item(itemInfo.First, Vector2.Zero, null); - spawnItems.Add(item); + AddToSpawnedList(item); var inventory = (Inventory)itemInfo.Second; inventory.TryPutItem(item, null, false); items.Add(item); - inventories.Add(inventory); + //inventories.Add(inventory); } } - if (GameMain.Server != null) GameMain.Server.SendItemSpawnMessage(items, inventories); + if (GameMain.Server != null) GameMain.Server.SendItemSpawnMessage(items); } - public void FillNetworkData(Lidgren.Network.NetBuffer message, List items, List inventories) + public void AddToSpawnedList(Item item) + { + spawnItems.Add(item); + } + + public void FillNetworkData(Lidgren.Network.NetBuffer message, List items) { message.Write((byte)items.Count); @@ -93,7 +98,25 @@ namespace Barotrauma message.Write(items[i].Prefab.Name); message.Write(items[i].ID); - message.Write((inventories == null || inventories[i] == null || inventories[i].Owner == null) ? (ushort)0 : inventories[i].Owner.ID); + if (items[i].ParentInventory == null || items[i].ParentInventory.Owner == null) + { + message.Write((ushort)0); + + message.Write(items[i].Position.X); + message.Write(items[i].Position.Y); + } + else + { + message.Write(items[i].ParentInventory.Owner.ID); + + int index = items[i].ParentInventory.FindIndex(items[i]); + message.Write(index < 0 ? (byte)255 : (byte)index); + } + + if (items[i].Name == "ID Card") + { + message.Write(items[i].Tags); + } } } @@ -103,10 +126,29 @@ namespace Barotrauma for (int i = 0; i < itemCount; i++) { string itemName = message.ReadString(); - ushort itemId = message.ReadUInt16(); + ushort itemId = message.ReadUInt16(); + Vector2 pos = Vector2.Zero; ushort inventoryId = message.ReadUInt16(); + Submarine sub = null; + + int inventorySlotIndex = -1; + + if (inventoryId > 0) + { + inventorySlotIndex = message.ReadByte(); + } + else + { + pos = new Vector2(message.ReadSingle(), message.ReadSingle()); + } + + string tags = ""; + if (itemName == "ID Card") + { + tags = message.ReadString(); + } var prefab = MapEntityPrefab.list.Find(me => me.Name == itemName); if (prefab == null) continue; @@ -133,9 +175,23 @@ namespace Barotrauma } } - var item = new Item(itemPrefab, Vector2.Zero, null); + var item = new Item(itemPrefab, pos, null); + item.ID = itemId; - if (inventory != null) inventory.TryPutItem(item, null, false); + item.CurrentHull = Hull.FindHull(pos, null, false); + item.Submarine = item.CurrentHull == null ? null : item.CurrentHull.Submarine; + + if (!string.IsNullOrEmpty(tags)) item.Tags = tags; + + if (inventory != null) + { + if (inventorySlotIndex >= 0 && inventorySlotIndex < 255 && + inventory.TryPutItem(item, inventorySlotIndex, false, false)) + { + continue; + } + inventory.TryPutItem(item, item.AllowedSlots, false); + } } } @@ -204,8 +260,8 @@ namespace Barotrauma { ushort itemId = message.ReadUInt16(); - var item = MapEntity.FindEntityByID(itemId); - if (item == null || !(item is Item)) continue; + var item = MapEntity.FindEntityByID(itemId) as Item; + if (item == null) continue; item.Remove(); } diff --git a/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs b/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs index 832339281..64b3e1823 100644 --- a/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs +++ b/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs @@ -411,7 +411,7 @@ namespace Barotrauma.RuinGeneration doorPos.Y = (wall.A.Y + wall.B.Y) / 2.0f; } - var door = new Item(doorPrefab.Prefab as ItemPrefab, doorPos - new Vector2(doorPrefab.Prefab.sprite.size.X, -doorPrefab.Prefab.sprite.size.Y)/2.0f, null); + var door = new Item(doorPrefab.Prefab as ItemPrefab, doorPos, null); door.MoveWithLevel = true; door.GetComponent().IsOpen = Rand.Range(0.0f, 1.0f, false) < 0.8f; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 730a7047e..dc753867b 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -456,6 +456,8 @@ namespace Barotrauma.Networking updateTimer = DateTime.Now + updateInterval; } + private CoroutineHandle startGameCoroutine; + /// /// Check for new incoming messages from server /// @@ -463,6 +465,8 @@ namespace Barotrauma.Networking { // Create new incoming message holder NetIncomingMessage inc; + + if (startGameCoroutine != null && CoroutineManager.IsCoroutineRunning(startGameCoroutine)) return; while ((inc = client.ReadMessage()) != null) { @@ -492,7 +496,7 @@ namespace Barotrauma.Networking case (byte)PacketTypes.StartGame: if (Screen.Selected == GameMain.GameScreen) continue; - GameMain.ShowLoading(StartGame(inc), false); + startGameCoroutine = GameMain.ShowLoading(StartGame(inc), false); break; case (byte)PacketTypes.EndGame: @@ -615,7 +619,9 @@ namespace Barotrauma.Networking case (byte)PacketTypes.RemoveItem: Item.Remover.ReadNetworkData(inc); break; - } + } + + if (packetType == (byte)PacketTypes.StartGame) break; } } @@ -650,7 +656,6 @@ namespace Barotrauma.Networking yield return CoroutineStatus.Success; } - yield return CoroutineStatus.Running; Rand.SetSyncedSeed(seed); //int gameModeIndex = inc.ReadInt32(); @@ -660,7 +665,6 @@ namespace Barotrauma.Networking if (respawnAllowed) respawnManager = new RespawnManager(this); - yield return CoroutineStatus.Running; //myCharacter = ReadCharacterData(inc); //Character.Controlled = myCharacter; @@ -699,7 +703,7 @@ namespace Barotrauma.Networking Character newCharacter = ReadCharacterData(inc, ownerId == myID); - if (id != myID) + if (ownerId != myID) { var characterOwner = otherClients.Find(c => c.ID == ownerId); if (characterOwner != null) characterOwner.Character = newCharacter; @@ -707,7 +711,6 @@ namespace Barotrauma.Networking crew.Add(newCharacter); } - //int count = inc.ReadByte(); //for (int n = 0; n < count; n++) //{ @@ -725,7 +728,8 @@ namespace Barotrauma.Networking // yield return CoroutineStatus.Running; //} } - gameStarted = true; + + gameStarted = true; endRoundButton.Visible = Voting.AllowEndVoting && myCharacter != null; @@ -1061,12 +1065,7 @@ namespace Barotrauma.Networking string jobName = inc.ReadString(); JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName); - ushort spawnPointID = inc.ReadUInt16(); - - if (inc.Position > inc.LengthBits) - { - return null; - } + //ushort spawnPointID = inc.ReadUInt16(); CharacterInfo ch = new CharacterInfo(Character.HumanConfigFile, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab); ch.HeadSpriteId = headSpriteID; @@ -1076,32 +1075,13 @@ namespace Barotrauma.Networking character.ID = ID; - WayPoint spawnPoint = Entity.FindEntityByID(spawnPointID) as WayPoint; - if (spawnPoint != null) - { - character.GiveJobItems(spawnPoint); - } + //WayPoint spawnPoint = Entity.FindEntityByID(spawnPointID) as WayPoint; + //if (spawnPoint != null) + //{ + // //character.GiveJobItems(spawnPoint); + //} - for (int i = 0; i < character.Inventory.Items.Length; i++) - { - ushort itemID = inc.ReadUInt16(); - - System.Diagnostics.Debug.Assert((itemID == 0) == (character.Inventory.Items[i] == null)); - if (character.Inventory.Items[i] == null) continue; - - character.Inventory.Items[i].ID = itemID; - - int containedCount = inc.ReadByte(); - if (containedCount > 0) - { - var containedItems = character.Inventory.Items[i].ContainedItems; - for (int j = 0; j() { sender.Connection }); - SendItemSpawnMessage(Item.Spawner.spawnItems, null, new List() { sender.Connection }); + SendItemSpawnMessage(Item.Spawner.spawnItems, new List() { sender.Connection }); yield return new WaitForSeconds(1.0f); @@ -1032,7 +1032,6 @@ namespace Barotrauma.Networking { connectedClients[i].Character = Character.Create( connectedClients[i].characterInfo, assignedWayPoints[i].WorldPosition, true, false); - connectedClients[i].Character.SpawnPoint = assignedWayPoints[i]; connectedClients[i].Character.GiveJobItems(assignedWayPoints[i]); GameMain.GameSession.CrewManager.characters.Add(connectedClients[i].Character); @@ -1043,15 +1042,17 @@ namespace Barotrauma.Networking myCharacter = Character.Create(characterInfo, assignedWayPoints[assignedWayPoints.Length - 1].WorldPosition, false, false); Character.Controlled = myCharacter; - myCharacter.SpawnPoint = assignedWayPoints[assignedWayPoints.Length - 1]; myCharacter.GiveJobItems(assignedWayPoints[assignedWayPoints.Length - 1]); GameMain.GameSession.CrewManager.characters.Add(myCharacter); } - + var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset); - SendMessage(startMessage, NetDeliveryMethod.ReliableUnordered); + + SendMessage(startMessage, NetDeliveryMethod.ReliableOrdered); + //SendItemSpawnMessage(allItems, inventories); + yield return CoroutineStatus.Running; UpdateCrewFrame(); @@ -1747,33 +1748,8 @@ namespace Barotrauma.Networking message.Write(character.WorldPosition.Y); message.Write(character.Info.Job.Name); - message.Write(character.SpawnPoint == null ? (ushort)0 : character.SpawnPoint.ID); - - for (int i = 0; i < character.Inventory.Items.Length; i++) - { - if (character.Inventory.Items[i] == null) - { - message.Write((ushort)0); - } - else - { - message.Write(character.Inventory.Items[i].ID); - var containedItems = character.Inventory.Items[i].ContainedItems; - if (containedItems == null || !containedItems.Any(c => c != null)) - { - message.Write((byte)0); - } - else - { - message.Write((byte)containedItems.Length); - for (int j = 0; j < containedItems.Length; j++) - { - message.Write(containedItems[j] == null ? (ushort)0 : containedItems[j].ID); - } - } - } - - } + + Item.Spawner.FillNetworkData(message, character.SpawnItems); } public void SendCharacterSpawnMessage(Character character, List recipients = null) @@ -1791,14 +1767,14 @@ namespace Barotrauma.Networking SendMessage(message, NetDeliveryMethod.ReliableUnordered, recipients); } - public void SendItemSpawnMessage(List items, List inventories = null, List recipients = null) + public void SendItemSpawnMessage(List items, List recipients = null) { if (items == null || !items.Any()) return; NetOutgoingMessage message = server.CreateMessage(); message.Write((byte)PacketTypes.NewItem); - Item.Spawner.FillNetworkData(message, items, inventories); + Item.Spawner.FillNetworkData(message, items); SendMessage(message, NetDeliveryMethod.ReliableOrdered, recipients); } diff --git a/Subsurface/Source/Networking/RespawnManager.cs b/Subsurface/Source/Networking/RespawnManager.cs index 50e525c7a..08584b5e7 100644 --- a/Subsurface/Source/Networking/RespawnManager.cs +++ b/Subsurface/Source/Networking/RespawnManager.cs @@ -223,6 +223,8 @@ namespace Barotrauma.Networking if (updateReturnTimer > 10.0f) { updateReturnTimer = 0.0f; + + respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBodies[0]); shuttleSteering.AutoPilot = true; shuttleSteering.MaintainPos = false; @@ -279,6 +281,8 @@ namespace Barotrauma.Networking ResetShuttle(); + shuttleSteering.TargetVelocity = Vector2.Zero; + server.SendChatMessage(ChatMessage.Create("", "Transportation shuttle dispatched", ChatMessageType.Server, null), server.ConnectedClients); server.SendRespawnManagerMsg(); @@ -346,6 +350,9 @@ namespace Barotrauma.Networking respawnShuttle.SetPosition(new Vector2(Level.Loaded.StartPosition.X, Level.Loaded.Size.Y + respawnShuttle.Borders.Height)); respawnShuttle.Velocity = Vector2.Zero; + + respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBodies[0]); + } public void WriteNetworkEvent(NetOutgoingMessage msg) @@ -371,11 +378,34 @@ namespace Barotrauma.Networking var waypoints = WayPoint.SelectCrewSpawnPoints(characterInfos, respawnShuttle); + ItemPrefab divingSuitPrefab = ItemPrefab.list.Find(ip => ip.Name == "Diving Suit") as ItemPrefab; + ItemPrefab oxyPrefab = ItemPrefab.list.Find(ip => ip.Name == "Oxygen Tank") as ItemPrefab; + + var cargoSp = WayPoint.WayPointList.Find(wp => wp.Submarine == respawnShuttle && wp.SpawnType == SpawnType.Cargo); + + List spawnedItems = new List(); + msg.Write((byte)characterInfos.Count); for (int i = 0; i < characterInfos.Count; i++) { var character = Character.Create(characterInfos[i], waypoints[i].WorldPosition, true, false); + if (divingSuitPrefab != null && oxyPrefab != null) + { + Vector2 pos = cargoSp == null ? character.Position : cargoSp.Position; + + var divingSuit = new Item(divingSuitPrefab, pos, respawnShuttle); + var oxyTank = new Item(oxyPrefab, pos, respawnShuttle); + + oxyTank.Combine(divingSuit); + + spawnedItems.Add(divingSuit); + spawnedItems.Add(oxyTank); + + Item.Spawner.AddToSpawnedList(divingSuit); + Item.Spawner.AddToSpawnedList(oxyTank); + } + if (i < clients.Count) { msg.Write((byte)clients[i].ID); @@ -388,14 +418,14 @@ namespace Barotrauma.Networking Character.Controlled = character; } - character.SpawnPoint = waypoints[i]; character.GiveJobItems(waypoints[i]); GameMain.GameSession.CrewManager.characters.Add(character); server.WriteCharacterData(msg, character.Name, character); } - + + GameMain.Server.SendItemSpawnMessage(spawnedItems); break; case State.Waiting: msg.Write(CountdownStarted); @@ -437,14 +467,11 @@ namespace Barotrauma.Networking case State.Waiting: CountdownStarted = true; - respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBodies[0]); - ResetShuttle(); respawnTimer = inc.ReadSingle(); break; case State.Returning: - respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBodies[0]); CountdownStarted = false; break;