feat(death): 사망/부활 시스템 개선

- DeathInfo에 lostItem 필드 추가 (광고 부활 시 복구용)
- 세이브 데이터 v4: MonetizationState 포함
- 사망 오버레이 UI 개선
- 부활 서비스 광고 연동
This commit is contained in:
JiWoong Sul
2026-01-16 20:09:52 +09:00
parent b272ef8f08
commit b6d5cd2abd
5 changed files with 309 additions and 67 deletions

View File

@@ -133,6 +133,7 @@ class DeathInfo {
this.lostItemName,
this.lostItemSlot,
this.lostItemRarity,
this.lostItem,
this.lastCombatEvents = const [],
});
@@ -154,6 +155,9 @@ class DeathInfo {
/// 제물로 바친 아이템 희귀도 (null이면 없음)
final ItemRarity? lostItemRarity;
/// 상실한 장비 전체 정보 (광고 부활 시 복구용)
final EquipmentItem? lostItem;
/// 사망 시점 골드
final int goldAtDeath;
@@ -173,6 +177,7 @@ class DeathInfo {
String? lostItemName,
EquipmentSlot? lostItemSlot,
ItemRarity? lostItemRarity,
EquipmentItem? lostItem,
int? goldAtDeath,
int? levelAtDeath,
int? timestamp,
@@ -185,6 +190,7 @@ class DeathInfo {
lostItemName: lostItemName ?? this.lostItemName,
lostItemSlot: lostItemSlot ?? this.lostItemSlot,
lostItemRarity: lostItemRarity ?? this.lostItemRarity,
lostItem: lostItem ?? this.lostItem,
goldAtDeath: goldAtDeath ?? this.goldAtDeath,
levelAtDeath: levelAtDeath ?? this.levelAtDeath,
timestamp: timestamp ?? this.timestamp,

View File

@@ -2,6 +2,7 @@ import 'dart:collection';
import 'package:asciineverdie/src/core/model/equipment_item.dart';
import 'package:asciineverdie/src/core/model/equipment_slot.dart';
import 'package:asciineverdie/src/core/model/monetization_state.dart';
import 'package:asciineverdie/src/core/model/monster_grade.dart';
import 'package:asciineverdie/src/core/util/deterministic_random.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
@@ -9,7 +10,8 @@ import 'package:asciineverdie/src/core/model/game_state.dart';
/// 세이브 파일 버전
/// - v2: 장비 이름만 저장 (레거시)
/// - v3: 장비 전체 정보 저장 (level, rarity, stats 포함)
const int kSaveVersion = 3;
/// - v4: MonetizationState 추가, DeathInfo.lostItem 추가
const int kSaveVersion = 4;
class GameSave {
GameSave({
@@ -23,9 +25,14 @@ class GameSave {
required this.progress,
required this.queue,
this.cheatsEnabled = false,
this.monetization,
});
factory GameSave.fromState(GameState state, {bool cheatsEnabled = false}) {
factory GameSave.fromState(
GameState state, {
bool cheatsEnabled = false,
MonetizationState? monetization,
}) {
return GameSave(
version: kSaveVersion,
rngState: state.rng.state,
@@ -37,6 +44,7 @@ class GameSave {
progress: state.progress,
queue: state.queue,
cheatsEnabled: cheatsEnabled,
monetization: monetization,
);
}
@@ -51,6 +59,9 @@ class GameSave {
final QueueState queue;
final bool cheatsEnabled;
/// 수익화 시스템 상태 (v4+)
final MonetizationState? monetization;
Map<String, dynamic> toJson() {
return {
'version': version,
@@ -132,6 +143,7 @@ class GameSave {
},
)
.toList(),
if (monetization != null) 'monetization': monetization!.toJson(),
};
}
@@ -244,6 +256,9 @@ class GameSave {
}),
),
),
monetization: _monetizationFromJson(
json['monetization'] as Map<String, dynamic>?,
),
);
}
@@ -355,3 +370,12 @@ Equipment _equipmentFromJson(Map<String, dynamic> json, int version) {
bestIndex: json['bestIndex'] as int? ?? 0,
);
}
/// MonetizationState 역직렬화 (v4+ 마이그레이션)
///
/// - v3 이하: null (기본값 사용)
/// - v4 이상: 저장된 상태 로드
MonetizationState? _monetizationFromJson(Map<String, dynamic>? json) {
if (json == null) return null;
return MonetizationState.fromJson(json);
}