From 09e8b8b9c6236fba45f5aec2b1ebb0f8e9f50718 Mon Sep 17 00:00:00 2001 From: Regalis Date: Tue, 3 May 2016 00:14:52 +0300 Subject: [PATCH] - RepairTools work for structures that are outside the submarine - Ruins are visible in sonar - Fixed ruin generation algorithm occasionally creating too narrow rooms and placing corridors so that they're blocked by corners of a room - Fix for wall textures being misaligned for map cells with no physics body --- .../Items/Components/Holdable/RepairTool.cs | 121 ++++++++++-------- .../Source/Items/Components/Machines/Radar.cs | 22 +++- Subsurface/Source/Map/Levels/CaveGenerator.cs | 42 +++--- Subsurface/Source/Map/Levels/Ruins/BTRoom.cs | 5 +- .../Source/Map/Levels/Ruins/Corridor.cs | 8 +- .../Source/Map/Levels/Ruins/RuinGenerator.cs | 17 ++- 6 files changed, 128 insertions(+), 87 deletions(-) diff --git a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs index 4dd1cc0c6..85b67fc43 100644 --- a/Subsurface/Source/Items/Components/Holdable/RepairTool.cs +++ b/Subsurface/Source/Items/Components/Holdable/RepairTool.cs @@ -129,68 +129,85 @@ namespace Barotrauma.Items.Components ignoredBodies.Add(limb.body.FarseerBody); } - Vector2 rayStart = item.WorldPosition; - Vector2 rayEnd = targetPosition; - Body targetBody = Submarine.PickBody( - ConvertUnits.ToSimUnits(rayStart - Submarine.Loaded.Position), - ConvertUnits.ToSimUnits(rayEnd - Submarine.Loaded.Position), ignoredBodies); - - pickedPosition = Submarine.LastPickedPosition; - - if (ExtinquishAmount > 0.0f) + for (int n = 0; n < 2; n++) { - Vector2 displayPos = rayStart + (rayEnd-rayStart)*Submarine.LastPickedFraction*0.9f; - Hull hull = Hull.FindHull(displayPos, item.CurrentHull); - if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos); - } + Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition); + Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition); - if (targetBody == null || targetBody.UserData == null) return true; - - Structure targetStructure; - Limb targetLimb; - Item targetItem; - if ((targetStructure = (targetBody.UserData as Structure)) != null) - { - if (!fixableEntities.Contains(targetStructure.Name)) return true; - - int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition)); - if (sectionIndex < 0) return true; - - 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) + if (n == 0) { - int nextSectionLength = targetStructure.SectionLength(sectionIndex + i); - if ((sectionIndex==1 && i ==-1) || - (sectionIndex==targetStructure.SectionCount-2 && i == 1) || - (nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f)) + //do a raycast in "submarine coordinates" + rayStart -= Submarine.Loaded.SimPosition; + rayEnd -= Submarine.Loaded.SimPosition; + } + 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) { - targetStructure.HighLightSection(sectionIndex + i); - targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess); + 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); + //isActive = true; } } - - - } - else if ((targetLimb = (targetBody.UserData as Limb)) != null) - { - if (character.IsKeyDown(InputType.Aim)) + else if ((targetItem = (targetBody.UserData as Item)) != null) { - targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, character); - //isActive = true; - } - } - else if ((targetItem = (targetBody.UserData as Item)) != null) - { - targetItem.IsHighlighted = true; + targetItem.IsHighlighted = true; - ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime); + ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime); + } + } + + return true; } diff --git a/Subsurface/Source/Items/Components/Machines/Radar.cs b/Subsurface/Source/Items/Components/Machines/Radar.cs index 11179755e..717472453 100644 --- a/Subsurface/Source/Items/Components/Machines/Radar.cs +++ b/Subsurface/Source/Items/Components/Machines/Radar.cs @@ -160,8 +160,7 @@ namespace Barotrauma.Items.Components GUI.DrawLine(spriteBatch, center + start, center + end, Color.Green); } - } - + } if (Level.Loaded != null && (item.CurrentHull==null || !DetectSubmarineWalls)) @@ -182,6 +181,25 @@ namespace Barotrauma.Items.Components CreateBlipsForLine(edge.point1 + cell.Translation, edge.point2+cell.Translation, radius, displayScale, 3.0f * (Math.Abs(facingDot) + 1.0f)); } + } + + foreach(RuinGeneration.Ruin ruin in Level.Loaded.Ruins) + { + if (!MathUtils.CircleIntersectsRectangle(item.WorldPosition, range, ruin.Area)) continue; + + foreach (var ruinShape in ruin.RuinShapes) + { + foreach (RuinGeneration.Line wall in ruinShape.Walls) + { + + float cellDot = Vector2.Dot( + Vector2.Normalize(ruinShape.Center - item.WorldPosition), + Vector2.Normalize((wall.A+wall.B)/2.0f - ruinShape.Center)); + if (cellDot > 0) continue; + + CreateBlipsForLine(wall.A, wall.B, radius, displayScale, -cellDot*5.0f); + } + } } } diff --git a/Subsurface/Source/Map/Levels/CaveGenerator.cs b/Subsurface/Source/Map/Levels/CaveGenerator.cs index 45a34615e..6452122ae 100644 --- a/Subsurface/Source/Map/Levels/CaveGenerator.cs +++ b/Subsurface/Source/Map/Levels/CaveGenerator.cs @@ -440,11 +440,11 @@ namespace Barotrauma foreach (VoronoiCell cell in cells) { - if (cell.body == null) continue; + //if (cell.body == null) continue; foreach (GraphEdge edge in cell.edges) { - if (edge.cell1 != null && edge.cell1.body == null) edge.cell1 = null; - if (edge.cell2 != null && edge.cell2.body == null) edge.cell2 = null; + if (edge.cell1 != null && edge.cell1.body == null && edge.cell1.CellType != CellType.Empty) edge.cell1 = null; + if (edge.cell2 != null && edge.cell2.body == null && edge.cell2.CellType != CellType.Empty) edge.cell2 = null; CompareCCW compare = new CompareCCW(cell.Center); if (compare.Compare(edge.point1, edge.point2) == -1) @@ -463,22 +463,9 @@ namespace Barotrauma { if (!edge.isSolid) continue; - GraphEdge leftEdge = null, rightEdge = null; - - foreach (GraphEdge edge2 in cell.edges) - { - if (edge == edge2) continue; - if (edge.point1 == edge2.point1 || - edge.point1 == edge2.point2) - { - leftEdge = edge2; - } - else if (edge.point2 == edge2.point2 || edge.point2 == edge2.point1) - { - rightEdge = edge2; - } - } - + GraphEdge leftEdge = cell.edges.Find(e => e != edge && (edge.point1 == e.point1 || edge.point1 == e.point2)); + GraphEdge rightEdge = cell.edges.Find(e => e != edge && (edge.point2 == e.point1 || edge.point2 == e.point2)); + Vector2 leftNormal = Vector2.Zero, rightNormal = Vector2.Zero; if (leftEdge == null) @@ -498,8 +485,11 @@ namespace Barotrauma #if DEBUG DebugConsole.ThrowError("Invalid right normal"); #endif - if (cell.body != null) GameMain.World.RemoveBody(cell.body); - cell.body = null; + if (cell.body != null) + { + GameMain.World.RemoveBody(cell.body); + cell.body = null; + } leftNormal = Vector2.UnitX; break; } @@ -521,15 +511,15 @@ namespace Barotrauma #if DEBUG DebugConsole.ThrowError("Invalid right normal"); #endif - if (cell.body != null) GameMain.World.RemoveBody(cell.body); - cell.body = null; + if (cell.body != null) + { + GameMain.World.RemoveBody(cell.body); + cell.body = null; + } rightNormal = Vector2.UnitX; break; } - - - for (int i = 0; i < 2; i++) { Vector2[] verts = new Vector2[3]; diff --git a/Subsurface/Source/Map/Levels/Ruins/BTRoom.cs b/Subsurface/Source/Map/Levels/Ruins/BTRoom.cs index dd0eab0de..ec494c04b 100644 --- a/Subsurface/Source/Map/Levels/Ruins/BTRoom.cs +++ b/Subsurface/Source/Map/Levels/Ruins/BTRoom.cs @@ -42,11 +42,12 @@ namespace Barotrauma.RuinGeneration this.rect = rect; } - public void Split(float minDivRatio, float verticalProbability = 0.5f) + public void Split(float minDivRatio, float verticalProbability = 0.5f, int minWidth = 200) { subRooms = new BTRoom[2]; - if (Rand.Range(0.0f, 1.0f, false) < verticalProbability) + if (Rand.Range(0.0f, 1.0f, false) < verticalProbability && + rect.Width * minDivRatio >= minWidth) { SplitVertical(minDivRatio); } diff --git a/Subsurface/Source/Map/Levels/Ruins/Corridor.cs b/Subsurface/Source/Map/Levels/Ruins/Corridor.cs index 042ffceca..48e086267 100644 --- a/Subsurface/Source/Map/Levels/Ruins/Corridor.cs +++ b/Subsurface/Source/Map/Levels/Ruins/Corridor.cs @@ -163,16 +163,16 @@ namespace Barotrauma.RuinGeneration //if (Math.Min(leaves1[i].Rect.Bottom, leaves2[i].Rect.Bottom) - Math.Max(leaves1[i].Rect.Y, leaves2[j].Rect.Y) < width) continue; - if (leaves1[i].Rect.Y > leaves2[j].Rect.Bottom) continue; - if (leaves1[i].Rect.Bottom < leaves2[j].Rect.Y) continue; + if (leaves1[i].Rect.Y > leaves2[j].Rect.Bottom-width) continue; + if (leaves1[i].Rect.Bottom < leaves2[j].Rect.Y+width) continue; } else { //if (Math.Min(leaves1[i].Rect.Right, leaves2[i].Rect.Right) - Math.Max(leaves1[i].Rect.X, leaves2[j].Rect.X) < width) continue; - if (leaves1[i].Rect.X > leaves2[j].Rect.Right) continue; - if (leaves1[i].Rect.Right < leaves2[j].Rect.X) continue; + if (leaves1[i].Rect.X > leaves2[j].Rect.Right-width) continue; + if (leaves1[i].Rect.Right < leaves2[j].Rect.X+width) continue; } diff --git a/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs b/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs index bf0e948ee..9d9318642 100644 --- a/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs +++ b/Subsurface/Source/Map/Levels/Ruins/RuinGenerator.cs @@ -28,6 +28,11 @@ namespace Barotrauma.RuinGeneration protected set; } + public Vector2 Center + { + get { return rect.Center.ToVector2(); } + } + public List Walls; public virtual void CreateWalls() { } @@ -170,6 +175,11 @@ namespace Barotrauma.RuinGeneration get { return allShapes; } } + public List Walls + { + get { return walls; } + } + public Rectangle Area { get; @@ -207,7 +217,7 @@ namespace Barotrauma.RuinGeneration for (int i = 0; i < iterations; i++) { - rooms.ForEach(l => l.Split(0.3f, verticalProbability)); + rooms.ForEach(l => l.Split(0.3f, verticalProbability, 300)); rooms = baseRoom.GetLeaves(); } @@ -340,6 +350,11 @@ namespace Barotrauma.RuinGeneration (int)((wall.B.X - wall.A.X) + radius*2.0f), (int)((wall.B.Y - wall.A.Y) + radius*2.0f)); + if (wall.A.Y == wall.B.Y) + { + rect.Inflate(-32, 0); + } + var structure = new Structure(rect, structurePrefab.Prefab as StructurePrefab, null); structure.MoveWithLevel = true; structure.SetCollisionCategory(Physics.CollisionLevel);