4.9 KiB
Converter: GFX paths → SFX paths in skill stubs
This document describes how skill .cs files get m_szFlySfxPath / m_szHitGrndSfxPath / m_szHitSfxPath from the same client .gfx assets that supply m_sz*GfxPath, and how to extend or re-run the pipeline.
Goal
For each non-empty GFX path emitted from .sgc (m_szFlyGfxPath, m_szHitGrndGfxPath, m_szHitGfxPath), find the matching .gfx file on disk under the GFX root (--gfx, e.g. C:\Users\BrewPC\Downloads\gfx) and read the classic file-based sound path from the Sound element inside that .gfx. Emit the corresponding m_sz*SfxPath field on SkillStub.
Example (skill 1):
m_szHitGfxPath = "策划联入/人物技能/击中/虎击击中.gfx"- On disk:
…\gfx\策划联入\人物技能\击中\虎击击中.gfx - Inside
.gfx: Sound element (GFXELEMENTID: 170) →Path:/PathNum:+Path:lines (see C++GFXSOUNDIMP::Load) - Result:
m_szHitSfxPath = "Skill\\01Fighter\\虎击_C"(exact string depends on asset data)
Reference: client behavior
See C++_SkillGfx_Sfx_Play_Flow.md: the client plays Sfx\ + filename from the Sound element in the GFX resource.
Unity data model
In skill.cs, SkillStub defines:
| Field | Source |
|---|---|
m_szFlyGfxPath |
.sgc line 1 Path |
m_szHitGrndGfxPath |
.sgc line 2 Path |
m_szHitGfxPath |
.sgc 3rd Path (after version/scales per format) |
m_szFlySfxPath |
First classic SFX path parsed from fly .gfx |
m_szHitGrndSfxPath |
Same for hit-ground .gfx |
m_szHitSfxPath |
Same for hit .gfx |
If a GFX path is empty, or the .gfx file is missing, or there is no parseable Sound element, the matching SFX field is string.Empty.
Tool: convert_skills_fixed.py
Inputs
--cpp—CElementSkill(skill*.h)--cs— UnityScripts/Skills(or subfolder layout you use)--gfx— GFX root (folder that containssgc\and the same tree as in-game paths, e.g.策划联入\...)
Resolution rule (GFX file on disk)
Game path uses /. On Windows, join under gfx_root:
gfx_root + path.replace("/", os.sep)
Example: 策划联入/人物技能/击中/虎击击中.gfx → gfx_root\策划联入\人物技能\击中\虎击击中.gfx
Text .gfx detection
Text format starts with a line matching Version: <int> (Angelica A3DGFXEx::Load). If the file does not match (likely binary .gfx), SFX extraction is skipped (empty string).
Parsing Sound element (classic mode)
- Split file into blocks after each line
GFXELEMENTID: <id>. - For blocks with id = 170 (
ID_ELE_TYPE_SOUNDin client headers):- Take the substring before the first
SoundVer:line (start ofGfxSoundParamInfo). - If
PathNum: N: read the next N linesPath: …; use the first path as the stub value (runtime may randomize among N). - Else: use the last
Path: …line in that prefix (legacy single path).
- Take the substring before the first
- Normalize:
"\\"→"/"for logical path (same separator style asm_sz*GfxPath)- Strip trailing
.wav/.ogg/.mp3if present
- Escape for C# with the same helper used for other strings in the generator.
Limitations (v1)
| Topic | Behavior |
|---|---|
Binary .gfx |
No SFX extracted |
GFXSOUNDIMP22 audio-event Path: after SoundVer: |
Not used as classic SFX in v1 |
Multiple GFXELEMENTID: 170 |
First non-empty classic path wins |
No --gfx / missing file |
All three m_sz*SfxPath = string.Empty |
Skills without .sgc data |
No gfx_path_code block; stub defaults apply |
Regenerating stubs
From repo root (adjust paths):
python convert_skills_fixed.py --stubs "E:\Projects\perfect-world-source\perfect-world-source\CElement\CElementSkill\stubs1.cpp" --gfx "C:\Users\BrewPC\Downloads\gfx"
Or --ids 1 for a single skill smoke test.
Future work (checklist)
- Binary
.gfx: port minimal binary reader forGFXELEMENTID+ Sound chunk, or shell out to a small C++/CLI tool. - Audio-event mode: map
GFXSOUNDIMP22Path:(afterSoundVer:) to a separate field or naming convention if Unity uses FMOD/Wwise events. - Multiple sounds: emit multiple candidates or document “first only” vs random.
- Runtime: wire
m_sz*SfxPathinto actual playback (load underSfx\or Addressables) wherem_sz*GfxPathis consumed today.
Files touched by this feature
| File | Role |
|---|---|
| convert_skills_fixed.py | _resolve_gfx_path_on_disk, text .gfx parse, m_sz*SfxPath emission |
| skill.cs | SkillStub fields m_szFlySfxPath, m_szHitGrndSfxPath, m_szHitSfxPath |
Generated skillN.cs |
Constructor assignments next to GFX paths |