CombatManager static class for a game, contains damage application, healing for player and AI, and simple RNG helpers for crits and blocks. It applies magic shields, armor mitigation and shatter logic, prestige-based special effects (rebound, counter-strike, defiance), and logs events to GameManager and engine Log.
using System;
using System.Collections.Generic;
using Keyboard_Warriors_.Models;
using Keyboard_Warriors_.Systems; // Added to access your EventLog system
namespace Keyboard_Warriors_.Managers;
public static class CombatManager
{
private static Random rand = new Random();
public static void applyDamage( ref Player target, int damage )
{
Log.Info( $"[TRACE] Incoming Damage: {damage} | Current Armor: {target.defense} | Current HP: {target.hp}" );
if ( damage <= 0 ) return;
var manager = Sandbox.Game.ActiveScene.Get<GameManager>();
bool isPlayer = (manager != null && target == manager.LocalPlayer);
int prestige = manager != null ? manager.CurrentPrestige : 0;
if ( manager != null && isPlayer )
{
manager.HasPlayerTakenAnyDamage = true;
}
if ( target.isMagicBlocking )
{
if ( target.activeMagicShield == "Fortify" )
{
if ( isPlayer ) GameManager.AddPlayerLog( " Fortify blocks incoming damage!" );
else GameManager.AddAILog( " Fortify blocks incoming damage!" );
damage = 0;
}
else if ( target.activeMagicShield == "Magic Wall" )
{
if ( isPlayer ) GameManager.AddPlayerLog( " Magic Wall reduces incoming damage!" );
else GameManager.AddAILog( " Magic Wall reduces incoming damage!" );
damage /= 2;
Log.Info( $"[TRACE] After Magic Wall: {damage}" );
}
}
// ARMOR LOGIC
if ( target.defense > 0 && damage > 0 )
{
if ( manager != null && isPlayer && target.defense == 100 )
{
if ( manager.CurrentPrestige > 0 && target.defense < manager.LocalPlayer.maxDefense )
{
Log.Info( $"[FIX] Desync detected! Restoring Prestige {manager.CurrentPrestige} Armor from 100 to {manager.LocalPlayer.maxDefense}" );
target.defense = manager.LocalPlayer.maxDefense;
}
}
// Cache the target's current armor pool into a temporary calculation register
int workingTargetDefense = target.defense;
// 🚀 THE PERK INTERCEPT: Evaluate who the attacker is to apply armor-shredding parameters safely
bool isAttackerHuman = (manager != null && target == manager.AIEnemy);
if ( isAttackerHuman && manager.LocalPlayer.Perks != null && manager.LocalPlayer.Perks.IgnoresEnemyArmor )
{
workingTargetDefense = (int)(workingTargetDefense * 0.5f);
}
else if ( !isAttackerHuman && manager != null && manager.AIEnemy.Perks != null && manager.AIEnemy.Perks.IgnoresEnemyArmor )
{
workingTargetDefense = (int)(workingTargetDefense * 0.5f);
}
// 🛡️ LAYER 1: Inherent Armor Hardening (Armor takes 15% less damage inherently)
int hardenedArmorDamage = (int)(damage * 0.85f);
if ( hardenedArmorDamage < 1 && damage > 0 ) hardenedArmorDamage = 1;
// The incoming hit checks against the perk-mitigated defense window safely
if ( hardenedArmorDamage <= workingTargetDefense )
{
// The armor completely holds the impact! Deduct points from their true sheet
target.defense = System.Math.Max( 0, target.defense - hardenedArmorDamage );
damage = 0; // No damage spills over to the green HP bar
Log.Info( $"[TRACE] Armor hardened (15% reduction). Absorbed: {hardenedArmorDamage} | Remaining Armor: {target.defense}" );
if ( isPlayer )
{
GameManager.AddPlayerLog( $"🛡️ {target.name}'s armor hardened the impact! Shield absorbed {hardenedArmorDamage} damage." );
if ( prestige >= 6 )
{
// 20% base at P6, climbing +3% per prestige up to 32% at P10
int reboundChance = System.Math.Clamp( 20 + ((prestige - 6) * 3), 20, 35 );
if ( Random.Shared.Next( 100 ) < reboundChance )
{
// Calculate 50% of the blocked damage to punch back into the AI
int reboundDamage = (int)(hardenedArmorDamage * 0.5f);
if ( reboundDamage < 1 ) reboundDamage = 1;
// Flashes an emerald light bloom indicating success
GameManager.AddButtonFeedbackLog( $"⚡ KINETIC REBOUND! ({reboundChance}% Success) Your shields flip the energy signature, bouncing {reboundDamage} damage right back to the AI Overlord out-of-turn!", isSuccess: true );
// Punish the AI Overlord out of turn directly
if ( manager != null && manager.AIEnemy != null )
{
var aiRef = manager.AIEnemy;
aiRef.hp = System.Math.Max( 0, aiRef.hp - reboundDamage );
}
}
}
}
else GameManager.AddAILog( $"🛡️ {target.name}'s armor hardened the impact! Shield absorbed {hardenedArmorDamage} damage." );
}
else
{
// 🛡️ LAYER 2: Kinetic Shield-Gate (Armor completely shatters, overflow cut by 50%)
int rawDamageAbsorbedByPlating = (int)System.MathF.Ceiling( target.defense / 0.85f );
int rawOverflowDamage = damage - rawDamageAbsorbedByPlating;
if ( rawOverflowDamage < 0 ) rawOverflowDamage = 0;
// Spillover protection rule kicks in to protect skin and bones
int finalHPDamage = (int)(rawOverflowDamage * 0.5f);
if ( finalHPDamage < 1 && rawOverflowDamage > 0 ) finalHPDamage = 1;
Log.Info( $"[TRACE] Armor shattered! Raw overflow: {rawOverflowDamage} -> Mitigated HP damage: {finalHPDamage}" );
if ( isPlayer ) GameManager.AddPlayerLog( $"🚨 ARMOR SHATTERED! {target.name}'s metal plating crushed! Overflow damage cut in half: -{finalHPDamage} HP." );
else GameManager.AddAILog( $"🚨 ARMOR SHATTERED! {target.name}'s metal plating crushed! Overflow damage cut in half: -{finalHPDamage} HP." );
target.defense = 0; // Armor is entirely stripped
damage = finalHPDamage; // Pass the mitigated remainder down to the HP subtraction lines below!
}
}
// HP LOGIC
if ( damage > 0 )
{
prestige = manager != null ? manager.CurrentPrestige : 0;
if ( isPlayer && (manager?.CombatLogs?.Count > 0) && prestige >= 4 )
{
var latestLog = manager.CombatLogs[manager.CombatLogs.Count - 1];
if ( latestLog.AnimationClass == "flash-crit" )
{
// Base 15% chance at Prestige 4, climbing by +5% per level up to a hard 45% maximum cap at Prestige 10!
int critCounterChance = System.Math.Clamp( 15 + ((prestige - 4) * 5), 15, 45 );
bool isCounterTriggered = Random.Shared.Next( 100 ) < critCounterChance;
if ( isCounterTriggered )
{
int counterDamage = 5 + (prestige * 3); // Base 5 + 3 per prestige tier
GameManager.AddButtonFeedbackLog( $"👾 MALWARE COUNTER-STRIKE ACTIVE! ({critCounterChance}% Success) Your background scripts detected the critical breach and retaliated by blasting {counterDamage} virus damage back to the AI frame!", isSuccess: true );
if ( manager != null && manager.AIEnemy != null )
{
var aiRef = manager.AIEnemy;
aiRef.hp = System.Math.Max( 0, aiRef.hp - counterDamage );
}
}
else
{
Log.Info( $"[MALWARE TRAFFIC] Passive counter script failed the transmission check. Roll missed the {critCounterChance}% probability window." );
}
}
}
// --- BRANCH 1: PLAYER DEFIANCE CHECK ---
if ( isPlayer && (target.hp - damage) <= 0 && prestige >= 3 && !manager.HasDefiedDeathThisMatch )
{
// Player Scales: 10% base at P3, climbing up to a hard 25% max cap at P10
int playerChance = System.Math.Clamp( 10 + ((prestige - 3) * 2), 10, 25 );
if ( Random.Shared.Next( 100 ) < playerChance )
{
target.hp = 1;
manager.HasDefiedDeathThisMatch = true; // Consumed
// 🔵 PLAYER HIGHLIGHT: Emerald light bloom alerts your kernel recovery
GameManager.AddButtonFeedbackLog( $"🚨 PRESTIGE DEFIANCE MATRIX INJECTED! ({playerChance}% Success) Restored emergency player files! Clamped physical health grid at 1 HP!", isSuccess: true );
return;
}
}
// --- BRANCH 2: AI OVERLORD DEFIANCE CHECK ---
if ( !isPlayer && (target.hp - damage) <= 0 && prestige >= 3 && !manager.HasAIDefiedDeathThisMatch )
{
// AI Scales with its massive edge: 15% base at P3, climbing up to a 50% max cap at P10
int aiChance = System.Math.Clamp( 15 + ((prestige - 3) * 5), 15, 50 );
if ( Random.Shared.Next( 100 ) < aiChance )
{
target.hp = 1;
manager.HasAIDefiedDeathThisMatch = true; // Consumed
// 💥 FLASH CRIT ANNOTATION: Strobe flashes a malicious red emergency core restart alert!
GameManager.AddCriticalLog( $"🚨 WARNING: AI MAINFRAME BACKUP INJECTED! ({aiChance}% Success) Overlord executed emergency hardware reboot! AI hull locked at 1 HP!", isPlayer: false );
return;
}
}
target.hp -= damage;
Log.Info( $"[TRACE] HP reduced by {damage} | New HP: {target.hp}" );
if ( isPlayer ) GameManager.AddPlayerLog( $"{target.name} takes {damage} HP damage!" );
else GameManager.AddAILog( $"{target.name} takes {damage} HP damage!" );
}
if ( target.hp < 0 ) target.hp = 0;
}
public static void healPlayer( ref Player p, Weapon w )
{
var manager = Sandbox.Game.ActiveScene.Get<GameManager>();
int prestige = manager != null ? manager.CurrentPrestige : 0;
// Calculate prestige scaling: Base 10 + 3 extra HP per prestige level + weapon bonus
int scaledHealAmount = 10 + (prestige * 3) + w.healBonus;
p.hp += scaledHealAmount;
if ( manager != null && manager.LocalPlayer != null )
{
// Dynamic Cap: Clamp to your prestige-scaled maximum health
if ( p.hp > manager.LocalPlayer.maxHp )
{
p.hp = manager.LocalPlayer.maxHp;
}
}
else
{
if ( p.hp > 100 ) p.hp = 100;
}
Log.Info( $"[TRACE HEAL] Player healed for {scaledHealAmount}. Current HP: {p.hp}/{manager?.LocalPlayer?.maxHp ?? 100}" );
}
public static void healAI( ref Player ai, Weapon w )
{
var manager = Sandbox.Game.ActiveScene.Get<GameManager>();
int prestige = manager != null ? manager.CurrentPrestige : 0;
// Calculate prestige scaling: Base 10 + 4 extra HP per prestige level + weapon bonus
int scaledHealAmount = 10 + (prestige * 4) + w.healBonus;
ai.hp += scaledHealAmount;
if ( manager != null && manager.AIEnemy != null )
{
// Dynamic Cap: Clamp to the AI's prestige-scaled maximum health
if ( ai.hp > manager.AIEnemy.maxHp )
{
ai.hp = manager.AIEnemy.maxHp;
}
}
else
{
if ( ai.hp > 100 ) ai.hp = 100;
}
Log.Info( $"[TRACE HEAL] AI healed for {scaledHealAmount}. Current HP: {ai.hp}/{manager?.AIEnemy?.maxHp ?? 100}" );
}
public static bool isCriticalHit()
{
return rand.Next( 100 ) < 5;
}
public static bool attemptBlock( float modifier = 1.0f )
{
return rand.Next( 100 ) < (int)(50 * modifier);
}
}