構造体からのHandle取得

Last-modified: 2018-12-14 (金) 00:25:38
 

概要

main.scmで関連づけされた人、物、乗り物は通常opcode 08E5 等では取得できません。
そもそも、opcodeで取得出来る物は放っておいたら消える物なのです。
それをスクリプトで確保し、消えないようにするということをいつもやっているわけです。
関連づけられた物であろうが、メモリに存在しています。
試しにスクリプトで適当に近くの人を変数に格納して値を見てやるといいでしょう。
構造体配列の添え字(ID)とSCMで格納された値(Handle)を比較すると規則があり、以下の式が成り立ちます。

Handle = ID * 256 + N  (0 ≦ N ≦ 127)

これを使えばミッション中の敵や車や物でも自由自在です。

全てのハンドルを取得

  • コードその1
    あり得る全てのHandleを調べるのでちょっと負荷がかかるかもしれません。
    for 28@ = 0 to 0x8B00 step 0x100
        0085: 26@ = 28@ // (int)
        for 29@ = 0 to 0x7F
            if and
            056D: actor 26@ defined
            803C: not $PLAYER_ACTOR == 26@ // (int)
            then
                0321: kill_actor 26@
                break
            end
            26@ += 1
        end
    end
  • コードその2
    構造体のフラグを調べます。
    その1と比べると負荷が1%未満と思われます。
    0A8D: 27@ = read_memory 0xB74490 size 4 virtual_protect 0
    000A: 27@ += 0x4
    0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0
    for 28@ = 0 to 0x8B00 step 0x100
        0A8D: 26@ = read_memory 27@ size 1 virtual_protect 0
        000A: 27@ += 0x1
        if and
        0029: 26@ >= 0
        001B: 0x80 > 26@
        then
            005A: 26@ += 28@ // (int)
            if
            803C: not $PLAYER_ACTOR == 26@ // (int)
            then
                0321: kill_actor 26@
            end
        end
    end

どちらもCJ以外の人がすべて死にます。
main.scmで関連づけられた、例えばミッション中の敵や味方全員もです。
用途によって 0x8B00 や 0xB74490 の値を変えるとよいでしょう。

人:0x8B00 = (人の最大数(140)-1)*0x100 ・ 0xB74490
車:0x6D00 = (車の最大数(110)-1)*0x100 ・ 0xB74494
物:0x15D00 = (物の最大数(350)-1)*0x100 ・ 0xB7449C

アドレスからハンドル取得

全てではなく、構造体の先頭アドレスからハンドルを取得したい場合は以下のコードを使います。

(1@にはすでに構造体の先頭アドレスが格納されているとする)
0A8D: 2@ = read_memory 0xB7449C size 4 virtual_protect 0
0A8D: 2@ = read_memory 2@ size 4 virtual_protect 0
0062: 1@ -= 2@ // (int)
0016: 1@ /= 0x19C
0A8D: 2@ = read_memory 0xB7449C size 4 virtual_protect 0
000A: 2@ += 0x4
0A8D: 2@ = read_memory 2@ size 4 virtual_protect 0
005A: 2@ += 1@ // (int)
0A8D: 2@ = read_memory 2@ size 1 virtual_protect 0
0012: 1@ *= 0x100
005A: 1@ += 2@ // (int)

1@にハンドルが格納されています
用途によって 0xB7449C と 0x19C の値を変えます。
人: 0xB74490 ・ 0x7C4
車: 0xB74494 ・ 0xA18
物: 0xB7449C ・ 0x19C
※このコードはCLEO4で以下のopcodeによってサポートされました。

0AEA: $actor = actor_struct $ped_struct handle
0AEB: $car = car_struct $vehicle_struct handle
0AEC: $object = object_struct $object_struct handle