feat: 초기 커밋

- Progress Quest 6.4 Flutter 포팅 프로젝트
- 게임 루프, 상태 관리, UI 구현
- 캐릭터 생성, 인벤토리, 장비, 주문 시스템
- 시장/판매/구매 메커니즘
This commit is contained in:
JiWoong Sul
2025-12-09 17:24:04 +09:00
commit 08054d97c1
168 changed files with 12876 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
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),
);
}
}