import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../game/models.dart'; import '../../game/enums.dart'; import '../../providers.dart'; import 'battle_animation_widget.dart'; import '../../game/config.dart'; class CharacterStatusCard extends StatelessWidget { final Character character; final bool isPlayer; final bool isTurn; final GlobalKey? animationKey; final bool hideStats; final String? overrideImage; const CharacterStatusCard({ super.key, required this.character, this.isPlayer = false, this.isTurn = false, this.animationKey, this.hideStats = false, this.overrideImage, }); @override Widget build(BuildContext context) { return Column( children: [ AnimatedOpacity( opacity: hideStats ? 0.0 : 1.0, duration: AnimationConfig.fadeDuration, child: Column( children: [ FittedBox( fit: BoxFit.scaleDown, child: Text( "Armor: ${character.armor}", style: const TextStyle(color: ThemeConfig.textColorWhite), ), ), FittedBox( fit: BoxFit.scaleDown, child: Text( "${character.name}: HP ${character.hp}/${character.totalMaxHp}", style: TextStyle( color: character.isDead ? ThemeConfig.statHpEnemyColor : ThemeConfig.textColorWhite, fontWeight: FontWeight.bold, ), ), ), SizedBox( width: ThemeConfig.playerImageSize, child: LinearProgressIndicator( value: character.totalMaxHp > 0 ? character.hp / character.totalMaxHp : 0, color: !isPlayer ? ThemeConfig.statHpEnemyColor : ThemeConfig.statHpPlayerColor, backgroundColor: ThemeConfig.textColorGrey, ), ), if (character.statusEffects.isNotEmpty) Padding( padding: const EdgeInsets.only(top: 4.0), child: Wrap( spacing: 4.0, children: character.statusEffects.map((effect) { final isBuff = effect.type == StatusEffectType.attackUp; return Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2, ), decoration: BoxDecoration( color: isBuff ? ThemeConfig.effectBuffBg : ThemeConfig.effectDebuffBg, borderRadius: BorderRadius.circular(4), ), child: Text( "${effect.type.name.toUpperCase()} (${effect.duration})", style: const TextStyle( color: ThemeConfig.effectText, fontSize: ThemeConfig.statusEffectFontSize, fontWeight: FontWeight.bold, ), ), ); }).toList(), ), ), ], ), ), const SizedBox(height: 8), BattleAnimationWidget( key: animationKey, child: Container( width: isPlayer ? ThemeConfig.playerImageSize : ThemeConfig.enemyImageSize, height: isPlayer ? ThemeConfig.playerImageSize : ThemeConfig.enemyImageSize, decoration: BoxDecoration( // color: isPlayer ? ThemeConfig.playerImageBgColor : null, borderRadius: BorderRadius.circular(8), ), child: Center( child: (overrideImage != null || (character.image != null && character.image!.isNotEmpty)) ? Image.asset( overrideImage ?? character.image!, width: isPlayer ? ThemeConfig.playerImageSize : ThemeConfig.enemyImageSize, height: isPlayer ? ThemeConfig.playerImageSize : ThemeConfig.enemyImageSize, fit: BoxFit.contain, errorBuilder: (context, error, stackTrace) { return const Icon( Icons.error_outline, size: ThemeConfig.characterIconSize, color: ThemeConfig.textColorWhite, ); }, ) : Icon( isPlayer ? Icons.person : Icons.psychology, size: ThemeConfig.characterIconSize, color: ThemeConfig.textColorWhite, ), ), ), ), if (!isPlayer && !hideStats) Consumer( builder: (context, provider, child) { if (provider.currentEnemyIntent != null && !character.isDead) { final intent = provider.currentEnemyIntent!; return Padding( padding: const EdgeInsets.only(top: 8.0), child: Container( padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( color: ThemeConfig.enemyIntentBg, borderRadius: BorderRadius.circular(8), border: Border.all(color: ThemeConfig.enemyIntentBorder), ), child: Column( children: [ Row( mainAxisSize: MainAxisSize.min, children: [ Icon( intent.type == EnemyActionType.attack ? Icons.flash_on : Icons.shield, color: ThemeConfig.rarityRare, size: ThemeConfig.intentIconSize, ), const SizedBox(width: 4), Flexible( child: FittedBox( fit: BoxFit.scaleDown, child: Text( intent.description, style: const TextStyle( color: ThemeConfig.textColorWhite, fontSize: ThemeConfig.intentFontSize, ), ), ), ), ], ), ], ), ), ); } return const SizedBox.shrink(); }, ), ], ); } }