s&box Package Code Search

Search C# source code, UI razor templates, shaders, and configs across s&box packages.

Showing code results for query: * (6 total matches found)
rwtrcsc.checkpointsystem / Editor/CheckpointPlacer.cs
Editor library
using Editor;
using Sandbox;

[EditorTool]
[Title( "Checkpoint Placer" )]
[Icon( "add_location" )]
public class CheckpointPlacer : EditorTool
{
	int _nextIndex = 0;
	GameObject _manager;

	public override void OnEnabled()
	{
		EnsureManager();
		RecalculateIndex();
		Log.Info( "[CheckpointPlacer] Active. Next index: " + _nextIndex );
	}

	void EnsureManager()
	{
		foreach ( var go in Scene.GetAllObjects( true ) )
		{
			if ( go.Name == "CheckpointManager" )
			{
				_manager = go;
				return;
			}
		}

		_manager = new GameObject();
		_manager.Name = "CheckpointManager";
		_manager.Components.Create<CheckpointManager>();
		Log.Info( "[CheckpointPlacer] Created CheckpointManager" );
	}

	void RecalculateIndex()
	{
		if ( _manager == null ) return;

		int count = 0;
		foreach ( var child in _manager.Children )
		{
			var cp = child.Components.Get<CheckpointRing>();
			if ( cp is not null )
				count++;
		}
		_nextIndex = count;
	}

	public override void OnUpdate()
	{
		base.OnUpdate();

		var ray = Gizmo.CurrentRay;
		var tr = Scene.Trace.Ray( ray, 10000f ).WithoutTags( "trigger" ).Run();

		if ( !tr.Hit ) return;

		var pos = tr.HitPosition + Vector3.Up * 10f;

		Gizmo.Draw.Color = Color.Cyan.WithAlpha( 0.5f );
		Gizmo.Draw.SolidSphere( pos, 80f );

		Gizmo.Draw.Color = Color.White;
		Gizmo.Draw.ScreenText( "Left click to place checkpoint " + _nextIndex, new Vector2( 10, 10 ) );

		if ( Gizmo.WasLeftMousePressed )
		{
			EnsureManager();
			RecalculateIndex();
			PlaceCheckpoint( pos );
		}
	}

	void PlaceCheckpoint( Vector3 position )
	{
		var go = new GameObject();
		go.Parent = _manager;
		go.WorldPosition = position;
		go.Name = "Checkpoint_" + _nextIndex;

		var col = go.Components.Create<SphereCollider>();
		col.Radius = 150f;
		col.IsTrigger = true;
		go.Tags.Add( "trigger" );

		var cp = go.Components.Create<CheckpointRing>();
		cp.CheckpointIndex = _nextIndex;
		cp.IsFinishLine = false;
		cp.IsLastCheckpoint = false;

		var model = go.Components.Create<ModelRenderer>();
		model.Model = Model.Load( "models/primitives/sphere.vmdl" );
		model.Tint = Color.Cyan;
		go.WorldScale = new Vector3( 0.8f, 0.8f, 3f );

		_nextIndex++;
		Log.Info( "[CheckpointPlacer] Placed Checkpoint_" + (_nextIndex - 1) );
	}
}
rwtrcsc.checkpointsystem / .obj/__compiler_extra.cs
Game library
global using static Sandbox.Internal.GlobalGameNamespace;
global using Microsoft.AspNetCore.Components;
global using Microsoft.AspNetCore.Components.Rendering;
[assembly: global::System.Reflection.AssemblyMetadata( "AddonTitle", "Checkpoint System" )]
[assembly: global::System.Reflection.AssemblyMetadata( "AddonIdent", "checkpointsystem" )]
[assembly: global::System.Reflection.AssemblyMetadata( "OrgIdent", "rwtrcsc" )]
[assembly: global::System.Reflection.AssemblyMetadata( "Ident", "rwtrcsc.checkpointsystem" )]
[assembly: global::System.Reflection.AssemblyMetadata( "EngineVersion", "29" )]
[assembly: global::System.Reflection.AssemblyMetadata( "EngineMinorVersion", "1" )]

