refactor(engine): 포션/진행 서비스 개선
- PotionService 로직 개선 - ProgressService 몬스터 등급 지원
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:asciineverdie/data/potion_data.dart';
|
||||
import 'package:asciineverdie/src/core/model/monster_grade.dart';
|
||||
import 'package:asciineverdie/src/core/model/potion.dart';
|
||||
|
||||
/// 물약 서비스
|
||||
@@ -357,19 +360,35 @@ class PotionService {
|
||||
///
|
||||
/// 전투 승리 시 물약 드랍 여부 결정 및 물약 획득
|
||||
/// [playerLevel] 플레이어 레벨 (드랍 확률 및 티어 결정)
|
||||
/// [monsterLevel] 몬스터 레벨 (티어 결정에 영향)
|
||||
/// [monsterGrade] 몬스터 등급 (드랍 확률 보너스)
|
||||
/// [inventory] 현재 물약 인벤토리
|
||||
/// [roll] 0~99 범위의 난수 (드랍 확률 판정)
|
||||
/// [typeRoll] 0~99 범위의 난수 (HP/MP 결정)
|
||||
/// Returns: (업데이트된 인벤토리, 드랍된 물약 또는 null)
|
||||
(PotionInventory, Potion?) tryPotionDrop({
|
||||
required int playerLevel,
|
||||
required int monsterLevel,
|
||||
required MonsterGrade monsterGrade,
|
||||
required PotionInventory inventory,
|
||||
required int roll,
|
||||
required int typeRoll,
|
||||
}) {
|
||||
// 드랍 확률 계산
|
||||
final dropChance = (baseDropChance + playerLevel * dropChancePerLevel)
|
||||
// 기본 드랍 확률 계산
|
||||
var dropChance = (baseDropChance + playerLevel * dropChancePerLevel)
|
||||
.clamp(baseDropChance, maxDropChance);
|
||||
|
||||
// 몬스터 등급 보너스 (Elite +5%, Boss +15%)
|
||||
dropChance += monsterGrade.potionDropBonus;
|
||||
|
||||
// 몬스터 레벨 > 플레이어 레벨이면 추가 확률 (+1%/레벨 차이)
|
||||
if (monsterLevel > playerLevel) {
|
||||
dropChance += (monsterLevel - playerLevel) * 0.01;
|
||||
}
|
||||
|
||||
// 최대 확률 제한 (50%)
|
||||
dropChance = dropChance.clamp(0.0, 0.5);
|
||||
|
||||
final dropThreshold = (dropChance * 100).round();
|
||||
|
||||
// 드랍 실패
|
||||
@@ -380,8 +399,9 @@ class PotionService {
|
||||
// 물약 타입 결정 (60% HP, 40% MP)
|
||||
final isHpPotion = typeRoll < 60;
|
||||
|
||||
// 레벨 기반 티어 결정
|
||||
final tier = PotionData.tierForLevel(playerLevel);
|
||||
// 티어 결정: max(플레이어 레벨, 몬스터 레벨) 기반
|
||||
final effectiveLevel = math.max(playerLevel, monsterLevel);
|
||||
final tier = PotionData.tierForLevel(effectiveLevel);
|
||||
|
||||
// 물약 선택
|
||||
final Potion? potion;
|
||||
|
||||
@@ -14,6 +14,7 @@ import 'package:asciineverdie/src/core/model/equipment_item.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/monster_combat_stats.dart';
|
||||
import 'package:asciineverdie/src/core/model/monster_grade.dart';
|
||||
import 'package:asciineverdie/src/core/model/potion.dart';
|
||||
import 'package:asciineverdie/src/core/model/pq_config.dart';
|
||||
import 'package:asciineverdie/src/core/model/skill.dart';
|
||||
@@ -591,6 +592,7 @@ class ProgressService {
|
||||
monsterBaseName: monsterResult.baseName,
|
||||
monsterPart: monsterResult.part,
|
||||
monsterLevel: monsterResult.level,
|
||||
monsterGrade: monsterResult.grade,
|
||||
),
|
||||
currentCombat: combatState,
|
||||
);
|
||||
@@ -646,6 +648,7 @@ class ProgressService {
|
||||
monsterBaseName: 'Glitch God',
|
||||
monsterPart: '*', // 특수 전리품
|
||||
monsterLevel: glitchGod.level,
|
||||
monsterGrade: MonsterGrade.boss, // 최종 보스는 항상 boss 등급
|
||||
),
|
||||
currentCombat: combatState,
|
||||
);
|
||||
@@ -963,8 +966,12 @@ class ProgressService {
|
||||
// 물약 드랍 시도
|
||||
final potionService = const PotionService();
|
||||
final rng = resultState.rng;
|
||||
final monsterLevel = taskInfo.monsterLevel ?? resultState.traits.level;
|
||||
final monsterGrade = taskInfo.monsterGrade ?? MonsterGrade.normal;
|
||||
final (updatedPotionInventory, droppedPotion) = potionService.tryPotionDrop(
|
||||
playerLevel: resultState.traits.level,
|
||||
monsterLevel: monsterLevel,
|
||||
monsterGrade: monsterGrade,
|
||||
inventory: resultState.potionInventory,
|
||||
roll: rng.nextInt(100),
|
||||
typeRoll: rng.nextInt(100),
|
||||
|
||||
Reference in New Issue
Block a user