From e4517031617148161a616a49ca1f7f2bef2e8f17 Mon Sep 17 00:00:00 2001 From: JiWoong Sul Date: Wed, 17 Dec 2025 17:26:50 +0900 Subject: [PATCH] =?UTF-8?q?fix(race-class):=20=EC=9B=90=EB=B3=B8=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EA=B8=B0=EC=A4=80=20=EC=A2=85?= =?UTF-8?q?=EC=A1=B1/=ED=81=B4=EB=9E=98=EC=8A=A4=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 종족: 7개 → 21개 (pq_config_data.dart 기준) - 클래스: 6개 → 18개 (pq_config_data.dart 기준) - 각 종족/클래스에 적절한 스탯 보정 및 패시브 추가 --- lib/data/class_data.dart | 484 ++++++++++++++++++++++++++++++++------- lib/data/race_data.dart | 422 +++++++++++++++++++++++++++------- 2 files changed, 733 insertions(+), 173 deletions(-) diff --git a/lib/data/class_data.dart b/lib/data/class_data.dart index 7dff208..3a722b7 100644 --- a/lib/data/class_data.dart +++ b/lib/data/class_data.dart @@ -3,45 +3,120 @@ import 'package:askiineverdie/src/core/model/race_traits.dart'; /// 클래스 데이터 정의 (class data) /// -/// 프로그래밍 테마의 6가지 클래스 정의 +/// 프로그래밍 테마의 18가지 클래스 정의 +/// pq_config_data.dart의 Klasses 데이터 기반 class ClassData { ClassData._(); - /// Bug Hunter: 전사형, 물리 공격 보너스 + // ========================================================================== + // 전사 계열 (STR 기반) + // ========================================================================== + + /// Bug Hunter: STR + INT static const bugHunter = ClassTraits( classId: 'bug_hunter', name: 'Bug Hunter', statModifiers: { StatType.str: 2, - StatType.dex: 1, + StatType.intelligence: 1, }, startingSkills: ['power_strike'], - classSkills: ['power_strike', 'execute', 'berserker_rage'], + classSkills: ['power_strike', 'execute', 'bug_smash'], passives: [ ClassPassive( type: ClassPassiveType.physicalDamageBonus, - value: 0.20, - description: '일반 공격 +20%', + value: 0.10, + description: '물리 공격 +10%', ), ], restriction: EquipmentRestriction.none, ); - /// Debugger Paladin: 탱커형, 방어/회복 보너스 + /// Overflow Warrior: STR + static const overflowWarrior = ClassTraits( + classId: 'overflow_warrior', + name: 'Overflow Warrior', + statModifiers: { + StatType.str: 2, + }, + startingSkills: ['power_strike'], + classSkills: ['power_strike', 'overflow_slash', 'buffer_break'], + passives: [ + ClassPassive( + type: ClassPassiveType.physicalDamageBonus, + value: 0.15, + description: '물리 공격 +15%', + ), + ], + restriction: EquipmentRestriction.none, + ); + + /// Stack Crusher: STR + CON + static const stackCrusher = ClassTraits( + classId: 'stack_crusher', + name: 'Stack Crusher', + statModifiers: { + StatType.str: 2, + StatType.con: 1, + }, + startingSkills: ['power_strike'], + classSkills: ['power_strike', 'stack_smash', 'heap_slam'], + passives: [ + ClassPassive( + type: ClassPassiveType.physicalDamageBonus, + value: 0.10, + description: '물리 공격 +10%', + ), + ClassPassive( + type: ClassPassiveType.hpBonus, + value: 0.05, + description: 'HP +5%', + ), + ], + restriction: EquipmentRestriction.none, + ); + + /// Assertion Knight: STR + WIS + static const assertionKnight = ClassTraits( + classId: 'assertion_knight', + name: 'Assertion Knight', + statModifiers: { + StatType.str: 2, + StatType.wis: 1, + }, + startingSkills: ['shield_bash'], + classSkills: ['shield_bash', 'assert_strike', 'validation_guard'], + passives: [ + ClassPassive( + type: ClassPassiveType.defenseBonus, + value: 0.10, + description: '방어력 +10%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.heavy, + ), + ); + + // ========================================================================== + // 탱커 계열 (CON 기반) + // ========================================================================== + + /// Debugger Paladin: WIS + CON static const debuggerPaladin = ClassTraits( classId: 'debugger_paladin', name: 'Debugger Paladin', statModifiers: { - StatType.str: 1, - StatType.con: 2, + StatType.wis: 2, + StatType.con: 1, }, startingSkills: ['shield_bash'], - classSkills: ['shield_bash', 'holy_light', 'divine_protection'], + classSkills: ['shield_bash', 'debug_heal', 'breakpoint_guard'], passives: [ ClassPassive( type: ClassPassiveType.defenseBonus, - value: 0.15, - description: '방어력 +15%', + value: 0.10, + description: '방어력 +10%', ), ClassPassive( type: ClassPassiveType.healingBonus, @@ -54,83 +129,28 @@ class ClassData { ), ); - /// Compiler Mage: 마법사형, 마법 데미지 보너스 - static const compilerMage = ClassTraits( - classId: 'compiler_mage', - name: 'Compiler Mage', + /// Loop Breaker: CON + static const loopBreaker = ClassTraits( + classId: 'loop_breaker', + name: 'Loop Breaker', statModifiers: { - StatType.intelligence: 2, - StatType.wis: 1, + StatType.con: 2, }, - startingSkills: ['fireball'], - classSkills: ['fireball', 'ice_storm', 'arcane_blast', 'mana_shield'], + startingSkills: ['shield_bash'], + classSkills: ['shield_bash', 'infinite_guard', 'break_stance'], 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, + type: ClassPassiveType.hpBonus, value: 0.15, - description: '회피율 +15%', - ), - ClassPassive( - type: ClassPassiveType.multiAttack, - value: 1.0, - description: '연속 공격 가능', + description: 'HP +15%', ), ], restriction: EquipmentRestriction( - armorWeight: ArmorWeight.light, + armorWeight: ArmorWeight.heavy, ), ); - /// 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/전투 후 회복 + /// Garbage Collector: CON + STR static const garbageCollector = ClassTraits( classId: 'garbage_collector', name: 'Garbage Collector', @@ -139,17 +159,17 @@ class ClassData { StatType.str: 1, }, startingSkills: ['absorb'], - classSkills: ['absorb', 'recycle', 'memory_leak'], + classSkills: ['absorb', 'recycle', 'memory_sweep'], passives: [ ClassPassive( type: ClassPassiveType.hpBonus, - value: 0.30, - description: 'HP +30%', + value: 0.20, + description: 'HP +20%', ), ClassPassive( type: ClassPassiveType.postCombatHeal, - value: 0.10, - description: '전투 후 HP 10% 회복', + value: 0.05, + description: '전투 후 HP 5% 회복', ), ], restriction: EquipmentRestriction( @@ -157,14 +177,308 @@ class ClassData { ), ); - /// 모든 클래스 목록 + // ========================================================================== + // 마법사 계열 (INT 기반) + // ========================================================================== + + /// Compiler Mage: INT + MP Max + static const compilerMage = ClassTraits( + classId: 'compiler_mage', + name: 'Compiler Mage', + statModifiers: { + StatType.intelligence: 2, + }, + startingSkills: ['fireball'], + classSkills: ['fireball', 'compile_blast', 'syntax_storm'], + passives: [ + ClassPassive( + type: ClassPassiveType.magicDamageBonus, + value: 0.15, + description: '마법 데미지 +15%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// Recursion Master: INT + static const recursionMaster = ClassTraits( + classId: 'recursion_master', + name: 'Recursion Master', + statModifiers: { + StatType.intelligence: 2, + }, + startingSkills: ['fireball'], + classSkills: ['fireball', 'recursive_bolt', 'stack_overflow'], + passives: [ + ClassPassive( + type: ClassPassiveType.magicDamageBonus, + value: 0.20, + description: '마법 데미지 +20%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// Memory Leaker: INT + WIS + static const memoryLeaker = ClassTraits( + classId: 'memory_leaker', + name: 'Memory Leaker', + statModifiers: { + StatType.intelligence: 2, + StatType.wis: 1, + }, + startingSkills: ['fireball'], + classSkills: ['fireball', 'leak_drain', 'memory_corrupt'], + passives: [ + ClassPassive( + type: ClassPassiveType.magicDamageBonus, + value: 0.10, + description: '마법 데미지 +10%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// Type Caster: INT + CHA + static const typeCaster = ClassTraits( + classId: 'type_caster', + name: 'Type Caster', + statModifiers: { + StatType.intelligence: 2, + StatType.cha: 1, + }, + startingSkills: ['fireball'], + classSkills: ['fireball', 'type_coercion', 'cast_spell'], + passives: [ + ClassPassive( + type: ClassPassiveType.magicDamageBonus, + value: 0.10, + description: '마법 데미지 +10%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// DevOps Shaman: CON + INT + static const devOpsShaman = ClassTraits( + classId: 'devops_shaman', + name: 'DevOps Shaman', + statModifiers: { + StatType.con: 1, + StatType.intelligence: 2, + }, + startingSkills: ['fireball'], + classSkills: ['fireball', 'deploy_strike', 'ci_cd_flow'], + passives: [ + ClassPassive( + type: ClassPassiveType.magicDamageBonus, + value: 0.05, + description: '마법 데미지 +5%', + ), + ClassPassive( + type: ClassPassiveType.hpBonus, + value: 0.10, + description: 'HP +10%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + // ========================================================================== + // 민첩 계열 (DEX 기반) + // ========================================================================== + + /// Refactor Monk: DEX + static const refactorMonk = ClassTraits( + classId: 'refactor_monk', + name: 'Refactor Monk', + statModifiers: { + StatType.dex: 2, + }, + startingSkills: ['flurry'], + classSkills: ['flurry', 'clean_code_strike', 'refactor_combo'], + passives: [ + ClassPassive( + type: ClassPassiveType.evasionBonus, + value: 0.10, + description: '회피율 +10%', + ), + ClassPassive( + type: ClassPassiveType.multiAttack, + value: 1.0, + description: '연속 공격', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// Pointer Assassin: DEX + static const pointerAssassin = ClassTraits( + classId: 'pointer_assassin', + name: 'Pointer Assassin', + statModifiers: { + StatType.dex: 2, + }, + startingSkills: ['backstab'], + classSkills: ['backstab', 'null_strike', 'dereference_kill'], + passives: [ + ClassPassive( + type: ClassPassiveType.criticalBonus, + value: 0.15, + description: '크리티컬 +15%', + ), + ClassPassive( + type: ClassPassiveType.firstStrikeBonus, + value: 1.5, + description: '첫 공격 1.5배', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// Callback Samurai: DEX + STR + static const callbackSamurai = ClassTraits( + classId: 'callback_samurai', + name: 'Callback Samurai', + statModifiers: { + StatType.dex: 2, + StatType.str: 1, + }, + startingSkills: ['power_strike'], + classSkills: ['power_strike', 'async_slash', 'promise_blade'], + passives: [ + ClassPassive( + type: ClassPassiveType.criticalBonus, + value: 0.10, + description: '크리티컬 +10%', + ), + ClassPassive( + type: ClassPassiveType.physicalDamageBonus, + value: 0.05, + description: '물리 공격 +5%', + ), + ], + restriction: EquipmentRestriction.none, + ); + + /// Tester Jester: DEX + CHA + static const testerJester = ClassTraits( + classId: 'tester_jester', + name: 'Tester Jester', + statModifiers: { + StatType.dex: 2, + StatType.cha: 1, + }, + startingSkills: ['flurry'], + classSkills: ['flurry', 'mock_strike', 'assert_fail'], + passives: [ + ClassPassive( + type: ClassPassiveType.evasionBonus, + value: 0.10, + description: '회피율 +10%', + ), + ClassPassive( + type: ClassPassiveType.criticalBonus, + value: 0.05, + description: '크리티컬 +5%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + // ========================================================================== + // 지혜 계열 (WIS 기반) + // ========================================================================== + + /// Exception Handler: WIS + static const exceptionHandler = ClassTraits( + classId: 'exception_handler', + name: 'Exception Handler', + statModifiers: { + StatType.wis: 2, + }, + startingSkills: ['heal'], + classSkills: ['heal', 'try_catch', 'finally_heal'], + passives: [ + ClassPassive( + type: ClassPassiveType.healingBonus, + value: 0.15, + description: '회복력 +15%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// Null Checker: WIS + INT + static const nullChecker = ClassTraits( + classId: 'null_checker', + name: 'Null Checker', + statModifiers: { + StatType.wis: 2, + StatType.intelligence: 1, + }, + startingSkills: ['heal'], + classSkills: ['heal', 'null_guard', 'safe_call'], + passives: [ + ClassPassive( + type: ClassPassiveType.healingBonus, + value: 0.10, + description: '회복력 +10%', + ), + ClassPassive( + type: ClassPassiveType.defenseBonus, + value: 0.05, + description: '방어력 +5%', + ), + ], + restriction: EquipmentRestriction( + armorWeight: ArmorWeight.light, + ), + ); + + /// 모든 클래스 목록 (18개) static const List all = [ + // 전사 계열 bugHunter, + overflowWarrior, + stackCrusher, + assertionKnight, + // 탱커 계열 debuggerPaladin, + loopBreaker, + garbageCollector, + // 마법사 계열 compilerMage, + recursionMaster, + memoryLeaker, + typeCaster, + devOpsShaman, + // 민첩 계열 refactorMonk, pointerAssassin, - garbageCollector, + callbackSamurai, + testerJester, + // 지혜 계열 + exceptionHandler, + nullChecker, ]; /// ID로 클래스 찾기 diff --git a/lib/data/race_data.dart b/lib/data/race_data.dart index 4fc9076..bfbbe30 100644 --- a/lib/data/race_data.dart +++ b/lib/data/race_data.dart @@ -2,131 +2,125 @@ import 'package:askiineverdie/src/core/model/race_traits.dart'; /// 종족 데이터 정의 (race data) /// -/// 프로그래밍 테마의 7가지 종족 정의 +/// 프로그래밍 테마의 21가지 종족 정의 +/// pq_config_data.dart의 Races 데이터 기반 class RaceData { RaceData._(); - /// Byte Human: 균형형, 경험치 보너스 + // ========================================================================== + // 기본 종족 (HP/밸런스형) + // ========================================================================== + + /// Byte Human: HP 보너스 static const byteHuman = RaceTraits( raceId: 'byte_human', name: 'Byte Human', - statModifiers: { - StatType.cha: 2, - }, + statModifiers: {}, passives: [ PassiveAbility( - type: PassiveType.expBonus, + type: PassiveType.hpBonus, 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%', + description: 'HP +10%', ), ], ); - /// 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', + /// Kernel Giant: STR + HP 보너스 + static const kernelGiant = RaceTraits( + raceId: 'kernel_giant', + name: 'Kernel Giant', statModifiers: { StatType.str: 3, - StatType.con: 3, StatType.dex: -2, - StatType.intelligence: -2, }, passives: [ PassiveAbility( type: PassiveType.hpBonus, - value: 0.20, - description: 'HP +20%', + value: 0.15, + description: 'HP +15%', ), ], ); - /// Pointer Fairy: 마법형, MP 보너스 - static const pointerFairy = RaceTraits( - raceId: 'pointer_fairy', - name: 'Pointer Fairy', + // ========================================================================== + // 지혜 종족 (WIS 기반) + // ========================================================================== + + /// Null Elf: WIS 보너스 + static const nullElf = RaceTraits( + raceId: 'null_elf', + name: 'Null Elf', statModifiers: { - StatType.str: -2, - StatType.con: -2, - StatType.dex: 2, - StatType.intelligence: 2, StatType.wis: 2, + StatType.con: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.magicDamageBonus, + value: 0.10, + description: '마법 데미지 +10%', + ), + ], + ); + + /// Recursive Sage: WIS + INT 보너스 + static const recursiveSage = RaceTraits( + raceId: 'recursive_sage', + name: 'Recursive Sage', + statModifiers: { + StatType.wis: 2, + StatType.intelligence: 2, + StatType.str: -2, }, passives: [ PassiveAbility( type: PassiveType.mpBonus, - value: 0.20, - description: 'MP +20%', + value: 0.10, + description: 'MP +10%', ), ], ); - /// Coredump Undead: 탱커형, 사망 시 장비 보존 + /// Callback Priest: WIS + CHA 보너스 + static const callbackPriest = RaceTraits( + raceId: 'callback_priest', + name: 'Callback Priest', + statModifiers: { + StatType.wis: 2, + StatType.cha: 2, + StatType.str: -1, + StatType.dex: -1, + }, + passives: [], + ); + + // ========================================================================== + // 체력 종족 (CON 기반) + // ========================================================================== + + /// Buffer Dwarf: CON 보너스 + static const bufferDwarf = RaceTraits( + raceId: 'buffer_dwarf', + name: 'Buffer Dwarf', + statModifiers: { + StatType.con: 2, + StatType.dex: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.defenseBonus, + value: 0.05, + description: '방어력 +5%', + ), + ], + ); + + /// Coredump Undead: CON 보너스 static const coredumpUndead = RaceTraits( raceId: 'coredump_undead', name: 'Coredump Undead', statModifiers: { - StatType.str: 1, StatType.con: 2, - StatType.dex: -1, StatType.cha: -2, }, passives: [ @@ -138,15 +132,267 @@ class RaceData { ], ); - /// 모든 종족 목록 + // ========================================================================== + // 민첩 종족 (DEX 기반) + // ========================================================================== + + /// Bit Halfling: DEX 보너스 + static const bitHalfling = RaceTraits( + raceId: 'bit_halfling', + name: 'Bit Halfling', + statModifiers: { + StatType.dex: 2, + StatType.str: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.criticalBonus, + value: 0.03, + description: '크리티컬 +3%', + ), + ], + ); + + /// Cache Imp: DEX 보너스 + static const cacheImp = RaceTraits( + raceId: 'cache_imp', + name: 'Cache Imp', + statModifiers: { + StatType.dex: 2, + StatType.con: -1, + }, + passives: [], + ); + + /// Iterator Rogue: DEX 보너스 + static const iteratorRogue = RaceTraits( + raceId: 'iterator_rogue', + name: 'Iterator Rogue', + statModifiers: { + StatType.dex: 2, + StatType.wis: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.criticalBonus, + value: 0.05, + description: '크리티컬 +5%', + ), + ], + ); + + // ========================================================================== + // 힘 종족 (STR 기반) + // ========================================================================== + + /// Array Orc: STR 보너스 + static const arrayOrc = RaceTraits( + raceId: 'array_orc', + name: 'Array Orc', + statModifiers: { + StatType.str: 2, + StatType.intelligence: -1, + }, + passives: [], + ); + + /// Flag Knight: CHA + STR 보너스 + static const flagKnight = RaceTraits( + raceId: 'flag_knight', + name: 'Flag Knight', + statModifiers: { + StatType.cha: 2, + StatType.str: 2, + StatType.intelligence: -2, + }, + passives: [], + ); + + /// Protocol Paladin: STR + CHA 보너스 + static const protocolPaladin = RaceTraits( + raceId: 'protocol_paladin', + name: 'Protocol Paladin', + statModifiers: { + StatType.str: 2, + StatType.cha: 2, + StatType.dex: -2, + }, + passives: [ + PassiveAbility( + type: PassiveType.defenseBonus, + value: 0.05, + description: '방어력 +5%', + ), + ], + ); + + // ========================================================================== + // 복합 스탯 종족 + // ========================================================================== + + /// Stack Goblin: DEX + CON 보너스 + static const stackGoblin = RaceTraits( + raceId: 'stack_goblin', + name: 'Stack Goblin', + statModifiers: { + StatType.dex: 2, + StatType.con: 1, + StatType.cha: -2, + }, + passives: [], + ); + + /// Heap Troll: CON + STR 보너스 + static const heapTroll = RaceTraits( + raceId: 'heap_troll', + name: 'Heap Troll', + statModifiers: { + StatType.con: 2, + StatType.str: 2, + StatType.intelligence: -2, + StatType.dex: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.hpBonus, + value: 0.10, + description: 'HP +10%', + ), + ], + ); + + /// Index Ranger: DEX + CON 보너스 + static const indexRanger = RaceTraits( + raceId: 'index_ranger', + name: 'Index Ranger', + statModifiers: { + StatType.dex: 2, + StatType.con: 1, + StatType.intelligence: -1, + }, + passives: [], + ); + + // ========================================================================== + // 마법 종족 (MP/INT 기반) + // ========================================================================== + + /// Pointer Fairy: MP Max + WIS 보너스 + static const pointerFairy = RaceTraits( + raceId: 'pointer_fairy', + name: 'Pointer Fairy', + statModifiers: { + StatType.wis: 2, + StatType.str: -2, + }, + passives: [ + PassiveAbility( + type: PassiveType.mpBonus, + value: 0.15, + description: 'MP +15%', + ), + ], + ); + + /// Register Gnome: INT 보너스 + static const registerGnome = RaceTraits( + raceId: 'register_gnome', + name: 'Register Gnome', + statModifiers: { + StatType.intelligence: 2, + StatType.str: -1, + }, + passives: [], + ); + + /// Thread Spirit: MP Max 보너스 + static const threadSpirit = RaceTraits( + raceId: 'thread_spirit', + name: 'Thread Spirit', + statModifiers: { + StatType.con: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.mpBonus, + value: 0.20, + description: 'MP +20%', + ), + ], + ); + + /// Loop Wizard: INT + MP Max 보너스 + static const loopWizard = RaceTraits( + raceId: 'loop_wizard', + name: 'Loop Wizard', + statModifiers: { + StatType.intelligence: 2, + StatType.str: -1, + StatType.con: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.mpBonus, + value: 0.10, + description: 'MP +10%', + ), + PassiveAbility( + type: PassiveType.magicDamageBonus, + value: 0.05, + description: '마법 데미지 +5%', + ), + ], + ); + + /// Lambda Druid: INT + WIS 보너스 + static const lambdaDruid = RaceTraits( + raceId: 'lambda_druid', + name: 'Lambda Druid', + statModifiers: { + StatType.intelligence: 2, + StatType.wis: 2, + StatType.str: -2, + StatType.con: -1, + }, + passives: [ + PassiveAbility( + type: PassiveType.magicDamageBonus, + value: 0.10, + description: '마법 데미지 +10%', + ), + ], + ); + + /// 모든 종족 목록 (21개) static const List all = [ + // 기본/HP형 byteHuman, + kernelGiant, + // 지혜형 nullElf, + recursiveSage, + callbackPriest, + // 체력형 bufferDwarf, + coredumpUndead, + // 민첩형 + bitHalfling, + cacheImp, + iteratorRogue, + // 힘형 + arrayOrc, + flagKnight, + protocolPaladin, + // 복합형 stackGoblin, heapTroll, + indexRanger, + // 마법형 pointerFairy, - coredumpUndead, + registerGnome, + threadSpirit, + loopWizard, + lambdaDruid, ]; /// ID로 종족 찾기