AI/Guests/Guest.Crime.cs
using System;
namespace HC3;
public partial class Guest
{
/// <summary>
/// How much suspicion a guest must have for security to arrest them.
/// </summary>
public const float ArrestSuspicionThreshold = 0.8f;
/// <summary>
/// The maximum range from which a crime can be witnessed.
/// </summary>
public const float MaxCrimeWitnessRange = 600f * 600f;
/// <summary>
/// How suspicious this guest is. The higher the suspicion, the more likely
/// they are to be caught by security.
/// </summary>
public float SuspicionLevel { get; internal set; }
/// <summary>
/// Is this guest being persued by a member of staff?
/// </summary>
public bool IsPursued { get; set; }
/// <summary>
/// Has this guest been arrested? In which case they should leave the park.
/// </summary>
public bool IsArrested { get; set; }
/// <summary>
/// Log that this guest has committed a crime. Guests in the vicinity may
/// notice and report the crime.
/// </summary>
public void CommitCrime( float suspicionGain, Guest victim = null )
{
var allStaff = Scene.GetAll<Staff>();
var allGuests = Scene.GetAll<Guest>().Where( x => x != this && x != victim );
foreach ( var staff in allStaff )
{
var distance = staff.WorldPosition.DistanceSquared( WorldPosition );
if ( distance > MaxCrimeWitnessRange ) continue;
var witnessChance = Math.Clamp( 1f - distance / MaxCrimeWitnessRange, 0f, 1f );
if ( Game.Random.Float() >= witnessChance )
continue;
SuspicionLevel += suspicionGain * Game.Random.Float( 0.5f, 1.2f ) * staff.Alertness;
SuspicionLevel = SuspicionLevel.Clamp( 0f, 1f );
}
foreach ( var guest in allGuests )
{
var distance = guest.WorldPosition.DistanceSquared( WorldPosition );
if ( distance > MaxCrimeWitnessRange ) continue;
var witnessChance = Math.Clamp( 1f - distance / MaxCrimeWitnessRange, 0f, 1f );
if ( Game.Random.Float() >= witnessChance )
continue;
SuspicionLevel += suspicionGain * Game.Random.Float( 0.5f, 1.2f );
SuspicionLevel = SuspicionLevel.Clamp( 0f, 1f );
}
}
private void DecaySuspicionLevel()
{
// Very slowly decay our suspicion if we haven't been caught yet.
SuspicionLevel = MathF.Max( 0f, SuspicionLevel - Time.Delta * 0.01f );
}
}