Editor/Porch/ArchPorchTrim.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;

namespace Sunless.Architecture;

public static partial class ArchPorchGen {
	// A frieze caps the seam where the boards die into the wall.
	static void Ceiling( ArchMesh canvas, ArchPorchShape shape, ArchKit kit, ArchBrush boards, ArchBrush trim ) {
		var bite = ArchLap.Bite( kit );
		var thickness = MathF.Max( 1f, kit.PorchCeilingThickness );

		foreach ( var loop in ArchFootprint.Grow( new[] { shape.Footprint }, bite ) ) {
			ArchFloorGen.Slab( canvas, loop, null, shape.Ceiling - thickness, shape.Ceiling, boards );
		}

		var height = MathF.Max( 2f, kit.PorchFriezeHeight );
		var depth = MathF.Max( 0.5f, kit.PorchFriezeDepth );

		foreach ( var wall in shape.Walls ) {
			ArchBandSection.Between( -bite, depth, shape.Ceiling - thickness - height, shape.Ceiling - thickness + bite )
				.Emit( canvas, ArchRunPath.Between( wall.From, wall.To ), trim );
		}
	}

	// Covers the raw seam where the roof's high edge dies in the brick.
	static void Flashing( ArchMesh canvas, ArchPorchShape shape, ArchPorchPart porch, ArchBuilding building, ArchKit kit, ArchBrush brush ) {
		var roof = building.Roofs.FirstOrDefault( part => part.Id == porch.RoofId );

		if ( roof is null ) {
			return;
		}

		var thickness = roof.Thickness > 0f ? roof.Thickness : kit.RoofThickness;
		var slope = ArchRoofPlane.Slope( roof );
		var height = MathF.Max( 2f, kit.PorchFlashingHeight );
		var depth = MathF.Max( 0.5f, kit.PorchFriezeDepth );
		var bite = ArchLap.Bite( kit );

		foreach ( var wall in shape.Walls ) {
			var deck = roof.BaseHeight + slope * (wall.Depth + roof.Overhang) + thickness;

			ArchBandSection.Between( -bite, depth, deck - 1f, deck + height )
				.Emit( canvas, ArchRunPath.Between( wall.From, wall.To ), brush );
		}
	}

}