feat(game): 게임 시스템 전면 개편 및 다국어 지원 확장
## 스킬 시스템 개선 - skill_data.dart: 스킬 데이터 구조 전면 개편 (+1176 라인) - skill_service.dart: 스킬 발동 로직 확장 및 버프 시스템 연동 - skill.dart: 스킬 모델 개선, 쿨다운/효과 타입 추가 ## Canvas 애니메이션 리팩토링 - battle_composer.dart 삭제 (레거시 위젯 기반 렌더러) - monster_colors.dart 삭제 (AsciiCell 색상 시스템으로 통합) - canvas_battle_composer.dart: z-index 정렬 (몬스터 z=1, 캐릭터 z=2, 이펙트 z=3) - ascii_cell.dart, ascii_layer.dart: 코드 정리 ## UI/UX 개선 - hp_mp_bar.dart: l10n 적용, 몬스터 HP 바 컴팩트화 - death_overlay.dart: 사망 화면 개선 - equipment_stats_panel.dart: 장비 스탯 표시 확장 - active_buff_panel.dart: 버프 패널 개선 - notification_overlay.dart: 알림 시스템 개선 ## 다국어 지원 확장 - game_text_l10n.dart: 게임 텍스트 통합 (+758 라인) - 한국어/일본어/영어/중국어 번역 업데이트 - ARB 파일 동기화 ## 게임 로직 개선 - progress_service.dart: 진행 로직 리팩토링 - combat_calculator.dart: 전투 계산 로직 개선 - stat_calculator.dart: 스탯 계산 시스템 개선 - story_service.dart: 스토리 진행 로직 개선 ## 기타 - theme_preferences.dart 삭제 (미사용) - 테스트 파일 업데이트 - class_data.dart: 클래스 데이터 정리
This commit is contained in:
@@ -1,3 +1,28 @@
|
||||
// ============================================================================
|
||||
// 랭크 스케일링 (Rank Scaling)
|
||||
// ============================================================================
|
||||
|
||||
/// 스펠 랭크에 따른 스킬 배율 계산
|
||||
///
|
||||
/// 랭크 1: 1.0x, 랭크 2: 1.15x, 랭크 3: 1.30x, ...
|
||||
double getRankMultiplier(int rank) => 1.0 + (rank - 1) * 0.15;
|
||||
|
||||
/// 랭크에 따른 쿨타임 감소율 계산
|
||||
///
|
||||
/// 랭크당 5% 감소 (최대 50% 감소)
|
||||
double getRankCooldownMultiplier(int rank) =>
|
||||
(1.0 - (rank - 1) * 0.05).clamp(0.5, 1.0);
|
||||
|
||||
/// 랭크에 따른 MP 비용 감소율 계산
|
||||
///
|
||||
/// 랭크당 3% 감소 (최대 30% 감소)
|
||||
double getRankMpMultiplier(int rank) =>
|
||||
(1.0 - (rank - 1) * 0.03).clamp(0.7, 1.0);
|
||||
|
||||
// ============================================================================
|
||||
// 스킬 타입 (Skill Types)
|
||||
// ============================================================================
|
||||
|
||||
/// 스킬 타입
|
||||
enum SkillType {
|
||||
/// 공격 스킬
|
||||
@@ -103,6 +128,9 @@ class Skill {
|
||||
this.baseDotDamage,
|
||||
this.baseDotDurationMs,
|
||||
this.baseDotTickMs,
|
||||
this.hitCount = 1,
|
||||
this.lifestealPercent = 0.0,
|
||||
this.mpHealAmount = 0,
|
||||
});
|
||||
|
||||
/// 스킬 ID
|
||||
@@ -156,6 +184,15 @@ class Skill {
|
||||
/// DOT 기본 틱 간격 (밀리초, 스킬 레벨로 결정)
|
||||
final int? baseDotTickMs;
|
||||
|
||||
/// 다중 타격 횟수 (기본 1)
|
||||
final int hitCount;
|
||||
|
||||
/// HP 흡수율 (0.0 ~ 1.0, 데미지의 N% 회복)
|
||||
final double lifestealPercent;
|
||||
|
||||
/// MP 회복량 (MP 회복 스킬용)
|
||||
final int mpHealAmount;
|
||||
|
||||
/// 공격 스킬 여부
|
||||
bool get isAttack => type == SkillType.attack;
|
||||
|
||||
@@ -207,11 +244,7 @@ class SkillState {
|
||||
return cooldownMs - elapsed;
|
||||
}
|
||||
|
||||
SkillState copyWith({
|
||||
String? skillId,
|
||||
int? lastUsedMs,
|
||||
int? rank,
|
||||
}) {
|
||||
SkillState copyWith({String? skillId, int? lastUsedMs, int? rank}) {
|
||||
return SkillState(
|
||||
skillId: skillId ?? this.skillId,
|
||||
lastUsedMs: lastUsedMs ?? this.lastUsedMs,
|
||||
@@ -302,11 +335,7 @@ class SkillUseResult {
|
||||
|
||||
/// 실패 결과 생성
|
||||
factory SkillUseResult.failed(Skill skill, SkillFailReason reason) {
|
||||
return SkillUseResult(
|
||||
skill: skill,
|
||||
success: false,
|
||||
failReason: reason,
|
||||
);
|
||||
return SkillUseResult(skill: skill, success: false, failReason: reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,7 +413,11 @@ class DotEffect {
|
||||
/// [skill] DOT 스킬
|
||||
/// [playerInt] 플레이어 INT (틱당 데미지 보정)
|
||||
/// [playerWis] 플레이어 WIS (틱 간격 보정)
|
||||
factory DotEffect.fromSkill(Skill skill, {int playerInt = 10, int playerWis = 10}) {
|
||||
factory DotEffect.fromSkill(
|
||||
Skill skill, {
|
||||
int playerInt = 10,
|
||||
int playerWis = 10,
|
||||
}) {
|
||||
assert(skill.isDot, 'DOT 스킬만 DotEffect 생성 가능');
|
||||
assert(skill.baseDotDamage != null, 'baseDotDamage 필수');
|
||||
assert(skill.baseDotDurationMs != null, 'baseDotDurationMs 필수');
|
||||
@@ -396,7 +429,9 @@ class DotEffect {
|
||||
|
||||
// WIS → 틱 간격 보정 (WIS 10 기준, ±2%/포인트, 빨라짐)
|
||||
final wisMod = 1.0 + (playerWis - 10) * 0.02;
|
||||
final actualTickMs = (skill.baseDotTickMs! / wisMod).clamp(200, 2000).round();
|
||||
final actualTickMs = (skill.baseDotTickMs! / wisMod)
|
||||
.clamp(200, 2000)
|
||||
.round();
|
||||
|
||||
return DotEffect(
|
||||
skillId: skill.id,
|
||||
|
||||
Reference in New Issue
Block a user