Enemy subclass Tree, defines a stationary, non-attacking tree enemy with specific stats, loot/gib behavior, and simple physics damping. It customizes spawn scale, health, gib assets, and spawns particle effects and randomized gibs on death.
using System;
using Sandbox;
public class Tree : Enemy
{
public override EnemyType EnemyType => EnemyType.Tree;
public override float GetMaxHealth()
{
return 100f;
}
public override Vector3 SpawnScale => new Vector3( 1.2f );
public override bool CanHaveTarget => false;
public override bool CanAttack => false;
public override bool CanTurn => false;
public override bool CanBeBackstabbed => false;
public override bool CountsAsKill => false;
public override bool CanMove => false;
public override bool CanBeTargeted => false;
public override bool CanBeStunned => false;
public override string GibFolder => "wood";
public override float OverrideGibChance => 1f;
public override float HealthPackChanceMultiplier => 4f;
public override float ParticleYPosOverride => 0.65f;
protected override void OnStart()
{
base.OnStart();
CoinValueMin = 1;
CoinValueMax = 2;
CoinChance = 0.75f;
PushStrength = 20000f;
Weight = 8f;
if ( IsProxy )
return;
Deceleration = 4.5f;
}
protected override void OnUpdate()
{
base.OnUpdate();
//Gizmo.Draw.Color = Color.White;
//Gizmo.Draw.Text( $"{Health}", new global::Transform( WorldPosition ) );
if ( IsProxy || IsDying || IsSpawning )
return;
Velocity *= Math.Max( 1f - Time.Delta * Deceleration * Manager.Instance.GlobalFrictionModifier, 0f );
WorldPosition += (Vector3)Velocity * Time.Delta;
}
public override void Flinch( float time, Vector2 dir )
{
base.Flinch( time, dir );
ModelRenderer.LocalRotation = new Angles( Game.Random.Float( -3f, 3f ), 0f, Game.Random.Float( -3f, 3f ) );
}
public override void StopFlinching()
{
base.StopFlinching();
ModelRenderer.LocalRotation = new Angles( 0f, 0f, 0f );
}
protected override void HandleAnimation()
{
}
public override void SetAnim( string name, bool forceRestart = false )
{
}
protected override void DropLoot( Player player )
{
base.DropLoot( player );
//Barrel.DropLoot( player, Position2D );
}
//protected override void ResetMaterial()
//{
// ModelRenderer.ClearMaterialOverrides();
// ModelRenderer.RenderType = Sandbox.ModelRenderer.ShadowRenderType.On;
//}
protected override void SpawnGibs( Vector2 dir, float force, DamageType damageType )
{
//GameObject.Clone( "prefabs/effects/tree_debris.prefab", new CloneConfig { StartEnabled = true, Transform = new Transform( WorldPosition.WithZ( Game.Random.Float( 40f, 60f ) ), Rotation.Identity ) } );
GameObject.Clone( $"prefabs/effects/dark_cloud_explosion.prefab", new CloneConfig { StartEnabled = true, Transform = new Transform( WorldPosition.WithZ( Game.Random.Float( 20f, 40f ) ), Rotation.Identity ) } );
GameObject.Clone( $"prefabs/effects/dark_cloud_explosion.prefab", new CloneConfig { StartEnabled = true, Transform = new Transform( WorldPosition.WithZ( Game.Random.Float( 110f, 125f ) ), Rotation.Identity ) } );
SpawnGibs( "fragment", Game.Random.Int( 4, 8 ), force, damageType );
SpawnGibs( "fragment_2", Game.Random.Int( 4, 8 ), force, damageType );
SpawnGibs( "fragment_3", Game.Random.Int( 4, 8 ), force, damageType );
}
void SpawnGibs( string name, int count, float force, DamageType damageType )
{
for ( int i = 0; i < count; i++ )
{
var color = Color.Lerp( TintFullHp, TintZeroHp, Game.Random.Float( 0.25f, 1f ) );
color = Color.Lerp( color, Color.Black, Game.Random.Float( 0.3f, 0.7f ) );
SpawnGoreGib(
$"{GibFolder}/{name}",
localPos: new Vector3( Game.Random.Float( -10f, 10f ), Game.Random.Float( -10f, 10f ), Game.Random.Float( 20f, 65f ) ) + Vector3.Random * Game.Random.Float( 0f, 30f ),
localRot: Rotation.Random,
scaleMultiplier: Game.Random.Float( 1f, 1.5f ),
dir: Vector3.Random,
force: Game.Random.Float( 0.25f, 3f ),
color,
damageType
);
}
}
}