Changes to submarine<->outside teleporting logic:

- contacts between limbs and the sub are temporarily disabled before teleporting to prevent the character from "exploding"
- impact damage is disabled for 0.25 seconds after teleporting in case the character still explodes
- characters with disabled impact damage won't damage the walls when hitting
- the collider of SubmarineBody is generated based on walls instead of hulls
- fixed Submarine.CheckVisibilit ignoring fixtures with (CollisionWall | CollisionLevel) collisioncategory
This commit is contained in:
Regalis
2016-05-18 11:43:22 +03:00
parent be72fee824
commit 63e5f02057
7 changed files with 184 additions and 94 deletions
+33
View File
@@ -586,6 +586,39 @@ namespace Barotrauma
hull2.Oxygen += Math.Sign(totalOxygen * hull2.FullVolume / (totalVolume) - hull2.Oxygen) * Hull.OxygenDistributionSpeed;
}
public static Gap FindAdjacent(List<Gap> gaps, Vector2 worldPos, float allowedOrthogonalDist)
{
foreach (Gap gap in gaps)
{
if (gap.Open == 0.0f || gap.IsRoomToRoom) continue;
if (gap.ConnectedWall != null)
{
int sectionIndex = gap.ConnectedWall.FindSectionIndex(gap.Position);
if (sectionIndex > -1 && !gap.ConnectedWall.SectionBodyDisabled(sectionIndex)) continue;
}
if (gap.isHorizontal)
{
if (worldPos.Y < gap.WorldRect.Y && worldPos.Y > gap.WorldRect.Y - gap.WorldRect.Height &&
Math.Abs(gap.WorldRect.Center.X - worldPos.X) < allowedOrthogonalDist)
{
return gap;
}
}
else
{
if (worldPos.X > gap.WorldRect.X && worldPos.X < gap.WorldRect.Right &&
Math.Abs(gap.WorldRect.Y - gap.WorldRect.Height / 2 - worldPos.Y) < allowedOrthogonalDist)
{
return gap;
}
}
}
return null;
}
public override void Remove()
{
base.Remove();
+8 -2
View File
@@ -431,13 +431,19 @@ namespace Barotrauma
if (limb.character.AnimController.IgnorePlatforms) return false;
}
}
if (f2.Body.UserData is Limb)
{
var character = ((Limb)f2.Body.UserData).character;
if (character.DisableImpactDamageTimer > 0.0f || ((Limb)f2.Body.UserData).Mass < 100.0f) return true;
}
if (!prefab.IsPlatform && prefab.StairDirection == Direction.None)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(f2.Body.Position);
int section = FindSectionIndex(pos);
if (section>0)
if (section > 0)
{
Vector2 normal = contact.Manifold.LocalNormal;
@@ -529,7 +535,7 @@ namespace Barotrauma
public AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, float deltaTime, bool playSound = false)
{
if (Submarine.Loaded != null && Submarine.Loaded.GodMode) return new AttackResult(0.0f, 0.0f);
if (Submarine.Loaded != null && Submarine.Loaded.GodMode && Submarine == Submarine.Loaded) return new AttackResult(0.0f, 0.0f);
if (!prefab.HasBody || prefab.IsPlatform) return new AttackResult(0.0f, 0.0f);
Vector2 transformedPos = position;
+1 -1
View File
@@ -365,7 +365,7 @@ namespace Barotrauma
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
if (fixture == null ||
(fixture.CollisionCategories != Physics.CollisionWall && fixture.CollisionCategories != Physics.CollisionLevel)) return -1;
(!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) && !fixture.CollisionCategories.HasFlag(Physics.CollisionLevel))) return -1;
if (ignoreLevel && fixture.CollisionCategories == Physics.CollisionLevel) return -1;
+39 -57
View File
@@ -112,30 +112,41 @@ namespace Barotrauma
body = BodyFactory.CreateBody(GameMain.World, this);
foreach (Hull hull in Hull.hullList)
foreach (Structure wall in Structure.WallList)
{
Rectangle rect = hull.Rect;
foreach (Structure wall in Structure.WallList)
{
if (!Submarine.RectsOverlap(wall.Rect, hull.Rect)) continue;
Rectangle wallRect = wall.IsHorizontal ?
new Rectangle(hull.Rect.X, wall.Rect.Y, hull.Rect.Width, wall.Rect.Height) :
new Rectangle(wall.Rect.X, hull.Rect.Y, wall.Rect.Width, hull.Rect.Height);
rect = Rectangle.Union(
new Rectangle(wallRect.X, wallRect.Y - wallRect.Height, wallRect.Width, wallRect.Height),
new Rectangle(rect.X, rect.Y - rect.Height, rect.Width, rect.Height));
rect.Y = rect.Y + rect.Height;
}
Rectangle rect = wall.Rect;
FixtureFactory.AttachRectangle(
ConvertUnits.ToSimUnits(rect.Width),
ConvertUnits.ToSimUnits(rect.Height),
5.0f,
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
body, this);
ConvertUnits.ToSimUnits(rect.Width),
ConvertUnits.ToSimUnits(rect.Height),
5.0f,
ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
body, this);
}
//foreach (Hull hull in Hull.hullList)
//{
// Rectangle rect = hull.Rect;
// foreach (Structure wall in Structure.WallList)
// {
// if (!Submarine.RectsOverlap(wall.Rect, hull.Rect)) continue;
// Rectangle wallRect = wall.IsHorizontal ?
// new Rectangle(hull.Rect.X, wall.Rect.Y, hull.Rect.Width, wall.Rect.Height) :
// new Rectangle(wall.Rect.X, hull.Rect.Y, wall.Rect.Width, hull.Rect.Height);
// rect = Rectangle.Union(
// new Rectangle(wallRect.X, wallRect.Y - wallRect.Height, wallRect.Width, wallRect.Height),
// new Rectangle(rect.X, rect.Y - rect.Height, rect.Width, rect.Height));
// rect.Y = rect.Y + rect.Height;
// }
// FixtureFactory.AttachRectangle(
// ConvertUnits.ToSimUnits(rect.Width),
// ConvertUnits.ToSimUnits(rect.Height),
// 5.0f,
// ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)),
// body, this);
//}
}
@@ -311,7 +322,7 @@ namespace Barotrauma
Debug.Assert(intersection != null);
//''+ translatedir'' in order to move the character slightly away from the wall
c.AnimController.SetPosition(c.WorldPosition + ConvertUnits.ToSimUnits((Vector2)intersection - limb.WorldPosition) + translateDir);
c.AnimController.SetPosition(ConvertUnits.ToSimUnits(c.WorldPosition + ((Vector2)intersection - limb.WorldPosition)) + translateDir);
return;
}
@@ -432,7 +443,7 @@ namespace Barotrauma
FixedArray2<Vector2> points;
contact.GetWorldManifold(out normal2, out points);
Vector2 normalizedVel = limb.character.AnimController.RefLimb.LinearVelocity == Vector2.Zero ?
Vector2 normalizedVel = limb.character.AnimController.RefLimb.LinearVelocity == Vector2.Zero ?
Vector2.Zero : Vector2.Normalize(limb.character.AnimController.RefLimb.LinearVelocity);
Vector2 targetPos = ConvertUnits.ToDisplayUnits(points[0] - normal2);
@@ -441,9 +452,9 @@ namespace Barotrauma
if (newHull == null)
{
targetPos = ConvertUnits.ToDisplayUnits(points[0] - normalizedVel);
targetPos = ConvertUnits.ToDisplayUnits(points[0] + normalizedVel);
newHull = Hull.FindHull(targetPos, null);
newHull = Hull.FindHull(targetPos, null);
if (newHull == null) return true;
}
@@ -452,41 +463,12 @@ namespace Barotrauma
targetPos = limb.character.WorldPosition;
bool gapFound = false;
foreach (Gap gap in gaps)
{
if (gap.Open == 0.0f || gap.IsRoomToRoom) continue;
Gap adjacentGap = Gap.FindAdjacent(gaps, targetPos, 200.0f);
if (gap.ConnectedWall != null)
{
int sectionIndex = gap.ConnectedWall.FindSectionIndex(gap.Position);
if (sectionIndex > -1 && !gap.ConnectedWall.SectionBodyDisabled(sectionIndex)) continue;
}
if (gap.isHorizontal)
{
if (targetPos.Y < gap.WorldRect.Y && targetPos.Y > gap.WorldRect.Y - gap.WorldRect.Height &&
Math.Abs(gap.WorldRect.Center.X-targetPos.X)<200.0f)
{
gapFound = true;
break;
}
}
else
{
if (targetPos.X > gap.WorldRect.X && targetPos.X < gap.WorldRect.Right &&
Math.Abs(gap.WorldRect.Y - gap.WorldRect.Height/2 - targetPos.Y) < 200.0f)
{
gapFound = true;
break;
}
}
}
if (!gapFound) return true;
if (adjacentGap==null) return true;
var ragdoll = limb.character.AnimController;
ragdoll.FindHull(newHull.WorldPosition);
ragdoll.FindHull(newHull.WorldPosition, true);
return false;
}