今更なオブリビオンブログ
おもにMOD関連のメモを書いていくと思います、MODをいじったり、作ってるのが楽しいです。
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

TeleportMagic
若干…というか、かなりチートな気はしますが公開します。

ダウンロードはこちら
http://www.4shared.com/zip/eCehmemm/TeleportMagic_v101.html

■概要
ドラゴンボールの瞬間移動のように、PCを任意のNPCの元に移動させる魔法を覚えます。

「Teleport」と「TeleportTargetSet」という魔法(神秘魔法)を覚えます。
TeleportTargetSetで人物をセットし、Teleportでセットした人物の元にテレポートします。
32人分覚えることが出来ます。



この魔法を使って不法侵入した場合、おそらく鍵の掛かった部屋に行く事になるので、脱出の方法は考えておきましょう。
続きを読む
スポンサーサイト

テーマ:PCゲー - ジャンル:ゲーム

MOD作り7
今度は、ドラゴンボールの瞬間移動のようなものを作ってみました。

ターゲットをセットする魔法と、場所移動用の魔法の二つになりました。



ターゲットを取得するにはRef変数を宣言して使います。
この辺は自分でもよく分かってないんですが、オブジェクトのデータを格納するための変数は、
Ref変数を使わなければいけないそうです。


クエストスクリプトにターゲットのデータ格納用の変数を宣言しておき、
それを二つの魔法のスクリプト内から参照するという形にしました。

ターゲット取得用の魔法で「GetSelf」関数をつかって、対象のデータを取得して、クエストスクリプトの変数に格納しています。
ワープ用の魔法では、クエストスクリプトの変数を参照してターゲットを取得しています。



また、ターゲットには、32人分の枠を用意したので、今回はメッセージボックスを活用して、ページの切り替えを出来るメニューを用意しました。
今回初めてページの切り替えができるメッセージボックスを作ったのですが、ボタンを複数作るだけのメッセージボックスとはまた勝手が違ってちょっと苦労しました。

以下はターゲットを設定する時の魔法のスクリプトの一部になります。

Short Stage
Short Page
Short Button

中略


begin ScriptEffectStart

中略

set Page to 0
set Stage to 1
end


begin GameMode
if Stage == 0
return
elseif Stage == 1
If Page == 0
[1つ目のメニュー]
set Stage to 2
ElseIf Page == 1
[2つ目のメニュー]
set Stage to 2
ElseIf Page == 2
[3つ目のメニュー]
set Stage to 2
ElseIf Page == 3
[4つ目のメニュー]
set Stage to 2
endif

elseif Stage == 2
If Page == 0
[1ページ目のメニューのボタンの処理]
elseif Page == 1
[2ページ目のメニューのボタンの処理]
elseif Page == 2
[3ページ目のメニューのボタンの処理]
elseif Page == 3
[4ページ目のメニューのボタンの処理]
endif
endif
end


・変数の役割ですが、
「Button」は、「GetButtonPressed」を使ってボタンの処理をするための変数です。
「Page」と言う変数で現在どのページを表示しているのかを表します。
「Stage」と言う変数で現在行っている処理を分けています。最初、処理を分けずに書いたら、メッセージボックスの表示から処理が進まなくて困りました。


・最初に「begin ScriptEffectStart」のブロックで初期化設定を行っています。
これは魔法を使った時に初めに一回だけ処理されます。

1枚目のページを表示するために、「Page」に0を、メッセージボックスを表示するために「Stage」に1を入れています。


・次の「begin GameMode」のブロック内でメッセージボックスの表示とボタンの処理を行っています。
これは魔法の効果が現れている間、常に処理されています。

「Stage」が0の時は「return」で、何の処理もしていません。

「Stage」が1の時はメッセージボックスの表示です。その中で「Page」を判定してそれぞれに対応したメニューを出しています。
メッセージボックスの表示後に「Stage」に「2」を入れてボタンの判定に移ります。

「Stage」が2の時はボタンの処理をしています。ここで「Stage」に「0」を入れれば処理を抜けます。
「Stage」に「1」を入れればメッセージボックスの再表示になります。
その際に「Page」に数字を入れればそのページのメニューを出すことになります。




続きを読む

テーマ:PCゲー - ジャンル:ゲーム

うまくいかない…
一対のドアを作り、「MoveTo」のコマンドを利用して移動させれば、どこでもドアみたいに利用出来るんじゃないかと思いついて
作ってみました。


