update
This commit is contained in:
@@ -15,6 +15,8 @@ import '../game/enums.dart';
|
||||
import '../game/model/damage_event.dart'; // DamageEvent import
|
||||
import '../game/model/effect_event.dart'; // EffectEvent import
|
||||
|
||||
import '../game/save_manager.dart';
|
||||
|
||||
class EnemyIntent {
|
||||
final EnemyActionType type;
|
||||
final int value;
|
||||
@@ -47,8 +49,10 @@ class BattleProvider with ChangeNotifier {
|
||||
int turnCount = 1;
|
||||
List<Item> rewardOptions = [];
|
||||
bool showRewardPopup = false;
|
||||
int _lastGoldReward = 0; // New: Stores gold gained from last victory
|
||||
|
||||
List<String> get logs => battleLogs;
|
||||
int get lastGoldReward => _lastGoldReward;
|
||||
|
||||
// Damage Event Stream
|
||||
final _damageEventController = StreamController<DamageEvent>.broadcast();
|
||||
@@ -69,6 +73,18 @@ class BattleProvider with ChangeNotifier {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void loadFromSave(Map<String, dynamic> data) {
|
||||
stage = data['stage'];
|
||||
turnCount = data['turnCount'];
|
||||
player = Character.fromJson(data['player']);
|
||||
|
||||
battleLogs.clear();
|
||||
_addLog("Game Loaded! Resuming Stage $stage");
|
||||
|
||||
_prepareNextStage();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void initializeBattle() {
|
||||
stage = 1;
|
||||
turnCount = 1;
|
||||
@@ -87,6 +103,9 @@ class BattleProvider with ChangeNotifier {
|
||||
);
|
||||
}
|
||||
|
||||
// Give test gold
|
||||
player.gold = 50;
|
||||
|
||||
// Provide starter equipment
|
||||
final starterSword = Item(
|
||||
id: "starter_sword",
|
||||
@@ -147,6 +166,9 @@ class BattleProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
void _prepareNextStage() {
|
||||
// Save Game at the start of each stage
|
||||
SaveManager.saveGame(this);
|
||||
|
||||
StageType type;
|
||||
|
||||
// Stage Type Logic
|
||||
@@ -209,15 +231,7 @@ class BattleProvider with ChangeNotifier {
|
||||
_addLog("Stage $stage ($type) started! A wild ${enemy.name} appeared.");
|
||||
} else if (type == StageType.shop) {
|
||||
// Generate random items for shop
|
||||
final random = Random();
|
||||
List<ItemTemplate> allTemplates = List.from(ItemTable.allItems);
|
||||
allTemplates.shuffle(random);
|
||||
|
||||
int count = min(4, allTemplates.length);
|
||||
shopItems = allTemplates
|
||||
.sublist(0, count)
|
||||
.map((t) => t.createItem(stage: stage))
|
||||
.toList();
|
||||
shopItems = _generateShopItems();
|
||||
|
||||
// Dummy enemy to prevent null errors in existing UI (until UI is fully updated)
|
||||
enemy = Character(name: "Merchant", maxHp: 9999, armor: 0, atk: 0);
|
||||
@@ -238,6 +252,55 @@ class BattleProvider with ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Generate 4 random items for the shop based on current stage tier
|
||||
List<Item> _generateShopItems() {
|
||||
ItemTier currentTier = ItemTier.tier1;
|
||||
if (stage > 24)
|
||||
currentTier = ItemTier.tier3;
|
||||
else if (stage > 12)
|
||||
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 = 50;
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
// Replaces _spawnEnemy
|
||||
// void _spawnEnemy() { ... } - Removed
|
||||
|
||||
@@ -621,28 +684,68 @@ class BattleProvider with ChangeNotifier {
|
||||
}
|
||||
|
||||
void _onVictory() {
|
||||
_addLog("Enemy defeated! Choose a reward.");
|
||||
|
||||
// Calculate Gold Reward
|
||||
// Base 10 + (Stage * 5) + Random variance
|
||||
final random = Random();
|
||||
int goldReward = 10 + (stage * 5) + random.nextInt(10);
|
||||
|
||||
player.gold += goldReward;
|
||||
_lastGoldReward = goldReward; // Store for UI display
|
||||
_addLog("Enemy defeated! Gained $goldReward Gold.");
|
||||
_addLog("Choose a reward.");
|
||||
|
||||
List<ItemTemplate> allTemplates = List.from(ItemTable.allItems);
|
||||
allTemplates.shuffle(random); // Shuffle to randomize selection
|
||||
|
||||
// Take first 3 items (ensure distinct templates if possible, though list is small now)
|
||||
int count = min(3, allTemplates.length);
|
||||
rewardOptions = allTemplates.sublist(0, count).map((template) {
|
||||
return template.createItem(stage: stage);
|
||||
}).toList();
|
||||
// Item Rewards
|
||||
// Logic: Get random items based on current round tier? For now just random.
|
||||
// Ideally should use ItemTable.getRandomItem() with Tier logic.
|
||||
// Let's use our new weighted random logic if available, or fallback to simple shuffle for now to keep it simple.
|
||||
// Since we just refactored ItemTable, let's use getRandomItem!
|
||||
|
||||
ItemTier currentTier = ItemTier.tier1;
|
||||
if (stage > 24)
|
||||
currentTier = ItemTier.tier3;
|
||||
else if (stage > 12)
|
||||
currentTier = ItemTier.tier2;
|
||||
|
||||
rewardOptions = [];
|
||||
// Get 3 distinct items if possible
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ItemTemplate? item = ItemTable.getRandomItem(tier: currentTier);
|
||||
if (item != null) {
|
||||
rewardOptions.add(item.createItem(stage: stage));
|
||||
}
|
||||
}
|
||||
|
||||
// Add "None" (Skip) Option
|
||||
// We can represent "None" as a null or a special Item.
|
||||
// Using a special Item with ID "reward_skip" is safer for List<Item>.
|
||||
rewardOptions.add(
|
||||
Item(
|
||||
id: "reward_skip",
|
||||
name: "Skip Reward",
|
||||
description: "Take nothing and move on.",
|
||||
atkBonus: 0,
|
||||
hpBonus: 0,
|
||||
slot: EquipmentSlot.accessory,
|
||||
),
|
||||
);
|
||||
|
||||
showRewardPopup = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void selectReward(Item item) {
|
||||
bool added = player.addToInventory(item);
|
||||
if (added) {
|
||||
_addLog("Added ${item.name} to inventory.");
|
||||
if (item.id == "reward_skip") {
|
||||
_addLog("Skipped reward.");
|
||||
} else {
|
||||
_addLog("Inventory is full! ${item.name} discarded.");
|
||||
bool added = player.addToInventory(item);
|
||||
if (added) {
|
||||
_addLog("Added ${item.name} to inventory.");
|
||||
} else {
|
||||
_addLog("Inventory is full! ${item.name} discarded.");
|
||||
}
|
||||
}
|
||||
|
||||
// Heal player after selecting reward
|
||||
|
||||
Reference in New Issue
Block a user