(26f71bab4) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev
This commit is contained in:
@@ -40,6 +40,9 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(false, false)]
|
||||
public bool RepairThroughWalls { get; set; }
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool RepairMultiple { get; set; }
|
||||
|
||||
public Vector2 TransformedBarrelPos
|
||||
{
|
||||
get
|
||||
@@ -158,12 +161,22 @@ namespace Barotrauma.Items.Components
|
||||
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
|
||||
{
|
||||
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
|
||||
if (RepairThroughWalls)
|
||||
if (RepairMultiple)
|
||||
{
|
||||
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true);
|
||||
Type lastHitType = null;
|
||||
foreach (Body body in bodies)
|
||||
{
|
||||
FixBody(user, deltaTime, degreeOfSuccess, body);
|
||||
Type bodyType = body.UserData?.GetType();
|
||||
if (!RepairThroughWalls && bodyType != null && bodyType != lastHitType)
|
||||
{
|
||||
//stop the ray if it already hit a door/wall and is now about to hit some other type of entity
|
||||
if (lastHitType == typeof(Item) || lastHitType == typeof(Structure)) { break; }
|
||||
}
|
||||
if (FixBody(user, deltaTime, degreeOfSuccess, body))
|
||||
{
|
||||
if (bodyType != null) { lastHitType = bodyType; }
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -202,19 +215,19 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void FixBody(Character user, float deltaTime, float degreeOfSuccess, Body targetBody)
|
||||
private bool FixBody(Character user, float deltaTime, float degreeOfSuccess, Body targetBody)
|
||||
{
|
||||
if (targetBody?.UserData == null) { return; }
|
||||
if (targetBody?.UserData == null) { return false; }
|
||||
|
||||
pickedPosition = Submarine.LastPickedPosition;
|
||||
|
||||
if (targetBody.UserData is Structure targetStructure)
|
||||
{
|
||||
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) return;
|
||||
if (targetStructure.IsPlatform) return;
|
||||
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) { return false; }
|
||||
if (targetStructure.IsPlatform) { return false; }
|
||||
|
||||
int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition));
|
||||
if (sectionIndex < 0) return;
|
||||
if (sectionIndex < 0) { return false; }
|
||||
|
||||
FixStructureProjSpecific(user, deltaTime, targetStructure, sectionIndex);
|
||||
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess, user);
|
||||
@@ -239,12 +252,14 @@ namespace Barotrauma.Items.Components
|
||||
targetCharacter.LastDamageSource = item;
|
||||
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new List<ISerializableEntity>() { targetCharacter });
|
||||
FixCharacterProjSpecific(user, deltaTime, targetCharacter);
|
||||
return true;
|
||||
}
|
||||
else if (targetBody.UserData is Limb targetLimb)
|
||||
{
|
||||
targetLimb.character.LastDamageSource = item;
|
||||
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new List<ISerializableEntity>() { targetLimb.character, targetLimb });
|
||||
FixCharacterProjSpecific(user, deltaTime, targetLimb.character);
|
||||
return true;
|
||||
}
|
||||
else if (targetBody.UserData is Item targetItem)
|
||||
{
|
||||
@@ -269,6 +284,7 @@ namespace Barotrauma.Items.Components
|
||||
#endif
|
||||
}
|
||||
FixItemProjSpecific(user, deltaTime, targetItem, prevCondition);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -730,7 +730,15 @@ namespace Barotrauma
|
||||
return closestBody;
|
||||
}
|
||||
|
||||
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)
|
||||
private static readonly Dictionary<Body, float> bodyDist = new Dictionary<Body, float>();
|
||||
private static readonly List<Body> bodies = new List<Body>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of physics bodies the ray intersects with, sorted according to distance (the closest body is at the beginning of the list).
|
||||
/// </summary>
|
||||
/// <param name="customPredicate">Can be used to filter the bodies based on some condition. If the predicate returns false, the body isignored.</param>
|
||||
/// <param name="allowInsideFixture">Should fixtures that the start of the ray is inside be returned</param>
|
||||
public static IEnumerable<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)
|
||||
{
|
||||
@@ -738,20 +746,25 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
float closestFraction = 1.0f;
|
||||
List<Body> bodies = new List<Body>();
|
||||
bodies.Clear();
|
||||
bodyDist.Clear();
|
||||
GameMain.World.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return -1; }
|
||||
|
||||
if (fixture.Body != null) { bodies.Add(fixture.Body); }
|
||||
if (fixture.Body != null)
|
||||
{
|
||||
bodies.Add(fixture.Body);
|
||||
bodyDist[fixture.Body] = fraction;
|
||||
}
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * fraction;
|
||||
lastPickedFraction = fraction;
|
||||
lastPickedNormal = normal;
|
||||
}
|
||||
|
||||
return fraction;
|
||||
//continue
|
||||
return -1;
|
||||
}, rayStart, rayEnd);
|
||||
|
||||
if (allowInsideFixture)
|
||||
@@ -770,10 +783,12 @@ namespace Barotrauma
|
||||
lastPickedFraction = 0.0f;
|
||||
lastPickedNormal = Vector2.Normalize(rayEnd - rayStart);
|
||||
bodies.Add(fixture.Body);
|
||||
bodyDist[fixture.Body] = 0.0f;
|
||||
return false;
|
||||
}, ref aabb);
|
||||
}
|
||||
|
||||
bodies.Sort((b1, b2) => { return bodyDist[b1].CompareTo(bodyDist[b2]); });
|
||||
return bodies;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user