[assembly: System.Runtime.Versioning.TargetFramework( ".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0" )]
[assembly: global::System.Reflection.AssemblyMetadata( "CompileTime", "2026-10-08T19:47:22.9791400Z" )]
[assembly: global::System.Reflection.AssemblyVersion("0.0.111.0")]
[assembly: global::System.Reflection.AssemblyFileVersion("0.0.111.0")]
rwtrcsc.checkpointsystem / Code/CheckpointRing.cs
Game library
using Sandbox;
using System;
using System.Linq;
public sealed class CheckpointRing : Component
{
	[Property] public int CheckpointIndex { get; set; } = 0;
	[Property] public bool IsFinishLine { get; set; } = false;
	[Property] public bool IsLastCheckpoint { get; set; } = false;
	[Property] public float DetectionRadius { get; set; } = 150f;

	// Events � anyone can listen to these
	public static Action<int> OnCheckpointHit;
	public static Action OnFinishHit;

	bool _triggered = false;

	bool IsSequential => CheckpointManager.Instance?.Sequential ?? true;

	int TotalCheckpoints()
	{
		if ( CheckpointManager.Instance == null ) return 0;
		int count = 0;
		foreach ( var child in CheckpointManager.Instance.GameObject.Children )
		{
			var cp = child.Components.Get<CheckpointRing>();
			if ( cp is not null && !cp.IsFinishLine && !cp.IsLastCheckpoint )
				count++;
		}
		return count;
	}

	bool AllCheckpointsHit()
	{
		int total = TotalCheckpoints();
		int next = CheckpointManager.Instance?.NextCheckpoint ?? 0;
		return next >= total;
	}

	protected override void OnUpdate()
	{
		if ( _triggered ) return;

		var player = Scene.GetAllObjects( true )
			.FirstOrDefault( go => go.Tags.Has( "player" ) );

		if ( player == null ) return;

		float dist = Vector3.DistanceBetween( WorldPosition, player.WorldPosition );

		if ( dist >= DetectionRadius ) return;

		if ( IsFinishLine || IsLastCheckpoint )
		{
			if ( !AllCheckpointsHit() )
			{
				int remaining = TotalCheckpoints() - (CheckpointManager.Instance?.NextCheckpoint ?? 0);
				Log.Info( "[Checkpoint] Finish blocked � " + remaining + " remaining" );
				return;
			}
		}
		else if ( IsSequential )
		{
			int next = CheckpointManager.Instance?.NextCheckpoint ?? 0;
			if ( CheckpointIndex != next ) return;
		}

		_triggered = true;

		if ( IsFinishLine || IsLastCheckpoint )
		{
			Log.Info( "[Checkpoint] Finished!" );
			CheckpointManager.Instance?.OnFinishReached();
			OnFinishHit?.Invoke();

			var cube = CheckpointManager.Instance?.ColorCube;
			if ( cube is not null )
				cube.Tint = Color.Green;
		}
		else
		{
			Log.Info( "[Checkpoint " + CheckpointIndex + "] Hit" );
			CheckpointManager.Instance?.OnCheckpointReached( CheckpointIndex );
			OnCheckpointHit?.Invoke( CheckpointIndex );
		}
	}

	public void ResetCheckpoint()
	{
		_triggered = false;
	}
}
rwtrcsc.checkpointsystem / CheckpointManager.cs
Game library
using Sandbox;
using System;

public sealed class CheckpointManager : Component
{
	public static CheckpointManager Instance { get; private set; }

	[Property] public bool Sequential { get; set; } = true;
	[Property] public ModelRenderer ColorCube { get; set; }
	[Property] public CheckpointRing FinishLine { get; set; }
	[Property] public CheckpointRing LastCheckpoint { get; set; }

	// Events
	public Action<int> OnCheckpointReachedEvent;
	public Action OnFinishReachedEvent;

	public int NextCheckpoint { get; private set; } = 0;

	protected override void OnAwake()
	{
		Instance = this;

		if ( FinishLine is not null )
		{
			FinishLine.IsFinishLine = true;
			FinishLine.IsLastCheckpoint = false;
		}

		if ( LastCheckpoint is not null )
		{
			LastCheckpoint.IsLastCheckpoint = true;
			LastCheckpoint.IsFinishLine = false;
		}
	}

	protected override void OnStart()
	{
		NextCheckpoint = 0;
	}

