From d4e0cbbf02cf67bbe203133538121cf52e04071a Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Fri, 26 Jan 2018 16:47:32 +0200 Subject: [PATCH] Submarines can't enter ruins through broken walls, ramming ruins causes damage to the sub and the ruin structures. Closes #199 --- .../Source/Map/Levels/Ruins/RuinGenerator.cs | 21 ++++++++++++---- .../Source/Map/SubmarineBody.cs | 25 ++++++++++++++----- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs index a963828f1..1f7e758dd 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/Ruins/RuinGenerator.cs @@ -1,4 +1,6 @@ -using Microsoft.Xna.Framework; +using FarseerPhysics; +using FarseerPhysics.Factories; +using Microsoft.Xna.Framework; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -344,6 +346,15 @@ namespace Barotrauma.RuinGeneration Rectangle backgroundRect = new Rectangle(leaf.Rect.X, leaf.Rect.Y + leaf.Rect.Height, leaf.Rect.Width, leaf.Rect.Height); new Structure(backgroundRect, (background.Prefab as StructurePrefab), null).MoveWithLevel = true; + + var submarineBlocker = BodyFactory.CreateRectangle(GameMain.World, + ConvertUnits.ToSimUnits(leaf.Rect.Width), + ConvertUnits.ToSimUnits(leaf.Rect.Height), + 1, ConvertUnits.ToSimUnits(leaf.Center)); + + submarineBlocker.IsStatic = true; + submarineBlocker.CollisionCategories = Physics.CollisionWall; + submarineBlocker.CollidesWith = Physics.CollisionWall; } List doorlessRooms = new List(shapes); @@ -407,7 +418,7 @@ namespace Barotrauma.RuinGeneration //generate props -------------------------------------------------------------- - for (int i = 0; i < shapes.Count*2; i++ ) + for (int i = 0; i < shapes.Count * 2; i++) { Alignment[] alignments = new Alignment[] { Alignment.Top, Alignment.Bottom, Alignment.Right, Alignment.Left, Alignment.Center }; @@ -416,14 +427,14 @@ namespace Barotrauma.RuinGeneration Vector2 size = (prop.Prefab is StructurePrefab) ? ((StructurePrefab)prop.Prefab).Size : Vector2.Zero; //if the prop is placed at the center of the room, we have to use a room without a door (because they're also placed at the center) - var shape = prop.Alignment.HasFlag(Alignment.Center) ? - doorlessRooms[Rand.Int(doorlessRooms.Count, Rand.RandSync.Server)] : + var shape = prop.Alignment.HasFlag(Alignment.Center) ? + doorlessRooms[Rand.Int(doorlessRooms.Count, Rand.RandSync.Server)] : shapes[Rand.Int(shapes.Count, Rand.RandSync.Server)]; Vector2 position = shape.Rect.Center.ToVector2(); if (prop.Alignment.HasFlag(Alignment.Top)) { - position = new Vector2(Rand.Range(shape.Rect.X+size.X, shape.Rect.Right - size.X, Rand.RandSync.Server), shape.Rect.Bottom - 64); + position = new Vector2(Rand.Range(shape.Rect.X + size.X, shape.Rect.Right - size.X, Rand.RandSync.Server), shape.Rect.Bottom - 64); } else if (prop.Alignment.HasFlag(Alignment.Bottom)) { diff --git a/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs b/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs index a75fc759f..5b8aa1f5d 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/SubmarineBody.cs @@ -381,7 +381,22 @@ namespace Barotrauma VoronoiCell cell = f2.Body.UserData as VoronoiCell; if (cell != null) { - HandleLevelCollision(contact, cell); + HandleLevelCollision(contact, Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center)); + return true; + } + + Structure structure = f2.Body.UserData as Structure; + if (structure != null) + { + Vector2 normal; + FixedArray2 points; + contact.GetWorldManifold(out normal, out points); + if (contact.FixtureA.Body == f1.Body) + { + normal = -normal; + } + + HandleLevelCollision(contact, normal); return true; } @@ -510,10 +525,8 @@ namespace Barotrauma } } - private void HandleLevelCollision(Contact contact, VoronoiCell cell) + private void HandleLevelCollision(Contact contact, Vector2 collisionNormal) { - var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center); - float wallImpact = Vector2.Dot(Velocity, -collisionNormal); ApplyImpact(wallImpact, -collisionNormal, contact); @@ -522,11 +535,11 @@ namespace Barotrauma dockedSub.SubBody.ApplyImpact(wallImpact, -collisionNormal, contact); } +#if CLIENT Vector2 n; FixedArray2 particlePos; contact.GetWorldManifold(out n, out particlePos); - -#if CLIENT + int particleAmount = (int)Math.Min(wallImpact * 10.0f, 50); for (int i = 0; i < particleAmount; i++) {