feat(ui): 도움말 다이얼로그 및 UI 개선
- HelpDialog 추가 - 게임 화면에 통계/도움말 버튼 추가 - CombatLog에 디버프 이벤트 표시 - AudioService mp3 확장자 지원 - 설정 텍스트 l10n 추가
This commit is contained in:
@@ -5,7 +5,9 @@ import 'package:askiineverdie/src/core/engine/progress_service.dart';
|
||||
import 'package:askiineverdie/src/core/engine/resurrection_service.dart';
|
||||
import 'package:askiineverdie/src/core/engine/shop_service.dart';
|
||||
import 'package:askiineverdie/src/core/model/game_state.dart';
|
||||
import 'package:askiineverdie/src/core/model/game_statistics.dart';
|
||||
import 'package:askiineverdie/src/core/storage/save_manager.dart';
|
||||
import 'package:askiineverdie/src/core/storage/statistics_storage.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
enum GameSessionStatus { idle, loading, running, error, dead }
|
||||
@@ -18,12 +20,15 @@ class GameSessionController extends ChangeNotifier {
|
||||
this.autoSaveConfig = const AutoSaveConfig(),
|
||||
Duration tickInterval = const Duration(milliseconds: 50),
|
||||
DateTime Function()? now,
|
||||
StatisticsStorage? statisticsStorage,
|
||||
}) : _tickInterval = tickInterval,
|
||||
_now = now ?? DateTime.now;
|
||||
_now = now ?? DateTime.now,
|
||||
_statisticsStorage = statisticsStorage ?? StatisticsStorage();
|
||||
|
||||
final ProgressService progressService;
|
||||
final SaveManager saveManager;
|
||||
final AutoSaveConfig autoSaveConfig;
|
||||
final StatisticsStorage _statisticsStorage;
|
||||
|
||||
final Duration _tickInterval;
|
||||
final DateTime Function() _now;
|
||||
@@ -36,12 +41,26 @@ class GameSessionController extends ChangeNotifier {
|
||||
GameState? _state;
|
||||
String? _error;
|
||||
|
||||
// 통계 관련 필드
|
||||
SessionStatistics _sessionStats = SessionStatistics.empty();
|
||||
CumulativeStatistics _cumulativeStats = CumulativeStatistics.empty();
|
||||
int _previousLevel = 0;
|
||||
int _previousGold = 0;
|
||||
int _previousMonstersKilled = 0;
|
||||
int _previousQuestsCompleted = 0;
|
||||
|
||||
GameSessionStatus get status => _status;
|
||||
GameState? get state => _state;
|
||||
String? get error => _error;
|
||||
bool get isRunning => _status == GameSessionStatus.running;
|
||||
bool get cheatsEnabled => _cheatsEnabled;
|
||||
|
||||
/// 현재 세션 통계
|
||||
SessionStatistics get sessionStats => _sessionStats;
|
||||
|
||||
/// 누적 통계
|
||||
CumulativeStatistics get cumulativeStats => _cumulativeStats;
|
||||
|
||||
/// 현재 ProgressLoop 인스턴스 (치트 기능용)
|
||||
ProgressLoop? get loop => _loop;
|
||||
|
||||
@@ -62,6 +81,13 @@ class GameSessionController extends ChangeNotifier {
|
||||
_status = GameSessionStatus.running;
|
||||
_cheatsEnabled = cheatsEnabled;
|
||||
|
||||
// 통계 초기화
|
||||
if (isNewGame) {
|
||||
_sessionStats = SessionStatistics.empty();
|
||||
await _statisticsStorage.recordGameStart();
|
||||
}
|
||||
_initPreviousValues(state);
|
||||
|
||||
_loop = ProgressLoop(
|
||||
initialState: state,
|
||||
progressService: progressService,
|
||||
@@ -74,6 +100,7 @@ class GameSessionController extends ChangeNotifier {
|
||||
);
|
||||
|
||||
_subscription = _loop!.stream.listen((next) {
|
||||
_updateStatistics(next);
|
||||
_state = next;
|
||||
notifyListeners();
|
||||
});
|
||||
@@ -82,6 +109,76 @@ class GameSessionController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// 이전 값 초기화 (통계 변화 추적용)
|
||||
void _initPreviousValues(GameState state) {
|
||||
_previousLevel = state.traits.level;
|
||||
_previousGold = state.inventory.gold;
|
||||
_previousMonstersKilled = state.progress.monstersKilled;
|
||||
_previousQuestsCompleted = state.progress.questCount;
|
||||
}
|
||||
|
||||
/// 상태 변화에 따른 통계 업데이트
|
||||
void _updateStatistics(GameState next) {
|
||||
// 플레이 시간 업데이트
|
||||
_sessionStats = _sessionStats.updatePlayTime(next.skillSystem.elapsedMs);
|
||||
|
||||
// 레벨업 감지
|
||||
if (next.traits.level > _previousLevel) {
|
||||
final levelUps = next.traits.level - _previousLevel;
|
||||
for (var i = 0; i < levelUps; i++) {
|
||||
_sessionStats = _sessionStats.recordLevelUp();
|
||||
}
|
||||
_previousLevel = next.traits.level;
|
||||
|
||||
// 최고 레벨 업데이트
|
||||
unawaited(_statisticsStorage.updateHighestLevel(next.traits.level));
|
||||
}
|
||||
|
||||
// 골드 변화 감지
|
||||
if (next.inventory.gold > _previousGold) {
|
||||
final earned = next.inventory.gold - _previousGold;
|
||||
_sessionStats = _sessionStats.recordGoldEarned(earned);
|
||||
|
||||
// 최대 골드 업데이트
|
||||
unawaited(_statisticsStorage.updateHighestGold(next.inventory.gold));
|
||||
} else if (next.inventory.gold < _previousGold) {
|
||||
final spent = _previousGold - next.inventory.gold;
|
||||
_sessionStats = _sessionStats.recordGoldSpent(spent);
|
||||
}
|
||||
_previousGold = next.inventory.gold;
|
||||
|
||||
// 몬스터 처치 감지
|
||||
if (next.progress.monstersKilled > _previousMonstersKilled) {
|
||||
final kills = next.progress.monstersKilled - _previousMonstersKilled;
|
||||
for (var i = 0; i < kills; i++) {
|
||||
_sessionStats = _sessionStats.recordKill();
|
||||
}
|
||||
_previousMonstersKilled = next.progress.monstersKilled;
|
||||
}
|
||||
|
||||
// 퀘스트 완료 감지
|
||||
if (next.progress.questCount > _previousQuestsCompleted) {
|
||||
final quests = next.progress.questCount - _previousQuestsCompleted;
|
||||
for (var i = 0; i < quests; i++) {
|
||||
_sessionStats = _sessionStats.recordQuestComplete();
|
||||
}
|
||||
_previousQuestsCompleted = next.progress.questCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// 누적 통계 로드
|
||||
Future<void> loadCumulativeStats() async {
|
||||
_cumulativeStats = await _statisticsStorage.loadCumulative();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// 세션 통계를 누적 통계에 병합
|
||||
Future<void> mergeSessionStats() async {
|
||||
await _statisticsStorage.mergeSession(_sessionStats);
|
||||
_cumulativeStats = await _statisticsStorage.loadCumulative();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> loadAndStart({
|
||||
String? fileName,
|
||||
bool cheatsEnabled = false,
|
||||
@@ -148,6 +245,7 @@ class GameSessionController extends ChangeNotifier {
|
||||
|
||||
/// 플레이어 사망 콜백 (ProgressLoop에서 호출)
|
||||
void _onPlayerDied() {
|
||||
_sessionStats = _sessionStats.recordDeath();
|
||||
_status = GameSessionStatus.dead;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user