200 lines
7.4 KiB
Python
200 lines
7.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
스토커 기본 데이터 추출 스크립트
|
|
|
|
DT_CharacterStat, DT_CharacterAbility, DT_Skill에서
|
|
10명 스토커의 모든 정보를 추출합니다.
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
STALKERS = ['hilda', 'urud', 'nave', 'baran', 'rio', 'clad', 'rene', 'sinobu', 'lian', 'cazimord']
|
|
|
|
def load_json(file_path):
|
|
"""JSON 파일 로드"""
|
|
with open(file_path, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
# Assets 배열 반환
|
|
return data.get('Assets', [])
|
|
|
|
def find_table(datatables, table_name):
|
|
"""특정 테이블 찾기"""
|
|
for dt in datatables:
|
|
if dt.get('AssetName') == table_name:
|
|
return dt
|
|
return None
|
|
|
|
def extract_character_stats(datatables):
|
|
"""DT_CharacterStat에서 스토커 기본 정보 추출"""
|
|
char_stat_table = find_table(datatables, 'DT_CharacterStat')
|
|
if not char_stat_table:
|
|
return {}
|
|
|
|
stalker_data = {}
|
|
for row in char_stat_table.get('Rows', []):
|
|
row_name = row['RowName']
|
|
if row_name in STALKERS:
|
|
data = row['Data']
|
|
stalker_data[row_name] = {
|
|
'name': data.get('name', ''),
|
|
'jobName': data.get('jobName', ''),
|
|
'str': data.get('str', 0),
|
|
'dex': data.get('dex', 0),
|
|
'int': data.get('int', 0),
|
|
'con': data.get('con', 0),
|
|
'wis': data.get('wis', 0),
|
|
'hP': data.get('hP', 0),
|
|
'mP': data.get('mP', 0),
|
|
'manaRegen': data.get('manaRegen', 0),
|
|
'physicalDamage': data.get('physicalDamage', 0),
|
|
'magicalDamage': data.get('magicalDamage', 0),
|
|
'defaultSkills': data.get('defaultSkills', []),
|
|
'subSkill': data.get('subSkill', ''),
|
|
'ultimateSkill': data.get('ultimateSkill', ''),
|
|
'equipableTypes': data.get('equipableTypes', []),
|
|
'ultimatePoint': data.get('ultimatePoint', 0)
|
|
}
|
|
return stalker_data
|
|
|
|
def extract_character_abilities(datatables):
|
|
"""DT_CharacterAbility에서 평타 몽타주 추출"""
|
|
char_ability_table = find_table(datatables, 'DT_CharacterAbility')
|
|
if not char_ability_table:
|
|
return {}
|
|
|
|
stalker_abilities = {}
|
|
for row in char_ability_table.get('Rows', []):
|
|
row_name = row['RowName']
|
|
if row_name in STALKERS:
|
|
data = row['Data']
|
|
attack_montage_map = data.get('attackMontageMap', {})
|
|
stalker_abilities[row_name] = {
|
|
'attackMontageMap': attack_montage_map,
|
|
'abilities': data.get('abilities', [])
|
|
}
|
|
return stalker_abilities
|
|
|
|
def extract_skills(datatables, stalker_stats):
|
|
"""DT_Skill에서 스토커별 스킬 정보 추출"""
|
|
skill_table = find_table(datatables, 'DT_Skill')
|
|
if not skill_table:
|
|
return {}
|
|
|
|
# 모든 스킬을 ID로 매핑
|
|
all_skills = {}
|
|
for row in skill_table.get('Rows', []):
|
|
skill_id = row['RowName']
|
|
data = row['Data']
|
|
all_skills[skill_id] = {
|
|
'skillId': skill_id,
|
|
'stalkerName': data.get('stalkerName', ''),
|
|
'name': data.get('name', ''),
|
|
'bIsUltimate': data.get('bIsUltimate', False),
|
|
'bIsStackable': data.get('bIsStackable', False),
|
|
'maxStackCount': data.get('maxStackCount', 0),
|
|
'skillDamageRate': data.get('skillDamageRate', 0),
|
|
'skillAttackType': data.get('skillAttackType', ''),
|
|
'skillElementType': data.get('skillElementType', ''),
|
|
'manaCost': data.get('manaCost', 0),
|
|
'coolTime': data.get('coolTime', 0),
|
|
'useMontages': data.get('useMontages', []),
|
|
'abilityClass': data.get('abilityClass', '')
|
|
}
|
|
|
|
# 스토커별로 스킬 그룹화
|
|
stalker_skills = {}
|
|
for stalker_id, stats in stalker_stats.items():
|
|
skills = {
|
|
'defaultSkills': [],
|
|
'subSkill': None,
|
|
'ultimateSkill': None
|
|
}
|
|
|
|
# 기본 스킬
|
|
for skill_id in stats['defaultSkills']:
|
|
if skill_id in all_skills:
|
|
skills['defaultSkills'].append(all_skills[skill_id])
|
|
|
|
# 서브 스킬
|
|
if stats['subSkill'] in all_skills:
|
|
skills['subSkill'] = all_skills[stats['subSkill']]
|
|
|
|
# 궁극기
|
|
if stats['ultimateSkill'] in all_skills:
|
|
skills['ultimateSkill'] = all_skills[stats['ultimateSkill']]
|
|
|
|
stalker_skills[stalker_id] = skills
|
|
|
|
return stalker_skills
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print("사용법: python extract_stalker_data.py <DataTable.json 경로>")
|
|
sys.exit(1)
|
|
|
|
json_path = Path(sys.argv[1])
|
|
if not json_path.exists():
|
|
print(f"오류: 파일을 찾을 수 없습니다: {json_path}")
|
|
sys.exit(1)
|
|
|
|
print(f"분석 중: {json_path}")
|
|
datatables = load_json(json_path)
|
|
|
|
print("\n=== 스토커 기본 스탯 추출 ===")
|
|
stalker_stats = extract_character_stats(datatables)
|
|
print(f"추출 완료: {len(stalker_stats)}명")
|
|
|
|
print("\n=== 스토커 평타 몽타주 추출 ===")
|
|
stalker_abilities = extract_character_abilities(datatables)
|
|
print(f"추출 완료: {len(stalker_abilities)}명")
|
|
|
|
print("\n=== 스토커 스킬 정보 추출 ===")
|
|
stalker_skills = extract_skills(datatables, stalker_stats)
|
|
print(f"추출 완료: {len(stalker_skills)}명")
|
|
|
|
# 결과 출력
|
|
for stalker_id in STALKERS:
|
|
if stalker_id not in stalker_stats:
|
|
continue
|
|
|
|
stats = stalker_stats[stalker_id]
|
|
print(f"\n{'='*80}")
|
|
print(f"【{stats['name']}】 ({stats['jobName']})")
|
|
print(f"{'='*80}")
|
|
print(f"STR: {stats['str']:2d} | DEX: {stats['dex']:2d} | INT: {stats['int']:2d} | CON: {stats['con']:2d} | WIS: {stats['wis']:2d}")
|
|
print(f"HP: {stats['hP']} | MP: {stats['mP']} | Mana Regen: {stats['manaRegen']}")
|
|
print(f"장착 가능: {', '.join(stats['equipableTypes'])}")
|
|
print(f"궁극기 포인트: {stats['ultimatePoint']}")
|
|
|
|
# 스킬 정보
|
|
if stalker_id in stalker_skills:
|
|
skills = stalker_skills[stalker_id]
|
|
print(f"\n[기본 스킬]")
|
|
for skill in skills['defaultSkills']:
|
|
print(f" - {skill['name']} ({skill['skillId']}): {skill['skillAttackType']} | 쿨타임: {skill['coolTime']}초 | 마나: {skill['manaCost']}")
|
|
|
|
if skills['subSkill']:
|
|
skill = skills['subSkill']
|
|
print(f"\n[서브 스킬]")
|
|
print(f" - {skill['name']} ({skill['skillId']}): {skill['skillAttackType']} | 쿨타임: {skill['coolTime']}초")
|
|
|
|
if skills['ultimateSkill']:
|
|
skill = skills['ultimateSkill']
|
|
print(f"\n[궁극기]")
|
|
print(f" - {skill['name']} ({skill['skillId']}): {skill['skillAttackType']}")
|
|
|
|
# 평타 몽타주
|
|
if stalker_id in stalker_abilities:
|
|
abilities = stalker_abilities[stalker_id]
|
|
attack_map = abilities.get('attackMontageMap', {})
|
|
if attack_map:
|
|
print(f"\n[평타 몽타주]")
|
|
for weapon_type, montage_data in attack_map.items():
|
|
montage_array = montage_data.get('montageArray', [])
|
|
print(f" - {weapon_type}: {len(montage_array)}타 연속")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|