feat(core): 장비 시스템 및 게임 상태 모델 확장
- Equipment 클래스를 11개 슬롯으로 확장 (원본 Main.dfm 충실) - TaskInfo에 몬스터 정보(baseName, part) 추가 - Stats에 현재 HP/MP 필드 추가 - 히스토리 기능 구현 (plotHistory, questHistory) - pq_logic winEquip/winStatIndex 원본 로직 개선 - 퀘스트 몬스터 처리 로직 구현 - SaveData 직렬화 확장
This commit is contained in:
@@ -38,7 +38,8 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
int _wis = 0;
|
||||
int _cha = 0;
|
||||
|
||||
// 롤 이력 (Unroll 기능용)
|
||||
// 롤 이력 (Unroll 기능용) - 원본 OldRolls TListBox
|
||||
static const int _maxRollHistory = 20; // 최대 저장 개수
|
||||
final List<int> _rollHistory = [];
|
||||
|
||||
// 현재 RNG 시드 (Re-Roll 전 저장)
|
||||
@@ -93,6 +94,11 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
// 현재 시드를 이력에 저장
|
||||
_rollHistory.insert(0, _currentSeed);
|
||||
|
||||
// 최대 개수 초과 시 가장 오래된 항목 제거
|
||||
if (_rollHistory.length > _maxRollHistory) {
|
||||
_rollHistory.removeLast();
|
||||
}
|
||||
|
||||
// 새 시드로 굴림
|
||||
_currentSeed = math.Random().nextInt(0x7FFFFFFF);
|
||||
_rollStats();
|
||||
@@ -132,6 +138,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
}
|
||||
|
||||
/// Sold! 버튼 클릭 - 캐릭터 생성 완료
|
||||
/// 원본 Main.pas:1371-1388 RollCharacter 로직
|
||||
void _onSold() {
|
||||
final name = _nameController.text.trim();
|
||||
if (name.isEmpty) {
|
||||
@@ -144,22 +151,23 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
// 게임에 사용할 새 RNG 생성
|
||||
final gameSeed = math.Random().nextInt(0x7FFFFFFF);
|
||||
|
||||
// 종족/직업의 보너스 스탯 파싱
|
||||
final raceEntry = _config.races[_selectedRaceIndex];
|
||||
final klassEntry = _config.klasses[_selectedKlassIndex];
|
||||
final raceBonus = _parseStatBonus(raceEntry);
|
||||
final klassBonus = _parseStatBonus(klassEntry);
|
||||
// 원본 Main.pas:1380-1381 - 기본 롤 값(CON.Tag, INT.Tag)만 사용
|
||||
// 종족/직업 보너스는 스탯에 적용되지 않음 (UI 힌트용)
|
||||
// Put(Stats,'HP Max',Random(8) + CON.Tag div 6);
|
||||
// Put(Stats,'MP Max',Random(8) + INT.Tag div 6);
|
||||
final hpMax = math.Random().nextInt(8) + _con ~/ 6;
|
||||
final mpMax = math.Random().nextInt(8) + _int ~/ 6;
|
||||
|
||||
// 최종 스탯 계산 (기본 + 종족 보너스 + 직업 보너스)
|
||||
// 원본 Main.pas:1375-1379 - 기본 롤 값 그대로 저장 (보너스 없음)
|
||||
final finalStats = Stats(
|
||||
str: _str + (raceBonus['STR'] ?? 0) + (klassBonus['STR'] ?? 0),
|
||||
con: _con + (raceBonus['CON'] ?? 0) + (klassBonus['CON'] ?? 0),
|
||||
dex: _dex + (raceBonus['DEX'] ?? 0) + (klassBonus['DEX'] ?? 0),
|
||||
intelligence: _int + (raceBonus['INT'] ?? 0) + (klassBonus['INT'] ?? 0),
|
||||
wis: _wis + (raceBonus['WIS'] ?? 0) + (klassBonus['WIS'] ?? 0),
|
||||
cha: _cha + (raceBonus['CHA'] ?? 0) + (klassBonus['CHA'] ?? 0),
|
||||
hpMax: _con + (raceBonus['CON'] ?? 0) + (klassBonus['CON'] ?? 0),
|
||||
mpMax: _int + (raceBonus['INT'] ?? 0) + (klassBonus['INT'] ?? 0),
|
||||
str: _str,
|
||||
con: _con,
|
||||
dex: _dex,
|
||||
intelligence: _int,
|
||||
wis: _wis,
|
||||
cha: _cha,
|
||||
hpMax: hpMax,
|
||||
mpMax: mpMax,
|
||||
);
|
||||
|
||||
final traits = Traits(
|
||||
@@ -186,24 +194,6 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
widget.onCharacterCreated?.call(initialState);
|
||||
}
|
||||
|
||||
/// 종족/직업 보너스 파싱 (예: "Half Orc|STR+2,INT-1")
|
||||
Map<String, int> _parseStatBonus(String entry) {
|
||||
final parts = entry.split('|');
|
||||
if (parts.length < 2) return {};
|
||||
|
||||
final bonuses = <String, int>{};
|
||||
final bonusPart = parts[1];
|
||||
|
||||
// STR+2,INT-1 형식 파싱
|
||||
final regex = RegExp(r'([A-Z]+)([+-]\d+)');
|
||||
for (final match in regex.allMatches(bonusPart)) {
|
||||
final stat = match.group(1)!;
|
||||
final value = int.parse(match.group(2)!);
|
||||
bonuses[stat] = value;
|
||||
}
|
||||
return bonuses;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
|
||||
Reference in New Issue
Block a user