update
This commit is contained in:
+101
-178
@@ -266,65 +266,8 @@ class BattleProvider with ChangeNotifier {
|
||||
if (!isPlayerTurn || player.isDead || enemy.isDead || showRewardPopup)
|
||||
return;
|
||||
|
||||
// 0. Apply Enemy Pre-emptive Defense (Just-in-Time)
|
||||
if (currentEnemyIntent?.type == EnemyActionType.defend &&
|
||||
!currentEnemyIntent!.isApplied) {
|
||||
final intent = currentEnemyIntent!;
|
||||
|
||||
if (intent.isSuccess) {
|
||||
enemy.armor += intent.finalValue;
|
||||
_addLog(
|
||||
"Enemy raises shield just in time! (+${intent.finalValue} Armor)",
|
||||
);
|
||||
|
||||
// Visual Effect for Enemy Defense Success
|
||||
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);
|
||||
}
|
||||
if (!intent.isSuccess) {
|
||||
_addLog("Enemy tried to raise shield but fumbled!");
|
||||
print("[Logic Debug] Enemy Defense Fumbled Event"); // Debug Log
|
||||
|
||||
// Visual Effect for Enemy Defense Failure
|
||||
final event = EffectEvent(
|
||||
id:
|
||||
DateTime.now().millisecondsSinceEpoch.toString() +
|
||||
Random().nextInt(1000).toString(),
|
||||
type: ActionType.defend,
|
||||
risk: intent.risk,
|
||||
target: EffectTarget.enemy,
|
||||
feedbackType: BattleFeedbackType.failed,
|
||||
attacker: enemy,
|
||||
targetEntity: enemy,
|
||||
isSuccess: false,
|
||||
);
|
||||
_effectEventController.sink.add(event);
|
||||
}
|
||||
|
||||
intent.isApplied = true;
|
||||
|
||||
notifyListeners();
|
||||
|
||||
// Re-add delay to show the defense before player attack lands
|
||||
|
||||
int tid = _turnTransactionId;
|
||||
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
if (tid != _turnTransactionId) return;
|
||||
}
|
||||
// 0. Apply Enemy Pre-emptive Defense - REMOVED (Standard Turn-Based Logic)
|
||||
// Defense now happens on Enemy's Turn.
|
||||
|
||||
// Update Enemy Status Effects at the start of Player's turn (user request)
|
||||
|
||||
@@ -433,7 +376,6 @@ class BattleProvider with ChangeNotifier {
|
||||
event,
|
||||
); // Send event for miss/fail feedback
|
||||
_addLog("${player.name}'s ${type.name} ${feedbackType.name}!");
|
||||
print("[Logic Debug] Player Action Failed Event"); // Debug Log
|
||||
// handleImpact(event); // REMOVED: Driven by UI
|
||||
}
|
||||
|
||||
@@ -469,18 +411,90 @@ class BattleProvider with ChangeNotifier {
|
||||
|
||||
// --- Turn Management Phases ---
|
||||
|
||||
// Phase 4: Start Player Turn
|
||||
void _startPlayerTurn() {
|
||||
// Player Turn Start Logic
|
||||
// Armor decay (Player)
|
||||
if (player.armor > 0) {
|
||||
player.armor = (player.armor * GameConfig.armorDecayRate).toInt();
|
||||
_addLog("Player's armor decayed to ${player.armor}.");
|
||||
}
|
||||
|
||||
if (player.isDead) {
|
||||
_onDefeat();
|
||||
return;
|
||||
}
|
||||
|
||||
// [New] Apply Pre-emptive Enemy Intent (Defense/Buffs)
|
||||
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.");
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
isPlayerTurn = true;
|
||||
turnCount++;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _addLog(String log) {
|
||||
_logManager.addLog(log);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Check Status Effects at Start of Turn
|
||||
bool _processStartTurnEffects(Character character) {
|
||||
final result = CombatCalculator.processStartTurnEffects(character);
|
||||
|
||||
int totalBleed = result['bleedDamage'];
|
||||
bool isStunned = result['isStunned'];
|
||||
|
||||
// 1. Bleed Damage
|
||||
if (totalBleed > 0) {
|
||||
character.hp -= totalBleed;
|
||||
if (character.hp < 0) character.hp = 0;
|
||||
_addLog("${character.name} takes $totalBleed bleed damage!");
|
||||
|
||||
// Emit DamageEvent for bleed
|
||||
_damageEventController.sink.add(
|
||||
DamageEvent(
|
||||
damage: totalBleed,
|
||||
target: (character == player)
|
||||
? DamageTarget.player
|
||||
: DamageTarget.enemy,
|
||||
type: DamageType.bleed,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Stun Check
|
||||
if (isStunned) {
|
||||
_addLog("${character.name} is stunned!");
|
||||
}
|
||||
|
||||
return !isStunned;
|
||||
}
|
||||
|
||||
// --- Turn Management Phases ---
|
||||
|
||||
// Phase 1: Enemy Action Phase
|
||||
Future<void> _startEnemyTurn() async {
|
||||
_turnTransactionId++; // Start of Enemy Turn Phase
|
||||
if (!isPlayerTurn && (player.isDead || enemy.isDead)) return;
|
||||
|
||||
_addLog("Enemy's turn...");
|
||||
// REMOVED: Initial delay for faster pacing
|
||||
// await Future.delayed(
|
||||
// const Duration(milliseconds: GameConfig.animDelayEnemyTurn),
|
||||
// );
|
||||
|
||||
// Armor decay
|
||||
// Armor decay (Enemy)
|
||||
if (enemy.armor > 0) {
|
||||
enemy.armor = (enemy.armor * GameConfig.armorDecayRate).toInt();
|
||||
_addLog("Enemy's armor decayed to ${enemy.armor}.");
|
||||
@@ -498,33 +512,18 @@ class BattleProvider with ChangeNotifier {
|
||||
final intent = currentEnemyIntent!;
|
||||
|
||||
if (intent.type == EnemyActionType.defend) {
|
||||
// Defensive Action (Non-animating)
|
||||
// Defensive Action (Pre-applied at start of Player Turn)
|
||||
// Just show a log or maintain stance visual
|
||||
_addLog("${enemy.name} maintains defensive stance.");
|
||||
|
||||
// Check if already applied in Phase 3 of previous turn
|
||||
if (intent.isApplied) {
|
||||
_addLog("Enemy maintains defensive stance.");
|
||||
// Proceed manually
|
||||
int tid = _turnTransactionId;
|
||||
int delay = skipAnimations ? 500 : 1000; // Faster if animations off
|
||||
Future.delayed(Duration(milliseconds: delay), () {
|
||||
if (tid != _turnTransactionId) return;
|
||||
_endEnemyTurn();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (intent.isSuccess) {
|
||||
// ... (success logic) ...
|
||||
} else {
|
||||
// ... (failure logic) ...
|
||||
}
|
||||
// For defense (if not applied), we proceed manually
|
||||
// IMPORTANT: We still need to end the turn sequence properly.
|
||||
// Since no animation is needed (or a very short one), we can just delay slightly.
|
||||
int tid = _turnTransactionId;
|
||||
int delay = skipAnimations ? 500 : 1500; // Faster if animations off
|
||||
Future.delayed(Duration(milliseconds: delay), () {
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (tid != _turnTransactionId) return;
|
||||
_endEnemyTurn();
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// Attack Action (Animating)
|
||||
if (intent.isSuccess) {
|
||||
@@ -542,10 +541,8 @@ class BattleProvider with ChangeNotifier {
|
||||
isSuccess: true,
|
||||
);
|
||||
_effectEventController.sink.add(event);
|
||||
// CRITICAL: We DO NOT call _endEnemyTurn here.
|
||||
// The UI will play the animation, then call handleImpact.
|
||||
// handleImpact will trigger _endEnemyTurn.
|
||||
return; // Exit _startEnemyTurn after emitting event for UI to handle
|
||||
// UI monitors event -> animates -> calls handleImpact -> _endEnemyTurn
|
||||
return;
|
||||
} else {
|
||||
// Missed Attack
|
||||
_addLog("Enemy's ${intent.risk.name} attack missed!");
|
||||
@@ -562,7 +559,7 @@ class BattleProvider with ChangeNotifier {
|
||||
isSuccess: false,
|
||||
);
|
||||
_effectEventController.sink.add(event);
|
||||
return; // Exit _startEnemyTurn after emitting event for UI to handle
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (!canAct) {
|
||||
@@ -594,42 +591,14 @@ class BattleProvider with ChangeNotifier {
|
||||
|
||||
// Phase 3: Middle Turn (Apply Defense Effects)
|
||||
Future<void> _processMiddleTurn() async {
|
||||
// Apply Intent Effects (Pre-emptive Defense)
|
||||
// Phase 3 Middle Turn - Reduced functionality as Defense is now Phase 1.
|
||||
int tid = _turnTransactionId;
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
await Future.delayed(const Duration(milliseconds: 200)); // Short pause
|
||||
if (tid != _turnTransactionId) return;
|
||||
_applyEnemyIntentEffects();
|
||||
|
||||
// REMOVED: Delay for faster pacing
|
||||
// Small pause to let the player see the enemy's new stance
|
||||
|
||||
_startPlayerTurn();
|
||||
}
|
||||
|
||||
// Phase 4: Start Player Turn
|
||||
void _startPlayerTurn() {
|
||||
// Player Turn Start Logic
|
||||
// Armor decay
|
||||
if (player.armor > 0) {
|
||||
player.armor = (player.armor * GameConfig.armorDecayRate).toInt();
|
||||
_addLog("Player's armor decayed to ${player.armor}.");
|
||||
}
|
||||
|
||||
if (player.isDead) {
|
||||
_onDefeat();
|
||||
return;
|
||||
}
|
||||
|
||||
isPlayerTurn = true;
|
||||
turnCount++;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _addLog(String message) {
|
||||
_logManager.addLog(message);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _onVictory() {
|
||||
// Calculate Gold Reward
|
||||
// Base 10 + (Stage * 5) + Random variance
|
||||
@@ -897,21 +866,14 @@ class BattleProvider with ChangeNotifier {
|
||||
/// Applies the effects of the enemy's intent (specifically Defense)
|
||||
/// This should be called just before the Player's turn starts.
|
||||
void _applyEnemyIntentEffects() {
|
||||
if (currentEnemyIntent == null || enemy.isDead) return;
|
||||
|
||||
// Prevent duplicate application
|
||||
if (currentEnemyIntent!.isApplied) return;
|
||||
|
||||
if (currentEnemyIntent!.type == EnemyActionType.defend) {
|
||||
// Logic moved to playerAction for "Just-in-Time" defense.
|
||||
// Nothing to do here except maybe log intent (optional, but Intent UI covers it).
|
||||
return;
|
||||
}
|
||||
// No pre-emptive effects in Standard Turn-Based model.
|
||||
// Logic cleared.
|
||||
}
|
||||
|
||||
// New public method to be called by UI at impact moment
|
||||
void handleImpact(EffectEvent event) {
|
||||
if (event.isSuccess == false || event.feedbackType != null) {
|
||||
if ((event.isSuccess == false || event.feedbackType != null) &&
|
||||
event.type != ActionType.defend) {
|
||||
// If it's a miss/fail/feedback, just log and return
|
||||
// Logging and feedback text should already be handled when event created
|
||||
notifyListeners(); // Ensure UI updates for log
|
||||
@@ -920,11 +882,8 @@ class BattleProvider with ChangeNotifier {
|
||||
if (event.attacker == player) {
|
||||
_endPlayerTurn();
|
||||
} else if (event.attacker == enemy) {
|
||||
// Special Case: Do NOT call _endEnemyTurn for Enemy Defense (Phase 1 & 3).
|
||||
// Phase 1 relies on manual timer. Phase 3 relies on _processMiddleTurn sequence.
|
||||
if (event.type != ActionType.defend) {
|
||||
_endEnemyTurn();
|
||||
}
|
||||
// Special Case: Phase 1 relies on manual timer. Phase 3 relies on _processMiddleTurn sequence.
|
||||
_endEnemyTurn();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -970,10 +929,10 @@ class BattleProvider with ChangeNotifier {
|
||||
// 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.
|
||||
|
||||
// Step 1: Modifying handleImpact to block ALL Enemy Defend logic.
|
||||
if (event.attacker == enemy && event.type == ActionType.defend) {
|
||||
return;
|
||||
}
|
||||
// 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);
|
||||
@@ -1068,40 +1027,6 @@ class BattleProvider with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Process effects that happen at the start of the turn (Bleed, Stun).
|
||||
/// Returns true if the character can act, false if stunned.
|
||||
bool _processStartTurnEffects(Character character) {
|
||||
final result = CombatCalculator.processStartTurnEffects(character);
|
||||
|
||||
int totalBleed = result['bleedDamage'];
|
||||
bool isStunned = result['isStunned'];
|
||||
|
||||
// 1. Bleed Damage
|
||||
if (totalBleed > 0) {
|
||||
character.hp -= totalBleed;
|
||||
if (character.hp < 0) character.hp = 0;
|
||||
_addLog("${character.name} takes $totalBleed bleed damage!");
|
||||
|
||||
// Emit DamageEvent for bleed
|
||||
_damageEventController.sink.add(
|
||||
DamageEvent(
|
||||
damage: totalBleed,
|
||||
target: (character == player)
|
||||
? DamageTarget.player
|
||||
: DamageTarget.enemy,
|
||||
type: DamageType.bleed,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Stun Check
|
||||
if (isStunned) {
|
||||
_addLog("${character.name} is stunned!");
|
||||
}
|
||||
|
||||
return !isStunned;
|
||||
}
|
||||
|
||||
/// Tries to apply status effects from attacker's equipment to the target.
|
||||
void _tryApplyStatusEffects(Character attacker, Character target) {
|
||||
List<StatusEffect> effectsToApply = CombatCalculator.getAppliedEffects(
|
||||
@@ -1113,6 +1038,4 @@ class BattleProvider with ChangeNotifier {
|
||||
_addLog("Applied ${effect.type.name} to ${target.name}!");
|
||||
}
|
||||
}
|
||||
|
||||
/// Process effects that happen at the start of the turn (Bleed, Stun).
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
class SettingsProvider with ChangeNotifier {
|
||||
static const String _keyEnemyAnim = 'settings_enemy_anim';
|
||||
|
||||
bool _enableEnemyAnimations = false; // Default: Disabled
|
||||
bool _enableEnemyAnimations = true; // Default: Enabled
|
||||
|
||||
bool get enableEnemyAnimations => _enableEnemyAnimations;
|
||||
|
||||
@@ -14,7 +14,7 @@ class SettingsProvider with ChangeNotifier {
|
||||
|
||||
Future<void> _loadSettings() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_enableEnemyAnimations = prefs.getBool(_keyEnemyAnim) ?? false;
|
||||
_enableEnemyAnimations = prefs.getBool(_keyEnemyAnim) ?? true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -126,11 +126,13 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
|
||||
void _addFloatingEffect(EffectEvent event) {
|
||||
if (_processedEffectIds.contains(event.id)) {
|
||||
// print("[UI Debug] Duplicate Event Ignored: ${event.id}");
|
||||
return;
|
||||
}
|
||||
|
||||
_processedEffectIds.add(event.id);
|
||||
if (_processedEffectIds.length > 20) {
|
||||
// Keep the set size manageable
|
||||
if (_processedEffectIds.length > 50) {
|
||||
_processedEffectIds.remove(_processedEffectIds.first);
|
||||
}
|
||||
|
||||
@@ -138,7 +140,9 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
|
||||
// Feedback Text Cooldown
|
||||
if (event.feedbackType != null) {
|
||||
print("[UI Debug] Feedback Event: ${event.id}, Type: ${event.feedbackType}");
|
||||
// print(
|
||||
// "[UI Debug] Feedback Event: ${event.id}, Type: ${event.feedbackType}",
|
||||
// );
|
||||
if (_lastFeedbackTime != null &&
|
||||
DateTime.now().difference(_lastFeedbackTime!).inMilliseconds < 300) {
|
||||
return; // Skip if too soon
|
||||
@@ -194,7 +198,7 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
|
||||
// Prevent duplicate feedback texts for the same event ID (UI Level)
|
||||
if (_floatingFeedbackTexts.any((e) => e.eventId == event.id)) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
@@ -208,7 +212,7 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
top: position.dy,
|
||||
child: FloatingFeedbackText(
|
||||
key: ValueKey(id),
|
||||
feedback: "$feedbackText (${event.id.substring(0, 4)})",
|
||||
feedback: feedbackText,
|
||||
color: feedbackColor,
|
||||
onRemove: () {
|
||||
if (mounted) {
|
||||
@@ -259,9 +263,7 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
}
|
||||
|
||||
// 1. Player Attack Animation Trigger (Success or Miss)
|
||||
if (event.type == ActionType.attack &&
|
||||
event.target == EffectTarget.enemy) {
|
||||
|
||||
if (event.type == ActionType.attack && event.target == EffectTarget.enemy) {
|
||||
final RenderBox? playerBox =
|
||||
_playerKey.currentContext?.findRenderObject() as RenderBox?;
|
||||
final RenderBox? enemyBox =
|
||||
@@ -277,11 +279,13 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
});
|
||||
|
||||
// Force SAFE animation for MISS, otherwise use event risk
|
||||
final RiskLevel animRisk = event.feedbackType != null ? RiskLevel.safe : event.risk;
|
||||
final RiskLevel animRisk = event.feedbackType != null
|
||||
? RiskLevel.safe
|
||||
: event.risk;
|
||||
|
||||
_playerAnimKey.currentState
|
||||
?.animateAttack(offset, () {
|
||||
showEffect();
|
||||
showEffect();
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
|
||||
if (event.risk == RiskLevel.risky && event.feedbackType == null) {
|
||||
@@ -306,11 +310,10 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// 2. Enemy Attack Animation Trigger (Success or Miss)
|
||||
else if (event.type == ActionType.attack &&
|
||||
event.target == EffectTarget.player) {
|
||||
|
||||
bool enableAnim = context.read<SettingsProvider>().enableEnemyAnimations;
|
||||
|
||||
if (!enableAnim) {
|
||||
@@ -334,11 +337,13 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
});
|
||||
|
||||
// Force SAFE animation for MISS
|
||||
final RiskLevel animRisk = event.feedbackType != null ? RiskLevel.safe : event.risk;
|
||||
final RiskLevel animRisk = event.feedbackType != null
|
||||
? RiskLevel.safe
|
||||
: event.risk;
|
||||
|
||||
_enemyAnimKey.currentState
|
||||
?.animateAttack(offset, () {
|
||||
showEffect();
|
||||
showEffect();
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
|
||||
if (event.risk == RiskLevel.risky && event.feedbackType == null) {
|
||||
@@ -363,36 +368,36 @@ class _BattleScreenState extends State<BattleScreen> {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// 3. Defend Animation Trigger (Success OR Failure)
|
||||
else if (event.type == ActionType.defend) {
|
||||
if (event.target == EffectTarget.player) {
|
||||
_playerAnimKey.currentState?.animateDefense(() {
|
||||
showEffect();
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
});
|
||||
} else if (event.target == EffectTarget.enemy) {
|
||||
_enemyAnimKey.currentState?.animateDefense(() {
|
||||
showEffect();
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
});
|
||||
} else {
|
||||
if (event.target == EffectTarget.player) {
|
||||
_playerAnimKey.currentState?.animateDefense(() {
|
||||
showEffect();
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
}
|
||||
});
|
||||
} else if (event.target == EffectTarget.enemy) {
|
||||
_enemyAnimKey.currentState?.animateDefense(() {
|
||||
showEffect();
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
});
|
||||
} else {
|
||||
showEffect();
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
}
|
||||
}
|
||||
// 4. Others (Feedback for attacks, Buffs, etc.)
|
||||
else {
|
||||
showEffect();
|
||||
|
||||
|
||||
// If it's a feedback event (MISS/FAILED for attacks), wait 500ms.
|
||||
if (event.feedbackType != null) {
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (mounted) context.read<BattleProvider>().handleImpact(event);
|
||||
});
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (mounted) context.read<BattleProvider>().handleImpact(event);
|
||||
});
|
||||
} else {
|
||||
// Success events (Icon)
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
// Success events (Icon)
|
||||
context.read<BattleProvider>().handleImpact(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,9 +90,18 @@ class CharacterStatusCard extends StatelessWidget {
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
Text("ATK: ${character.totalAtk}", style: const TextStyle(color: ThemeConfig.textColorWhite)),
|
||||
Text("DEF: ${character.totalDefense}", style: const TextStyle(color: ThemeConfig.textColorWhite)),
|
||||
Text("LUCK: ${character.totalLuck}", style: const TextStyle(color: ThemeConfig.textColorWhite)),
|
||||
Text(
|
||||
"ATK: ${character.totalAtk}",
|
||||
style: const TextStyle(color: ThemeConfig.textColorWhite),
|
||||
),
|
||||
Text(
|
||||
"DEF: ${character.totalDefense}",
|
||||
style: const TextStyle(color: ThemeConfig.textColorWhite),
|
||||
),
|
||||
Text(
|
||||
"LUCK: ${character.totalLuck}",
|
||||
style: const TextStyle(color: ThemeConfig.textColorWhite),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -124,7 +133,6 @@ class CharacterStatusCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8), // 아이콘과 정보 사이 간격
|
||||
|
||||
if (!isPlayer && !hideStats)
|
||||
Consumer<BattleProvider>(
|
||||
builder: (context, provider, child) {
|
||||
|
||||
@@ -268,9 +268,10 @@ class FloatingFeedbackTextState extends State<FloatingFeedbackText>
|
||||
fontWeight: FontWeight.bold,
|
||||
shadows: const [
|
||||
Shadow(
|
||||
blurRadius: 2.0,
|
||||
blurRadius:
|
||||
0.0, // Sharper shadow to avoid blurry/double look
|
||||
color: ThemeConfig.feedbackShadow,
|
||||
offset: Offset(1.0, 1.0),
|
||||
offset: Offset(1.5, 1.5),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user