かなりふつう

ヾ( ゚д゚)ノ゙

指定の乗り物を取得するコード

DOFさんへの返信用記事です。


以下のコードは、CJからもっとも近くにある乗り物のハンドルを、
自分で追加したメモリプールの0x000番地に書き込むためのものです。

まず、一番下のMemoryPoolルーチンでメモリを確保します。0が8つあるので
最大0xFFFFFFFFまで、つまり4byteデータを1つ格納できます。それを5つ
用意してあります。GTAで扱う変数は、1つ当たり4byteあれば充分なので、
私は基本的に4byteメモリを1変数として使っています。

次にGetPointerルーチンは、メモリプールのMemoryPoolの位置を調べて
そのメモリ上のアドレスを変数30@に書き込む処理です。csの最初に

gosub @GetPointer

と書いておけば、以降30@を基準として追加メモリにいつでもアクセス
できるようになります。なので30@はcs内では絶対書き換えないように
しましょう。

そしてGetNearVehicleを呼び出すと、現在画面内に生成されている乗り物
全てを、ハンドルの数値が若い順から1つずつ探していきます。もし1つ
見つかったら、その乗り物とCJの距離を計算し、記憶します。同時にその
乗り物のハンドルも記憶しておきます。そして次の乗り物を探し、また
その乗り物との距離を計算し、もし現在記憶している距離よりも短ければ
上書き記憶します。長ければ無視します。これを全ての乗り物に対して
実行すれば、最期に記憶された乗り物はCJとの距離が一番近いものです。

ここで、このコードでは「CJとの距離」を条件にしています(赤字部分)が、
これを「規定の直方体の中にある乗り物で、最初に見つかったNGR500」
に変更すれば、GetNearVehicleを呼び出した時に規定の範囲内にNGR500が
存在するかをチェックできます。もし存在していたなら何もしなくていいですし、
1台も見つからなかった時はその範囲内の指定の位置に生成させればOKです。

あとはそのチェックするタイミングですが、これはCJが規定範囲内のある位置から
一定距離離れた瞬間とか、一定時間ごとなど、色々やり方はあると思います。


