DiamondDebris.Rotation.cs
using System;
using Sandbox;
using static Diamonds.DiamondBoard;
namespace Diamonds;
public sealed partial class DiamondDebris
{
/// <summary>Emit a small spray from one or two open corners after syncing the debris world.</summary>
public void EmitRotationSparks( Piece piece )
{
if ( physicsScene is null || currentBoard is null || currentBoard.Paused ) return;
var corners = new List<(Vector2 Position, Vector2 Outward, int Color)>();
Vector2[] offsets = [new( 0, -Height / 2 ), new( Width / 2, 0 ), new( 0, Height / 2 ), new( -Width / 2, 0 )];
foreach ( var cell in CellsOf( piece ) )
foreach ( var offset in offsets )
{
var origin = new Vector2( LaneX( cell.Lane ), cell.Y ) + offset;
// Reject buried corners and corners pressed against the floor or stack.
if ( HasRoom( origin + offset.Normal * 5, 2.2f ) )
corners.Add( (origin, offset.Normal, cell.ColorIndex) );
}
int cornerCount = Math.Min( corners.Count, random.Next( 1, 3 ) );
int remaining = random.Next( 3, 7 );
for ( int corner = 0; corner < cornerCount; corner++ )
{
int index = random.Next( corners.Count );
var source = corners[index];
corners.RemoveAt( index );
int count = corner == cornerCount - 1 ? remaining : (remaining + 1) / 2;
remaining -= count;
for ( int spark = 0; spark < count; spark++ )
{
float radius = Range( 0.7f, 1.3f );
for ( int attempt = 0; attempt < 8; attempt++ )
{
float angle = Range( -0.65f, 0.65f );
var direction = source.Outward * MathF.Cos( angle )
+ new Vector2( -source.Outward.y, source.Outward.x ) * MathF.Sin( angle );
var position = source.Position + direction * Range( 4, 7 );
if ( !HasRoom( position, radius + 0.5f ) ) continue;
AddSpark( position, direction * Range( 35, 70 ), radius, source.Color );
break;
}
}
}
}
}