Merge branch 'master' into moStuff
This commit is contained in:
@@ -23,6 +23,7 @@ namespace Barotrauma
|
||||
public Explosion(float range, float force, float damage, float structureDamage)
|
||||
{
|
||||
attack = new Attack(damage, structureDamage, 0.0f, range);
|
||||
attack.SeverLimbsProbability = 1.0f;
|
||||
this.force = force;
|
||||
sparks = true;
|
||||
shockwave = true;
|
||||
@@ -118,7 +119,7 @@ namespace Barotrauma
|
||||
|
||||
explosionPos = ConvertUnits.ToSimUnits(explosionPos);
|
||||
|
||||
bool wasDead = c.IsDead;
|
||||
Dictionary<Limb, float> distFactors = new Dictionary<Limb, float>();
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
float dist = Vector2.Distance(limb.WorldPosition, worldPosition);
|
||||
@@ -134,6 +135,8 @@ namespace Barotrauma
|
||||
|
||||
//solid obstacles between the explosion and the limb reduce the effect of the explosion by 90%
|
||||
if (Submarine.CheckVisibility(limb.SimPosition, explosionPos) != null) distFactor *= 0.1f;
|
||||
|
||||
distFactors.Add(limb, distFactor);
|
||||
|
||||
c.AddDamage(limb.WorldPosition, DamageType.None,
|
||||
attack.GetDamage(1.0f) / c.AnimController.Limbs.Length * distFactor,
|
||||
@@ -143,17 +146,27 @@ namespace Barotrauma
|
||||
|
||||
if (limb.WorldPosition != worldPosition && force > 0.0f)
|
||||
{
|
||||
limb.body.ApplyLinearImpulse(Vector2.Normalize(limb.WorldPosition - worldPosition) * distFactor * force);
|
||||
Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition);
|
||||
Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius;
|
||||
limb.body.ApplyLinearImpulse(limbDiff * distFactor * force, impulsePoint);
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasDead && c.IsDead)
|
||||
//sever joints
|
||||
if (c.IsDead && attack.SeverLimbsProbability > 0.0f)
|
||||
{
|
||||
foreach (LimbJoint joint in c.AnimController.LimbJoints)
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
if (Rand.Range(0.0f, 1.0f) < attack.SeverLimbsProbability)
|
||||
if (!distFactors.ContainsKey(limb)) continue;
|
||||
|
||||
foreach (LimbJoint joint in c.AnimController.LimbJoints)
|
||||
{
|
||||
c.AnimController.SeverLimbJoint(joint);
|
||||
if (joint.IsSevered || (joint.LimbA != limb && joint.LimbB != limb)) continue;
|
||||
|
||||
if (Rand.Range(0.0f, 1.0f) < attack.SeverLimbsProbability * distFactors[limb])
|
||||
{
|
||||
c.AnimController.SeverLimbJoint(joint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,8 +264,8 @@ namespace Barotrauma
|
||||
|
||||
Vector2 nodeInterval = generationParams.MainPathNodeIntervalRange;
|
||||
|
||||
for (float x = startPosition.X + Rand.Range(nodeInterval.X, nodeInterval.Y, Rand.RandSync.Server);
|
||||
x < endPosition.X - Rand.Range(nodeInterval.X, nodeInterval.Y, Rand.RandSync.Server);
|
||||
for (float x = startPosition.X + nodeInterval.X;
|
||||
x < endPosition.X - nodeInterval.X;
|
||||
x += Rand.Range(nodeInterval.X, nodeInterval.Y, Rand.RandSync.Server))
|
||||
{
|
||||
pathNodes.Add(new Vector2(x, Rand.Range(pathBorders.Y, pathBorders.Bottom, Rand.RandSync.Server)));
|
||||
@@ -275,7 +275,7 @@ namespace Barotrauma
|
||||
|
||||
if (pathNodes.Count <= 2)
|
||||
{
|
||||
pathNodes.Add((startPosition + endPosition) / 2);
|
||||
pathNodes.Insert(1, borders.Center.ToVector2());
|
||||
}
|
||||
|
||||
GenerateTunnels(pathNodes, minWidth);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Created by SharpDevelop.
|
||||
* User: Burhan
|
||||
* Date: 17/06/2014
|
||||
@@ -8,31 +8,31 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2011 James Humphreys. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY James Humphreys ``AS IS\" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those of the
|
||||
authors and should not be interpreted as representing official policies, either expressed
|
||||
or implied, of James Humphreys.
|
||||
Copyright 2011 James Humphreys. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
of conditions and the following disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY James Humphreys ``AS IS\" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those of the
|
||||
authors and should not be interpreted as representing official policies, either expressed
|
||||
or implied, of James Humphreys.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -58,63 +58,63 @@ using System.Collections.Generic;
|
||||
namespace Voronoi2
|
||||
{
|
||||
public class Point
|
||||
{
|
||||
public double x, y;
|
||||
|
||||
public void setPoint ( double x, double y )
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
// use for sites and vertecies
|
||||
public class Site
|
||||
{
|
||||
public Point coord;
|
||||
public int sitenbr;
|
||||
{
|
||||
public double x, y;
|
||||
|
||||
public void setPoint ( double x, double y )
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
// use for sites and vertecies
|
||||
public class Site
|
||||
{
|
||||
public Point coord;
|
||||
public int sitenbr;
|
||||
|
||||
public void SetPoint(Vector2 point)
|
||||
{
|
||||
coord.setPoint(point.X, point.Y);
|
||||
}
|
||||
|
||||
public Site ()
|
||||
{
|
||||
coord = new Point();
|
||||
}
|
||||
}
|
||||
|
||||
public class Edge
|
||||
{
|
||||
public double a = 0, b = 0, c = 0;
|
||||
public Site[] ep;
|
||||
public Site[] reg;
|
||||
public int edgenbr;
|
||||
|
||||
public Edge ()
|
||||
{
|
||||
ep = new Site[2];
|
||||
reg = new Site[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Halfedge
|
||||
{
|
||||
public Halfedge ELleft, ELright;
|
||||
public Edge ELedge;
|
||||
public bool deleted;
|
||||
public int ELpm;
|
||||
public Site vertex;
|
||||
public double ystar;
|
||||
public Halfedge PQnext;
|
||||
|
||||
public Halfedge ()
|
||||
{
|
||||
PQnext = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Site ()
|
||||
{
|
||||
coord = new Point();
|
||||
}
|
||||
}
|
||||
|
||||
public class Edge
|
||||
{
|
||||
public double a = 0, b = 0, c = 0;
|
||||
public Site[] ep;
|
||||
public Site[] reg;
|
||||
public int edgenbr;
|
||||
|
||||
public Edge ()
|
||||
{
|
||||
ep = new Site[2];
|
||||
reg = new Site[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Halfedge
|
||||
{
|
||||
public Halfedge ELleft, ELright;
|
||||
public Edge ELedge;
|
||||
public bool deleted;
|
||||
public int ELpm;
|
||||
public Site vertex;
|
||||
public double ystar;
|
||||
public Halfedge PQnext;
|
||||
|
||||
public Halfedge ()
|
||||
{
|
||||
PQnext = null;
|
||||
}
|
||||
}
|
||||
|
||||
public enum CellType
|
||||
{
|
||||
@@ -187,11 +187,11 @@ namespace Voronoi2
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class GraphEdge
|
||||
{
|
||||
|
||||
public class GraphEdge
|
||||
{
|
||||
public Vector2 point1, point2;
|
||||
public Site site1, site2;
|
||||
public Site site1, site2;
|
||||
public VoronoiCell cell1, cell2;
|
||||
|
||||
public bool isSolid;
|
||||
@@ -239,20 +239,20 @@ namespace Voronoi2
|
||||
|
||||
return normal;
|
||||
}
|
||||
}
|
||||
|
||||
// للترتيب
|
||||
public class SiteSorterYX : IComparer<Site>
|
||||
{
|
||||
public int Compare ( Site p1, Site p2 )
|
||||
{
|
||||
Point s1 = p1.coord;
|
||||
Point s2 = p2.coord;
|
||||
if ( s1.y < s2.y ) return -1;
|
||||
if ( s1.y > s2.y ) return 1;
|
||||
if ( s1.x < s2.x ) return -1;
|
||||
if ( s1.x > s2.x ) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// للترتيب
|
||||
public class SiteSorterYX : IComparer<Site>
|
||||
{
|
||||
public int Compare ( Site p1, Site p2 )
|
||||
{
|
||||
Point s1 = p1.coord;
|
||||
Point s2 = p2.coord;
|
||||
if ( s1.y < s2.y ) return -1;
|
||||
if ( s1.y > s2.y ) return 1;
|
||||
if ( s1.x < s2.x ) return -1;
|
||||
if ( s1.x > s2.x ) return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,11 +89,11 @@ namespace Barotrauma
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
protected bool ResizeHorizontal
|
||||
public bool ResizeHorizontal
|
||||
{
|
||||
get { return prefab != null && prefab.ResizeHorizontal; }
|
||||
}
|
||||
protected bool ResizeVertical
|
||||
public bool ResizeVertical
|
||||
{
|
||||
get { return prefab != null && prefab.ResizeVertical; }
|
||||
}
|
||||
|
||||
@@ -89,6 +89,11 @@ namespace Barotrauma
|
||||
get { return prefab.Body; }
|
||||
}
|
||||
|
||||
public List<Body> Bodies
|
||||
{
|
||||
get { return bodies; }
|
||||
}
|
||||
|
||||
public bool CastShadow
|
||||
{
|
||||
get { return prefab.CastShadow; }
|
||||
@@ -272,7 +277,13 @@ namespace Barotrauma
|
||||
|
||||
public override MapEntity Clone()
|
||||
{
|
||||
return new Structure(rect, prefab, Submarine);
|
||||
var clone = new Structure(rect, prefab, Submarine);
|
||||
foreach (KeyValuePair<string, SerializableProperty> property in SerializableProperties)
|
||||
{
|
||||
if (!property.Value.Attributes.OfType<Editable>().Any()) continue;
|
||||
clone.SerializableProperties[property.Key].TrySetValue(property.Value.GetValue());
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
private void CreateStairBodies()
|
||||
@@ -651,23 +662,28 @@ namespace Barotrauma
|
||||
Vector2 transformedPos = worldPosition;
|
||||
if (Submarine != null) transformedPos -= Submarine.Position;
|
||||
|
||||
int i = FindSectionIndex(transformedPos);
|
||||
if (i == -1) return new AttackResult(0.0f, 0.0f);
|
||||
|
||||
float damageAmount = attack.GetStructureDamage(deltaTime);
|
||||
|
||||
AddDamage(i, damageAmount, attacker);
|
||||
float damageAmount = 0.0f;
|
||||
for (int i = 0; i < SectionCount; i++)
|
||||
{
|
||||
if (Vector2.DistanceSquared(SectionPosition(i, true), worldPosition) <= attack.DamageRange * attack.DamageRange)
|
||||
{
|
||||
damageAmount = attack.GetStructureDamage(deltaTime);
|
||||
AddDamage(i, damageAmount, attacker);
|
||||
|
||||
#if CLIENT
|
||||
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
if (playSound)// && !SectionBodyDisabled(i))
|
||||
{
|
||||
string damageSoundType = (attack.DamageType == DamageType.Blunt) ? "StructureBlunt" : "StructureSlash";
|
||||
SoundPlayer.PlayDamageSound(damageSoundType, damageAmount, worldPosition, tags: Tags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return new AttackResult(damageAmount, 0.0f);
|
||||
}
|
||||
|
||||
@@ -838,6 +854,7 @@ namespace Barotrauma
|
||||
{
|
||||
StairDirection = StairDirection == Direction.Left ? Direction.Right : Direction.Left;
|
||||
bodies.ForEach(b => GameMain.World.RemoveBody(b));
|
||||
bodies.Clear();
|
||||
|
||||
CreateStairBodies();
|
||||
}
|
||||
|
||||
@@ -1208,9 +1208,9 @@ namespace Barotrauma
|
||||
Item.ItemList.Clear();
|
||||
}
|
||||
|
||||
PhysicsBody.RemoveAll();
|
||||
Ragdoll.RemoveAll();
|
||||
|
||||
Ragdoll.list.Clear();
|
||||
PhysicsBody.RemoveAll();
|
||||
|
||||
GameMain.World.Clear();
|
||||
|
||||
|
||||
@@ -491,6 +491,22 @@ namespace Barotrauma
|
||||
if (contactDot > 0.0f)
|
||||
{
|
||||
Body.LinearVelocity -= Vector2.Normalize(Body.LinearVelocity) * contactDot;
|
||||
|
||||
float damageAmount = contactDot * Body.Mass / limb.character.Mass;
|
||||
|
||||
Vector2 n;
|
||||
FixedArray2<Vector2> contactPos;
|
||||
contact.GetWorldManifold(out n, out contactPos);
|
||||
limb.character.DamageLimb(ConvertUnits.ToDisplayUnits(contactPos[0]), limb, DamageType.Blunt, damageAmount, 0.0f, 0.0f, true, 0.0f);
|
||||
|
||||
if (limb.character.IsDead)
|
||||
{
|
||||
foreach (LimbJoint limbJoint in limb.character.AnimController.LimbJoints)
|
||||
{
|
||||
if (limbJoint.IsSevered || (limbJoint.LimbA != limb && limbJoint.LimbB != limb)) continue;
|
||||
limb.character.AnimController.SeverLimbJoint(limbJoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,6 +150,20 @@ namespace Barotrauma
|
||||
wayPoint.Remove();
|
||||
}
|
||||
|
||||
//find all open doors and temporarily activate their bodies to prevent visibility checks
|
||||
//from ignoring the doors and generating waypoint connections that go straight through the door
|
||||
List<Door> openDoors = new List<Door>();
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
var door = item.GetComponent<Door>();
|
||||
if (door != null && !door.Body.Enabled)
|
||||
{
|
||||
openDoors.Add(door);
|
||||
door.Body.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float minDist = 150.0f;
|
||||
float heightFromFloor = 110.0f;
|
||||
|
||||
@@ -201,15 +215,15 @@ namespace Barotrauma
|
||||
|
||||
borders.Height += inflateAmount;
|
||||
}
|
||||
|
||||
WayPoint[,] cornerWaypoint = new WayPoint[2,2];
|
||||
|
||||
for (int i = 0; i<2; i++)
|
||||
WayPoint[,] cornerWaypoint = new WayPoint[2, 2];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (float x = borders.X + outSideWaypointInterval; x < borders.Right - outSideWaypointInterval; x += outSideWaypointInterval)
|
||||
{
|
||||
var wayPoint = new WayPoint(
|
||||
new Vector2(x, borders.Y - borders.Height * i) + submarine.HiddenSubPosition,
|
||||
new Vector2(x, borders.Y - borders.Height * i) + submarine.HiddenSubPosition,
|
||||
SpawnType.Path, submarine);
|
||||
|
||||
if (x == borders.X + outSideWaypointInterval)
|
||||
@@ -218,13 +232,13 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
wayPoint.ConnectTo(WayPoint.WayPointList[WayPointList.Count-2]);
|
||||
wayPoint.ConnectTo(WayPointList[WayPointList.Count - 2]);
|
||||
}
|
||||
}
|
||||
|
||||
cornerWaypoint[i, 1] = WayPoint.WayPointList[WayPointList.Count - 1];
|
||||
cornerWaypoint[i, 1] = WayPointList[WayPointList.Count - 1];
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
WayPoint wayPoint = null;
|
||||
@@ -300,7 +314,7 @@ namespace Barotrauma
|
||||
|
||||
while (prevPoint != ladderPoints[1])
|
||||
{
|
||||
var pickedBody = Submarine.PickBody(prevPos, ladderPoints[1].SimPosition, ignoredBodies);
|
||||
var pickedBody = Submarine.PickBody(prevPos, ladderPoints[1].SimPosition, ignoredBodies, null, false);
|
||||
|
||||
if (pickedBody == null) break;
|
||||
|
||||
@@ -333,19 +347,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
ladderPoints[i].Ladders = ladders;
|
||||
@@ -357,8 +359,6 @@ namespace Barotrauma
|
||||
ladderPoints[i].ConnectTo(closest);
|
||||
}
|
||||
}
|
||||
|
||||
//ladderPoints[0].ConnectTo(ladderPoints[1]);
|
||||
}
|
||||
|
||||
foreach (Gap gap in Gap.GapList)
|
||||
@@ -394,7 +394,7 @@ namespace Barotrauma
|
||||
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, gap);
|
||||
new Vector2(gap.Rect.Center.X, gap.Rect.Y - gap.Rect.Height / 2), SpawnType.Path, submarine, gap);
|
||||
|
||||
for (int dir = -1; dir <= 1; dir += 2)
|
||||
{
|
||||
@@ -410,6 +410,12 @@ namespace Barotrauma
|
||||
{
|
||||
wp.Remove();
|
||||
}
|
||||
|
||||
//re-disable the bodies of the doors that are supposed to be open
|
||||
foreach (Door door in openDoors)
|
||||
{
|
||||
door.Body.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private WayPoint FindClosest(int dir, bool horizontalSearch, Vector2 tolerance, Body ignoredBody = null)
|
||||
@@ -443,7 +449,7 @@ namespace Barotrauma
|
||||
float dist = Vector2.Distance(wp.Position, Position);
|
||||
if (closest == null || dist < closestDist)
|
||||
{
|
||||
var body = Submarine.CheckVisibility(SimPosition, wp.SimPosition, true, true);
|
||||
var body = Submarine.CheckVisibility(SimPosition, wp.SimPosition, true, true, false);
|
||||
if (body != null && body != ignoredBody && !(body.UserData is Submarine))
|
||||
{
|
||||
if (body.UserData is Structure || body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue;
|
||||
|
||||
Reference in New Issue
Block a user