AI/Staff/StaffManager.cs
using Sandbox.Diagnostics;
using System;
namespace HC3;
public partial class StaffManager : Component, IParkEvents
{
/// <summary>
/// Singleton
/// </summary>
public static StaffManager Instance { get; private set; }
/// <summary>
/// All staff members currently employed and working in the park.
/// </summary>
public IEnumerable<Staff> StaffList => _staff;
private IEnumerable<Staff> _staff => Scene.GetAll<Staff>();
/// <summary>
/// How many staff are currently in the park?
/// </summary>
public int StaffCount => _staff.Count();
/// <summary>
/// A quick reference to the <see cref="ParkManager"/>
/// </summary>
public ParkManager ParkManager => ParkManager.Instance;
/// <summary>
/// The park entrance, just find one in the scene
/// </summary>
private ParkEntrance _cachedEntrance;
private ParkEntrance Entrance => _cachedEntrance ??= Scene.GetAll<ParkEntrance>().FirstOrDefault();
/// <summary>
/// Get existing staff of type
/// </summary>
/// <param name="def"></param>
/// <returns></returns>
public IEnumerable<Staff> OfType( StaffDefinition def )
{
return _staff.Where( x => x.Definition == def );
}
public Staff CreateStaffMember( StaffDefinition definition, Action<Staff> onInit = null )
{
var target = Scene.GetAll<SpawnPoint>().OrderBy( x => Random.Shared.Next() ).FirstOrDefault()?.GameObject.WorldPosition ?? Entrance.WorldPosition;
var staffObject = definition.Prefab?.Clone( new CloneConfig()
{
Transform = new Transform( target, Entrance.WorldRotation, 1f ),
StartEnabled = false
} );
Assert.True( staffObject.IsValid(), "Staff prefab not hooked up to StaffManager" );
var staff = staffObject.GetComponent<Staff>( true );
Assert.True( staff.IsValid(), "Staff prefab does not have a Staff component" );
staffObject.Enabled = true;
onInit?.Invoke( staff );
staffObject.NetworkSpawn();
return staff;
}
[Rpc.Host]
public void Hire( StaffDefinition definition )
{
if ( !ParkManager.Instance.TakeMoney( definition.HireCost, "Staff Wages" ) )
return;
var isParkOpen = ParkManager.IsOpen();
var staff = CreateStaffMember( definition, x =>
{
x.SetWorkingState( isParkOpen );
} );
SelectionSystem.Instance.Select( staff.GameObject );
CameraPanning.Instance.Follow( staff.GameObject );
NotificationPanel.Instance?.Broadcast( $"You hired a {definition.DisplayName}!" );
Stats.Increment( "staff.hired" );
Stats.Increment( $"staff.hired.{definition.DisplayName.ToIdentifier()}" );
// Conna: we probably want some feedback here. Do we play a money sound to the user?
// Also, should we limit how many staff of each type can exist at once?
}
protected override void OnStart()
{
Instance = this;
}
void IParkEvents.OnParkOpened()
{
foreach ( var staff in _staff )
{
staff.SetWorkingState( true );
}
}
}