(d34fb2097) Major refactoring: - Replace custom logic regarding subobjectives with generic logic. - Ensure that all the objectives follow the same logic, reduce duplicate code where possible.

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:32:56 +03:00
parent 05270aa165
commit a3db11876b
23 changed files with 555 additions and 865 deletions
@@ -13,12 +13,10 @@ namespace Barotrauma
public override bool ForceRun => true;
public override bool KeepDivingGearOn => true;
private Hull targetHull;
private readonly Hull targetHull;
private AIObjectiveGetItem getExtinguisherObjective;
private AIObjectiveGoTo gotoObjective;
private float useExtinquisherTimer;
public AIObjectiveExtinguishFire(Character character, Hull targetHull, AIObjectiveManager objectiveManager, float priorityModifier = 1)
@@ -40,111 +38,91 @@ namespace Barotrauma
return MathHelper.Lerp(0, 100, MathHelper.Clamp(devotion + severityFactor * distanceFactor, 0, 1));
}
public override bool IsCompleted()
{
return targetHull.FireSources.Count == 0;
}
public override bool IsCompleted() => targetHull.FireSources.None();
public override bool IsDuplicate(AIObjective otherObjective)
{
var otherExtinguishFire = otherObjective as AIObjectiveExtinguishFire;
return otherExtinguishFire != null && otherExtinguishFire.targetHull == targetHull;
}
public override bool CanBeCompleted =>
(getExtinguisherObjective == null || getExtinguisherObjective.IsCompleted() || getExtinguisherObjective.CanBeCompleted) &&
(gotoObjective == null || gotoObjective.IsCompleted() || gotoObjective.CanBeCompleted);
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveExtinguishFire otherExtinguishFire && otherExtinguishFire.targetHull == targetHull;
protected override void Act(float deltaTime)
{
var extinguisherItem = character.Inventory.FindItemByIdentifier("extinguisher") ?? character.Inventory.FindItemByTag("extinguisher");
if (extinguisherItem == null || extinguisherItem.Condition <= 0.0f || !character.HasEquippedItem(extinguisherItem))
{
if (getExtinguisherObjective == null)
TryAddSubObjective(ref getExtinguisherObjective, () =>
{
character.Speak(TextManager.Get("DialogFindExtinguisher"), null, 2.0f, "findextinguisher", 30.0f);
getExtinguisherObjective = new AIObjectiveGetItem(character, "extinguisher", objectiveManager, equip: true);
}
else
{
getExtinguisherObjective.TryComplete(deltaTime);
}
return;
return new AIObjectiveGetItem(character, "extinguisher", objectiveManager, equip: true);
});
}
var extinguisher = extinguisherItem.GetComponent<RepairTool>();
if (extinguisher == null)
else
{
DebugConsole.ThrowError("AIObjectiveExtinguishFire failed - the item \"" + extinguisherItem + "\" has no RepairTool component but is tagged as an extinguisher");
return;
}
foreach (FireSource fs in targetHull.FireSources)
{
bool inRange = fs.IsInDamageRange(character, MathHelper.Clamp(fs.DamageRange * 1.5f, extinguisher.Range * 0.5f, extinguisher.Range));
bool move = !inRange;
if (inRange || useExtinquisherTimer > 0.0f)
var extinguisher = extinguisherItem.GetComponent<RepairTool>();
if (extinguisher == null)
{
useExtinquisherTimer += deltaTime;
if (useExtinquisherTimer > 2.0f)
#if DEBUG
DebugConsole.ThrowError("AIObjectiveExtinguishFire failed - the item \"" + extinguisherItem + "\" has no RepairTool component but is tagged as an extinguisher");
#endif
abandon = true;
return;
}
foreach (FireSource fs in targetHull.FireSources)
{
bool inRange = fs.IsInDamageRange(character, MathHelper.Clamp(fs.DamageRange * 1.5f, extinguisher.Range * 0.5f, extinguisher.Range));
bool move = !inRange;
if (inRange || useExtinquisherTimer > 0.0f)
{
useExtinquisherTimer = 0.0f;
}
character.AIController.SteeringManager.Reset();
character.CursorPosition = fs.Position;
if (extinguisher.Item.RequireAimToUse)
{
bool isOperatingButtons = false;
if (SteeringManager == PathSteering)
useExtinquisherTimer += deltaTime;
if (useExtinquisherTimer > 2.0f)
{
var door = PathSteering.CurrentPath?.CurrentNode?.ConnectedDoor;
if (door != null && !door.IsOpen)
useExtinquisherTimer = 0.0f;
}
character.AIController.SteeringManager.Reset();
character.CursorPosition = fs.Position;
if (extinguisher.Item.RequireAimToUse)
{
bool isOperatingButtons = false;
if (SteeringManager == PathSteering)
{
isOperatingButtons = door.HasIntegratedButtons || door.Item.GetConnectedComponents<Controller>(true).Any();
var door = PathSteering.CurrentPath?.CurrentNode?.ConnectedDoor;
if (door != null && !door.IsOpen)
{
isOperatingButtons = door.HasIntegratedButtons || door.Item.GetConnectedComponents<Controller>(true).Any();
}
}
if (!isOperatingButtons)
{
character.SetInput(InputType.Aim, false, true);
}
}
if (!isOperatingButtons)
Limb sightLimb = null;
if (character.Inventory.IsInLimbSlot(extinguisherItem, InvSlotType.RightHand))
{
character.SetInput(InputType.Aim, false, true);
sightLimb = character.AnimController.GetLimb(LimbType.RightHand);
}
else if (character.Inventory.IsInLimbSlot(extinguisherItem, InvSlotType.LeftHand))
{
sightLimb = character.AnimController.GetLimb(LimbType.LeftHand);
}
if (!character.CanSeeTarget(fs, sightLimb))
{
move = true;
}
else
{
move = false;
extinguisher.Use(deltaTime, character);
if (!targetHull.FireSources.Contains(fs))
{
character.Speak(TextManager.Get("DialogPutOutFire").Replace("[roomname]", targetHull.Name), null, 0, "putoutfire", 10.0f);
}
}
}
Limb sightLimb = null;
if (character.Inventory.IsInLimbSlot(extinguisherItem, InvSlotType.RightHand))
if (move)
{
sightLimb = character.AnimController.GetLimb(LimbType.RightHand);
}
else if (character.Inventory.IsInLimbSlot(extinguisherItem, InvSlotType.LeftHand))
{
sightLimb = character.AnimController.GetLimb(LimbType.LeftHand);
}
if (!character.CanSeeTarget(fs, sightLimb))
{
move = true;
}
else
{
move = false;
extinguisher.Use(deltaTime, character);
if (!targetHull.FireSources.Contains(fs))
{
character.Speak(TextManager.Get("DialogPutOutFire").Replace("[roomname]", targetHull.Name), null, 0, "putoutfire", 10.0f);
}
//go to the first firesource
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(fs.Position), character, objectiveManager));
}
break;
}
if (move)
{
//go to the first firesource
if (gotoObjective == null || !gotoObjective.CanBeCompleted || gotoObjective.IsCompleted())
{
gotoObjective = new AIObjectiveGoTo(ConvertUnits.ToSimUnits(fs.Position), character, objectiveManager);
}
else
{
gotoObjective.TryComplete(deltaTime);
}
}
break;
}
}
}