すいませんが、帰宅したばかりでもう寝ないとヤバいのでこの辺で(´・ω・`)ノシ
かなりアバウトな内容だとは思いますが、ほとんど全てを書いてます。



サンプルコード
--------------------------------

// ************************
// 追加メモリの先頭アドレスを取得する
// ************************
:GetPointer
0A9F: 30@ = current_thread_pointer
000A: 30@ += 0x10
0A8D: 30@ = read_memory 30@ size 4 virtual_protect 0
000E: 30@ -= @MemoryPool
return

// ********************************************************
// もっとも近くにある乗り物のハンドルを0x000に格納する
// ********************************************************
:GetNearVehicle
0A8E: 31@ = 30@ + 0x000
0A8C: write_memory 31@ size 4 value -1 virtual_protect 0

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
056E: car 26@ defined
then
0A8E: 31@ = 30@ + 0x05C
0A8D: 15@ = read_memory 31@ size 4 virtual_protect 0

if
15@ == -1
then
0A8C: write_memory 31@ size 4 value 26@ virtual_protect 0
else
00A0: store_actor $PLAYER_ACTOR position_to 10@ 11@ 12@
00AA: store_car 15@ position_to 13@ 14@ 15@
00AA: store_car 26@ position_to 16@ 17@ 18@

050A: 19@ = distance_between_XYZ 10@ 11@ 12@ and_XYZ 13@ 14@ 15@
050A: 20@ = distance_between_XYZ 10@ 11@ 12@ and_XYZ 16@ 17@ 18@

if
0025: 19@ > 20@
then
0A8C: write_memory 31@ size 4 value 26@ virtual_protect 0
end
end
end
end
end
return

// ************************
// 追加メモリのプール (5個分)
// ************************
:MemoryPool
hex
00000000 00000000 00000000 00000000 00000000
end
--------------------------------

Comment

無題

  • DOF
  • 2014-05-14 11:34
  • edit
分かりやすい例文ありがとうございます。
これを元に作成してみます。本当にありがとうございました

無題

  • Dof
  • 2015-03-01 10:28
  • edit
こんにちは。
CLEOコードの事で質問なんですが、例えばカメラの視野角を変更するCSを使っていた場合にですね。
そのCSにカットシーン時のみ無効にするという事は可能なのでしょうか?
可能でしたら、よろしかったらCLEOコードを教えていただきたいです。よろしくお願いいたします

存じません

  • 普通のげーまー
  • 2015-03-04 12:33
  • edit
まず、そういうことはやったことがないので可能かどうかわかりません。

Dofさんはどのようなコードを作り、結果どうなって、試行錯誤を経てうまくいかなかったのでしょうか?それを教えて貰えれば、何か助言ができるかもしれません。

無題

  • Dof
  • 2015-03-04 16:06
  • edit
まずこちらのcleo modを改造しようとしています。
http://ashslowgameblog.blog.fc2.com/blog-entry-1435.html

コードはこちらになるのですが。
// This file was decompiled using sascm.ini published by GTAG (http://gtag.gtagaming.com/opcode-database) on 14.6.2013
{$CLEO .cs}

//-------------MAIN---------------
0000: NOP

:NONAME_2
wait 0
if and
Player.Defined($PLAYER_CHAR)
82D8: not actor $PLAYER_ACTOR current_weapon == 99
jf @NONAME_2
0922: set_camera_zoom_from 103.0 to 0.0 timelimit 15000 smooth_transition 2
jump @NONAME_53

:NONAME_53
wait 0
if
82D8: not actor $PLAYER_ACTOR current_weapon == 99
jf @NONAME_2
0922: set_camera_zoom_from 103.0 to 0.0 timelimit 15000 smooth_transition 2
jump @NONAME_53

このコードに、例えば $ONMISSION == 0 のようなコードを加えることで、カットシーン時のみ無効化させたいのですが、mission時に無効化させるコードは知っていますが、カットシーンでcsを無効化させるコードを知りませんでしたので...。
普通のげーまーさんなら御存知かと思ってお聞きした次第です。

お返事遅れてすみません

  • 普通のげーまー
  • 2015-03-09 02:40
  • edit
まず、「カットシーン時のみ」無効にしたい理由が分かりません。例えば通常プレイからカットシーンを含めた流れを動画にしたいとしても、カットシーンだけそのCSを省いて撮影して動画に挿入すればよいだけです。プレイ中に自動的にOFFにする必要性が見えません。

一応解決策としては、これがCSならば、事前にコマンド受付にしておき、ON/OFFを切り替えられるようにしておけば解決する気がします。つまり、カットシーンで無効化するのではなく、カットシーンに入る前にこのルーチンを通らないようにすれば。

具体的に言うと
1、1byteのメモリを確保し、コマンドを入れる度にその中身が1と0に切り替わる処理を作る
2、上の処理の「外側」に、1の処理を用意する
3、1のメモリがONのときだけ上の処理に入るようにする。0なら処理に入らずにコマンド入力待ちに戻る。

ローテクですが、これで解決するはずです。
あくまで自動にしたいなら、まず特定のメモリを監視させ、それが1のときだけ上の処理がされるようにし、0のときはスルーしてループするように上のbuilding effect.csを改造しておきます。次にmain.scmを改造し、目的のカットシーンに入る直前に、そのメモリが0になるようなコードを埋め込んでおきましょう。そうすれば、カットシーンに入る時点でbuilding effectが働かなくなるので、無効化したのと同じになるはずです。

いかがでしょうか?

無題

  • Dof
  • 2015-03-11 09:50
  • edit
プレイ中にOFFにする必要があったと感じたのは視野角の広さです。
通常より視野角が格段に広く映るため、カットシーンで通常見えないような、例えばキャラクターの待機状態など動きだしが見えてしまうためでした。
でも、ON/OFF機能を使えば簡単ですね。言われるまで気付きませんでした。
確かにON/OFF機能を追加すれば何も問題はなくなりますね。
助言ありがとうございました。ON/OFF機能を付けてみようと思います。

Form

お名前
タイトル
E-MAIL
URL
コメント
パスワード

カウんター

カウンター

プロフィール

普通のげーまー
ニコニコ動画で「東方姫一華」連載中です

最新コメント

[03/11 Dof]
[03/09 普通のげーまー]
[03/04 Dof]
[03/04 普通のげーまー]
[03/04 普通のげーまー]

ブログ内検索

管理用

TemplateDesign by KARMA7