まずは、テスティングホールに二枚のドアを作って繋げます。
あとは魔法でドアAを呼び出して、別の場所でドアBを呼び出せば、任意の場所同士をつなげるドアが出来るはずです。
けれど、ドアAを呼び出して、テスティングホールに行くのは成功したんですが、そこから元の場所に戻ろうとすると
セルは移動できるものの、変な座標に飛ばされて、うまくいきません。


そういう仕様なのか、ドアは移動させちゃいけないみたいです。
移動させたドアへのTeleportは、飛ばされる座標は毎回同じなので、
セル間の移動はできても、Teleportしてくる座標はドアを移動させる前と同じ座標になっているようです。
(オブジェクトとしてのドアと、Teleportの機能は切り離せないけれど、システム的には別扱いになっている?)


どこでもドアみたいな物をつくろうとすると、どうやらドアの外見をしたアクティベーターにして、
スクリプトでPCを移動するようにするしかないみたいです。
せっかくドアで場所移動できるのに、こういう利用ができないとはもったいない…

テーマ:PCゲーム - ジャンル:ゲーム

メッセージの表示について
メッセージの表示

MODでよく使われる、いわゆる「天の声」としてのメッセージの表示の仕方について自分なりに、軽くまとめをしておこうと思います。

メッセージの表示は主に3つの方法があります。
・「クエストジャーナル」を使う
・「Message」を使う
・「MessageBox」を使う


■「クエストジャーナル」を使う場合は、画像のようにQuestStagesに文章を書いておくと、SetStageなどのコマンドで
その数字のステージになった時に自動的に表示されます。



利点としては、見ての通り、文章の表示とともに記述したスクリプトを一回だけ走らせることが出来ます。
あえて文章を表示せず、スクリプトの実行だけをすることも可能です。
この文章はメニューからいつでも見直すことが出来るため、重要なメッセージや、複雑な指示を必要とするクエストに向いています。


注意点は一度しかポップアップで表示できないことです。
一度進めたステージは、戻すことが出来ないので、これも注意が必要です。
以前にも書いたようにダイアログのスクリプトからのSetStageだと、ポップアップで表示されません。
どうしても会話後にクエストジャーナルの表示がしたい場合は、外部にステージを進めるための専用のスクリプトを作っておき、
ダイアログでそのスクリプトを発動させる、等の工夫が必要になります。



■「Message」を使う場合は、スクリプトで

Message "表示させたい文章"

と記述します。
これで画面上部に文章が表示されます。喋る武器のMODなどではこれがよく使われています。

利点としては、唯一文章の表示中に時間を止めないという特性のため、戦闘中にも流れる可能性のあるメッセージの表示に向いています。
ほかの方法に比べると、あんまりうるさくないので、各種確認のメッセージとして使うのにも向いています。
ゲーム中でちゃんとスクリプトが走ったかどうか、確認したい時には処理の途中に挟んでおくと分かりやすいです。

注意点は自動で流れていってしまうため、読んでいる途中で消える、戦闘中など忙しい時には見逃す可能性があるということ。
そのため、重要なメッセージの表示には向きません。



■「MessageBox」を使う場合は、スクリプトで

MessageBox "表示させたい文章"

と記述します。
これで画面中央に文章がポップアップで表示されます。
完了(done)のボタンを押さない限り、表示されたままです。

利点としては、文章の表示中に時間を止めるため、わりと重要なメッセージの表示にも向いています。
とは言え、本当に重要なメッセージの表示は後から見直せるクエストジャーナルのほうがいいです。

注意点は、表示中時間を止めるため、戦闘中にこれが出ると、かなりめんどうな事になります。





また、「MessageBox」には色々オプションがあって、駆使すれば、擬似メニュー画面が作れたりします。
簡単な使い方の説明だけしておきます。

・メッセージの中で変数の表示が出来ます。これは「Message」でも使えます。

short LV

set LV to player.GetLevel

MessageBox "あなたのレベルは %.0f です",LV


と記述すると、プレイヤーのレベルが表示されるはずです。

書式は、

MessageBox "文章 %.0f ",[変数名]

となっていて、「%.0f」の所に変数が入ります。これは、複数表示させることも出来て、その場合は

MessageBox "文章 %.0f 文章 %.0f 文章 %.0f 文章 %.0f",[変数名1],[変数名2],[変数名3],[変数名4]

という感じになります。「%.0f」を書いた所に順番に変数が入っていきます。
最大9個まで変数を表記することが出来ます。

