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:
185
lib/data/class_data.dart
Normal file
185
lib/data/class_data.dart
Normal file
@@ -0,0 +1,185 @@
|
||||
import 'package:askiineverdie/src/core/model/class_traits.dart';
|
||||
import 'package:askiineverdie/src/core/model/race_traits.dart';
|
||||
|
||||
/// 클래스 데이터 정의 (class data)
|
||||
///
|
||||
/// 프로그래밍 테마의 6가지 클래스 정의
|
||||
class ClassData {
|
||||
ClassData._();
|
||||
|
||||
/// Bug Hunter: 전사형, 물리 공격 보너스
|
||||
static const bugHunter = ClassTraits(
|
||||
classId: 'bug_hunter',
|
||||
name: 'Bug Hunter',
|
||||
statModifiers: {
|
||||
StatType.str: 2,
|
||||
StatType.dex: 1,
|
||||
},
|
||||
startingSkills: ['power_strike'],
|
||||
classSkills: ['power_strike', 'execute', 'berserker_rage'],
|
||||
passives: [
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.physicalDamageBonus,
|
||||
value: 0.20,
|
||||
description: '일반 공격 +20%',
|
||||
),
|
||||
],
|
||||
restriction: EquipmentRestriction.none,
|
||||
);
|
||||
|
||||
/// Debugger Paladin: 탱커형, 방어/회복 보너스
|
||||
static const debuggerPaladin = ClassTraits(
|
||||
classId: 'debugger_paladin',
|
||||
name: 'Debugger Paladin',
|
||||
statModifiers: {
|
||||
StatType.str: 1,
|
||||
StatType.con: 2,
|
||||
},
|
||||
startingSkills: ['shield_bash'],
|
||||
classSkills: ['shield_bash', 'holy_light', 'divine_protection'],
|
||||
passives: [
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.defenseBonus,
|
||||
value: 0.15,
|
||||
description: '방어력 +15%',
|
||||
),
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.healingBonus,
|
||||
value: 0.10,
|
||||
description: '회복력 +10%',
|
||||
),
|
||||
],
|
||||
restriction: EquipmentRestriction(
|
||||
armorWeight: ArmorWeight.heavy,
|
||||
),
|
||||
);
|
||||
|
||||
/// Compiler Mage: 마법사형, 마법 데미지 보너스
|
||||
static const compilerMage = ClassTraits(
|
||||
classId: 'compiler_mage',
|
||||
name: 'Compiler Mage',
|
||||
statModifiers: {
|
||||
StatType.intelligence: 2,
|
||||
StatType.wis: 1,
|
||||
},
|
||||
startingSkills: ['fireball'],
|
||||
classSkills: ['fireball', 'ice_storm', 'arcane_blast', 'mana_shield'],
|
||||
passives: [
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.magicDamageBonus,
|
||||
value: 0.25,
|
||||
description: '마법 데미지 +25%',
|
||||
),
|
||||
],
|
||||
restriction: EquipmentRestriction(
|
||||
armorWeight: ArmorWeight.light,
|
||||
),
|
||||
);
|
||||
|
||||
/// Refactor Monk: 민첩형, 회피/연속공격
|
||||
static const refactorMonk = ClassTraits(
|
||||
classId: 'refactor_monk',
|
||||
name: 'Refactor Monk',
|
||||
statModifiers: {
|
||||
StatType.dex: 2,
|
||||
StatType.wis: 1,
|
||||
},
|
||||
startingSkills: ['flurry'],
|
||||
classSkills: ['flurry', 'palm_strike', 'meditation'],
|
||||
passives: [
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.evasionBonus,
|
||||
value: 0.15,
|
||||
description: '회피율 +15%',
|
||||
),
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.multiAttack,
|
||||
value: 1.0,
|
||||
description: '연속 공격 가능',
|
||||
),
|
||||
],
|
||||
restriction: EquipmentRestriction(
|
||||
armorWeight: ArmorWeight.light,
|
||||
),
|
||||
);
|
||||
|
||||
/// Pointer Assassin: 암살자형, 크리티컬/첫 공격 보너스
|
||||
static const pointerAssassin = ClassTraits(
|
||||
classId: 'pointer_assassin',
|
||||
name: 'Pointer Assassin',
|
||||
statModifiers: {
|
||||
StatType.dex: 2,
|
||||
StatType.str: 1,
|
||||
},
|
||||
startingSkills: ['backstab'],
|
||||
classSkills: ['backstab', 'poison_blade', 'shadow_step'],
|
||||
passives: [
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.criticalBonus,
|
||||
value: 0.20,
|
||||
description: '크리티컬 +20%',
|
||||
),
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.firstStrikeBonus,
|
||||
value: 2.0,
|
||||
description: '첫 공격 2배',
|
||||
),
|
||||
],
|
||||
restriction: EquipmentRestriction(
|
||||
armorWeight: ArmorWeight.light,
|
||||
),
|
||||
);
|
||||
|
||||
/// Garbage Collector: 탱커형, HP/전투 후 회복
|
||||
static const garbageCollector = ClassTraits(
|
||||
classId: 'garbage_collector',
|
||||
name: 'Garbage Collector',
|
||||
statModifiers: {
|
||||
StatType.con: 2,
|
||||
StatType.str: 1,
|
||||
},
|
||||
startingSkills: ['absorb'],
|
||||
classSkills: ['absorb', 'recycle', 'memory_leak'],
|
||||
passives: [
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.hpBonus,
|
||||
value: 0.30,
|
||||
description: 'HP +30%',
|
||||
),
|
||||
ClassPassive(
|
||||
type: ClassPassiveType.postCombatHeal,
|
||||
value: 0.10,
|
||||
description: '전투 후 HP 10% 회복',
|
||||
),
|
||||
],
|
||||
restriction: EquipmentRestriction(
|
||||
armorWeight: ArmorWeight.heavy,
|
||||
),
|
||||
);
|
||||
|
||||
/// 모든 클래스 목록
|
||||
static const List<ClassTraits> all = [
|
||||
bugHunter,
|
||||
debuggerPaladin,
|
||||
compilerMage,
|
||||
refactorMonk,
|
||||
pointerAssassin,
|
||||
garbageCollector,
|
||||
];
|
||||
|
||||
/// ID로 클래스 찾기
|
||||
static ClassTraits? findById(String classId) {
|
||||
for (final klass in all) {
|
||||
if (klass.classId == classId) return klass;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 이름으로 클래스 찾기
|
||||
static ClassTraits? findByName(String name) {
|
||||
for (final klass in all) {
|
||||
if (klass.name == name) return klass;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
167
lib/data/race_data.dart
Normal file
167
lib/data/race_data.dart
Normal file
@@ -0,0 +1,167 @@
|
||||
import 'package:askiineverdie/src/core/model/race_traits.dart';
|
||||
|
||||
/// 종족 데이터 정의 (race data)
|
||||
///
|
||||
/// 프로그래밍 테마의 7가지 종족 정의
|
||||
class RaceData {
|
||||
RaceData._();
|
||||
|
||||
/// Byte Human: 균형형, 경험치 보너스
|
||||
static const byteHuman = RaceTraits(
|
||||
raceId: 'byte_human',
|
||||
name: 'Byte Human',
|
||||
statModifiers: {
|
||||
StatType.cha: 2,
|
||||
},
|
||||
passives: [
|
||||
PassiveAbility(
|
||||
type: PassiveType.expBonus,
|
||||
value: 0.10,
|
||||
description: '경험치 +10%',
|
||||
),
|
||||
],
|
||||
expMultiplier: 1.10,
|
||||
);
|
||||
|
||||
/// Null Elf: 민첩/지능형, 마법 데미지 보너스
|
||||
static const nullElf = RaceTraits(
|
||||
raceId: 'null_elf',
|
||||
name: 'Null Elf',
|
||||
statModifiers: {
|
||||
StatType.str: -1,
|
||||
StatType.con: -1,
|
||||
StatType.dex: 2,
|
||||
StatType.intelligence: 2,
|
||||
},
|
||||
passives: [
|
||||
PassiveAbility(
|
||||
type: PassiveType.magicDamageBonus,
|
||||
value: 0.15,
|
||||
description: '마법 데미지 +15%',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
/// Buffer Dwarf: 힘/체력형, 방어력 보너스
|
||||
static const bufferDwarf = RaceTraits(
|
||||
raceId: 'buffer_dwarf',
|
||||
name: 'Buffer Dwarf',
|
||||
statModifiers: {
|
||||
StatType.str: 2,
|
||||
StatType.con: 2,
|
||||
StatType.dex: -1,
|
||||
StatType.intelligence: -1,
|
||||
},
|
||||
passives: [
|
||||
PassiveAbility(
|
||||
type: PassiveType.defenseBonus,
|
||||
value: 0.10,
|
||||
description: '방어력 +10%',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
/// Stack Goblin: 민첩형, 크리티컬 보너스
|
||||
static const stackGoblin = RaceTraits(
|
||||
raceId: 'stack_goblin',
|
||||
name: 'Stack Goblin',
|
||||
statModifiers: {
|
||||
StatType.str: -1,
|
||||
StatType.con: -1,
|
||||
StatType.dex: 3,
|
||||
StatType.cha: 1,
|
||||
},
|
||||
passives: [
|
||||
PassiveAbility(
|
||||
type: PassiveType.criticalBonus,
|
||||
value: 0.05,
|
||||
description: '크리티컬 확률 +5%',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
/// Heap Troll: 체력형, HP 보너스
|
||||
static const heapTroll = RaceTraits(
|
||||
raceId: 'heap_troll',
|
||||
name: 'Heap Troll',
|
||||
statModifiers: {
|
||||
StatType.str: 3,
|
||||
StatType.con: 3,
|
||||
StatType.dex: -2,
|
||||
StatType.intelligence: -2,
|
||||
},
|
||||
passives: [
|
||||
PassiveAbility(
|
||||
type: PassiveType.hpBonus,
|
||||
value: 0.20,
|
||||
description: 'HP +20%',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
/// Pointer Fairy: 마법형, MP 보너스
|
||||
static const pointerFairy = RaceTraits(
|
||||
raceId: 'pointer_fairy',
|
||||
name: 'Pointer Fairy',
|
||||
statModifiers: {
|
||||
StatType.str: -2,
|
||||
StatType.con: -2,
|
||||
StatType.dex: 2,
|
||||
StatType.intelligence: 2,
|
||||
StatType.wis: 2,
|
||||
},
|
||||
passives: [
|
||||
PassiveAbility(
|
||||
type: PassiveType.mpBonus,
|
||||
value: 0.20,
|
||||
description: 'MP +20%',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
/// Coredump Undead: 탱커형, 사망 시 장비 보존
|
||||
static const coredumpUndead = RaceTraits(
|
||||
raceId: 'coredump_undead',
|
||||
name: 'Coredump Undead',
|
||||
statModifiers: {
|
||||
StatType.str: 1,
|
||||
StatType.con: 2,
|
||||
StatType.dex: -1,
|
||||
StatType.cha: -2,
|
||||
},
|
||||
passives: [
|
||||
PassiveAbility(
|
||||
type: PassiveType.deathEquipmentPreserve,
|
||||
value: 1.0,
|
||||
description: '사망 시 장비 1개 유지',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
/// 모든 종족 목록
|
||||
static const List<RaceTraits> all = [
|
||||
byteHuman,
|
||||
nullElf,
|
||||
bufferDwarf,
|
||||
stackGoblin,
|
||||
heapTroll,
|
||||
pointerFairy,
|
||||
coredumpUndead,
|
||||
];
|
||||
|
||||
/// ID로 종족 찾기
|
||||
static RaceTraits? findById(String raceId) {
|
||||
for (final race in all) {
|
||||
if (race.raceId == raceId) return race;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 이름으로 종족 찾기
|
||||
static RaceTraits? findByName(String name) {
|
||||
for (final race in all) {
|
||||
if (race.name == name) return race;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user