(ae643deeb) Added alive checks to a couple of diving gear status effects (don't consume tanks when dead)
This commit is contained in:
@@ -28,8 +28,10 @@ namespace Barotrauma
|
||||
|
||||
public Explosion(float range, float force, float damage, float structureDamage, float empStrength = 0.0f)
|
||||
{
|
||||
attack = new Attack(damage, 0.0f, 0.0f, structureDamage, range);
|
||||
attack.SeverLimbsProbability = 1.0f;
|
||||
attack = new Attack(damage, 0.0f, 0.0f, structureDamage, range)
|
||||
{
|
||||
SeverLimbsProbability = 1.0f
|
||||
};
|
||||
this.force = force;
|
||||
this.empStrength = empStrength;
|
||||
sparks = true;
|
||||
@@ -183,9 +185,6 @@ namespace Barotrauma
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
explosionPos = ConvertUnits.ToSimUnits(explosionPos);
|
||||
|
||||
Dictionary<Limb, float> distFactors = new Dictionary<Limb, float>();
|
||||
|
||||
@@ -175,12 +175,11 @@ namespace Barotrauma
|
||||
LimitSize();
|
||||
|
||||
UpdateProjSpecific(growModifier);
|
||||
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
if (size.X < 1.0f) Remove();
|
||||
|
||||
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||
{
|
||||
Remove();
|
||||
}
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float growModifier);
|
||||
@@ -293,10 +292,6 @@ namespace Barotrauma
|
||||
//evaporate some of the water
|
||||
hull.WaterVolume -= extinguishAmount;
|
||||
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||
{
|
||||
Remove();
|
||||
@@ -325,12 +320,11 @@ namespace Barotrauma
|
||||
size.X -= extinguishAmount;
|
||||
|
||||
hull.WaterVolume -= extinguishAmount;
|
||||
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
if (size.X < 1.0f) Remove();
|
||||
|
||||
if (size.X < 1.0f && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer))
|
||||
{
|
||||
Remove();
|
||||
}
|
||||
}
|
||||
|
||||
public void Extinguish(float deltaTime, float amount, Vector2 worldPosition)
|
||||
|
||||
@@ -88,6 +88,7 @@ namespace Barotrauma
|
||||
Gap.UpdateHulls();
|
||||
}
|
||||
|
||||
OxygenPercentage = prevOxygenPercentage;
|
||||
surface = drawSurface = rect.Y - rect.Height + WaterVolume / rect.Width;
|
||||
Pressure = surface;
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ namespace Barotrauma
|
||||
|
||||
public static Level CreateRandom(LocationConnection locationConnection)
|
||||
{
|
||||
string seed = locationConnection.Locations[0].Name + locationConnection.Locations[1].Name;
|
||||
string seed = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName;
|
||||
|
||||
float sizeFactor = MathUtils.InverseLerp(
|
||||
MapGenerationParams.Instance.SmallLevelConnectionLength,
|
||||
@@ -1522,21 +1522,49 @@ namespace Barotrauma
|
||||
outpost.MakeOutpost();
|
||||
|
||||
Point? minSize = null;
|
||||
DockingPort subPort = null;
|
||||
if (Submarine.MainSub != null)
|
||||
{
|
||||
Point subSize = Submarine.MainSub.GetDockedBorders().Size;
|
||||
Point outpostSize = outpost.GetDockedBorders().Size;
|
||||
minSize = new Point(Math.Max(subSize.X, outpostSize.X), subSize.Y + outpostSize.Y);
|
||||
|
||||
float closestDistance = float.MaxValue;
|
||||
foreach (DockingPort port in DockingPort.List)
|
||||
{
|
||||
if (port.IsHorizontal || port.Docked) { continue; }
|
||||
if (port.Item.Submarine != Submarine.MainSub) { continue; }
|
||||
//the submarine port has to be at the top of the sub
|
||||
if (port.Item.WorldPosition.Y < Submarine.MainSub.WorldPosition.Y) { continue; }
|
||||
float dist = Math.Abs(port.Item.WorldPosition.X - Submarine.MainSub.WorldPosition.X);
|
||||
if (dist < closestDistance)
|
||||
{
|
||||
subPort = port;
|
||||
closestDistance = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outpost.SetPosition(outpost.FindSpawnPos(i == 0 ? StartPosition : EndPosition, minSize));
|
||||
float subDockingPortOffset = subPort == null ? 0.0f : subPort.Item.WorldPosition.X - Submarine.MainSub.WorldPosition.X;
|
||||
//don't try to compensate if the port is very far from the sub's center of mass
|
||||
if (Math.Abs(subDockingPortOffset) > 2000.0f)
|
||||
{
|
||||
subDockingPortOffset = MathHelper.Clamp(subDockingPortOffset, -2000.0f, 2000.0f);
|
||||
string warningMsg = "Docking port very far from the sub's center of mass (submarine: " + Submarine.MainSub.Name + ", dist: " + subDockingPortOffset + "). The level generator may not be able to place the outpost so that docking is possible.";
|
||||
DebugConsole.NewMessage(warningMsg, Color.Orange);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Lever.CreateOutposts:DockingPortVeryFar" + Submarine.MainSub.Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Warning, warningMsg);
|
||||
}
|
||||
|
||||
outpost.SetPosition(outpost.FindSpawnPos(i == 0 ? StartPosition : EndPosition, minSize, subDockingPortOffset));
|
||||
if ((i == 0) == !Mirrored)
|
||||
{
|
||||
StartOutpost = outpost;
|
||||
if (GameMain.GameSession?.StartLocation != null) { outpost.Name = GameMain.GameSession.StartLocation.Name; }
|
||||
}
|
||||
else
|
||||
{
|
||||
EndOutpost = outpost;
|
||||
if (GameMain.GameSession?.EndLocation != null) { outpost.Name = GameMain.GameSession.EndLocation.Name; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace Barotrauma
|
||||
public Vector3 Position;
|
||||
|
||||
public float NetworkUpdateTimer;
|
||||
public const float NetworkUpdateInterval = 0.2f;
|
||||
|
||||
public float Scale;
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { obj });
|
||||
obj.NeedsNetworkSyncing = false;
|
||||
obj.NetworkUpdateTimer = LevelObject.NetworkUpdateInterval;
|
||||
obj.NetworkUpdateTimer = NetConfig.LevelObjectUpdateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -432,12 +432,16 @@ namespace Barotrauma
|
||||
{
|
||||
if (ForceFluctuationStrength > 0.0f)
|
||||
{
|
||||
forceFluctuationTimer += deltaTime;
|
||||
if (forceFluctuationTimer > ForceFluctuationInterval)
|
||||
//no need for force fluctuation (or network updates) if the trigger limits velocity and there are no triggerers
|
||||
if (forceMode != TriggerForceMode.LimitVelocity || triggerers.Any())
|
||||
{
|
||||
NeedsNetworkSyncing = true;
|
||||
currentForceFluctuation = Rand.Range(1.0f - ForceFluctuationStrength, 1.0f);
|
||||
forceFluctuationTimer = 0.0f;
|
||||
forceFluctuationTimer += deltaTime;
|
||||
if (forceFluctuationTimer > ForceFluctuationInterval)
|
||||
{
|
||||
NeedsNetworkSyncing = true;
|
||||
currentForceFluctuation = Rand.Range(1.0f - ForceFluctuationStrength, 1.0f);
|
||||
forceFluctuationTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ namespace Barotrauma
|
||||
|
||||
public int TypeChangeTimer;
|
||||
|
||||
public string BaseName { get => baseName; }
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
||||
public Vector2 MapPosition { get; private set; }
|
||||
@@ -32,10 +34,10 @@ namespace Barotrauma
|
||||
get
|
||||
{
|
||||
CheckMissionCompleted();
|
||||
|
||||
|
||||
for (int i = availableMissions.Count; i < Connections.Count * 2; i++)
|
||||
{
|
||||
int seed = (ToolBox.StringToInt(Name) + MissionsCompleted * 10 + i) % int.MaxValue;
|
||||
int seed = (ToolBox.StringToInt(BaseName) + MissionsCompleted * 10 + i) % int.MaxValue;
|
||||
MTRandom rand = new MTRandom(seed);
|
||||
|
||||
LocationConnection connection = Connections[(MissionsCompleted + i) % Connections.Count];
|
||||
@@ -46,7 +48,7 @@ namespace Barotrauma
|
||||
if (availableMissions.Any(m => m.Prefab == mission.Prefab)) { continue; }
|
||||
if (GameSettings.VerboseLogging && mission != null)
|
||||
{
|
||||
DebugConsole.NewMessage("Generated a new mission for a location connection (seed: " + seed.ToString("X") + ", type: " + mission.Name + ")", Color.White);
|
||||
DebugConsole.NewMessage("Generated a new mission for a location (location: " + Name + ", seed: " + seed.ToString("X") + ", missions completed: " + MissionsCompleted + ", type: " + mission.Name + ")", Color.White);
|
||||
}
|
||||
availableMissions.Add(mission);
|
||||
}
|
||||
@@ -75,10 +77,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public Location(Vector2 mapPosition, int? zone)
|
||||
public Location(Vector2 mapPosition, int? zone, Random rand)
|
||||
{
|
||||
this.Type = LocationType.Random("", zone);
|
||||
this.Name = RandomName(Type);
|
||||
this.Type = LocationType.Random(rand, zone);
|
||||
this.Name = RandomName(Type, rand);
|
||||
this.MapPosition = mapPosition;
|
||||
|
||||
PortraitId = ToolBox.StringToInt(Name);
|
||||
@@ -86,9 +88,9 @@ namespace Barotrauma
|
||||
Connections = new List<LocationConnection>();
|
||||
}
|
||||
|
||||
public static Location CreateRandom(Vector2 position, int? zone)
|
||||
public static Location CreateRandom(Vector2 position, int? zone , Random rand)
|
||||
{
|
||||
return new Location(position, zone);
|
||||
return new Location(position, zone, rand);
|
||||
}
|
||||
|
||||
public IEnumerable<Mission> GetMissionsInConnection(LocationConnection connection)
|
||||
@@ -99,7 +101,16 @@ namespace Barotrauma
|
||||
|
||||
public void ChangeType(LocationType newType)
|
||||
{
|
||||
if (newType == Type) return;
|
||||
if (newType == Type) { return; }
|
||||
|
||||
//clear missions from this and adjacent locations (they may be invalid now)
|
||||
availableMissions.Clear();
|
||||
foreach (LocationConnection connection in Connections)
|
||||
{
|
||||
connection.OtherLocation(this)?.availableMissions.Clear();
|
||||
}
|
||||
|
||||
DebugConsole.Log("Location " + baseName + " changed it's type from " + Type + " to " + newType);
|
||||
|
||||
Type = newType;
|
||||
Name = Type.NameFormats[nameFormatIndex % Type.NameFormats.Count].Replace("[name]", baseName);
|
||||
@@ -111,6 +122,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (mission.Completed)
|
||||
{
|
||||
DebugConsole.Log("Mission \"" + mission.Name + "\" completed in \"" + Name + "\".");
|
||||
MissionsCompleted++;
|
||||
}
|
||||
}
|
||||
@@ -118,10 +130,10 @@ namespace Barotrauma
|
||||
availableMissions.RemoveAll(m => m.Completed);
|
||||
}
|
||||
|
||||
private string RandomName(LocationType type)
|
||||
private string RandomName(LocationType type, Random rand)
|
||||
{
|
||||
baseName = type.GetRandomName();
|
||||
nameFormatIndex = Rand.Int(type.NameFormats.Count, Rand.RandSync.Server);
|
||||
baseName = type.GetRandomName(rand);
|
||||
nameFormatIndex = rand.Next() % type.NameFormats.Count;
|
||||
return type.NameFormats[nameFormatIndex].Replace("[name]", baseName);
|
||||
}
|
||||
|
||||
|
||||
@@ -155,20 +155,15 @@ namespace Barotrauma
|
||||
return portraits[Math.Abs(portraitId) % portraits.Count];
|
||||
}
|
||||
|
||||
public string GetRandomName()
|
||||
{
|
||||
return names[Rand.Int(names.Count, Rand.RandSync.Server)];
|
||||
}
|
||||
|
||||
public static LocationType Random(string seed = "", int? zone = null)
|
||||
{
|
||||
Debug.Assert(List.Count > 0, "LocationType.list.Count == 0, you probably need to initialize LocationTypes");
|
||||
|
||||
public string GetRandomName(Random rand)
|
||||
{
|
||||
return names[rand.Next() % names.Count];
|
||||
}
|
||||
|
||||
public static LocationType Random(Random rand, int? zone = null)
|
||||
{
|
||||
Debug.Assert(List.Count > 0, "LocationType.list.Count == 0, you probably need to initialize LocationTypes");
|
||||
|
||||
List<LocationType> allowedLocationTypes = zone.HasValue ? List.FindAll(lt => lt.CommonnessPerZone.ContainsKey(zone.Value)) : List;
|
||||
|
||||
if (allowedLocationTypes.Count == 0)
|
||||
@@ -180,12 +175,12 @@ namespace Barotrauma
|
||||
{
|
||||
return ToolBox.SelectWeightedRandom(
|
||||
allowedLocationTypes,
|
||||
allowedLocationTypes.Select(a => a.CommonnessPerZone[zone.Value]).ToList(),
|
||||
Rand.RandSync.Server);
|
||||
allowedLocationTypes.Select(a => a.CommonnessPerZone[zone.Value]).ToList(),
|
||||
rand);
|
||||
}
|
||||
else
|
||||
{
|
||||
return allowedLocationTypes[Rand.Int(allowedLocationTypes.Count, Rand.RandSync.Server)];
|
||||
return allowedLocationTypes[rand.Next() % allowedLocationTypes.Count];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace Barotrauma
|
||||
Vector2 position = points[positionIndex];
|
||||
if (newLocations[1 - i] != null && newLocations[1 - i].MapPosition == position) position = points[1 - positionIndex];
|
||||
int zone = MathHelper.Clamp(generationParams.DifficultyZones - (int)Math.Floor(Vector2.Distance(position, mapCenter) / zoneRadius), 1, generationParams.DifficultyZones);
|
||||
newLocations[i] = Location.CreateRandom(position, zone);
|
||||
newLocations[i] = Location.CreateRandom(position, zone, Rand.GetRNG(Rand.RandSync.Server));
|
||||
Locations.Add(newLocations[i]);
|
||||
}
|
||||
|
||||
@@ -578,10 +578,12 @@ namespace Barotrauma
|
||||
location.MissionsCompleted = missionsCompleted;
|
||||
if (showNotifications && prevLocationType != location.Type)
|
||||
{
|
||||
ChangeLocationType(
|
||||
location,
|
||||
prevLocationName,
|
||||
prevLocationType.CanChangeTo.Find(c => c.ChangeToType.ToLowerInvariant() == location.Type.Identifier.ToLowerInvariant()));
|
||||
var change = prevLocationType.CanChangeTo.Find(c =>
|
||||
c.ChangeToType.ToLowerInvariant() == location.Type.Identifier.ToLowerInvariant());
|
||||
if (change != null)
|
||||
{
|
||||
ChangeLocationType(location, prevLocationName, change);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "connection":
|
||||
|
||||
@@ -297,7 +297,13 @@ namespace Barotrauma
|
||||
CreateStairBodies();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Only add ai targets automatically to walls
|
||||
if (aiTarget == null && HasBody && Tags.Contains("wall"))
|
||||
{
|
||||
aiTarget = new AITarget(this);
|
||||
}
|
||||
|
||||
InsertToList();
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,10 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
SerializableProperty.DeserializeProperties(sp, element);
|
||||
if (sp.Body)
|
||||
{
|
||||
sp.Tags.Add("wall");
|
||||
}
|
||||
string translatedDescription = TextManager.Get("EntityDescription." + sp.identifier, true);
|
||||
if (!string.IsNullOrEmpty(translatedDescription)) sp.Description = translatedDescription;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Xml.Linq;
|
||||
using Voronoi2;
|
||||
|
||||
@@ -493,7 +494,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 FindSpawnPos(Vector2 spawnPos, Point? submarineSize = null)
|
||||
public Vector2 FindSpawnPos(Vector2 spawnPos, Point? submarineSize = null, float subDockingPortOffset = 0.0f)
|
||||
{
|
||||
Rectangle dockedBorders = GetDockedBorders();
|
||||
Vector2 diffFromDockedBorders =
|
||||
@@ -532,6 +533,10 @@ namespace Barotrauma
|
||||
{
|
||||
maxX = Math.Min(maxX, ruin.Area.X - 100.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxX = Math.Min(maxX, ruin.Area.X - 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (minX < 0.0f && maxX > Level.Loaded.Size.X)
|
||||
@@ -554,6 +559,26 @@ namespace Barotrauma
|
||||
spawnPos.X = (minX + maxX) / 2;
|
||||
}
|
||||
|
||||
if (minX < 0.0f && maxX > Level.Loaded.Size.X)
|
||||
{
|
||||
//no walls found at either side, just use the initial spawnpos and hope for the best
|
||||
}
|
||||
else if (minX < 0)
|
||||
{
|
||||
//no wall found at the left side, spawn to the left from the right-side wall
|
||||
spawnPos.X = maxX - minWidth - 100.0f + subDockingPortOffset;
|
||||
}
|
||||
else if (maxX > Level.Loaded.Size.X)
|
||||
{
|
||||
//no wall found at right side, spawn to the right from the left-side wall
|
||||
spawnPos.X = minX + minWidth + 100.0f + subDockingPortOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
//walls found at both sides, use their midpoint
|
||||
spawnPos.X = (minX + maxX) / 2 + subDockingPortOffset;
|
||||
}
|
||||
|
||||
spawnPos.Y = Math.Min(spawnPos.Y, Level.Loaded.Size.Y - dockedBorders.Height / 2 - 10);
|
||||
return spawnPos - diffFromDockedBorders;
|
||||
}
|
||||
@@ -665,7 +690,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, IEnumerable<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null)
|
||||
public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, IEnumerable<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null, bool allowInsideFixture = false)
|
||||
{
|
||||
if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.00001f)
|
||||
{
|
||||
@@ -677,21 +702,20 @@ namespace Barotrauma
|
||||
Body closestBody = null;
|
||||
if (allowInsideFixture)
|
||||
{
|
||||
if (fixture == null ||
|
||||
(ignoreSensors && fixture.IsSensor) ||
|
||||
fixture.CollisionCategories == Category.None ||
|
||||
fixture.CollisionCategories == Physics.CollisionItem) return -1;
|
||||
|
||||
if (customPredicate != null && !customPredicate(fixture)) return -1;
|
||||
|
||||
if (collisionCategory != null &&
|
||||
!fixture.CollisionCategories.HasFlag((Category)collisionCategory) &&
|
||||
!((Category)collisionCategory).HasFlag(fixture.CollisionCategories)) return -1;
|
||||
var aabb = new FarseerPhysics.Collision.AABB(rayStart - Vector2.One * 0.001f, rayStart + Vector2.One * 0.001f);
|
||||
GameMain.World.QueryAABB((fixture) =>
|
||||
{
|
||||
if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return true; }
|
||||
|
||||
fixture.Body.GetTransform(out FarseerPhysics.Common.Transform transform);
|
||||
if (!fixture.Shape.TestPoint(ref transform, ref rayStart)) { return true; }
|
||||
|
||||
if (fixture.Body.UserData is Structure structure)
|
||||
closestFraction = 0.0f;
|
||||
closestNormal = Vector2.Normalize(rayEnd - rayStart);
|
||||
if (fixture.Body != null) closestBody = fixture.Body;
|
||||
return false;
|
||||
}, ref aabb);
|
||||
if (closestFraction <= 0.0f)
|
||||
{
|
||||
lastPickedPosition = rayStart;
|
||||
lastPickedFraction = closestFraction;
|
||||
@@ -721,7 +745,7 @@ namespace Barotrauma
|
||||
return closestBody;
|
||||
}
|
||||
|
||||
public static List<Body> PickBodies(Vector2 rayStart, Vector2 rayEnd, List<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null)
|
||||
public static List<Body> PickBodies(Vector2 rayStart, Vector2 rayEnd, IEnumerable<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null, bool allowInsideFixture = false)
|
||||
{
|
||||
if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.00001f)
|
||||
{
|
||||
@@ -732,25 +756,9 @@ namespace Barotrauma
|
||||
List<Body> bodies = new List<Body>();
|
||||
GameMain.World.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
if (fixture == null ||
|
||||
(ignoreSensors && fixture.IsSensor) ||
|
||||
fixture.CollisionCategories == Category.None ||
|
||||
fixture.CollisionCategories == Physics.CollisionItem) return -1;
|
||||
if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return -1; }
|
||||
|
||||
if (customPredicate != null && !customPredicate(fixture)) return -1;
|
||||
|
||||
if (collisionCategory != null &&
|
||||
!fixture.CollisionCategories.HasFlag((Category)collisionCategory) &&
|
||||
!((Category)collisionCategory).HasFlag(fixture.CollisionCategories)) return -1;
|
||||
|
||||
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body)) return -1;
|
||||
|
||||
if (fixture.Body.UserData is Structure structure)
|
||||
{
|
||||
if (structure.IsPlatform && collisionCategory != null && !((Category)collisionCategory).HasFlag(Physics.CollisionPlatform)) return -1;
|
||||
}
|
||||
|
||||
bodies.Add(fixture.Body);
|
||||
if (fixture.Body != null) { bodies.Add(fixture.Body); }
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * fraction;
|
||||
@@ -760,10 +768,68 @@ namespace Barotrauma
|
||||
|
||||
return fraction;
|
||||
}, rayStart, rayEnd);
|
||||
|
||||
|
||||
if (allowInsideFixture)
|
||||
{
|
||||
var aabb = new FarseerPhysics.Collision.AABB(rayStart - Vector2.One * 0.001f, rayStart + Vector2.One * 0.001f);
|
||||
GameMain.World.QueryAABB((fixture) =>
|
||||
{
|
||||
if (bodies.Contains(fixture.Body) || fixture.Body == null) { return true; }
|
||||
if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return true; }
|
||||
|
||||
fixture.Body.GetTransform(out FarseerPhysics.Common.Transform transform);
|
||||
if (!fixture.Shape.TestPoint(ref transform, ref rayStart)) { return true; }
|
||||
|
||||
closestFraction = 0.0f;
|
||||
lastPickedPosition = rayStart;
|
||||
lastPickedFraction = 0.0f;
|
||||
lastPickedNormal = Vector2.Normalize(rayEnd - rayStart);
|
||||
bodies.Add(fixture.Body);
|
||||
return false;
|
||||
}, ref aabb);
|
||||
}
|
||||
|
||||
return bodies;
|
||||
}
|
||||
|
||||
private static bool CheckFixtureCollision(Fixture fixture, IEnumerable<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null)
|
||||
{
|
||||
if (fixture == null ||
|
||||
(ignoreSensors && fixture.IsSensor) ||
|
||||
fixture.CollisionCategories == Category.None ||
|
||||
fixture.CollisionCategories == Physics.CollisionItem)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (customPredicate != null && !customPredicate(fixture))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (collisionCategory != null &&
|
||||
!fixture.CollisionCategories.HasFlag((Category)collisionCategory) &&
|
||||
!((Category)collisionCategory).HasFlag(fixture.CollisionCategories))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fixture.Body.UserData is Structure structure)
|
||||
{
|
||||
if (structure.IsPlatform && collisionCategory != null && !((Category)collisionCategory).HasFlag(Physics.CollisionPlatform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// check visibility between two points (in sim units)
|
||||
/// </summary>
|
||||
|
||||
@@ -615,7 +615,7 @@ namespace Barotrauma
|
||||
ID = (ushort)int.Parse(element.Attribute("ID").Value)
|
||||
};
|
||||
|
||||
Enum.TryParse(element.GetAttributeString("spawn", "Path"), out w.spawnType);
|
||||
w.spawnType = spawnType;
|
||||
|
||||
string idCardDescString = element.GetAttributeString("idcarddesc", "");
|
||||
if (!string.IsNullOrWhiteSpace(idCardDescString))
|
||||
|
||||
Reference in New Issue
Block a user