Reference[1]
https://dammit.typepad.com/blog/2011/01/ddsom-critical-hits-random-numbers.html
위 블로그에서 법사찌르기 랜덤데미지를 찾았다.
법사의 강공력은 다른 캐릭터처럼 1.5배의 데미지를 주는것이 아닌, 1도트의 데미지만 주다가 한번씩 엄청난 데미지가 주어진다.
사실 이 문제에 관심을 가진 것은 아니고, ddsom의 무기 공격력 테이블이나, 각 캐릭터별 레벨명 공격력 변경값 같은걸 찾으려고 ddsom + offset +memory 로 검색을 하다가 나온 것이다.
일단 더 많은 정보는 없었고, 히트박스 관련글이 있었으나 이 부분은 관심이 없다.
위 블로그 주인장은, 적 유닛의 체력값의 주소를 기억하고 해당 주소값의 데이터를 변경하는 함수 콜을 추적한 것으로 보인다.
사실 내가 필요 한게 저 메모리주소리스트 들인데 설명을 위한거 말고는 없어서 아쉽다.
Register A0는 player base 0xff75de(for Player 1) 이고 A1은 공격대상의 베이스라고 한다. (0xFFBA1E for boses) 라고 하는데 무슨 소리인지 잘모르겠다. 저기 있는 메모리 값을 저 레지스터로 읽어온다는 것이겠지.
(저 부분의 코드가 호출 될 때 레지스터에 저게 올라가 있다는건지... )
$19a88.l 이라는 서브루틴은 D0에 2바이트 랜덤넘버를 심는 서브루틴이라고 한다.
랜덤함수는 알면 게임의 랜덤성을 이용하는데 모두 접근 할 수 있어 좋다.
작은 바이트의 반만 사용한다라고 써놓고는 나중에는 또 다른 반바이트를 써서 좋 1바이트를 쓴다.
$3ec0와 $3ed4는 테이블 룩업을 하는거라는데 잘 모르겠다.
아래에 테이블 룩업을 테이블로 표시해놨는데
그냥 이건 그대로 가져왔다.
Table Ref[1]
random number D0 at $3EBE | D4 at $3EC4 | random number D0 at $3ED2 | D4 at $3ED8 |
---|---|---|---|
0x0 - 0xA | 0xFF | n/a | |
0xB - 0xC | 0x00 | 0x0 - 0x5 | 0x02 |
0x6 - 0xF | 0xFF | ||
0xD - 0xE | 0x10 | 0x0 - 0x3 | 0x01 |
0x4 - 0xF | 0xFF | ||
0xF | 0x20 | 0x0 - 0x1 | 0x00 |
0x2 - 0xF | 0xFF |
3EBE의 하프바이트를 통해서 3ec4의 값을 설정 하는데 내부 계산을 위해쓰이는거 같고,
다음 D0 at $3ED2의 테이블 룩업을 통해 0,1,2 값을 얻고 그 외에는 1도트 데미지를 주게하고,
0,1,2값을 얻었을 때는 적의 전체HP에다가 저 숫자를 shift-right-bit? 연산을 한다.
그 결과 다음과 같은 결과를 얻는다.
full damage | 1/16 x 2/16 | 1/128 | 0.78% |
---|---|---|---|
1/2 damage | 2/16 x 4/16 | 4/128 | 3.13% |
1/4 damage | 2/16 x 6/16 | 6/128 | 4.69% |
1 point damage | 128/128 - 1/128 - 4/128 - 6/128 | 117/128 | 91.5% |
의외로 8.5%의 확률로 빅데미지가 들어간다. 10번 때려서 1/4이상 데미지를 줄 수 있다면 딱히 찌르는데 목적을 둘 필요는 없다. (그냥 콤보용) 여럿이 할 수록 적의 체력이 많아지므로 보스잡는데는는 역시 확실하다.
음 나중에 테스트로 랜덤함수 결과 나오는 부분을 건드리면, 저게 잘 적용되는지 확인할 수 있을거로 보이지만 지금 당장은 이거할 여유가 없다.
이어서 뭐 이소리 저소리 있는데 적의 체력은 최대 1000 까지인데, 최대데미지 99제한 코드가 7바이트 연산으로 처리되어서, 100-127일 때만 99로 줄어들고 나머지는 정상적용이라고 한다.
또 rng 서브루틴의 대한 말도 있는데, 랜덤함수는 여러군데서 호출되므로 임의로 조작할수는 없다고 한다.