(bfd095a0a) Fix a bunch of bugs related to the recent refactoring.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:34:56 +03:00
parent 6bb7f5f0f1
commit e1584be2f7
11 changed files with 427 additions and 180 deletions
@@ -71,38 +71,56 @@ namespace Barotrauma
protected override void Act(float deltaTime)
{
var currentHull = character.AnimController.CurrentHull;
if (HumanAIController.NeedsDivingGear(currentHull) && divingGearObjective == null)
var currentHull = character.AnimController.CurrentHull;
bool needsDivingGear = HumanAIController.NeedsDivingGear(currentHull);
bool needsDivingSuit = needsDivingGear && (currentHull == null || currentHull.WaterPercentage > 90);
bool needsEquipment = false;
if (needsDivingSuit)
{
bool needsDivingSuit = currentHull == null || currentHull.WaterPercentage > 90;
bool hasEquipment = needsDivingSuit ? HumanAIController.HasDivingSuit(character) : HumanAIController.HasDivingGear(character);
if (!hasEquipment)
{
TryAddSubObjective(ref divingGearObjective,
() => new AIObjectiveFindDivingGear(character, needsDivingSuit, objectiveManager),
onAbandon: () => searchHullTimer = Math.Min(1, searchHullTimer));
}
needsEquipment = !HumanAIController.HasDivingSuit(character);
}
if (divingGearObjective != null) { return; }
// Reset the devotion.
Priority = 0;
if (currenthullSafety < HumanAIController.HULL_SAFETY_THRESHOLD)
else if (needsDivingGear)
{
searchHullTimer = Math.Min(1, searchHullTimer);
needsEquipment = !HumanAIController.HasDivingGear(character);
}
if (searchHullTimer > 0.0f)
if (needsEquipment)
{
searchHullTimer -= deltaTime;
TryAddSubObjective(ref divingGearObjective,
() => new AIObjectiveFindDivingGear(character, needsDivingSuit, objectiveManager),
onAbandon: () => searchHullTimer = Math.Min(1, searchHullTimer));
}
else
{
searchHullTimer = SearchHullInterval;
var bestHull = FindBestHull();
if (bestHull != null && bestHull != currentHull)
if (divingGearObjective != null && divingGearObjective.IsCompleted())
{
if (goToObjective?.Target != bestHull)
// Reset the devotion.
Priority = 0;
divingGearObjective = null;
}
if (currenthullSafety < HumanAIController.HULL_SAFETY_THRESHOLD)
{
searchHullTimer = Math.Min(1, searchHullTimer);
}
if (searchHullTimer > 0.0f)
{
searchHullTimer -= deltaTime;
}
else
{
searchHullTimer = SearchHullInterval;
var bestHull = FindBestHull();
if (bestHull != null && bestHull != currentHull)
{
goToObjective = null;
if (goToObjective?.Target != bestHull)
{
goToObjective = null;
}
TryAddSubObjective(ref goToObjective, () =>
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));
}
TryAddSubObjective(ref goToObjective, () =>
new AIObjectiveGoTo(bestHull, character, objectiveManager, getDivingGearIfNeeded: false)
@@ -111,50 +129,50 @@ namespace Barotrauma
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
}, onAbandon: () => unreachable.Add(goToObjective.Target as Hull));
}
}
if (goToObjective != null) { return; }
if (currentHull == null) { return; }
//goto objective doesn't exist (a safe hull not found, or a path to a safe hull not found)
// -> attempt to manually steer away from hazards
Vector2 escapeVel = Vector2.Zero;
foreach (FireSource fireSource in currentHull.FireSources)
{
Vector2 dir = character.Position - fireSource.Position;
float distMultiplier = MathHelper.Clamp(100.0f / Vector2.Distance(fireSource.Position, character.Position), 0.1f, 10.0f);
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
}
foreach (Character enemy in Character.CharacterList)
{
//don't run from friendly NPCs
if (enemy.TeamID == Character.TeamType.FriendlyNPC) { continue; }
//friendly NPCs don't run away from anything but characters controlled by EnemyAIController (= monsters)
if (character.TeamID == Character.TeamType.FriendlyNPC && !(enemy.AIController is EnemyAIController)) { continue; }
if (enemy.CurrentHull == currentHull && !enemy.IsDead && !enemy.IsUnconscious &&
(enemy.AIController is EnemyAIController || enemy.TeamID != character.TeamID))
if (goToObjective != null) { return; }
if (currentHull == null) { return; }
//goto objective doesn't exist (a safe hull not found, or a path to a safe hull not found)
// -> attempt to manually steer away from hazards
Vector2 escapeVel = Vector2.Zero;
foreach (FireSource fireSource in currentHull.FireSources)
{
Vector2 dir = character.Position - enemy.Position;
float distMultiplier = MathHelper.Clamp(100.0f / Vector2.Distance(enemy.Position, character.Position), 0.1f, 10.0f);
Vector2 dir = character.Position - fireSource.Position;
float distMultiplier = MathHelper.Clamp(100.0f / Vector2.Distance(fireSource.Position, character.Position), 0.1f, 10.0f);
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
}
}
if (escapeVel != Vector2.Zero)
{
//only move if we haven't reached the edge of the room
if ((escapeVel.X < 0 && character.Position.X > currentHull.Rect.X + 50) ||
(escapeVel.X > 0 && character.Position.X < currentHull.Rect.Right - 50))
foreach (Character enemy in Character.CharacterList)
{
character.AIController.SteeringManager.SteeringManual(deltaTime, escapeVel);
//don't run from friendly NPCs
if (enemy.TeamID == Character.TeamType.FriendlyNPC) { continue; }
//friendly NPCs don't run away from anything but characters controlled by EnemyAIController (= monsters)
if (character.TeamID == Character.TeamType.FriendlyNPC && !(enemy.AIController is EnemyAIController)) { continue; }
if (enemy.CurrentHull == currentHull && !enemy.IsDead && !enemy.IsUnconscious &&
(enemy.AIController is EnemyAIController || enemy.TeamID != character.TeamID))
{
Vector2 dir = character.Position - enemy.Position;
float distMultiplier = MathHelper.Clamp(100.0f / Vector2.Distance(enemy.Position, character.Position), 0.1f, 10.0f);
escapeVel += new Vector2(Math.Sign(dir.X) * distMultiplier, !character.IsClimbing ? 0 : Math.Sign(dir.Y) * distMultiplier);
}
}
if (escapeVel != Vector2.Zero)
{
//only move if we haven't reached the edge of the room
if ((escapeVel.X < 0 && character.Position.X > currentHull.Rect.X + 50) ||
(escapeVel.X > 0 && character.Position.X < currentHull.Rect.Right - 50))
{
character.AIController.SteeringManager.SteeringManual(deltaTime, escapeVel);
}
else
{
character.AnimController.TargetDir = escapeVel.X < 0.0f ? Direction.Right : Direction.Left;
character.AIController.SteeringManager.Reset();
}
}
else
{
character.AnimController.TargetDir = escapeVel.X < 0.0f ? Direction.Right : Direction.Left;
character.AIController.SteeringManager.Reset();
}
}
else
{
character.AIController.SteeringManager.Reset();
}
}
public Hull FindBestHull(IEnumerable<Hull> ignoredHulls = null)
@@ -54,14 +54,17 @@ namespace Barotrauma
{
if (!Leak.IsRoomToRoom)
{
TryAddSubObjective(ref findDivingGear, () => new AIObjectiveFindDivingGear(character, true, objectiveManager));
if (findDivingGear != null) { return; }
if (!HumanAIController.HasDivingSuit(character))
{
TryAddSubObjective(ref findDivingGear, () => new AIObjectiveFindDivingGear(character, true, objectiveManager));
return;
}
}
var weldingTool = character.Inventory.FindItemByTag("weldingtool");
if (weldingTool == null)
{
TryAddSubObjective(ref getWeldingTool, () => new AIObjectiveGetItem(character, "weldingtool", objectiveManager, true));
if (getWeldingTool != null) { return; }
return;
}
else
{
@@ -86,8 +89,9 @@ namespace Barotrauma
if (containedItems.None(i => i.HasTag("weldingfueltank") && i.Condition > 0.0f))
{
TryAddSubObjective(ref refuelObjective, () => new AIObjectiveContainItem(character, "weldingfueltank", weldingTool.GetComponent<ItemContainer>(), objectiveManager));
if (refuelObjective != null) { return; }
return;
}
canReach = character.CanSeeTarget(Leak, sightLimb);
}
var repairTool = weldingTool.GetComponent<RepairTool>();
if (repairTool == null)
@@ -105,26 +109,15 @@ namespace Barotrauma
HumanAIController.AnimController.Crouching = true;
}
float reach = ConvertUnits.ToSimUnits(repairTool.Range);
bool canReach = ConvertUnits.ToSimUnits(gapDiff.Length()) < reach;
if (canReach)
bool canOperate = ConvertUnits.ToSimUnits(gapDiff.Length()) < reach;
if (canOperate)
{
Limb sightLimb = null;
if (character.Inventory.IsInLimbSlot(repairTool.Item, InvSlotType.RightHand))
{
sightLimb = character.AnimController.GetLimb(LimbType.RightHand);
}
else if (character.Inventory.IsInLimbSlot(repairTool.Item, InvSlotType.LeftHand))
{
sightLimb = character.AnimController.GetLimb(LimbType.LeftHand);
}
canReach = character.CanSeeTarget(Leak, sightLimb);
TryAddSubObjective(ref operateObjective, () => new AIObjectiveOperateItem(repairTool, character, objectiveManager, option: "", requireEquip: true, operateTarget: Leak));
}
if (!canReach)
else
{
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach });
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach * 0.75f });
}
if (gotoObjective != null) { return; }
TryAddSubObjective(ref operateObjective, () => new AIObjectiveOperateItem(repairTool, character, objectiveManager, option: "", requireEquip: true, operateTarget: Leak));
}
private Vector2 GetStandPosition()
@@ -74,21 +74,6 @@ 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;
@@ -70,15 +70,7 @@ namespace Barotrauma
{
if (character.SelectedConstruction != target.Item)
{
if (character.SelectedConstruction != target.Item)
{
target.Item.TryInteract(character, false, true);
}
if (component.AIOperate(deltaTime, character, this))
{
isCompleted = true;
}
return;
isCompleted = true;
}
if (component.AIOperate(deltaTime, character, this))
{