import 'package:askiineverdie/src/core/model/equipment_slot.dart'; import 'package:askiineverdie/src/core/model/game_state.dart'; import 'package:askiineverdie/src/core/model/pq_config.dart'; import 'package:askiineverdie/src/core/util/pq_logic.dart' as pq_logic; /// Game state mutations that mirror the original PQ win/reward logic. class GameMutations { const GameMutations(this.config); final PqConfig config; GameState winEquip(GameState state, int level, EquipmentSlot slot) { final rng = state.rng; final name = pq_logic.winEquip(config, rng, level, slot); final equip = state.equipment; final updatedEquip = switch (slot) { EquipmentSlot.weapon => equip.copyWith( weapon: name, bestIndex: EquipmentSlot.weapon.index, ), EquipmentSlot.shield => equip.copyWith( shield: name, bestIndex: EquipmentSlot.shield.index, ), EquipmentSlot.armor => equip.copyWith( armor: name, bestIndex: EquipmentSlot.armor.index, ), }; return state.copyWith(rng: rng, equipment: updatedEquip); } GameState winStat(GameState state) { final updatedStats = pq_logic.winStat(state.stats, state.rng); return state.copyWith(rng: state.rng, stats: updatedStats); } GameState winSpell(GameState state, int wisdom, int level) { final result = pq_logic.winSpell(config, state.rng, wisdom, level); final parts = result.split('|'); final name = parts[0]; final rank = parts.length > 1 ? parts[1] : 'I'; final spells = [...state.spellBook.spells]; final index = spells.indexWhere((s) => s.name == name); if (index >= 0) { spells[index] = spells[index].copyWith(rank: rank); } else { spells.add(SpellEntry(name: name, rank: rank)); } return state.copyWith( rng: state.rng, spellBook: state.spellBook.copyWith(spells: spells), ); } GameState winItem(GameState state) { final rng = state.rng; final result = pq_logic.winItem(config, rng, state.inventory.items.length); final items = [...state.inventory.items]; if (result.isEmpty) { // Duplicate an existing item if possible. if (items.isNotEmpty) { final pickIndex = rng.nextInt(items.length); final picked = items[pickIndex]; items[pickIndex] = picked.copyWith(count: picked.count + 1); } } else { final existing = items.indexWhere((e) => e.name == result); if (existing >= 0) { items[existing] = items[existing].copyWith( count: items[existing].count + 1, ); } else { items.add(InventoryEntry(name: result, count: 1)); } } return state.copyWith( rng: rng, inventory: state.inventory.copyWith(items: items), ); } }