なお、変数の表記法ですが、
「%[数字(省略可)].[数字]f」となっていて、前の数が表示する桁数を、後ろの数が小数点の表示する桁数を表しています。
つまり、
「%.0f」…変数を整数で表すことになります。
「%.2f」…変数の小数点第2位までを表示します。(「3」を「3.00」と表記)
「%5.0f」…変数を5桁の整数で表します。(「3」を「00003」と表記)

また、「%」の直後に「+」や「-」を付けて書くと、数字の前にこれらの記号を付けて表記することが出来ます。
MessageBoxで「%」を表示するためには、「%%」と書かなくてはいけません。(全角の「%」は、問題なく表示できます)


・ボタンを複数作ることも出来ます。

MessageBox "ボタンを選んでください","ボタン1","ボタン2","ボタン3"


こんな感じで""で囲って「,」で区切った文章が羅列した順にボタンになります。最大10個までボタンを作ることが出来ます。
ただし、これだけだと本当にボタンが増えただけで、どれを押してもOKボタンを押すのとなんら変わりがありません。


それぞれのボタンに意味を持たせるには「GetButtonPressed」という関数を利用します。
これは、今MessageBoxのどのボタンを押しているかの識別に使える関数です。
「GetButtonPressed」は、何もボタンを押していない時には「-1」の数字を返して、
一つ目のボタンを押した時に「0」を、二つ目のボタンを押した時に「1」を…という感じで順番に数字を返してきます。


以下は石像などのアクティベーターに付けるためのスクリプトです。
アクティベートした時にメッセージを表示させるものです。
文章の内容は適当です、気にしないでください。

short button
short LV

begin onActivate
set LV to player.GetLevel
MessageBox "あなたのレベルは %.0f ですね",LV,"そうだよ","ちがうよ"
end

begin GameMode
set button to GetButtonPressed
if button == -1
return
elseif button == 0
MessageBox "この正直者め!"
elseif button == 1
MessageBox "嘘をつくな!"
endif
end


このように二つのブロックに分けて書かなければいけません。


「begin onActivate」のブロックでは、一枚目のMessageBoxを出しています。
ここで出したMessageBoxにはボタンが二つあるはずです。

次の「begin GameMode」のブロックではボタンの状態を常に監視しています。
初めにボタンの状態が「-1」(ボタンを押していない状態)だと、「return」のコマンドを実行しています。
これは、そこで処理を中断するという意味になります。
これをこのブロックの最初のほうに書いておくと、以下のスクリプトの内容を評価しないため、負荷の軽減になるそうです。

次にボタンの状態が「0」(一つ目のボタンを押した状態)だったら、二枚目のMessageBox "この正直者め!"を出します。
次にボタンの状態が「1」(二つ目のボタンを押した状態)だったら、二枚目のMessageBox "嘘をつくな!"を出します。


ただし、これだけでは実際に運用するには支障があります。
どういうことかというと、初めのMessageBoxが出てから次のMessageBoxが出るまでにほんの少しタイムラグがあるため、
その間に再度アクティベートできてしまい、動作がおかしくなる可能性があります。
そのため、普通は以下のようにして処理が全て終わるまではアクティベートが出来ないようにします。

short Choosing
short button
short LV

begin onActivate
if Choosing == 0
set LV to player.GetLevel
MessageBox "あなたのレベルは %.0f ですね",LV,"そうだよ","ちがうよ"
set Choosing to 1
endif
end

begin GameMode
if Choosing == 1
set button to GetButtonPressed
if button == -1
return
elseif button == 0
MessageBox "この正直者め!"
set Choosing to 0
elseif button == 1
MessageBox "嘘をつくな!"
set Choosing to 0
endif
endif
end




OBSEを使えば、「MessageEx」「MessageBoxEx」が扱えるようになります。
これは、上記に加えて色々と変数の表示の種類が増えたり、専用の関数が増えたりしています。
一部を紹介すると、

「%r」…改行する
「%i」…IDを表示
「%n」…名前を表示
「%k」…その数に該当するキーボードのキーを表示する
「|」…メッセージ内に書くと、以降の文章をボタン扱いに出来る。それの何が嬉しいかというと、ボタンに変数を表示することが可能になります。

・「SetMessageSound」…MessageBoxExの呼び出しによって再生される音を設定します。
書式は
SetMessageSound [soundID:string]

