{$VERSION 3.1.0027} {$CLEO .cs} { 私は余っている変数を適当に使うので、ほとんど変数毎に役割を当てていません。 強いて言うならば 0@ = Corona存在フラグ 1@ = bit番号 2@ = bit番号 3@ = Corona速度フラグ 6@ = CoronaX座標 7@ = CoronaY座標 8@ = CoronaZ座標 26@ - 28@ Handle取得用 30@ = メモリアドレス 31@ = PLAYERの元々の耐性 32@ = Coronaの生成間隔 / ループ抜け 33@ = 絶対時間 } thread 'OEYAMA' :key wait 0 0006: 0@ = -229907 008B: 0@ = &0(0@,1i) 0012: 0@ *= 0x10000 //オーバーフローを使って変数を節約。0@しか使ってません if //節約法は色々あります。 0039: 0@ == 0x4F450000 //OE then 0006: 0@ = -229908 008B: 0@ = &0(0@,1i) if 8039: not 0@ == 0x59414D41 //YAMA then jump @key end else jump @key end 0006: 0@ = -229908 0004:&0(0@,1i) = 0x20202020 //ONOFFが同じキー入力なので、メモリ値を適当に書き換える(0x20はスペース) 0A96: 0@ = actor $PLAYER_ACTOR struct //31@に現在の耐性フラグを記憶 000A: 0@ += 0x42 // 〃 0A8D: 31@ = read_memory 0@ size 1 virtual_protect 0 // 〃 03E5: show_text_box 'CHEAT1' 03CF: load_wav 12603 as 4 while 83D0: not wav 4 loaded wait 0 end :main wait 0 0006: 0@ = -229907 008B: 0@ = &0(0@,1i) 0012: 0@ *= 0x10000 if 0039: 0@ == 0x4F450000 //OE then 0006: 0@ = -229908 008B: 0@ = &0(0@,1i) if 0039: 0@ == 0x59414D41 //YAMA then 0006: 0@ = -229908 0004:&0(0@,1i) = 0x20202020 0A96: 0@ = actor $PLAYER_ACTOR struct //耐性フラグを元に戻す 000A: 0@ += 0x42 // 〃 0A8C: write_memory 0@ size 1 value 31@ virtual_protect 0// 〃 040D: unload_wav 4 03E5: show_text_box 'CHEAT8' jump @key end end if or 02D8: actor $PLAYER_ACTOR current_weapon == 0 02D8: actor $PLAYER_ACTOR current_weapon == 1 then if and 8449: not actor $PLAYER_ACTOR in_a_car 00E1: player 0 pressed_key 17 //fire then if 0AAB: file_exists "CLEO\money.s" //money.sがcleoフォルダにあるか調べる then 0A92: create_custom_thread "money.s" //あったら実行 end 0812: AS_actor $PLAYER_ACTOR perform_animation "NULL" IFP_file "NULL" 4.0 loopA 0 lockX 0 lockY 0 lockF 0 time 1 // versionB パンチ防止 02AB: set_actor $PLAYER_ACTOR immunities BP 1 FP 1 EP 1 CP 1 MP 1 0006: 32@ = 131 //最初のフレームで弾を出すために初期値を設定 0006: 33@ = 0 0006: 2@ = 0 // 2@ -- bit number - bit番号。0~31まで使用可だが、ここでは0~24まで使用する 0006: 0@ = 0 // 0@ -- existence flag 0006: 3@ = 0 // 3@ -- speed flag (fast or slow) // 0@と3@は bit毎にフラグを立てている。 // 変数のサイズは4byte、 bitに直すと32bit // つまり一つの変数で32個のフラグを扱うことが出来る // このスクリプトでは25セットのCoronaを扱うので32個フラグがあれば十分対応できる jump @create_corona end end jump @main ////////////////////////////////// main loop ///////////////////////////////////// :create_corona wait 0 if and // 警棒など拾って武器が変わってしまうのを防ぐ 82D8: not actor $PLAYER_ACTOR current_weapon == 0 82D8: not actor $PLAYER_ACTOR current_weapon == 1 then 01B9: set_actor $PLAYER_ACTOR armed_weapon_to 0 end //spell break if and //FIREが離されて1.5秒経つとループを中断する 80E1: not player 0 pressed_key 17 //fire //(FIREが押されないと32@がリセットされないのを利用) 0019: 32@ > 1500 then if 0AAB: file_exists "CLEO\money.s" //ファイルチェックを忘れずに。 then 0ABA: end_custom_thread_named 'money' end jump @main end // set pos & time if and 0019: 32@ > 130 //0.13秒に一回のペースで同時に2セットのCoronaを作る 00E1: player 0 pressed_key 17 //fire //0.13秒なのは、1フレーム0.04秒として4フレーム以上時間を置くため。 then //1フレーム毎に配置すると0.5秒で25セット使い切ってしまう。 //2秒あれば十分に密度を保つことが出来る。 04C4: store_coords_to 6@ 7@ 8@ from_actor $PLAYER_ACTOR with_offset 0.0 25.0 0.0 03D7: set_wav 4 location 6@ 7@ 8@ //音が大きすぎるので 25m離れたところで鳴らしている 03D1: play_wav 4 //これはあまり良くないかも Y(前)よりZ(頭上)の方が良いかもしれない。 for 1@ = 0 to 1 //1度に2セット作るためfor-endを使用する if 88B9: not test 0@ bit 2@ //08B9は指定された変数の指定されたbit番号が 1 ならば真を返す then //存在していないところにCoronaを作るので 否定型にする。 08BF: set 0@ bit 2@ //08BFは指定された変数の指定されたbitを1にする これで存在フラグを立てる。 0208: 6@ = random_float_in_ranges -8.0 8.0 //Corona発生場所をランダム生成 0208: 7@ = random_float_in_ranges -2.0 2.0 //Corona速度ランダム設定 if 0021: 7@ > -1.0 then 08BF: set 3@ bit 2@ //速度フラグを立てる。 end 04C4: store_coords_to 6@ 7@ 8@ from_actor $PLAYER_ACTOR with_offset 6@ -4.0 0.0 02CE: 10@ = ground_z_at 6@ 7@ 8@ //---ここから--- if 0043: 10@ == 0.0 then 000B: 8@ += 3.0 02CE: 10@ = ground_z_at 6@ 7@ 8@ if 0043: 10@ == 0.0 then 000F: 8@ -= 3.0 else 000B: 10@ += 0.6 //生成場所判定部(XとY座標は確定しているのでZ座標を探す ) 0087: 8@ = 10@ // (float) end else 0087: 9@ = 8@ // (float) 0063: 9@ -= 10@ // (float) if 0023: 5.0 > 9@ then 000B: 10@ += 0.6 0087: 8@ = 10@ // (float) end end //---ここまで--- //:get_pointer //オリジナルソースでは gosub @get_pointer となっている 0A9F: 30@ = current_thread_pointer //説明のためここに持ってくる 000A: 30@ += 0x10 //0A9Fはこのスレッドのポインタ(メモリアドレス)を取得。 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0//スレッドの構造体+0x10にはメモリ上のスレッド開始アドレスが入っている 000E: 30@ -= @pos_pool //ラベルは開始アドレスからのサイズが負の値で書き込まれる。 //return //開始アドレスにラベル分のサイズを足すことによって //:pos_poolのアドレスを取得する。 //ここへ値を直接書き込む。 0085: 13@ = 2@ // (int) //2@はbit番号。この値を利用して目的のアドレスを探す。 0012: 13@ *= 12 //bit番号*12 2@が1増える毎に12byteアドレスがずれる。 //なぜ12かというと、座標XYZの3つの変数を格納しなければならないため。4byte*3 = 12byte 005A: 30@ += 13@ // (int) //0から始まるので 初回は30@+0byte 0A8C: write_memory 30@ size 4 value 6@ virtual_protect 0 //X座標を入れる。 変数は4byteなのでsizeは4 000A: 30@ += 4 //4byte入れたので、4byte進める 0A8C: write_memory 30@ size 4 value 7@ virtual_protect 0 //Y座標 000A: 30@ += 4 //+4byte 0A8C: write_memory 30@ size 4 value 8@ virtual_protect 0 //Z座標 000E: 30@ -= 8 //もう一度ポインタを取っても良いが、速度が速い計算だけを使う。 0062: 30@ -= 13@ // (int) //と言っても現代のPCはこのくらいの差は皆無と言っていい //初期のポインタ値に戻った。 0085: 13@ = 2@ // (int) //今度は現在時刻を書き込む。 0012: 13@ *= 4 //bit番号*4 つまり4byteずつずらして書き込む。 005A: 30@ += 13@ // (int) //当然さっきX座標を書き込んだ場所になってしまう。 000A: 30@ += 300 //それでは当然いけないので300byteずらす。 0A8C: write_memory 30@ size 4 value 33@ virtual_protect 0 // ※12*25=300 //型が何であろうが必ず4byte end 000A: 2@ += 1 //bit番号次へ回す if 0039: 2@ == 25 //0〜24までの25種類を使用するので 25になったら0に戻す then 0006: 2@ = 0 end end 0006: 32@ = 0 //弾を出す間隔リセット end // control for 1@ = 0 to 24 //1@もbit番号 for-endで記述するととても便利。 if 08B9: test 0@ bit 1@ //0@中の1@ 上で0番と1番は1になっているので真を返す。 ↓1ループ目はここを調べる then //ここまでの0@をbitに表すと 0000 0000 0000 0000 0000 0000 0000 0011 となっている。 //create corona gosub @get_pointer //ポインタ取得 0085: 13@ = 1@ // (int) //----ここから 0012: 13@ *= 12 //bit番号に値を掛けて一つずつ座標を読み出す。 005A: 30@ += 13@ // (int) // 0A8D: 6@ = read_memory 30@ size 4 virtual_protect 0 //X座標 000A: 30@ += 4 // 0A8D: 7@ = read_memory 30@ size 4 virtual_protect 0 //Y座標 000A: 30@ += 4 // 0A8D: 8@ = read_memory 30@ size 4 virtual_protect 0 //X座標 //----ここまで 0085: 10@ = 1@ // (int) //Corona制御。(この部分についてはwikiを参照して下さい。) 0012: 10@ *= -0x3A //これもbit番号を利用して使っていく。 000A: 10@ += @corona // gosub 10@ // //check hit 0A8D: 27@ = read_memory 0xB74490 size 4 virtual_protect 0 //構造体からPEDと車を一つずつ取り出し、Coronaとの距離を調べる 近かったら爆発 000A: 27@ += 0x4 //この部分は省略しながら解説 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 for 28@ = 0 to 35584 step 0x100 0A8D: 26@ = read_memory 27@ size 1 virtual_protect 0 000A: 27@ += 0x1 if and 0029: 26@ >= 0x00 001B: 0x80 > 26@ then 005A: 26@ += 28@ // (int) if and 8118: not actor 26@ dead 803C: not $PLAYER_ACTOR == 26@ // (int) then 00A0: store_actor 26@ position_to 10@ 11@ 12@ 050A: 15@ = distance_between_XYZ 10@ 11@ 12@ and_XYZ 6@ 7@ 8@ 0062: 24@ -= 33@ // (int) if and 001B: 0 > 24@ 0023: 2.5 > 15@ then for 13@ = 0 to 2 0208: 16@ = random_float_in_ranges -3.0 3.0 0208: 17@ = random_float_in_ranges -3.0 3.0 0208: 18@ = random_float_in_ranges -3.0 3.0 08EB: create_sparks_at 10@ 11@ 12@ velocity_direction 16@ 17@ 18@ density 30 end 018C: play_sound 1190 at 0.0 0.0 0.0 0006: 24@ = 200 else 005A: 24@ += 33@ // (int) end if 0023: 0.7 > 15@ then 020C: create_explosion_with_radius 12 at 6@ 7@ 8@ 08C5: clear 0@ bit 1@ //当たったらCoronaを消す。 08C5: clear 3@ bit 1@ //勝手に消えるのでフラグを消せばそれだけで良い。 //このスクリプトはフラグを調べて読み書きなのでメモリに書き込んだ物も放置して問題はない。 //オブジェクトのHandleを書き込んで読み出し、03CAチェックというスクリプトでは問題が出る //その場合は0を書き込めば良いでしょう。 end end end end 0A8D: 27@ = read_memory 0xB74494 size 4 virtual_protect 0 000A: 27@ += 0x4 0A8D: 27@ = read_memory 27@ size 4 virtual_protect 0 for 28@ = 0 to 27904 step 0x100 0A8D: 26@ = read_memory 27@ size 1 virtual_protect 0 000A: 27@ += 0x1 if and 0029: 26@ >= 0x00 001B: 0x80 > 26@ then 005A: 26@ += 28@ // (int) if 8119: not car 26@ wrecked then 0A97: 25@ = car 26@ struct //車の耐性チェック 000A: 25@ += 0x42 0A8D: 25@ = read_memory 25@ size 1 virtual_protect 0 if or 88B7: not test 25@ bit 2 //全ての耐性が付いている車"以外"が対象となる。 88B7: not test 25@ bit 3 //ミッション中などで使って爆発されては困りますからね 88B7: not test 25@ bit 4 88B7: not test 25@ bit 5 88B7: not test 25@ bit 7 then 00AA: store_car 26@ position_to 10@ 11@ 12@ 050A: 15@ = distance_between_XYZ 10@ 11@ 12@ and_XYZ 6@ 7@ 8@ 0062: 24@ -= 33@ // (int) if and 001B: 0 > 24@ 0023: 3.5 > 15@ then for 13@ = 0 to 2 0208: 16@ = random_float_in_ranges -3.0 3.0 0208: 17@ = random_float_in_ranges -3.0 3.0 0208: 18@ = random_float_in_ranges -3.0 3.0 08EB: create_sparks_at 10@ 11@ 12@ velocity_direction 16@ 17@ 18@ density 30 end 018C: play_sound 1190 at 0.0 0.0 0.0 //グレイズ音 0006: 24@ = 200 else 005A: 24@ += 33@ // (int) end if 0023: 2.0 > 15@ then 02AC: set_car 26@ immunities BP 0 FP 0 EP 0 CP 0 MP 0 //020Bを使うために耐性消去 020B: explode_car 26@ // versionA 08C5: clear 0@ bit 1@ //Corona削除 08C5: clear 3@ bit 1@ end end end end end if 08B9: test 0@ bit 1@ //上で存在フラグを消した場合、無駄な処理をしないようチェック。 then //人物車などとは違うので、これが無くてもエラーは起きない。 //check timer gosub @get_pointer //ポインタ取得 0085: 13@ = 1@ // (int) //タイマーを調べるため、読み出す 0012: 13@ *= 4 // 005A: 30@ += 13@ // (int) // 000A: 30@ += 300 // 0A8D: 9@ = read_memory 30@ size 4 virtual_protect 0 // 0062: 9@ -= 33@ // (int) //生成時間-現在の時間で出してからどれくらい時間が経ったかを調べる if 08B9: test 3@ bit 1@ //速度によって消す時間を変えてあるため、速度フラグのチェック then if 001B: -2500 > 9@ //2.5秒経った場合Corona消去 then 08C5: clear 0@ bit 1@ //フラグ消去 08C5: clear 3@ bit 1@ else //move corona 0172: 20@ = actor $PLAYER_ACTOR Z_angle //2.5秒経っていない場合Coronaの座標を変更する 02F6: 21@ = sine 20@ // (float) //sine cosineは逆です。 Sanny Builder の間違い。 ここでは修正済み 02F7: 22@ = cosine 20@ // (float) 0013: 21@ *= -1.0 //Y座標は"北(-)から南(+)へ"座標が変動するので負の値を掛けます。 0013: 22@ *= 1.0 //1.0倍は書く必要ありませんが、速度の調整のためにあえて書きました。 005B: 6@ += 21@ // (float) //現在の座標に一定の距離を足して移動後の座標とする。 005B: 7@ += 22@ // (float) 02CE: 10@ = ground_z_at 6@ 7@ 8@ //Z座標の選定。割愛 if 0043: 10@ == 0.0 then 000B: 8@ += 3.0 02CE: 10@ = ground_z_at 6@ 7@ 8@ if 0043: 10@ == 0.0 then 000F: 8@ -= 3.0 else 000B: 10@ += 0.6 0087: 8@ = 10@ // (float) end else 0087: 11@ = 8@ // (float) 0063: 11@ -= 10@ // (float) if 0021: 11@ > 3.0 then 000F: 8@ -= 0.3 else 000B: 10@ += 0.6 0087: 8@ = 10@ // (float) end end gosub @get_pointer //ポインタ取得 0085: 13@ = 1@ // (int) //移動後の座標を書き込む 0012: 13@ *= 12 //ここで変更しても現在のフレームには適用されない 005A: 30@ += 13@ // (int) //次のフレームでCoronaが移動したことが分かる。 0A8C: write_memory 30@ size 4 value 6@ virtual_protect 0 //X 000A: 30@ += 4 0A8C: write_memory 30@ size 4 value 7@ virtual_protect 0 //Y 000A: 30@ += 4 0A8C: write_memory 30@ size 4 value 8@ virtual_protect 0 //Z end else if 001B: -1500 > 9@ //速度フラグが0だったときの場合。 //1.5秒経った場合Corona消去。 それ以外はほぼ上と同じ then 08C5: clear 0@ bit 1@ else //move corona 0172: 20@ = actor $PLAYER_ACTOR Z_angle 02F6: 21@ = sine 20@ // (float) 02F7: 22@ = cosine 20@ // (float) 0013: 21@ *= -1.5 //上よりも足す距離が長い。 0013: 22@ *= 1.5 //つまり上よりも速く移動する。 005B: 6@ += 21@ // (float) 005B: 7@ += 22@ // (float) 02CE: 10@ = ground_z_at 6@ 7@ 8@ if 0043: 10@ == 0.0 then 000B: 8@ += 3.0 02CE: 10@ = ground_z_at 6@ 7@ 8@ if 0043: 10@ == 0.0 then 000F: 8@ -= 3.0 else 000B: 10@ += 0.6 0087: 8@ = 10@ // (float) end else 0087: 11@ = 8@ // (float) 0063: 11@ -= 10@ // (float) if 0021: 11@ > 3.0 then 000F: 8@ -= 0.3 else 000B: 10@ += 0.6 0087: 8@ = 10@ // (float) end end gosub @get_pointer 0085: 13@ = 1@ // (int) 0012: 13@ *= 12 005A: 30@ += 13@ // (int) 0A8C: write_memory 30@ size 4 value 6@ virtual_protect 0 000A: 30@ += 4 0A8C: write_memory 30@ size 4 value 7@ virtual_protect 0 000A: 30@ += 4 0A8C: write_memory 30@ size 4 value 8@ virtual_protect 0 end end end end end //forループのend 25回行う。 jump @create_corona //ループ最初に戻る ////////////////////////////////// subroutine & storage ///////////////////////////////////// :get_pointer 0A9F: 30@ = current_thread_pointer 000A: 30@ += 0x10 0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0 000E: 30@ -= @pos_pool return :corona { 58 , 0x3A byte 詳しくはwikiへ。 この場合はCoronaを同じ位置に2つ生成するため、少し大きい。 バイナリ変換前はコレ。 04D5: create_corona_at 6@ 7@ 8@ radius 0.6 type 9 flare 0 RGB 192 192 192 04D5: create_corona_at 6@ 7@ 8@ radius 0.55 type 9 flare 0 RGB 95 63 255 return } hex D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 D504030600030700030800069A99193F0409040005C00005C00005C000 D50403060003070003080006CDCC0C3F04090400045F043F05FF005100 end :pos_pool { 力業。 そのうち詳しくwikiに書きます。 hexなので16進数。 1塊4byte 00000000〜FFFFFFFFまで。10進にすると0〜4294967295 2進に至っては 0000 0000 0000 0000 0000 0000 0000 0000〜1111 1111 1111 1111 1111 1111 1111 1111となる。 ここに値を書き込んでいく。 際限なくスペースを広げることが出来るため、この方法は知っておきたいところ。 } hex //pos - 300 , 0x12C byte 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 //timer - 100 , 0x64 byte 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 end