feat(core): 장비 시스템 및 게임 상태 모델 확장

- Equipment 클래스를 11개 슬롯으로 확장 (원본 Main.dfm 충실)
- TaskInfo에 몬스터 정보(baseName, part) 추가
- Stats에 현재 HP/MP 필드 추가
- 히스토리 기능 구현 (plotHistory, questHistory)
- pq_logic winEquip/winStatIndex 원본 로직 개선
- 퀘스트 몬스터 처리 로직 구현
- SaveData 직렬화 확장
This commit is contained in:
JiWoong Sul
2025-12-09 22:30:37 +09:00
parent b512fde1fb
commit b450bf2600
12 changed files with 571 additions and 208 deletions

View File

@@ -63,6 +63,8 @@ class GameSave {
'cha': stats.cha,
'hpMax': stats.hpMax,
'mpMax': stats.mpMax,
'hpCurrent': stats.hpCurrent,
'mpCurrent': stats.mpCurrent,
},
'inventory': {
'gold': inventory.gold,
@@ -73,7 +75,15 @@ class GameSave {
'equipment': {
'weapon': equipment.weapon,
'shield': equipment.shield,
'armor': equipment.armor,
'helm': equipment.helm,
'hauberk': equipment.hauberk,
'brassairts': equipment.brassairts,
'vambraces': equipment.vambraces,
'gauntlets': equipment.gauntlets,
'gambeson': equipment.gambeson,
'cuisses': equipment.cuisses,
'greaves': equipment.greaves,
'sollerets': equipment.sollerets,
'bestIndex': equipment.bestIndex,
},
'spells': spellBook.spells
@@ -88,9 +98,23 @@ class GameSave {
'taskInfo': {
'caption': progress.currentTask.caption,
'type': progress.currentTask.type.name,
'monsterBaseName': progress.currentTask.monsterBaseName,
'monsterPart': progress.currentTask.monsterPart,
},
'plotStages': progress.plotStageCount,
'questCount': progress.questCount,
'plotHistory': progress.plotHistory
.map((e) => {'caption': e.caption, 'complete': e.isComplete})
.toList(),
'questHistory': progress.questHistory
.map((e) => {'caption': e.caption, 'complete': e.isComplete})
.toList(),
'questMonster': progress.currentQuestMonster != null
? {
'data': progress.currentQuestMonster!.monsterData,
'index': progress.currentQuestMonster!.monsterIndex,
}
: null,
},
'queue': queue.entries
.map(
@@ -134,6 +158,8 @@ class GameSave {
cha: statsJson['cha'] as int? ?? 0,
hpMax: statsJson['hpMax'] as int? ?? 0,
mpMax: statsJson['mpMax'] as int? ?? 0,
hpCurrent: statsJson['hpCurrent'] as int?,
mpCurrent: statsJson['mpCurrent'] as int?,
),
inventory: Inventory(
gold: inventoryJson['gold'] as int? ?? 0,
@@ -149,7 +175,15 @@ class GameSave {
equipment: Equipment(
weapon: equipmentJson['weapon'] as String? ?? 'Sharp Stick',
shield: equipmentJson['shield'] as String? ?? '',
armor: equipmentJson['armor'] as String? ?? '',
helm: equipmentJson['helm'] as String? ?? '',
hauberk: equipmentJson['hauberk'] as String? ?? '',
brassairts: equipmentJson['brassairts'] as String? ?? '',
vambraces: equipmentJson['vambraces'] as String? ?? '',
gauntlets: equipmentJson['gauntlets'] as String? ?? '',
gambeson: equipmentJson['gambeson'] as String? ?? '',
cuisses: equipmentJson['cuisses'] as String? ?? '',
greaves: equipmentJson['greaves'] as String? ?? '',
sollerets: equipmentJson['sollerets'] as String? ?? '',
bestIndex: equipmentJson['bestIndex'] as int? ?? 0,
),
spellBook: SpellBook(
@@ -178,6 +212,15 @@ class GameSave {
),
plotStageCount: progressJson['plotStages'] as int? ?? 1,
questCount: progressJson['questCount'] as int? ?? 0,
plotHistory: _historyListFromJson(
progressJson['plotHistory'] as List<dynamic>?,
),
questHistory: _historyListFromJson(
progressJson['questHistory'] as List<dynamic>?,
),
currentQuestMonster: _questMonsterFromJson(
progressJson['questMonster'] as Map<String, dynamic>?,
),
),
queue: QueueState(
entries: Queue<QueueEntry>.from(
@@ -233,5 +276,29 @@ TaskInfo _taskInfoFromJson(Map<String, dynamic> json) {
(t) => t.name == typeName,
orElse: () => TaskType.neutral,
);
return TaskInfo(caption: json['caption'] as String? ?? '', type: type);
return TaskInfo(
caption: json['caption'] as String? ?? '',
type: type,
monsterBaseName: json['monsterBaseName'] as String?,
monsterPart: json['monsterPart'] as String?,
);
}
List<HistoryEntry> _historyListFromJson(List<dynamic>? json) {
if (json == null || json.isEmpty) return [];
return json.map((e) {
final m = e as Map<String, dynamic>;
return HistoryEntry(
caption: m['caption'] as String? ?? '',
isComplete: m['complete'] as bool? ?? false,
);
}).toList();
}
QuestMonsterInfo? _questMonsterFromJson(Map<String, dynamic>? json) {
if (json == null) return null;
return QuestMonsterInfo(
monsterData: json['data'] as String? ?? '',
monsterIndex: json['index'] as int? ?? -1,
);
}