・「SetMessageIcon」…MessageBoxExのテキストの左側に表示されるアイコンを設定します。("Data\Textures\Menus\"に位置するDDSファイルです)
書式は
SetMessageIcon [iconPath:string]


その他注意としては、MessageBoxは、どんなに長くなっても改行せずに書かなくてはいけません。

あと、アイテムを使ってこういうメニューを出したい場合は、
「onActivate」を「OnEquip」に、「GameMode」を「MenuMode」にすればいけると思います。


それから、これはあくまでも簡単な使い方の例で、あんまり負荷とかを考慮していません。
「begin GameMode」を使っているため、こういうオブジェクトが同一セルに沢山増えるとその分負荷がかかってしまいます。
まあ、二つや三つくらいなら問題ないでしょうが…
余談ですが、大型MODのMMMでは宝石をクリックして粉末に出来る機能があるんですが、そのときに出るメッセージボックスが
おそらく上記のような書き方で「MenuMode」のスクリプトを付けていると思われます。
そのせいで、気づかずに2~300個くらい貯まっていたりすると、メニューを開いた時に高負荷のせいでCTDを頻発します。

解決法としては、「GameMode」あるいは「MenuMode」で行っている処理を「マジックエフェクトスクリプト」か「クエストスクリプト」に任せるのがいいと思います。
魔法でやる場合はアビリティにスクリプトを付与して、一枚目のメッセージボックスを表示した時にAddして終わったらRemoveする。
クエストスクリプトの時は必要な時にそのクエストをStartQuestして、終わったらStopQuestするのがいいと思います。
クエストスクリプトでやる際には忘れずに「fQuestDelayTime」を使ってクエストスクリプトが処理される頻度を変更しないとサクサク動かないでしょう。

続きを読む

テーマ:PCゲーム - ジャンル:ゲーム

クエストアイテムフラグおよびリスポーンについて
クエストアイテムとは、その名の通り主にクエスト用のアイテムで、それにに付けられるものがクエストアイテムフラグなんですが、
アイテムだけではなく、オブジェクトには全てクエストアイテムフラグが付います。



これがオンになっていると「捨てられない」「重さが0になる」「リスポーンしない」という性質を持ちます。
アイテムの場合は重さが強制的に0になるため、「捨てられない重たい荷物」というものは作れません。

クエストアイテムフラグをオンにした場合の最大の特徴が「リスポーンしない」というところです。



NPCのクエストアイテムフラグをチェックした場合、リスポーン期間を過ぎても、そのNPCの死体は、ずっと居残り続けます。



画像はとあるNPCの死体。ちなみにNPCの最大体力が0で不死身でなければ死体扱いになります。

死体、あるいは死ぬ可能性があるNPCに重要なアイテムを持たせる場合や、死体をオブジェクトとして置いておきたい場合に有効です。
チェックしていないとリスポーン期間を過ぎると消えてしまいます。

事件の現場などから死体役がいなくなってしまうのは味気ないです。
そういう演出を狙う時意外は忘れずにチェックしておきましょう。





WorldObjectsにもクエストアイテムフラグがありますが、こちらは設定がやや特殊です。
こちらはObjectWindowからEditorIDごとにも設定できますが、RenderWindowで配置したオブジェクトのReferenceごとにも設定することが出来ます。



画像の赤枠の所は、見ての通り本来はスクリプトから参照したい時にチェックする所です。
ここにチェックが入っていないと、特定のオブジェクトをスクリプトで操作する時にReferenceIDを参照できず、
スクリプトを保存する時エラーになります。ターゲットを選ぶときのリストに出てもきません。

チェックするとクエストアイテムフラグをオンにするのと同様で、リスポーンしなくなります。




ドアの場合は、ここがデフォルトでオンになっていて、オフにすることは出来ないため、
一度出現したら、リスポーン期間を過ぎてもずっと動かないままです。

つまり、MODでドアを移動させても一度そのドアを出現させたセーブデータでは
リスポーン期間を過ぎても移動が反映されないということが起こります。

※このあたり、勘違いしていたようです。リスポーンに関してはこちらの記事をどうぞ。




また、クエストアイテムをリスポーンするNPCに持たせておくと、リスポーンした時に持ち物がリセットされない、という仕様があります。
(これにより見かけ上NPCがリスポーンしなくなったようにみえます)


SetQuestObjectのコマンドでクエストフラグのオン・オフの制御が出来ます。
ヴァニラでは、これでクエストの終了とともにPCの持ち物の中にある各アイテムのクエストフラグをオフにしています。

SetQuestObject MG05FingersMiscBook 0

書式
SetQuestObject [アイテムID] [0or1]

アイテムの場合、オフにした瞬間に本来の重さに戻ります。
指定はEditorIDのため、同一のアイテムは一律に変わってしまいます。

続きを読む

テーマ:PCゲーム - ジャンル:ゲーム



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。