add wiring for offensive buffs

This commit is contained in:
Ian Woods 2026-06-02 23:40:00 -07:00
parent 04ead32846
commit 3737ad517c
12 changed files with 338 additions and 3 deletions

View file

@ -58,6 +58,11 @@ namespace TD.Combat
// Cached on OnNetworkSpawn — avoids GetComponent every Update.
private TowerInstance towerInstance;
// Lazily resolved on first attack — the owner's slot isn't guaranteed to be
// set at spawn time, so we defer the lookup until combat actually begins.
private PlayerBuffManager ownerBuffManager;
private bool buffManagerResolved;
// Shared OverlapSphere result buffer. 32 covers any realistic enemy
// density; size up if profiling reveals overflow.
private static readonly Collider[] s_overlapBuffer = new Collider[32];
@ -211,6 +216,25 @@ namespace TD.Combat
ClearTarget();
}
// ----- Buff multiplier lookup -------------------------------------
// Resolved lazily on the first attack because the owner slot NetworkVariable
// may not yet have replicated by the time OnNetworkSpawn runs.
private PlayerBuffManager GetOwnerBuffManager()
{
if (buffManagerResolved) return ownerBuffManager;
buffManagerResolved = true;
var slot = towerInstance.Owner;
if (slot == PlayerSlot.None) return null;
var matchState = PlayerMatchState.GetForSlot(slot);
if (matchState == null) return null;
ownerBuffManager = matchState.GetComponent<PlayerBuffManager>();
return ownerBuffManager;
}
// ----- Attack tick -------------------------------------------------
private void TickAttack(TowerDefinition def)
@ -218,7 +242,9 @@ namespace TD.Combat
attackCooldown -= Time.deltaTime;
if (attackCooldown > 0f) return;
attackCooldown = 1f / def.FireRate;
float effectiveFireRate = def.FireRate
* (GetOwnerBuffManager()?.GetMultiplier(BuffStat.AttackSpeed) ?? 1f);
attackCooldown = 1f / effectiveFireRate;
Fire(def);
}
@ -316,7 +342,9 @@ namespace TD.Combat
private void HitEnemy(TowerDefinition def, EnemyHealth target, PlayerSlot owner)
{
target.TakeDamage(def.Damage, def.DamageType, owner);
float effectiveDamage = def.Damage
* (GetOwnerBuffManager()?.GetMultiplier(BuffStat.Damage) ?? 1f);
target.TakeDamage(effectiveDamage, def.DamageType, owner);
ApplyStatusEffect(def, target, owner);
}
@ -340,6 +368,8 @@ namespace TD.Combat
// ----- Projectile spawning -----------------------------------------
// TODO this seems wacky. Why do we calculate effective damage twice? Are they both used?
// Spawn projectile is void. Should it return a projectile?
private void SpawnProjectile(TowerDefinition def, EnemyHealth target)
{
var go = Instantiate(def.ProjectilePrefab, transform.position, Quaternion.identity);
@ -354,9 +384,11 @@ namespace TD.Combat
return;
}
float effectiveDamage = def.Damage
* (GetOwnerBuffManager()?.GetMultiplier(BuffStat.Damage) ?? 1f);
proj.InitializeServer(
target,
def.Damage,
effectiveDamage,
def.DamageType,
def.TargetType,
def.SplashRadius,