Units/EnemyChallengeReceiver.cs
using System;
namespace PlanetMeat;
[Group( "Planet Meat - Units" ), Title( "Enemy Challenge Receiver" ), Icon( "addchart" )]
public sealed class EnemyChallengeReceiver : Component
{
const float HP_SCALE = 0.01f;
[Property, ReadOnly] public int MaxHp { get; private set; } = -1;
[Property, ReadOnly] public float MoveSpeed { get; private set; }
[Property, ReadOnly] public float SpeedMult { get; private set; }
[Property, ReadOnly] public float DamageMult { get; private set; }
public float MinAttackSpeed { get; private set; }
public float MaxAttackSpeed { get; private set; }
public int MinDamage { get; private set; }
public int MaxDamage { get; private set; }
private int GetDamage( double baseValue ) => Progressions.Intify( baseValue * DamageMult );
public void Bake()
{
var round = Agenda.Current.RoundNum;
var wave = Agenda.Current.WaveNum;
var slowRamp = Progressions.ExpSlow( 3 * (round - 1) + wave ) - 1;
SpeedMult = Difficulty.Current.GetMult( "EnemySpeed" );
if ( Components.Get<NavMeshAgent>() is NavMeshAgent navAgent )
MoveSpeed = (navAgent.MaxSpeed + (5.0f * round + 0.5f * wave)) * SpeedMult;
DamageMult = Difficulty.Current.GetMult( "EnemyDmg" );
var firstDmg = true;
foreach ( var w in Components.GetAll<IEnemyAttackReceiver>() )
{
var dmg = GetDamage( w.BaseDamage + slowRamp );
if ( firstDmg )
{
firstDmg = false;
MinDamage = MaxDamage = dmg;
}
else
{
MinDamage = Math.Min( MinDamage, dmg );
MaxDamage = Math.Max( MaxDamage, dmg );
}
}
var firstWep = true;
foreach ( var w in Components.GetAll<AutoWeapon>() )
{
var recharge = w.BaseRecharge * SpeedMult;
if ( firstWep )
{
firstWep = false;
MinAttackSpeed = MaxAttackSpeed = recharge;
}
else
{
MinAttackSpeed = Math.Min( MinAttackSpeed, recharge );
MaxAttackSpeed = Math.Max( MaxAttackSpeed, recharge );
}
}
if ( Components.Get<Targetable>() is Targetable targ )
MaxHp = Progressions.Intify( slowRamp * targ.BaseMaxHp * HP_SCALE * Difficulty.Current.GetMult( "EnemyHp" ) );
}
protected override void OnStart()
{
base.OnStart();
if ( MaxHp < 0 )
Bake();
var round = Agenda.Current.RoundNum;
var roundCrawl = Progressions.StairCrawlInt( round ) - 1;
if ( Components.Get<NavMeshAgent>() is NavMeshAgent navAgent )
{
var accelFraction = navAgent.Acceleration / navAgent.MaxSpeed;
navAgent.MaxSpeed = MoveSpeed;
navAgent.Acceleration = accelFraction * MoveSpeed;
}
foreach ( var w in Components.GetAll<IEnemyAttackReceiver>() )
w.BaseDamage = GetDamage( w.BaseDamage + roundCrawl );
foreach ( var w in Components.GetAll<AutoWeapon>() )
w.BaseRecharge *= SpeedMult;
if ( Components.Get<Targetable>() is Targetable targ )
targ.BaseMaxHp = MaxHp;
}
}