From 7349cdd310babc9ff20ef7be0ce125243367b58f Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 9 Jun 2016 22:15:50 +0300 Subject: [PATCH] Progress (compiles now) --- .../Characters/AI/IndoorsSteeringManager.cs | 3 + Subsurface/Source/CoroutineManager.cs | 22 +-- Subsurface/Source/GameSession/GameSession.cs | 4 + .../Items/Components/Holdable/RepairTool.cs | 137 +++++++++--------- Subsurface/Source/Map/EntityGrid.cs | 26 +++- Subsurface/Source/Map/Hull.cs | 23 ++- Subsurface/Source/Map/Levels/Level.cs | 6 +- Subsurface/Source/Map/MapEntity.cs | 2 +- Subsurface/Source/Map/MapEntityPrefab.cs | 8 +- Subsurface/Source/Map/Structure.cs | 4 +- Subsurface/Source/Map/StructurePrefab.cs | 14 +- Subsurface/Source/Map/Submarine.cs | 12 +- Subsurface/Source/Map/WayPoint.cs | 79 +++++----- Subsurface/Source/Networking/GameClient.cs | 2 +- Subsurface/Source/Networking/GameServer.cs | 22 ++- Subsurface/Source/Program.cs | 2 +- Subsurface/Source/Screens/EditMapScreen.cs | 32 ++-- Subsurface/Source/Screens/GameScreen.cs | 19 ++- Subsurface/Source/Sounds/SoundPlayer.cs | 9 +- Subsurface/Source/Utils/SaveUtil.cs | 4 +- Subsurface_Solution.sln | 47 ------ Subsurface_Solution.v12.suo | Bin 385024 -> 385024 bytes 22 files changed, 237 insertions(+), 240 deletions(-) diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index c1e622deb..8c1ba6307 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -78,6 +78,7 @@ namespace Barotrauma Vector2 pos = host.SimPosition; if (character!=null && character.Submarine==null) { + //todo: take multiple subs into account pos -= Submarine.MainSub.SimPosition; } @@ -107,6 +108,7 @@ namespace Barotrauma Vector2 pos2 = host.SimPosition; if (character != null && character.Submarine == null) { + //todo: take multiple subs into account pos2 -= Submarine.MainSub.SimPosition; } return currentTarget-pos2; @@ -120,6 +122,7 @@ namespace Barotrauma Vector2 pos = host.SimPosition; if (character != null && character.Submarine == null) { + //todo: take multiple subs into account pos -= Submarine.MainSub.SimPosition; } diff --git a/Subsurface/Source/CoroutineManager.cs b/Subsurface/Source/CoroutineManager.cs index 7d9187e9c..a6b9929d5 100644 --- a/Subsurface/Source/CoroutineManager.cs +++ b/Subsurface/Source/CoroutineManager.cs @@ -86,21 +86,21 @@ namespace Barotrauma } } - try - { + //try + //{ Coroutines[i].Coroutine.MoveNext(); - } + //} - catch (Exception e) - { - DebugConsole.ThrowError("Coroutine " + Coroutines[i].Name + " threw an exception: " + e.Message); + //catch (Exception e) + //{ + // DebugConsole.ThrowError("Coroutine " + Coroutines[i].Name + " threw an exception: " + e.Message); -#if DEBUG - throw e; -#endif +//#if DEBUG +// throw e; +//#endif - Coroutines.RemoveAt(i); - } +// Coroutines.RemoveAt(i); +// } } } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index 901e59b26..d31140560 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -68,6 +68,8 @@ namespace Barotrauma public GameSession(Submarine submarine, string saveFile, GameModePreset gameModePreset = null, string missionType="") { + Submarine.MainSub = submarine; + GameMain.GameSession = this; CrewManager = new CrewManager(); @@ -88,6 +90,8 @@ namespace Barotrauma public GameSession(Submarine selectedSub, string saveFile, XDocument doc) : this(selectedSub, saveFile) { + Submarine.MainSub = submarine; + GameMain.GameSession = this; CrewManager = new CrewManager(); diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs index e23911b06..b1d4037f1 100644 --- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs @@ -132,80 +132,19 @@ namespace Barotrauma.Items.Components IsActive = true; activeTimer = 0.1f; + Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition); + Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition); - for (int n = 0; n < 2; n++) + if (character.Submarine == null) { - Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition); - Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition); - - if (n == 0) + foreach (Submarine sub in Submarine.Loaded) { - //do a raycast in "submarine coordinates" - rayStart -= Submarine.Loaded.SimPosition; - rayEnd -= Submarine.Loaded.SimPosition; + Repair(rayStart - sub.SimPosition, rayEnd - sub.SimPosition, deltaTime, character, degreeOfSuccess, ignoredBodies); } - else - { - //do a raycast outside the sub if the character is outside - if (character.AnimController.CurrentHull != null) continue; - } - - Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies); - - pickedPosition = Submarine.LastPickedPosition; - - if (ExtinquishAmount > 0.0f) - { - Vector2 displayPos = rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f; - Hull hull = Hull.FindHull(displayPos, item.CurrentHull); - if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos); - } - - if (targetBody == null || targetBody.UserData == null) continue; - - Structure targetStructure; - Limb targetLimb; - Item targetItem; - if ((targetStructure = (targetBody.UserData as Structure)) != null) - { - if (!fixableEntities.Contains(targetStructure.Name)) continue; - - int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition)); - if (sectionIndex < 0) continue; - - targetStructure.HighLightSection(sectionIndex); - - targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess); - - //if the next section is small enough, apply the effect to it as well - //(to make it easier to fix a small "left-over" section) - for (int i = -1; i < 2; i += 2) - { - int nextSectionLength = targetStructure.SectionLength(sectionIndex + i); - if ((sectionIndex == 1 && i == -1) || - (sectionIndex == targetStructure.SectionCount - 2 && i == 1) || - (nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f)) - { - targetStructure.HighLightSection(sectionIndex + i); - targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess); - } - } - - - } - else if ((targetLimb = (targetBody.UserData as Limb)) != null) - { - if (character.IsKeyDown(InputType.Aim)) - { - targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, character); - } - } - else if ((targetItem = (targetBody.UserData as Item)) != null) - { - targetItem.IsHighlighted = true; - - ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime); - } + } + else + { + Repair(rayStart, rayEnd, deltaTime, character, degreeOfSuccess, ignoredBodies); } GameMain.ParticleManager.CreateParticle(particles, item.WorldPosition + TransformedBarrelPos, @@ -214,6 +153,64 @@ namespace Barotrauma.Items.Components return true; } + private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List ignoredBodies) + { + + Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies); + + pickedPosition = Submarine.LastPickedPosition; + + if (ExtinquishAmount > 0.0f) + { + Vector2 displayPos = rayStart + (rayEnd - rayStart) * Submarine.LastPickedFraction * 0.9f; + Hull hull = Hull.FindHull(displayPos, item.CurrentHull); + if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos); + } + + if (targetBody == null || targetBody.UserData == null) return; + + Structure targetStructure; + Limb targetLimb; + Item targetItem; + if ((targetStructure = (targetBody.UserData as Structure)) != null) + { + if (!fixableEntities.Contains(targetStructure.Name)) return; + + int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition)); + if (sectionIndex < 0) return; + + targetStructure.HighLightSection(sectionIndex); + + targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess); + + //if the next section is small enough, apply the effect to it as well + //(to make it easier to fix a small "left-over" section) + for (int i = -1; i < 2; i += 2) + { + int nextSectionLength = targetStructure.SectionLength(sectionIndex + i); + if ((sectionIndex == 1 && i == -1) || + (sectionIndex == targetStructure.SectionCount - 2 && i == 1) || + (nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f)) + { + targetStructure.HighLightSection(sectionIndex + i); + targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess); + } + } + + + } + else if ((targetLimb = (targetBody.UserData as Limb)) != null) + { + targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user); + } + else if ((targetItem = (targetBody.UserData as Item)) != null) + { + targetItem.IsHighlighted = true; + + ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime); + } + } + public override bool AIOperate(float deltaTime, Character character, AIObjectiveOperateItem objective) { Gap leak = objective.OperateTarget as Gap; diff --git a/Subsurface/Source/Map/EntityGrid.cs b/Subsurface/Source/Map/EntityGrid.cs index b5b5b9d90..8641b6539 100644 --- a/Subsurface/Source/Map/EntityGrid.cs +++ b/Subsurface/Source/Map/EntityGrid.cs @@ -12,9 +12,12 @@ namespace Barotrauma private float cellSize; - public EntityGrid(Rectangle limits, float cellSize) + public readonly Submarine Submarine; + + public EntityGrid(Submarine submarine, float cellSize) { - this.limits = limits; + this.limits = submarine.Borders; + this.Submarine = submarine; this.cellSize = cellSize; entities = new List[(int)Math.Ceiling(limits.Width / cellSize), (int)Math.Ceiling(limits.Height / cellSize)]; @@ -71,11 +74,28 @@ namespace Barotrauma } } + public static List GetEntities(List entityGrids, Vector2 position, bool useWorldCoordinates = true) + { + List entities = new List(); + foreach (EntityGrid entityGrid in entityGrids) + { + Vector2 transformedPosition = position; + if (useWorldCoordinates) + { + transformedPosition -= entityGrid.Submarine.Position; + } + + entities.AddRange(entityGrid.GetEntities(position)); + } + + return entities; + } + public List GetEntities(Vector2 position) { if (!MathUtils.IsValid(position)) new List(); - if (Submarine.Loaded != null) position -= Submarine.HiddenSubPosition; + if (Submarine != null) position -= Submarine.HiddenSubPosition; Point indices = GetIndices(position); diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 813119bf8..d124b5305 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -15,7 +15,7 @@ namespace Barotrauma class Hull : MapEntity, IPropertyObject { public static List hullList = new List(); - private static EntityGrid entityGrid; + private static List entityGrids = new List(); public static bool ShowHulls = true; @@ -248,13 +248,15 @@ namespace Barotrauma return rect; } - public static void GenerateEntityGrid() + public static void GenerateEntityGrid(Submarine submarine) { - entityGrid = new EntityGrid(Submarine.Borders, 200.0f); + var newGrid = new EntityGrid(submarine, 200.0f); + + entityGrids.Add(newGrid); foreach (Hull hull in hullList) { - entityGrid.InsertEntity(hull); + if (hull.Submarine == submarine) newGrid.InsertEntity(hull); } } @@ -313,8 +315,14 @@ namespace Barotrauma } //renderer.Dispose(); + if (entityGrids != null) + { + foreach (EntityGrid entityGrid in entityGrids) + { + entityGrid.RemoveEntity(this); + } + } - if (entityGrid != null) entityGrid.RemoveEntity(this); hullList.Remove(this); } @@ -652,15 +660,14 @@ namespace Barotrauma //returns the water block which contains the point (or null if it isn't inside any) public static Hull FindHull(Vector2 position, Hull guess = null, bool useWorldCoordinates = true) { - if (entityGrid == null) return null; + if (entityGrids == null) return null; if (guess != null) { if (Submarine.RectContains(useWorldCoordinates ? guess.WorldRect : guess.rect, position)) return guess; } - var entities = entityGrid.GetEntities( - useWorldCoordinates && Submarine.Loaded!=null ? position-Submarine.Loaded.Position : position); + var entities = EntityGrid.GetEntities(entityGrids, position, useWorldCoordinates); foreach (Hull hull in entities) { diff --git a/Subsurface/Source/Map/Levels/Level.cs b/Subsurface/Source/Map/Levels/Level.cs index 338de50a6..8a34933fa 100644 --- a/Subsurface/Source/Map/Levels/Level.cs +++ b/Subsurface/Source/Map/Levels/Level.cs @@ -181,7 +181,7 @@ namespace Barotrauma float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3; GameMain.LightManager.AmbientLight = new Color(backgroundColor*(40.0f/avgValue), 1.0f); - float minWidth = Submarine.Loaded == null ? 0.0f : Math.Max(Submarine.Borders.Width, Submarine.Borders.Height); + float minWidth = Submarine.MainSub == null ? 0.0f : Math.Max(Submarine.MainSub.Borders.Width, Submarine.MainSub.Borders.Height); minWidth = Math.Max(minWidth, 6500.0f); startPosition = new Vector2(minWidth * 2, Rand.Range(minWidth * 2, borders.Height - minWidth * 2, false)); @@ -783,9 +783,9 @@ namespace Barotrauma public void Update (float deltaTime) { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - WrappingWall.UpdateWallShift(Submarine.Loaded.WorldPosition, wrappingWalls); + WrappingWall.UpdateWallShift(Submarine.MainSub.WorldPosition, wrappingWalls); } renderer.Update(deltaTime); diff --git a/Subsurface/Source/Map/MapEntity.cs b/Subsurface/Source/Map/MapEntity.cs index 0e9867f99..e1fa83562 100644 --- a/Subsurface/Source/Map/MapEntity.cs +++ b/Subsurface/Source/Map/MapEntity.cs @@ -518,7 +518,7 @@ namespace Barotrauma Vector2 placePosition = new Vector2(rect.X, rect.Y); Vector2 placeSize = new Vector2(rect.Width, rect.Height); - Vector2 mousePos = Submarine.MouseToWorldGrid(cam); + Vector2 mousePos = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (resizeDirX >0) { diff --git a/Subsurface/Source/Map/MapEntityPrefab.cs b/Subsurface/Source/Map/MapEntityPrefab.cs index f4056f461..c16577b7d 100644 --- a/Subsurface/Source/Map/MapEntityPrefab.cs +++ b/Subsurface/Source/Map/MapEntityPrefab.cs @@ -128,7 +128,7 @@ namespace Barotrauma if (placePosition == Vector2.Zero) { - Vector2 position = Submarine.MouseToWorldGrid(cam); + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); GUI.DrawLine(spriteBatch, new Vector2(position.X-GameMain.GraphicsWidth, -position.Y), new Vector2(position.X+GameMain.GraphicsWidth, -position.Y), Color.White); @@ -138,7 +138,7 @@ namespace Barotrauma } else { - Vector2 position = Submarine.MouseToWorldGrid(cam); + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (resizeHorizontal) placeSize.X = position.X - placePosition.X; if (resizeVertical) placeSize.Y = placePosition.Y - position.Y; @@ -147,9 +147,9 @@ namespace Barotrauma newRect.Width = (int)Math.Max(newRect.Width, Submarine.GridSize.X); newRect.Height = (int)Math.Max(newRect.Height, Submarine.GridSize.Y); - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - newRect.Location -= Submarine.Loaded.Position.ToPoint(); + newRect.Location -= Submarine.MainSub.Position.ToPoint(); } if (PlayerInput.LeftButtonReleased()) diff --git a/Subsurface/Source/Map/Structure.cs b/Subsurface/Source/Map/Structure.cs index 6298baf60..349498bb3 100644 --- a/Subsurface/Source/Map/Structure.cs +++ b/Subsurface/Source/Map/Structure.cs @@ -520,7 +520,7 @@ namespace Barotrauma public AttackResult AddDamage(IDamageable attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = false) { - if (Submarine.Loaded != null && Submarine.Loaded.GodMode && Submarine == Submarine.Loaded) return new AttackResult(0.0f, 0.0f); + if (Submarine != null && Submarine.GodMode) return new AttackResult(0.0f, 0.0f); if (!prefab.HasBody || prefab.IsPlatform) return new AttackResult(0.0f, 0.0f); Vector2 transformedPos = worldPosition; @@ -546,7 +546,7 @@ namespace Barotrauma private void SetDamage(int sectionIndex, float damage) { - if (Submarine.Loaded != null && Submarine.Loaded.GodMode) return; + if (Submarine != null && Submarine.GodMode) return; if (!prefab.HasBody) return; if (!MathUtils.IsValid(damage)) return; diff --git a/Subsurface/Source/Map/StructurePrefab.cs b/Subsurface/Source/Map/StructurePrefab.cs index abedc550c..9d9f7f123 100644 --- a/Subsurface/Source/Map/StructurePrefab.cs +++ b/Subsurface/Source/Map/StructurePrefab.cs @@ -128,7 +128,7 @@ namespace Barotrauma public override void UpdatePlacing(SpriteBatch spriteBatch, Camera cam) { - Vector2 position = Submarine.MouseToWorldGrid(cam); + Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); //Vector2 placeSize = size; Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y); @@ -137,7 +137,7 @@ namespace Barotrauma if (placePosition == Vector2.Zero) { if (PlayerInput.LeftButtonHeld()) - placePosition = Submarine.MouseToWorldGrid(cam); + placePosition = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); newRect.X = (int)position.X; newRect.Y = (int)position.Y; @@ -154,14 +154,10 @@ namespace Barotrauma if (PlayerInput.LeftButtonReleased()) { - if (Submarine.Loaded != null) - { - newRect.Location -= Submarine.Loaded.Position.ToPoint(); - } + newRect.Location -= Submarine.MainSub.Position.ToPoint(); - var structure = new Structure(newRect, this, Submarine.Loaded); - - structure.Submarine = Submarine.Loaded; + var structure = new Structure(newRect, this, Submarine.MainSub); + structure.Submarine = Submarine.MainSub; selected = null; return; diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 7c5da46d5..87382b78c 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -31,7 +31,7 @@ namespace Barotrauma public static readonly Vector2 GridSize = new Vector2(16.0f, 16.0f); public static Submarine MainSub; - private static List loaded; + private static List loaded = new List(); private SubmarineBody subBody; @@ -97,10 +97,10 @@ namespace Barotrauma } } - //public static List Loaded - //{ - // get { return loaded; } - //} + public static List Loaded + { + get { return loaded; } + } public Rectangle Borders { @@ -789,7 +789,7 @@ namespace Barotrauma loaded.Add(this); - Hull.GenerateEntityGrid(); + Hull.GenerateEntityGrid(this); for (int i = 0; i < MapEntity.mapEntityList.Count; i++) { diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index 2197edc70..9854a9348 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -83,7 +83,7 @@ namespace Barotrauma } public WayPoint(MapEntityPrefab prefab, Rectangle rectangle) - : this (rectangle, Submarine.Loaded) + : this (rectangle, Submarine.MainSub) { if (prefab.Name.Contains("Spawn")) { @@ -306,7 +306,7 @@ namespace Barotrauma return editingHUD; } - public static void GenerateSubWaypoints() + public static void GenerateSubWaypoints(Submarine submarine) { if (!Hull.hullList.Any()) { @@ -332,13 +332,13 @@ namespace Barotrauma if (hull.Rect.Width(); if (door != null) { - WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, Submarine.Loaded); + WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, submarine); newPoint.Ladders = ladders; newPoint.ConnectedGap = door.LinkedGap; @@ -538,7 +539,7 @@ namespace Barotrauma if (gap.Rect.Height < 150.0f) continue; var wayPoint = new WayPoint( - new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height + heightFromFloor), SpawnType.Path, Submarine.Loaded, gap); + new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height + heightFromFloor), SpawnType.Path, submarine, gap); for (int dir = -1; dir <= 1; dir += 2) { @@ -557,7 +558,7 @@ namespace Barotrauma if (gap.Rect.Width < 100.0f) continue; var wayPoint = new WayPoint( - new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height/2), SpawnType.Path, Submarine.Loaded, gap); + new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height/2), SpawnType.Path, submarine, gap); for (int dir = -1; dir <= 1; dir += 2) { @@ -583,35 +584,35 @@ namespace Barotrauma WayPoint closest = null; - foreach (WayPoint wp in WayPointList) + foreach (WayPoint wp in WayPointList) + { + if (wp.SpawnType != SpawnType.Path || wp == this) continue; + + float diff = 0.0f; + if (horizontalSearch) { - if (wp.SpawnType != SpawnType.Path || wp == this) continue; + if ((wp.Position.Y - Position.Y) < tolerance.X || (wp.Position.Y - Position.Y) > tolerance.Y) continue; - float diff = 0.0f; - if (horizontalSearch) - { - if ((wp.Position.Y - Position.Y) < tolerance.X || (wp.Position.Y - Position.Y) > tolerance.Y) continue; - - diff = wp.Position.X - Position.X; - } - else - { - if ((wp.Position.X - Position.X) < tolerance.X || (wp.Position.X - Position.X) > tolerance.Y) continue; - - diff = wp.Position.Y - Position.Y; - } - - if (Math.Sign(diff) != dir) continue; - - float dist = Vector2.Distance(wp.Position, Position); - if (closest == null || dist < closestDist) - { - if (Submarine.CheckVisibility(SimPosition, wp.SimPosition) != null) continue; - - closestDist = dist; - closest = wp; - } + diff = wp.Position.X - Position.X; } + else + { + if ((wp.Position.X - Position.X) < tolerance.X || (wp.Position.X - Position.X) > tolerance.Y) continue; + + diff = wp.Position.Y - Position.Y; + } + + if (Math.Sign(diff) != dir) continue; + + float dist = Vector2.Distance(wp.Position, Position); + if (closest == null || dist < closestDist) + { + if (Submarine.CheckVisibility(SimPosition, wp.SimPosition) != null) continue; + + closestDist = dist; + closest = wp; + } + } return closest; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 0cc704603..905d2e5e1 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -729,7 +729,7 @@ namespace Barotrauma.Networking if (Screen.Selected == GameMain.GameScreen) { - var cinematic = new TransitionCinematic(Submarine.Loaded, GameMain.GameScreen.Cam, endPreviewLength); + var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, endPreviewLength); float secondsLeft = endPreviewLength; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index f15001b48..0ea8f8c99 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -289,7 +289,7 @@ namespace Barotrauma.Networking //restart if all characters are dead or submarine is at the end of the level if ((autoRestart && isCrewDead) || - (endRoundAtLevelEnd && Submarine.Loaded!=null && Submarine.Loaded.AtEndPosition)) + (endRoundAtLevelEnd && Submarine.MainSub != null && Submarine.MainSub.AtEndPosition)) { if (AutoRestart && isCrewDead) { @@ -363,7 +363,8 @@ namespace Barotrauma.Networking { if (!(c is AICharacter) || c.IsDead) continue; - Vector2 diff = c.WorldPosition-Submarine.Loaded.WorldPosition; + //todo: take multiple subs into account + Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; @@ -389,7 +390,13 @@ namespace Barotrauma.Networking private void SparseUpdate() { - if (gameStarted) new NetworkEvent(Submarine.Loaded.ID, false); + if (gameStarted) + { + foreach (Submarine sub in Submarine.Loaded) + { + new NetworkEvent(sub.ID, false); + } + } foreach (Character c in Character.CharacterList) { @@ -397,7 +404,8 @@ namespace Barotrauma.Networking if (c is AICharacter) { - Vector2 diff = c.WorldPosition - Submarine.Loaded.WorldPosition; + //todo: take multiple subs into account + Vector2 diff = c.WorldPosition - Submarine.MainSub.WorldPosition; if (FarseerPhysics.ConvertUnits.ToSimUnits(diff.Length()) > NetConfig.CharacterIgnoreDistance) continue; } @@ -601,7 +609,7 @@ namespace Barotrauma.Networking case (byte)PacketTypes.SpectateRequest: if (gameStarted && allowSpectating) { - var startMessage = CreateStartMessage(roundStartSeed, Submarine.Loaded, GameMain.GameSession.gameMode.Preset); + var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset); server.SendMessage(startMessage, inc.SenderConnection, NetDeliveryMethod.ReliableUnordered); dataSender.Spectating = true; @@ -985,7 +993,7 @@ namespace Barotrauma.Networking GameMain.GameSession.CrewManager.characters.Add(myCharacter); } - var startMessage = CreateStartMessage(roundStartSeed, Submarine.Loaded, GameMain.GameSession.gameMode.Preset); + var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset); SendMessage(startMessage, NetDeliveryMethod.ReliableUnordered); @@ -1113,7 +1121,7 @@ namespace Barotrauma.Networking float endPreviewLength = 10.0f; - var cinematic = new TransitionCinematic(Submarine.Loaded, GameMain.GameScreen.Cam, endPreviewLength); + var cinematic = new TransitionCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, endPreviewLength); float secondsLeft = endPreviewLength; diff --git a/Subsurface/Source/Program.cs b/Subsurface/Source/Program.cs index d330ef949..a9467f510 100644 --- a/Subsurface/Source/Program.cs +++ b/Subsurface/Source/Program.cs @@ -65,7 +65,7 @@ namespace Barotrauma sb.AppendLine("Game version " + GameMain.Version); sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name); sb.AppendLine("Level seed: "+ ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); - sb.AppendLine("Loaded submarine: " + ((Submarine.Loaded == null) ? "none" : Submarine.Loaded.Name +" ("+Submarine.Loaded.MD5Hash+")")); + sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "none" : Submarine.MainSub.Name +" ("+Submarine.MainSub.MD5Hash+")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (GameMain.Server != null) diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index eccca1c49..2e17f1da8 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -46,7 +46,7 @@ namespace Barotrauma public string GetSubName() { - return ((Submarine.Loaded == null) ? "" : Submarine.Loaded.Name); + return (Submarine.MainSub == null) ? "" : Submarine.MainSub.Name; } private string GetItemCount() @@ -231,11 +231,11 @@ namespace Barotrauma GUIComponent.MouseOn = null; characterMode = false; - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - cam.Position = Submarine.Loaded.Position + Submarine.HiddenSubPosition; - nameBox.Text = Submarine.Loaded.Name; - descriptionBox.Text = ToolBox.LimitString(Submarine.Loaded.Description,15); + cam.Position = Submarine.MainSub.Position + Submarine.HiddenSubPosition; + nameBox.Text = Submarine.MainSub.Name; + descriptionBox.Text = ToolBox.LimitString(Submarine.MainSub.Description, 15); } else { @@ -303,9 +303,9 @@ namespace Barotrauma string savePath = nameBox.Text + ".sub"; - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - savePath = Path.Combine(Path.GetDirectoryName(Submarine.Loaded.FilePath), savePath); + savePath = Path.Combine(Path.GetDirectoryName(Submarine.MainSub.FilePath), savePath); } else { @@ -313,9 +313,9 @@ namespace Barotrauma } Submarine.SaveCurrent(savePath); - Submarine.Loaded.CheckForErrors(); + Submarine.MainSub.CheckForErrors(); - GUI.AddMessage("Submarine saved to " + Submarine.Loaded.FilePath, Color.Green, 3.0f); + GUI.AddMessage("Submarine saved to " + Submarine.MainSub.FilePath, Color.Green, 3.0f); return false; } @@ -560,7 +560,7 @@ namespace Barotrauma return false; } - if (Submarine.Loaded != null) Submarine.Loaded.Name = text; + if (Submarine.MainSub != null) Submarine.MainSub.Name = text; textBox.Deselect(); textBox.Text = text; @@ -572,9 +572,9 @@ namespace Barotrauma private bool ChangeSubDescription(GUITextBox textBox, string text) { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - Submarine.Loaded.Description = text; + Submarine.MainSub.Description = text; } else { @@ -593,9 +593,9 @@ namespace Barotrauma private void ExpandDescriptionBox(GUITextBox textBox, Keys key) { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - textBox.Text = Submarine.Loaded.Description; + textBox.Text = Submarine.MainSub.Description; } else if (textBox.UserData is string) { @@ -617,7 +617,9 @@ namespace Barotrauma private bool GenerateWaypoints(GUIButton button, object obj) { - WayPoint.GenerateSubWaypoints(); + if (Submarine.MainSub == null) return false; + + WayPoint.GenerateSubWaypoints(Submarine.MainSub); return true; } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index a00726b7c..1532eeea0 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -56,9 +56,9 @@ namespace Barotrauma { cam.Position = Character.Controlled.WorldPosition; } - else if (Submarine.Loaded != null) + else if (Submarine.MainSub != null) { - cam.Position = Submarine.Loaded.WorldPosition; + cam.Position = Submarine.MainSub.WorldPosition; } foreach (MapEntity entity in MapEntity.mapEntityList) @@ -119,9 +119,11 @@ namespace Barotrauma //Lights.LightManager.ViewPos = Character.Controlled.WorldPosition; } cam.MoveCamera((float)Physics.step); - - - if (Submarine.Loaded != null) Submarine.Loaded.SetPrevTransform(Submarine.Loaded.Position); + + foreach (Submarine sub in Submarine.Loaded) + { + sub.SetPrevTransform(sub.Position); + } foreach (PhysicsBody pb in PhysicsBody.list) { @@ -175,7 +177,7 @@ namespace Barotrauma if (GameMain.GameSession != null) GameMain.GameSession.Draw(spriteBatch); - if (Character.Controlled == null && Submarine.Loaded != null) DrawSubmarineIndicator(spriteBatch, Submarine.Loaded); + if (Character.Controlled == null && Submarine.Loaded != null) DrawSubmarineIndicator(spriteBatch, Submarine.MainSub); GUI.Draw((float)deltaTime, spriteBatch, cam); @@ -187,7 +189,10 @@ namespace Barotrauma public void DrawMap(GraphicsDevice graphics, SpriteBatch spriteBatch) { - if (Submarine.Loaded != null) Submarine.Loaded.UpdateTransform(); + foreach (Submarine sub in Submarine.Loaded) + { + sub.UpdateTransform(); + } GameMain.LightManager.ObstructVision = Character.Controlled != null && Character.Controlled.ObstructVision; diff --git a/Subsurface/Source/Sounds/SoundPlayer.cs b/Subsurface/Source/Sounds/SoundPlayer.cs index 6663693a2..59606fefd 100644 --- a/Subsurface/Source/Sounds/SoundPlayer.cs +++ b/Subsurface/Source/Sounds/SoundPlayer.cs @@ -183,7 +183,8 @@ namespace Barotrauma startDrone = null; } - if (Submarine.Loaded==null) + //todo: ambient sounds for multiple subs + if (Submarine.MainSub == null) { for (int i = 0; i < waterAmbienceIndexes.Length; i++) { @@ -213,9 +214,9 @@ namespace Barotrauma //how fast the sub is moving, scaled to 0.0 -> 1.0 float movementFactor = 0.0f; - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - movementFactor = (Submarine.Loaded.Velocity == Vector2.Zero) ? 0.0f : Submarine.Loaded.Velocity.Length() / 5.0f; + movementFactor = (Submarine.MainSub.Velocity == Vector2.Zero) ? 0.0f : Submarine.MainSub.Velocity.Length() / 5.0f; movementFactor = MathHelper.Clamp(movementFactor, 0.0f, 1.0f); } @@ -303,7 +304,7 @@ namespace Barotrauma { return musicClips.Where(x => x != null && x.type == "ruins").ToList(); } - else if (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) + else if (Submarine.MainSub != null && Submarine.MainSub.AtDamageDepth) { return musicClips.Where(x => x != null && x.type == "deep").ToList(); } diff --git a/Subsurface/Source/Utils/SaveUtil.cs b/Subsurface/Source/Utils/SaveUtil.cs index cd6903cd3..cf4f714d1 100644 --- a/Subsurface/Source/Utils/SaveUtil.cs +++ b/Subsurface/Source/Utils/SaveUtil.cs @@ -30,9 +30,9 @@ namespace Barotrauma try { - if (Submarine.Loaded != null) + if (Submarine.MainSub != null) { - Submarine.Loaded.SaveAs(Path.Combine(tempPath, Submarine.Loaded.Name+".sub")); + Submarine.MainSub.SaveAs(Path.Combine(tempPath, Submarine.MainSub.Name+".sub")); } } catch (Exception e) diff --git a/Subsurface_Solution.sln b/Subsurface_Solution.sln index acdb73956..19e687774 100644 --- a/Subsurface_Solution.sln +++ b/Subsurface_Solution.sln @@ -11,8 +11,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network", "Lidgren. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Launcher", "Launcher2\Launcher.csproj", "{251AAFE1-F24B-4837-9128-9D04FCBFD528}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrashReporter", "CrashReporter\CrashReporter.csproj", "{6BE950CD-9A34-49C9-939A-786AC89C287E}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D32A29D8-AC7B-4189-B734-8ED9EB4120D0}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hyper.ComponentModel", "Hyper.ComponentModel\Hyper.ComponentModel.csproj", "{3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}" @@ -228,51 +226,6 @@ Global {251AAFE1-F24B-4837-9128-9D04FCBFD528}.Windows8|Mixed Platforms.Build.0 = Release|x86 {251AAFE1-F24B-4837-9128-9D04FCBFD528}.Windows8|x86.ActiveCfg = Release|x86 {251AAFE1-F24B-4837-9128-9D04FCBFD528}.Windows8|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Android|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|Any CPU.ActiveCfg = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|x86.ActiveCfg = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Debug|x86.Build.0 = Debug|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.iOS|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Linux|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.OSX|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.PSM|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Release|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows|x86.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|Any CPU.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|Mixed Platforms.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|Mixed Platforms.Build.0 = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|x86.ActiveCfg = Release|x86 - {6BE950CD-9A34-49C9-939A-786AC89C287E}.Windows8|x86.Build.0 = Release|x86 {3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}.Android|Any CPU.ActiveCfg = Release|Any CPU {3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}.Android|Any CPU.Build.0 = Release|Any CPU {3B8F9EDB-6E5E-450C-ABC2-EC49075D0B50}.Android|Mixed Platforms.ActiveCfg = Release|Any CPU diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index fd7b05d759a106c14de4c06e169dc44c9022020d..ab8b5bd6d7356afa1875ffd39fd3b9de1e534392 100644 GIT binary patch delta 11161 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