Data refactor
This commit is contained in:
@@ -78,11 +78,8 @@ namespace Minigames.FortFight.Core
|
|||||||
|
|
||||||
#region State
|
#region State
|
||||||
|
|
||||||
// Per-player turn-based cooldowns: projectileType -> playerIndex -> turnsRemaining
|
// Per-player ammunition state (encapsulates cooldowns, selection, usage)
|
||||||
private Dictionary<ProjectileType, Dictionary<int, int>> cooldowns = new Dictionary<ProjectileType, Dictionary<int, int>>();
|
private Dictionary<int, PlayerAmmoState> playerStates = new Dictionary<int, PlayerAmmoState>();
|
||||||
|
|
||||||
// Per-player selected ammo: playerIndex -> ProjectileType
|
|
||||||
private Dictionary<int, ProjectileType> selectedAmmoByPlayer = new Dictionary<int, ProjectileType>();
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -92,21 +89,21 @@ namespace Minigames.FortFight.Core
|
|||||||
{
|
{
|
||||||
base.OnManagedStart();
|
base.OnManagedStart();
|
||||||
|
|
||||||
// Initialize per-player turn-based cooldowns to 0 for all players
|
// Initialize player states
|
||||||
var configs = AvailableConfigs;
|
var configs = AvailableConfigs;
|
||||||
|
|
||||||
|
for (int playerIndex = 0; playerIndex < MaxPlayers; playerIndex++)
|
||||||
|
{
|
||||||
|
// Create player state with default ammo
|
||||||
|
playerStates[playerIndex] = new PlayerAmmoState(playerIndex, defaultProjectileType);
|
||||||
|
|
||||||
|
// Initialize cooldowns for all projectile types
|
||||||
foreach (var config in configs)
|
foreach (var config in configs)
|
||||||
{
|
{
|
||||||
cooldowns[config.projectileType] = new Dictionary<int, int>();
|
playerStates[playerIndex].InitializeCooldown(config.projectileType);
|
||||||
|
|
||||||
for (int playerIndex = 0; playerIndex < MaxPlayers; playerIndex++)
|
|
||||||
{
|
|
||||||
cooldowns[config.projectileType][playerIndex] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select default ammo for all players
|
// Select default ammo (triggers event)
|
||||||
for (int playerIndex = 0; playerIndex < MaxPlayers; playerIndex++)
|
|
||||||
{
|
|
||||||
SelectAmmo(defaultProjectileType, playerIndex);
|
SelectAmmo(defaultProjectileType, playerIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,21 +114,14 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void DecrementCooldowns(int playerIndex)
|
public void DecrementCooldowns(int playerIndex)
|
||||||
{
|
{
|
||||||
List<ProjectileType> completedCooldowns = new List<ProjectileType>();
|
if (!playerStates.ContainsKey(playerIndex))
|
||||||
List<ProjectileType> projectileTypes = new List<ProjectileType>(cooldowns.Keys);
|
{
|
||||||
|
Logging.Warning($"[AmmunitionManager] Player {playerIndex} state not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var type in projectileTypes)
|
// Decrement cooldowns and get completed types
|
||||||
{
|
List<ProjectileType> completedCooldowns = playerStates[playerIndex].DecrementCooldowns();
|
||||||
if (cooldowns[type].ContainsKey(playerIndex) && cooldowns[type][playerIndex] > 0)
|
|
||||||
{
|
|
||||||
cooldowns[type][playerIndex]--;
|
|
||||||
|
|
||||||
if (cooldowns[type][playerIndex] == 0)
|
|
||||||
{
|
|
||||||
completedCooldowns.Add(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire events for completed cooldowns
|
// Fire events for completed cooldowns
|
||||||
var settings = CachedSettings;
|
var settings = CachedSettings;
|
||||||
@@ -157,6 +147,12 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SelectAmmo(ProjectileType type, int playerIndex)
|
public bool SelectAmmo(ProjectileType type, int playerIndex)
|
||||||
{
|
{
|
||||||
|
if (!playerStates.ContainsKey(playerIndex))
|
||||||
|
{
|
||||||
|
Logging.Warning($"[AmmunitionManager] Player {playerIndex} state not found!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var settings = CachedSettings;
|
var settings = CachedSettings;
|
||||||
var config = settings?.GetProjectileConfig(type);
|
var config = settings?.GetProjectileConfig(type);
|
||||||
|
|
||||||
@@ -172,7 +168,7 @@ namespace Minigames.FortFight.Core
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedAmmoByPlayer[playerIndex] = type;
|
playerStates[playerIndex].SelectedAmmo = type;
|
||||||
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex} selected: {config.displayName}");
|
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex} selected: {config.displayName}");
|
||||||
|
|
||||||
OnAmmoSelected?.Invoke(type, playerIndex);
|
OnAmmoSelected?.Invoke(type, playerIndex);
|
||||||
@@ -184,9 +180,9 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ProjectileType GetSelectedAmmoType(int playerIndex)
|
public ProjectileType GetSelectedAmmoType(int playerIndex)
|
||||||
{
|
{
|
||||||
if (selectedAmmoByPlayer.ContainsKey(playerIndex))
|
if (playerStates.ContainsKey(playerIndex))
|
||||||
{
|
{
|
||||||
return selectedAmmoByPlayer[playerIndex];
|
return playerStates[playerIndex].SelectedAmmo;
|
||||||
}
|
}
|
||||||
return defaultProjectileType;
|
return defaultProjectileType;
|
||||||
}
|
}
|
||||||
@@ -201,21 +197,16 @@ namespace Minigames.FortFight.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if ammo is available for a specific player (not on cooldown)
|
/// Check if ammunition type is available for a specific player (not on cooldown)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsAmmoAvailable(ProjectileType type, int playerIndex)
|
public bool IsAmmoAvailable(ProjectileType type, int playerIndex)
|
||||||
{
|
{
|
||||||
if (!cooldowns.ContainsKey(type))
|
if (!playerStates.ContainsKey(playerIndex))
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cooldowns[type].ContainsKey(playerIndex))
|
return playerStates[playerIndex].IsAmmoAvailable(type);
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cooldowns[type][playerIndex] <= 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -223,17 +214,12 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int GetCooldownRemaining(ProjectileType type, int playerIndex)
|
public int GetCooldownRemaining(ProjectileType type, int playerIndex)
|
||||||
{
|
{
|
||||||
if (!cooldowns.ContainsKey(type))
|
if (!playerStates.ContainsKey(playerIndex))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cooldowns[type].ContainsKey(playerIndex))
|
return playerStates[playerIndex].GetCooldown(type);
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cooldowns[type][playerIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -245,6 +231,12 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void UseAmmo(ProjectileType type, int playerIndex)
|
public void UseAmmo(ProjectileType type, int playerIndex)
|
||||||
{
|
{
|
||||||
|
if (!playerStates.ContainsKey(playerIndex))
|
||||||
|
{
|
||||||
|
Logging.Warning($"[AmmunitionManager] Player {playerIndex} state not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var settings = CachedSettings;
|
var settings = CachedSettings;
|
||||||
var config = settings?.GetProjectileConfig(type);
|
var config = settings?.GetProjectileConfig(type);
|
||||||
|
|
||||||
@@ -254,19 +246,9 @@ namespace Minigames.FortFight.Core
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize cooldowns dict if needed
|
// Set cooldown and record usage
|
||||||
if (!cooldowns.ContainsKey(type))
|
playerStates[playerIndex].SetCooldown(type, config.cooldownTurns);
|
||||||
{
|
playerStates[playerIndex].RecordUsage(type);
|
||||||
cooldowns[type] = new Dictionary<int, int>();
|
|
||||||
|
|
||||||
for (int i = 0; i < MaxPlayers; i++)
|
|
||||||
{
|
|
||||||
cooldowns[type][i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start turn-based cooldown for this player
|
|
||||||
cooldowns[type][playerIndex] = config.cooldownTurns;
|
|
||||||
|
|
||||||
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex}: {config.displayName} used - cooldown: {config.cooldownTurns} turns");
|
if (showDebugLogs) Logging.Debug($"[AmmunitionManager] Player {playerIndex}: {config.displayName} used - cooldown: {config.cooldownTurns} turns");
|
||||||
|
|
||||||
@@ -282,14 +264,13 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void ResetAllCooldowns()
|
public void ResetAllCooldowns()
|
||||||
{
|
{
|
||||||
foreach (var projectileType in cooldowns.Keys)
|
var configs = AvailableConfigs;
|
||||||
|
|
||||||
|
foreach (var playerState in playerStates.Values)
|
||||||
{
|
{
|
||||||
for (int playerIndex = 0; playerIndex < MaxPlayers; playerIndex++)
|
foreach (var config in configs)
|
||||||
{
|
{
|
||||||
if (cooldowns[projectileType].ContainsKey(playerIndex))
|
playerState.SetCooldown(config.projectileType, 0);
|
||||||
{
|
|
||||||
cooldowns[projectileType][playerIndex] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
156
Assets/Scripts/Minigames/FortFight/Data/PlayerAmmoState.cs
Normal file
156
Assets/Scripts/Minigames/FortFight/Data/PlayerAmmoState.cs
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Minigames.FortFight.Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Encapsulates all ammunition state for a single player.
|
||||||
|
/// Tracks cooldowns, selection, and usage history per player.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class PlayerAmmoState
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public int PlayerIndex { get; private set; }
|
||||||
|
public ProjectileType SelectedAmmo { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region State
|
||||||
|
|
||||||
|
// Cooldowns per projectile type (turns remaining)
|
||||||
|
private Dictionary<ProjectileType, int> cooldowns;
|
||||||
|
|
||||||
|
// Optional: Track usage for statistics/analytics
|
||||||
|
private Dictionary<ProjectileType, int> usageCount;
|
||||||
|
private ProjectileType lastUsedProjectile;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public PlayerAmmoState(int playerIndex, ProjectileType defaultAmmo)
|
||||||
|
{
|
||||||
|
PlayerIndex = playerIndex;
|
||||||
|
SelectedAmmo = defaultAmmo;
|
||||||
|
cooldowns = new Dictionary<ProjectileType, int>();
|
||||||
|
usageCount = new Dictionary<ProjectileType, int>();
|
||||||
|
lastUsedProjectile = defaultAmmo;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Cooldown Management
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize cooldown for a specific projectile type.
|
||||||
|
/// </summary>
|
||||||
|
public void InitializeCooldown(ProjectileType type)
|
||||||
|
{
|
||||||
|
if (!cooldowns.ContainsKey(type))
|
||||||
|
{
|
||||||
|
cooldowns[type] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set cooldown for a specific projectile type.
|
||||||
|
/// </summary>
|
||||||
|
public void SetCooldown(ProjectileType type, int turns)
|
||||||
|
{
|
||||||
|
cooldowns[type] = turns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get remaining cooldown turns for a projectile type.
|
||||||
|
/// </summary>
|
||||||
|
public int GetCooldown(ProjectileType type)
|
||||||
|
{
|
||||||
|
return cooldowns.ContainsKey(type) ? cooldowns[type] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if projectile type is available (not on cooldown).
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAmmoAvailable(ProjectileType type)
|
||||||
|
{
|
||||||
|
return GetCooldown(type) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrement all cooldowns by 1 turn.
|
||||||
|
/// Returns list of projectile types that completed cooldown this turn.
|
||||||
|
/// </summary>
|
||||||
|
public List<ProjectileType> DecrementCooldowns()
|
||||||
|
{
|
||||||
|
List<ProjectileType> completedCooldowns = new List<ProjectileType>();
|
||||||
|
List<ProjectileType> types = new List<ProjectileType>(cooldowns.Keys);
|
||||||
|
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
if (cooldowns[type] > 0)
|
||||||
|
{
|
||||||
|
cooldowns[type]--;
|
||||||
|
|
||||||
|
if (cooldowns[type] == 0)
|
||||||
|
{
|
||||||
|
completedCooldowns.Add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return completedCooldowns;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Usage Tracking
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Record that a projectile type was used.
|
||||||
|
/// </summary>
|
||||||
|
public void RecordUsage(ProjectileType type)
|
||||||
|
{
|
||||||
|
lastUsedProjectile = type;
|
||||||
|
|
||||||
|
if (!usageCount.ContainsKey(type))
|
||||||
|
{
|
||||||
|
usageCount[type] = 0;
|
||||||
|
}
|
||||||
|
usageCount[type]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get usage count for a projectile type.
|
||||||
|
/// </summary>
|
||||||
|
public int GetUsageCount(ProjectileType type)
|
||||||
|
{
|
||||||
|
return usageCount.ContainsKey(type) ? usageCount[type] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the last projectile type used by this player.
|
||||||
|
/// </summary>
|
||||||
|
public ProjectileType LastUsedProjectile => lastUsedProjectile;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get total number of projectiles used by this player.
|
||||||
|
/// </summary>
|
||||||
|
public int TotalUsageCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int total = 0;
|
||||||
|
foreach (var count in usageCount.Values)
|
||||||
|
{
|
||||||
|
total += count;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fd7545bfc92d4096b53954bab9884b15
|
||||||
|
timeCreated: 1764797211
|
||||||
Reference in New Issue
Block a user