River.cs

A Sandbox Component named River that tracks Thing objects currently touching it and damps their velocity each update. It stores counts per Thing in a dictionary, updates velocities toward zero using Utils.DynamicEaseTo, and handles trigger enter/exit to increment/decrement counts.

using Sandbox;
using System;
using static Sandbox.VertexLayout;

public sealed class River : Component
{
	public Dictionary<Thing, int> Touching = new();

	protected override void OnUpdate()
	{
		//Gizmo.Draw.Color = Color.White;
		//Gizmo.Draw.Text( $"Touching: {Touching.Count}", new global::Transform( WorldPosition ) );

		var dt = Time.Delta;
		for ( int i = Touching.Keys.Count - 1; i >= 0; i-- )
		{
			var other = Touching.Keys.ElementAt( i );
			if ( !other.IsValid() )
			{
				Touching.Remove( other );
				continue;
			}

			if ( other.IgnoreCollision )
				continue;

			other.Velocity = Utils.DynamicEaseTo( other.Velocity, Vector3.Zero, 0.06f, dt );
		}
	}

	public void Restart()
	{
		Touching.Clear();
	}

	public void OnTriggerEnter( Thing thing )
	{
		if ( Touching.ContainsKey( thing ) )
			Touching[thing]++;
		else
			Touching.Add( thing, 1 );
	}

	public void OnTriggerExit( Thing thing )
	{
		if ( !Touching.ContainsKey( thing ) )
			return;

		Touching[thing]--;
		if( Touching[thing] <= 0 )
			Touching.Remove( thing );
	}
}