feat(race-class): Phase 5 종족/클래스 특화 시스템 구현
- RaceTraits: 7종족 (Byte Human, Null Elf, Buffer Dwarf 등) - ClassTraits: 6클래스 (Bug Hunter, Compiler Mage 등) - StatCalculator: 종족/클래스 보정 계산 - CombatStats.fromStats: 종족/클래스 패시브 효과 통합 - 종족별 스탯 보정 및 패시브 (경험치, HP/MP, 크리티컬 등) - 클래스별 스탯 보정 및 패시브 (공격력, 방어력, 회피 등)
This commit is contained in:
200
lib/src/core/engine/stat_calculator.dart
Normal file
200
lib/src/core/engine/stat_calculator.dart
Normal file
@@ -0,0 +1,200 @@
|
||||
import 'package:askiineverdie/src/core/model/class_traits.dart';
|
||||
import 'package:askiineverdie/src/core/model/combat_stats.dart';
|
||||
import 'package:askiineverdie/src/core/model/game_state.dart';
|
||||
import 'package:askiineverdie/src/core/model/race_traits.dart';
|
||||
|
||||
/// 스탯 계산기 (stat calculator)
|
||||
///
|
||||
/// 기본 스탯에 종족/클래스 보정을 적용하여 최종 스탯 계산
|
||||
class StatCalculator {
|
||||
const StatCalculator();
|
||||
|
||||
/// 기본 스탯에 종족/클래스 보정 적용
|
||||
///
|
||||
/// [baseStats] 기본 캐릭터 스탯
|
||||
/// [race] 종족 특성
|
||||
/// [klass] 클래스 특성
|
||||
Stats applyModifiers({
|
||||
required Stats baseStats,
|
||||
required RaceTraits race,
|
||||
required ClassTraits klass,
|
||||
}) {
|
||||
// 종족 보정 적용
|
||||
var str = baseStats.str + race.getModifier(StatType.str);
|
||||
var con = baseStats.con + race.getModifier(StatType.con);
|
||||
var dex = baseStats.dex + race.getModifier(StatType.dex);
|
||||
var intel = baseStats.intelligence + race.getModifier(StatType.intelligence);
|
||||
var wis = baseStats.wis + race.getModifier(StatType.wis);
|
||||
var cha = baseStats.cha + race.getModifier(StatType.cha);
|
||||
|
||||
// 클래스 보정 적용
|
||||
str += klass.getModifier(StatType.str);
|
||||
con += klass.getModifier(StatType.con);
|
||||
dex += klass.getModifier(StatType.dex);
|
||||
intel += klass.getModifier(StatType.intelligence);
|
||||
wis += klass.getModifier(StatType.wis);
|
||||
cha += klass.getModifier(StatType.cha);
|
||||
|
||||
// HP/MP에 종족 패시브 적용
|
||||
var hpMax = baseStats.hpMax;
|
||||
var mpMax = baseStats.mpMax;
|
||||
|
||||
// 종족 HP 보너스 (Heap Troll: +20%)
|
||||
final raceHpBonus = race.getPassiveValue(PassiveType.hpBonus);
|
||||
if (raceHpBonus > 0) {
|
||||
hpMax = (hpMax * (1 + raceHpBonus)).round();
|
||||
}
|
||||
|
||||
// 종족 MP 보너스 (Pointer Fairy: +20%)
|
||||
final raceMpBonus = race.getPassiveValue(PassiveType.mpBonus);
|
||||
if (raceMpBonus > 0) {
|
||||
mpMax = (mpMax * (1 + raceMpBonus)).round();
|
||||
}
|
||||
|
||||
// 클래스 HP 보너스 (Garbage Collector: +30%)
|
||||
final classHpBonus = klass.getPassiveValue(ClassPassiveType.hpBonus);
|
||||
if (classHpBonus > 0) {
|
||||
hpMax = (hpMax * (1 + classHpBonus)).round();
|
||||
}
|
||||
|
||||
return baseStats.copyWith(
|
||||
str: str,
|
||||
con: con,
|
||||
dex: dex,
|
||||
intelligence: intel,
|
||||
wis: wis,
|
||||
cha: cha,
|
||||
hpMax: hpMax,
|
||||
mpMax: mpMax,
|
||||
);
|
||||
}
|
||||
|
||||
/// CombatStats에 종족/클래스 패시브 효과 적용
|
||||
///
|
||||
/// [combatStats] 기본 전투 스탯
|
||||
/// [race] 종족 특성
|
||||
/// [klass] 클래스 특성
|
||||
CombatStats applyPassives({
|
||||
required CombatStats combatStats,
|
||||
required RaceTraits race,
|
||||
required ClassTraits klass,
|
||||
}) {
|
||||
var atk = combatStats.atk;
|
||||
var def = combatStats.def;
|
||||
var magAtk = combatStats.magAtk;
|
||||
var criRate = combatStats.criRate;
|
||||
var evasion = combatStats.evasion;
|
||||
|
||||
// 종족 패시브 적용
|
||||
|
||||
// 마법 데미지 보너스 (Null Elf: +15%)
|
||||
final raceMagicBonus = race.getPassiveValue(PassiveType.magicDamageBonus);
|
||||
if (raceMagicBonus > 0) {
|
||||
magAtk = (magAtk * (1 + raceMagicBonus)).round();
|
||||
}
|
||||
|
||||
// 방어력 보너스 (Buffer Dwarf: +10%)
|
||||
final raceDefenseBonus = race.getPassiveValue(PassiveType.defenseBonus);
|
||||
if (raceDefenseBonus > 0) {
|
||||
def = (def * (1 + raceDefenseBonus)).round();
|
||||
}
|
||||
|
||||
// 크리티컬 보너스 (Stack Goblin: +5%)
|
||||
final raceCritBonus = race.getPassiveValue(PassiveType.criticalBonus);
|
||||
if (raceCritBonus > 0) {
|
||||
criRate = (criRate + raceCritBonus).clamp(0.0, 0.8);
|
||||
}
|
||||
|
||||
// 클래스 패시브 적용
|
||||
|
||||
// 물리 공격력 보너스 (Bug Hunter: +20%)
|
||||
final classPhysicalBonus = klass.getPassiveValue(ClassPassiveType.physicalDamageBonus);
|
||||
if (classPhysicalBonus > 0) {
|
||||
atk = (atk * (1 + classPhysicalBonus)).round();
|
||||
}
|
||||
|
||||
// 방어력 보너스 (Debugger Paladin: +15%)
|
||||
final classDefenseBonus = klass.getPassiveValue(ClassPassiveType.defenseBonus);
|
||||
if (classDefenseBonus > 0) {
|
||||
def = (def * (1 + classDefenseBonus)).round();
|
||||
}
|
||||
|
||||
// 마법 데미지 보너스 (Compiler Mage: +25%)
|
||||
final classMagicBonus = klass.getPassiveValue(ClassPassiveType.magicDamageBonus);
|
||||
if (classMagicBonus > 0) {
|
||||
magAtk = (magAtk * (1 + classMagicBonus)).round();
|
||||
}
|
||||
|
||||
// 회피율 보너스 (Refactor Monk: +15%)
|
||||
final classEvasionBonus = klass.getPassiveValue(ClassPassiveType.evasionBonus);
|
||||
if (classEvasionBonus > 0) {
|
||||
evasion = (evasion + classEvasionBonus).clamp(0.0, 0.6);
|
||||
}
|
||||
|
||||
// 크리티컬 보너스 (Pointer Assassin: +20%)
|
||||
final classCritBonus = klass.getPassiveValue(ClassPassiveType.criticalBonus);
|
||||
if (classCritBonus > 0) {
|
||||
criRate = (criRate + classCritBonus).clamp(0.0, 0.8);
|
||||
}
|
||||
|
||||
return combatStats.copyWith(
|
||||
atk: atk,
|
||||
def: def,
|
||||
magAtk: magAtk,
|
||||
criRate: criRate,
|
||||
evasion: evasion,
|
||||
);
|
||||
}
|
||||
|
||||
/// 경험치 배율 계산
|
||||
///
|
||||
/// 종족 경험치 배율 반환 (Byte Human: 1.10)
|
||||
double calculateExpMultiplier(RaceTraits race) {
|
||||
return race.expMultiplier;
|
||||
}
|
||||
|
||||
/// 전투 후 HP 회복량 계산 (Garbage Collector 패시브)
|
||||
///
|
||||
/// [klass] 클래스 특성
|
||||
/// [maxHp] 최대 HP
|
||||
/// Returns: 회복할 HP 양
|
||||
int calculatePostCombatHeal({
|
||||
required ClassTraits klass,
|
||||
required int maxHp,
|
||||
}) {
|
||||
final healRate = klass.getPassiveValue(ClassPassiveType.postCombatHeal);
|
||||
if (healRate <= 0) return 0;
|
||||
return (maxHp * healRate).round();
|
||||
}
|
||||
|
||||
/// 첫 공격 배율 계산 (Pointer Assassin 패시브)
|
||||
///
|
||||
/// [klass] 클래스 특성
|
||||
/// Returns: 첫 공격 배율 (기본 1.0)
|
||||
double calculateFirstStrikeMultiplier(ClassTraits klass) {
|
||||
final bonus = klass.getPassiveValue(ClassPassiveType.firstStrikeBonus);
|
||||
return bonus > 0 ? bonus : 1.0;
|
||||
}
|
||||
|
||||
/// 사망 시 보존할 장비 개수 (Coredump Undead 패시브)
|
||||
///
|
||||
/// [race] 종족 특성
|
||||
/// Returns: 보존 장비 개수
|
||||
int calculateDeathEquipmentPreserve(RaceTraits race) {
|
||||
if (race.hasPassive(PassiveType.deathEquipmentPreserve)) {
|
||||
return race.getPassiveValue(PassiveType.deathEquipmentPreserve).round();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// 연속 공격 가능 여부 (Refactor Monk 패시브)
|
||||
bool hasMultiAttack(ClassTraits klass) {
|
||||
return klass.hasPassive(ClassPassiveType.multiAttack);
|
||||
}
|
||||
|
||||
/// 회복력 배율 계산 (Debugger Paladin 패시브)
|
||||
double calculateHealingMultiplier(ClassTraits klass) {
|
||||
final bonus = klass.getPassiveValue(ClassPassiveType.healingBonus);
|
||||
return 1.0 + bonus;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user