Placeholder
using Sandbox;
using System;
using System.Threading.Tasks;
public sealed class BreakableDoor : Component, Component.ITriggerListener
{
[Property] public float MaxHealth { get; set; } = 2f;
[Sync] public float CurrentHealth { get; set; } = 2f;
[Sync] public bool IsBroken { get; set; } = false;
[Property] public string HitSound { get; set; } = "music/buttonhover.sound";
[Property] public string BreakSound { get; set; } = "music/buttonhover.sound";
private Collider _collider;
private ModelRenderer _modelRenderer;
[Sync] private TimeSince _timeSinceLastHit { get; set; } = 1f;
protected override void OnStart()
{
CurrentHealth = MaxHealth;
_collider = Components.Get<Collider>() ?? Components.GetInChildren<Collider>();
_modelRenderer = Components.Get<ModelRenderer>() ?? Components.GetInChildren<ModelRenderer>();
}
public void TakeHit( float amount = 1f )
{
if ( IsBroken ) return;
CurrentHealth -= amount;
_timeSinceLastHit = 0f;
if ( !string.IsNullOrEmpty( HitSound ) )
{
Sound.Play( HitSound, WorldPosition );
}
CameraJuice.Instance?.Shake( 12f, 3f );
if ( CurrentHealth <= 0f )
{
Break();
}
}
public void Break()
{
if ( IsBroken ) return;
IsBroken = true;
if ( !string.IsNullOrEmpty( BreakSound ) )
{
Sound.Play( BreakSound, WorldPosition );
}
CameraJuice.Instance?.Shake( 26f, 6f );
if ( _collider.IsValid() ) _collider.Enabled = false;
if ( _modelRenderer.IsValid() ) _modelRenderer.Enabled = false;
// Splinter burst effect
SpawnDebris();
Log.Info( $"[BreakableDoor] Door {GameObject.Name} was smashed open!" );
}
private void SpawnDebris()
{
for ( int i = 0; i < 3; i++ )
{
var debris = Scene.CreateObject();
debris.Name = "Door_Splinter";
debris.WorldPosition = WorldPosition + Vector3.Up * ( 20f * i );
debris.WorldScale = new Vector3( 0.4f, 0.4f, 0.4f );
var mr = debris.Components.Create<ModelRenderer>();
mr.Model = Model.Load( "models/sbox_props/wooden_crate/wooden_crate.vmdl" ) ?? Model.Load( "models/dev/box.vmdl" );
var col = debris.Components.Create<BoxCollider>();
col.Scale = new Vector3( 20f, 20f, 20f );
var rb = debris.Components.Create<Rigidbody>();
rb.Velocity = Vector3.Random * 250f + Vector3.Up * 150f;
_ = DestroyAfter( debris, 6f );
}
}
private async Task DestroyAfter( GameObject go, float delay )
{
await Task.DelaySeconds( delay );
if ( go.IsValid() ) go.Destroy();
}
public void OnTriggerEnter( Collider other )
{
if ( IsBroken || !other.GameObject.IsValid() ) return;
// If a Nextbot hits the door, smash it
var nextbot = other.GameObject.Root.Components.Get<NextbotAI>();
if ( nextbot.IsValid() && _timeSinceLastHit > 0.8f )
{
TakeHit( 1f );
}
}
}