Fix: Prevent enemy preemptive defense on first turn

This commit is contained in:
2025-12-07 21:36:40 +09:00
parent fef803d064
commit e1b000772e
2 changed files with 159 additions and 45 deletions
+78 -45
View File
@@ -31,6 +31,7 @@ class EnemyIntent {
final String description;
final bool isSuccess;
final int finalValue;
bool isApplied; // New field to track if effect (like defense) is already applied
EnemyIntent({
required this.type,
@@ -39,6 +40,7 @@ class EnemyIntent {
required this.description,
required this.isSuccess,
required this.finalValue,
this.isApplied = false,
});
}
@@ -215,7 +217,7 @@ class BattleProvider with ChangeNotifier {
isPlayerTurn = true;
showRewardPopup = false;
_generateEnemyIntent(); // Generate first intent
_generateEnemyIntent(applyImmediate: false); // Generate first intent without applying effects
_addLog("Stage $stage ($type) started! A wild ${enemy.name} appeared.");
} else if (type == StageType.shop) {
@@ -419,47 +421,73 @@ class BattleProvider with ChangeNotifier {
return;
}
if (canAct && currentEnemyIntent != null) {
final intent = currentEnemyIntent!;
if (canAct && currentEnemyIntent != null) {
if (intent.type == EnemyActionType.defend) {
// Apply defense immediately if successful, then send event
if (intent.isSuccess) {
final event = EffectEvent(
id:
DateTime.now().millisecondsSinceEpoch.toString() +
Random().nextInt(1000).toString(),
type: ActionType.defend,
risk: intent.risk,
target: EffectTarget.enemy,
feedbackType: null,
attacker: enemy,
targetEntity: enemy,
armorGained: intent.finalValue,
isSuccess: true,
);
_effectEventController.sink.add(event);
handleImpact(event); // Process impact via handleImpact for safety
} else {
_addLog("Enemy tried to defend but fumbled!");
final event = EffectEvent(
id:
DateTime.now().millisecondsSinceEpoch.toString() +
Random().nextInt(1000).toString(),
type: ActionType.defend,
risk: intent.risk,
target: EffectTarget.enemy,
feedbackType:
BattleFeedbackType.failed, // Feedback type for failed defense
attacker: enemy,
targetEntity: enemy,
isSuccess: false,
);
_effectEventController.sink.add(event);
handleImpact(event); // Process impact via handleImpact for safety
}
} else {
// Attack Logic
final intent = currentEnemyIntent!;
if (intent.type == EnemyActionType.defend) {
// Handle Deferred Defense (from first turn)
if (!intent.isApplied && intent.isSuccess) {
// Apply defense now
final eventId = DateTime.now().millisecondsSinceEpoch.toString() + Random().nextInt(1000).toString();
final event = EffectEvent(
id: eventId,
type: ActionType.defend,
risk: intent.risk,
target: EffectTarget.enemy,
feedbackType: null,
attacker: enemy,
targetEntity: enemy,
armorGained: intent.finalValue,
isSuccess: true,
);
_effectEventController.sink.add(event);
_processAttackImpact(event); // Apply armor and log
intent.isApplied = true;
} else if (intent.isApplied) {
_addLog("Enemy maintains defensive stance.");
} else {
// Failed defense (already logged? maybe not if deferred)
// If it was deferred fail, we should log it now?
// But _generateEnemyIntent logged fail immediately even if deferred?
// No, I changed it to log only if !success.
// Wait, previous logic: if (!success) log.
// So fail is already logged.
_addLog("Enemy tried to defend but fumbled!");
}
} else { // Attack Logic
if (intent.isSuccess) {
final event = EffectEvent(
id:
@@ -711,7 +739,7 @@ class BattleProvider with ChangeNotifier {
_prepareNextStage();
}
void _generateEnemyIntent() {
void _generateEnemyIntent({bool applyImmediate = true}) {
if (enemy.isDead) {
currentEnemyIntent = null;
return;
@@ -807,9 +835,10 @@ class BattleProvider with ChangeNotifier {
finalValue: armor,
);
// Apply defense immediately if successful
if (success) {
// Apply defense immediately if successful AND allowed
if (success && applyImmediate) {
enemy.armor += armor;
currentEnemyIntent!.isApplied = true;
_addLog("Enemy prepares defense! (+$armor Armor)");
_effectEventController.sink.add(
EffectEvent(
@@ -823,7 +852,11 @@ class BattleProvider with ChangeNotifier {
),
);
} else {
_addLog("Enemy tried to defend but fumbled!");
// Either failed or deferred
if (!success) {
_addLog("Enemy tried to defend but fumbled!");
}
// If deferred (applyImmediate = false), we don't log or apply yet.
}
}
notifyListeners();