Files
asciinevrdie/lib/src/core/engine/reward_service.dart
JiWoong Sul a1d22369cb feat(engine): 엔진 서비스 개선 및 테스트 캐릭터 서비스 추가
- ProgressService 로직 개선
- RewardService 확장
- CombatCalculator, ItemService 정리
- TestCharacterService 추가
2026-01-12 20:02:45 +09:00

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,
),
);
}
}
}