- adjust risky animation offset
 - show inventory in shop
This commit is contained in:
2025-12-09 11:47:37 +09:00
parent d544f46766
commit ac4df02654
8 changed files with 726 additions and 649 deletions
+27 -67
View File
@@ -2,7 +2,7 @@ import 'dart:async'; // StreamController 사용을 위해 import
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; // For context.read in _prepareNextStage
import '../game/model/entity.dart';
import '../game/model/item.dart';
import '../game/model/status_effect.dart';
@@ -214,11 +214,10 @@ class BattleProvider with ChangeNotifier {
if (!isPlayerTurn || player.isDead || enemy.isDead || showRewardPopup)
return;
// 0. Apply Enemy Pre-emptive Defense - REMOVED (Standard Turn-Based Logic)
// Defense now happens on Enemy's Turn.
// 0. Ensure Pre-emptive Enemy Defense is applied (if not already via animation)
applyPendingEnemyDefense();
// Update Enemy Status Effects at the start of Player's turn (user request)
enemy.updateStatusEffects(); // 1. Check for Defense Forbidden status
if (type == ActionType.defend &&
player.hasStatus(StatusEffectType.defenseForbidden)) {
@@ -375,23 +374,10 @@ class BattleProvider with ChangeNotifier {
}
// [New] Apply Pre-emptive Enemy Intent (Defense/Buffs)
// MOVED: Logic moved to applyPendingEnemyDefense() to sync with animation.
// We just check intent existence here but do NOT apply effects yet.
if (currentEnemyIntent != null) {
final intent = currentEnemyIntent!;
if (intent.type == EnemyActionType.defend) {
if (intent.isSuccess) {
enemy.armor += intent.finalValue;
_addLog(
"${enemy.name} assumes a defensive stance (+${intent.finalValue} Armor).",
);
} else {
_addLog("${enemy.name} tried to defend but failed.");
// Optional: Emit failed defense visual?
// For now, let's keep it simple as log only for failure, or add visual later.
}
intent.isApplied = true; // Mark as applied so we don't do it again
}
// Add other pre-emptive intent types here if needed (e.g., Buffs)
// Intent generated, waiting for player interaction or action to apply.
}
isPlayerTurn = true;
@@ -774,6 +760,26 @@ class BattleProvider with ChangeNotifier {
notifyListeners();
}
/// Ensure the enemy's pending defense is applied.
/// Called manually by UI during animation, or auto-called by playerAction as fallback.
void applyPendingEnemyDefense() {
if (currentEnemyIntent != null &&
currentEnemyIntent!.type == EnemyActionType.defend &&
!currentEnemyIntent!.isApplied) {
final intent = currentEnemyIntent!;
if (intent.isSuccess) {
enemy.armor += intent.finalValue;
_addLog(
"${enemy.name} assumes a defensive stance (+${intent.finalValue} Armor).",
);
} else {
_addLog("${enemy.name} tried to defend but failed.");
}
intent.isApplied = true;
notifyListeners();
}
}
/// Applies the effects of the enemy's intent (specifically Defense)
/// This should be called just before the Player's turn starts.
void _applyEnemyIntentEffects() {
@@ -806,52 +812,6 @@ class BattleProvider with ChangeNotifier {
return;
}
// Special Case: Enemy Defense (Phase 3 & Phase 1)
// - Phase 3 Defense: Logic applied in _applyEnemyIntentEffects. Event is Visual Only.
// - Phase 1 Defense: Logic applied in _startEnemyTurn (if we add it there) or here?
// Wait, Phase 1 Defense is distinct.
// However, currently Phase 1 Defense also uses _effectEventController.sink.add(event).
// BUT Phase 1 Defense Logic is NOT applied in _startEnemyTurn yet (it just emits event).
// So Phase 1 Defense SHOULD go through _processAttackImpact?
// NO, because Phase 1 Defense uses the same ActionType.defend.
// Let's look at _startEnemyTurn for Phase 1 Defense:
// It emits event with armorGained. It does NOT increase armor directly.
// So for Phase 1, we NEED handleImpact -> _processAttackImpact.
// Let's look at _applyEnemyIntentEffects for Phase 3 Defense:
// It increases armor DIRECTLY: "enemy.armor += intent.finalValue;"
// AND it emits event.
// This discrepancy is the root cause.
// We should standardize.
// DECISION: Phase 3 Defense event should be flagged or handled as visual-only.
// Since we can't easily add flags to EffectEvent without changing other files,
// let's rely on the context.
// Actually, simply removing the direct armor application in _applyEnemyIntentEffects
// and letting handleImpact do it is cleaner?
// NO, because Phase 3 needs armor applied BEFORE Player Turn starts, independent of UI speed.
// And _processMiddleTurn relies on the logic sequence.
// So, we MUST block handleImpact for Phase 3 Defense.
// Phase 1 Defense (Rare, usually Attack) needs to work too.
// BUT wait, _startEnemyTurn (Phase 1) code:
// if (intent.type == EnemyActionType.defend) { ... sink.add(event); ... }
// It does NOT apply armor. So Phase 1 relies on handleImpact.
// PROBLEM: handleImpact cannot distinguish Phase 1 vs Phase 3 event easily.
// FIX: Update _startEnemyTurn (Phase 1) to ALSO apply armor directly and make the event visual-only.
// Then we can globally block Enemy Defend in handleImpact.
// REMOVED: Blocking Enemy Defend. Now we want to process it.
// if (event.attacker == enemy && event.type == ActionType.defend) {
// return;
// }
// Only process actual attack or defend impacts here
_processAttackImpact(event);
@@ -945,7 +905,7 @@ class BattleProvider with ChangeNotifier {
notifyListeners();
}
/// Tries to apply status effects from attacker's equipment to the target.
/// Tries to applyStatus effects from attacker's equipment to the target.
void _tryApplyStatusEffects(Character attacker, Character target) {
List<StatusEffect> effectsToApply = CombatCalculator.getAppliedEffects(
attacker,