Major pipeline changes to map building, introducing 3player map, and adding Shared build mode to level authoring options

This commit is contained in:
Matt F 2026-08-04 22:50:33 -07:00
parent 749c9203de
commit 2b1aee3e03
37 changed files with 5418 additions and 30 deletions

View file

@ -355,6 +355,39 @@ namespace TD.Gameplay
return level.OwnerGrid[idx];
}
/// <summary>
/// This map's build-permission rule. <see cref="BuildAccess.OwnerOnly"/> for an unloaded
/// or unbaked level, which is the safe default (it can only ever reject more).
/// </summary>
public BuildAccess BuildAccess => level != null ? level.BuildAccess : BuildAccess.OwnerOnly;
/// <summary>
/// True if <paramref name="slot"/> is permitted to build on <paramref name="tile"/> under
/// this map's <see cref="BuildAccess"/> rule.
/// </summary>
/// <remarks>
/// <para>Permission ONLY — the caller still has to check <see cref="GetPlacement"/> and
/// <see cref="IsOccupied"/>. Keeping them separate is deliberate: each produces a different
/// <c>PlacementRejectionReason</c>, and collapsing them would cost the player a useful
/// message.</para>
///
/// <para>Both the client's ghost preview and the server's authoritative check call this, so
/// they cannot drift apart and show a white ghost that then gets rejected.</para>
///
/// <para>Under <see cref="BuildAccess.Shared"/> the tile must still belong to SOME player
/// zone. In practice every Buildable tile does, but stating it here keeps the method
/// meaningful on its own rather than relying on a caller's later check.</para>
/// </remarks>
public bool HasBuildPermission(Vector2Int tile, PlayerSlot slot)
{
if (slot == PlayerSlot.None) return false;
PlayerSlot owner = GetOwner(tile); // PlayerSlot.None when out of bounds
return BuildAccess == BuildAccess.Shared
? owner != PlayerSlot.None
: owner == slot;
}
/// <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