- 追加された行はこの色です。
- 削除された行はこの色です。
*シナリオ作成応用編 [#s470aea3]
#contents
----
**Q601. 敵を倒したら強化パーツを手に入れさせるにはどうすれば良いのですか? [#Q601]
SRWなどでは、ボスを倒した時に強化パーツが手に入ります。
これをSRCで再現するためには破壊ラベルを使いましょう。
破壊 (破壊されたユニットのパイロット名):
(強化パーツを手に入れるイベント)
Exit
強化パーツを手に入れるイベントに関して以下に例を挙げます。
Item (強化パーツ名)
Talk システム
(強化パーツ名)を手に入れた
End
まとめ
・敵を倒したかどうか判別するには…破壊ラベル
・強化パーツを手に入れるには…Itemコマンド
**Q602. ステージ終了時の残りSPによる経験値ボーナスをやめることはできますか? [#Q602]
SRCではステージを終了すると、
ステージ終了時点のSPx2が経験値ボーナスとして
自動で加算されるようになっています。
ただ、毎回経験値が加算されてしまうと、
レベル調整するのが難しくなってしまうので、
これをやめたいという場合もあるかと思います。
<経験値加算が行われる条件>
・Continueコマンドを使った時点で
・"出撃"or"格納"状態になっている味方ユニット
つまり、Continueコマンドを使う直前に
Escapeコマンドで味方全体を"待機"状態にしてしまえば
経験値が加算されませんし、表示自体も行われなくなります。
Escape 味方
Continue シナリオ02.eve
直後がContinueコマンドになっていますので、
味方の全滅イベントが発生する心配はありません。
Destroyコマンドを使うと修理費がかかってしまうので
気をつけましょう。
''関連項目:''
[[Q612. 戦闘時の獲得経験値をすべてゼロにする方法は?&br; 敵撃墜時の獲得資金をすべてゼロにする方法は?>#Q612]]
**Q603. 指定座標のビットマップ番号はどうやって調べれば良いですか? [#Q603]
ChangeTerrainコマンドではビットマップ番号を指定する必要がありますが、
Info関数ではビットマップ名しか調べられません。
(ビットマップ名 = "remains1.bmp"、"base-1.bmp" など)
ビットマップ名は必ず"文字列"+"数値"+"."+"拡張子"の順に並んでいますので、
SRCのイベントコマンドと関数を利用すれば、番号だけの抽出が可能です。
# ビットマップ名取得
# (Info関数を使用してください)
mBMP = Info(マップ, X座標, Y座標, ビットマップ名)
# 拡張子切捨て
# ("文字列" + "ビットマップ番号" にする)
mBMP = Mid(mBMP, 1, (Instr(mBMP,".") - 1))
# ビットマップ番号抽出
# (数値 or "-" 以降の部分を抽出する)
For i = 1 To Len(mBMP)
If Mid(mBMP,i,1) = "-" OR IsNumeric(Mid(mBMP,i,1)) Then
mBMP_No = Mid(mBMP,i)
Break
Endif
Next
結果
・"mBMP_No"がビットマップ番号になります。("1"とか"-1")
**Q604. 全ての味方、敵、または特定グループIDのユニットに対し何かをするには?[#Q604]
「ForEach」コマンドを使います。
# 全ての敵の気力を 10 下げる。
ForEach 敵
IncreaseMorale -10
Next
# 全ての味方ユニットに搭乗する全パイロットの SP を回復させる。
ForEach 味方
For i = 1 to CountPilot()
RecoverSP PilotID(対象ユニットID,i) 100
Next
Next
# 同じ名前のパイロットが複数いないならば、
# PilotID()関数のかわりに Pilot()関数でもかまいません。
ただし、ForEachループの中に ForEachを入れることはできないので、ご注意ください。
次は、特定グループに対しまとめて何かをする例です。
# グループID「防衛隊」の全出撃ユニットの思考ルーチン動作を変える
ForEach 防衛隊
ChangeMode 待機
Next
処理内容がやや複雑な例です。&aname(Q604ActionRec);
# すべての行動済み味方ユニットを行動可能状態に戻すサブルーチン
全味方行動可能:
ForEach 味方
If Action() = 0 Then //この「Action() = 0」は、"残り行動数が
// 0 か"をチェックする判別式です
Action() = 1 //この「Action() = 1」は、"残り行動数に 1 を代入する"
//という意味で、「Action()」は関数の左辺値用法です
EndIf
Next
Redraw // ユニットアイコンの網掛けをはずす
Return
# このサブルーチンは、2回行動には対応していません
#br
#hr
コマンドによっては、陣営名やグループIDをパラメータにすることによってまとめて処理できます。
# 出撃中の全ての味方を脱出させる。
Escape 味方
ただし、この方法はコマンドごとの仕様に依存します。 特に慣れないうちはヘルプでしっかり確認してから使うことをおすすめします。
**Q605. ユニットが装備する全アイテムを調べ、処理するには?[#Q605]
「CountItem」関数で装備アイテム数を調べ、「For〜Next」ループや「Do〜Loop」ループを使います。
以下の例では、メインパイロット名が「パイロットA」のユニットのアイテムの名称を連想配列「Aアイテム」に入力します。
Set Aアイテム
For i = 1 To CountItem(パイロットA)
Aアイテム[i] = Item(パイロットA, i)
Next
ループの実行中にアイテムの番号が変化するかもしれないときは注意が必要です。 以下は、パイロットAの持つアイテムのうち装備個所が「武器」であるアイテムを削除します。
For i = CountItem(パイロットA) To 1 Step -1
If Info(アイテム, Item(パイロットA, i), 装備個所) = "武器" Then
RemoveItem パイロットA i
EndIf
Next
For〜Next、ForEach〜Next、Do〜Loop は繰り返し構造と呼ばれ、パラメータを変えながら繰り返し順番に実行していきます。 しばしば誤解されますが、決して「当てはまる要素に対して一度に実行する」というものではありません。
したがって、上と同じ目的で以下のようにするのは誤りです。
For i = 1 To CountItem(パイロットA) // まちがい
If Info(アイテム, Item(パイロットA, 1), 装備個所) = "武器" Then
RemoveItem パイロットA 1
EndIf
Next
これだと、ループを繰り返すなかで RemoveItem されたときアイテムの番号がずれてしまい、チェックされないアイテムが出てきます。
あえて正順でやりたい場合は、たとえば次のようにします。
Set i
Do While i <= CountItem(パイロットA)
If Info(アイテム, Item(パイロットA, i), 装備個所) = "武器" Then
RemoveItem パイロットA i
Else
Incr i // 順番がずれないときだけ、i を増やす
EndIf
Loop
**Q606. ユニットがマップの特定領域に入ったときに何かを起こすには?[#Q606]
ユニットが特定領域に存在するとき処理したい場合は、[[Q.607>#Q607]]を参照してください。
「特定領域」がたった一つの座標の場合は、単純に「進入イベント」を使います。
# 味方ユニットが X = 5、Y = 7 に入ったときにイベントを起こす
進入 味方 5 7:
(イベント内容)
Exit
#br
座標が複数あるときは、「進入イベントラベル」を並べます。
# これらのイベントは合わせて1回しか起こらない。
進入 味方 5 7:
進入 味方 4 7:
進入 味方 5 8:
(イベント内容)
ClearEvent "進入 味方 5 7"
ClearEvent "進入 味方 4 7"
ClearEvent "進入 味方 5 8"
Exit
ClearEventコマンドのパラメータを省略すると、イベント内容を引き起こしたイベントラベルだけを消去します。 並べられたイベントラベルをすべて消去したい場合は、上のように記述してください。
座標がもっと多い場合などには、「進入イベント」内部で座標を判別させます。
以下は「特定領域」の X座標が 5 以下、Y座標が 4 以上 8 未満の場合にイベントを起こします。
進入 味方 全 全:
If X() <= 5 And Y() >= 4 And Y() < 8 Then
(イベント内容)
EndIf
Exit
「特定領域」が特定の地形の場合には、以下のようになります。
進入 味方 地形名称:
(イベント内容)
Exit
これを応用して、terrain.txt にイベント用の地形を記述してマップ上に配置するという手段もあります。
#br
**Q607. ユニットがマップの特定領域に存在するときに何かを起こすには?[#Q607]
(この項は、[[Q606.ユニットがマップの特定領域に入ったときに何かを起こしたいときには?>#Q606]]と共通事項が多いので、そちらも参照してください)。
これには、X 関数と Y 関数を使ってユニットの表示位置を出し、それを判別します。
以下は、味方ターン冒頭に X座標が 5 以下、Y座標が 4 以上 8 未満のユニットの HP を回復させます。
ターン 全 味方:
ForEach 味方 出撃
If X() <= 5 And Y() >= 4 And Y() < 8 Then
RecoverHP 対象パイロット HP回復率
EndIf
Next
Exit
**Q608. 発動に追加条件が付いたイベントを設定するには?[#Q608]
ここでは、
「敵を破壊したとき、敵数が5体以下のときだけイベントを実行したい」
「敵ユニットが特定パイロットに破壊されたときだけ、何かをさせたい」
など、イベントラベルで表される条件以外の追加条件をイベントに付加する方法を説明します。
一般には ''「If」コマンド を使います''。
# 敵ユニットが5体以下になったときに何かを起こす
破壊 敵:
If 敵数 <= 5 Then
(動作内容)
EndIf
Exit
# パイロットAが出撃中かどうかを追加条件にする場合は、
(イベントラベル):
If パイロットA Then
(動作内容)
EndIf
Exit
# となります。「パイロットA」はパイロットの名称または愛称です。
# (ザコ)または(汎用)でパイロットを特定できない場合、
# 予想外の動作になることがあります。
# 第3ターン以降毎ターンの味方フェイズに何かを起こします。
ターン 全 味方:
If ターン数 >= 3 Then
(動作内容)
EndIf
Exit
# ユニットAが武器「豆腐の角」で倒されたときのイベントです。
破壊 ユニットA:
If 相手ユニット使用武器 = 豆腐の角 Then
(動作内容)
EndIf
Exit
# 味方ユニットが属性「音」の武器を使った後、何かを起こします。
使用後 味方 対象ユニット使用武器:
If Info(ユニット, 対象ユニット, 武器, 対象ユニット使用武器, 属性所有, 音) = 1 Then
(動作内容)
EndIf
Exit
# イベントラベルの最後のパラメータが「全」だとアビリティやスペシャルパワーなど
# にも反応してしまうので、システム変数「対象ユニット使用武器」を使います。
#br
If コマンドを使うとき注意すべきは、「If の効果は EndIf を使うまでは有効だ」ということです。 EndIf の書き忘れは非常によくあるミスなので、ご注意ください。 このミスを減らすためにも「If」「ElseIf」「Else」「EndIf」のあいだの行は字下げすることを強くおすすめします。
初心者向け注意:イベント冒頭の「If」はしばしば誤解されます。 これは、イベントそのものに発生条件を付けるわけではありません。 「If」実行時にはすでにイベントは始まっているが、イベントが始まったとたんに「If」の条件が付けられた、ということです。
とりわけ、ClearEvent の置き場所はしばしばまちがえられます。
# 以下は、パイロットAが敵を破壊した場合に1回だけ起こるイベントです。
破壊 敵:
If 相手パイロット = パイロットA Then
(動作内容)
ClearEvent
EndIf
Exit
# そのつもりで以下のようにするのはまちがいです。これだと、
# ステージ最初に敵が破壊されたとき、破壊したのが誰であろう
# と ClearEvent されてしまいます
破壊 敵:
If 相手パイロット = パイロットA Then
(動作内容)
EndIf
ClearEvent
Exit
#br
追加条件を変化させたり判定させたりするタイミングが別のイベントの場合は、フラグや判別用変数を用います。[[Q609.>#Q609]]、[[Q610.>#Q610]]、[[Q613.の(3)(4)>#Q613-3]]などを参照してください。
''関連項目:''
[[Q608.1. イベント内で条件に応じ違ったことをさせる方法>#Q608_1]]
[[Q609.あるできごとが起こってから数ターン後にイベントを起動させるには?>#Q609]]
[[Q610.敵と中立の両方が全滅したときにイベントを起こすには?>#Q610]]
[[Q613.複雑な条件分岐を設定する方法は?>#Q613]]
**Q608.1. イベント内で条件に応じ違ったことをさせる方法[#Q608_1]
「敵全滅のとき、ボス登場済みかどうかで動作を変えたい」
「ターンによって勝利条件表示を変えたい」
など、条件によってイベント内容を変えるやり方です。
最もよく使うのは ''「If」コマンド を使う方法''です。
# 敵全滅時、まだボスが登場していなかったらボスを登場させ、
# すでに登場していたら別 のできごとを起こしたいときには、
# 次のようになります。
全滅 敵:
If ボス登場 = 0 Then
(ボス登場動作内容)
Set ボス登場
Else
(それ以外の時の動作内容)
EndIf
Exit
# ターンによって勝利条件表示を変える例です。
勝利条件:
If ターン数 < 5 Then
Talk
(4ターンまでの勝利条件表示)
End
Else
Talk
(5ターン以降の勝利条件表示)
End
EndIf
Exit
# 敵を倒したとき、撃墜数に応じたイベントを実行します
# スタートイベントなどで前もって変数「撃墜数」を作っておきます
スタート:
Set 撃墜数 0
Exit
破壊 敵:
Incr 撃墜数
If 撃墜数 >= 20 Then
(撃墜数20以上のときの動作)
ElseIf 撃墜数 >= 10 Then
(撃墜数10以上20未満のときの動作)
Else
(それ以外のときの動作)
EndIf
Exit
# サポートアタックがパイロットAにより行われたとき、
# それ以外のパイロットによるとき、サポートアタックが行われない
# ときそれぞれに、違った動作をさせます
使用後 全 対象ユニット使用武器:
If Pilot(サポートアタックユニットID) = "" Then
(サポートアタック不成立時の動作)
ElseIf Pilot(サポートアタックユニットID) = パイロットA Then
(パイロットAが行ったときの動作)
Else
(パイロットA以外がサポートアタックしたときの動作)
EndIf
Exit
// # Vir.2.2.27 の時点で、システム変数「サポートアタックユニットID」
// # は攻撃イベント・使用イベントでは有効ではありません。攻撃後イベント・
// # 使用後イベントでは有効です。
#br
パラメータの値によっていろいろなできごとを起こしたいときには、''「Switch」''が便利です。
# 次の例は、敵全滅のたびに違ったできごとを起こします。
スタート:
Set 全滅回数 0
Exit
全滅 敵:
Incr 全滅回数
Switch 全滅回数
Case 1
(全滅1回目で発生する動作)
Case 2
(全滅2回目で発生する動作)
…(中略)
EndSw
Exit
# 以下は、ユニットAが破壊されたとき、撃墜したパイロット
# ごとに違ったできごとを起こします。
破壊 ユニットA:
Switch 相手パイロット
Case パイロットA
(パイロットAが撃墜したときの動作)
Case パイロットB
(パイロットBが撃墜したときの動作)
…(中略)
Case Else
(それら以外のパイロットが撃墜したときの動作)
EndSw
Exit
''関連項目:''
[[Q608.発動に追加条件が付いたイベントを設定するには?>#Q608]]
[[Q613.複雑な条件分岐を設定する方法は?>#Q613]]
**Q609. あるできごとが起こってから数ターン後にイベントを起動させるには?[#Q609]
これには、ターン判別用の変数を用意しておいて判定します。
以下は、ユニットAが破壊された5ターン後にイベントを起こす二つの方法です。
<方法1>
# まず、ステージの最初に、
# ユニットA破壊まで条件が満たされないよう
# 変数「イベント起動時間」をセットします。
# 変数未定義でも条件が満たされない場合、この部分は省略可能です
# (実はこの例もそうです)。
スタート:
Set イベント起動時間 -1
Exit
# ユニットA破壊時、イベント起動予定ターンをセットします。
破壊 ユニットA:
イベント起動時間 = ターン数 + 5
Exit
# そして、ターンイベントで判別します。
ターン イベント起動時間 味方:
(イベント内容)
Exit
<方法2>
# ステージの最初に ClearEvent を使い
# ターンイベントが起こらないようにします。
スタート:
ClearEvent "ターン イベント起動時間 味方"
Exit
# ユニットA破壊時、変数をセットし、
# RestoreEvent でターンイベントを復活させます。
破壊 ユニットA:
イベント起動時間 = ターン数 + 5
RestoreEvent "ターン イベント起動時間 味方"
Exit
ターン イベント起動時間 味方:
(イベント内容)
Exit
''関連項目:''
[[Q608.発動に追加条件が付いたイベントを設定するには?>#Q608]]
**Q610. 敵と中立の両方が全滅したときにイベントを起こすには?[#Q610]
「敵と中立の両方が全滅したときにイベントを起こす」ということは、「敵全滅時、もし中立が全滅していればイベントを起こし、中立全滅時、もし敵が全滅していれば同じイベントを起こす」と同じことです。 したがって、「全滅 敵」と「全滅 中立」の二つのイベントを作り、もう一方がすでに全滅していることを追加条件にすればよいわけです。
全滅 敵:
If 中立全滅 = 1 Then
Call 双方全滅イベント
EndIf
Set 敵全滅
Exit
全滅 中立:
If 敵全滅 = 1 Then
Call 双方全滅イベント
EndIf
Set 中立全滅
Exit
# 「Set 〜」は「If〜EndIf」内の「Else」節に入れても可です。
双方全滅イベント:
(イベント内容)
Return
フラグ「敵全滅」「中立全滅」を Set して判別するかわりに、システム変数「敵数」「中立数」がゼロかどうかで判別する方法もあります。
同じことをもっと短く書くこともできます。
全滅 敵:
全滅 中立:
If 敵数 + 中立数 = 0 Then
(イベント内容)
EndIf
Exit
''関連項目:''
[[Q608.発動に追加条件が付いたイベントを設定するには?>#Q608]]
**Q611. 攻撃イベントや攻撃後イベントで味方の仕掛けた戦闘と敵が仕掛けた戦闘を判別するには?[#Q611]
よく使われる方法は二つあります。
<方法1>
以下のように、イベントを二つ作成する方法です。
攻撃 ユニットA ユニットB:
(AからBへの攻撃イベント内容)
Exit
攻撃 ユニットB ユニットA:
(BからAへの攻撃イベント内容)
Exit
<方法2>
システム変数「対象ユニットID」などを Party関数に入れ、陣営を判別します。攻撃イベントでは、「対象パイロット」「対象ユニットID」に攻撃を仕掛けた側のデータが、「相手パイロット」「相手ユニットID」に攻撃を仕掛けられた側のデータが入ります。
攻撃 味方 敵:
If Party(対象ユニットID) = 味方 Then
(味方から敵への攻撃イベント内容)
Else
(敵から味方への攻撃イベント内容)
EndIf
Exit
**Q612. 戦闘時の獲得経験値をすべてゼロにする方法は?&br; 敵撃墜時の獲得資金をすべてゼロにする方法は?[#Q612]
両方とも、おもに二つの方法があります。
(1) すべての敵ユニットの「修理費」または「経験値」をゼロにします。 味方ユニットが暴走したり憑依されたり ChangeParty する可能性があるときは、味方ユニットも同様にします。
(2) すべての味方メインパイロットにパイロット用特殊能力「資金獲得Lv-10」を付けます。 またはすべての味方パイロットにパイロット用特殊能力「素質Lv-10」を付けます。(味方パイロットが獲得資金・経験値を増加させるスペシャルパワー・特殊能力を持っていればはずしておきます)
''関連項目:''
[[Q602. ステージ終了時の残りSPによる経験値ボーナスをやめることはできますか?>#Q602]]
**Q613. 複雑な条件分岐を設定する方法は?[#Q613]
''(1)And や Or 、Not を使う''
複数の条件をともに満たしたときに動作させたいのなら And演算子を、どちらかを満たしたときに操作させたいのなら Or演算子を、条件が満たされないときに動作させたいときは Not演算子を使います。
# メインパイロットがパイロットPのユニットがアイテムAとアイテムBの両方を
# 装備しているなら、何かを起こす
If IsEquiped(パイロットP,アイテムA) = 1 And IsEquiped(パイロットP,アイテムB) = 1 Then
(処理内容)
EndIf
# アイテムAかアイテムBのどちらかを装備しているなら何かを起こす
If IsEquiped(パイロットP,アイテムA) = 1 Or IsEquiped(パイロットP,アイテムB) = 1 Then
(処理内容)
EndIf
# 相手ユニットがユニットAでもユニットBでもないとき何かを起こす
If Not (相手ユニット = ユニットA Or 相手ユニット = ユニットB) Then
(処理内容)
EndIf
# パイロットAが出場していないとき何かを起こす
If Not パイロットA Then
(処理内容)
EndIf
以下はもっと複雑な例です。
# パイロットAが座標 (2, 3) か座標 (5, 7)にいるなら何かを動作させます
If X(パイロットA) = 2 And Y(パイロットA) = 3 Or X(パイロットA) = 5 And Y(パイロットA) = 7 Then
(動作内容)
EndIf
こうした場合注意したいのは、演算子の優先順位です。 演算子は優先順位の高い順に処理され、この順番を変えるためには半角括弧「(」「)」でくくらなくてはなりません。
優先順位は、その他の演算子、Not、And、Or の順ですので、上の例のように Or の項の中に And を入れる場合には括弧は不必要です。 下の例のように And の項の中に Or を入れる場合は項を括弧でくくらなくてはいけません。
# パイロット「パA」の X座標が 3 か 4 で、Y座標が 1 か 20以上なら何かを起こします。
If (X(パA) = 2 Or X(パA) = 3) And (Y(パA) = 1 Or Y(パA) >= 20) Then
(動作内容)
EndIf
# この判別式の括弧を省略すると、Or より And が優先されるので、
# X(パA) = 2 Or (X(パA) = 3 And Y(パA) = 1) Or Y(パA) >= 20
# という意味になってしまいます。
演算子と優先順位の詳細は、ヘルプの&Color(green){「シナリオの作成」->「式」のページの「演算子」};をご覧ください。
''(2)If の入れ子''
「条件1が成立したとき動作1を行い、さらに条件2も成立するなら動作2も行う」など、追加動作がある場合に便利な方法です。
# メインパイロットがパイロットPであるユニットがアイテムAの装備しているなら
# 処理Aを起こし、さらにアイテムBも装備しているなら処理Bも起こす
If IsEquiped(パイロットP,アイテムA) = 1 Then
(処理内容A)
If IsEquiped(パイロットP,アイテムB) = 1 Then
(処理内容B)
EndIf
EndIf
(1)の方法とくらべ、個々の判別式は単純になるけれど行数は長く複雑になりがちです。場合により、(1)と使い分けます。
&aname(Q613-3);
''(3)フラグを使う''
特定のできごとがすでに起こったかどうかを条件にする場合は、フラグを使います。 ヘルプの&color(green){「シナリオの作成」->「変数」の最初のほう};をご覧ください。
以前のステージのできごとを条件にするには、フラグをグローバル変数にします。 Set コマンドは変数の値を 1 にセットしますが、Global コマンドは空文字列(数値として扱う場合は 0)がセットされます。
''(4)判別用変数を使う''
これはフラグの応用で、条件判別のための変数を準備し、この変数をさまざまなできごとや状態に応じて変化させ、判別時に使う方法です。
# 味方ユニットの座標(2,3)への進入・ユニットAの破壊・
# 味方ユニットBの母艦格納の3条件のうち二つを満たした後、
# 最初の味方フェイズに何かを起こします
スタート:
Set 判別変数 0
Exit
進入 味方 2 3:
破壊 ユニットA:
収納 ユニットB:
Incr 判別変数
ClearEvent
Exit
ターン 全 味方:
If 判別変数 >= 2 Then
(できごと)
EndIf
Exit
# 以下では、敵ユニットを倒すたびにそのランクに応じた勝利ポイントを
# 与え、勝利ポイントが 20 以上でエピローグイベントに移ります
スタート:
Set 勝利P 0
Exit
破壊 敵:
Incr 勝利P Rank(対象ユニットID)
If 勝利P >= 20 Then
Continue 次のイベントファイル名
EndIf
Exit
#br
''(5)Switch を使う''
変数の値によってさまざまに分岐させるには、「Switch」コマンドが便利です。
# ターン数を判別し、第1〜3ターン、第4〜5ターン、それら以外、
# で別の処理を行います
Switch ターン数
Case 1 2 3
(1〜3ターンの処理)
Case 4 5
(4〜5ターンの処理)
Case Else
(その他のときの処理)
EndSw
#br
''(6)多くの条件の組み合わせで分岐させる''
これはさらに複雑な場合で、多くの条件がたがいにからみあいながら分岐させます。 これには、諸条件の状態を工夫して一つの判別用変数に整理するとすっきりします。
# 三つの条件、条件A・条件B・条件Cがあり、全て不成立・条件Aのみ成立・
# ABが成立…などなどありえる組み合わせすべてで分岐させる
# まず、判別用変数をセットします。
判別変数 = IIf(判別式A, 1, 0) + IIf(判別式B, 2, 0) + IIf(判別式C, 4, 0)
# これにより、たとえば条件BCのみが成立するとき「判別変数」の値は
# 0 + 2 + 4 = 6 になります。
# あとはこの変数を使って Switch か IF で分岐させればよいだけです。
Switch 判別変数
Case 0
(全て不成立のときの処理)
Case 1
(Aのみ成立のときの処理)
Case 2
(Bのみ成立のときの処理)
Case 3
(AB成立のときの処理)
…(中略)
EndSw
# この例では判別変数を省略して、
Switch (IIf(判別式A, 1, 0) + IIf(判別式B, 2, 0) + IIf(判別式C, 4, 0))
…(後略)
# とすることもできます。が、判別変数をきっちり出しておいたほうが、
# デバッグ作業や機能拡張・改変がしやすいです。
# 判別変数の値を文字列にする手もあります。
判別変数 = IIf(判別式A, "o", "x") & IIf(判別式B, "o", "x") & IIf(判別式C, "o", "x")
# この場合、たとえば条件BCだけが成立するとき「判別変数」の値は
# "xoo" になります。
# この方法では、Like 演算子と If を組み合わせることによって、
# 柔軟な判別が可能です。
# たとえば以下は、条件ACが成立、Bはどちらでもよいときの判別です。
If 判別変数 Like "o?o" Then
…
#br
''(7)複数の分岐で処理内容が重複している場合''
サブルーチンを活用します。
# 一つ目の分岐では処理Aと処理B、二つ目では処理Bと処理C、
# 三つ目では処理Cと処理Aを、この順番で行います。
If (判別式1) Then
Call 処理A
Call 処理B
ElseIf (判別式2) Then
Call 処理B
Call 処理C
Else
Call 処理C
Call 処理A
EndIf
もちろん同じコマンド群を繰り返して書いてもかまいませんが、変更や書き換え作業が煩雑になり、また行数が長くなる分プログラムの見通しが悪くなります。
しばしば、Call サブルーチンの代わりに Goto を使いたくなりますがおすすめできません。 処理の流れが錯綜し、If〜EndIf や Switch〜EndSw などがどこで終了するのかもわかりづらい、非常にバグが出やすく検査のしにくいプログラムになってしまいます。
**Q614. パイロットのパラメータをイベントで変更する方法は?[#Q614]
ここでは、パイロットのパラメータ(格闘・射撃・命中・回避・技量・反応)をイベントで変更する方法を列挙します。 それぞれ性質が異なりますので使い分けてください。 項目はじめに「&color(green){☆};」をつけたものが比較的よく使われます。
パラメータそのものを変化させる手段のほか、修正値を与える手段も含みます。
下記のうち特殊能力に関連したものは、さらに多様な調整方法を持っています。 → [[Q616>#Q616]]、[[Q617>#Q617]]
- &color(green){☆};パイロットデータを複数用意し、ReplacePilotコマンドで切り替える。 【全般】
- Printコマンドでデータを書き換え、Forget・Loadコマンドで再読み込みする。 【全般】
- sp.txt にてパラメータを変化させるスペシャルパワーを設定しておき、SpecialPowerコマンドをかけ続ける。【スペシャルパワーによる】
- sp.txt にてパラメータを変化させるスペシャルパワーを設定しておき、パイロット用特殊能力「スペシャルパワー自動実行」で毎ターン自動実行する。【スペシャルパワーによる】
- ステータス 盲目【命中率・回避率、一斉】、撹乱【命中率】、運動性UP・運動性DOWN【命中・回避、一斉】をSetStatusコマンドでかける。
- &color(green){☆};パイロット用特殊能力「○○UP」「○○DOWN」【全て】
- パイロット用特殊能力 「超感覚」「知覚強化」「念力」「サイボーグ」「悟り」【命中・回避、一斉】、「超能力」「超反応」【命中・回避・CT率、一斉】、「○○成長」(パイロットレベルに依存する)【格闘・射撃・命中・回避・技量・反応】、「追加レベル」【全て一斉】
- パイロット用特殊能力「サポート」「○○サポート」を持ったサブパイロット・サポートパイロットを搭乗させる。【格闘・射撃・命中・回避・技量・反応】
- パイロット用特殊能力「○○成長」のレベルを調整する。【格闘・射撃・命中・回避・技量・反応】
- &color(green){☆};ユニット用特殊能力 「○○強化」【格闘・射撃・命中・回避・技量・反応】、「命中率強化=全」【命中】
- LevelUpコマンドでレベルを増減させる。 【全て一斉】
#br
**Q615. ユニットのパラメータをイベントで変更する方法は?[#Q615]
ここでは、ユニットのパラメータ(HP・EN・装甲・運動性・移動力)をイベントで変更する方法を列挙します。 それぞれ性質が異なりますので使い分けてください。 項目はじめに「&color(green){☆};」をつけたものが比較的よく使われます。
下記のうち特殊能力に関連したものは、さらに多様な調整方法を持っています。 → [[Q616.>#Q616]]、[[Q617.>#Q617]]
- &color(green){☆};ユニットデータを複数用意し、UpGradeコマンドで切り替える。
または、変形系特殊能力でたがいに関連付けられたユニットデータを複数用意し、Transformコマンドで切り替える。 【全般】
- Printコマンドでデータを書き換え、Forget・Loadコマンドで再読み込みする。 【全般】
- RankUpコマンドでランクを増減させる 【HP・EN・装甲・運動性、一斉】
- &color(green){☆};パラメータへの修正値を持つかパラメータを変化させる特殊能力を持ったアイテムを着脱する、または装備しておきDisableコマンドで封印・Enableコマンドで封印解除する、またはアイテムに必要技能を付けその条件を変化させる。 【アイテムによる】
- sp.txt にてパラメータを変化させるスペシャルパワーを設定しておき、SpecialPowerコマンドをかけ続ける。 【スペシャルパワーによる】
- sp.txt にてパラメータを変化させるスペシャルパワーを設定しておき、特殊能力「スペシャルパワー自動実行」で毎ターン自動実行する。 【スペシャルパワーによる】
- &color(green){☆};ステータス 防御力UP・防御力DOWN【装甲】、移動力UP・移動力DOWN【移動力】をSetStatusコマンドでかける。
- パイロット用特殊能力 「耐久」【装甲】、「オーラ」(必要:ユニット用特殊能力「オーラ変換器」)【HP・EN・装甲・運動性、一斉】、「超能力」(必要:ユニット用特殊能力「サイキックドライブ」)【装甲・運動性、一斉】、「同調率」「同調率成長」(必要:ユニット用特殊能力「シンクロドライブ」)【運動性】
- パイロット用特殊能力 「霊力」「霊力成長」を持たせ、RecoverPlanaコマンド、Plana関数で調整する【HP・EN・装甲・移動力、一斉】
- &color(green){☆};ユニット用特殊能力 「○○強化」【HP・EN・装甲・運動性】、「○○割合強化」【HP・EN・装甲・運動性・移動力】
- ユニット用特殊能力 「アーマー」【装甲】、「追加移動力」【移動力】
#br
**Q616. パイロット用特殊能力をイベントで付加・強化などする方法は?[#Q616]
- パイロットデータを複数用意し、ReplacePilotコマンドで切り替える。
- Printコマンドでデータを書き換え、Forget・Loadコマンドで再読み込みする。
- ユニット用特殊能力「パイロット能力付加」「パイロット能力強化」でパイロット用特殊能力を指定し、Disableコマンドで封印しておき、Enableコマンドで封印解除する。
- 「パイロット能力付加」「パイロット能力強化」を持つアイテムを、Equipコマンド、RemoveItemコマンドなどで着脱する。
- SetSkillコマンドで追加または封印、ClearSkillコマンドで封印解除する。
- ユニット用特殊能力「パイロット能力付加」「パイロット能力強化」に必要技能か必要条件を付け、条件となる特殊能力・アイテムなどを着脱する。
- ユニット用特殊能力「パイロット能力付加」「パイロット能力強化」を持つアイテムに必要技能を付け、条件となる特殊能力・アイテムなどを着脱する。
- SetStatusコマンドで特殊状態「'''特殊能力名'''使用不能」を付け、ClearStatusコマンドで解除する。
- アビリティ効果「付加」「強化」を持つアビリティで特殊能力を指定、UseAbilityコマンドなどでアビリティを実行する。
- 特殊能力を持ったサポートパイロット・サブパイロットを搭乗させる(メインパイロット以外にも有効な特殊能力のみ)。
関連項目:[[ヘルプ補足/パイロットデータ/パイロット用特殊能力>ヘルプ補足/パイロットデータ#h1b76c85]]
**Q617. ユニット用特殊能力をイベントで付加・強化などする方法は?[#Q617]
- ユニットデータを複数用意し、UpGradeコマンドで切り替える。
または、変形系特殊能力でたがいに関連付けられたユニットデータを複数用意し、Transformコマンドで切り替える。
- 「ユニットに付加する特殊能力」を持つパイロットデータを複数用意し、ReplacePilotコマンドで切り替える。
- Printコマンドでデータを書き換え、Forget・Loadコマンドで再読み込みする。
- Disableコマンドで封印しておき、Enableコマンドで封印解除する。
- 特殊能力を持つアイテムを、Equipコマンド、RemoveItemコマンドなどで着脱する。
- 特殊能力に必要技能か必要条件を付け、条件となる特殊能力・アイテムなどを着脱する。
- 特殊能力を持つアイテムに必要技能を付け、条件となる特殊能力・アイテムなどを着脱する。
- アビリティ効果「付加」を持つアビリティをUseAbilityコマンドなどで実行する。
関連項目:[[ヘルプ補足/ユニットデータ/ユニット用特殊能力>ヘルプ補足/ユニットデータ#a0df16ff]]
**Q618. 命中・回避・クリティカル、反撃オプション、特殊能力の発動など、戦闘時に起こったことを取得するには?[#Q618]
一般的なやり方は、SetMessageコマンドを使う方法です。
# 切り払い時に気力を1増やす
*攻撃 全 全:
SetMessage 相手ユニットID 切り払い $(Call(Sub2))
Exit
Sub1:
IncreaseMorale 相手パイロット 1
Return
ユニットの組み合わせを限定するときには、*攻撃イベントのパラメータを調整します。
メッセージデータに直接書き込む手段もあります。 こちらは、特定キャラクターだけの動作に向いていますが、設定できるシチュエーションはより豊富です。
どのようなシチュエーションで可能かなど、詳細はヘルプの「データの作成」->「メッセージデータ」および「SetMessageコマンド」をお読みください。
似たようなことは、戦闘アニメデータ・特殊効果データでも可能ではあります。 しかし、これらはプレイヤーの設定により切り替えるものだから、他の人に公開するシナリオではおすすめできません。
似たようなことは、戦闘アニメデータ・特殊効果データでも可能ではあります。 ただし、以下のことに注意する必要があります。
・ 戦闘アニメは、プレイヤーの選択によりオフされることもあります
・ 特殊効果は、戦闘アニメがオンのとき、戦闘アニメと重複していると実行されません
&br;
なお、使われた反撃オプションの検知は、システム変数「相手ユニット使用武器」で知ることもできます。
反撃オプションに限っては、システム変数「相手ユニット使用武器」を使うこともできます。
**Q619. さまざまな乱数の生成方法は? [#wd5cd9eb]
''(1) 1以外から始まる乱数''
これは修正値をつければいいだけです。
# 4から9までの乱数
i = Random(6) + 3
# -3から6までの乱数
i = Random(10) - 4
#br
''(2) 「連続的な(稠密な)」値域の乱数''
コンピュータというものの性質上、厳密に連続的な乱数は不可能です。 しかし、引数を十分に大きな数にすれば、擬似的に表現することはできます。 (ただし、VBの仕様により、2 ^ 22 ≒約1670万以上にしても精度は上がりません: 詳しくは[[Random関数>ヘルプ補足/算術処理関数#f2c28c18]]を参照してください)
# 0以上 1未満の実数を返す乱数です。
# シナリオの最初などで、定数を初期化しておきます。実行時間を気にしないのなら、
# この部分は省いて、そのかわり LargeInt を関数本体で逐一求めてもかまいません
Global LargeInt
LargeInt = 2 ^ 20
# 関数本体
RealRnd:
Return ((Random(LargeInt) - 1) / LargeInt)
#br
''(3) 山型の確率分布の乱数''
両端よりも中央の確率が大きい乱数です。 単純な乱数よりも安定した結果が出、ゲーム上の使い勝手が良いのでしばしば使われています。
やり方はいろいろありますが、かんたんなのは複数の乱数の和か差を使う方法です。
i = Random(6) + Random(6)
上の例は、6面サイコロを二つ振ったのと同じです。
i = Random(6) - Random(6)
差の場合も分布の形は和の場合とまったく同じですが、平均値・中央値はちょうどゼロになります。
i = Random(6) + Random(6) + Random(6)
このように3つ以上の乱数を使ってもかまいません。 このほうが中央部の確率がより大きくなります。
乱数2つのときは二等辺三角形の形の確率分布になりますが、3つ以上だと丸みをおびた形になり、数が大きくなるほど正規分布曲線に近づきます。
''(4) 下端または上端が大きい確率分布の乱数''
これもいろいろやり方がありますが、比較的かんたんなやり方を紹介します。
下記の例はいずれも 1から 10までの整数値を返します。
<方法1>
i = Random(Random(10))
この方法は偏りが激しいのが特徴です。 上の例だと、1だけで29.29%、1か2になる確率は48.58%にもなります。他方、6以上は17.72%にすぎません。
三つ以上乱数を重ねて
i = Random(Random(Random(10)))
とすると偏りはもっと激しくなります。
<方法2>
i = Min(Random(10), Random(10))
方法1とくらべて偏りは小さくなります。 上の例だと、1は19%、2は17%、以下2%づつ小さくなります。6以上は25%です。
三つ以上の乱数の最小値(または最大値)をとってもかまいません。
<方法3>
i = Int(RealRnd ^ 2 * 10) + 1
上記''(2)''の RealRnd関数を使う方法です。 累乗のパラメータは2乗に限定する必要はなく、小数でも1以下でもよいので柔軟な設定ができます。
''(5) 「カード」のシャッフル(ランダムな順列)''
カードのシャッフルや、あらかじめ決められた複数の役割りにユニットを割り振る、たくさんのアイテムを各ユニットに一つづつ配る、などの方法です。
大量のユニット、アイテムなどなどから重複無しに数個選ぶ(''ランダムな組み合わせ'')方法としても使えます。
# 52枚のカードをシャッフルします。
# ここでは連想配列「順番[カードナンバー]」で
# カードの順番を表現します。
# 順番を適当に初期化しておきます。
# 2回目以降のシャッフルでは、初期化は不要です。
Set 枚数 52
Set 順番
For i = 1 To 枚数
順番[i] = i
Next
# シャッフル
For i = 枚数 To 2 Step -1
Swap 順番[i] 順番[Random(枚数)]
Next
まず最初のループで、52枚目のカードをランダムに選ばれたカードと入れ替えます。 これでどのカードも52枚目になる確率は1/52になり、このカードは「確定」としておきます。
次のループで、51枚目のカードと入れ替える相手を、「確定」分をのぞいた残る51枚からランダムに選び、入れ替えます。どのカードも未確定である確率は51/52で同じ、どの未確定カードも51枚目になる確率は1/51で同じで、結局、どのカードも51枚目になる確率は同じです。
以下、数を減らしながらこれを繰り返します。
**Q620.マス目座標とピクセル座標との変換 [#wf46456a]
SRC では、おもに二種類の座標系が使われています。
一つは、ユニットのマップ上の位置特定などに使われ、マップ左上隅のマス目を (1, 1) としてマス目単位で数えられる座標です。
もう一つは、グラフィックなどで使われ、マップウインドウ左上隅または (BaseX, BaseY) を (0, 0) としてピクセル単位で数えられる座標です。システム変数 MouseX, MouseY もこの座標系によるものです。
この二つの座標系は、数える単位も、基準位置も違います。
これらの座標を変換するには、WX(), WY()関数を利用します。
# マップ座標 mx, my → ピクセル座標 px, py の変換
# マス目(mx, my) の左上隅の表示上のピクセル位置を求める
px = (mx - 1) * 32 + WX(1)
py = (my - 1) * 32 + WY(1)
# ピクセル座標 px, py → マップ座標 mx, my の変換
# ピクセル位置(px, py)が属しているマス目を求める
mx = Int((px - WX(1)) / 32) + 1
my = Int((py - WY(1)) / 32) + 1
# (この式は (px, py) がマップ外なら、
# マップ座標を上下左右に拡張した値を返します)
# (px, py) が必ずマップ内ならば、下の式でもかまいません。
# しかし、マップ外でマップ上方・左方のとき、答えが 1 ずれます
mx = (px - WX(1)) \ 32 + 1
my = (py - WY(1)) \ 32 + 1
「Int(変数 / 32)」 と 「変数 ¥ 32」の違いについては、[[演算子 ¥, Mod>ヘルプ補足/式#rcc6b1eb]]を参照してください。
# クリック地点のマップ座標を (ClickX, ClickY) に入れるサブルーチン
# マップ内をクリックした時 1 を返し、マップ外クリック・右クリック・
# キーボード押下の場合は 0 を返す。
# (ずっと機能拡張されたコマンドが 2008/04/08、リクエスト掲示板[2648]
# にてリクエスト中です)
ClickPoint:
Wait Click
If KeyState(1) Then
ClickX = Int((MouseX - WX(1)) / 32) + 1
ClickY = Int((MouseY - WY(1)) / 32) + 1
If ClickX > 0 And ClickX <= Info(マップ, 幅) And _
ClickY > 0 And ClickY <= Info(マップ, 高さ) Then
Return 1
# Else
# (拡張用:必要ならここにマップ外クリック時の動作)
EndIf
#ElseIf KeyState(2) Then
#(拡張用:必要ならここに右クリック時の動作
# Talk コマンドなどを行う場合、その前に Wait Click が必要です)
#Else
#(拡張用:必要ならここにキーボード押下時の動作)
EndIf
Return 0
-----
*コメント [#ia8e7067]
#comment_nospam