Adding new tower types and concept of tower deck
This commit is contained in:
parent
d1930a6b00
commit
117c77b4a8
16 changed files with 463 additions and 19 deletions
|
|
@ -71,12 +71,17 @@ namespace TD.Gameplay
|
|||
"worst-case 90/second (9 players × 10 placements/second).")]
|
||||
[SerializeField] private int requestsPerFrame = 3;
|
||||
|
||||
[Tooltip("Tower definitions available in this match, indexed by TowerTypeId. " +
|
||||
"Populate this with every TowerDefinition asset the current race roster " +
|
||||
"contains. Index 0 is reserved; valid IDs start at 1. " +
|
||||
"(Temporary: will be driven by RaceDefinition once Path E is complete.)")]
|
||||
[Tooltip("Tower CATALOG for this match, indexed by TowerTypeId. This is the full " +
|
||||
"pool of towers that can exist (be drafted) this match — NOT what any one " +
|
||||
"player can build. Per-player buildable sets live in PlayerTowerDeck. " +
|
||||
"Index 0 is reserved; valid IDs start at 1.")]
|
||||
[SerializeField] private TowerDefinition[] towerDefinitions = new TowerDefinition[0];
|
||||
|
||||
[Tooltip("The starter towers every player begins the match with. Each must also " +
|
||||
"appear in the catalog above (that's where its TowerTypeId comes from). " +
|
||||
"Resolved to TypeIds and granted to each PlayerTowerDeck at match start.")]
|
||||
[SerializeField] private TowerDefinition[] startingDeck = new TowerDefinition[0];
|
||||
|
||||
// ----- Internal request queue -------------------------------------
|
||||
|
||||
private struct PlacementRequest
|
||||
|
|
@ -188,6 +193,16 @@ namespace TD.Gameplay
|
|||
return;
|
||||
}
|
||||
|
||||
// Deck membership — the requesting player must have unlocked this tower.
|
||||
// Authoritative gate: a modded client cannot place a tower it hasn't drafted,
|
||||
// even though every tower exists in the shared catalog.
|
||||
var deck = PlayerTowerDeck.GetForClient(req.SenderClientId);
|
||||
if (deck == null || !deck.Contains(req.TowerTypeId))
|
||||
{
|
||||
Reject(req, PlacementRejectionReason.TowerNotInDeck);
|
||||
return;
|
||||
}
|
||||
|
||||
var loader = LevelLoader.Instance;
|
||||
if (loader == null || !loader.IsLoaded)
|
||||
{
|
||||
|
|
@ -652,6 +667,46 @@ namespace TD.Gameplay
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverse lookup: returns the TowerTypeId (catalog index) for a given
|
||||
/// definition asset, or false if it isn't in the catalog. Used to resolve the
|
||||
/// <see cref="startingDeck"/> assets into the TypeIds a <see cref="PlayerTowerDeck"/>
|
||||
/// stores.
|
||||
/// </summary>
|
||||
public bool TryGetTypeId(TowerDefinition def, out int typeId)
|
||||
{
|
||||
typeId = 0;
|
||||
if (def == null) return false;
|
||||
for (int i = 1; i < towerDefinitions.Length; i++)
|
||||
{
|
||||
if (towerDefinitions[i] == def) { typeId = i; return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the configured <see cref="startingDeck"/> assets to their catalog
|
||||
/// TypeIds. Logs an error for any starter tower missing from the catalog (it
|
||||
/// would have no TypeId and couldn't be placed). Called once at match start.
|
||||
/// </summary>
|
||||
public List<int> GetStartingDeckTypeIds()
|
||||
{
|
||||
var ids = new List<int>();
|
||||
if (startingDeck == null) return ids;
|
||||
|
||||
foreach (var def in startingDeck)
|
||||
{
|
||||
if (def == null) continue;
|
||||
if (TryGetTypeId(def, out int id))
|
||||
ids.Add(id);
|
||||
else
|
||||
Debug.LogError($"[TowerPlacementManager] Starting-deck tower '{def.name}' " +
|
||||
$"is not in the towerDefinitions catalog. Add it to the catalog " +
|
||||
$"so it has a TowerTypeId, or it can't be granted/placed.");
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private static PlayerSlot ClientIdToPlayerSlot(ulong clientId)
|
||||
=> PlayerMatchState.SlotForClient(clientId);
|
||||
|
||||
|
|
@ -707,6 +762,10 @@ namespace TD.Gameplay
|
|||
/// <summary>The requested tower type ID is not in the server's definition list.</summary>
|
||||
InvalidTowerType,
|
||||
|
||||
/// <summary>The requested tower exists in the catalog but the placing player has
|
||||
/// not unlocked it in their deck. Draft it first.</summary>
|
||||
TowerNotInDeck,
|
||||
|
||||
/// <summary>An unexpected server-side error occurred (e.g., LevelLoader not loaded,
|
||||
/// client not mapped to a PlayerSlot). Check server logs.</summary>
|
||||
ServerError,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue