StrategyRPG/Johnmagotchi/GameContent/Logic/BattleLogic.cs

123 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Johnmagotchi.GameContent.Objects.Units;
using Johnmagotchi.GameContent.Objects.Units.BattleObjects;
using Johnmagotchi.GameContent.Units;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Threading.Tasks;
namespace Johnmagotchi.GameContent.Logic
{
public static class BattleLogic
{
private static double CriticalMultiplier = 1.5;
public static Random Random = new Random();
public static BattleResults RunBattle(ref Unit Attacker, ref Unit Defender, AttackObj attack, AttackObj counterAttack) {
// these are debugs, should be parsed from attack + unit combos
bool IsCounterAttackOccuring = true;
bool IsDoubleAttackOccuring = false;
bool IsDoubleCounterAttackOccuring = false;
BattleResults results = new BattleResults(); // battle results will determine how the battles are animated
// for each combat, we need to do each attack phase that occurs apply results here
//Initial Attack
HandleAttackPhase(ref Attacker, ref Defender, attack, ref results, false);
//Enemy's counter attack
if (IsCounterAttackOccuring)
{
HandleAttackPhase(ref Defender, ref Attacker, counterAttack, ref results, true);
}
// FE style double attack
if (IsDoubleAttackOccuring)
{
HandleAttackPhase(ref Attacker, ref Defender, attack, ref results, false);
}
// FE style Double Counter Attack
if (IsDoubleCounterAttackOccuring)
{
HandleAttackPhase(ref Defender, ref Attacker, counterAttack, ref results, true);
}
return results;
}
// this is each step
public static void HandleAttackPhase(
ref Unit Attacker, ref Unit Defender, AttackObj attack,
ref BattleResults results, bool isCounter)
{
int hitcount = attack.BaseHitCount; // anything that adjusts how many times an attack happens PER PHASE should be adjusted here
for (int i = 0; i < hitcount; i++) {
int hitRoll = BattleLogic.Random.Next(100) + 1; // random int 1 - 100
int hitThreshold = attack.BaseAccuracy + Attacker.stats.baseStats.Speed - Defender.stats.baseStats.Speed;
// this should be adjusted, in FE games its usally something like......
// ATTACKER = Hit + (Skill × 2) + (Luck / 2) + (Support bonus)+(Weapon triangle advantage/ disadvantage) +(S level bonus)
// DEFENDER = ((Attack speed × 2) +(Luck) + (Terrain bonus) +(Support bonus) +Tactician bonus) )
// hit perentage = attacker - defender
int critThreshold = 95;
if (hitRoll < hitThreshold) //handle misses
{
results.addResult(BattleResults.resultType.MISS, 0, isCounter);
}
else if (hitRoll >= critThreshold) //Handle Crits
{
if (Defender.stats.status.CurrentShieldCount > 1) Defender.stats.status.CurrentShieldCount--; // as is, crits ignore shields but should still tick a shield down
if (Defender.stats.status.CurrentShieldCount < 0) Defender.stats.status.CurrentShieldCount = 0;
int BaseDamage = CalculateDamage(Attacker,Defender,attack);
int TotalCritDamage = (int) Math.Ceiling (BaseDamage * CriticalMultiplier);
//apply Damage to defending unit, then add to result report
Defender.stats.status.CurrentHealth -= TotalCritDamage;
results.addResult(BattleResults.resultType.CRITICAL, TotalCritDamage, isCounter);
}
else if (Defender.stats.status.CurrentShieldCount > 1) // Shielded
{
Defender.stats.status.CurrentShieldCount--;
results.addResult(BattleResults.resultType.SHIELDED,1, isCounter); // 1 siginfies 1 shield lost
}
else // normal attack
{
int BaseDamage = CalculateDamage(Attacker, Defender, attack);
//Apply damage + report to animation handler
Defender.stats.status.CurrentHealth -= BaseDamage;
results.addResult(BattleResults.resultType.ATTACK, BaseDamage, isCounter);
}
}
return;
}
private static int CalculateDamage( Unit Attacker, Unit Defender, AttackObj attack)
{
int damage = 0;
damage += attack.BaseDamage;
damage += Attacker.stats.baseStats.Attack;
damage -= Defender.stats.baseStats.Defense;
if (damage < 0) damage = 0;
return damage ;
}
}
}