{"scope":"skill-equipment-state-layout-review","sourceArtifacts":{"exe":"Hwanse2.exe","uiCnsGridMappings":"out/ui_cns_grid_mappings.json","skillEquipmentGateReview":"out/skill_equipment_gate_review.json"},"summary":{"status":"skill-equipment-state-slot-layout-grounded","actorBaseVaHex":"0x00457750","actorStride":216,"currentEquipmentOffsetHex":"+0x48","equipmentSlotsOffsetHex":"+0x4a","skillSlotsOffsetHex":"+0x56","functionCount":10,"typeMappingCount":6,"conclusion":"장비와 기술은 개별 scenario flag가 아니라 actor 상태 구조체 내부의 6-slot 배열이다. e2/e3 gate, 장비 추가/삭제/장착, 기술 추가/삭제 helper가 같은 슬롯을 읽고 쓴다."},"actorLayout":{"baseVaHex":"0x00457750","stride":216,"currentEquipment":{"offsetHex":"+0x48","weaponOrLiquor":"byte actor+0x48","armor":"byte actor+0x49"},"equipmentSlots":{"offsetHex":"+0x4a","shape":"2 groups x 6 slots","groups":{"0":"무기/술","1":"방어구"}},"skillSlots":{"offsetHex":"+0x56","shape":"4 categories x 6 slots","categories":{"0":"기본기","1":"개인공격기","2":"전체공격기","3":"특수기"}}},"functions":[{"key":"skillPredicateDownOrExisting","label":"기술 보유/하위 숙련도 lookup","startVa":4332339,"endVa":4332511,"role":"actor+0x56 category 슬롯에서 action id를 하향 스캔한다.","startVaHex":"0x00421b33","endVaHex":"0x00421bdf","size":172,"callRefs":[{"callVa":4256913,"callVaHex":"0x0040f491","targetVa":4332339,"targetVaHex":"0x00421b33","bytes":"e8 9d 26 01 00"},{"callVa":4333324,"callVaHex":"0x00421f0c","targetVa":4332339,"targetVaHex":"0x00421b33","bytes":"e8 22 fc ff ff"},{"callVa":4335251,"callVaHex":"0x00422693","targetVa":4332339,"targetVaHex":"0x00421b33","bytes":"e8 9b f4 ff ff"}],"callRefCount":3},{"key":"skillPredicateTier","label":"기술 숙련도 gate lookup","startVa":4332511,"endVa":4332861,"role":"e3 handler가 호출한다. action table record+0x10 tier marker를 따라 actor+0x56 슬롯을 검사한다.","startVaHex":"0x00421bdf","endVaHex":"0x00421d3d","size":350,"callRefs":[{"callVa":4260844,"callVaHex":"0x004103ec","targetVa":4332511,"targetVaHex":"0x00421bdf","bytes":"e8 ee 17 01 00"}],"callRefCount":1},{"key":"equipmentOwnedPredicate","label":"장비 보유 gate lookup","startVa":4332861,"endVa":4333105,"role":"e2 handler가 호출한다. detail+0x29 type으로 actor/group을 고른 뒤 actor+0x4a 슬롯을 검사한다.","startVaHex":"0x00421d3d","endVaHex":"0x00421e31","size":244,"callRefs":[{"callVa":4257028,"callVaHex":"0x0040f504","targetVa":4332861,"targetVaHex":"0x00421d3d","bytes":"e8 34 28 01 00"},{"callVa":4259334,"callVaHex":"0x0040fe06","targetVa":4332861,"targetVaHex":"0x00421d3d","bytes":"e8 32 1f 01 00"},{"callVa":4260553,"callVaHex":"0x004102c9","targetVa":4332861,"targetVaHex":"0x00421d3d","bytes":"e8 6f 1a 01 00"}],"callRefCount":3},{"key":"skillInsertWriter","label":"기술 추가 writer","startVa":4333303,"endVa":4333468,"role":"중복 검사 후 actor+0x56 category의 첫 빈 슬롯에 action id를 쓴다.","startVaHex":"0x00421ef7","endVaHex":"0x00421f9c","size":165,"callRefs":[{"callVa":4256351,"callVaHex":"0x0040f25f","targetVa":4333303,"targetVaHex":"0x00421ef7","bytes":"e8 93 2c 01 00"},{"callVa":4259676,"callVaHex":"0x0040ff5c","targetVa":4333303,"targetVaHex":"0x00421ef7","bytes":"e8 96 1f 01 00"},{"callVa":4336503,"callVaHex":"0x00422b77","targetVa":4333303,"targetVaHex":"0x00421ef7","bytes":"e8 7b f3 ff ff"}],"callRefCount":3},{"key":"skillSortHelper","label":"기술 슬롯 pack/sort helper","startVa":4333468,"endVa":4333715,"role":"기술 슬롯의 0 구멍을 뒤로 밀고 action id를 정렬/압축한다.","startVaHex":"0x00421f9c","endVaHex":"0x00422093","size":247,"callRefs":[],"callRefCount":0},{"key":"equipmentAddWriter","label":"장비 추가 writer","startVa":4334414,"endVa":4334983,"role":"detail+0x29 type으로 actor/group을 고른 뒤 actor+0x4a group 슬롯에 item id를 쓴다.","startVaHex":"0x0042234e","endVaHex":"0x00422587","size":569,"callRefs":[],"callRefCount":0},{"key":"equipmentSortHelper","label":"장비 슬롯 pack/sort helper","startVa":4334983,"endVa":4335230,"role":"장비 보유 슬롯의 0 구멍을 뒤로 밀고 item id를 정렬/압축한다.","startVaHex":"0x00422587","endVaHex":"0x0042267e","size":247,"callRefs":[],"callRefCount":0},{"key":"skillRemoveWriter","label":"기술 제거 writer","startVa":4335230,"endVa":4335337,"role":"actor+0x56 category 슬롯에서 skill id를 찾아 0으로 지운다.","startVaHex":"0x0042267e","endVaHex":"0x004226e9","size":107,"callRefs":[{"callVa":4256632,"callVaHex":"0x0040f378","targetVa":4335230,"targetVaHex":"0x0042267e","bytes":"e8 01 33 01 00"},{"callVa":4336382,"callVaHex":"0x00422afe","targetVa":4335230,"targetVaHex":"0x0042267e","bytes":"e8 7b fb ff ff"}],"callRefCount":2},{"key":"equipmentRemoveWriter","label":"장비 제거 writer","startVa":4335769,"endVa":4336257,"role":"actor+0x4a group 슬롯에서 item id를 찾아 0으로 지운다.","startVaHex":"0x00422899","endVaHex":"0x00422a81","size":488,"callRefs":[{"callVa":4256708,"callVaHex":"0x0040f3c4","targetVa":4335769,"targetVaHex":"0x00422899","bytes":"e8 d0 34 01 00"}],"callRefCount":1},{"key":"equipmentApplyAndSkillGrant","label":"장비 장착/제공 기술 갱신","startVa":4336257,"endVa":4336533,"role":"현재 장비 actor+0x48/+0x49를 바꾸고 기존 제공 기술 제거 뒤 detail+0x2a..0x2d 기술을 추가한다.","startVaHex":"0x00422a81","endVaHex":"0x00422b95","size":276,"callRefs":[{"callVa":4257589,"callVaHex":"0x0040f735","targetVa":4336257,"targetVaHex":"0x00422a81","bytes":"e8 47 33 01 00"}],"callRefCount":1}],"tables":[{"key":"equipmentOwnedJumpTable","label":"장비 보유 predicate jump table","va":4333048,"length":28,"vaHex":"0x00421df8","rawHex":"5f 1d 42 00 85 1d 42 00 ab 1d 42 00 72 1d 42 00 98 1d 42 00 be 1d 42 00 98 1e 42 00"},{"key":"equipmentOwnedTypeIndexTable","label":"장비 보유 predicate type index table","va":4333076,"length":132,"vaHex":"0x00421e14","rawHex":"00 01 06 02 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 03 04 06 05"},{"key":"equipmentAddJumpTable","label":"장비 추가 writer jump table","va":4334583,"length":28,"vaHex":"0x004223f7","rawHex":"70 23 42 00 90 23 42 00 b0 23 42 00 80 23 42 00 a0 23 42 00 c0 23 42 00 97 24 42 00"},{"key":"equipmentAddTypeIndexTable","label":"장비 추가 writer type index table","va":4334611,"length":132,"vaHex":"0x00422413","rawHex":"00 01 06 02 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 03 04 06 05"},{"key":"equipmentRemoveJumpTable","label":"장비 제거 writer jump table","va":4335938,"length":28,"vaHex":"0x00422942","rawHex":"bb 28 42 00 db 28 42 00 fb 28 42 00 cb 28 42 00 eb 28 42 00 0b 29 42 00 e2 29 42 00"},{"key":"equipmentRemoveTypeIndexTable","label":"장비 제거 writer type index table","va":4335966,"length":132,"vaHex":"0x0042295e","rawHex":"00 01 06 02 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 03 04 06 05"}],"equipmentTypeMap":[{"type":1,"typeHex":"0x01","actorMask":1,"isArmor":false,"actor":"아타호","group":"무기","storageRule":"actorBase + 0x4a + group*6 + slot","examples":["맨주먹","술","노주","특급주","화주","명주·귀신살"]},{"type":2,"typeHex":"0x02","actorMask":2,"isArmor":false,"actor":"린샹","group":"무기","storageRule":"actorBase + 0x4a + group*6 + slot","examples":["고양이 발톱","곰발톱","빙마조","표범의 발톱","팬톰크로우","호랑이발톱"]},{"type":4,"typeHex":"0x04","actorMask":4,"isArmor":false,"actor":"스마슈","group":"무기","storageRule":"actorBase + 0x4a + group*6 + slot","examples":["닌자도","청룡도","불타는 마검","그레이트소드","나찰의 흉인","마인아수라"]},{"type":129,"typeHex":"0x81","actorMask":1,"isArmor":true,"actor":"아타호","group":"방어구","storageRule":"actorBase + 0x4a + group*6 + slot","examples":["인민복","권법가 도복","달인의 도복","호랑이 도복","나찰의 도복","백호 도복"]},{"type":130,"typeHex":"0x82","actorMask":2,"isArmor":true,"actor":"린샹","group":"방어구","storageRule":"actorBase + 0x4a + group*6 + slot","examples":["드레스","프리티드레스","쿵푸드레스","배틀드레스","데몬드레스","퀸드레스"]},{"type":132,"typeHex":"0x84","actorMask":4,"isArmor":true,"actor":"스마슈","group":"방어구","storageRule":"actorBase + 0x4a + group*6 + slot","examples":["스마슈타이츠","가죽 갑옷","흑장속","철편 갑옷","어설트 슈트","투신의 갑옷"]}],"actorStateRows":[{"actorIndex":0,"actor":"아타호","baseVa":4552528,"baseVaHex":"0x00457750","stride":216,"currentEquipment":{"offsetHex":"+0x48","weaponOrLiquorId":1,"weaponOrLiquorName":"맨주먹","armorId":7,"armorName":"인민복"},"equipmentGroups":[{"groupIndex":0,"group":"무기/술","offsetHex":"+0x4a","values":[1,0,0,0,0,0],"names":["맨주먹","","","","",""],"nonZeroCount":1},{"groupIndex":1,"group":"방어구","offsetHex":"+0x50","values":[7,0,0,0,0,0],"names":["인민복","","","","",""],"nonZeroCount":1}],"skillCategories":[{"categoryIndex":0,"category":"기본기","offsetHex":"+0x56","values":[1,2,3,4,0,0],"names":["","","","","",""],"nonZeroCount":4},{"categoryIndex":1,"category":"개인공격기","offsetHex":"+0x5c","values":[10,0,0,0,0,0],"names":["호격권","","","","",""],"nonZeroCount":1},{"categoryIndex":2,"category":"전체공격기","offsetHex":"+0x62","values":[35,0,0,0,0,0],"names":["맹호난무","","","","",""],"nonZeroCount":1},{"categoryIndex":3,"category":"특수기","offsetHex":"+0x68","values":[58,59,0,0,0,0],"names":["","","","","",""],"nonZeroCount":2}]},{"actorIndex":1,"actor":"린샹","baseVa":4552744,"baseVaHex":"0x00457828","stride":216,"currentEquipment":{"offsetHex":"+0x48","weaponOrLiquorId":13,"weaponOrLiquorName":"고양이 발톱","armorId":19,"armorName":"드레스"},"equipmentGroups":[{"groupIndex":0,"group":"무기/술","offsetHex":"+0x4a","values":[13,0,0,0,0,0],"names":["고양이 발톱","","","","",""],"nonZeroCount":1},{"groupIndex":1,"group":"방어구","offsetHex":"+0x50","values":[19,0,0,0,0,0],"names":["드레스","","","","",""],"nonZeroCount":1}],"skillCategories":[{"categoryIndex":0,"category":"기본기","offsetHex":"+0x56","values":[1,2,3,4,5,0],"names":["","","","","",""],"nonZeroCount":5},{"categoryIndex":1,"category":"개인공격기","offsetHex":"+0x5c","values":[9,0,0,0,0,0],"names":["안면백조권","","","","",""],"nonZeroCount":1},{"categoryIndex":2,"category":"전체공격기","offsetHex":"+0x62","values":[28,0,0,0,0,0],"names":["고양이달래기","","","","",""],"nonZeroCount":1},{"categoryIndex":3,"category":"특수기","offsetHex":"+0x68","values":[47,48,49,0,0,0],"names":["","","","","",""],"nonZeroCount":3}]},{"actorIndex":2,"actor":"스마슈","baseVa":4552960,"baseVaHex":"0x00457900","stride":216,"currentEquipment":{"offsetHex":"+0x48","weaponOrLiquorId":25,"weaponOrLiquorName":"닌자도","armorId":31,"armorName":"스마슈타이츠"},"equipmentGroups":[{"groupIndex":0,"group":"무기/술","offsetHex":"+0x4a","values":[25,0,0,0,0,0],"names":["닌자도","","","","",""],"nonZeroCount":1},{"groupIndex":1,"group":"방어구","offsetHex":"+0x50","values":[31,0,0,0,0,0],"names":["스마슈타이츠","","","","",""],"nonZeroCount":1}],"skillCategories":[{"categoryIndex":0,"category":"기본기","offsetHex":"+0x56","values":[1,0,0,0,0,0],"names":["","","","","",""],"nonZeroCount":1},{"categoryIndex":1,"category":"개인공격기","offsetHex":"+0x5c","values":[5,0,0,0,0,0],"names":["대타격","","","","",""],"nonZeroCount":1},{"categoryIndex":2,"category":"전체공격기","offsetHex":"+0x62","values":[20,0,0,0,0,0],"names":["백인일섬","","","","",""],"nonZeroCount":1},{"categoryIndex":3,"category":"특수기","offsetHex":"+0x68","values":[35,36,0,0,0,0],"names":["","","","","",""],"nonZeroCount":2}]}],"stateWriteSummary":[{"kind":"equipment-add","functionVaHex":"0x0042234e","writeTarget":"actorBase+0x4a+group*6+slot","returnSemantics":"0 inserted, 1 duplicate, 2 no empty slot"},{"kind":"equipment-remove","functionVaHex":"0x00422899","writeTarget":"actorBase+0x4a+group*6+slot = 0","returnSemantics":"0 removed, 1 not found"},{"kind":"equipment-apply","functionVaHex":"0x00422a81","writeTarget":"actorBase+0x48 weapon/liquor or actorBase+0x49 armor","sideEffect":"old equipment-provided skills removed, new detail+0x2a..0x2d skills inserted"},{"kind":"skill-add","functionVaHex":"0x00421ef7","writeTarget":"actorBase+0x56+category*6+slot","returnSemantics":"1 already known, 0 inserted"},{"kind":"skill-remove","functionVaHex":"0x0042267e","writeTarget":"actorBase+0x56+category*6+slot = 0","returnSemantics":"matched slot cleared then packed/sorted"}]}