simpler enemy split
This commit is contained in:
parent
11ad19992d
commit
0a70f36838
3 changed files with 43 additions and 22 deletions
|
|
@ -457,7 +457,8 @@ namespace TD.Gameplay
|
|||
|
||||
private void SpawnEnemy(EnemyDefinition def, Vector2Int spawnerTile, PlayerSlot ownerSlot,
|
||||
float xHalfExtent = 0f, float zHalfExtent = 0f, bool held = false,
|
||||
Direction facing = Direction.South)
|
||||
Direction facing = Direction.South, bool canRollAbility = true,
|
||||
float hpMultiplier = 1f, float visualScale = 1f)
|
||||
{
|
||||
if (def.EnemyPrefab == null)
|
||||
{
|
||||
|
|
@ -491,6 +492,12 @@ namespace TD.Gameplay
|
|||
spawnPos,
|
||||
Quaternion.Euler(0f, yaw, 0f));
|
||||
|
||||
// Scales the whole prefab hierarchy uniformly (used for split-on-death minions).
|
||||
// Relies on the enemy prefab's NetworkTransform syncing scale to clients — verify
|
||||
// that's enabled if a scaled spawn doesn't look smaller on remote peers.
|
||||
if (visualScale != 1f)
|
||||
go.transform.localScale *= visualScale;
|
||||
|
||||
var health = go.GetComponent<EnemyHealth>();
|
||||
var movement = go.GetComponent<EnemyMovement>();
|
||||
|
||||
|
|
@ -502,14 +509,16 @@ namespace TD.Gameplay
|
|||
return;
|
||||
}
|
||||
|
||||
health.InitializeServer(def.MaxHp, def.LivesCost, def.IsFlying, held);
|
||||
health.InitializeServer(def.MaxHp * hpMultiplier, def.LivesCost, def.IsFlying, held);
|
||||
movement.InitializeServer(def.MoveSpeed, spawnerTile, ownerSlot, def.IsFlying);
|
||||
|
||||
// Optional — only prefabs with an EnemyAbility component roll an ability. See
|
||||
// EnemyAbility's remarks for why on-death abilities aren't event-subscription driven.
|
||||
// canRollAbility is false for split-spawned minions (see ServerSpawnSplitEnemies) so
|
||||
// they can never chain into further splits or pick up any other ability.
|
||||
var ability = go.GetComponent<EnemyAbility>();
|
||||
if (ability != null)
|
||||
ability.InitializeServer(EnemyAbilityPool.Instance?.RollRandom());
|
||||
ability.InitializeServer(canRollAbility ? EnemyAbilityPool.Instance?.RollRandom() : null);
|
||||
|
||||
if (held) heldEnemies.Add(health);
|
||||
|
||||
|
|
@ -530,12 +539,19 @@ namespace TD.Gameplay
|
|||
/// position. Reuses <see cref="SpawnEnemy"/> so split children get the same
|
||||
/// <c>activeEnemyCount</c>/event-wiring bookkeeping as any other spawn.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Split-spawned minions never roll an ability of their own — they're always plain,
|
||||
/// so a split can't chain into further splits (or any other ability) regardless of
|
||||
/// which EnemyDefinition/prefab is used for <paramref name="def"/>.
|
||||
/// </remarks>
|
||||
public void ServerSpawnSplitEnemies(EnemyDefinition def, int count, Vector2Int atTile,
|
||||
PlayerSlot ownerSlot, float scatterRadius)
|
||||
PlayerSlot ownerSlot, float scatterRadius,
|
||||
float hpMultiplier = 1f, float visualScale = 1f)
|
||||
{
|
||||
if (!IsServer) return;
|
||||
for (int i = 0; i < count; i++)
|
||||
SpawnEnemy(def, atTile, ownerSlot, scatterRadius, scatterRadius);
|
||||
SpawnEnemy(def, atTile, ownerSlot, scatterRadius, scatterRadius, canRollAbility: false,
|
||||
hpMultiplier: hpMultiplier, visualScale: visualScale);
|
||||
}
|
||||
|
||||
// ----- Enemy event handlers (server-only) -------------------------
|
||||
|
|
@ -580,8 +596,6 @@ namespace TD.Gameplay
|
|||
// this kill's activeEnemyCount-- below, or a split on a wave's last enemy could let
|
||||
// CheckWaveComplete see activeEnemyCount hit 0 and advance the wave prematurely.
|
||||
var ability = health.GetComponent<EnemyAbility>();
|
||||
Debug.Log($"[WaveManager] HandleEnemyKilled: ability={(ability != null)}, " +
|
||||
$"definition={(ability != null ? ability.Definition?.name ?? "null" : "n/a")}");
|
||||
ability?.Definition?.ServerOnDeath(ability, health);
|
||||
|
||||
UnsubscribeEnemy(health);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue