Park/Paths/PathFurniture.cs
using HC3.Persistence;
using HC3.Terrain;
using HC3.UI;
namespace HC3;
/// <summary>
/// Specifies the available categories of furniture items.
/// </summary>
public enum FurnitureType
{
[Title( "Uncategorised" )]
Uncategorised = 0,
[Title( "Bins" ), Icon( "delete" )]
Bin,
[Title( "Benches" ), Icon( "chair_alt" )]
Bench,
[Title( "Lamps" ), Icon( "tungsten" )]
Lamp,
[Title( "Signs" ), Icon( "assignment" )]
Sign,
[Title( "Other" ), Icon( "other_houses" )]
Other
}
public partial class PathFurniture : Component, IPlacementObject, IGridObjectEvent, IInspectable, IPathBlocker
{
private static float PathOffset => 0.7f;
[Property] public FurnitureType FurnitureType { get; set; } = FurnitureType.Uncategorised;
/// <summary>
/// Cost to place this in the world.
/// </summary>
[Property, Feature( "Building" )] public int Cost { get; set; } = 15;
[Property, Feature( "Building" ), Group( "Display" )] public string Title { get; set; } = "Furniture";
[Property, Feature( "Building" ), Group( "Display" ), ImageAssetPath] public string Thumbnail { get; set; } = "textures/thumbnails/missing_thumbnail.png";
public Group Group => new( "Furniture", FurnitureType.ToString() );
[Property, Feature( "Masks" )]
public PathMask BlockedDirections { get; set; }
[Property, Feature( "Masks" )]
public PathMask BlockedNavigation { get; set; }
[RequireComponent]
public GridObject GridObject { get; private set; }
protected override void OnValidate()
{
GridObject ??= GetOrAddComponent<GridObject>( false );
GridObject.Enabled = false;
}
/// <summary>
/// Check whether or not this building has been placed or is currently being placed.
/// </summary>
public bool IsPlaced
{
get => _isPlaced;
set
{
_isPlaced = value;
GridObject.Enabled = value;
}
}
private bool _isPlaced = false;
public TileEdge TileEdge { get; set; }
protected override void OnAwake()
{
if ( GameObject.IsPrefabInstanceRoot )
{
PrefabSource = GameObject.PrefabInstanceSource;
}
}
void IGridObjectEvent.NeighborsChanged( GridCell cell )
{
int level = GridManager.FloorWorldHeightToGrid( WorldPosition.z );
var path = cell?.GetComponent<Path>( level );
if ( !IsAllowed( path, TileEdge ) )
{
ParkManager.Instance.DestroyObject( this );
}
}
Window IInspectable.Select()
{
var building = this;
var inspector = new DecorationInspector();
inspector.Building = building;
return inspector;
}
public bool IsAllowed( Path path, TileEdge edge )
{
if ( !path.IsValid() ) return false;
// no stairs
if ( path.IsStairs ) return false;
if ( FurnitureType is FurnitureType.Sign )
{
// require a walkable edge
if ( !path.IsWalkable( edge, GridCell.ConnectionFlags.RequirePlaced ) ) return false;
}
else
{
// require an unwalkable edge
if ( path.IsWalkable( edge, GridCell.ConnectionFlags.RequirePlaced ) ) return false;
}
// already something there
if ( path.GetComponentsInChildren<PathFurniture>().Any( x => x != this && x.TileEdge == edge ) )
return false;
return true;
}
public static float GetPathOffset( FurnitureType furnitureType )
{
if ( furnitureType is FurnitureType.Sign ) return 0.9f;
return PathOffset;
}
}
file sealed class PathFurnitureSaveData : SpawnedPrefabSaveData<PathFurniture, PathFurniture.SaveData>
{
public override string PropertyName => "PathFurniture";
public override int PropertyOrder => 1;
}