Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveEscapeHandcuffs.cs
2024-06-18 16:50:02 +03:00

108 lines
3.9 KiB
C#

using System;
using System.Linq;
namespace Barotrauma
{
class AIObjectiveEscapeHandcuffs : AIObjective
{
// Used for prisoner escorts to allow them to escape their binds
public override Identifier Identifier { get; set; } = "escape handcuffs".ToIdentifier();
public override bool AllowAutomaticItemUnequipping => true;
protected override bool AllowOutsideSubmarine => true;
protected override bool AllowInAnySub => true;
private int escapeProgress;
private bool isBeingWatched;
private readonly bool shouldSwitchTeams;
const string EscapeTeamChangeIdentifier = "escape";
public AIObjectiveEscapeHandcuffs(Character character, AIObjectiveManager objectiveManager, bool shouldSwitchTeams = true, bool beginInstantly = false, float priorityModifier = 1) : base(character, objectiveManager, priorityModifier)
{
this.shouldSwitchTeams = shouldSwitchTeams;
if (beginInstantly)
{
escapeTimer = EscapeIntervalTimer;
}
}
public override bool CanBeCompleted => true;
protected override bool CheckObjectiveSpecific() => false;
// escape timer is set to 60 by default to allow players to locate prisoners in time
private float escapeTimer = 60f;
private const float EscapeIntervalTimer = 7.5f;
private float updateTimer;
private const float UpdateIntervalTimer = 4f;
protected override float GetPriority()
{
Priority = !isBeingWatched && character.LockHands ? AIObjectiveManager.LowestOrderPriority - 1 : 0;
return Priority;
}
public override void Update(float deltaTime)
{
updateTimer -= deltaTime;
if (updateTimer <= 0.0f)
{
if (shouldSwitchTeams)
{
if (!character.LockHands)
{
if (!character.HasTeamChange(EscapeTeamChangeIdentifier))
{
character.TryAddNewTeamChange(EscapeTeamChangeIdentifier, new ActiveTeamChange(CharacterTeamType.None, ActiveTeamChange.TeamChangePriorities.Willful));
}
}
else
{
character.TryRemoveTeamChange(EscapeTeamChangeIdentifier);
}
}
isBeingWatched = false;
foreach (Character otherCharacter in Character.CharacterList)
{
if (HumanAIController.IsActive(otherCharacter) && otherCharacter.TeamID == CharacterTeamType.Team1 && HumanAIController.VisibleHulls.Contains(otherCharacter.CurrentHull)) // hasn't been tested yet
{
isBeingWatched = true; // act casual when player characters are around
escapeProgress = 0;
break;
}
}
updateTimer = UpdateIntervalTimer * Rand.Range(0.75f, 1.25f);
}
}
protected override void Act(float deltaTime)
{
SteeringManager.Reset();
escapeTimer -= deltaTime;
if (escapeTimer <= 0.0f)
{
escapeProgress += Rand.Range(2, 5);
if (escapeProgress > 15)
{
foreach (var it in character.HeldItems)
{
if (it.HasTag(Tags.HandLockerItem) && it.IsInteractable(character))
{
it.Drop(character);
}
}
}
escapeTimer = EscapeIntervalTimer * Rand.Range(0.75f, 1.25f);
}
}
public override void Reset()
{
base.Reset();
escapeProgress = 0;
}
}
}