	public void OnCheckpointReached( int index )
	{
		NextCheckpoint = index + 1;
		OnCheckpointReachedEvent?.Invoke( index );
		Log.Info( "[CheckpointManager] Checkpoint " + index + " reached. Next: " + NextCheckpoint );
	}

	public void OnFinishReached()
	{
		OnFinishReachedEvent?.Invoke();
		Log.Info( "[CheckpointManager] Finish reached!" );
	}

	public void ResetAll()
	{
		NextCheckpoint = 0;
		foreach ( var child in GameObject.Children )
		{
			var cp = child.Components.Get<CheckpointRing>();
			cp?.ResetCheckpoint();
		}
		Log.Info( "[CheckpointManager] Reset all checkpoints" );
	}
}
rwtrcsc.checkpointsystem / CheckpointRing.cs
Game library
using Sandbox;
using System;
using System.Linq;
public sealed class CheckpointRing : Component
{
	[Property] public int CheckpointIndex { get; set; } = 0;
	[Property] public bool IsFinishLine { get; set; } = false;
	[Property] public bool IsLastCheckpoint { get; set; } = false;
	[Property] public float DetectionRadius { get; set; } = 150f;

	// Events � anyone can listen to these
	public static Action<int> OnCheckpointHit;
	public static Action OnFinishHit;

	bool _triggered = false;

	bool IsSequential => CheckpointManager.Instance?.Sequential ?? true;

	int TotalCheckpoints()
	{
		if ( CheckpointManager.Instance == null ) return 0;
		int count = 0;
		foreach ( var child in CheckpointManager.Instance.GameObject.Children )
		{
			var cp = child.Components.Get<CheckpointRing>();
			if ( cp is not null && !cp.IsFinishLine && !cp.IsLastCheckpoint )
				count++;
		}
		return count;
	}

	bool AllCheckpointsHit()
	{
		int total = TotalCheckpoints();
		int next = CheckpointManager.Instance?.NextCheckpoint ?? 0;
		return next >= total;
	}

	protected override void OnUpdate()
	{
		if ( _triggered ) return;

		var player = Scene.GetAllObjects( true )
			.FirstOrDefault( go => go.Tags.Has( "player" ) );

		if ( player == null ) return;

		float dist = Vector3.DistanceBetween( WorldPosition, player.WorldPosition );

		if ( dist >= DetectionRadius ) return;

		if ( IsFinishLine || IsLastCheckpoint )
		{
			if ( !AllCheckpointsHit() )
			{
				int remaining = TotalCheckpoints() - (CheckpointManager.Instance?.NextCheckpoint ?? 0);
				Log.Info( "[Checkpoint] Finish blocked � " + remaining + " remaining" );
				return;
			}
		}
		else if ( IsSequential )
		{
			int next = CheckpointManager.Instance?.NextCheckpoint ?? 0;
			if ( CheckpointIndex != next ) return;
		}

		_triggered = true;

		if ( IsFinishLine || IsLastCheckpoint )
		{
			Log.Info( "[Checkpoint] Finished!" );
			CheckpointManager.Instance?.OnFinishReached();
			OnFinishHit?.Invoke();

			var cube = CheckpointManager.Instance?.ColorCube;
			if ( cube is not null )
				cube.Tint = Color.Green;
		}
		else
		{
			Log.Info( "[Checkpoint " + CheckpointIndex + "] Hit" );
			CheckpointManager.Instance?.OnCheckpointReached( CheckpointIndex );
			OnCheckpointHit?.Invoke( CheckpointIndex );
		}
	}

	public void ResetCheckpoint()
	{
		_triggered = false;
	}
}
rwtrcsc.checkpointsystem / Code/CheckpointManager.cs
Game library
using Sandbox;
using System;

public sealed class CheckpointManager : Component
{
	public static CheckpointManager Instance { get; private set; }

	[Property] public bool Sequential { get; set; } = true;
	[Property] public ModelRenderer ColorCube { get; set; }
	[Property] public CheckpointRing FinishLine { get; set; }
	[Property] public CheckpointRing LastCheckpoint { get; set; }

	// Events
	public Action<int> OnCheckpointReachedEvent;
	public Action OnFinishReachedEvent;

	public int NextCheckpoint { get; private set; } = 0;

