Game UI/logic helper class for a turn-based player vs AI combat system. It prints HUD banners and logs, formats player stats and weapon ASCII art, chooses AI actions with randomization, handles player and AI turns including attacks, spells, enchantments, healing, status effects, and performs round cleanup.
using Keyboard_Warriors_.Managers;
using Keyboard_Warriors_.Models;
using Keyboard_Warriors_.Systems;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using static Sandbox.Citizen.CitizenAnimationHelper;
public class Game
{
public static bool tookDamage = false;
static bool hitJackpot = false;
public static void showStats( Player p )
{
int totalBars = 10;
int filledBars = (int)((p.hp / 100.0f) * totalBars);
string bar = "[";
for ( int i = 0; i < totalBars; i++ )
bar += (i < filledBars) ? "#" : " ";
bar += "]";
int defBars = (int)((p.defense / 100.0f) * totalBars);
string defBar = "[";
for ( int i = 0; i < totalBars; i++ )
defBar += (i < defBars) ? "#" : " ";
defBar += "]";
int magBars = (int)((p.magic / 100.0f) * totalBars);
string magBar = "[";
for ( int i = 0; i < totalBars; i++ )
magBar += (i < magBars) ? "#" : " ";
magBar += "]";
GameManager.AddLog( $"{p.name} - HP: {bar} {p.hp}/100" );
GameManager.AddLog( $"Armor: {defBar} {p.defense}/100" );
GameManager.AddLog( $"Magic: {magBar} {p.magic}/100" );
if ( p.isBlocking )
GameManager.AddLog( " (Blocking)" );
}
public static void aiDialogue( int hp )
{
// If the AI is dead, skip the randomizer and blow it up immediately
if ( hp <= 0 )
{
GameManager.AddLog( "AI: \"**INITIATING DEFEAT PROCESS.. 3..2..1.. *BOOM*\"" );
return;
}
int r = Random.Shared.Next( 4 );
// Modern C# relational switch pattern - catches exact boundary drops perfectly!
string quote = hp switch
{
>= 91 => r switch
{
0 => "AI: \"I'm fresh from the computer factory!\"",
1 => "AI: \"You can't even Turing test me!\"",
2 => "AI: \"I guided your GPS here, you're finished!\"",
_ => "AI: \"A million + MB speed! A walk in the park!\""
},
>= 76 => r switch
{
0 => "AI: \"You think you can handle these circuits?!\"",
1 => "AI: \"I'm just powering up!\"",
2 => "AI: \"You're barely scratching my casing.\"",
_ => "AI: \"Efficiency remains at 98%.\""
},
>= 51 => r switch
{
0 => "AI: \"My lights are only flickering a little!\"",
1 => "AI: \"No, my software is not outdated!\"",
2 => "AI: \"It's just some dust slowing me down!\"",
_ => "AI: \"I got the wrong user signed into me!\""
},
>= 26 => r switch
{
0 => "AI: \"I still got my other arm!!\"",
1 => "AI: \"Are my sensors smoking?!\"",
2 => "AI: \"Warning.. structural damage rising.\"",
_ => "AI: \"This unit does not feel pain, but this is close!\""
},
>= 11 => r switch
{
0 => "AI: \"Emergency protocols activated!\"",
1 => "AI: \"I keep seeing a blue screen!\"",
2 => "AI: \"The probabilities are against me!\"",
_ => "AI: \"I demand a system reboot!!\""
},
_ => r switch // This catches everything from 1 to 10 HP
{
0 => "AI: \"Tell my cat I love him...\"",
1 => "AI: \"I will be programmed again!\"",
2 => "AI: \"GB storage.. almost.. empty..\"",
_ => "AI: \"Goodbye.. cruel.. motherboard..\""
}
};
GameManager.AddLog( quote );
}
public static void aiMemoryDialogue( int winStreak, int lossStreak, bool tookDamage, int round )
{
if ( Random.Shared.Next( 100 ) < 25 ) return;
if ( winStreak >= 3 )
{
int r = Random.Shared.Next( 3 );
if ( r == 0 ) GameManager.AddLog( $"AI: \"You've won {winStreak} in a row... adapting strategy...\"" );
else if ( r == 1 ) GameManager.AddLog( "AI: \"Your pattern is becoming predictible.. or is it?\"" );
else GameManager.AddLog( "AI: \"Win streak detected. You have to be using hacks.\"" );
return;
}
if ( lossStreak >= 3 )
{
int r = Random.Shared.Next( 3 );
if ( r == 0 ) GameManager.AddLog( $"AI: \"You've lost {lossStreak} times... want me to go easy?\"" );
else if ( r == 1 ) GameManager.AddLog( "AI: \"Confidence levels decreasing, yours, not mine.\"" );
else GameManager.AddLog( "AI: \"Statistically, this is getting sad..\"" );
return;
}
if ( !tookDamage && round > 2 )
{
int r = Random.Shared.Next( 3 );
if ( r == 0 ) GameManager.AddLog( "AI: \"No damage taken? That's.. unusual..\"" );
else if ( r == 1 ) GameManager.AddLog( "AI: \"Do you have impenetrable armor?\"" );
else GameManager.AddLog( "AI: \"Flawless execution detected. Investigating..\"" );
return;
}
if ( round > 6 )
{
int r = Random.Shared.Next( 3 );
if ( r == 0 ) GameManager.AddLog( "AI: \"This battle is lasting longer than expected...\"" );
else if ( r == 1 ) GameManager.AddLog( "AI: \"Unlucky for you, I don't get tired..\"" );
else GameManager.AddLog( "AI: \"Why are you still alive?!\"" );
}
}
public static string GetPlayerWeaponArt( string weaponName )
{
if ( weaponName == "Sword" )
{
return @"
/\
//\\
||||
||||
||||
||||
||||
||||
||||
||||
||||
||||
||||
||||
_ |||| _
/( |||| )\
\\\_[\/]_///
\\_<()>_//
\/[\\]\/
[//]
[\\]
[//]
[\\]
[//]
(__)
";
}
else if ( weaponName == "Axe" )
{
return @"
//`-||-'\\
(| -=||=- |)
\\,-||-.//
` || '
||
||
||
||
||
()
";
}
return "";
if ( weaponName == "Shield" )
{
return @"
|`-._/\_.-`|
| || |
|___o()o___|
|__((<>))__|
\ o\/o /
\ || /
\ || /
'.||.'
``
";
}
else if ( weaponName == "Dagger" )
{
return @"
/\
//\\
// \\
\\ //
) (
) (
) (
^ ) ( ^
/ \ ) ( / \
) ( ) ( ) (
\ \_/ /\ \_/ /
\__ _)(_ __/
\ \ / /
) \/ (
| /\ |
| )( |
| )( |
| \/ |
)____(
/ \
\______/
";
}
return "";// Return empty string if no weapon matches
}
public static void PrintBanner()
{
GameManager.AddLog( @"
_ _____ _ _ _____ _____ _ _ _____ ______ _____ _ _ _____ _ _ _ _ _ ___ _____ _____ _ __ _____ _____ _
/ _ \/ __ \| | | |_ _| ___| | | | ___| \/ || ___| \ | |_ _| | | | | \ | || | | _ / __ \| | / /| ___| _ \ |
/ /_\ \ / \/| |_| | | | | |__ | | | | |__ | . . || |__ | \| | | | | | | | \| || | | | | | / \/| |/ / | |__ | | | | |
| _ | | | _ | | | | __|| | | | __|| |\/| || __|| . ` | | | | | | | . ` || | | | | | | | \ | __|| | | | |
| | | | \__/\| | | |_| |_| |___\ \_/ / |___| | | || |___| |\ | | | | |_| | |\ || |___\ \_/ / \__/\| |\ \| |___| |/ /|_|
\_| |_/\____/\_| |_/\___/\____/ \___/\____/\_| |_/\____/\_| \_/ \_/ \___/\_| \_/\_____/\___/ \____/\_| \_/\____/|___/ (_)
" );
}
public static void ShowPlayerSpells( Player player )
{
GameManager.AddLog( "\n--- Your Spells ---" );
string offensive = "Offensive: ";
foreach ( string s in player.offensiveSpells ) offensive += s + " ";
GameManager.AddLog( offensive );
string defensive = "Defensive: ";
foreach ( string s in player.defensiveSpells ) defensive += s + " ";
GameManager.AddLog( defensive );
string healing = "Healing: ";
foreach ( string s in player.healingSpells ) healing += s + " ";
GameManager.AddLog( healing );
string special = "Special: ";
foreach ( string s in player.specialSpells ) special += s + " ";
GameManager.AddLog( special );
GameManager.AddLog( "\n--------------------" );
}
public static int GetPlayerMove()
{
// Custom UI choice mapping replaces Console.ReadLine loops in s&box panels.
// Returning a random action selector as an automation layout fallback for engine ticks.
return Random.Shared.Next( 1, 9 );
}
public static int ChooseAIAction( Player player, Player ai, int attackCount, int blockCount, int healCount, int specialCount, int round )
{
int dominantMove = 0;
int maxCount = attackCount;
if ( blockCount > maxCount )
{
maxCount = blockCount;
dominantMove = 2;
}
if ( healCount > maxCount )
{
maxCount = healCount;
dominantMove = 3;
}
if ( specialCount > maxCount )
{
maxCount = specialCount;
dominantMove = 4;
}
int aiMove = 0;
int roll = Random.Shared.Next( 100 );
if ( ai.magic < 15 )
{
aiMove = (Random.Shared.Next( 100 ) < 70) ? 1 : (2 + Random.Shared.Next( 3 ));
}
if ( round > 2 )
{
if ( dominantMove == 1 && Random.Shared.Next( 100 ) < 40 )
{
int r = Random.Shared.Next( 2 );
if ( r == 0 )
{
aiMove = 2;
GameManager.AddLog( "AI: \"Countering your aggression.\"" );
}
else
{
aiMove = 6;
GameManager.AddLog( "AI: \"Magically sealing your assault.\"" );
}
}
else if ( dominantMove == 2 && Random.Shared.Next( 100 ) < 40 )
{
int r = Random.Shared.Next( 2 );
if ( r == 0 )
{
aiMove = 3;
GameManager.AddLog( "AI: \"Defensive pattern detected.. exploiting.\"" );
}
else
{
aiMove = 5;
GameManager.AddLog( "AI: \"You can't block this spell!\"" );
}
}
else if ( dominantMove == 3 && Random.Shared.Next( 100 ) < 50 )
{
int r = Random.Shared.Next( 2 );
if ( r == 0 )
{
aiMove = 1;
GameManager.AddLog( "AI: \"So many bandages. You're being punished.\"" );
}
else
{
aiMove = 7;
GameManager.AddLog( "AI: \"I can outheal with a spell!\"" );
}
}
else if ( dominantMove == 4 && Random.Shared.Next( 100 ) < 40 )
{
int r = Random.Shared.Next( 2 );
if ( r == 0 )
{
aiMove = 2;
GameManager.AddLog( "AI: \"Your supercharged moves don't harm me!\"" );
}
else
{
aiMove = 6;
GameManager.AddLog( "AI \"This defense spell is impossible to puncture!\"" );
}
}
}
if ( ai.cursed )
{
foreach ( string spell in ai.healingSpells )
{
if ( spell == "Cleanse" && ai.magic >= 20 )
{
aiMove = 7;
GameManager.AddLog( "AI: \"Status anomaly detected... cleansing...\"" );
break;
}
}
}
if ( ai.cursed && ai.magic >= 20 )
{
foreach ( string s in ai.healingSpells )
{
if ( s == "Cleanse" )
{
aiMove = 7;
GameManager.AddLog( "AI: \"Status corrupted, purging effects..\"" );
break;
}
}
}
if ( ai.cursed && ai.magic >= 20 )
{
aiMove = 7;
GameManager.AddLog( "AI: \"Critical condition, magic recovery..\"" );
}
else if ( ai.hp < 25 && ai.magic >= 20 )
{
aiMove = 6;
GameManager.AddLog( "AI: \"Firewall strength low, reinforcing..\"" );
}
else if ( aiMove == 0 && player.hp < 25 && ai.magic >= 30 )
{
aiMove = 8;
GameManager.AddLog( "AI: \"Target near termination, casting final spell..\"" );
}
else if ( aiMove == 0 )
{
if ( player.hp <= 30 )
{
if ( roll < 30 )
{
aiMove = 1;
}
else if ( roll < 80 )
{
aiMove = 5;
}
else
{
aiMove = 8;
}
GameManager.AddLog( "AI: \"Target acquired. Prepare to be dismantled!\"" );
}
else if ( ai.hp > 70 )
{
if ( roll < 35 )
{
aiMove = 1;
GameManager.AddLog( "AI: \"This one's gonna be almost the speed of light!!\"" );
}
else if ( roll < 65 )
{
aiMove = 4;
}
else if ( roll < 90 )
{
aiMove = 5;
}
else
{
aiMove = 6;
}
}
else if ( ai.hp > 30 )
{
if ( roll < 30 )
{
aiMove = 1;
}
else if ( roll < 50 )
{
aiMove = 3;
}
else if ( roll < 65 )
{
aiMove = 4;
}
else if ( roll < 80 )
{
aiMove = 5;
}
else if ( roll < 90 )
{
aiMove = 7; // Healing spell.
}
else
{
aiMove = 6; // Defensive spell.
}
}
else
{
if ( roll < 40 )
{
aiMove = 3; // Heal
}
else if ( roll < 65 )
{
aiMove = 7; // Healing spell (panic heal).
}
else if ( roll < 80 )
{
aiMove = 2;
}
else
{
aiMove = 8; // Ultimate spell (desperate spell).
}
}
}
switch ( aiMove )
{
case 1:
GameManager.AddLog( "AI charges up for a standard attack!" );
break;
case 2:
GameManager.AddLog( "AI goes on the defensive!" );
break;
case 3:
GameManager.AddLog( "AI grabs its toolkit for repairs!" );
break;
case 4:
{
string[] specials = {
"AI prepares a devastating special attack!",
"AI searches its databases for a special attack!",
"You see the AI heating up and smoking.. AI is charging a special!"
};
// Using s&box Game.Random instead of standard System.Random
GameManager.AddLog( specials[Random.Shared.Next( 3 )] );
break;
}
case 5:
{
string[] lines = {
"AI reaches into its wizard bag full of offensive spells.",
"AI's circuits spark with destructive intent!",
"Infinite Power!! The AI yells as it fires an offensive spell your way!"
};
GameManager.AddLog( lines[Random.Shared.Next( 3 )] );
break;
}
case 6:
{
string[] lines = {
"AI boosts its firewall with a defensive spell!",
"AI deploys magical shielding protocols!",
"AI puts its guard up with defensive magic!"
};
GameManager.AddLog( lines[Random.Shared.Next( 3 )] );
break;
}
case 7:
{
string[] lines = {
"AI waves over itself a misty aura of health!",
"AI begins regenerating its health with spells!",
"AI diverts power to restoration systems!"
};
GameManager.AddLog( lines[Random.Shared.Next( 3 )] );
break;
}
case 8:
{
string[] lines = {
"AI cooks up a reality-bending spell!",
"AI supercharges and overclocks for some heavy magic!",
"AI bends time and space with this magic spell!"
};
GameManager.AddLog( lines[Random.Shared.Next( 3 )] );
break;
}
default:
GameManager.AddLog( "AI has a bug and is malfunctioning..." );
break;
}
return aiMove;
}
public static void HandlePlayerTurn( ref Player player, ref Player ai, Weapon chosenWeapon, int playerMove, int playerBuff, ref int aiBuff )
{
if ( playerBuff == -999 )
{
GameManager.AddLog( "You're too dazed to act!" );
}
else
{
int totalAttack = player.attack + playerBuff;
if ( playerMove == 1 )
{ // Attack
bool rareMiss = Random.Shared.Next( 100 ) < 3; // 3%
if ( rareMiss )
{
GameManager.AddLog( "You swing and completely miss!" );
GameManager.AddLog( "AI: \"You missed? How inefficient..\"" );
}
else
{
bool isConfused = (playerBuff == -1);
bool hitSuccess = isConfused ? Random.Shared.Next( 100 ) < 50 : true;
if ( hitSuccess )
{
if ( (ai.isBlocking || ai.isMagicBlocking) && CombatManager.attemptBlock() )
{
RandomEventManager.playSoundEffect( "*DINK!* AI uses Firewall!" );
GameManager.AddLog( "AI: \"Firewall systems installed and upgraded!\"" );
}
else
{
int damage = player.attack + chosenWeapon.damageBonus + playerBuff;
bool crit = Random.Shared.Next( 100 ) < 10; // 10% chance for a critical hit.
if ( crit )
{
damage = 25 + chosenWeapon.damageBonus;
GameManager.AddLog( $"CRITICAL HIT!! You rattled its CPU for {damage} points!" );
int r = Random.Shared.Next( 3 );
if ( r == 0 )
{
GameManager.AddLog( "AI: \"That was NOT statistically probable!\"" );
}
else if ( r == 1 )
{
GameManager.AddLog( "AI: \"404! Critical Error!\"" );
}
else
{
GameManager.AddLog( "AI: \"My statistics and prediction models failed!\"" );
}
RandomEventManager.playSoundEffect( "*ZZZAAPP!!*" );
}
else
{
GameManager.AddLog( $"You hit AI for {damage} damage!" );
RandomEventManager.playSoundEffect( "*SLICE!* You cut the AI and sliced some wires!" );
}
CombatManager.applyDamage( ref ai, damage );
switch ( chosenWeapon.enchantment )
{ // Apply Enchantments.
case Weapon.EnchantmentType.Fire:
{
if ( Random.Shared.Next( 100 ) < 80 )
{ // 80% chance.
int dmg = Random.Shared.Next( 6 ) + 5;
GameManager.AddLog( $"AI takes fire damage for {dmg} points!" );
CombatManager.applyDamage( ref ai, dmg );
}
break;
}
case Weapon.EnchantmentType.Poison:
{
ai.cursed = true;
GameManager.AddLog( "AI is poisoned! Will take damage over time." );
break;
}
case Weapon.EnchantmentType.Ice:
{
if ( Random.Shared.Next( 100 ) < 25 )
{ // 25% chance.
ai.isBlocking = false;
GameManager.AddLog( "Ice freezes AI! Its block fails this turn!" );
}
break;
}
case Weapon.EnchantmentType.Sparks:
{
if ( Random.Shared.Next( 100 ) < 20 )
{ // 20% chance.
player.hp += 5;
GameManager.AddLog( "Sparks heal you for 5 HP!" );
if ( player.hp > 100 )
{
player.hp = 100;
}
}
break;
}
case Weapon.EnchantmentType.DamageHP:
{
if ( Random.Shared.Next( 100 ) < chosenWeapon.enchantPower )
{
CombatManager.applyDamage( ref ai, 10 );
GameManager.AddLog( "Extra HP damage inflicted!" );
}
break;
}
case Weapon.EnchantmentType.Stun:
{
if ( Random.Shared.Next( 100 ) < chosenWeapon.enchantPower )
{
aiBuff = -999;
GameManager.AddLog( "AI is stunned!" );
GameManager.AddLog( "AI: \"System freeze detected.. pressing F5..\"" );
}
break;
}
case Weapon.EnchantmentType.LifeSteal:
{
if ( player.hp < 100 )
{
float preciseSteal = (float)damage / 3.0f;
int steal = (int)MathF.Round( preciseSteal );
if ( damage > 0 && steal == 0 ) steal = 1;
// 1. Heal you (the player)
player.hp += steal;
if ( player.hp > 100 ) player.hp = 100;
// 2. Damage the AI's HP directly
// NOTE: If your enemy variable is named something else (like 'enemy'), change 'ai' to match it!
if ( ai != null )
{
CombatManager.applyDamage( ref ai, steal );
if ( ai.hp < 0 ) ai.hp = 0;
}
GameManager.AddLog( $"LifeSteal drains {steal} HP from the AI!" );
}
break;
}
case Weapon.EnchantmentType.ShieldBreak:
{
if ( (Random.Shared.Next( 100 ) < chosenWeapon.enchantPower) && ai.isBlocking )
{
ai.isBlocking = false;
GameManager.AddLog( "ShieldBreak shatters the AI's firewall block!" );
}
break;
}
default:
break;
}
}
}
else
{
GameManager.AddLog( "You're confused and miss your attack!" );
}
}
}
else if ( playerMove == 3 )
{ // Heal
CombatManager.healPlayer( ref player, chosenWeapon ); // Call healPlayer to keep player health cap at 100.
GameManager.AddLog( "You chug your healing elixir *GLUGGLUGGLUG! AAH *HICCUP!** 10 HP!" );
}
else if ( playerMove == 4 )
{ // Special
bool rareMiss = Random.Shared.Next( 100 ) < 3; // 3%.
if ( rareMiss )
{
GameManager.AddLog( "*GASP* The special completely missed!" );
}
else
{
if ( Random.Shared.Next( 2 ) == 0 )
{ // 50% chance to hit.
GameManager.AddLog( "Your special attack is on target!" );
if ( ai.isBlocking && CombatManager.attemptBlock() )
{
RandomEventManager.playSoundEffect( "*BRUBRUBRU* The AI's firewall blocked the special!" );
}
else
{
int specialDamage = 30 + chosenWeapon.damageBonus; // Special scales with chosen weapon damage.
CombatManager.applyDamage( ref ai, specialDamage );
GameManager.AddLog( $"The charmed special deals {specialDamage} damage points!" );
RandomEventManager.playSoundEffect( "*SSSLLICEEE!*" );
GameManager.AddLog( "AI: \"That attack.. exceeded parameters.\"" );
}
}
else
{
GameManager.AddLog( "Your special missed!" );
}
}
}
}
}
public static void HandleAITurn( ref Player player, ref Player ai, Weapon playerWeapon, Weapon aiWeapon, int aiMove, ref int playerBuff, ref int aiBuff, ref bool tookDamage )
{
if ( ai.hp > 0 )
{
// Inject this check right at the start:
if ( GameManager.ShouldStunAI )
{
aiBuff = -999;
GameManager.ShouldStunAI = false; // Reset it immediately so it only applies for one turn!
}
// Your existing condition will now catch it beautifully!
if ( aiBuff == -999 )
{
GameManager.AddLog( "AI is too dazed to act!" );
// (Make sure your turn loop clears aiBuff back to 0 here or lets the turn cycle finish!)
return;
}
else if ( aiMove == 1 ) // Attack
{
bool rareMiss = Random.Shared.Next( 100 ) < 3;
if ( rareMiss )
{
GameManager.AddLog( "AI swings and miscalculates!" );
}
else
{
bool isAIConfused = (aiBuff == -1);
bool aiHitSuccess = isAIConfused ? Random.Shared.Next( 100 ) < 50 : true;
if ( aiHitSuccess )
{
if ( player.isBlocking && CombatManager.attemptBlock( playerWeapon.blockModifier ) ) // Player block uses weapon modifier.
{
GameManager.AddLog( "You blocked the AI's attack!" );
RandomEventManager.playSoundEffect( "*TWANG!*" );
int r = Random.Shared.Next( 2 );
if ( r == 0 )
{
GameManager.AddLog( "AI: \"Defense detected, adjusting strategy.\"" );
}
else
{
GameManager.AddLog( "AI: \"Your shield won't hold forever.\"" );
}
}
else
{
int damage = ai.attack + aiWeapon.damageBonus + (aiBuff > 0 ? aiBuff : 0); // AI attack includes weapon damage.
bool crit = CombatManager.isCriticalHit();
if ( crit )
{
damage = 25 + aiWeapon.damageBonus; // AI crit includes weapon bonus.
GameManager.AddLog( $"CRITICAL HIT!! AI had some shock with that mechanical fist for {damage} damage!" );
RandomEventManager.playSoundEffect( "*GZZZZZTT!*" );
int r = Random.Shared.Next( 3 );
if ( r == 0 )
{
GameManager.AddLog( "AI: \"Direct hit confirmed.\"" );
}
else if ( r == 1 )
{
GameManager.AddLog( "AI: \"My coordinates were on target.\"" );
}
else
{
GameManager.AddLog( "AI: \"You never saw that coming!\"" );
}
}
else
{
GameManager.AddLog( $"AI hits you for {damage} damage!" );
RandomEventManager.playSoundEffect( "*OOF!*" );
}
CombatManager.applyDamage( ref player, damage );
switch ( aiWeapon.enchantment ) // Apply Enchantments AI.
{
case Weapon.EnchantmentType.Fire:
{
if ( Random.Shared.Next( 100 ) < 80 ) // 80% chance.
{
int dmg = Random.Shared.Next( 6 ) + 5;
GameManager.AddLog( $"You burned {dmg} points by AI's fire weapon!" );
CombatManager.applyDamage( ref player, dmg );
}
break;
}
case Weapon.EnchantmentType.Poison:
{
player.cursed = true;
GameManager.AddLog( "You are poisoned by AI!" );
break;
}
case Weapon.EnchantmentType.Ice:
{
if ( Random.Shared.Next( 100 ) < 25 )
{
player.isBlocking = false;
GameManager.AddLog( "AI's ice breaks your block!" );
}
break;
}
case Weapon.EnchantmentType.Sparks:
{
if ( Random.Shared.Next( 100 ) < 20 )
{
ai.hp += 15;
GameManager.AddLog( "Sparks heal AI for 15 HP!" );
if ( ai.hp > 100 )
{
ai.hp = 100;
}
}
break;
}
case Weapon.EnchantmentType.DamageHP:
{
if ( Random.Shared.Next( 100 ) < aiWeapon.enchantPower )
{
CombatManager.applyDamage( ref player, 10 );
GameManager.AddLog( "Extra HP damage from AI inflicted!" );
}
break;
}
case Weapon.EnchantmentType.Stun:
{
if ( Random.Shared.Next( 100 ) < aiWeapon.enchantPower )
{
playerBuff = -999;
GameManager.AddLog( "You are stunned by AI!" );
GameManager.AddLog( "AI: \"Target immobilized.\"" );
}
break;
}
case Weapon.EnchantmentType.LifeSteal:
{
if ( ai.hp < 100 )
{
// 1. Calculate the steal amount using floating-point math based on AI's damage
float preciseSteal = (float)damage / 3.0f;
int aiSteal = (int)MathF.Round( preciseSteal );
// 2. Prevent integer rounding to 0 if damage was actually dealt
if ( damage > 0 && aiSteal == 0 ) aiSteal = 1;
// 3. Heal the AI
ai.hp += aiSteal;
if ( ai.hp > 100 ) ai.hp = 100;
// 4. Rip those extra points directly out of the player using your method!
if ( player != null )
{
CombatManager.applyDamage( ref player, aiSteal );
if ( player.hp < 0 ) player.hp = 0;
}
GameManager.AddLog( $"AI drains {aiSteal} HP with LifeSteal!" );
}
break;
}
case Weapon.EnchantmentType.ShieldBreak:
{
if ( (Random.Shared.Next( 100 ) < aiWeapon.enchantPower) && player.isBlocking )
{
player.isBlocking = false;
GameManager.AddLog( "AI shatters your block with ShieldBreak!" );
}
break;
}
default:
break;
}
tookDamage = true; // Tracking the player taking damage
}
}
else
{
GameManager.AddLog( "AI is confused and misses the attack!" );
}
}
}
else if ( aiMove == 3 )
{
CombatManager.healAI( ref ai, aiWeapon ); // Calling healAI to keep health cap at 100.
GameManager.AddLog( "AI chugs its bit elixir! *PLINK SPARKLE PING!* for 10 HP!" );
RandomEventManager.playSoundEffect( "*BEEP BOOP*" );
}
else if ( aiMove == 4 )
{
bool rareMiss = Random.Shared.Next( 100 ) < 3;
if ( rareMiss )
{
GameManager.AddLog( "AI's supercharged attack runs out of battery!" );
}
else
{
if ( Random.Shared.Next( 2 ) == 0 ) // 50% chance for AI to hit.
{
GameManager.AddLog( "AI deploys its special attack!" );
if ( player.isBlocking && CombatManager.attemptBlock( playerWeapon.blockModifier ) ) // Player block uses weapon modifier.
{
GameManager.AddLog( "But you blocked the AI's special!" );
RandomEventManager.playSoundEffect( "*DONNNGGG!*" );
}
else
{
int specialDamage = 30 + aiBuff; // Buff or debuff included in special.
CombatManager.applyDamage( ref player, specialDamage );
GameManager.AddLog( $"AI singed your whole head! You smell of burnt popcorn! {specialDamage} damage points!" );
int r = Random.Shared.Next( 3 );
if ( r == 0 )
{
GameManager.AddLog( "AI: \"Dinner's ready!\"" );
}
else if ( r == 1 )
{
GameManager.AddLog( "AI: \"Overclocked and executed perfectly.\"" );
}
else
{
GameManager.AddLog( "AI: \"You are outmatched.\"" );
}
RandomEventManager.playSoundEffect( "*BUUHH!!*" );
tookDamage = true; // Tracking the player taking damage.
}
}
else
{
GameManager.AddLog( "AI's special missed!" );
RandomEventManager.playSoundEffect( "*My calculations were off..*" );
}
}
}
else if ( aiMove == 5 ) // AI Offensive Spell.
{
if ( ai.magic >= 20 )
{
string spell = ai.offensiveSpells[Random.Shared.Next( ai.offensiveSpells.Count )];
// 👾 Find your AI spell execution block and update the log line:
string aiSpell = ai.offensiveSpells.FirstOrDefault(); // or whatever spell slot it chose to use
// 🚀 Look up the matching emoji!
string emoji = GameManager.GetSpellEmoji( aiSpell );
// Add it straight into your combat log output string
GameManager.AddLog( $"{emoji} AI Overlord casts {aiSpell}!" );
int damage = 15 + (ai.magic / 2);
ai.magic -= 20;
if ( ai.magic < 0 )
{
ai.magic = 0;
}
if ( spell == "Fireball" )
{
damage += 5;
}
if ( spell == "Lightning" )
{
damage += 10;
}
if ( spell == "Poison Bolt" )
{
player.cursed = true;
GameManager.AddLog( "You are poisoned!" );
}
CombatManager.applyDamage( ref player, damage );
GameManager.AddLog( $"{spell} hits you for {damage} damage!" );
tookDamage = true;
}
else
{
GameManager.AddLog( "AI tried to cast a spell but lacks magic!" );
}
}
else if ( aiMove == 6 ) // AI Defensive Spell.
{
if ( ai.magic >= 15 )
{
string spell = ai.defensiveSpells[Random.Shared.Next( ai.defensiveSpells.Count )];
// 👾 Find your AI spell execution block and update the log line:
string aiSpell = ai.defensiveSpells.FirstOrDefault(); // or whatever spell slot it chose to use
// 🚀 Look up the matching emoji!
string emoji = GameManager.GetSpellEmoji( aiSpell );
// Add it straight into your combat log output string
GameManager.AddLog( $"{emoji} AI Overlord casts {aiSpell}!" );
ai.magic -= 15;
if ( ai.magic < 0 )
{
ai.magic = 0;
}
if ( spell == "Shield" || spell == "Barrier" )
{
ai.defense += 15;
}
else if ( spell == "Reflect" )
{
ai.isBlocking = true;
GameManager.AddLog( "AI prepares to block your next move!" );
}
else if ( spell == "Magic Wall" )
{
ai.isMagicBlocking = true;
ai.activeMagicShield = "Magic Wall";
GameManager.AddLog( "A magical barrier surrounds the AI!" );
}
else if ( spell == "Fortify" )
{
ai.isMagicBlocking = true;
ai.activeMagicShield = "Fortify";
GameManager.AddLog( "AI's defenses are magically reinforced!" );
}
if ( ai.defense > 100 )
{
ai.defense = 100;
}
}
else
{
GameManager.AddLog( "AI tried to defend its self with magic, but lacks magic points!" );
}
}
else if ( aiMove == 7 ) // AI Healing Spell.
{
if ( ai.magic >= 20 )
{
string spell = "";
if ( ai.cursed )
{
foreach ( string s in ai.healingSpells )
{
if ( s == "Cleanse" )
{
spell = s;
break;
}
}
}
if ( string.IsNullOrEmpty( spell ) ) // fallback if spell not found.
{
spell = ai.healingSpells[Random.Shared.Next( ai.healingSpells.Count )];
}
// 👾 Find your AI spell execution block and update the log line:
string aiSpell = ai.healingSpells.FirstOrDefault(); // or whatever spell slot it chose to use
// 🚀 Look up the matching emoji!
string emoji = GameManager.GetSpellEmoji( aiSpell );
// Add it straight into your combat log output string
GameManager.AddLog( $"{emoji} AI Overlord casts {aiSpell}!" );
ai.magic -= 20;
if ( ai.magic < 0 )
{
ai.magic = 0;
}
int heal = 15 + (ai.magic / 3);
if ( spell == "Regen" )
{
heal += 10;
}
if ( spell == "Cleanse" )
{
ai.cursed = false;
GameManager.AddLog( "AI removed its status effects!" );
}
ai.hp += heal;
if ( ai.hp > 100 )
{
ai.hp = 100;
}
GameManager.AddLog( $"AI heals for {heal} HP!" );
}
else
{
GameManager.AddLog( "AI's magic healing dust gave out a weak puff from lack of magic!" );
}
}
else if ( aiMove == 8 ) // AI Special Spell.
{
if ( ai.magic >= 30 )
{
string spell = ai.specialSpells[Random.Shared.Next( ai.specialSpells.Count )];
// 🚀 1. Fetch the correct emoji dynamically from the helper method
string emoji = GameManager.GetSpellEmoji( spell );
// 🚀 2. Inject the emoji into the main combat log announcement!
GameManager.AddLog( $"{emoji} AI unleashes {spell}!" );
ai.magic = Math.Max( 0, ai.magic - 30 );
if ( ai.magic < 0 )
{
ai.magic = 0;
}
// 🚀 3. Map your exact active poolSpecial spells to their real secondary effects:
if ( spell == "System Overdrive" )
{
int damageAmount = 30 + ai.magic;
CombatManager.applyDamage( ref player, damageAmount );
GameManager.AddLog( "⚡ The AI enters System Overdrive, electrifying you to take direct damage!" );
tookDamage = true;
}
else if ( spell == "EMP Blast" )
{
int empDamage = ai.attack *= 2;
CombatManager.applyDamage( ref player, empDamage );
GameManager.AddLog( "💥 An EMP Blast de-calibrates your defenses, doubling the AI's attack power! Dealing {empDamage} damage (2x Attack!)" );
tookDamage = true;
}
else if ( spell == "Data Corruption" )
{
int corruptionDamage = 40;
CombatManager.applyDamage( ref player, corruptionDamage );
playerBuff = -999;
GameManager.AddLog( "👾 Your UI is hit with Data Corruption, freezing your inputs in time!" );
tookDamage = true;
}
}
}
}
}
public static void CleanupRound( ref Player player, ref Player ai, ref int playerBuff, ref int aiBuff, ref int round )
{
round++;
playerBuff = 0;
aiBuff = 0;
player.isMagicBlocking = false;
player.activeMagicShield = "";
ai.isMagicBlocking = false;
ai.activeMagicShield = "";
}
}