diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index a0285d8a9..8965cd2a0 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -632,6 +632,9 @@ PreserveNewest Designer + + PreserveNewest + PreserveNewest @@ -721,9 +724,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest Designer diff --git a/Subsurface/Content/Items/MiniMap/reactor.png b/Subsurface/Content/Items/MiniMap/reactor.png deleted file mode 100644 index ab6d4d0e7..000000000 Binary files a/Subsurface/Content/Items/MiniMap/reactor.png and /dev/null differ diff --git a/Subsurface/Content/Items/Weapons/railgun.xml b/Subsurface/Content/Items/Weapons/railgun.xml index 7d0cbfa7f..ef3dfc35a 100644 --- a/Subsurface/Content/Items/Weapons/railgun.xml +++ b/Subsurface/Content/Items/Weapons/railgun.xml @@ -56,7 +56,7 @@ - + diff --git a/Subsurface/Content/Items/Weapons/railgunloader.png b/Subsurface/Content/Items/Weapons/railgunloader.png index 30992d88c..76cbaf2db 100644 Binary files a/Subsurface/Content/Items/Weapons/railgunloader.png and b/Subsurface/Content/Items/Weapons/railgunloader.png differ diff --git a/Subsurface/Content/Map/StructurePrefabs.xml b/Subsurface/Content/Map/StructurePrefabs.xml index 0c6384379..5850dcba4 100644 --- a/Subsurface/Content/Map/StructurePrefabs.xml +++ b/Subsurface/Content/Map/StructurePrefabs.xml @@ -76,8 +76,8 @@ - + diff --git a/Subsurface/Content/Map/waypointIcons.png b/Subsurface/Content/Map/waypointIcons.png new file mode 100644 index 000000000..b6ceff9a2 Binary files /dev/null and b/Subsurface/Content/Map/waypointIcons.png differ diff --git a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs index 9454cdb4f..b3aefd52e 100644 --- a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs @@ -651,7 +651,7 @@ namespace Barotrauma MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, head.SimPosition.Y + 0.05f), 10.5f); MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, torso.SimPosition.Y), 10.5f); MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, waist.SimPosition.Y), 10.5f); - + float stepHeight = ConvertUnits.ToSimUnits(30.0f); handPos = new Vector2( diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs index 631dd8c3b..75c3d48d1 100644 --- a/Subsurface/Source/DebugConsole.cs +++ b/Subsurface/Source/DebugConsole.cs @@ -363,6 +363,16 @@ namespace Barotrauma return; } if (Submarine.SaveCurrent(fileName +".sub")) NewMessage("map saved", Color.Green); + + if (WayPoint.WayPointList.Find(wp => !wp.MoveWithLevel && wp.SpawnType == SpawnType.Path)==null) + { + DebugConsole.ThrowError("No waypoints found in the submarine. Did you forget to generate the waypoints?"); + } + + if (WayPoint.WayPointList.Find(wp => wp.SpawnType == SpawnType.Cargo) == null) + { + DebugConsole.ThrowError("The submarine doesn't have a waypoint marked as ''Cargo'', which are used for determining where to place bought items."); + } break; case "loadmap": case "loadsub": @@ -454,7 +464,7 @@ namespace Barotrauma //messages.Add(new ColoredText(msg, color)); - if (textBox != null && textBox.Text == "") selectedIndex = listBox.children.Count; + selectedIndex = listBox.children.Count; } public static void ThrowError(string error, Exception e = null) diff --git a/Subsurface/Source/Items/CharacterInventory.cs b/Subsurface/Source/Items/CharacterInventory.cs index 54d743620..aebb6ddc7 100644 --- a/Subsurface/Source/Items/CharacterInventory.cs +++ b/Subsurface/Source/Items/CharacterInventory.cs @@ -25,7 +25,7 @@ namespace Barotrauma LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any, LimbSlot.Any}; - private Vector2[] slotPositions; + public Vector2[] SlotPositions; public CharacterInventory(int capacity, Character character) : base(character, capacity) @@ -34,11 +34,11 @@ namespace Barotrauma if (icons == null) icons = TextureLoader.FromFile("Content/UI/inventoryIcons.png"); - slotPositions = new Vector2[limbSlots.Length]; + SlotPositions = new Vector2[limbSlots.Length]; int rectWidth = 40, rectHeight = 40; int spacing = 10; - for (int i = 0; i < slotPositions.Length; i++) + for (int i = 0; i < SlotPositions.Length; i++) { switch (i) { @@ -46,19 +46,19 @@ namespace Barotrauma case 0: case 1: case 2: - slotPositions[i] = new Vector2( + SlotPositions[i] = new Vector2( spacing, GameMain.GraphicsHeight - (spacing + rectHeight) * (3 - i)); break; //lefthand, righthand case 3: case 4: - slotPositions[i] = new Vector2( + SlotPositions[i] = new Vector2( spacing * 2 + rectWidth + (spacing + rectWidth) * (i - 3), GameMain.GraphicsHeight - (spacing + rectHeight)*3); break; default: - slotPositions[i] = new Vector2( + SlotPositions[i] = new Vector2( spacing * 2 + rectWidth + (spacing + rectWidth) * ((i - 3)%5), GameMain.GraphicsHeight - (spacing + rectHeight) * ((i>9) ? 2 : 1)); break; @@ -225,8 +225,8 @@ namespace Barotrauma for (int i = 0; i < capacity; i++) { - slotRect.X = (int)slotPositions[i].X; - slotRect.Y = (int)slotPositions[i].Y; + slotRect.X = (int)SlotPositions[i].X; + slotRect.Y = (int)SlotPositions[i].Y; if (i==1) //head { @@ -246,8 +246,8 @@ namespace Barotrauma for (int i = 0; i < capacity; i++) { - slotRect.X = (int)slotPositions[i].X; - slotRect.Y = (int)slotPositions[i].Y; + slotRect.X = (int)SlotPositions[i].X; + slotRect.Y = (int)SlotPositions[i].Y; bool multiSlot = false; //skip if the item is in multiple slots @@ -285,8 +285,8 @@ namespace Barotrauma //check if the item is in multiple slots if (Items[i] != null) { - slotRect.X = (int)slotPositions[i].X; - slotRect.Y = (int)slotPositions[i].Y; + slotRect.X = (int)SlotPositions[i].X; + slotRect.Y = (int)SlotPositions[i].Y; slotRect.Width = 40; slotRect.Height = 40; @@ -300,7 +300,7 @@ namespace Barotrauma { multiSlot = true; slotRect = Rectangle.Union( - new Rectangle((int)slotPositions[n].X, (int)slotPositions[n].Y, rectWidth, rectHeight), slotRect); + new Rectangle((int)SlotPositions[n].X, (int)SlotPositions[n].Y, rectWidth, rectHeight), slotRect); } } } diff --git a/Subsurface/Source/Items/Components/Door.cs b/Subsurface/Source/Items/Components/Door.cs index 356b1ad31..76f148d05 100644 --- a/Subsurface/Source/Items/Components/Door.cs +++ b/Subsurface/Source/Items/Components/Door.cs @@ -13,12 +13,12 @@ namespace Barotrauma.Items.Components { class Door : ItemComponent { - Gap linkedGap; + private Gap linkedGap; - Rectangle window; + private Rectangle window; - ConvexHull convexHull; - ConvexHull convexHull2; + private ConvexHull convexHull; + private ConvexHull convexHull2; private bool isOpen; @@ -45,7 +45,7 @@ namespace Barotrauma.Items.Components } } - Gap LinkedGap + public Gap LinkedGap { get { @@ -139,7 +139,7 @@ namespace Barotrauma.Items.Components doorRect = new Rectangle( item.Rect.Center.X - (int)(doorSprite.size.X / 2), - item.Rect.Y, + item.Rect.Y - item.Rect.Height/2 + (int)(doorSprite.size.Y / 2.0f), (int)doorSprite.size.X, (int)doorSprite.size.Y); @@ -165,24 +165,23 @@ namespace Barotrauma.Items.Components private void UpdateConvexHulls() { Rectangle rect = doorRect; - - rect.Height = (int)(rect.Height * (1.0f - openState)); - if (window.Height == 0 || window.Width == 0) + if (isHorizontal) { - + rect.Width = (int)(rect.Width * (1.0f - openState)); } else { - //Rectangle rect = item.Rect; - //rect.Height = (int)(rect.Height * (1.0f - openState)); + rect.Height = (int)(rect.Height * (1.0f - openState)); + } + if (window.Height > 0 && window.Width > 0) + { rect.Height = -window.Y; rect.Y += (int)(doorRect.Height * openState); rect.Height = Math.Max(rect.Height - (rect.Y - doorRect.Y), 0); rect.Y = Math.Min(doorRect.Y, rect.Y); - if (convexHull2 != null) { Rectangle rect2 = doorRect; @@ -395,8 +394,8 @@ namespace Barotrauma.Items.Components if (isHorizontal) { - l.body.SetTransform(new Vector2(l.SimPosition.X, item.SimPosition.Y + dir * simSize.Y * 1.2f), l.body.Rotation); - l.body.ApplyLinearImpulse(new Vector2(isOpen ? 0.0f : 1.0f, dir * 0.5f)); + l.body.SetTransform(new Vector2(l.SimPosition.X, item.SimPosition.Y + dir * simSize.Y * 2.0f), l.body.Rotation); + l.body.ApplyLinearImpulse(new Vector2(isOpen ? 0.0f : 1.0f, dir * 2.0f)); } else { diff --git a/Subsurface/Source/Items/Components/Turret.cs b/Subsurface/Source/Items/Components/Turret.cs index d0bd5514b..ce1f197fe 100644 --- a/Subsurface/Source/Items/Components/Turret.cs +++ b/Subsurface/Source/Items/Components/Turret.cs @@ -89,6 +89,24 @@ namespace Barotrauma.Items.Components drawPos + barrelPos, Color.White, rotation + MathHelper.PiOver2, 1.0f, SpriteEffects.None, item.Sprite.Depth+0.01f); + + if (!editing) return; + + GUI.DrawLine(spriteBatch, + drawPos + barrelPos, + drawPos + barrelPos + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation))*60.0f, + Color.Green); + + GUI.DrawLine(spriteBatch, + drawPos + barrelPos, + drawPos + barrelPos + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * 60.0f, + Color.Green); + + GUI.DrawLine(spriteBatch, + drawPos + barrelPos, + drawPos + barrelPos + new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)) * 60.0f, + Color.LightGreen); + } public override void Update(float deltaTime, Camera cam) diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 626a4274b..24e97da19 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -908,8 +908,8 @@ namespace Barotrauma transformedTrigger.X + transformedTrigger.Width / 2.0f, transformedTrigger.Y - transformedTrigger.Height / 2.0f); - dist = MathHelper.Min(Math.Abs(triggerCenter.X - displayPos.X), Math.Abs(triggerCenter.Y-displayPos.Y)); - if (dist > closestDist && closest!=null) continue; + //dist = MathHelper.Min(Math.Abs(triggerCenter.X - displayPos.X), Math.Abs(triggerCenter.Y-displayPos.Y)); + //if (dist > closestDist && closest!=null) continue; dist = MathHelper.Min(Math.Abs(triggerCenter.X - displayPickPos.X), Math.Abs(triggerCenter.Y - displayPickPos.Y)); if (closest == null || dist < closestDist) @@ -951,6 +951,13 @@ namespace Barotrauma return false; } + public bool IsInPickRange(Vector2 worldPosition) + { + if (IsInsideTrigger(worldPosition)) return true; + + return Vector2.Distance(WorldPosition, worldPosition) < PickDistance; + } + public bool Pick(Character picker, bool ignoreRequiredItems=false, bool forceSelectKey=false, bool forceActionKey=false) { @@ -1019,7 +1026,7 @@ namespace Barotrauma picker.SelectedConstruction = this; } - if (!hasRequiredSkills && Character.Controlled==picker) + if (!hasRequiredSkills && Character.Controlled==picker && Screen.Selected != GameMain.EditMapScreen) { GUI.AddMessage("Your skills may be insufficient to use the item!", Color.Red, 5.0f); if (requiredSkill != null) diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs index a40fb0849..94319dd21 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -67,7 +67,7 @@ namespace Barotrauma } } - public Gap(Rectangle rectangle) + public Gap(MapEntityPrefab prefab, Rectangle rectangle) : this (rectangle, Submarine.Loaded) { } @@ -225,7 +225,6 @@ namespace Barotrauma soundIndex = SoundPlayer.flowSounds[index].Loop(soundIndex, soundVolume, WorldPosition, 2000.0f); flowForce = Vector2.Zero; - lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, 0.05f); if (open == 0.0f) return; @@ -242,7 +241,9 @@ namespace Barotrauma UpdateRoomToRoom(deltaTime); } - if (LerpedFlowForce.Length() > 150.0f && flowTargetHull != null && flowTargetHull.Volume < flowTargetHull.FullVolume) + lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, deltaTime*2.0f); + + if (LerpedFlowForce.Length() > 100.0f && flowTargetHull != null && flowTargetHull.Volume < flowTargetHull.FullVolume) { //UpdateFlowForce(); @@ -256,8 +257,10 @@ namespace Barotrauma MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.5f, 0.7f), flowForce.Y * Rand.Range(0.5f, 0.7f)); - var particle = GameMain.ParticleManager.CreateParticle("watersplash", - new Vector2(pos.X, pos.Y - Rand.Range(0.0f, 10.0f)), velocity); + var particle = GameMain.ParticleManager.CreateParticle( + "watersplash", + (Submarine.Loaded==null ? pos : pos + Submarine.Loaded.Position) - Vector2.UnitY * Rand.Range(0.0f, 10.0f), + velocity); if (particle != null) { @@ -266,7 +269,10 @@ namespace Barotrauma pos.Y = Rand.Range(lowerSurface, rect.Y - rect.Height); - GameMain.ParticleManager.CreateParticle("bubbles", pos, flowForce / 200.0f); + GameMain.ParticleManager.CreateParticle( + "bubbles", + Submarine.Loaded==null ? pos : pos + Submarine.Loaded.Position, + flowForce / 200.0f); } else { @@ -278,13 +284,18 @@ namespace Barotrauma Vector2 velocity = new Vector2( flowForce.X * Rand.Range(0.5f, 0.7f), Math.Max(flowForce.Y,-100.0f) * Rand.Range(0.5f, 0.7f)); - - var splash = GameMain.ParticleManager.CreateParticle("watersplash", pos, + + var splash = GameMain.ParticleManager.CreateParticle( + "watersplash", + Submarine.Loaded == null ? pos : pos + Submarine.Loaded.Position, velocity); if (splash != null) splash.Size = splash.Size * MathHelper.Clamp(rect.Width / 50.0f, 0.8f, 4.0f); - GameMain.ParticleManager.CreateParticle("bubbles", pos, flowForce / 2.0f); + GameMain.ParticleManager.CreateParticle( + "bubbles", + Submarine.Loaded == null ? pos : pos + Submarine.Loaded.Position, + flowForce / 2.0f); } } diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 91dac09e2..21b4dd180 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -136,7 +136,7 @@ namespace Barotrauma get { return fireSources; } } - public Hull(Rectangle rectangle) + public Hull(MapEntityPrefab prefab, Rectangle rectangle) : this (rectangle, Submarine.Loaded) { diff --git a/Subsurface/Source/Map/MapEntityPrefab.cs b/Subsurface/Source/Map/MapEntityPrefab.cs index 8c0f35697..3a387a439 100644 --- a/Subsurface/Source/Map/MapEntityPrefab.cs +++ b/Subsurface/Source/Map/MapEntityPrefab.cs @@ -89,25 +89,31 @@ namespace Barotrauma public static void Init() { MapEntityPrefab ep = new MapEntityPrefab(); - ep.name = "hull"; + ep.name = "Hull"; ep.Description = "Hulls determine which parts are considered to be ''inside the sub''. Generally every room should be enclosed by a hull."; - ep.constructor = typeof(Hull).GetConstructor(new Type[] { typeof(Rectangle) }); + ep.constructor = typeof(Hull).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) }); ep.resizeHorizontal = true; ep.resizeVertical = true; list.Add(ep); ep = new MapEntityPrefab(); - ep.name = "gap"; + ep.name = "Gap"; ep.Description = "Gaps allow water and air to flow between two hulls. "; - ep.constructor = typeof(Gap).GetConstructor(new Type[] { typeof(Rectangle) }); + ep.constructor = typeof(Gap).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) }); ep.resizeHorizontal = true; ep.resizeVertical = true; list.Add(ep); ep = new MapEntityPrefab(); - ep.name = "waypoint"; - ep.constructor = typeof(WayPoint).GetConstructor(new Type[] { typeof(Rectangle) }); + ep.name = "Waypoint"; + ep.constructor = typeof(WayPoint).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) }); list.Add(ep); + + ep = new MapEntityPrefab(); + ep.name = "Spawnpoint"; + ep.constructor = typeof(WayPoint).GetConstructor(new Type[] { typeof(MapEntityPrefab), typeof(Rectangle) }); + list.Add(ep); + } @@ -121,7 +127,7 @@ namespace Barotrauma GUI.DrawLine(spriteBatch, new Vector2(position.X-GameMain.GraphicsWidth, -position.Y), new Vector2(position.X+GameMain.GraphicsWidth, -position.Y), Color.White); - GUI.DrawLine(spriteBatch, new Vector2(position.X, position.Y - GameMain.GraphicsHeight), new Vector2(position.X, position.Y+GameMain.GraphicsHeight), Color.White); + GUI.DrawLine(spriteBatch, new Vector2(position.X, -(position.Y - GameMain.GraphicsHeight)), new Vector2(position.X, -(position.Y + GameMain.GraphicsHeight)), Color.White); if (PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed) placePosition = position; } @@ -138,7 +144,7 @@ namespace Barotrauma if (PlayerInput.GetMouseState.LeftButton == ButtonState.Released) { - object[] lobject = new object[] { newRect }; + object[] lobject = new object[] { this, newRect }; constructor.Invoke(lobject); placePosition = Vector2.Zero; selected = null; diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index b131c78da..6c296645e 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -673,7 +673,7 @@ namespace Barotrauma MapEntity.MapLoaded(); - WayPoint.GenerateSubWaypoints(); + //WayPoint.GenerateSubWaypoints(); GameMain.LightManager.OnMapLoaded(); diff --git a/Subsurface/Source/Map/WayPoint.cs b/Subsurface/Source/Map/WayPoint.cs index 0408d8360..86f631785 100644 --- a/Subsurface/Source/Map/WayPoint.cs +++ b/Subsurface/Source/Map/WayPoint.cs @@ -8,17 +8,22 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System.Collections.ObjectModel; using Barotrauma.Items.Components; +using FarseerPhysics.Dynamics; namespace Barotrauma { - public enum SpawnType { None, Human, Enemy, Cargo, Path }; + public enum SpawnType { Path, Human, Enemy, Cargo }; class WayPoint : MapEntity { public static List WayPointList = new List(); public static bool ShowWayPoints = true, ShowSpawnPoints = true; - private SpawnType spawnType; + private static Texture2D iconTexture; + private const int IconSize = 32; + private static int[] iconIndices = { 3, 0, 1, 2 }; + + protected SpawnType spawnType; //characters spawning at the waypoint will be given an ID card with these tags private string[] idCardTags; @@ -47,13 +52,13 @@ namespace Barotrauma set { spawnType = value; } } - public override string Name - { - get - { - return "WayPoint"; - } - } + //public override string Name + //{ + // get + // { + // return spawnType == SpawnType.Path ? "WayPoint" : "SpawnPoint"; + // } + //} public string[] IdCardTags { @@ -75,9 +80,18 @@ namespace Barotrauma ConnectedGap = gap; } - public WayPoint(Rectangle rectangle) + public WayPoint(MapEntityPrefab prefab, Rectangle rectangle) : this (rectangle, Submarine.Loaded) - { } + { + if (prefab.Name.Contains("Spawn")) + { + spawnType = SpawnType.Human; + } + else + { + SpawnType = SpawnType.Path; + } + } public WayPoint(Rectangle newRect, Submarine submarine) : base (submarine) @@ -86,6 +100,11 @@ namespace Barotrauma linkedTo = new ObservableCollection(); idCardTags = new string[0]; + if (iconTexture==null) + { + iconTexture = Sprite.LoadTexture("Content/Map/waypointIcons.png"); + } + InsertToList(); WayPointList.Add(this); @@ -105,19 +124,31 @@ namespace Barotrauma if (IsHidden()) return; - Rectangle drawRect = - Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); + //Rectangle drawRect = + // Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height); + Vector2 drawPos = Position; + if (Submarine!=null) drawPos += Submarine.DrawPosition; + drawPos.Y = -drawPos.Y; - Color clr = (isSelected) ? Color.Red : Color.LightGreen; - GUI.DrawRectangle(spriteBatch, new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), clr, true); + Color clr = (isSelected) ? Color.Red : Color.White; + if (isHighlighted) clr = Color.DarkRed; + + int iconX = iconIndices[(int)spawnType]*IconSize % iconTexture.Width; + int iconY = (int)(Math.Floor(iconIndices[(int)spawnType]*IconSize / (float)iconTexture.Width))*IconSize; + + spriteBatch.Draw(iconTexture, + new Rectangle((int)(drawPos.X - IconSize/2), (int)(drawPos.Y - IconSize/2), IconSize, IconSize), + new Rectangle(iconX, iconY, IconSize,IconSize), clr); + + //GUI.DrawRectangle(spriteBatch, new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height), clr, true); //spriteBatch.DrawString(GUI.SmallFont, Position.ToString(), new Vector2(Position.X, -Position.Y), Color.White); foreach (MapEntity e in linkedTo) { GUI.DrawLine(spriteBatch, - new Vector2(drawRect.X+rect.Width/2.0f, -drawRect.Y+rect.Height/2.0f), + drawPos, new Vector2(e.DrawPosition.X, -e.DrawPosition.Y), Color.Green); } @@ -167,8 +198,8 @@ namespace Barotrauma spawnType += (int)button.UserData; - if (spawnType > SpawnType.Cargo) spawnType = SpawnType.None; - if (spawnType < SpawnType.None) spawnType = SpawnType.Enemy; + if (spawnType > SpawnType.Path) spawnType = SpawnType.Human; + if (spawnType < SpawnType.Human) spawnType = SpawnType.Path; spawnTypeText.Text = spawnType.ToString(); @@ -179,7 +210,7 @@ namespace Barotrauma { IdCardTags = text.Split(','); textBox.Text = text; - textBox.Color = Color.White; + textBox.Color = Color.Green; return true; } @@ -191,7 +222,7 @@ namespace Barotrauma if (assignedJob !=null && trimmedName!="none") { - textBox.Color = Color.White; + textBox.Color = Color.Green; textBox.Text = (assignedJob == null) ? "None" : assignedJob.Name; } @@ -378,16 +409,59 @@ namespace Barotrauma ladderPoints[1] = new WayPoint(new Vector2(item.Rect.Center.X, item.Rect.Y-1.0f), SpawnType.Path, Submarine.Loaded); - WayPoint prevPoint = ladderPoints[0]; - for (float y = ladderPoints[0].Position.Y+100.0f; y < ladderPoints[1].Position.Y; y+=100.0f ) - { - var midPoint = new WayPoint(new Vector2(item.Rect.Center.X, y), SpawnType.Path, Submarine.Loaded); - midPoint.Ladders = ladders; - midPoint.ConnectTo(prevPoint); - prevPoint = midPoint; + + WayPoint prevPoint = ladderPoints[0]; + Vector2 prevPos = prevPoint.SimPosition; + + List ignoredBodies = new List(); + + while (prevPoint != ladderPoints[1]) + { + var pickedBody = Submarine.PickBody(prevPos, ladderPoints[1].SimPosition, ignoredBodies); + + if (pickedBody == null) break; + + ignoredBodies.Add(pickedBody); + + if (pickedBody.UserData is Item) + { + var door = (pickedBody.UserData as Item).GetComponent(); + if (door != null) + { + WayPoint newPoint = new WayPoint(door.Item.Position, SpawnType.Path, Submarine.Loaded); + newPoint.ConnectedGap = door.LinkedGap; + + newPoint.ConnectTo(prevPoint); + + prevPoint = newPoint; + + prevPos = ConvertUnits.ToSimUnits(door.Item.Position - Vector2.UnitY * door.Item.Rect.Height); + } + else + { + prevPos = Submarine.LastPickedPosition; + } + } + else + { + prevPos = Submarine.LastPickedPosition; + } } - ladderPoints[1].ConnectTo(prevPoint); + + prevPoint.ConnectTo(ladderPoints[1]); + + + + //for (float y = ladderPoints[0].Position.Y+100.0f; y < ladderPoints[1].Position.Y; y+=100.0f ) + //{ + // var midPoint = new WayPoint(new Vector2(item.Rect.Center.X, y), SpawnType.Path, Submarine.Loaded); + // midPoint.Ladders = ladders; + + // midPoint.ConnectTo(prevPoint); + // prevPoint = midPoint; + //} + //ladderPoints[1].ConnectTo(prevPoint); for (int i = 0; i < 2; i++) { @@ -395,13 +469,13 @@ namespace Barotrauma for (int dir = -1; dir <= 1; dir += 2) { - WayPoint closest = ladderPoints[i].FindClosest(dir, true, new Vector2(-100.0f, 0f)); + WayPoint closest = ladderPoints[i].FindClosest(dir, true, new Vector2(-150.0f, 10f)); if (closest == null) continue; ladderPoints[i].ConnectTo(closest); } } - ladderPoints[0].ConnectTo(ladderPoints[1]); + //ladderPoints[0].ConnectTo(ladderPoints[1]); } foreach (Gap gap in Gap.GapList) @@ -423,6 +497,24 @@ namespace Barotrauma } } + foreach (Gap gap in Gap.GapList) + { + if (gap.isHorizontal || gap.IsRoomToRoom) continue; + + //too small to walk through + 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); + + for (int dir = -1; dir <= 1; dir += 2) + { + WayPoint closest = wayPoint.FindClosest(dir, false, new Vector2(-outSideWaypointInterval, outSideWaypointInterval) / 2.0f); + if (closest == null) continue; + wayPoint.ConnectTo(closest); + } + } + var orphans = WayPointList.FindAll(w => w.spawnType == SpawnType.Path && !w.linkedTo.Any()); foreach (WayPoint wp in orphans) @@ -438,27 +530,37 @@ namespace Barotrauma float closestDist = 0.0f; WayPoint closest = null; - if (horizontalSearch) - { + foreach (WayPoint wp in WayPointList) { 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; + } - float diff = wp.Position.X - Position.X; if (Math.Sign(diff) != dir) continue; - diff = Math.Abs(diff); - if (closest == null || diff < closestDist) + float dist = Vector2.Distance(wp.Position, Position); + if (closest == null || dist < closestDist) { if (Submarine.CheckVisibility(SimPosition, wp.SimPosition) != null) continue; - closestDist = diff; + closestDist = dist; closest = wp; } } - } + return closest; } @@ -469,13 +571,13 @@ namespace Barotrauma if (!wayPoint2.linkedTo.Contains(this)) wayPoint2.linkedTo.Add(this); } - public static WayPoint GetRandom(SpawnType spawnType = SpawnType.None, Job assignedJob = null) + public static WayPoint GetRandom(SpawnType spawnType = SpawnType.Human, Job assignedJob = null) { List wayPoints = new List(); foreach (WayPoint wp in WayPointList) { - if (spawnType != SpawnType.None && wp.spawnType != spawnType) continue; + if (wp.spawnType != spawnType) continue; if (assignedJob != null && wp.assignedJob != assignedJob.Prefab) continue; wayPoints.Add(wp); @@ -525,6 +627,16 @@ namespace Barotrauma if (assignedWayPoints[i] != null) continue; + //try to assign a spawnpoint that isn't meant for any specific job + var nonJobSpecificPoints = WayPointList.FindAll(wp => wp.spawnType == SpawnType.Human && wp.assignedJob == null); + + if (nonJobSpecificPoints.Any()) + { + assignedWayPoints[i] = nonJobSpecificPoints[Rand.Int(nonJobSpecificPoints.Count, false)]; + } + + if (assignedWayPoints[i] != null) continue; + //everything else failed -> just give a random spawnpoint assignedWayPoints[i] = GetRandom(SpawnType.Human); } @@ -548,7 +660,7 @@ namespace Barotrauma public override XElement Save(XDocument doc) { - if (MoveWithLevel || spawnType == SpawnType.Path) return null; + if (MoveWithLevel) return null; XElement element = new XElement("WayPoint"); element.Add(new XAttribute("ID", ID), @@ -591,8 +703,8 @@ namespace Barotrauma WayPoint w = new WayPoint(rect, submarine); w.ID = (ushort)int.Parse(element.Attribute("ID").Value); - w.spawnType = (SpawnType)Enum.Parse(typeof(SpawnType), - ToolBox.GetAttributeString(element, "spawn", "None")); + + Enum.TryParse(ToolBox.GetAttributeString(element, "spawn", "Path"), out w.spawnType); string idCardTagString = ToolBox.GetAttributeString(element, "idcardtags", ""); if (!string.IsNullOrWhiteSpace(idCardTagString)) diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index 650c24576..8f7159628 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -2,6 +2,7 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; +using System.Linq; namespace Barotrauma { @@ -16,6 +17,9 @@ namespace Barotrauma private GUITextBox nameBox; + const int PreviouslyUsedCount = 10; + private GUIListBox previouslyUsedList; + //a Character used for picking up and manipulating items private Character dummyCharacter; @@ -161,9 +165,7 @@ namespace Barotrauma y+=50; new GUITextBlock(new Rectangle(0, y, 0, 20), "Show:", GUI.Style, GUIpanel); - - - + var tickBox = new GUITickBox(new Rectangle(0,y+20,20,20), "Waypoints", Alignment.TopLeft, GUIpanel); tickBox.OnSelected = (GUITickBox obj) => { WayPoint.ShowWayPoints = !WayPoint.ShowWayPoints; return true; }; tickBox.Selected = true; @@ -180,6 +182,16 @@ namespace Barotrauma tickBox.OnSelected = (GUITickBox obj) => { Gap.ShowGaps = !Gap.ShowGaps; return true; }; tickBox.Selected = true; + y+=150; + + if (y < GameMain.GraphicsHeight - 100) + { + new GUITextBlock(new Rectangle(0, y, 0, 15), "Previously used:", GUI.Style, GUIpanel); + + previouslyUsedList = new GUIListBox(new Rectangle(0, y + 15, 0, Math.Min(GameMain.GraphicsHeight - y - 40, 150)), GUI.Style, GUIpanel); + previouslyUsedList.OnSelected = SelectPrefab; + } + } public void StartTutorial() @@ -230,6 +242,12 @@ namespace Barotrauma if (dummyCharacter != null) dummyCharacter.Remove(); dummyCharacter = Character.Create(Character.HumanConfigFile, Vector2.Zero); + + for (int i = 0; i15) + { + name = name.Substring(0,12)+"..."; + } + + var textBlock = new GUITextBlock(new Rectangle(0,0,0,15), name, GUI.Style, previouslyUsedList); + textBlock.UserData = mapEntityPrefab; + + previouslyUsedList.RemoveChild(textBlock); + previouslyUsedList.children.Insert(0, textBlock); + } + /// /// Allows the game to run logic such as updating the world, diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index fa243281d..6d5967165 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -191,7 +191,7 @@ namespace Barotrauma { Character.Controlled.SelectedConstruction.DrawHUD(spriteBatch, Character.Controlled); } - else + else if (!Character.Controlled.SelectedConstruction.IsInPickRange(Character.Controlled.WorldPosition)) { Character.Controlled.SelectedConstruction = null; } diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index 9e3968bcb..4e061f525 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