- ProgressService 로직 개선 - RewardService 확장 - CombatCalculator, ItemService 정리 - TestCharacterService 추가
83 lines
2.8 KiB
Dart
83 lines
2.8 KiB
Dart
import 'package:asciineverdie/src/core/engine/game_mutations.dart';
|
|
import 'package:asciineverdie/src/core/engine/item_service.dart';
|
|
import 'package:asciineverdie/src/core/engine/shop_service.dart';
|
|
import 'package:asciineverdie/src/core/model/equipment_slot.dart';
|
|
import 'package:asciineverdie/src/core/model/game_state.dart';
|
|
import 'package:asciineverdie/src/core/model/pq_config.dart';
|
|
import 'package:asciineverdie/src/core/util/pq_logic.dart' as pq_logic;
|
|
|
|
/// Applies quest/act rewards to the GameState using shared RNG.
|
|
class RewardService {
|
|
RewardService(this.mutations, this.config);
|
|
|
|
final GameMutations mutations;
|
|
final PqConfig config;
|
|
|
|
GameState applyReward(GameState state, pq_logic.RewardKind reward) {
|
|
switch (reward) {
|
|
case pq_logic.RewardKind.spell:
|
|
return mutations.winSpell(state, state.stats.wis, state.traits.level);
|
|
case pq_logic.RewardKind.equip:
|
|
return _applyEquipReward(state);
|
|
case pq_logic.RewardKind.stat:
|
|
return mutations.winStat(state);
|
|
case pq_logic.RewardKind.item:
|
|
return mutations.winItem(state);
|
|
}
|
|
}
|
|
|
|
/// 장비 보상 처리 (개선된 로직)
|
|
///
|
|
/// - 빈 슬롯: 무조건 장착
|
|
/// - 기존 장비 있음: 점수 비교 → 업그레이드만 / 다운그레이드 시 판매
|
|
GameState _applyEquipReward(GameState state) {
|
|
final slotIndex = state.rng.nextInt(Equipment.slotCount);
|
|
final slot = EquipmentSlot.values[slotIndex];
|
|
final currentItem = state.equipment.getItemByIndex(slotIndex);
|
|
final level = state.traits.level;
|
|
|
|
// 새 장비 생성
|
|
final itemService = ItemService(rng: state.rng);
|
|
final name = pq_logic.winEquip(config, state.rng, level, slotIndex);
|
|
final newItem = itemService.generateEquipment(
|
|
name: name,
|
|
slot: slot,
|
|
level: level,
|
|
);
|
|
|
|
// 빈 슬롯이면 무조건 장착
|
|
if (currentItem.isEmpty) {
|
|
return state.copyWith(
|
|
rng: state.rng,
|
|
equipment: state.equipment
|
|
.setItemByIndex(slotIndex, newItem)
|
|
.copyWith(bestIndex: slotIndex),
|
|
);
|
|
}
|
|
|
|
// 점수 비교
|
|
final currentScore = ItemService.calculateEquipmentScore(currentItem);
|
|
final newScore = ItemService.calculateEquipmentScore(newItem);
|
|
|
|
if (newScore > currentScore) {
|
|
// 업그레이드: 새 장비 장착
|
|
return state.copyWith(
|
|
rng: state.rng,
|
|
equipment: state.equipment
|
|
.setItemByIndex(slotIndex, newItem)
|
|
.copyWith(bestIndex: slotIndex),
|
|
);
|
|
} else {
|
|
// 다운그레이드: 새 장비 판매 (골드로 변환)
|
|
final shopService = ShopService(rng: state.rng);
|
|
final sellPrice = shopService.calculateSellPrice(newItem);
|
|
return state.copyWith(
|
|
rng: state.rng,
|
|
inventory: state.inventory.copyWith(
|
|
gold: state.inventory.gold + sellPrice,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|