using System.Collections.Generic; using UnityEngine; namespace MazeGen { /// /// Skeleton for resolving combat between an agent and monsters in a room. /// This is NOT a full implementation - you'll need to expand this with: /// - Turn order calculation /// - Action resolution (attack, defend, ability) /// - Damage calculation /// - Status effects /// - Ability cooldowns /// /// This provides just the structure and basic helper functions. /// public class CombatResolver { public enum CombatOutcome { AgentVictory, AgentDefeated, Fleeing // Agent escaped before resolution } /// /// Simulate combat between an agent and the monsters in this room. /// Returns the outcome. You'll need to expand this significantly for a real system. /// public static CombatOutcome ResolveCombat(MazeAgent agent, MonsterEncounter encounter) { if (encounter == null || !encounter.HasLivingMonsters) return CombatOutcome.AgentVictory; // No fight needed // TODO: Implement full combat loop // 1. Build turn order from Speed stats var turnOrder = BuildTurnOrder(agent, encounter); // 2. Simulate turns until victory/defeat int maxRounds = 100; // Prevent infinite loops during development int round = 0; while (round < maxRounds && agent.CharacterSheet.Stats.IsAlive && encounter.HasLivingMonsters) { round++; // Execute each turn in order foreach (var turn in turnOrder) { if (turn.IsAgent) { ExecuteAgentTurn(agent, encounter); } else { ExecuteMonsterTurn(turn.MonsterIndex, agent, encounter); } // Check win conditions each turn if (!agent.CharacterSheet.Stats.IsAlive) return CombatOutcome.AgentDefeated; if (!encounter.HasLivingMonsters) return CombatOutcome.AgentVictory; } } if (agent.CharacterSheet.Stats.IsAlive && !encounter.HasLivingMonsters) return CombatOutcome.AgentVictory; return CombatOutcome.AgentDefeated; } /// /// Determine turn order based on Speed stats. /// Higher speed = earlier in turn order. /// private static List<(bool IsAgent, int MonsterIndex)> BuildTurnOrder(MazeAgent agent, MonsterEncounter encounter) { var order = new List<(bool, int)>(); // Agent's speed float agentInitiative = agent.CharacterSheet.GetEffectiveSpeed(); order.Add((true, -1)); // IsAgent=true, MonsterIndex unused // Each monster's speed for (int i = 0; i < encounter.Monsters.Count; i++) { if (!encounter.Monsters[i].IsDefeated) { float monsterInitiative = encounter.Monsters[i].CharacterSheet.GetEffectiveSpeed(); order.Add((false, i)); } } // Sort by initiative (higher = first) // TODO: Implement proper sorting by speed // order.Sort((a, b) => ...) return order; } /// /// Execute the agent's turn. Pick a target and attack. /// This is a stub - implement your action selection here. /// private static void ExecuteAgentTurn(MazeAgent agent, MonsterEncounter encounter) { // TODO: Implement agent decision (which monster to target, what ability to use) // For now, just attack the first alive monster for (int i = 0; i < encounter.Monsters.Count; i++) { if (!encounter.Monsters[i].IsDefeated) { AttackMonster(agent, encounter, i); break; } } } /// /// Execute one monster's turn. They attack the agent. /// This is a stub - add AI/decision logic here. /// private static void ExecuteMonsterTurn(int monsterIndex, MazeAgent agent, MonsterEncounter encounter) { if (monsterIndex < 0 || monsterIndex >= encounter.Monsters.Count) return; var monster = encounter.Monsters[monsterIndex]; if (monster.IsDefeated) return; // TODO: Implement monster AI (target selection, ability choice, etc.) // For now, just attack the agent AttackAgent(monster, agent); } /// /// Calculate and apply damage when agent attacks a monster. /// Stub - expand with damage types, abilities, modifiers, etc. /// private static void AttackMonster(MazeAgent agent, MonsterEncounter encounter, int targetIndex) { var target = encounter.Monsters[targetIndex]; // Simple attack: agent's attack vs target's defense float baseDamage = agent.CharacterSheet.GetEffectiveAttack(); float damage = target.CharacterSheet.Stats.CalculateDamageReduction(baseDamage); Debug.Log($"{agent.Name} attacks {target.Template.MonsterName} for {damage} damage"); target.CharacterSheet.Stats.TakeDamage(damage); if (target.IsDefeated) { Debug.Log($"{target.Template.MonsterName} defeated!"); // TODO: Award loot to agent } } /// /// Calculate and apply damage when monster attacks agent. /// Stub - expand similarly to AttackMonster. /// private static void AttackAgent(MonsterEncounter.MonsterInstance attacker, MazeAgent target) { float baseDamage = attacker.CharacterSheet.GetEffectiveAttack(); float damage = target.CharacterSheet.Stats.CalculateDamageReduction(baseDamage); Debug.Log($"{attacker.Template.MonsterName} attacks {target.Name} for {damage} damage"); target.CharacterSheet.Stats.TakeDamage(damage); if (!target.CharacterSheet.Stats.IsAlive) { Debug.Log($"{target.Name} defeated!"); target.Die(); } } /// /// Award loot from a defeated monster to the agent. /// Stub - implement inventory/pickup logic. /// private static void AwardLoot(MonsterEncounter.MonsterInstance monster, MazeAgent agent) { // TODO: Implement loot pickup // var loot = monster.Template.GetRandomLoot(); // if (loot != null) // agent.CharacterSheet.AddToInventory(loot); } } }