Adding tons of new functionality
Decals, ghost textures, placement functionality, builder stub ins, a new camera system, and more.
This commit is contained in:
parent
56dc775c68
commit
a63cce53e2
54 changed files with 4817 additions and 238 deletions
|
|
@ -74,15 +74,30 @@ namespace TD.Gameplay
|
|||
|
||||
// The mutable walkability grid. Initialized from LevelData.WalkabilityGrid
|
||||
// and mutated by tower placement at runtime. Stays in lockstep with the
|
||||
// baked grid until towers are placed (none yet, since tower placement
|
||||
// isn't implemented).
|
||||
// baked grid until towers are placed.
|
||||
//
|
||||
// This is intentionally NOT exposed through a property yet -- consumers
|
||||
// will query through IsWalkable(Vector2Int) instead, hiding the array
|
||||
// indexing. When tower placement needs to mutate it, we'll expose a
|
||||
// SetWalkable method then. Easier to add than to take away.
|
||||
// Consumers query through IsWalkable(Vector2Int) and mutate through
|
||||
// SetWalkable(Vector2Int, bool), which hide the flat-array indexing.
|
||||
//
|
||||
// NOTE: This grid will move to MatchState when that NetworkBehaviour is
|
||||
// implemented, so server-authoritative mutation is co-located with other
|
||||
// match-wide state. For now it lives here because no consumer needed it
|
||||
// to live elsewhere.
|
||||
private bool[] runtimeWalkability;
|
||||
|
||||
// Per-tile tower occupancy. True when a tower's footprint covers this tile.
|
||||
// Distinct from runtimeWalkability because:
|
||||
// (a) spawner and leak-exit tiles are walkable but can never be occupied
|
||||
// by a tower — tracking them separately avoids ambiguity.
|
||||
// (b) the placement ghost needs to detect tile conflicts independently
|
||||
// of walkability (a tile is walkable until the tower is placed,
|
||||
// but the ghost should turn red as soon as a prior placement
|
||||
// reserves it).
|
||||
//
|
||||
// Initialized to all-false on Awake. Mutated via SetOccupied; queried
|
||||
// via IsOccupied. Will move to MatchState alongside runtimeWalkability.
|
||||
private bool[] runtimeOccupied;
|
||||
|
||||
// The buildable-plane GameObject we instantiated as our child.
|
||||
// Cached for inspector debugging and future destruction.
|
||||
private GameObject buildablePlaneGO;
|
||||
|
|
@ -113,6 +128,7 @@ namespace TD.Gameplay
|
|||
}
|
||||
|
||||
InitializeRuntimeWalkability();
|
||||
InitializeRuntimeOccupied();
|
||||
SpawnBuildablePlane();
|
||||
|
||||
IsLoaded = true;
|
||||
|
|
@ -190,6 +206,13 @@ namespace TD.Gameplay
|
|||
level.WalkabilityGrid, runtimeWalkability, level.WalkabilityGrid.Length);
|
||||
}
|
||||
|
||||
private void InitializeRuntimeOccupied()
|
||||
{
|
||||
// All tiles start unoccupied. bool[] default-initializes to false,
|
||||
// so Array.Clear is redundant but makes intent explicit.
|
||||
runtimeOccupied = new bool[level.WalkabilityGrid.Length];
|
||||
}
|
||||
|
||||
private void SpawnBuildablePlane()
|
||||
{
|
||||
// Compute the world-space center and size of the grid.
|
||||
|
|
@ -314,6 +337,59 @@ namespace TD.Gameplay
|
|||
return level.OwnerGrid[idx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if <paramref name="tile"/> is currently occupied by a placed tower footprint.
|
||||
/// Returns false for out-of-bounds tiles. Unlike <see cref="IsWalkable"/>, this grid
|
||||
/// starts all-false and only becomes true when a tower is successfully placed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The placement ghost uses this (alongside <see cref="GetPlacement"/> and
|
||||
/// <see cref="GetOwner"/>) to decide whether to render as valid (white) or invalid (red).
|
||||
/// The server uses it as part of the tile-availability check before path validation.
|
||||
/// </remarks>
|
||||
public bool IsOccupied(Vector2Int tile)
|
||||
{
|
||||
if (!TryFlatIndex(tile, out int idx)) return false;
|
||||
return runtimeOccupied[idx];
|
||||
}
|
||||
|
||||
// ----- Runtime mutators -------------------------------------------
|
||||
//
|
||||
// Called by TowerPlacementManager (server-side) when a tower placement
|
||||
// is accepted. Both mutators must be called for every tile in the tower's
|
||||
// footprint so the two grids stay in sync.
|
||||
//
|
||||
// These are not RPCs — LevelLoader is a plain MonoBehaviour, not a
|
||||
// NetworkBehaviour. The server calls these directly after authoritative
|
||||
// validation; clients learn about the change when the TowerInstance
|
||||
// NetworkObject spawns and its Start/OnNetworkSpawn stamps its own
|
||||
// footprint locally.
|
||||
|
||||
/// <summary>
|
||||
/// Sets the runtime walkability of <paramref name="tile"/>. Called by
|
||||
/// <c>TowerPlacementManager</c> on the server when a tower is accepted (pass
|
||||
/// <c>false</c>) and when a tower is sold/destroyed (pass <c>true</c>).
|
||||
/// No-ops silently for out-of-bounds tiles.
|
||||
/// </summary>
|
||||
public void SetWalkable(Vector2Int tile, bool walkable)
|
||||
{
|
||||
if (!TryFlatIndex(tile, out int idx)) return;
|
||||
runtimeWalkability[idx] = walkable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the runtime occupancy of <paramref name="tile"/>. Called alongside
|
||||
/// <see cref="SetWalkable"/> — always update both grids together so they
|
||||
/// stay in sync. Pass <c>true</c> when a tower is placed, <c>false</c> when
|
||||
/// it is sold or destroyed.
|
||||
/// No-ops silently for out-of-bounds tiles.
|
||||
/// </summary>
|
||||
public void SetOccupied(Vector2Int tile, bool occupied)
|
||||
{
|
||||
if (!TryFlatIndex(tile, out int idx)) return;
|
||||
runtimeOccupied[idx] = occupied;
|
||||
}
|
||||
|
||||
// Translates world-tile coordinates to a flat-array index, returning
|
||||
// false if the tile is out of bounds. Used by all query methods.
|
||||
private bool TryFlatIndex(Vector2Int tile, out int idx)
|
||||
|
|
@ -332,9 +408,9 @@ namespace TD.Gameplay
|
|||
// Gizmos run in both edit mode and play mode. In edit mode we use the
|
||||
// baked walkability/owner grids from the LevelData asset directly,
|
||||
// because runtimeWalkability hasn't been initialized yet. In play mode
|
||||
// we use runtimeWalkability so the visualization reflects any future
|
||||
// tower stamps. Owner and placement grids are immutable, so we read
|
||||
// them from the asset in both modes.
|
||||
// we use runtimeWalkability so the visualization reflects tower stamps.
|
||||
// Owner and placement grids are immutable, so we read them from the
|
||||
// asset in both modes.
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue