概要
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