- 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
This commit is contained in:
@@ -129,69 +129,86 @@ namespace Barotrauma.Items.Components
|
|||||||
ignoredBodies.Add(limb.body.FarseerBody);
|
ignoredBodies.Add(limb.body.FarseerBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 rayStart = item.WorldPosition;
|
|
||||||
Vector2 rayEnd = targetPosition;
|
|
||||||
|
|
||||||
Body targetBody = Submarine.PickBody(
|
for (int n = 0; n < 2; n++)
|
||||||
ConvertUnits.ToSimUnits(rayStart - Submarine.Loaded.Position),
|
|
||||||
ConvertUnits.ToSimUnits(rayEnd - Submarine.Loaded.Position), ignoredBodies);
|
|
||||||
|
|
||||||
pickedPosition = Submarine.LastPickedPosition;
|
|
||||||
|
|
||||||
if (ExtinquishAmount > 0.0f)
|
|
||||||
{
|
{
|
||||||
Vector2 displayPos = rayStart + (rayEnd-rayStart)*Submarine.LastPickedFraction*0.9f;
|
Vector2 rayStart = ConvertUnits.ToSimUnits(item.WorldPosition);
|
||||||
Hull hull = Hull.FindHull(displayPos, item.CurrentHull);
|
Vector2 rayEnd = ConvertUnits.ToSimUnits(targetPosition);
|
||||||
if (hull != null) hull.Extinquish(deltaTime, ExtinquishAmount, displayPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetBody == null || targetBody.UserData == null) return true;
|
if (n == 0)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int nextSectionLength = targetStructure.SectionLength(sectionIndex + i);
|
//do a raycast in "submarine coordinates"
|
||||||
if ((sectionIndex==1 && i ==-1) ||
|
rayStart -= Submarine.Loaded.SimPosition;
|
||||||
(sectionIndex==targetStructure.SectionCount-2 && i == 1) ||
|
rayEnd -= Submarine.Loaded.SimPosition;
|
||||||
(nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f))
|
}
|
||||||
|
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);
|
int nextSectionLength = targetStructure.SectionLength(sectionIndex + i);
|
||||||
targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess);
|
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 ((targetItem = (targetBody.UserData as Item)) != null)
|
||||||
|
|
||||||
}
|
|
||||||
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
|
|
||||||
{
|
|
||||||
if (character.IsKeyDown(InputType.Aim))
|
|
||||||
{
|
{
|
||||||
targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, character);
|
targetItem.IsHighlighted = true;
|
||||||
//isActive = true;
|
|
||||||
}
|
ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime);
|
||||||
}
|
}
|
||||||
else if ((targetItem = (targetBody.UserData as Item)) != null)
|
|
||||||
{
|
|
||||||
targetItem.IsHighlighted = true;
|
|
||||||
|
|
||||||
ApplyStatusEffects(ActionType.OnUse, targetItem.AllPropertyObjects, deltaTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,6 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (Level.Loaded != null && (item.CurrentHull==null || !DetectSubmarineWalls))
|
if (Level.Loaded != null && (item.CurrentHull==null || !DetectSubmarineWalls))
|
||||||
{
|
{
|
||||||
List<VoronoiCell> cells = Level.Loaded.GetCells(item.WorldPosition, 7);
|
List<VoronoiCell> cells = Level.Loaded.GetCells(item.WorldPosition, 7);
|
||||||
@@ -183,6 +182,25 @@ namespace Barotrauma.Items.Components
|
|||||||
CreateBlipsForLine(edge.point1 + cell.Translation, edge.point2+cell.Translation, radius, displayScale, 3.0f * (Math.Abs(facingDot) + 1.0f));
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Character c in Character.CharacterList)
|
foreach (Character c in Character.CharacterList)
|
||||||
|
|||||||
@@ -440,11 +440,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (VoronoiCell cell in cells)
|
foreach (VoronoiCell cell in cells)
|
||||||
{
|
{
|
||||||
if (cell.body == null) continue;
|
//if (cell.body == null) continue;
|
||||||
foreach (GraphEdge edge in cell.edges)
|
foreach (GraphEdge edge in cell.edges)
|
||||||
{
|
{
|
||||||
if (edge.cell1 != null && edge.cell1.body == null) edge.cell1 = 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 = null;
|
if (edge.cell2 != null && edge.cell2.body == null && edge.cell2.CellType != CellType.Empty) edge.cell2 = null;
|
||||||
|
|
||||||
CompareCCW compare = new CompareCCW(cell.Center);
|
CompareCCW compare = new CompareCCW(cell.Center);
|
||||||
if (compare.Compare(edge.point1, edge.point2) == -1)
|
if (compare.Compare(edge.point1, edge.point2) == -1)
|
||||||
@@ -463,21 +463,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!edge.isSolid) continue;
|
if (!edge.isSolid) continue;
|
||||||
|
|
||||||
GraphEdge leftEdge = null, rightEdge = null;
|
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));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 leftNormal = Vector2.Zero, rightNormal = Vector2.Zero;
|
Vector2 leftNormal = Vector2.Zero, rightNormal = Vector2.Zero;
|
||||||
|
|
||||||
@@ -498,8 +485,11 @@ namespace Barotrauma
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.ThrowError("Invalid right normal");
|
DebugConsole.ThrowError("Invalid right normal");
|
||||||
#endif
|
#endif
|
||||||
if (cell.body != null) GameMain.World.RemoveBody(cell.body);
|
if (cell.body != null)
|
||||||
cell.body = null;
|
{
|
||||||
|
GameMain.World.RemoveBody(cell.body);
|
||||||
|
cell.body = null;
|
||||||
|
}
|
||||||
leftNormal = Vector2.UnitX;
|
leftNormal = Vector2.UnitX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -521,15 +511,15 @@ namespace Barotrauma
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.ThrowError("Invalid right normal");
|
DebugConsole.ThrowError("Invalid right normal");
|
||||||
#endif
|
#endif
|
||||||
if (cell.body != null) GameMain.World.RemoveBody(cell.body);
|
if (cell.body != null)
|
||||||
cell.body = null;
|
{
|
||||||
|
GameMain.World.RemoveBody(cell.body);
|
||||||
|
cell.body = null;
|
||||||
|
}
|
||||||
rightNormal = Vector2.UnitX;
|
rightNormal = Vector2.UnitX;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Vector2[] verts = new Vector2[3];
|
Vector2[] verts = new Vector2[3];
|
||||||
|
|||||||
@@ -42,11 +42,12 @@ namespace Barotrauma.RuinGeneration
|
|||||||
this.rect = rect;
|
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];
|
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);
|
SplitVertical(minDivRatio);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 (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.Y > leaves2[j].Rect.Bottom-width) continue;
|
||||||
if (leaves1[i].Rect.Bottom < leaves2[j].Rect.Y) continue;
|
if (leaves1[i].Rect.Bottom < leaves2[j].Rect.Y+width) continue;
|
||||||
}
|
}
|
||||||
else
|
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 (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.X > leaves2[j].Rect.Right-width) continue;
|
||||||
if (leaves1[i].Rect.Right < leaves2[j].Rect.X) continue;
|
if (leaves1[i].Rect.Right < leaves2[j].Rect.X+width) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ namespace Barotrauma.RuinGeneration
|
|||||||
protected set;
|
protected set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2 Center
|
||||||
|
{
|
||||||
|
get { return rect.Center.ToVector2(); }
|
||||||
|
}
|
||||||
|
|
||||||
public List<Line> Walls;
|
public List<Line> Walls;
|
||||||
|
|
||||||
public virtual void CreateWalls() { }
|
public virtual void CreateWalls() { }
|
||||||
@@ -170,6 +175,11 @@ namespace Barotrauma.RuinGeneration
|
|||||||
get { return allShapes; }
|
get { return allShapes; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Line> Walls
|
||||||
|
{
|
||||||
|
get { return walls; }
|
||||||
|
}
|
||||||
|
|
||||||
public Rectangle Area
|
public Rectangle Area
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -207,7 +217,7 @@ namespace Barotrauma.RuinGeneration
|
|||||||
|
|
||||||
for (int i = 0; i < iterations; i++)
|
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();
|
rooms = baseRoom.GetLeaves();
|
||||||
}
|
}
|
||||||
@@ -340,6 +350,11 @@ namespace Barotrauma.RuinGeneration
|
|||||||
(int)((wall.B.X - wall.A.X) + radius*2.0f),
|
(int)((wall.B.X - wall.A.X) + radius*2.0f),
|
||||||
(int)((wall.B.Y - wall.A.Y) + 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);
|
var structure = new Structure(rect, structurePrefab.Prefab as StructurePrefab, null);
|
||||||
structure.MoveWithLevel = true;
|
structure.MoveWithLevel = true;
|
||||||
structure.SetCollisionCategory(Physics.CollisionLevel);
|
structure.SetCollisionCategory(Physics.CollisionLevel);
|
||||||
|
|||||||
Reference in New Issue
Block a user