Npcs/Diner/DinerMillSchedule.cs
using Sandbox.Npcs.Tasks;
namespace Sandbox.Npcs.Schedules;
/// <summary>
/// Mill around the home area complaining, periodically checking for a free chair.
/// The DinerNpc's GetSchedule() will interrupt this and switch to DinerSitSchedule
/// as soon as a chair becomes available.
/// </summary>
public class DinerMillSchedule : ScheduleBase
{
private static readonly string[] MillingLines =
[
"Where am I supposed to sit?!",
"This is unacceptable.",
"I paid for a full breakfast!",
"*mutters furiously*",
"There had better be compensation.",
"I'm going to stand here until there's a seat.",
"Does anyone work here?",
"My table is destroyed.",
"I'm writing a strongly worded letter.",
"Has anyone seen my hat? It was on the table.",
"The eggs are everywhere.",
"That car came from NOWHERE.",
"First the service, now THIS.",
"I just wanted a quiet breakfast.",
"This city, I swear.",
];
protected override void OnStart()
{
var diner = Npc as Sandbox.Npcs.Diner.DinerNpc;
// Wander to a random point within the home area
var randomDir = Vector3.Random.WithZ( 0 ).Normal;
var wanderRadius = diner?.MillRadius ?? 300f;
var home = diner?.HomeArea ?? Npc.WorldPosition;
var target = home + randomDir * Game.Random.Float( 80f, wanderRadius * 0.6f );
if ( Npc.Scene.NavMesh.GetClosestPoint( target ) is { } navPoint )
AddTask( new MoveTo( navPoint, 20f ) );
else
AddTask( new MoveTo( target, 20f ) );
// Stop and complain
AddTask( new Wait( Game.Random.Float( 0.5f, 1.5f ) ) );
if ( Npc.Speech.CanSpeak && Game.Random.Float() < 0.65f )
{
var line = MillingLines[Game.Random.Int( 0, MillingLines.Length - 1 )];
AddTask( new Say( line, 3f ) );
}
AddTask( new Wait( Game.Random.Float( 0.5f, 2f ) ) );
}
}