Park/Decoration/Decoration.cs
using HC3;
using HC3.UI;
public sealed partial class Decoration : Component, ISceneMetadata, IInspectable, IPlacementObject, IPathBlocker
{
[RequireComponent]
public GridObject GridObject { get; private set; }
/// <summary>
/// Cost to place this in the world.
/// </summary>
[Property, Feature( "Building" ), Group( "Display" )] public int Cost { get; set; } = 15;
/// <summary>
/// The building's name
/// </summary>
[Property, Feature( "Building" ), Group( "Display" )] public string Title { get; set; } = "Building";
[Property, Feature( "Building" ), Group( "Display" ), ImageAssetPath] public string Thumbnail { get; set; } = "textures/thumbnails/missing_thumbnail.png";
[Property, Feature( "Building" ), Group( "Display" )] public bool SnapToGrid { get; set; } = false;
[Property, Feature( "Building" ), Group( "Display" )] public DecorationType Type { get; set; } = DecorationType.Prop;
[Property, Feature( "Building" ), Group( "Display" )] public ObjectMaterial ObjectMaterial { get; set; } = ObjectMaterial.Default;
[Property, Feature( "Building" ), Group( "Display" )] public int Weight { get; set; } = 0;
/// <summary>
/// Which directions should block paths through this decoration
/// </summary>
[Property, Feature( "Masks" )]
public PathMask BlockedDirections { get; set; } = 0;
/// <summary>
/// Which directions should block AI navigation (for one-way paths etc)
/// </summary>
[Property, Feature( "Masks" )]
public PathMask BlockedNavigation { get; set; } = 0;
public Group Group => new( "Decoration", Type.ToString() );
public TintChannelData RedChannel { get; set; } = new( true, Color.White );
public TintChannelData GreenChannel { get; set; } = new( false, Color.White );
public TintChannelData BlueChannel { get; set; } = new( false, Color.White );
public TintChannelData AlphaChannel { get; set; } = new( false, Color.White );
/// <summary>
/// A list of thematic tags
/// </summary>
[Property]
public List<string> ThemeTags { get; set; }
IEnumerable<string> IPlacementObject.GetTags()
{
return ThemeTags;
}
public static IEnumerable<GameObject> AllPrefabs
{
get
{
return ResourceLibrary.GetAll<PrefabFile>()
.Where( x => x.GetMetadata( "Type", "" ).Equals( "Decoration" ) )
.ToList()
.Select( x => GameObject.GetPrefab( x.ResourcePath ) );
}
}
Dictionary<string, string> ISceneMetadata.GetMetadata()
{
return new()
{
{ "Type", "Decoration" }
};
}
public TintMaskComponent GetTintComponent()
{
return GetComponentsInChildren<TintMaskComponent>().FirstOrDefault();
}
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;
if ( value )
{
ActiveDecorations.Add( this );
}
else
{
ActiveDecorations.Remove( this );
}
}
}
private bool _isPlaced = false;
/// <summary>
/// Right now just a collection of all enabled buildings, we can later what active means, have separate sets for open/closed buildings, etc.
/// </summary>
public static HashSet<Decoration> ActiveDecorations = new();
protected override void OnEnabled()
{
base.OnEnabled();
if ( IsPlaced ) ActiveDecorations.Add( this );
}
protected override void OnDisabled()
{
base.OnDisabled();
if ( IsPlaced ) ActiveDecorations.Remove( this );
}
protected override void OnStart()
{
base.OnStart();
UpdateColors();
}
Window IInspectable.Select()
{
var building = this;
var inspector = new DecorationInspector();
inspector.Building = building;
return inspector;
}
void ITintMaskEvents.OnColorsChanged( TintMaskComponent component )
{
var tintMask = GetTintComponent();
if ( tintMask != component )
return;
var red = RedChannel;
red.Color = component.PrimaryColor;
RedChannel = red;
var green = GreenChannel;
green.Color = component.SecondaryColor;
GreenChannel = green;
var blue = BlueChannel;
blue.Color = component.AccentColor;
BlueChannel = blue;
var alpha = AlphaChannel;
alpha.Color = component.DetailColor;
AlphaChannel = alpha;
}
void UpdateColors()
{
if ( !Networking.IsHost )
return;
var tintMask = GetTintComponent();
if ( tintMask is null )
return;
tintMask.PrimaryColor = RedChannel.Color;
tintMask.SecondaryColor = GreenChannel.Color;
tintMask.AccentColor = BlueChannel.Color;
tintMask.DetailColor = AlphaChannel.Color;
}
}
public enum DecorationType
{
Nature,
Building,
Fence,
Prop,
Sign,
Light,
Effect
}
public struct TintChannelData
{
public bool Enabled { get; set; }
public Color Color { get; set; }
public TintChannelData( bool enabled, Color color )
{
Enabled = enabled;
Color = color;
}
}