refactor(model): SpellBook을 SkillBook으로 리네이밍
- 게임 컨셉에 맞게 주문서 → 스킬북 용어 통일 - 관련 모든 참조 일괄 변경
This commit is contained in:
@@ -29,16 +29,16 @@ class ArenaService {
|
|||||||
// 스킬 시스템 헬퍼
|
// 스킬 시스템 헬퍼
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/// HallOfFameEntry의 finalSpells에서 Skill 목록 추출
|
/// HallOfFameEntry의 finalSkills에서 Skill 목록 추출
|
||||||
List<Skill> _getSkillsFromEntry(HallOfFameEntry entry) {
|
List<Skill> _getSkillsFromEntry(HallOfFameEntry entry) {
|
||||||
final spells = entry.finalSpells;
|
final skillData = entry.finalSkills;
|
||||||
if (spells == null || spells.isEmpty) return [];
|
if (skillData == null || skillData.isEmpty) return [];
|
||||||
|
|
||||||
final skills = <Skill>[];
|
final skills = <Skill>[];
|
||||||
for (final spell in spells) {
|
for (final data in skillData) {
|
||||||
final spellName = spell['name'];
|
final skillName = data['name'];
|
||||||
if (spellName != null) {
|
if (skillName != null) {
|
||||||
final skill = SkillData.getSkillBySpellName(spellName);
|
final skill = SkillData.getSkillBySpellName(skillName);
|
||||||
if (skill != null) {
|
if (skill != null) {
|
||||||
skills.add(skill);
|
skills.add(skill);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,17 +49,17 @@ class GameMutations {
|
|||||||
final name = parts[0];
|
final name = parts[0];
|
||||||
final rank = parts.length > 1 ? parts[1] : 'I';
|
final rank = parts.length > 1 ? parts[1] : 'I';
|
||||||
|
|
||||||
final spells = [...state.spellBook.spells];
|
final skills = [...state.skillBook.skills];
|
||||||
final index = spells.indexWhere((s) => s.name == name);
|
final index = skills.indexWhere((s) => s.name == name);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
spells[index] = spells[index].copyWith(rank: rank);
|
skills[index] = skills[index].copyWith(rank: rank);
|
||||||
} else {
|
} else {
|
||||||
spells.add(SpellEntry(name: name, rank: rank));
|
skills.add(SkillEntry(name: name, rank: rank));
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.copyWith(
|
return state.copyWith(
|
||||||
rng: state.rng,
|
rng: state.rng,
|
||||||
spellBook: state.spellBook.copyWith(spells: spells),
|
skillBook: state.skillBook.copyWith(skills: skills),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1240,11 +1240,11 @@ class ProgressService {
|
|||||||
|
|
||||||
// 플레이어 공격 체크
|
// 플레이어 공격 체크
|
||||||
if (playerAccumulator >= playerStats.attackDelayMs) {
|
if (playerAccumulator >= playerStats.attackDelayMs) {
|
||||||
// SpellBook에서 사용 가능한 스킬 ID 목록 조회
|
// SkillBook에서 사용 가능한 스킬 ID 목록 조회
|
||||||
var availableSkillIds = skillService.getAvailableSkillIdsFromSpellBook(
|
var availableSkillIds = skillService.getAvailableSkillIdsFromSkillBook(
|
||||||
state.spellBook,
|
state.skillBook,
|
||||||
);
|
);
|
||||||
// SpellBook에 스킬이 없으면 기본 스킬 사용
|
// SkillBook에 스킬이 없으면 기본 스킬 사용
|
||||||
if (availableSkillIds.isEmpty) {
|
if (availableSkillIds.isEmpty) {
|
||||||
availableSkillIds = SkillData.defaultSkillIds;
|
availableSkillIds = SkillData.defaultSkillIds;
|
||||||
}
|
}
|
||||||
@@ -1259,9 +1259,9 @@ class ProgressService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (selectedSkill != null && selectedSkill.isAttack) {
|
if (selectedSkill != null && selectedSkill.isAttack) {
|
||||||
// 스펠 랭크 조회 (SpellBook 기반)
|
// 스킬 랭크 조회 (SkillBook 기반)
|
||||||
final spellRank = skillService.getSkillRankFromSpellBook(
|
final skillRank = skillService.getSkillRankFromSkillBook(
|
||||||
state.spellBook,
|
state.skillBook,
|
||||||
selectedSkill.id,
|
selectedSkill.id,
|
||||||
);
|
);
|
||||||
// 랭크 스케일링 적용된 공격 스킬 사용
|
// 랭크 스케일링 적용된 공격 스킬 사용
|
||||||
@@ -1270,7 +1270,7 @@ class ProgressService {
|
|||||||
player: playerStats,
|
player: playerStats,
|
||||||
monster: monsterStats,
|
monster: monsterStats,
|
||||||
skillSystem: updatedSkillSystem,
|
skillSystem: updatedSkillSystem,
|
||||||
rank: spellRank,
|
rank: skillRank,
|
||||||
);
|
);
|
||||||
playerStats = skillResult.updatedPlayer;
|
playerStats = skillResult.updatedPlayer;
|
||||||
monsterStats = skillResult.updatedMonster;
|
monsterStats = skillResult.updatedMonster;
|
||||||
|
|||||||
@@ -552,50 +552,50 @@ class SkillService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// SpellBook 연동
|
// SkillBook 연동
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/// SpellBook에서 사용 가능한 스킬 목록 조회
|
/// SkillBook에서 사용 가능한 스킬 목록 조회
|
||||||
///
|
///
|
||||||
/// SpellEntry 이름을 Skill로 매핑하여 반환
|
/// SkillEntry 이름을 Skill로 매핑하여 반환
|
||||||
List<Skill> getAvailableSkillsFromSpellBook(SpellBook spellBook) {
|
List<Skill> getAvailableSkillsFromSkillBook(SkillBook skillBook) {
|
||||||
return spellBook.spells
|
return skillBook.skills
|
||||||
.map((spell) => SkillData.getSkillBySpellName(spell.name))
|
.map((entry) => SkillData.getSkillBySpellName(entry.name))
|
||||||
.whereType<Skill>()
|
.whereType<Skill>()
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SpellBook에서 스킬의 랭크(레벨) 조회
|
/// SkillBook에서 스킬의 랭크(레벨) 조회
|
||||||
///
|
///
|
||||||
/// 로마숫자 랭크(I, II, III)를 정수로 변환하여 반환
|
/// 로마숫자 랭크(I, II, III)를 정수로 변환하여 반환
|
||||||
/// 스펠이 없으면 1 반환
|
/// 스킬이 없으면 1 반환
|
||||||
int getSkillRankFromSpellBook(SpellBook spellBook, String skillId) {
|
int getSkillRankFromSkillBook(SkillBook skillBook, String skillId) {
|
||||||
// skillId로 스킬 찾기
|
// skillId로 스킬 찾기
|
||||||
final skill = SkillData.getSkillById(skillId);
|
final skill = SkillData.getSkillById(skillId);
|
||||||
if (skill == null) return 1;
|
if (skill == null) return 1;
|
||||||
|
|
||||||
// 스킬 이름으로 SpellEntry 찾기
|
// 스킬 이름으로 SkillEntry 찾기
|
||||||
for (final spell in spellBook.spells) {
|
for (final entry in skillBook.skills) {
|
||||||
if (spell.name == skill.name) {
|
if (entry.name == skill.name) {
|
||||||
return romanToInt(spell.rank);
|
return romanToInt(entry.rank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; // 기본 랭크
|
return 1; // 기본 랭크
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SpellBook에서 스킬 ID 목록 조회
|
/// SkillBook에서 스킬 ID 목록 조회
|
||||||
///
|
///
|
||||||
/// 전투 시스템에서 사용 가능한 스킬 ID 목록 반환
|
/// 전투 시스템에서 사용 가능한 스킬 ID 목록 반환
|
||||||
List<String> getAvailableSkillIdsFromSpellBook(SpellBook spellBook) {
|
List<String> getAvailableSkillIdsFromSkillBook(SkillBook skillBook) {
|
||||||
return getAvailableSkillsFromSpellBook(
|
return getAvailableSkillsFromSkillBook(
|
||||||
spellBook,
|
skillBook,
|
||||||
).map((skill) => skill.id).toList();
|
).map((skill) => skill.id).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 랭크 스케일링이 적용된 공격 스킬 사용
|
/// 랭크 스케일링이 적용된 공격 스킬 사용
|
||||||
///
|
///
|
||||||
/// [rank] 스펠 랭크 (SpellBook에서 조회)
|
/// [rank] 스펠 랭크 (SkillBook에서 조회)
|
||||||
({
|
({
|
||||||
SkillUseResult result,
|
SkillUseResult result,
|
||||||
CombatStats updatedPlayer,
|
CombatStats updatedPlayer,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class GameState {
|
|||||||
Stats? stats,
|
Stats? stats,
|
||||||
Inventory? inventory,
|
Inventory? inventory,
|
||||||
Equipment? equipment,
|
Equipment? equipment,
|
||||||
SpellBook? spellBook,
|
SkillBook? skillBook,
|
||||||
ProgressState? progress,
|
ProgressState? progress,
|
||||||
QueueState? queue,
|
QueueState? queue,
|
||||||
SkillSystemState? skillSystem,
|
SkillSystemState? skillSystem,
|
||||||
@@ -32,7 +32,7 @@ class GameState {
|
|||||||
stats = stats ?? Stats.empty(),
|
stats = stats ?? Stats.empty(),
|
||||||
inventory = inventory ?? Inventory.empty(),
|
inventory = inventory ?? Inventory.empty(),
|
||||||
equipment = equipment ?? Equipment.empty(),
|
equipment = equipment ?? Equipment.empty(),
|
||||||
spellBook = spellBook ?? SpellBook.empty(),
|
skillBook = skillBook ?? SkillBook.empty(),
|
||||||
progress = progress ?? ProgressState.empty(),
|
progress = progress ?? ProgressState.empty(),
|
||||||
queue = queue ?? QueueState.empty(),
|
queue = queue ?? QueueState.empty(),
|
||||||
skillSystem = skillSystem ?? SkillSystemState.empty(),
|
skillSystem = skillSystem ?? SkillSystemState.empty(),
|
||||||
@@ -44,7 +44,7 @@ class GameState {
|
|||||||
Stats? stats,
|
Stats? stats,
|
||||||
Inventory? inventory,
|
Inventory? inventory,
|
||||||
Equipment? equipment,
|
Equipment? equipment,
|
||||||
SpellBook? spellBook,
|
SkillBook? skillBook,
|
||||||
ProgressState? progress,
|
ProgressState? progress,
|
||||||
QueueState? queue,
|
QueueState? queue,
|
||||||
SkillSystemState? skillSystem,
|
SkillSystemState? skillSystem,
|
||||||
@@ -57,7 +57,7 @@ class GameState {
|
|||||||
stats: stats,
|
stats: stats,
|
||||||
inventory: inventory,
|
inventory: inventory,
|
||||||
equipment: equipment,
|
equipment: equipment,
|
||||||
spellBook: spellBook,
|
skillBook: skillBook,
|
||||||
progress: progress,
|
progress: progress,
|
||||||
queue: queue,
|
queue: queue,
|
||||||
skillSystem: skillSystem,
|
skillSystem: skillSystem,
|
||||||
@@ -71,7 +71,7 @@ class GameState {
|
|||||||
final Stats stats;
|
final Stats stats;
|
||||||
final Inventory inventory;
|
final Inventory inventory;
|
||||||
final Equipment equipment;
|
final Equipment equipment;
|
||||||
final SpellBook spellBook;
|
final SkillBook skillBook;
|
||||||
final ProgressState progress;
|
final ProgressState progress;
|
||||||
final QueueState queue;
|
final QueueState queue;
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ class GameState {
|
|||||||
Stats? stats,
|
Stats? stats,
|
||||||
Inventory? inventory,
|
Inventory? inventory,
|
||||||
Equipment? equipment,
|
Equipment? equipment,
|
||||||
SpellBook? spellBook,
|
SkillBook? skillBook,
|
||||||
ProgressState? progress,
|
ProgressState? progress,
|
||||||
QueueState? queue,
|
QueueState? queue,
|
||||||
SkillSystemState? skillSystem,
|
SkillSystemState? skillSystem,
|
||||||
@@ -107,7 +107,7 @@ class GameState {
|
|||||||
stats: stats ?? this.stats,
|
stats: stats ?? this.stats,
|
||||||
inventory: inventory ?? this.inventory,
|
inventory: inventory ?? this.inventory,
|
||||||
equipment: equipment ?? this.equipment,
|
equipment: equipment ?? this.equipment,
|
||||||
spellBook: spellBook ?? this.spellBook,
|
skillBook: skillBook ?? this.skillBook,
|
||||||
progress: progress ?? this.progress,
|
progress: progress ?? this.progress,
|
||||||
queue: queue ?? this.queue,
|
queue: queue ?? this.queue,
|
||||||
skillSystem: skillSystem ?? this.skillSystem,
|
skillSystem: skillSystem ?? this.skillSystem,
|
||||||
@@ -660,26 +660,26 @@ class Equipment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpellEntry {
|
class SkillEntry {
|
||||||
const SpellEntry({required this.name, required this.rank});
|
const SkillEntry({required this.name, required this.rank});
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
final String rank; // e.g., Roman numerals
|
final String rank; // e.g., Roman numerals
|
||||||
|
|
||||||
SpellEntry copyWith({String? name, String? rank}) {
|
SkillEntry copyWith({String? name, String? rank}) {
|
||||||
return SpellEntry(name: name ?? this.name, rank: rank ?? this.rank);
|
return SkillEntry(name: name ?? this.name, rank: rank ?? this.rank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpellBook {
|
class SkillBook {
|
||||||
const SpellBook({required this.spells});
|
const SkillBook({required this.skills});
|
||||||
|
|
||||||
final List<SpellEntry> spells;
|
final List<SkillEntry> skills;
|
||||||
|
|
||||||
factory SpellBook.empty() => const SpellBook(spells: []);
|
factory SkillBook.empty() => const SkillBook(skills: []);
|
||||||
|
|
||||||
SpellBook copyWith({List<SpellEntry>? spells}) {
|
SkillBook copyWith({List<SkillEntry>? skills}) {
|
||||||
return SpellBook(spells: spells ?? this.spells);
|
return SkillBook(skills: skills ?? this.skills);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class HallOfFameEntry {
|
|||||||
required this.clearedAt,
|
required this.clearedAt,
|
||||||
this.finalStats,
|
this.finalStats,
|
||||||
this.finalEquipment,
|
this.finalEquipment,
|
||||||
this.finalSpells,
|
this.finalSkills,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// 고유 ID (UUID)
|
/// 고유 ID (UUID)
|
||||||
@@ -61,7 +61,7 @@ class HallOfFameEntry {
|
|||||||
final List<EquipmentItem>? finalEquipment;
|
final List<EquipmentItem>? finalEquipment;
|
||||||
|
|
||||||
/// 최종 스펠북 (스펠 이름 + 랭크)
|
/// 최종 스펠북 (스펠 이름 + 랭크)
|
||||||
final List<Map<String, String>>? finalSpells;
|
final List<Map<String, String>>? finalSkills;
|
||||||
|
|
||||||
/// 플레이 시간을 Duration으로 변환
|
/// 플레이 시간을 Duration으로 변환
|
||||||
Duration get totalPlayTime => Duration(milliseconds: totalPlayTimeMs);
|
Duration get totalPlayTime => Duration(milliseconds: totalPlayTimeMs);
|
||||||
@@ -96,7 +96,7 @@ class HallOfFameEntry {
|
|||||||
DateTime? clearedAt,
|
DateTime? clearedAt,
|
||||||
CombatStats? finalStats,
|
CombatStats? finalStats,
|
||||||
List<EquipmentItem>? finalEquipment,
|
List<EquipmentItem>? finalEquipment,
|
||||||
List<Map<String, String>>? finalSpells,
|
List<Map<String, String>>? finalSkills,
|
||||||
}) {
|
}) {
|
||||||
return HallOfFameEntry(
|
return HallOfFameEntry(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
@@ -111,7 +111,7 @@ class HallOfFameEntry {
|
|||||||
clearedAt: clearedAt ?? this.clearedAt,
|
clearedAt: clearedAt ?? this.clearedAt,
|
||||||
finalStats: finalStats ?? this.finalStats,
|
finalStats: finalStats ?? this.finalStats,
|
||||||
finalEquipment: finalEquipment ?? this.finalEquipment,
|
finalEquipment: finalEquipment ?? this.finalEquipment,
|
||||||
finalSpells: finalSpells ?? this.finalSpells,
|
finalSkills: finalSkills ?? this.finalSkills,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ class HallOfFameEntry {
|
|||||||
clearedAt: DateTime.now(),
|
clearedAt: DateTime.now(),
|
||||||
finalStats: combatStats,
|
finalStats: combatStats,
|
||||||
finalEquipment: List<EquipmentItem>.from(state.equipment.items),
|
finalEquipment: List<EquipmentItem>.from(state.equipment.items),
|
||||||
finalSpells: state.spellBook.spells
|
finalSkills: state.skillBook.skills
|
||||||
.map((s) => {'name': s.name, 'rank': s.rank})
|
.map((s) => {'name': s.name, 'rank': s.rank})
|
||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
@@ -156,7 +156,7 @@ class HallOfFameEntry {
|
|||||||
'clearedAt': clearedAt.toIso8601String(),
|
'clearedAt': clearedAt.toIso8601String(),
|
||||||
'finalStats': finalStats?.toJson(),
|
'finalStats': finalStats?.toJson(),
|
||||||
'finalEquipment': finalEquipment?.map((e) => e.toJson()).toList(),
|
'finalEquipment': finalEquipment?.map((e) => e.toJson()).toList(),
|
||||||
'finalSpells': finalSpells,
|
'finalSkills': finalSkills,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,8 +181,8 @@ class HallOfFameEntry {
|
|||||||
.map((e) => EquipmentItem.fromJson(e as Map<String, dynamic>))
|
.map((e) => EquipmentItem.fromJson(e as Map<String, dynamic>))
|
||||||
.toList()
|
.toList()
|
||||||
: null,
|
: null,
|
||||||
finalSpells: json['finalSpells'] != null
|
finalSkills: json['finalSkills'] != null
|
||||||
? (json['finalSpells'] as List<dynamic>)
|
? (json['finalSkills'] as List<dynamic>)
|
||||||
.map((s) => Map<String, String>.from(s as Map))
|
.map((s) => Map<String, String>.from(s as Map))
|
||||||
.toList()
|
.toList()
|
||||||
: null,
|
: null,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class GameSave {
|
|||||||
required this.stats,
|
required this.stats,
|
||||||
required this.inventory,
|
required this.inventory,
|
||||||
required this.equipment,
|
required this.equipment,
|
||||||
required this.spellBook,
|
required this.skillBook,
|
||||||
required this.progress,
|
required this.progress,
|
||||||
required this.queue,
|
required this.queue,
|
||||||
});
|
});
|
||||||
@@ -26,7 +26,7 @@ class GameSave {
|
|||||||
stats: state.stats,
|
stats: state.stats,
|
||||||
inventory: state.inventory,
|
inventory: state.inventory,
|
||||||
equipment: state.equipment,
|
equipment: state.equipment,
|
||||||
spellBook: state.spellBook,
|
skillBook: state.skillBook,
|
||||||
progress: state.progress,
|
progress: state.progress,
|
||||||
queue: state.queue,
|
queue: state.queue,
|
||||||
);
|
);
|
||||||
@@ -38,7 +38,7 @@ class GameSave {
|
|||||||
final Stats stats;
|
final Stats stats;
|
||||||
final Inventory inventory;
|
final Inventory inventory;
|
||||||
final Equipment equipment;
|
final Equipment equipment;
|
||||||
final SpellBook spellBook;
|
final SkillBook skillBook;
|
||||||
final ProgressState progress;
|
final ProgressState progress;
|
||||||
final QueueState queue;
|
final QueueState queue;
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ class GameSave {
|
|||||||
'sollerets': equipment.sollerets,
|
'sollerets': equipment.sollerets,
|
||||||
'bestIndex': equipment.bestIndex,
|
'bestIndex': equipment.bestIndex,
|
||||||
},
|
},
|
||||||
'spells': spellBook.spells
|
'skills': skillBook.skills
|
||||||
.map((e) => {'name': e.name, 'rank': e.rank})
|
.map((e) => {'name': e.name, 'rank': e.rank})
|
||||||
.toList(),
|
.toList(),
|
||||||
'progress': {
|
'progress': {
|
||||||
@@ -140,7 +140,7 @@ class GameSave {
|
|||||||
final equipmentJson = json['equipment'] as Map<String, dynamic>;
|
final equipmentJson = json['equipment'] as Map<String, dynamic>;
|
||||||
final progressJson = json['progress'] as Map<String, dynamic>;
|
final progressJson = json['progress'] as Map<String, dynamic>;
|
||||||
final queueJson = (json['queue'] as List<dynamic>? ?? []).cast<dynamic>();
|
final queueJson = (json['queue'] as List<dynamic>? ?? []).cast<dynamic>();
|
||||||
final spellsJson = (json['spells'] as List<dynamic>? ?? []).cast<dynamic>();
|
final skillsJson = (json['skills'] as List<dynamic>? ?? []).cast<dynamic>();
|
||||||
|
|
||||||
return GameSave(
|
return GameSave(
|
||||||
version: json['version'] as int? ?? kSaveVersion,
|
version: json['version'] as int? ?? kSaveVersion,
|
||||||
@@ -192,10 +192,10 @@ class GameSave {
|
|||||||
sollerets: equipmentJson['sollerets'] as String? ?? '',
|
sollerets: equipmentJson['sollerets'] as String? ?? '',
|
||||||
bestIndex: equipmentJson['bestIndex'] as int? ?? 0,
|
bestIndex: equipmentJson['bestIndex'] as int? ?? 0,
|
||||||
),
|
),
|
||||||
spellBook: SpellBook(
|
skillBook: SkillBook(
|
||||||
spells: spellsJson
|
skills: skillsJson
|
||||||
.map(
|
.map(
|
||||||
(e) => SpellEntry(
|
(e) => SkillEntry(
|
||||||
name: (e as Map<String, dynamic>)['name'] as String? ?? '',
|
name: (e as Map<String, dynamic>)['name'] as String? ?? '',
|
||||||
rank: (e)['rank'] as String? ?? 'I',
|
rank: (e)['rank'] as String? ?? 'I',
|
||||||
),
|
),
|
||||||
@@ -261,7 +261,7 @@ class GameSave {
|
|||||||
stats: stats,
|
stats: stats,
|
||||||
inventory: inventory,
|
inventory: inventory,
|
||||||
equipment: equipment,
|
equipment: equipment,
|
||||||
spellBook: spellBook,
|
skillBook: skillBook,
|
||||||
progress: progress,
|
progress: progress,
|
||||||
queue: queue,
|
queue: queue,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ class _ArenaBattleScreenState extends State<ArenaBattleScreen>
|
|||||||
message: '${widget.match.challenger.characterName} uses '
|
message: '${widget.match.challenger.characterName} uses '
|
||||||
'${turn.challengerSkillUsed}!',
|
'${turn.challengerSkillUsed}!',
|
||||||
timestamp: DateTime.now(),
|
timestamp: DateTime.now(),
|
||||||
type: CombatLogType.spell,
|
type: CombatLogType.skill,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ class _ArenaBattleScreenState extends State<ArenaBattleScreen>
|
|||||||
message: '${widget.match.opponent.characterName} uses '
|
message: '${widget.match.opponent.characterName} uses '
|
||||||
'${turn.opponentSkillUsed}!',
|
'${turn.opponentSkillUsed}!',
|
||||||
timestamp: DateTime.now(),
|
timestamp: DateTime.now(),
|
||||||
type: CombatLogType.spell,
|
type: CombatLogType.skill,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
|||||||
)
|
)
|
||||||
: (
|
: (
|
||||||
game_l10n.combatSkillDamage(skillName, event.damage),
|
game_l10n.combatSkillDamage(skillName, event.damage),
|
||||||
CombatLogType.spell,
|
CombatLogType.skill,
|
||||||
),
|
),
|
||||||
CombatEventType.playerHeal => (
|
CombatEventType.playerHeal => (
|
||||||
game_l10n.combatSkillHeal(
|
game_l10n.combatSkillHeal(
|
||||||
@@ -1327,11 +1327,11 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 통합 스킬 목록 (SpellBook 기반)
|
/// 통합 스킬 목록 (SkillBook 기반)
|
||||||
///
|
///
|
||||||
/// 스펠 이름, 랭크, 스킬 타입, 쿨타임 표시
|
/// 스킬 이름, 랭크, 스킬 타입, 쿨타임 표시
|
||||||
Widget _buildSkillsList(GameState state) {
|
Widget _buildSkillsList(GameState state) {
|
||||||
if (state.spellBook.spells.isEmpty) {
|
if (state.skillBook.skills.isEmpty) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
L10n.of(context).noSpellsYet,
|
L10n.of(context).noSpellsYet,
|
||||||
@@ -1345,12 +1345,12 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
itemCount: state.spellBook.spells.length,
|
itemCount: state.skillBook.skills.length,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final spell = state.spellBook.spells[index];
|
final skillEntry = state.skillBook.skills[index];
|
||||||
final skill = SkillData.getSkillBySpellName(spell.name);
|
final skill = SkillData.getSkillBySpellName(skillEntry.name);
|
||||||
final spellName = GameDataL10n.getSpellName(context, spell.name);
|
final skillName = GameDataL10n.getSpellName(context, skillEntry.name);
|
||||||
|
|
||||||
// 쿨타임 상태 확인
|
// 쿨타임 상태 확인
|
||||||
final skillState = skill != null
|
final skillState = skill != null
|
||||||
@@ -1361,8 +1361,8 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
|||||||
!skillState.isReady(state.skillSystem.elapsedMs, skill!.cooldownMs);
|
!skillState.isReady(state.skillSystem.elapsedMs, skill!.cooldownMs);
|
||||||
|
|
||||||
return _SkillRow(
|
return _SkillRow(
|
||||||
spellName: spellName,
|
skillName: skillName,
|
||||||
rank: spell.rank,
|
rank: skillEntry.rank,
|
||||||
skill: skill,
|
skill: skill,
|
||||||
isOnCooldown: isOnCooldown,
|
isOnCooldown: isOnCooldown,
|
||||||
);
|
);
|
||||||
@@ -1615,16 +1615,16 @@ class _GamePlayScreenState extends State<GamePlayScreen>
|
|||||||
|
|
||||||
/// 스킬 행 위젯
|
/// 스킬 행 위젯
|
||||||
///
|
///
|
||||||
/// 스펠 이름, 랭크, 스킬 타입 아이콘, 쿨타임 상태 표시
|
/// 스킬 이름, 랭크, 스킬 타입 아이콘, 쿨타임 상태 표시
|
||||||
class _SkillRow extends StatelessWidget {
|
class _SkillRow extends StatelessWidget {
|
||||||
const _SkillRow({
|
const _SkillRow({
|
||||||
required this.spellName,
|
required this.skillName,
|
||||||
required this.rank,
|
required this.rank,
|
||||||
required this.skill,
|
required this.skill,
|
||||||
required this.isOnCooldown,
|
required this.isOnCooldown,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String spellName;
|
final String skillName;
|
||||||
final String rank;
|
final String rank;
|
||||||
final Skill? skill;
|
final Skill? skill;
|
||||||
final bool isOnCooldown;
|
final bool isOnCooldown;
|
||||||
@@ -1641,7 +1641,7 @@ class _SkillRow extends StatelessWidget {
|
|||||||
// 스킬 이름
|
// 스킬 이름
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
spellName,
|
skillName,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: isOnCooldown ? Colors.grey : null,
|
color: isOnCooldown ? Colors.grey : null,
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ class _MobileCarouselLayoutState extends State<MobileCarouselLayout> {
|
|||||||
children: [
|
children: [
|
||||||
// 0: 스킬
|
// 0: 스킬
|
||||||
SkillsPage(
|
SkillsPage(
|
||||||
spellBook: state.spellBook,
|
skillBook: state.skillBook,
|
||||||
skillSystem: state.skillSystem,
|
skillSystem: state.skillSystem,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ import 'package:asciineverdie/src/features/game/widgets/active_buff_panel.dart';
|
|||||||
|
|
||||||
/// 스킬 페이지 (캐로셀)
|
/// 스킬 페이지 (캐로셀)
|
||||||
///
|
///
|
||||||
/// SpellBook 기반 스킬 목록과 활성 버프 표시.
|
/// SkillBook 기반 스킬 목록과 활성 버프 표시.
|
||||||
class SkillsPage extends StatelessWidget {
|
class SkillsPage extends StatelessWidget {
|
||||||
const SkillsPage({
|
const SkillsPage({
|
||||||
super.key,
|
super.key,
|
||||||
required this.spellBook,
|
required this.skillBook,
|
||||||
required this.skillSystem,
|
required this.skillSystem,
|
||||||
});
|
});
|
||||||
|
|
||||||
final SpellBook spellBook;
|
final SkillBook skillBook;
|
||||||
final SkillSystemState skillSystem;
|
final SkillSystemState skillSystem;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -61,7 +61,7 @@ class SkillsPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSkillsList(BuildContext context) {
|
Widget _buildSkillsList(BuildContext context) {
|
||||||
if (spellBook.spells.isEmpty) {
|
if (skillBook.skills.isEmpty) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
L10n.of(context).noSpellsYet,
|
L10n.of(context).noSpellsYet,
|
||||||
@@ -71,12 +71,12 @@ class SkillsPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
itemCount: spellBook.spells.length,
|
itemCount: skillBook.skills.length,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final spell = spellBook.spells[index];
|
final skillEntry = skillBook.skills[index];
|
||||||
final skill = SkillData.getSkillBySpellName(spell.name);
|
final skill = SkillData.getSkillBySpellName(skillEntry.name);
|
||||||
final spellName = GameDataL10n.getSpellName(context, spell.name);
|
final skillName = GameDataL10n.getSpellName(context, skillEntry.name);
|
||||||
|
|
||||||
// 쿨타임 상태 확인
|
// 쿨타임 상태 확인
|
||||||
final skillState = skill != null
|
final skillState = skill != null
|
||||||
@@ -87,8 +87,8 @@ class SkillsPage extends StatelessWidget {
|
|||||||
!skillState.isReady(skillSystem.elapsedMs, skill!.cooldownMs);
|
!skillState.isReady(skillSystem.elapsedMs, skill!.cooldownMs);
|
||||||
|
|
||||||
return _SkillRow(
|
return _SkillRow(
|
||||||
spellName: spellName,
|
skillName: skillName,
|
||||||
rank: spell.rank,
|
rank: skillEntry.rank,
|
||||||
skill: skill,
|
skill: skill,
|
||||||
isOnCooldown: isOnCooldown,
|
isOnCooldown: isOnCooldown,
|
||||||
);
|
);
|
||||||
@@ -100,13 +100,13 @@ class SkillsPage extends StatelessWidget {
|
|||||||
/// 스킬 행 위젯
|
/// 스킬 행 위젯
|
||||||
class _SkillRow extends StatelessWidget {
|
class _SkillRow extends StatelessWidget {
|
||||||
const _SkillRow({
|
const _SkillRow({
|
||||||
required this.spellName,
|
required this.skillName,
|
||||||
required this.rank,
|
required this.rank,
|
||||||
required this.skill,
|
required this.skill,
|
||||||
required this.isOnCooldown,
|
required this.isOnCooldown,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String spellName;
|
final String skillName;
|
||||||
final String rank;
|
final String rank;
|
||||||
final Skill? skill;
|
final Skill? skill;
|
||||||
final bool isOnCooldown;
|
final bool isOnCooldown;
|
||||||
@@ -123,7 +123,7 @@ class _SkillRow extends StatelessWidget {
|
|||||||
// 스킬 이름
|
// 스킬 이름
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
spellName,
|
skillName,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: isOnCooldown ? Colors.grey : null,
|
color: isOnCooldown ? Colors.grey : null,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ enum CombatLogType {
|
|||||||
levelUp, // 레벨업
|
levelUp, // 레벨업
|
||||||
questComplete, // 퀘스트 완료
|
questComplete, // 퀘스트 완료
|
||||||
loot, // 전리품 획득
|
loot, // 전리품 획득
|
||||||
spell, // 스킬 사용
|
skill, // 스킬 사용
|
||||||
critical, // 크리티컬 히트
|
critical, // 크리티컬 히트
|
||||||
evade, // 회피
|
evade, // 회피
|
||||||
block, // 방패 방어
|
block, // 방패 방어
|
||||||
@@ -157,7 +157,7 @@ class _LogEntryTile extends StatelessWidget {
|
|||||||
CombatLogType.levelUp => (Colors.amber, Icons.arrow_upward),
|
CombatLogType.levelUp => (Colors.amber, Icons.arrow_upward),
|
||||||
CombatLogType.questComplete => (Colors.blue.shade300, Icons.check_circle),
|
CombatLogType.questComplete => (Colors.blue.shade300, Icons.check_circle),
|
||||||
CombatLogType.loot => (Colors.orange.shade300, Icons.inventory_2),
|
CombatLogType.loot => (Colors.orange.shade300, Icons.inventory_2),
|
||||||
CombatLogType.spell => (Colors.purple.shade300, Icons.auto_fix_high),
|
CombatLogType.skill => (Colors.purple.shade300, Icons.auto_fix_high),
|
||||||
CombatLogType.critical => (Colors.yellow.shade300, Icons.flash_on),
|
CombatLogType.critical => (Colors.yellow.shade300, Icons.flash_on),
|
||||||
CombatLogType.evade => (Colors.cyan.shade300, Icons.directions_run),
|
CombatLogType.evade => (Colors.cyan.shade300, Icons.directions_run),
|
||||||
CombatLogType.block => (Colors.blueGrey.shade300, Icons.shield),
|
CombatLogType.block => (Colors.blueGrey.shade300, Icons.shield),
|
||||||
|
|||||||
@@ -516,12 +516,12 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
],
|
],
|
||||||
// 스펠 섹션 (Spells Section)
|
// 스킬 섹션 (Skills Section)
|
||||||
if (entry.finalSpells != null && entry.finalSpells!.isNotEmpty)
|
if (entry.finalSkills != null && entry.finalSkills!.isNotEmpty)
|
||||||
_buildSection(
|
_buildSection(
|
||||||
icon: Icons.auto_fix_high,
|
icon: Icons.auto_fix_high,
|
||||||
title: l10n.hofSpells,
|
title: l10n.hofSpells,
|
||||||
child: _buildSpellList(context),
|
child: _buildSkillList(context),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -983,15 +983,15 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
|||||||
return widgets;
|
return widgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSpellList(BuildContext context) {
|
Widget _buildSkillList(BuildContext context) {
|
||||||
final spells = entry.finalSpells!;
|
final skills = entry.finalSkills!;
|
||||||
return Wrap(
|
return Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
runSpacing: 4,
|
runSpacing: 4,
|
||||||
children: spells.map((spell) {
|
children: skills.map((skill) {
|
||||||
final name = spell['name'] ?? '';
|
final name = skill['name'] ?? '';
|
||||||
final rank = spell['rank'] ?? '';
|
final rank = skill['rank'] ?? '';
|
||||||
// 스펠 이름 번역 적용
|
// 스킬 이름 번역 적용
|
||||||
final translatedName = GameDataL10n.getSpellName(context, name);
|
final translatedName = GameDataL10n.getSpellName(context, name);
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
|||||||
stats: finalStats,
|
stats: finalStats,
|
||||||
inventory: const Inventory(gold: 0, items: []),
|
inventory: const Inventory(gold: 0, items: []),
|
||||||
equipment: Equipment.empty(),
|
equipment: Equipment.empty(),
|
||||||
spellBook: SpellBook.empty(),
|
skillBook: SkillBook.empty(),
|
||||||
progress: ProgressState.empty(),
|
progress: ProgressState.empty(),
|
||||||
queue: QueueState.empty(),
|
queue: QueueState.empty(),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user