	protected override void OnAwake()
	{
		Instance = this;

		if ( FinishLine is not null )
		{
			FinishLine.IsFinishLine = true;
			FinishLine.IsLastCheckpoint = false;
		}

		if ( LastCheckpoint is not null )
		{
			LastCheckpoint.IsLastCheckpoint = true;
			LastCheckpoint.IsFinishLine = false;
		}
	}

	protected override void OnStart()
	{
		NextCheckpoint = 0;
	}

	public void OnCheckpointReached( int index )
	{
		NextCheckpoint = index + 1;
		OnCheckpointReachedEvent?.Invoke( index );
		Log.Info( "[CheckpointManager] Checkpoint " + index + " reached. Next: " + NextCheckpoint );
	}

	public void OnFinishReached()
	{
		OnFinishReachedEvent?.Invoke();
		Log.Info( "[CheckpointManager] Finish reached!" );
	}

	public void ResetAll()
	{
		NextCheckpoint = 0;
		foreach ( var child in GameObject.Children )
		{
			var cp = child.Components.Get<CheckpointRing>();
			cp?.ResetCheckpoint();
		}
		Log.Info( "[CheckpointManager] Reset all checkpoints" );
	}
}
Debug: View Raw JSON Response
{
    "TotalCount": 6,
    "Files": [
        {
            "Ident": "rwtrcsc.checkpointsystem",
            "Path": "Editor/CheckpointPlacer.cs",
            "FileName": "CheckpointPlacer.cs",
            "PackageType": "library",
            "CodeKind": "Editor",
            "AssetVersionId": 421921,
            "IsPrivate": false,
            "Code": "using Editor;\r\nusing Sandbox;\r\n\r\n[EditorTool]\r\n[Title( \"Checkpoint Placer\" )]\r\n[Icon( \"add_location\" )]\r\npublic class CheckpointPlacer : EditorTool\r\n{\r\n\tint _nextIndex = 0;\r\n\tGameObject _manager;\r\n\r\n\tpublic override void OnEnabled()\r\n\t{\r\n\t\tEnsureManager();\r\n\t\tRecalculateIndex();\r\n\t\tLog.Info( \"[CheckpointPlacer] Active. Next index: \" + _nextIndex );\r\n\t}\r\n\r\n\tvoid EnsureManager()\r\n\t{\r\n\t\tforeach ( var go in Scene.GetAllObjects( true ) )\r\n\t\t{\r\n\t\t\tif ( go.Name == \"CheckpointManager\" )\r\n\t\t\t{\r\n\t\t\t\t_manager = go;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t_manager = new GameObject();\r\n\t\t_manager.Name = \"CheckpointManager\";\r\n\t\t_manager.Components.Create<CheckpointManager>();\r\n\t\tLog.Info( \"[CheckpointPlacer] Created CheckpointManager\" );\r\n\t}\r\n\r\n\tvoid RecalculateIndex()\r\n\t{\r\n\t\tif ( _manager == null ) return;\r\n\r\n\t\tint count = 0;\r\n\t\tforeach ( var child in _manager.Children )\r\n\t\t{\r\n\t\t\tvar cp = child.Components.Get<CheckpointRing>();\r\n\t\t\tif ( cp is not null )\r\n\t\t\t\tcount++;\r\n\t\t}\r\n\t\t_nextIndex = count;\r\n\t}\r\n\r\n\tpublic override void OnUpdate()\r\n\t{\r\n\t\tbase.OnUpdate();\r\n\r\n\t\tvar ray = Gizmo.CurrentRay;\r\n\t\tvar tr = Scene.Trace.Ray( ray, 10000f ).WithoutTags( \"trigger\" ).Run();\r\n\r\n\t\tif ( !tr.Hit ) return;\r\n\r\n\t\tvar pos = tr.HitPosition + Vector3.Up * 10f;\r\n\r\n\t\tGizmo.Draw.Color = Color.Cyan.WithAlpha( 0.5f );\r\n\t\tGizmo.Draw.SolidSphere( pos, 80f );\r\n\r\n\t\tGizmo.Draw.Color = Color.White;\r\n\t\tGizmo.Draw.ScreenText( \"Left click to place checkpoint \" + _nextIndex, new Vector2( 10, 10 ) );\r\n\r\n\t\tif ( Gizmo.WasLeftMousePressed )\r\n\t\t{\r\n\t\t\tEnsureManager();\r\n\t\t\tRecalculateIndex();\r\n\t\t\tPlaceCheckpoint( pos );\r\n\t\t}\r\n\t}\r\n\r\n\tvoid PlaceCheckpoint( Vector3 position )\r\n\t{\r\n\t\tvar go = new GameObject();\r\n\t\tgo.Parent = _manager;\r\n\t\tgo.WorldPosition = position;\r\n\t\tgo.Name = \"Checkpoint_\" + _nextIndex;\r\n\r\n\t\tvar col = go.Components.Create<SphereCollider>();\r\n\t\tcol.Radius = 150f;\r\n\t\tcol.IsTrigger = true;\r\n\t\tgo.Tags.Add( \"trigger\" );\r\n\r\n\t\tvar cp = go.Components.Create<CheckpointRing>();\r\n\t\tcp.CheckpointIndex = _nextIndex;\r\n\t\tcp.IsFinishLine = false;\r\n\t\tcp.IsLastCheckpoint = false;\r\n\r\n\t\tvar model = go.Components.Create<ModelRenderer>();\r\n\t\tmodel.Model = Model.Load( \"models/primitives/sphere.vmdl\" );\r\n\t\tmodel.Tint = Color.Cyan;\r\n\t\tgo.WorldScale = new Vector3( 0.8f, 0.8f, 3f );\r\n\r\n\t\t_nextIndex++;\r\n\t\tLog.Info( \"[CheckpointPlacer] Placed Checkpoint_\" + (_nextIndex - 1) );\r\n\t}\r\n}\r\n"
        },
        {
            "Ident": "rwtrcsc.checkpointsystem",
            "Path": ".obj/__compiler_extra.cs",
            "FileName": "__compiler_extra.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 421921,
            "IsPrivate": false,
            "Code": "global using static Sandbox.Internal.GlobalGameNamespace;\r\nglobal using Microsoft.AspNetCore.Components;\r\nglobal using Microsoft.AspNetCore.Components.Rendering;\r\n[assembly: global::System.Reflection.AssemblyMetadata( \"AddonTitle\", \"Checkpoint System\" )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \"AddonIdent\", \"checkpointsystem\" )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \"OrgIdent\", \"rwtrcsc\" )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \"Ident\", \"rwtrcsc.checkpointsystem\" )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \"EngineVersion\", \"29\" )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \"EngineMinorVersion\", \"1\" )]\r\n\r\n[assembly: System.Runtime.Versioning.TargetFramework( \".NETCoreApp,Version=v9.0\", FrameworkDisplayName = \".NET 9.0\" )]\r\n[assembly: global::System.Reflection.AssemblyMetadata( \"CompileTime\", \"2026-10-08T19:47:22.9791400Z\" )]\r\n[assembly: global::System.Reflection.AssemblyVersion(\"0.0.111.0\")]\r\n[assembly: global::System.Reflection.AssemblyFileVersion(\"0.0.111.0\")]"
        },
        {
            "Ident": "rwtrcsc.checkpointsystem",
            "Path": "Code/CheckpointRing.cs",
            "FileName": "CheckpointRing.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 421921,
            "IsPrivate": false,
            "Code": "using Sandbox;\r\nusing System;\r\nusing System.Linq;\r\npublic sealed class CheckpointRing : Component\r\n{\r\n\t[Property] public int CheckpointIndex { get; set; } = 0;\r\n\t[Property] public bool IsFinishLine { get; set; } = false;\r\n\t[Property] public bool IsLastCheckpoint { get; set; } = false;\r\n\t[Property] public float DetectionRadius { get; set; } = 150f;\r\n\r\n\t// Events \ufffd anyone can listen to these\r\n\tpublic static Action<int> OnCheckpointHit;\r\n\tpublic static Action OnFinishHit;\r\n\r\n\tbool _triggered = false;\r\n\r\n\tbool IsSequential => CheckpointManager.Instance?.Sequential ?? true;\r\n\r\n\tint TotalCheckpoints()\r\n\t{\r\n\t\tif ( CheckpointManager.Instance == null ) return 0;\r\n\t\tint count = 0;\r\n\t\tforeach ( var child in CheckpointManager.Instance.GameObject.Children )\r\n\t\t{\r\n\t\t\tvar cp = child.Components.Get<CheckpointRing>();\r\n\t\t\tif ( cp is not null && !cp.IsFinishLine && !cp.IsLastCheckpoint )\r\n\t\t\t\tcount++;\r\n\t\t}\r\n\t\treturn count;\r\n\t}\r\n\r\n\tbool AllCheckpointsHit()\r\n\t{\r\n\t\tint total = TotalCheckpoints();\r\n\t\tint next = CheckpointManager.Instance?.NextCheckpoint ?? 0;\r\n\t\treturn next >= total;\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tif ( _triggered ) return;\r\n\r\n\t\tvar player = Scene.GetAllObjects( true )\r\n\t\t\t.FirstOrDefault( go => go.Tags.Has( \"player\" ) );\r\n\r\n\t\tif ( player == null ) return;\r\n\r\n\t\tfloat dist = Vector3.DistanceBetween( WorldPosition, player.WorldPosition );\r\n\r\n\t\tif ( dist >= DetectionRadius ) return;\r\n\r\n\t\tif ( IsFinishLine || IsLastCheckpoint )\r\n\t\t{\r\n\t\t\tif ( !AllCheckpointsHit() )\r\n\t\t\t{\r\n\t\t\t\tint remaining = TotalCheckpoints() - (CheckpointManager.Instance?.NextCheckpoint ?? 0);\r\n\t\t\t\tLog.Info( \"[Checkpoint] Finish blocked \ufffd \" + remaining + \" remaining\" );\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\telse if ( IsSequential )\r\n\t\t{\r\n\t\t\tint next = CheckpointManager.Instance?.NextCheckpoint ?? 0;\r\n\t\t\tif ( CheckpointIndex != next ) return;\r\n\t\t}\r\n\r\n\t\t_triggered = true;\r\n\r\n\t\tif ( IsFinishLine || IsLastCheckpoint )\r\n\t\t{\r\n\t\t\tLog.Info( \"[Checkpoint] Finished!\" );\r\n\t\t\tCheckpointManager.Instance?.OnFinishReached();\r\n\t\t\tOnFinishHit?.Invoke();\r\n\r\n\t\t\tvar cube = CheckpointManager.Instance?.ColorCube;\r\n\t\t\tif ( cube is not null )\r\n\t\t\t\tcube.Tint = Color.Green;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tLog.Info( \"[Checkpoint \" + CheckpointIndex + \"] Hit\" );\r\n\t\t\tCheckpointManager.Instance?.OnCheckpointReached( CheckpointIndex );\r\n\t\t\tOnCheckpointHit?.Invoke( CheckpointIndex );\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void ResetCheckpoint()\r\n\t{\r\n\t\t_triggered = false;\r\n\t}\r\n}\r\n"
        },
        {
            "Ident": "rwtrcsc.checkpointsystem",
            "Path": "CheckpointManager.cs",
            "FileName": "CheckpointManager.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 421921,
            "IsPrivate": false,
            "Code": "using Sandbox;\r\nusing System;\r\n\r\npublic sealed class CheckpointManager : Component\r\n{\r\n\tpublic static CheckpointManager Instance { get; private set; }\r\n\r\n\t[Property] public bool Sequential { get; set; } = true;\r\n\t[Property] public ModelRenderer ColorCube { get; set; }\r\n\t[Property] public CheckpointRing FinishLine { get; set; }\r\n\t[Property] public CheckpointRing LastCheckpoint { get; set; }\r\n\r\n\t// Events\r\n\tpublic Action<int> OnCheckpointReachedEvent;\r\n\tpublic Action OnFinishReachedEvent;\r\n\r\n\tpublic int NextCheckpoint { get; private set; } = 0;\r\n\r\n\tprotected override void OnAwake()\r\n\t{\r\n\t\tInstance = this;\r\n\r\n\t\tif ( FinishLine is not null )\r\n\t\t{\r\n\t\t\tFinishLine.IsFinishLine = true;\r\n\t\t\tFinishLine.IsLastCheckpoint = false;\r\n\t\t}\r\n\r\n\t\tif ( LastCheckpoint is not null )\r\n\t\t{\r\n\t\t\tLastCheckpoint.IsLastCheckpoint = true;\r\n\t\t\tLastCheckpoint.IsFinishLine = false;\r\n\t\t}\r\n\t}\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tNextCheckpoint = 0;\r\n\t}\r\n\r\n\tpublic void OnCheckpointReached( int index )\r\n\t{\r\n\t\tNextCheckpoint = index + 1;\r\n\t\tOnCheckpointReachedEvent?.Invoke( index );\r\n\t\tLog.Info( \"[CheckpointManager] Checkpoint \" + index + \" reached. Next: \" + NextCheckpoint );\r\n\t}\r\n\r\n\tpublic void OnFinishReached()\r\n\t{\r\n\t\tOnFinishReachedEvent?.Invoke();\r\n\t\tLog.Info( \"[CheckpointManager] Finish reached!\" );\r\n\t}\r\n\r\n\tpublic void ResetAll()\r\n\t{\r\n\t\tNextCheckpoint = 0;\r\n\t\tforeach ( var child in GameObject.Children )\r\n\t\t{\r\n\t\t\tvar cp = child.Components.Get<CheckpointRing>();\r\n\t\t\tcp?.ResetCheckpoint();\r\n\t\t}\r\n\t\tLog.Info( \"[CheckpointManager] Reset all checkpoints\" );\r\n\t}\r\n}\r\n"
        },
        {
            "Ident": "rwtrcsc.checkpointsystem",
            "Path": "CheckpointRing.cs",
            "FileName": "CheckpointRing.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 421921,
            "IsPrivate": false,
            "Code": "using Sandbox;\r\nusing System;\r\nusing System.Linq;\r\npublic sealed class CheckpointRing : Component\r\n{\r\n\t[Property] public int CheckpointIndex { get; set; } = 0;\r\n\t[Property] public bool IsFinishLine { get; set; } = false;\r\n\t[Property] public bool IsLastCheckpoint { get; set; } = false;\r\n\t[Property] public float DetectionRadius { get; set; } = 150f;\r\n\r\n\t// Events \ufffd anyone can listen to these\r\n\tpublic static Action<int> OnCheckpointHit;\r\n\tpublic static Action OnFinishHit;\r\n\r\n\tbool _triggered = false;\r\n\r\n\tbool IsSequential => CheckpointManager.Instance?.Sequential ?? true;\r\n\r\n\tint TotalCheckpoints()\r\n\t{\r\n\t\tif ( CheckpointManager.Instance == null ) return 0;\r\n\t\tint count = 0;\r\n\t\tforeach ( var child in CheckpointManager.Instance.GameObject.Children )\r\n\t\t{\r\n\t\t\tvar cp = child.Components.Get<CheckpointRing>();\r\n\t\t\tif ( cp is not null && !cp.IsFinishLine && !cp.IsLastCheckpoint )\r\n\t\t\t\tcount++;\r\n\t\t}\r\n\t\treturn count;\r\n\t}\r\n\r\n\tbool AllCheckpointsHit()\r\n\t{\r\n\t\tint total = TotalCheckpoints();\r\n\t\tint next = CheckpointManager.Instance?.NextCheckpoint ?? 0;\r\n\t\treturn next >= total;\r\n\t}\r\n\r\n\tprotected override void OnUpdate()\r\n\t{\r\n\t\tif ( _triggered ) return;\r\n\r\n\t\tvar player = Scene.GetAllObjects( true )\r\n\t\t\t.FirstOrDefault( go => go.Tags.Has( \"player\" ) );\r\n\r\n\t\tif ( player == null ) return;\r\n\r\n\t\tfloat dist = Vector3.DistanceBetween( WorldPosition, player.WorldPosition );\r\n\r\n\t\tif ( dist >= DetectionRadius ) return;\r\n\r\n\t\tif ( IsFinishLine || IsLastCheckpoint )\r\n\t\t{\r\n\t\t\tif ( !AllCheckpointsHit() )\r\n\t\t\t{\r\n\t\t\t\tint remaining = TotalCheckpoints() - (CheckpointManager.Instance?.NextCheckpoint ?? 0);\r\n\t\t\t\tLog.Info( \"[Checkpoint] Finish blocked \ufffd \" + remaining + \" remaining\" );\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\telse if ( IsSequential )\r\n\t\t{\r\n\t\t\tint next = CheckpointManager.Instance?.NextCheckpoint ?? 0;\r\n\t\t\tif ( CheckpointIndex != next ) return;\r\n\t\t}\r\n\r\n\t\t_triggered = true;\r\n\r\n\t\tif ( IsFinishLine || IsLastCheckpoint )\r\n\t\t{\r\n\t\t\tLog.Info( \"[Checkpoint] Finished!\" );\r\n\t\t\tCheckpointManager.Instance?.OnFinishReached();\r\n\t\t\tOnFinishHit?.Invoke();\r\n\r\n\t\t\tvar cube = CheckpointManager.Instance?.ColorCube;\r\n\t\t\tif ( cube is not null )\r\n\t\t\t\tcube.Tint = Color.Green;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tLog.Info( \"[Checkpoint \" + CheckpointIndex + \"] Hit\" );\r\n\t\t\tCheckpointManager.Instance?.OnCheckpointReached( CheckpointIndex );\r\n\t\t\tOnCheckpointHit?.Invoke( CheckpointIndex );\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void ResetCheckpoint()\r\n\t{\r\n\t\t_triggered = false;\r\n\t}\r\n}\r\n"
        },
        {
            "Ident": "rwtrcsc.checkpointsystem",
            "Path": "Code/CheckpointManager.cs",
            "FileName": "CheckpointManager.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 421921,
            "IsPrivate": false,
            "Code": "using Sandbox;\r\nusing System;\r\n\r\npublic sealed class CheckpointManager : Component\r\n{\r\n\tpublic static CheckpointManager Instance { get; private set; }\r\n\r\n\t[Property] public bool Sequential { get; set; } = true;\r\n\t[Property] public ModelRenderer ColorCube { get; set; }\r\n\t[Property] public CheckpointRing FinishLine { get; set; }\r\n\t[Property] public CheckpointRing LastCheckpoint { get; set; }\r\n\r\n\t// Events\r\n\tpublic Action<int> OnCheckpointReachedEvent;\r\n\tpublic Action OnFinishReachedEvent;\r\n\r\n\tpublic int NextCheckpoint { get; private set; } = 0;\r\n\r\n\tprotected override void OnAwake()\r\n\t{\r\n\t\tInstance = this;\r\n\r\n\t\tif ( FinishLine is not null )\r\n\t\t{\r\n\t\t\tFinishLine.IsFinishLine = true;\r\n\t\t\tFinishLine.IsLastCheckpoint = false;\r\n\t\t}\r\n\r\n\t\tif ( LastCheckpoint is not null )\r\n\t\t{\r\n\t\t\tLastCheckpoint.IsLastCheckpoint = true;\r\n\t\t\tLastCheckpoint.IsFinishLine = false;\r\n\t\t}\r\n\t}\r\n\r\n\tprotected override void OnStart()\r\n\t{\r\n\t\tNextCheckpoint = 0;\r\n\t}\r\n\r\n\tpublic void OnCheckpointReached( int index )\r\n\t{\r\n\t\tNextCheckpoint = index + 1;\r\n\t\tOnCheckpointReachedEvent?.Invoke( index );\r\n\t\tLog.Info( \"[CheckpointManager] Checkpoint \" + index + \" reached. Next: \" + NextCheckpoint );\r\n\t}\r\n\r\n\tpublic void OnFinishReached()\r\n\t{\r\n\t\tOnFinishReachedEvent?.Invoke();\r\n\t\tLog.Info( \"[CheckpointManager] Finish reached!\" );\r\n\t}\r\n\r\n\tpublic void ResetAll()\r\n\t{\r\n\t\tNextCheckpoint = 0;\r\n\t\tforeach ( var child in GameObject.Children )\r\n\t\t{\r\n\t\t\tvar cp = child.Components.Get<CheckpointRing>();\r\n\t\t\tcp?.ResetCheckpoint();\r\n\t\t}\r\n\t\tLog.Info( \"[CheckpointManager] Reset all checkpoints\" );\r\n\t}\r\n}\r\n"
        }
    ]
}