Editor/LineSettings.cs
using System;
using Sandbox;

namespace TerrainLines;

public enum ShoulderCurve { Smooth, Linear, RoundIn, RoundOut }

public sealed class LineSettings
{
	[Property, Range( 1, 4096 ), Title( "Path Width" )]
	public float PathWidth { get; set; } = 128;
	[Property, Range( 0, 4096 ), Title( "Shoulder Width" )]
	public float ShoulderWidth { get; set; } = 64;
	public ShoulderCurve ShoulderCurve { get; set; }
	[Property, Title( "Shape Terrain" )]
	public bool ShapeTerrain { get; set; } = true;
	[Property, Range( 0, 1 ), Title( "Even Ramp" ), Description( "0 uses a smooth terrain-influenced profile. 1 makes an even grade from the first point to the last along the entire line. Values between blend these profiles." )]
	public float EvenRamp { get; set; }
	[Property, Range( 0, 90 ), Title( "Slope Limit" ), Description( "Maximum uphill or downhill angle along the line. Lower values extend steep sections into nearby terrain and can raise the endpoints. 0 makes the line flat at its highest profile height; 90 is unrestricted." )]
	public float SlopeLimit { get; set; } = 90;
	[Property, Description( "Raise or lower the resulting line in world units. Zero applies no offset." )]
	public float Elevation { get; set; }
	[Property, Title( "Paint Materials" )]
	public bool PaintMaterials { get; set; }
	[Property, Range( 0, 1 ), Title( "Paint Strength" )]
	public float PaintStrength { get; set; } = 1;
	public int SurfaceMaterial { get; set; }
	public int ShoulderMaterial { get; set; } = -1;

	internal bool IsFinite => float.IsFinite( PathWidth ) && float.IsFinite( ShoulderWidth )
		&& float.IsFinite( EvenRamp ) && float.IsFinite( SlopeLimit ) && float.IsFinite( Elevation ) && float.IsFinite( PaintStrength );
	internal int Fingerprint => HashCode.Combine( PathWidth, ShoulderWidth, ShoulderCurve, ShapeTerrain,
		HashCode.Combine( EvenRamp, SlopeLimit, Elevation, PaintMaterials, PaintStrength, SurfaceMaterial, ShoulderMaterial ) );
}