feat(engine): 엔진 서비스 개선 및 테스트 캐릭터 서비스 추가
- ProgressService 로직 개선 - RewardService 확장 - CombatCalculator, ItemService 정리 - TestCharacterService 추가
This commit is contained in:
@@ -1,25 +1,82 @@
|
||||
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/util/pq_logic.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);
|
||||
RewardService(this.mutations, this.config);
|
||||
|
||||
final GameMutations mutations;
|
||||
final PqConfig config;
|
||||
|
||||
GameState applyReward(GameState state, RewardKind reward) {
|
||||
GameState applyReward(GameState state, pq_logic.RewardKind reward) {
|
||||
switch (reward) {
|
||||
case RewardKind.spell:
|
||||
case pq_logic.RewardKind.spell:
|
||||
return mutations.winSpell(state, state.stats.wis, state.traits.level);
|
||||
case RewardKind.equip:
|
||||
// 원본 Main.pas:797 - Random(Equips.Items.Count) (11개 슬롯)
|
||||
final slotIndex = state.rng.nextInt(Equipment.slotCount);
|
||||
return mutations.winEquipByIndex(state, state.traits.level, slotIndex);
|
||||
case RewardKind.stat:
|
||||
case pq_logic.RewardKind.equip:
|
||||
return _applyEquipReward(state);
|
||||
case pq_logic.RewardKind.stat:
|
||||
return mutations.winStat(state);
|
||||
case RewardKind.item:
|
||||
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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user