feat(game): 포션 시스템 및 UI 패널 추가
- 포션 시스템 구현 (PotionService, Potion 모델) - 포션 인벤토리 패널 위젯 - 활성 버프 패널 위젯 - 장비 스탯 패널 위젯 - 스킬 시스템 확장 - 일본어 번역 추가 - 전투 이벤트/상태 모델 개선
This commit is contained in:
@@ -20,7 +20,10 @@ import 'package:askiineverdie/src/features/game/widgets/hp_mp_bar.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/notification_overlay.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/skill_panel.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/stats_panel.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/equipment_stats_panel.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/potion_inventory_panel.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/task_progress_panel.dart';
|
||||
import 'package:askiineverdie/src/features/game/widgets/active_buff_panel.dart';
|
||||
|
||||
/// 게임 진행 화면 (Main.dfm 기반 3패널 레이아웃)
|
||||
///
|
||||
@@ -199,6 +202,18 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
'${event.skillName} activated!',
|
||||
CombatLogType.buff,
|
||||
),
|
||||
CombatEventType.dotTick => (
|
||||
'${event.skillName} ticks for ${event.damage} damage',
|
||||
CombatLogType.dotTick,
|
||||
),
|
||||
CombatEventType.playerPotion => (
|
||||
'${event.skillName}: +${event.healAmount} ${event.targetName}',
|
||||
CombatLogType.potion,
|
||||
),
|
||||
CombatEventType.potionDrop => (
|
||||
'Dropped: ${event.skillName}',
|
||||
CombatLogType.potionDrop,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -534,6 +549,15 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
// Phase 8: 스킬 (Skills with cooldown glow)
|
||||
_buildSectionHeader('Skills'),
|
||||
Expanded(flex: 2, child: SkillPanel(skillSystem: state.skillSystem)),
|
||||
|
||||
// 활성 버프 (Active Buffs)
|
||||
_buildSectionHeader('Buffs'),
|
||||
Expanded(
|
||||
child: ActiveBuffPanel(
|
||||
activeBuffs: state.skillSystem.activeBuffs,
|
||||
currentMs: state.skillSystem.elapsedMs,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -549,12 +573,25 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
children: [
|
||||
_buildPanelHeader(l10n.equipment),
|
||||
|
||||
// Equipment 목록
|
||||
Expanded(flex: 2, child: _buildEquipmentList(state)),
|
||||
// Equipment 목록 (확장 가능 스탯 패널)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: EquipmentStatsPanel(equipment: state.equipment),
|
||||
),
|
||||
|
||||
// Inventory
|
||||
_buildPanelHeader(l10n.inventory),
|
||||
Expanded(flex: 2, child: _buildInventoryList(state)),
|
||||
Expanded(child: _buildInventoryList(state)),
|
||||
|
||||
// Potions (물약 인벤토리)
|
||||
_buildSectionHeader('Potions'),
|
||||
Expanded(
|
||||
child: PotionInventoryPanel(
|
||||
inventory: state.potionInventory,
|
||||
usedInBattle:
|
||||
state.progress.currentCombat?.usedPotionTypes ?? const {},
|
||||
),
|
||||
),
|
||||
|
||||
// Encumbrance 바
|
||||
_buildSectionHeader(l10n.encumbrance),
|
||||
@@ -729,58 +766,6 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEquipmentList(GameState state) {
|
||||
// 원본 Main.dfm Equips ListView - 11개 슬롯
|
||||
// (슬롯 레이블, 장비 이름, 슬롯 인덱스) 튜플
|
||||
final l10n = L10n.of(context);
|
||||
final equipment = [
|
||||
(l10n.equipWeapon, state.equipment.weapon, 0),
|
||||
(l10n.equipShield, state.equipment.shield, 1),
|
||||
(l10n.equipHelm, state.equipment.helm, 2),
|
||||
(l10n.equipHauberk, state.equipment.hauberk, 3),
|
||||
(l10n.equipBrassairts, state.equipment.brassairts, 4),
|
||||
(l10n.equipVambraces, state.equipment.vambraces, 5),
|
||||
(l10n.equipGauntlets, state.equipment.gauntlets, 6),
|
||||
(l10n.equipGambeson, state.equipment.gambeson, 7),
|
||||
(l10n.equipCuisses, state.equipment.cuisses, 8),
|
||||
(l10n.equipGreaves, state.equipment.greaves, 9),
|
||||
(l10n.equipSollerets, state.equipment.sollerets, 10),
|
||||
];
|
||||
|
||||
return ListView.builder(
|
||||
itemCount: equipment.length,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
itemBuilder: (context, index) {
|
||||
final equip = equipment[index];
|
||||
// 장비 이름 번역 (슬롯 인덱스 사용)
|
||||
final translatedName = equip.$2.isNotEmpty
|
||||
? GameDataL10n.translateEquipString(context, equip.$2, equip.$3)
|
||||
: '-';
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 60,
|
||||
child: Text(equip.$1, style: const TextStyle(fontSize: 11)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
translatedName,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInventoryList(GameState state) {
|
||||
final l10n = L10n.of(context);
|
||||
if (state.inventory.items.isEmpty) {
|
||||
|
||||
Reference in New Issue
Block a user