Npcs/Diner/DinerSitSchedule.cs
using Sandbox.Npcs.Tasks;
namespace Sandbox.Npcs.Schedules;
/// <summary>
/// Walk to an assigned chair and sit. While seated, occasionally make breakfast comments.
/// The schedule runs indefinitely until interrupted (by fleeing).
/// </summary>
public class DinerSitSchedule : ScheduleBase
{
public GameObject Chair { get; set; }
/// <summary>
/// Seconds to stay seated before the schedule ends so the customer can re-evaluate
/// (and possibly get up to wander). Set by DinerNpc. 0 or less = sit indefinitely until
/// interrupted, which is the original behaviour.
/// Note: the timer starts when the schedule begins, so it includes the short walk to the
/// chair — close enough for ambient pacing without extra plumbing.
/// </summary>
public float MaxSeatedTime { get; set; } = 0f;
private TimeSince _timeSinceStart;
private static readonly string[] SittingLines =
[
"Mmm, eggs.",
"Lovely morning.",
"*sips coffee*",
"Beautiful day for breakfast.",
"I could eat here every day.",
"The service is excellent.",
"*contentedly chews*",
"Simply divine.",
"Nothing like a full English.",
"I love this place.",
];
protected override void OnStart()
{
_timeSinceStart = 0f;
if ( !Chair.IsValid() ) return;
// Walk to the chair
AddTask( new MoveTo( Chair, stopDistance: 20f ) );
// Sit animation — we lower speed to zero and trigger the sit pose
AddTask( new SitDown( Chair ) );
// Idle in the seat with occasional comments
AddTask( new SeatIdle( SittingLines, minWait: 4f, maxWait: 10f, commentChance: 0.4f ) );
}
// Get up after a while so the customer re-evaluates (SeatIdle never ends on its own).
// MaxSeatedTime <= 0 keeps the original "sit until scared" behaviour.
protected override bool ShouldCancel()
{
return MaxSeatedTime > 0f && _timeSinceStart > MaxSeatedTime;
}
// The seated pose is entered by SitDown and held through SeatIdle; we clear it here, when
// the schedule actually ends (timeout, scare, death), so the diner properly stands up.
protected override void OnEnd()
{
Npc.Renderer?.Set( "b_sit", false );
Npc.Navigation.WishSpeed = 100f;
}
}