diff --git a/lib/src/core/engine/ad_service.dart b/lib/src/core/engine/ad_service.dart index e5f9c13..47e1685 100644 --- a/lib/src/core/engine/ad_service.dart +++ b/lib/src/core/engine/ad_service.dart @@ -5,6 +5,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; +import 'package:asciineverdie/src/core/engine/iap_service.dart'; + /// 광고 타입 enum AdType { /// 부활용 리워드 광고 (30초) @@ -105,9 +107,6 @@ class AdService { bool _isInitialized = false; - /// 디버그 모드에서 광고 활성화 여부 - bool _debugAdEnabled = true; - /// 로드된 리워드 광고 RewardedAd? _rewardedAd; @@ -144,23 +143,14 @@ class AdService { } // =========================================================================== - // 디버그 설정 + // 광고 스킵 판정 // =========================================================================== - /// 디버그 모드 광고 활성화 여부 - bool get debugAdEnabled => _debugAdEnabled; - - /// 디버그 모드 광고 토글 - set debugAdEnabled(bool value) { - _debugAdEnabled = value; - debugPrint('[AdService] Debug ad enabled: $value'); - } - /// 광고를 스킵할지 여부 /// /// 스킵 조건: /// - 비모바일 플랫폼 (macOS, Windows, Linux, Web) - /// - 디버그 모드에서 광고 비활성화 + /// - IAP로 광고 제거 구매 완료 (디버그 시뮬레이션 포함) bool get _shouldSkipAd { // 웹에서는 항상 스킵 if (kIsWeb) return true; @@ -168,8 +158,9 @@ class AdService { if (!Platform.isAndroid && !Platform.isIOS) { return true; } - // 디버그 모드에서 광고 비활성화 시 스킵 - return kDebugMode && !_debugAdEnabled; + // IAP 광고 제거 구매 시 스킵 (디버그 시뮬레이션 포함) + if (IAPService.instance.isAdRemovalPurchased) return true; + return false; } // =========================================================================== @@ -195,7 +186,9 @@ class AdService { }, onAdFailedToLoad: (error) { _isLoadingRewardedAd = false; - debugPrint('[AdService] Rewarded ad failed to load: ${error.message}'); + debugPrint( + '[AdService] Rewarded ad failed to load: ${error.message}', + ); }, ), ); @@ -249,7 +242,9 @@ class AdService { _loadRewardedAd(); // 다음 광고 미리 로드 // 보상 수령 여부에 따라 결과 반환 if (!completer.isCompleted) { - completer.complete(rewarded ? AdResult.completed : AdResult.cancelled); + completer.complete( + rewarded ? AdResult.completed : AdResult.cancelled, + ); } }, onAdFailedToShowFullScreenContent: (ad, error) { diff --git a/lib/src/core/engine/character_roll_service.dart b/lib/src/core/engine/character_roll_service.dart index 0380546..c01479f 100644 --- a/lib/src/core/engine/character_roll_service.dart +++ b/lib/src/core/engine/character_roll_service.dart @@ -143,11 +143,10 @@ class CharacterRollService { _rollsRemaining--; _saveRollsRemaining(); - // 무료 유저: 새 굴리기마다 되돌리기 기회 1회 부여 (광고 시청 필요) - // 유료 유저: 세션당 최대 횟수 유지 - if (!_isPaidUser && _undoRemaining < maxUndoFreeUser) { - _undoRemaining = maxUndoFreeUser; - } + // 매 굴림마다 되돌리기 횟수 리셋 + // - 유료 유저: 3회 + // - 무료 유저: 1회 (광고 시청 필요) + _undoRemaining = _isPaidUser ? maxUndoPaidUser : maxUndoFreeUser; debugPrint('[CharacterRollService] Rolled: remaining=$_rollsRemaining, ' 'history=${_rollHistory.length}, undo=$_undoRemaining'); diff --git a/lib/src/core/engine/debug_settings_service.dart b/lib/src/core/engine/debug_settings_service.dart index 330c63d..adf257d 100644 --- a/lib/src/core/engine/debug_settings_service.dart +++ b/lib/src/core/engine/debug_settings_service.dart @@ -1,7 +1,6 @@ import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:asciineverdie/src/core/engine/ad_service.dart'; import 'package:asciineverdie/src/core/engine/iap_service.dart'; /// 디버그 설정 서비스 (Phase 8) @@ -23,7 +22,6 @@ class DebugSettingsService { // 상수 // =========================================================================== - static const String _keyAdEnabled = 'debug_ad_enabled'; static const String _keyIapSimulated = 'debug_iap_simulated'; static const String _keyOfflineHours = 'debug_offline_hours'; @@ -36,9 +34,6 @@ class DebugSettingsService { bool _isInitialized = false; - /// 광고 활성화 여부 (디버그 모드 전용) - bool _adEnabled = true; - /// IAP 구매 시뮬레이션 여부 (디버그 모드 전용) bool _iapSimulated = false; @@ -58,7 +53,6 @@ class DebugSettingsService { } final prefs = await SharedPreferences.getInstance(); - _adEnabled = prefs.getBool(_keyAdEnabled) ?? true; _iapSimulated = prefs.getBool(_keyIapSimulated) ?? false; _offlineHours = prefs.getInt(_keyOfflineHours) ?? 0; @@ -66,13 +60,14 @@ class DebugSettingsService { _syncToServices(); _isInitialized = true; - debugPrint('[DebugSettings] Initialized: ad=$_adEnabled, ' - 'iap=$_iapSimulated, offline=$_offlineHours'); + debugPrint( + '[DebugSettings] Initialized: ' + 'iap=$_iapSimulated, offline=$_offlineHours', + ); } /// 설정을 다른 서비스에 동기화 void _syncToServices() { - AdService.instance.debugAdEnabled = _adEnabled; IAPService.instance.debugIAPSimulated = _iapSimulated; } @@ -83,29 +78,6 @@ class DebugSettingsService { /// 디버그 모드 활성화 여부 bool get isDebugMode => kDebugMode; - // =========================================================================== - // 광고 설정 - // =========================================================================== - - /// 광고 활성화 여부 - /// - /// - true: 실제 광고 표시 - /// - false: 광고 버튼 클릭 시 바로 보상 지급 - bool get adEnabled => _adEnabled; - - /// 광고 활성화 토글 - Future setAdEnabled(bool value) async { - if (!kDebugMode) return; - - _adEnabled = value; - AdService.instance.debugAdEnabled = value; - - final prefs = await SharedPreferences.getInstance(); - await prefs.setBool(_keyAdEnabled, value); - - debugPrint('[DebugSettings] Ad enabled: $value'); - } - // =========================================================================== // IAP 설정 // =========================================================================== @@ -171,7 +143,6 @@ class DebugSettingsService { Future resetAll() async { if (!kDebugMode) return; - await setAdEnabled(true); await setIapSimulated(false); await setOfflineHours(0); diff --git a/lib/src/core/engine/stat_calculator.dart b/lib/src/core/engine/stat_calculator.dart index 53cb0b9..4dacefb 100644 --- a/lib/src/core/engine/stat_calculator.dart +++ b/lib/src/core/engine/stat_calculator.dart @@ -187,17 +187,6 @@ class StatCalculator { return bonus > 0 ? bonus : 1.0; } - /// 사망 시 보존할 장비 개수 (Coredump Undead 패시브) - /// - /// [race] 종족 특성 - /// Returns: 보존 장비 개수 - int calculateDeathEquipmentPreserve(RaceTraits race) { - if (race.hasPassive(PassiveType.deathEquipmentPreserve)) { - return race.getPassiveValue(PassiveType.deathEquipmentPreserve).round(); - } - return 0; - } - /// 연속 공격 가능 여부 (Refactor Monk 패시브) bool hasMultiAttack(ClassTraits klass) { return klass.hasPassive(ClassPassiveType.multiAttack);