add wiring for offensive buffs
This commit is contained in:
parent
04ead32846
commit
3737ad517c
12 changed files with 338 additions and 3 deletions
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue