update : icon image

This commit is contained in:
2025-12-07 16:48:03 +09:00
parent 8771f2c1af
commit d5609aff0f
21 changed files with 684 additions and 394 deletions
+20 -54
View File
@@ -2,6 +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';
@@ -17,6 +18,7 @@ import '../game/model/effect_event.dart'; // EffectEvent import
import '../game/save_manager.dart';
import '../game/config/game_config.dart';
import 'shop_provider.dart'; // Import ShopProvider
class EnemyIntent {
final EnemyActionType type;
@@ -63,7 +65,10 @@ class BattleProvider with ChangeNotifier {
final _effectEventController = StreamController<EffectEvent>.broadcast();
Stream<EffectEvent> get effectStream => _effectEventController.stream;
BattleProvider() {
// Dependency injection
final ShopProvider shopProvider;
BattleProvider({required this.shopProvider}) {
// initializeBattle(); // Do not auto-start logic
}
@@ -231,8 +236,9 @@ class BattleProvider with ChangeNotifier {
_addLog("Stage $stage ($type) started! A wild ${enemy.name} appeared.");
} else if (type == StageType.shop) {
// Generate random items for shop
shopItems = _generateShopItems();
// Generate random items for shop using ShopProvider
shopProvider.generateShopItems(stage);
shopItems = shopProvider.availableItems;
// Dummy enemy to prevent null errors in existing UI (until UI is fully updated)
enemy = Character(name: "Merchant", maxHp: 9999, armor: 0, atk: 0);
@@ -247,60 +253,13 @@ class BattleProvider with ChangeNotifier {
currentStage = StageModel(
type: type,
enemy: newEnemy,
shopItems: shopItems,
shopItems: shopItems, // Pass items from ShopProvider
);
turnCount = 1;
notifyListeners();
}
/// Generate 4 random items for the shop based on current stage tier
List<Item> _generateShopItems() {
ItemTier currentTier = ItemTier.tier1;
if (stage > GameConfig.tier2StageMax)
currentTier = ItemTier.tier3;
else if (stage > GameConfig.tier1StageMax)
currentTier = ItemTier.tier2;
List<Item> items = [];
for (int i = 0; i < 4; i++) {
ItemTemplate? template = ItemTable.getRandomItem(tier: currentTier);
if (template != null) {
items.add(template.createItem(stage: stage));
}
}
return items;
}
void rerollShopItems() {
const int rerollCost = GameConfig.shopRerollCost;
if (player.gold >= rerollCost) {
player.gold -= rerollCost;
// Modify the existing list because shopItems is final
currentStage.shopItems.clear();
currentStage.shopItems.addAll(_generateShopItems());
_addLog("Shop items rerolled for $rerollCost G.");
notifyListeners();
} else {
_addLog("Not enough gold to reroll!");
}
}
void buyItem(Item item) {
if (player.gold >= item.price) {
bool added = player.addToInventory(item);
if (added) {
player.gold -= item.price;
currentStage.shopItems.remove(item); // Remove from shop
_addLog("Bought ${item.name} for ${item.price} G.");
} else {
_addLog("Inventory is full!");
}
notifyListeners();
} else {
_addLog("Not enough gold!");
}
}
// Shop-related methods are now handled by ShopProvider
// Replaces _spawnEnemy
// void _spawnEnemy() { ... } - Removed
@@ -737,18 +696,25 @@ class BattleProvider with ChangeNotifier {
notifyListeners();
}
void selectReward(Item item) {
bool selectReward(Item item) {
if (item.id == "reward_skip") {
_addLog("Skipped reward.");
_completeStage();
return true;
} else {
bool added = player.addToInventory(item);
if (added) {
_addLog("Added ${item.name} to inventory.");
_completeStage();
return true;
} else {
_addLog("Inventory is full! ${item.name} discarded.");
_addLog("Inventory is full! Could not take ${item.name}.");
return false;
}
}
}
void _completeStage() {
// Heal player after selecting reward
int healAmount = GameMath.floor(player.totalMaxHp * GameConfig.stageHealRatio);
player.heal(healAmount);
+72
View File
@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import '../game/model/item.dart';
import '../game/model/entity.dart';
import '../game/data/item_table.dart';
import '../game/enums.dart';
import '../game/config/game_config.dart';
import '../utils/game_math.dart';
class ShopProvider with ChangeNotifier {
List<Item> availableItems = [];
String _lastShopMessage = '';
String get lastShopMessage => _lastShopMessage;
void clearMessage() {
_lastShopMessage = '';
notifyListeners();
}
void generateShopItems(int stage) {
ItemTier currentTier = ItemTier.tier1;
if (stage > GameConfig.tier2StageMax)
currentTier = ItemTier.tier3;
else if (stage > GameConfig.tier1StageMax)
currentTier = ItemTier.tier2;
availableItems = [];
for (int i = 0; i < 4; i++) { // Generate 4 items
ItemTemplate? template = ItemTable.getRandomItem(tier: currentTier);
if (template != null) {
availableItems.add(template.createItem(stage: stage));
}
}
notifyListeners();
}
bool rerollShopItems(Character player, int currentStageNumber) {
const int rerollCost = GameConfig.shopRerollCost;
if (player.gold >= rerollCost) {
player.gold -= rerollCost;
generateShopItems(currentStageNumber); // Regenerate based on current stage
_lastShopMessage = "Shop items rerolled for $rerollCost G.";
notifyListeners();
return true;
} else {
_lastShopMessage = "Not enough gold to reroll!";
notifyListeners();
return false;
}
}
bool buyItem(Item item, Character player) {
if (player.gold >= item.price) {
if (player.inventory.length < player.maxInventorySize) {
player.gold -= item.price;
player.addToInventory(item);
availableItems.remove(item); // Remove from shop
_lastShopMessage = "Bought ${item.name} for ${item.price} G.";
notifyListeners();
return true;
} else {
_lastShopMessage = "Inventory is full! Cannot buy ${item.name}.";
notifyListeners();
return false;
}
} else {
_lastShopMessage = "Not enough gold!";
notifyListeners();
return false;
}
}
}