{"version":1,"kind":"hwanse-battle-stat-flag-status-semantics-review","source":{"script":"tools/build_battle_stat_flag_status_semantics_review.py","exe":"Hwanse2.exe","prior":"out/battle_damage_formula_trace_review.json","actorLayout":"out/battle_actor_stat_layout_review.json"},"status":"stat-flag-semantics-grounded-critical-presentation-supported","summary":["+0x08/+0x0a/+0x0e/+0x10/+0x59/+0x62/+0x6b/+0x6c/+0x6d/+0x6e는 동작 기준으로 확정.","+0x14는 플레이어 현재 EXP / 적 EXP reward base로 확정. 승리 루프는 KO 적의 +0x14를 공식에 넣고 살아있는 플레이어 +0x14에 결과를 더한다.","+0x1c/+0x20/+0x22/+0x24/+0x26은 플레이어 장비/레벨업 루틴과 전투 공식 사용처가 맞물려 공격력/방어력/기술력/순발력/운으로 확정.","+0x28은 대부분 100인 별도 기본 계수라 운으로 단정하지 않는다. 상태창에 표시되지 않는 숨은 attacker-side 상태/크리티컬 발동률 계수로 확정한다.","+0x2a는 전투 자세/상태 id다. 상태별 공격/방어/명중/회피/행동순서/크리티컬 계수는 0x48bcaa 테이블에서 읽힌다.","+0x7e는 target-side critical/status resistance 계수로 확정한다. 현재 확인된 자세/상태 테이블은 이 값을 바꾸지 않아 기본 100으로 남는다.","target bit 0x20은 MISS / HP 적용 skip, bit 0x08은 guard/glancing chip-damage branch, attacker bit 0x10은 critical presentation / alternate damage result 선택 플래그.","actor +0x62 bit 0x10의 전용 result 경로는 stream +3 WLK, helper 0x402321, opening display VM runtime WLK id 14 선택, palette flash/fade child script까지 확인됐다. 남은 wall-clock ms 환산은 전투 의미가 아니라 browser runner timing 보정이다."],"priorUnitSummary":{"skillRecordCount":281,"unitCount":452,"familyCounts":{"0x10":154,"0x12":76,"0x16":58,"0x11":27,"0x13":25,"0x15":24,"0x14":14,"0x17":13,"0x19":9,"0x20":7,"0x28":6,"0x21":5,"0x29":4,"0x25":4,"0x18":3,"0x01":3,"0x02":3,"0x2f":3,"0x03":3,"0x24":2,"0x27":2,"0x26":1,"0x2a":1,"0x2c":1,"0x23":1,"0x2e":1,"0x22":1,"0x2d":1},"statusCounts":{"0x00 none":366,"0x02 휙날아감":27,"0x01 넘어짐":26,"0x03 행동정지":22,"0x04 독":6,"0x05 마비":5},"targetScopeCounts":{"0x0a":263,"0x06":140,"0x01":46,"0x09":2,"0x05":1},"hitClassCounts":{"0x01":361,"0x00":43,"0x02":31,"0x03":17},"commonPowerTriples":[{"triple":"0/0/33","count":33},{"triple":"100/100/15","count":15},{"triple":"75/0/12","count":12},{"triple":"70/0/9","count":9},{"triple":"65/0/8","count":8},{"triple":"70/0/8","count":8},{"triple":"95/100/7","count":7},{"triple":"90/100/7","count":7},{"triple":"60/0/6","count":6},{"triple":"80/0/5","count":5},{"triple":"60/0/5","count":5},{"triple":"65/0/5","count":5},{"triple":"70/0/5","count":5},{"triple":"70/0/5","count":5},{"triple":"105/0/5","count":5},{"triple":"110/110/4","count":4}],"examples":[{"owner":"아타호","skill":"정권","skillIdHex":"0x01","unit":"64 64 64 00 0a 10 01 00","familyHex":"0x10","statusHex":"0x00","targetScopeHex":"0x0a","hitClassHex":"0x01"},{"owner":"아타호","skill":"돌려차기","skillIdHex":"0x02","unit":"6e 6e 5a 00 0a 10 01 00","familyHex":"0x10","statusHex":"0x00","targetScopeHex":"0x0a","hitClassHex":"0x01"},{"owner":"아타호","skill":"던지기","skillIdHex":"0x03","unit":"78 4b 3c 00 0a 10 03 02","familyHex":"0x10","statusHex":"0x02","targetScopeHex":"0x0a","hitClassHex":"0x03"},{"owner":"아타호","skill":"다리후리기","skillIdHex":"0x04","unit":"5a 41 69 00 0a 10 02 01","familyHex":"0x10","statusHex":"0x01","targetScopeHex":"0x0a","hitClassHex":"0x02"},{"owner":"아타호","skill":"마시기","skillIdHex":"0x05","unit":"00 00 00 00 01 26 01 00","familyHex":"0x26","statusHex":"0x00","targetScopeHex":"0x01","hitClassHex":"0x01"},{"owner":"아타호","skill":"마시기","skillIdHex":"0x06","unit":"00 00 00 00 01 28 01 00","familyHex":"0x28","statusHex":"0x00","targetScopeHex":"0x01","hitClassHex":"0x01"},{"owner":"아타호","skill":"마시기","skillIdHex":"0x07","unit":"00 00 00 00 01 29 01 00","familyHex":"0x29","statusHex":"0x00","targetScopeHex":"0x01","hitClassHex":"0x01"},{"owner":"아타호","skill":"마시기","skillIdHex":"0x08","unit":"00 00 00 00 01 2a 01 00","familyHex":"0x2a","statusHex":"0x00","targetScopeHex":"0x01","hitClassHex":"0x01"},{"owner":"아타호","skill":"마시기","skillIdHex":"0x09","unit":"00 00 00 00 01 2c 01 00","familyHex":"0x2c","statusHex":"0x00","targetScopeHex":"0x01","hitClassHex":"0x01"},{"owner":"아타호","skill":"호격권","skillIdHex":"0x0a","unit":"78 78 9b 00 0a 10 01 00","familyHex":"0x10","statusHex":"0x00","targetScopeHex":"0x0a","hitClassHex":"0x01"},{"owner":"아타호","skill":"호격권","skillIdHex":"0x0b","unit":"7e 7d a5 00 0a 10 01 00","familyHex":"0x10","statusHex":"0x00","targetScopeHex":"0x0a","hitClassHex":"0x01"},{"owner":"아타호","skill":"호격권","skillIdHex":"0x0c","unit":"84 82 af 00 0a 10 01 00","familyHex":"0x10","statusHex":"0x00","targetScopeHex":"0x0a","hitClassHex":"0x01"}]},"fieldRows":[{"offset":"+0x06","width":"word","role":"레벨 또는 레벨성 기본값","status":"고신뢰","evidence":"데미지 random 폭에서 attacker/target +0x06 / 2로 쓰이고, HP 0 처리에서 player max HP clamp 기준으로 쓰인다."},{"offset":"+0x08","width":"word","role":"현재 HP","status":"확정","evidence":"0x4353f8이 result만큼 차감하고, 0x435295가 회복한다."},{"offset":"+0x0a","width":"word","role":"최대 HP","status":"확정","evidence":"HP 회복 clamp 및 player 기절 시 최대 HP 감소에 사용된다."},{"offset":"+0x0e","width":"word","role":"현재 MP","status":"확정","evidence":"0x435356 MP recovery apply가 증가시키는 현재값이다."},{"offset":"+0x10","width":"word","role":"최대 MP","status":"확정","evidence":"MP recovery clamp 기준이다."},{"offset":"+0x14","width":"word","role":"플레이어 현재 EXP / 적 EXP reward base","status":"확정","evidence":"0x42157b는 defeated enemy +0x14를 base EXP로 읽고, 0x40e085..0x40e095는 산출 EXP를 live player actor +0x14에 더한다. player row +0x14도 전투 actor로 복사되는 현재 EXP 슬롯이다."},{"offset":"+0x1c","width":"word / byte table base","role":"공격력 축 / family resistance table base","status":"확정","evidence":"플레이어 장비 재계산은 base attack + 장비 +0x10을 actor +0x1c에 기록한다. normal/alternate damage는 attacker +0x70 * attacker +0x1c로 공격값을 만들고, target + family + 0x1c byte를 속성/계열 보정으로 읽는다."},{"offset":"+0x20","width":"word","role":"방어력 축","status":"확정","evidence":"플레이어 장비 재계산은 base defense + 장비 +0x11을 actor +0x20에 기록한다. normal/alternate damage는 target +0x7a * target +0x20로 방어값을 만든다."},{"offset":"+0x22","width":"word","role":"기술력/명중 축","status":"확정","evidence":"플레이어 장비 재계산은 base technique + 장비 +0x12를 actor +0x22에 기록한다. hit/avoid에서 attacker +0x06 + +0x22 및 status gate에서 attacker +0x74 * +0x22로 쓰인다."},{"offset":"+0x24","width":"word","role":"순발력/회피 축","status":"확정","evidence":"플레이어 장비 재계산은 base agility + 장비 +0x13을 actor +0x24에 기록한다. hit/avoid에서 target +0x06 + +0x24와 target +0x7c를 곱한 회피 점수에 쓰인다."},{"offset":"+0x26","width":"word","role":"운 / 상태/크리티컬 저항 쪽 축","status":"확정","evidence":"플레이어 장비 재계산과 레벨업 random luck 공식에서 actor +0x26이 운으로 확정됐다. critical/status gate에서는 attacker/target 양쪽의 luck-side 축으로 쓰인다."},{"offset":"+0x28","width":"word","role":"숨은 상태/크리티컬 발동률 계수","status":"역할 확정 / UI 비표시","evidence":"actor row actual +0x1a/exported HP view +0x12에서 복사된다. 0x4343db에서 attacker +0x28이 RNG range/base로 쓰이고, 통과 시 attacker +0x62 bit 0x10을 세운다. 0x4344ab 상태 성공 gate에서도 attacker-side 계수로 읽힌다. 상태창/장비/레벨업 운 경로와 분리되어 있고 몬스터 대부분이 100이라 상태창 운으로 단정하지 않는다."},{"offset":"+0x2a","width":"word","role":"전투 자세/상태 id","status":"확정","evidence":"0x433940이 actor +0x2a를 0x48bcaa 자세/상태 계수 테이블 index로 사용한다. 0x434e84..0x43512e는 상태이상/술취함/눈요기/도발 상태 id를 +0x2a에 쓰고 +0x66에 이전값을 저장한다."},{"offset":"+0x36 + unitByte6","width":"byte table","role":"공격 계열별 명중 보정 table","status":"확정","evidence":"hit/avoid에서 payload unit byte6으로 runtime target actor table을 인덱싱해 attacker hit score에 곱한다. 오프닝 샘플에서 데드드래곤 actor +0x36..+0x39 = 64/64/6e/46이고 actual actor row +0x28..+0x2b와 일치한다. class label은 0=상단/공중/상승, 1=일반, 2=하단/지면/다운, 3=잡기/밀착 특수로 승격한다."},{"offset":"+0x39 + status","width":"byte table","role":"상태이상 저항/성공 보정 table","status":"고신뢰","evidence":"status gate에서 target +0x6c 상태값으로 인덱싱해 성공 2단계 판정에 곱한다."},{"offset":"+0x59","width":"byte","role":"skill id","status":"확정","evidence":"payload table lookup index로 쓰인다."},{"offset":"+0x62","width":"byte flags","role":"전투 결과/상태 플래그","status":"확정","evidence":"hit branch, critical branch, HP zero, result dispatcher가 모두 이 byte의 bit를 검사하거나 세운다."},{"offset":"+0x6b","width":"byte","role":"hit family / damage family","status":"확정","evidence":"damage formula가 target family resistance table 인덱스로 사용한다."},{"offset":"+0x6c","width":"byte","role":"상태이상 후보/결과","status":"확정","evidence":"payload status byte가 들어가고 status gate 실패 시 0으로 지워진다."},{"offset":"+0x6d","width":"byte","role":"결과 적용 mode","status":"확정","evidence":"0 = HP damage, 1 = no apply, 2 = HP recovery dispatcher로 확인된다."},{"offset":"+0x6e","width":"word","role":"결과값 damage/recovery","status":"확정","evidence":"damage/recovery formula가 쓰고 target result dispatcher가 적용한다."},{"offset":"+0x70/+0x72/+0x74","width":"word x3","role":"payload power byte0..2와 actor modifier를 곱한 attacker-side 계수","status":"고신뢰","evidence":"0x433f0e가 hit unit byte0..2를 +0x80/+0x82/+0x84와 곱해 저장하고, damage/critical/hit/status gate가 사용한다."},{"offset":"+0x7a/+0x7c/+0x7e","width":"word x3","role":"target-side defense/avoid/critical-status resistance 계수","status":"확정","evidence":"+0x7a는 defense damage, +0x7c는 avoid, +0x7e는 critical/status resistance 계열 판정에 쓰인다. +0x7e는 reset 시 100으로 초기화되고 현재 자세/상태 테이블에서는 별도로 변조되지 않는다."}],"flagRows":[{"bit":"target +0x62 bit 0x20","exactBehavior":"target result dispatcher가 바로 반환하므로 HP 적용이 없다.","label":"MISS / full miss","status":"확정","evidence":"0x434218에서 큰 실패 폭이면 설정, 0x4340ae 첫 test cl,0x20에서 적용 skip. 결과 helper label 리뷰에서 helper 0x05 / selector 0x00100051의 MISS 표시 분기도 확인됐다."},{"bit":"target +0x62 bit 0x08","exactBehavior":"normal damage를 건너뛰고 random 1..3 result를 만들며 status +0x6c를 0으로 지운다.","label":"guard/glancing chip-damage hit","status":"확정","evidence":"0x43414d가 bit 0x08이면 result 1..3 설정 후 status 제거. target result script 0x004545b4가 WLK id 11/helper 0x16과 btl_efc F56..F59를 선택한다. 수동 관찰상 MISS 라벨 없이 normal frame 위에 1자리수 데미지와 약한 '팅' 계열 효과음만 뜬다."},{"bit":"attacker +0x62 bit 0x10","exactBehavior":"alternate damage formula 0x434737을 호출하고 0xc2 result sound handler의 alt WLK 선택 조건이 된다.","label":"critical presentation / alternate damage result","status":"정적 역할 확정 / 수동 관찰 정합","evidence":"0x4343db가 stat/random gate로 설정, 0x43414d가 alternate formula로 분기, 0xc2 result handler가 alt WLK/helper를 선택한다. 낮은 result면 0x434737이 bit를 해제. critical은 텍스트 없이 섬광/전용 사운드/높은 데미지로 인지된다는 관찰과 맞다."},{"bit":"target +0x62 bit 0x40","exactBehavior":"current HP가 0이 될 때 세워진다.","label":"기절/전투불능","status":"확정","evidence":"0x4353f8 HP damage apply."},{"bit":"actor +0x62 bit 0x80","exactBehavior":"target eligibility gate에서 대상 후보 제외 조건으로 쓰인다.","label":"대상 제외/이미 처리됨","status":"고신뢰","evidence":"0x433a30 target eligibility gate."}],"statusRows":[{"value":"0x00","label":"none","status":"확정","evidence":"payload status 없음. status gate가 바로 종료."},{"value":"0x01","label":"넘어짐","status":"고신뢰","evidence":"다리후리기/대폭진 등 사용자 검증 기술군과 payload 통계가 맞는다."},{"value":"0x02","label":"휙날아감","status":"고신뢰","evidence":"던지기/맹호비상각/쾌진격 계열 기술 설명과 payload 통계가 맞는다."},{"value":"0x03","label":"행동정지","status":"고신뢰","evidence":"고양이달래기/춤/행동정지 계열 기술군과 맞는다."},{"value":"0x04","label":"독","status":"고신뢰","evidence":"독 부여 기술/몬스터 기술 payload에서 드물게 나타난다."},{"value":"0x05","label":"마비","status":"고신뢰","evidence":"흡혈/장궁/기공독치료 관련 상태 설명과 맞는다."},{"value":"0x06","label":"졸림","status":"확정","evidence":"0x434fc4가 payload status 6을 +0x2a=0x15, timer current+rand(3)+4, +0x62 bit 0x02로 변환한다."}],"formulaRows":[{"name":"hit/avoid score","pseudo":"hitBase = attacker.level(+0x06) + attacker.hitAxis(+0x22)\nhit = floor(floor(hitBase * attacker.hitCoef(+0x74) / 100) * target.hitClassMod(+0x36+unitByte6) / 100) + rand(hitBase)\navoidBase = target.level(+0x06) + target.avoidAxis(+0x24)\navoid = rand(avoidBase) + floor(target.avoidCoef(+0x7c) * avoidBase / 100)","result":"hit > avoid이면 정상. 아니고 avoid - 3 > hit이면 bit 0x20, 그 외에는 bit 0x08."},{"name":"normal damage","pseudo":"atk = floor(attacker.power0(+0x70) * attacker.attack(+0x1c) / 100)\ndef = floor(target.defCoef(+0x7a) * target.defense(+0x20) / 100)\nfamily = target.familyTable[target.resultFamily(+0x6b)]\ndamage = floor(((atk * 2 - def) / 3 + rand(attacker.level/2) - rand(target.level/2)) * family / 100)","result":"damage < 3이면 rand(3)+1로 최소 보정."},{"name":"alternate/critical damage","pseudo":"입력 필드는 normal damage와 같지만 중심식이 floor((atk * 2 - def) / 2)에 가깝다.","result":"damage < 3이면 rand(5)+1로 최소 보정하고 attacker bit 0x10을 해제한다."},{"name":"status gate","pseudo":"status가 0이 아니면 attacker/target +0x26/+0x28/+0x22와 +0x72/+0x74/+0x7e, target status table(+0x39+status)을 두 단계 random 비교에 사용한다.","result":"실패하면 target +0x6c = 0. 성공하면 +0x6c가 유지되어 0x434e84 상태/피격 처리로 넘어간다."},{"name":"experience reward","pseudo":"diff = min(abs(enemy.level(+0x06) - player.level(+0x06)), 10)\nif enemy.level < player.level:\n    exp = enemy.expBase(+0x14) - enemy.expBase * diff * 12 / 100\n    exp = max(exp, 1)\nelse:\n    exp = enemy.expBase(+0x14) + enemy.expBase * diff * diff / 100\nif player/equipment class table 0x457798 == 0x1d:\n    exp = max(exp >> 1, 1)\nif player/equipment class table 0x457799 in (0x0b, 0x17):\n    exp = max(exp >> 1, 1)","result":"KO target마다 살아있는 player actor +0x14 current EXP에 더한다."}],"functionRows":[{"vaHex":"0x0043414d","endVaHex":"0x00434218","label":"common physical family coordinator","summary":"hit/avoid, alternate/critical, normal/alternate damage, status gate를 연결하고 attacker +0x6e result를 target +0x6e로 복사한다.","keyLines":["  434164:\te8 af 00 00 00       \tcall   0x434218","  434171:\t8a 48 62             \tmov    cl,BYTE PTR [eax+0x62]","  434182:\t8a 48 62             \tmov    cl,BYTE PTR [eax+0x62]","  43419f:\t66 89 41 6e          \tmov    WORD PTR [ecx+0x6e],ax","  4341b7:\te8 1f 02 00 00       \tcall   0x4343db","  4341c4:\t8a 48 62             \tmov    cl,BYTE PTR [eax+0x62]","  4341d8:\te8 5a 05 00 00       \tcall   0x434737","  4341ed:\te8 2d 04 00 00       \tcall   0x43461f","  4341fd:\te8 a9 02 00 00       \tcall   0x4344ab","  43420f:\t66 89 41 6e          \tmov    WORD PTR [ecx+0x6e],ax"]},{"vaHex":"0x00434218","endVaHex":"0x004343db","label":"hit/avoid branch flag test","summary":"attacker +0x06/+0x22/+0x74와 target +0x06/+0x24/+0x7c, target table +0x36+unitByte6을 비교한다. 실패 폭에 따라 target +0x62 bit 0x20 또는 0x08을 세운다.","keyLines":["  4342ab:\t66 8b 50 22          \tmov    dx,WORD PTR [eax+0x22]","  4342b8:\t66 8b 40 74          \tmov    ax,WORD PTR [eax+0x74]","  4342c5:\t66 8b 48 24          \tmov    cx,WORD PTR [eax+0x24]","  4342db:\t66 8b 40 7c          \tmov    ax,WORD PTR [eax+0x7c]","  4342ee:\t66 0f b6 44 01 36    \tmovzx  ax,BYTE PTR [ecx+eax*1+0x36]","  4343b7:\t80 c9 20             \tor     cl,0x20","  4343cd:\t80 c9 08             \tor     cl,0x8"]},{"vaHex":"0x004343db","endVaHex":"0x004344ab","label":"alternate result / critical flag gate","summary":"attacker +0x28/+0x72와 target +0x26/+0x7e를 비교하고, 추가 random 합산 조건이 통과되면 attacker +0x62 bit 0x10을 세운다.","keyLines":["  4343e7:\t66 8b 40 28          \tmov    ax,WORD PTR [eax+0x28]","  4343f2:\t66 8b 40 72          \tmov    ax,WORD PTR [eax+0x72]","  4343ff:\t66 8b 48 26          \tmov    cx,WORD PTR [eax+0x26]","  434408:\t66 8b 50 7e          \tmov    dx,WORD PTR [eax+0x7e]","  43448a:\t3d 96 00 00 00       \tcmp    eax,0x96","  43449d:\t80 c9 10             \tor     cl,0x10"]},{"vaHex":"0x004344ab","endVaHex":"0x0043461f","label":"status success gate","summary":"target +0x6c status 후보가 있으면 attacker/target 수치와 target status table +0x39+status로 성공 여부를 판정한다. 실패 시 target +0x6c를 0으로 지운다.","keyLines":["  4344b9:\t8a 48 6c             \tmov    cl,BYTE PTR [eax+0x6c]","  4344ce:\t66 8b 48 26          \tmov    cx,WORD PTR [eax+0x26]","  4344f1:\t66 8b 48 28          \tmov    cx,WORD PTR [eax+0x28]","  434514:\t66 8b 48 74          \tmov    cx,WORD PTR [eax+0x74]","  43451d:\t66 8b 50 22          \tmov    dx,WORD PTR [eax+0x22]","  434537:\t66 8b 48 26          \tmov    cx,WORD PTR [eax+0x26]","  43455a:\t8a 48 6c             \tmov    cl,BYTE PTR [eax+0x6c]","  434560:\t66 0f b6 44 01 39    \tmovzx  ax,BYTE PTR [ecx+eax*1+0x39]","  43459e:\tc6 40 6c 00          \tmov    BYTE PTR [eax+0x6c],0x0","  434611:\tc6 40 6c 00          \tmov    BYTE PTR [eax+0x6c],0x0"]},{"vaHex":"0x0043461f","endVaHex":"0x00434737","label":"normal damage formula","summary":"attacker +0x70 * +0x1c, target +0x7a * +0x20, level random, target family table +0x1c+family로 result +0x6e를 계산한다.","keyLines":["  43462d:\t66 8b 48 70          \tmov    cx,WORD PTR [eax+0x70]","  434636:\t66 8b 50 1c          \tmov    dx,WORD PTR [eax+0x1c]","  434660:\t66 8b 48 7a          \tmov    cx,WORD PTR [eax+0x7a]","  434669:\t66 8b 50 20          \tmov    dx,WORD PTR [eax+0x20]","  434693:\t8a 48 6b             \tmov    cl,BYTE PTR [eax+0x6b]","  434699:\t66 0f b6 44 01 1c    \tmovzx  ax,BYTE PTR [ecx+eax*1+0x1c]","  434709:\t66 89 41 6e          \tmov    WORD PTR [ecx+0x6e],ax","  43472e:\t66 89 41 6e          \tmov    WORD PTR [ecx+0x6e],ax"]},{"vaHex":"0x00434737","endVaHex":"0x0043485e","label":"alternate/critical damage formula","summary":"normal damage와 같은 입력 필드를 쓰지만 중심식이 /3이 아니라 /2에 가깝다. result가 너무 낮으면 attacker +0x62 bit 0x10을 해제한다.","keyLines":["  434745:\t66 8b 48 70          \tmov    cx,WORD PTR [eax+0x70]","  43474e:\t66 8b 50 1c          \tmov    dx,WORD PTR [eax+0x1c]","  434778:\t66 8b 48 7a          \tmov    cx,WORD PTR [eax+0x7a]","  434781:\t66 8b 50 20          \tmov    dx,WORD PTR [eax+0x20]","  4347ab:\t8a 48 6b             \tmov    cl,BYTE PTR [eax+0x6b]","  4347b1:\t66 0f b6 44 01 1c    \tmovzx  ax,BYTE PTR [ecx+eax*1+0x1c]","  434850:\t80 e1 ef             \tand    cl,0xef"]},{"vaHex":"0x004340ae","endVaHex":"0x0043414d","label":"target result mode dispatcher","summary":"target +0x62 bit 0x20이면 결과 적용을 건너뛰고, target +0x6d가 0이면 HP damage, 2이면 HP recovery를 호출한다.","keyLines":["  4340bf:\tf6 c1 20             \ttest   cl,0x20","  4340d2:\t8a 48 6d             \tmov    cl,BYTE PTR [eax+0x6d]","  4340e9:\te8 0a 13 00 00       \tcall   0x4353f8","  4340f5:\te8 8a 0d 00 00       \tcall   0x434e84","  434113:\te8 7d 11 00 00       \tcall   0x435295"]},{"vaHex":"0x004353f8","endVaHex":"0x004354eb","label":"HP damage apply","summary":"target +0x08 current HP에서 result를 차감한다. HP가 0이면 target +0x62 bit 0x40을 세우고, player actor는 max HP +0x0a도 일부 줄인다.","keyLines":["  435406:\t66 8b 48 08          \tmov    cx,WORD PTR [eax+0x8]","  43541d:\t66 8b 48 08          \tmov    cx,WORD PTR [eax+0x8]","  435436:\t66 8b 48 08          \tmov    cx,WORD PTR [eax+0x8]","  435447:\t66 89 48 08          \tmov    WORD PTR [eax+0x8],cx","  435453:\t66 c7 40 08 00 00    \tmov    WORD PTR [eax+0x8],0x0","  435461:\t80 c9 40             \tor     cl,0x40","  43548b:\t66 8b 48 0a          \tmov    cx,WORD PTR [eax+0xa]","  435494:\t66 8b 50 06          \tmov    dx,WORD PTR [eax+0x6]","  4354a1:\t66 89 48 0a          \tmov    WORD PTR [eax+0xa],cx","  4354aa:\t66 8b 48 06          \tmov    cx,WORD PTR [eax+0x6]","  4354b3:\t66 8b 50 0a          \tmov    dx,WORD PTR [eax+0xa]","  4354c2:\t66 8b 40 06          \tmov    ax,WORD PTR [eax+0x6]"]},{"vaHex":"0x00435295","endVaHex":"0x004353f8","label":"HP/MP recovery apply","summary":"HP recovery는 +0x08/+0x0a, MP recovery는 +0x0e/+0x10을 사용해 현재값을 증가시키고 최대값으로 clamp한다.","keyLines":["  4352a3:\t66 8b 48 0a          \tmov    cx,WORD PTR [eax+0xa]","  4352ac:\t66 8b 50 08          \tmov    dx,WORD PTR [eax+0x8]","  435314:\t66 8b 48 08          \tmov    cx,WORD PTR [eax+0x8]","  435325:\t66 89 48 08          \tmov    WORD PTR [eax+0x8],cx","  43532e:\t66 8b 48 08          \tmov    cx,WORD PTR [eax+0x8]","  435337:\t66 8b 50 0a          \tmov    dx,WORD PTR [eax+0xa]","  435346:\t66 8b 40 0a          \tmov    ax,WORD PTR [eax+0xa]","  435364:\t66 8b 48 10          \tmov    cx,WORD PTR [eax+0x10]","  43536d:\t66 8b 50 0e          \tmov    dx,WORD PTR [eax+0xe]","  4353b6:\t66 8b 48 0e          \tmov    cx,WORD PTR [eax+0xe]","  4353c7:\t66 89 48 0e          \tmov    WORD PTR [eax+0xe],cx","  4353d0:\t66 8b 48 0e          \tmov    cx,WORD PTR [eax+0xe]","  4353d9:\t66 8b 50 10          \tmov    dx,WORD PTR [eax+0x10]","  4353e8:\t66 8b 40 10          \tmov    ax,WORD PTR [eax+0x10]"]},{"vaHex":"0x0040dfb8","endVaHex":"0x0040e0c0","label":"victory EXP fanout","summary":"KO flag가 선 target마다 살아있는 player actor에 0x42157b 경험치를 더하고, 이후 0x435736으로 골드/드롭 보상을 처리한다.","keyLines":["  40e010:\t8a 48 62             \tmov    cl,BYTE PTR [eax+0x62]","  40e013:\tf6 c1 40             \ttest   cl,0x40","  40e047:\t8a 48 62             \tmov    cl,BYTE PTR [eax+0x62]","  40e04a:\tf6 c1 80             \ttest   cl,0x80","  40e06e:\te8 08 35 01 00       \tcall   0x42157b","  40e085:\t66 8b 51 14          \tmov    dx,WORD PTR [ecx+0x14]","  40e095:\t66 89 41 14          \tmov    WORD PTR [ecx+0x14],ax","  40e0a9:\te8 88 76 02 00       \tcall   0x435736"]},{"vaHex":"0x0042157b","endVaHex":"0x00421780","label":"EXP reward formula","summary":"defeated enemy +0x14 base EXP와 player/enemy level 차이로 보상 EXP를 계산하고, 특정 player/equipment class table 값에서는 절반 보정을 적용한다.","keyLines":["  421589:\t66 8b 48 06          \tmov    cx,WORD PTR [eax+0x6]","  421592:\t66 8b 50 06          \tmov    dx,WORD PTR [eax+0x6]","  4215a3:\t66 8b 48 06          \tmov    cx,WORD PTR [eax+0x6]","  4215ac:\t66 8b 50 06          \tmov    dx,WORD PTR [eax+0x6]","  4215c0:\t66 8b 48 06          \tmov    cx,WORD PTR [eax+0x6]","  4215c9:\t66 8b 50 06          \tmov    dx,WORD PTR [eax+0x6]","  4215f2:\t66 8b 48 06          \tmov    cx,WORD PTR [eax+0x6]","  4215fb:\t66 8b 50 06          \tmov    dx,WORD PTR [eax+0x6]","  42160c:\t66 8b 48 14          \tmov    cx,WORD PTR [eax+0x14]","  421615:\t66 8b 50 14          \tmov    dx,WORD PTR [eax+0x14]","  42163d:\t66 8b 48 14          \tmov    cx,WORD PTR [eax+0x14]","  421666:\t66 8b 48 14          \tmov    cx,WORD PTR [eax+0x14]","  4216a9:\t8a 8c c0 98 77 45 00 \tmov    cl,BYTE PTR [eax+eax*8+0x457798]","  4216d5:\tc1 e8 01             \tshr    eax,0x1","  421710:\t8a 8c c0 99 77 45 00 \tmov    cl,BYTE PTR [eax+eax*8+0x457799]","  42173c:\tc1 e8 01             \tshr    eax,0x1"]},{"vaHex":"0x00435736","endVaHex":"0x004357d0","label":"gold/drop reward handler","summary":"defeated actor +0x44 gold를 global money 0x4576e0에 더하고 cap을 적용한 뒤, +0x40/+0x41 기반 드롭 후보를 처리한다.","keyLines":["  435744:\t66 8b 48 44          \tmov    cx,WORD PTR [eax+0x44]","  43574b:\ta1 e0 76 45 00       \tmov    eax,ds:0x4576e0","  435753:\t3d 3f 42 0f 00       \tcmp    eax,0xf423f","  43575e:\tc7 05 e0 76 45 00 3f \tmov    DWORD PTR ds:0x4576e0,0xf423f","  435772:\t66 8b 48 44          \tmov    cx,WORD PTR [eax+0x44]","  435776:\t01 0d e0 76 45 00    \tadd    DWORD PTR ds:0x4576e0,ecx","  435781:\t8a 48 40             \tmov    cl,BYTE PTR [eax+0x40]","  43578f:\t66 0f b6 40 41       \tmovzx  ax,BYTE PTR [eax+0x41]","  4357ad:\t8a 40 40             \tmov    al,BYTE PTR [eax+0x40]","  4357b1:\te8 dd c8 fe ff       \tcall   0x422093","  4357bc:\t8a 40 40             \tmov    al,BYTE PTR [eax+0x40]"]}],"openQuestions":[]}