(ebf4529cc) Use a uniform way to check if the bot has reached it's target. Should fix issues where bot is stuck when trying to get or operate an item in some cases.
This commit is contained in:
+1
-2
@@ -91,8 +91,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (container.Item.CurrentHull != character.CurrentHull ||
|
||||
(Vector2.DistanceSquared(character.Position, container.Item.Position) > Math.Pow(container.Item.InteractDistance, 2) && !container.Item.IsInsideTrigger(character.WorldPosition)))
|
||||
if (!character.CanInteractWith(container.Item, out _, checkLinked: false))
|
||||
{
|
||||
TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(container.Item, character, objectiveManager));
|
||||
return;
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (itemToDecontain.OwnInventory != character.Inventory && itemToDecontain.ParentInventory != character.Inventory)
|
||||
{
|
||||
if (Vector2.DistanceSquared(character.Position, container.Item.Position) > MathUtils.Pow(container.Item.InteractDistance, 2) && !container.Item.IsInsideTrigger(character.WorldPosition))
|
||||
if (!character.CanInteractWith(container.Item, out _, checkLinked: false))
|
||||
{
|
||||
TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(container.Item, character, objectiveManager));
|
||||
return;
|
||||
|
||||
+6
-5
@@ -114,12 +114,13 @@ namespace Barotrauma
|
||||
{
|
||||
goToObjective = null;
|
||||
}
|
||||
TryAddSubObjective(ref goToObjective, () =>
|
||||
new AIObjectiveGoTo(bestHull, character, objectiveManager, getDivingGearIfNeeded: false)
|
||||
TryAddSubObjective(ref goToObjective,
|
||||
constructor: () => new AIObjectiveGoTo(bestHull, character, objectiveManager, getDivingGearIfNeeded: false)
|
||||
{
|
||||
// If we need diving gear, we should already have it, if possible.
|
||||
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
|
||||
}, onAbandon: () => unreachable.Add(goToObjective.Target as Hull));
|
||||
// If we need diving gear, we should already have it, if possible.
|
||||
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
|
||||
},
|
||||
onAbandon: () => unreachable.Add(goToObjective.Target as Hull));
|
||||
}
|
||||
}
|
||||
if (goToObjective != null) { return; }
|
||||
|
||||
@@ -179,6 +179,32 @@ namespace Barotrauma
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool");
|
||||
#endif
|
||||
abandon = true;
|
||||
return;
|
||||
}
|
||||
Vector2 gapDiff = Leak.WorldPosition - character.WorldPosition;
|
||||
// TODO: use the collider size/reach?
|
||||
if (!character.AnimController.InWater && Math.Abs(gapDiff.X) < 100 && gapDiff.Y < 0.0f && gapDiff.Y > -150)
|
||||
{
|
||||
HumanAIController.AnimController.Crouching = true;
|
||||
}
|
||||
float reach = ConvertUnits.ToSimUnits(repairTool.Range);
|
||||
bool canOperate = ConvertUnits.ToSimUnits(gapDiff.Length()) < reach * 1.5f;
|
||||
if (canOperate)
|
||||
{
|
||||
TryAddSubObjective(ref operateObjective, () => new AIObjectiveOperateItem(repairTool, character, objectiveManager, option: "", requireEquip: true, operateTarget: Leak));
|
||||
}
|
||||
else
|
||||
{
|
||||
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach * 0.75f });
|
||||
}
|
||||
if (subObjectives.Any()) { return; }
|
||||
var repairTool = weldingTool.GetComponent<RepairTool>();
|
||||
if (repairTool == null)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool");
|
||||
#endif
|
||||
abandon = true;
|
||||
return;
|
||||
|
||||
@@ -100,8 +100,7 @@ namespace Barotrauma
|
||||
objectiveManager.GetObjective<AIObjectiveIdle>()?.Wander(deltaTime);
|
||||
return;
|
||||
}
|
||||
if (moveToTarget.CurrentHull == character.CurrentHull &&
|
||||
Vector2.DistanceSquared(character.Position, moveToTarget.Position) < MathUtils.Pow(targetItem.InteractDistance, 2))
|
||||
if (character.CanInteractWith(targetItem, out _, checkLinked: false))
|
||||
{
|
||||
if (IsTakenBySomeone(targetItem))
|
||||
{
|
||||
|
||||
@@ -16,6 +16,11 @@ namespace Barotrauma
|
||||
private float waitUntilPathUnreachable;
|
||||
private bool getDivingGearIfNeeded;
|
||||
|
||||
public Func<bool> customCondition;
|
||||
|
||||
/// <summary>
|
||||
/// Sim units
|
||||
/// </summary>
|
||||
public float CloseEnough { get; set; } = 0.5f;
|
||||
public bool IgnoreIfTargetDead { get; set; }
|
||||
public bool AllowGoingOutside { get; set; }
|
||||
@@ -173,21 +178,38 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private bool isCompleted;
|
||||
public override bool IsCompleted()
|
||||
{
|
||||
// First check the distance
|
||||
// Then the custom condition
|
||||
// And finally check if can interact (heaviest)
|
||||
if (repeat) { return false; }
|
||||
bool completed = false;
|
||||
if (Target is Item item)
|
||||
if (isCompleted) { return true; }
|
||||
bool closeEnough = Vector2.DistanceSquared(Target != null ? Target.SimPosition : targetPos, character.SimPosition) < CloseEnough * CloseEnough;
|
||||
if (closeEnough)
|
||||
{
|
||||
if (item.IsInsideTrigger(character.WorldPosition)) { completed = true; }
|
||||
if (customCondition == null || customCondition())
|
||||
{
|
||||
if (Target is Item item)
|
||||
{
|
||||
if (character.CanInteractWith(item, out _, checkLinked: false)) { isCompleted = true; }
|
||||
}
|
||||
else if (Target is Character targetCharacter)
|
||||
{
|
||||
if (character.CanInteractWith(targetCharacter, ConvertUnits.ToDisplayUnits(CloseEnough))) { isCompleted = true; }
|
||||
}
|
||||
else
|
||||
{
|
||||
isCompleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Target is Character targetCharacter)
|
||||
if (isCompleted)
|
||||
{
|
||||
if (character.CanInteractWith(targetCharacter)) { completed = true; }
|
||||
character.AIController.SteeringManager.Reset();
|
||||
}
|
||||
completed = completed || Vector2.DistanceSquared(Target != null ? Target.SimPosition : targetPos, character.SimPosition) < CloseEnough * CloseEnough;
|
||||
if (completed) { character.AIController.SteeringManager.Reset(); }
|
||||
return completed;
|
||||
return isCompleted;
|
||||
}
|
||||
|
||||
public override bool IsDuplicate(AIObjective otherObjective)
|
||||
|
||||
@@ -88,6 +88,21 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (objectiveManager.CurrentObjective == this)
|
||||
{
|
||||
if (randomTimer > 0)
|
||||
{
|
||||
randomTimer -= deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRandom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCompleted() => false;
|
||||
public override bool CanBeCompleted => true;
|
||||
|
||||
|
||||
+6
-3
@@ -1,5 +1,6 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
@@ -66,9 +67,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (target.CanBeSelected)
|
||||
{
|
||||
bool inSameRoom = character.CurrentHull == target.Item.CurrentHull;
|
||||
bool withinReach = target.Item.IsInsideTrigger(character.WorldPosition) || Vector2.DistanceSquared(character.Position, target.Item.Position) < MathUtils.Pow(target.Item.InteractDistance, 2);
|
||||
if (inSameRoom && withinReach)
|
||||
if (character.CanInteractWith(target.Item, out _, checkLinked: false))
|
||||
{
|
||||
if (character.SelectedConstruction != target.Item)
|
||||
{
|
||||
@@ -446,6 +445,10 @@ namespace Barotrauma
|
||||
{
|
||||
isCompleted = true;
|
||||
}
|
||||
if (component.AIOperate(deltaTime, character, this))
|
||||
{
|
||||
isCompleted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (character.CurrentHull == Item.CurrentHull && character.CanInteractWith(Item))
|
||||
if (character.CanInteractWith(Item, out _, checkLinked: false))
|
||||
{
|
||||
if (repairTool != null)
|
||||
{
|
||||
|
||||
@@ -620,6 +620,25 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (targetItem.Prefab.DeconstructItems.Any())
|
||||
{
|
||||
inputContainer.Inventory.RemoveItem(targetItem);
|
||||
Entity.Spawner.AddToRemoveQueue(targetItem);
|
||||
MoveInputQueue();
|
||||
PutItemsToLinkedContainer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outputContainer.Inventory.Items.All(i => i != null))
|
||||
{
|
||||
targetItem.Drop(dropper: null);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputContainer.Inventory.TryPutItem(targetItem, user: null, createNetworkEvent: true);
|
||||
}
|
||||
}
|
||||
|
||||
if (targetItem.Prefab.DeconstructItems.Any())
|
||||
{
|
||||
inputContainer.Inventory.RemoveItem(targetItem);
|
||||
|
||||
@@ -212,6 +212,33 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2? PosToMaintain
|
||||
{
|
||||
get { return posToMaintain; }
|
||||
set { posToMaintain = value; }
|
||||
}
|
||||
|
||||
struct ObstacleDebugInfo
|
||||
{
|
||||
public Vector2 Point1;
|
||||
public Vector2 Point2;
|
||||
|
||||
public Vector2? Intersection;
|
||||
|
||||
public float Dot;
|
||||
|
||||
public Vector2 AvoidStrength;
|
||||
|
||||
public ObstacleDebugInfo(GraphEdge edge, Vector2? intersection, float dot, Vector2 avoidStrength)
|
||||
{
|
||||
Point1 = edge.Point1;
|
||||
Point2 = edge.Point2;
|
||||
Intersection = intersection;
|
||||
Dot = dot;
|
||||
AvoidStrength = avoidStrength;
|
||||
}
|
||||
}
|
||||
|
||||
//edge point 1, edge point 2, avoid strength
|
||||
private List<ObstacleDebugInfo> debugDrawObstacles = new List<ObstacleDebugInfo>();
|
||||
|
||||
|
||||
@@ -1128,10 +1128,6 @@ namespace Barotrauma
|
||||
{
|
||||
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
|
||||
}
|
||||
if (!broken)
|
||||
{
|
||||
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
|
||||
}
|
||||
|
||||
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }
|
||||
|
||||
@@ -1176,59 +1172,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTransform()
|
||||
{
|
||||
Submarine prevSub = Submarine;
|
||||
|
||||
FindHull();
|
||||
|
||||
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }
|
||||
|
||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
|
||||
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
|
||||
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
|
||||
|
||||
if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity ||
|
||||
Math.Abs(body.LinearVelocity.Y) > NetConfig.MaxPhysicsBodyVelocity)
|
||||
{
|
||||
body.LinearVelocity = new Vector2(
|
||||
MathHelper.Clamp(body.LinearVelocity.X, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity),
|
||||
MathHelper.Clamp(body.LinearVelocity.Y, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity));
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTransform()
|
||||
{
|
||||
Submarine prevSub = Submarine;
|
||||
|
||||
FindHull();
|
||||
|
||||
if (Submarine == null && prevSub != null)
|
||||
{
|
||||
body.SetTransform(body.SimPosition + prevSub.SimPosition, body.Rotation);
|
||||
}
|
||||
else if (Submarine != null && prevSub == null)
|
||||
{
|
||||
body.SetTransform(body.SimPosition - Submarine.SimPosition, body.Rotation);
|
||||
}
|
||||
else if (Submarine != null && prevSub != null && Submarine != prevSub)
|
||||
{
|
||||
body.SetTransform(body.SimPosition + prevSub.SimPosition - Submarine.SimPosition, body.Rotation);
|
||||
}
|
||||
|
||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
|
||||
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
|
||||
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
|
||||
|
||||
if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity ||
|
||||
Math.Abs(body.LinearVelocity.Y) > NetConfig.MaxPhysicsBodyVelocity)
|
||||
{
|
||||
body.LinearVelocity = new Vector2(
|
||||
MathHelper.Clamp(body.LinearVelocity.X, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity),
|
||||
MathHelper.Clamp(body.LinearVelocity.Y, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity));
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTransform()
|
||||
{
|
||||
Submarine prevSub = Submarine;
|
||||
|
||||
@@ -398,6 +398,25 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private string roomName;
|
||||
[Editable, Serialize("", true, translationTextTag: "RoomName.")]
|
||||
public string RoomName
|
||||
{
|
||||
get { return roomName; }
|
||||
set
|
||||
{
|
||||
if (roomName == value) { return; }
|
||||
roomName = value;
|
||||
DisplayName = TextManager.Get(roomName, returnNull: true) ?? roomName;
|
||||
}
|
||||
}
|
||||
|
||||
public override Rectangle Rect
|
||||
{
|
||||
get
|
||||
|
||||
Reference in New Issue
Block a user