ERB構文講座
前編基本、変数、表示
後編分岐と反復、関数と関数呼び出し、ラベルとキー入力、その他
特別編ビット演算について
参考ERBファイルの作成や改造時によくあるミスについてのQ&A




4)分岐と反復

条件式

 分岐や反復の前に、それらの実行される基準となる条件式についてです。
比較演算子
 条件式は変数と変数、変数と数値の大小などを比較し、それが正しいかどうかを判定します。
 その比較に使われるのが比較演算子で、==, !=, <, >, <=, >= などがあります。
 == は等しい、!= は等しくない、不等号はそれぞれそのままの意味です。
 例えば、A = 0, B = 1, C = 0 のとき
真偽
A == B偽(正しくない)
A == C真(正しい)
A != C
A > B
B > C
B <= A
A >= C

 また、比較演算子を使った条件式の代わりに0かそれ以外の数字を書くことでも
 真偽を表すことができます。
 この場合、0が偽、それ以外が真です。
 (関連記事:ERB編集における代表的なエラー#!= 0は-1も含まれる
否定演算子(Emueraのみ)
  Emueraでは、比較演算子の他に否定演算子というものがあり、!(感嘆符)で表します。
  これには、直後の条件式の結果を逆転させる効果があります。上の例で言えば、
  !(A > B) は真、!(A <= C) は偽になります。
条件式の結合
 複数の条件式を使う場合は、条件式と条件式の間に && や || を記述します。
 && は「○○かつ××」に使用し、|| は「○○または××」に使用します。
 例えば、変数Aが0かつ変数Bが1という条件の場合は
A == 0 && B == 1
 となります。
 変数Aが0または変数Bが0という条件なら
A == 0 || B == 0
 となります。
 もっと複雑に、変数Aが0で変数Bが1、または変数Aが0で変数Cが1なら
(A == 0 && B == 1) || (A == 0 && C == 1) もしくは
A == 0 && (B == 1 || C == 1)
 となります。
キャラの能力や素質を判定する
 よく使われる条件式の中に、キャラの能力や素質を判断するものがあります。
 例えば、調教中のキャラが処女の時、TALENT:TARGET:0 == 1 が成立します。
 素質は持っている状態が1、持っていない状態が0となるため、
 条件式に単に TALENT:TARGET:0 と書いた場合、「調教中のキャラが処女である」
 という条件と同じ意味になります。
 逆に、TALENT:TARGET:0 == 0(あるいは !TALENT:TARGET:0)と書いた場合には、
 「調教中のキャラが処女ではない」という意味になります。
 調教中のキャラの従順がLv3以上の時は、ABL:TARGET:0 >= 3 が成立します。
 能力や刻印はLvがそのまま数値となります。
 体力や経験などレベルで表されない能力は、値がそのまま使用されます。
 調教中のキャラのV経験が10以上であるという条件を表すなら、
 EXP:TARGET:0 >= 10 となります。
ランダム
 RAND:(数値もしくは数値変数)と記述することで、一定の範囲の中から
 ランダムで数値を決定することができます。
 例えば、A = RAND:10 と記述した場合、変数Aは0から9(= 10 - 1)までの
 いずれかの整数になります。また、
A = 5
B = RAND:A
 の場合、変数Bは0から4(= A - 1 = 5 - 1)までのいずれかの整数になります。
 (関連記事:ERB編集における代表的なエラー#RANDの使い方

分岐

 ○○が××した時□□を表示する、のような処理を行うのが分岐です。
 分岐に使われる構文には IF と SIF があります。
IF - ELSEIF - ELSE - ENDIF
 もし○○ならば、という処理に最もよく使われる構文です。
IF A == 0
  PRINTFORML 変数Aは0です。
ELSEIF B == 0
  PRINTFORML 変数Aは0でなく、変数Bは0です。
ELSE
  PRINTFORML 変数Aは0でなく、変数Bも0ではありません。
ENDIF
 上が IF - ELSEIF - ELSE - ENDIF 構文の基本的な形です。上の構文は
  1. もし変数Aが0ならば(IF A == 0)、『変数Aは0です。』と表示します。
  2. 変数Aが0でなく変数Bが0ならば(ELSEIF B == 0)、『変数Aは0でなく、変数Bは0です。』と表示します。
  3. いずれの条件にも当てはまらないならば(ELSE)、『変数Aは0でなく、変数Bも0ではありません。』と表示します。
 このように一つの IF - ENDIF 間では上から順に条件式を判定していき、
 条件の成立した部分の直後の処理のみを行います。
 上の例文では処理の部分が1行ずつしかありませんが、実際には
 次の ELSEIF, ELSE, ENDIF までの処理が全て行われます。
IF 条件式1
  処理1
  処理2
  処理3
ELSEIF 条件式2
  処理4
  処理5
ELSE
  処理6
ENDIF
(条件式1が成立の時は処理1〜3、条件式1が不成立で条件式2が成立の時は
 処理4と5、どちらも不成立の時は処理6のみが行われる)

 判定したい条件が3つ以上ある場合は、ELSEIF を増やしていくことができます。
IF A == 0
  PRINTFORML 変数Aは0です。
ELSEIF B == 0
  PRINTFORML 変数Aは0でなく、変数Bは0です。
ELSEIF C == 0
  PRINTFORML 変数A、Bは0でなく、変数Cは0です。
ELSE
  PRINTFORML 変数A、B、Cはいずれも0ではありません。
ENDIF
 判定したい条件が1つの場合は、ELSEIF 以下の部分はなくても構いません。
IF A == 0
  PRINTFORML 変数Aは0です。
ELSE
  PRINTFORML 変数Aは0ではありません。
ENDIF
 条件を満たさない時何もしない場合、ELSE 以下の部分はなくても構いません。
IF A == 0
  PRINTFORML 変数Aは0です。
ELSEIF B == 0
  PRINTFORML 変数Aは0でなく、変数Bは0です。
ENDIF
 IF と ENDIF は絶対に必要です。
 ENDIF の書き忘れはエラーの原因になりますので注意しましょう。
 (関連記事:ERB編集における代表的なエラー#ELSEIF を ELSE としてしまう/ ELSE IF としてしまう
 (関連記事:ERB編集における代表的なエラー#お前はもう死んでいる分岐
SIF
 上の IF - ENDIF を簡略化したのがSIFになります。
SIF A == 0
  PRINTFORML 変数Aは0です。
 SIF には ENDIF が必要ない、ELSEIF や ELSE が使用できない、
 直後の1行しか実行できない、などの特徴があります。例えば
SIF 条件式
  処理1
  処理2
 と記述すると、条件式の真偽に関わらず処理2は実行されてしまうので
 注意しましょう。
 2つ以上の処理を行う時は上の IF - ELSEIF - ELSE - ENDIF を使いましょう。
 (関連記事:ERB編集における代表的なエラー#SIF文に複数の行を収めようとしてしまう

 また、eramakerでは
SIF 条件式
  ;コメント
  処理1
 のように、SIF の直後にコメント行を入れると、必ず処理1が実行されてしまいますので、これも注意が必要です。
 (Emueraではコメント行がきちんと無視されるので、条件式が真であるときのみ処理1が実行されます。)
 (関連記事:ERB編集における代表的なエラー#SIFの直後にコメントを置くのは危険

・IF と SIF の組み合わせ
IF 条件式1
  SIF 条件式2
    処理1
  処理2
  処理3
ENDIF
 と記述すると、条件式1と条件式2の両方が真である場合は処理1から3を全て実行し、
 条件式2だけが成立する時は処理2と3のみを実行します。
SIF 条件式1
  IF 条件式2
    処理1
    処理2
  ENDIF
 逆にこう記述すると、条件式1が成立しない時にエラーが発生します。
 (条件式1が偽の場合は「IF 条件式2」の行だけを読み飛ばすので、「ENDIF が変な場所にある!」というエラーになる)
 SIF の直後の行に IF や SIF などの分岐や反復を行う文は書かないようにしましょう。
SELECTCASE - CASE - CASEELSE - ENDSELECT(Emueraのみ)
 IF 文と似た機能を持つ構文として SELECTCASE - CASE - CASEELSE - ENDSELECT があります。
 1つの数値変数の値によって処理を分岐させる時に使います。
 例えば乱数によって処理を分岐させる時に便利な構文です。
SELECTCASE A
  CASE 0
    PRINTFORML 変数Aは0です。
  CASE 1
    PRINTFORML 変数Aは1です。
  CASEELSE
    PRINTFORML 変数Aは0でも1でもありません。
ENDSELECT
 これは、次の IF 文と同じ意味を持ちます。
IF A == 0
  PRINTFORML 変数Aは0です。
ELSEIF A == 1
  PRINTFORML 変数Aは1です。
ELSE
  PRINTFORML 変数Aは0でも1でもありません。
ENDIF
 SELECTCASE 文は、CASE の後ろに書かれた数値が SELECTCASE の直後に書かれた数値変数(この場合は A)と等しいかどうかを判定して分岐します。
 CASE については次のような書き方をすることもできます。
SELECTCASE A
  CASE 1, 2, 3
    PRINTFORML 変数Aは1、2、3のいずれかです。
  CASE 4 TO 9
    PRINTFORML 変数Aは4以上9以下です。
  CASE IS >= 50
    PRINTFORML 変数Aは50以上です。
  CASE 10 TO 20, IS >= 40
    PRINTFORML 変数Aは50以上ではありません。
    PRINTFORML 変数Aは10以上20以下、あるいは40以上(かつ49以下)です。
  CASEELSE
    PRINTFORML 変数Aは0以下(上の条件のいずれも満たさない)です。
ENDSELECT
 CASE X TO Y は、数値変数が X 以上 Y 以下の場合に真となります。
 CASE IS >= X は、数値変数が X 以上の場合に真となります。
 また、CASE に書く条件は、カンマで区切って複数指定することができます。
 よってこの SELECTCASE 文は、次の IF 文と同じ意味を持ちます。
IF A == 1 || A == 2 || A == 3
  PRINTFORML 変数Aは1、2、3のいずれかです。
ELSEIF A >= 4 && A <= 9
  PRINTFORML 変数Aは4以上9以下です。
ELSEIF A >= 50
  PRINTFORML 変数Aは50以上です。
ELSEIF (A >= 10 && A <= 20) || A >= 40
  PRINTFORML 変数Aは50以上ではありません。
  PRINTFORML 変数Aは10以上20以下、あるいは40以上(かつ49以下)です。
ELSE
  PRINTFORML 変数Aは0以下(上の条件のいずれも満たさない)です。
ENDIF
 (関連記事:Emueraについての補足#IFを使うべきかSELECTCASEを使うべきか
三項演算子(Emueraのみ)
 三項演算子は、正確に言えば分岐構文ではありませんが、IF 文から派生してできた演算子なので、ここで説明します。
 三項演算子は、次のような形を取ります。
<代入先変数> = <条件式> ? <真の場合の代入値> # <偽の場合の代入値>
 例えば、変数 A が3以上の時に1、そうでない場合に0を変数 B に代入する操作は、IF 文を使うと次のようになります。
IF A >= 3
  B = 1
ELSE
  B = 0
ENDIF
 これを三項演算子で表現すると、次のように1行で書けます。
B = A >= 3 ? 1 # 0
 三項演算子は文字列変数に対しても使用できます。文字列を扱う場合は、三項演算子を ¥@ 〜 ¥@ で囲みます。
PRINTFORML %CALLNAME:TARGET%は\@ TALENT:0 ? 処女です。 # 処女ではありません。 \@
 上の文は、TALENT:TARGET:0 が0以外の時に『(TARGETの呼び名)は処女です。』と出力し、
 TALENT:TARGET:0 が0の時に『(TARGETの呼び名)は処女ではありません。』と出力します。

SELECTCASEとの組み合わせ

反復

 同じ処理を複数回繰り返すときに使うのが反復です。
REPEAT - REND
REPEAT 数式
  処理
REND
 REPEAT - REND 間の処理を繰り返し実行します。
 繰り返す回数はREPEATの直後にある数値、または数値変数に代入されている値です。A + 1 などの数式を置くこともできます。
 例えば、
REPEAT 10
  PRINTFORML あ
REND
 と記述すると、『あ』が10行表示されます。

・COUNT
 変数 COUNT は、現在までに何回繰り返しを行ったかを格納しています。
 REPEAT - REND 内の処理を最初に行う時はまだ1回目の繰り返しの途中(1回目の繰り返しが完了していない)なので
REPEAT 10
  PRINTFORML 現在{COUNT}回目です。
REND
 こう記述した場合、表示されるのは0回目から9回目となります。
 COUNT がとる値は 0 から REPEAT の直後の数値 - 1 までと覚えておきましょう。
 また、COUNTに数値を代入するのはエラーの原因となるので注意しましょう。
 (関連記事:ERB編集における代表的なエラー#REPEATループに注意

・REPEAT と IF, SIF の組み合わせ
 REPEAT - REND の間にも IF や SIF を使用することができます。
REPEAT 10
  IF COUNT == 5
    PRINTFORML 6回目です?
  ELSE
    PRINTFORML {COUNT + 1}回目です
  ENDIF
REND
 と記述すると、COUNTが5、つまり6回目のみ最後に?が表示されます。
 また、REPEAT - REND の間にもう一つ REPEAT - REND を使用する(入れ子にする)ことは
 可能ですが、COUNT の値が2つ目の REPEAT - REND によって変更されてしまうため
 そのままでは正常に動作しません。
 REPEAT - REND を入れ子にしたい場合は、内側の REPEAT - REND の前後に COUNT の値を
 退避・返還する処理を行うなどの工夫をするか、
 (Emueraを使う場合は)後で説明する FOR - NEXT で代用する必要があります。
;REPEAT を入れ子にする例
REPEAT 10
  COUNT:1 = COUNT
  REPEAT 10
    処理
  REND
  COUNT = COUNT:1
REND
 (関連記事:ERB編集における代表的なエラー#二重REPEAT文

・CONTINUE と BREAK
 REPEAT - REND 間で、以降の処理を行わずに次の繰り返しに入る場合には CONTINUE を、
 以降の処理を行わず、繰り返し自体を終了させる場合には BREAK を使用します。
REPEAT 10
  A = COUNT
  IF A == 5
    CONTINUE
  ENDIF
  PRINTFORM {A}:
REND
 これを実行すると、COUNT が5の時に CONTINUE が実行されるので、実際に表示されるのは
0:1:2:3:4:6:7:8:9:
 となります。また、
REPEAT 10
  A = COUNT
  IF A == 5
    BREAK
  ENDIF
  PRINTFORM {A}:
REND
 を実行すると、COUNT が5の時に BREAK が実行され REPEAT - REND から抜けるので、実際に表示されるのは
0:1:2:3:4:
 までになります。
FOR - NEXT(Emueraのみ)
FOR <カウンタ数値変数>, <数式>, <数式>[, <数式>]
  処理
NEXT
 REPEAT - REND の機能強化版が FOR - NEXT です。
 例えば、次の2つのスクリプトは全く同じ動作をします。
FOR COUNT, 0, 10
  PRINTFORML {COUNT}回目
NEXT
REPEAT 10
  PRINTFORML {COUNT}回目
REND
 FOR の直後の<カウンタ数値変数>は REPEAT でいう COUNT に相当します。
 REPEAT では繰り返しの回数を数える変数は COUNT に固定されていましたが、FOR ではこの変数を好きな変数に設定することができます。
 カウンタ変数を別にすることで、REPEAT では面倒だったループの入れ子を簡単に実現できます。
;入れ子の例
FOR A, 0, 10
  FOR B, 0, 10
    処理
  NEXT
NEXT
 FOR の後ろに来る2番目の<数式>は、繰り返しを始める<カウンタ数値変数>の値を設定します。
 3番目の<数式>で、繰り返しを終わる<カウンタ数値変数>の値を指定します。
 例えば、
FOR COUNT, 3, 8
  PRINTFORM {COUNT}:
NEXT
 を実行すると、
3:4:5:6:7:
と表示されます。
 FOR の後ろの4番目の<数式>は、ループを1回繰り返すごとにカウンタ変数に加算される値を設定できます。省略すると自動的に1が設定されます。
 例えば、
FOR COUNT, 0, 10, 2
  PRINTFORM {COUNT}:
NEXT
 を実行すると、
0:2:4:6:8:
 と表示されます。
 なお、REPEAT - REND と同様に CONTINUE と BREAK も使用できます。
WHILE - WEND(Emueraのみ)
WHILE 条件式
  処理
WEND
 条件式が真である間、ループを繰り返します。
 例えば、次のスクリプトは「あ」を10行表示します。
A = 0
WHILE A < 10
  PRINTFORML あ
  A += 1
WEND
 このとき、「A += 1」の行を書き忘れると、変数Aの値は0のままになってしまうので、
 A < 10 はいつまでも真のままとなり、無限ループに陥ってしまいますので注意が必要です。
 WHILE - WEND でも CONTINUE と BREAK を使用できます。
DO - LOOP(Emueraのみ)
DO
  処理
LOOP 条件式
 条件式が真である間、ループを繰り返します。
 WHILE - WEND との見た目の違いは条件式の位置が違う程度ですが、最初の繰り返しが必ず実行されるという特徴があります。
 次の2つのスクリプトを見比べてみてください。
A = 0
WHILE A < 0
  PRINTFORML あ
WEND
A = 0
DO
  PRINTFORML あ
LOOP A < 0
 WHILE 文はループの最初に条件式が真かどうか評価するので、この場合は PRINTFORML は一度も実行されません。
 一方 DO - LOOP はループの最後に条件式を評価するので、この例では PRINTFORML が1回実行され、その後に式が評価されてループを抜けます。
 (関連記事:Emueraについての補足#DO〜LOOP命令

 また、DO - LOOP 内で CONTINUE 文を呼ぶと、DO ではなく LOOP に飛ぶことにも注意してください。
 次のスクリプトは(DO → CONTINUE → DO ではなく)DO → CONTINUE → LOOP 0 の順に実行されるので、無限ループにはなりません。
DO
  CONTINUE
LOOP 0
 (関連記事:Emueraについての補足#CONTINUEの処理に関して


5)関数と関数呼び出し

ここからは主に機能パッチやバリアントを作成する際に使う範囲となります。

関数とは

 いくつかの決まった処理を行わせたい時、それを予め別の場所に記述しておいて、
 任意の場所から使えるようにしたものを関数と言います。
 例として、変数Aの値を10倍にする関数を作ってみましょう。
@A_TEN_TIMES
A = A * 10
 @の後に半角英数と_(アンダーバー)で関数の名前を付けることができます。
 それ以降の処理が関数で行う内容となります。
A = 0
CALL A_TEN_TIMES
PRINTFORML 変数Aは{A}です。

A = 5
CALL A_TEN_TIMES
PRINTFORML 変数Aは{A}です。
 作った関数を利用する(呼び出す)には CALL <関数名> と記述します。
 この結果、上は『変数Aは0です。』下は『変数Aは50です。』と表示されます。
 また、関数を呼び出すのに JUMP <関数名> を使うこともあります。
 CALL と JUMP の違いは関数での処理を実行した後、元の場所に戻るかどうかで、
 CALL は戻る、JUMP は戻らないようになっています。

 なお、同じ名前の関数が複数ある時はどれか1つだけが呼び出されます(イベント関数という特殊な関数を除く)。
 関数の名前は他と同じにならないよう注意しましょう。
 (関連記事:ERB編集における代表的なエラー#(関数が)かぶった!?

RETURN と戻り値

 ある条件を満たした時、関数を途中で終わらせたいという場合は
 RETURN <数値> と記述します。
@TEST
SIF A == 0
  RETURN 0
A = A * 5
 この場合、関数TESTを呼び出した時 A が0なら何も行われず、そうでなければ A が5倍されます。
 また、RETURN 文で関数を終了し元の場所に戻ってくると、変数 RESULT が RETURN で指定された数値に書き変えられます。
 この時、RESULT を関数の戻り値(返り値)といいます。
 例えば、
@TEST2
IF A == 0
  RETURN 0
ELSEIF A == 1
  RETURN 1
ELSEIF A == 2
  RETURN 2
ELSE
  RETURN 9
ENDIF
 という関数を作り、別の場所から呼び出すと
A = 0
CALL TEST2
PRINTFORML {RESULT}

A = 2
CALL TEST2
PRINTFORML {RESULT}

A = 3
CALL TEST2
PRINTFORML {RESULT}
 上から順に0, 2, 9が表示されます。
 なおEmueraでは、RETURN 文に数値変数や数式を指定できるほか、カンマで区切って複数の戻り値を指定することもできます。

引数(Emueraのみ)

 Emueraでは、関数は引数を取ることができます。引数とは、関数を CALL で呼び出す時に関数に渡すことのできる変数です。
 上に書いた関数 @TEST2 を、引数を取るように書き換えたのが次の例文です。
@TEST2, ARG
IF ARG == 0
  RETURN 0
ELSEIF ARG == 1
  RETURN 1
ELSEIF ARG == 2
  RETURN 2
ELSE
  RETURN 9
ENDIF
 呼び出すときは次のようにします。
CALL TEST2, 0
PRINTFORML {RESULT}

CALL TEST2, 2
PRINTFORML {RESULT}

CALL TEST2, 3
PRINTFORML {RESULT}
 CALL TEST2, 0 を実行すると、ARG に0が代入され、関数内で ARG を参照することができます。
 引数は複数取ることができ、そのような場合は ARG, ARG:1, ARG:2, …のように定義します。
@TEST3, ARG, ARG:1, ARG:2
(略)
CALL TEST3, 0, 7, 3
 引数には文字列変数も取ることができ、その場合は ARGS を使います。

ローカル変数(Emueraのみ)

 A, B などの一文字変数や COUNT など多くの変数は、プログラム全体で同時に一つの変数を共通で使用します。
 ですが、それが原因でバグが発生することがあります。
@MAIN
FOR COUNT, 0, 10
  CALL FUNC
NEXT

@FUNC
FOR COUNT, 0, 3
  (何か処理)
NEXT
 上の例文で MAIN 関数を実行すると、FUNC が呼ばれるたびに COUNT が3にセットされるので、無限ループに陥ります。
 この例では FUNC 内の FOR ループのカウンタ変数を COUNT:1 にすれば問題は解決しますが、
 1つのバリアント内で使われる関数は1000個を軽く超えるので、どこかで必ずこういった問題が発生します。

 そこで、ある関数の中でしか使えない変数(ローカル変数)を用意すれば、この問題は解決するはずです。
 そのローカル変数が LOCAL と LOCALS です。次の例を見てください。
@EVENTFIRST
  LOCAL = 123
  CALL FUNC001
  PRINTFORML {LOCAL}

@FUNC001
  LOCAL = 567
  RETURN
 一見すると LOCAL という同じ変数に数値を代入しているように見えますが、
 「EVENTFIRST の中で使っている LOCAL」と「FUNC001 の中で使っている LOCAL」は別物として扱われるので、
 PRINTFORML 文の結果は「123」と出力されます。

 なお、LOCALS は LOCAL の文字列変数バージョンです。
 先に説明した ARG と ARGS もローカル変数として扱われます。
LOCAL, ARG の初期化タイミングに注意
 他の言語でプログラミングをしたことのある人には特に注意して頂きたいのですが、
 ・LOCAL や ARG は関数が呼び出されたタイミングで初期化されない
 ・関数が呼び出されるたびに同じ LOCAL, ARG を使いまわす
 の2点に気をつける必要があります。
 この特徴は、関数の再帰などを利用した場合に注意が必要です。
@SAMPLE
LOCAL += 1
IF LOCAL < 10
  CALL SAMPLE
ENDIF
 上のコードは、プログラミング経験のある人からしてみれば
 「LOCAL はローカル変数で呼び出し時に0に初期化されるので、LOCAL は1のままで無限ループになり、そのうちスタックが溢れるはず」
 と思われるかもしれません。しかし実際に SAMPLE を呼び出すと、
 最初の外部からの呼び出しでは SAMPLE が9回再帰呼び出しされ、2回目以降は再帰呼び出しがされません
 なぜかといえば、最初の呼び出しで LOCAL に1が代入されると、次に再帰で呼び出された時に LOCAL が0で初期化されず、1という値が保持されるからです。
 また再帰が完了して SAMPLE 関数から抜けた後も、LOCAL の最終的な値である10が保持され続けるので、これ以降は外部から呼び出されても再帰はされません。

 ARG についても同様です。
@SAMPLE2, ARG
SIF ARG >= 10
  RETURN
CALL SAMPLE2, ARG + 1
PRINTVL ARG
 上のコードを書き、CALL SAMPLE2, 0 と呼び出すと10が10回表示されます

プログラマ向けの話

 (関連記事:Emueraについての補足#LOCAL変数であっても避けるべきこと

式中で使える関数(Emueraのみ)

 erabasicにおいて、値を返す命令の戻り値は RESULT を経由して受け取ります。
 例えば、与えられた数式の絶対値を返す ABS という命令を使って、
 変数A の絶対値を LOCAL に格納するには次のように記述します。
ABS A
LOCAL = RESULT
 これに対し、ABS という名前の「式中で使える関数(以下「式中関数」と書きます)」を使うと、上のスクリプトを次のように書くことができます。
LOCAL = ABS(A)
 「式中関数」の名前通り、代入式の中から直接関数を呼び出し、RESULT を介さずに戻り値を LOCAL に代入することができます。
 式中関数では、引数を (A) のように丸括弧で囲んで呼び出します。
 引数が複数ある場合は (A, B, C) のように丸括弧の中でカンマで区切って書きます。
 逆に引数がない場合は () と丸括弧だけを書きます。引数がなくても丸括弧は省略できません。

 文字列を返す命令でも、同様の書き方ができます。
STRLENS STR:0
IF RESULT > A
  SUBSTRING STR:0, A, 1
  LOCALS:0 = %RESULTS:0%
ENDIF
IF STRLENS(STR:0) > A
  LOCALS:0 = %SUBSTRING(STR:0, A, 1)%
ENDIF
 上の2つの例文は、同じ動作をします。
 式中関数の一覧はEmuera Wikiで確認できます。
式中関数を自分で定義する
 式中関数は自分で定義することができます。
 関数を定義する @ 行の直後に #FUNCTION と書き、RETURN を RETURNF に置換するだけで、その関数は式中関数になります。
;下の行は @TEST2, ARG と書いてもよいが、慣習的にこう書くことが多い
@TEST2(ARG)
#FUNCTION
IF ARG == 0
  RETURNF 0
ELSEIF ARG == 1
  RETURNF 1
ELSEIF ARG == 2
  RETURNF 2
ELSE
  RETURNF 9
ENDIF
 呼び出すときは次のようにします。
PRINTFORML {TEST2(0)}
PRINTFORML {TEST2(2)}
PRINTFORML {TEST2(3)}
 文字列を返す式中関数を作りたい場合は、#FUNCTIONS と書きます。
 ただし、RETURNF の書き方が他の命令(PRINTFORM など)とは異なるので注意してください。
 (関連記事:Emueraについての補足#文字列とRETURNFに関する面妖な仕様


6)ラベルとキー入力

主に選択肢による分岐で使用されるのがラベルとキー入力です。
PRINTFORML 選択してください
PRINTFORML [0] 選択肢1
PRINTFORML [1] 選択肢2
;Emueraは上のような[ ]で囲まれた数字を見つけると自動的にボタンに変換してくれます

$INPUT_LOOP
INPUT

IF RESULT != 0 && RESULT != 1
  GOTO INPUT_LOOP
ELSEIF RESULT == 0
  処理1
ELSEIF RESULT == 1
  処理2
ENDIF
INPUT はキー入力(またはボタン操作)を待ち、入力された数値を RESULT に格納します。
この場合、0を入力すれば処理1、1を入力すれば処理2を実行します。
0でも1でもない数値を入力した場合、RESULT != 0 && RESULT != 1 が
成立するため GOTO INPUT_LOOP が実行されます。
GOTO (ラベル名)は $(ラベル名)の処理に移動するもので、CALL や JUMP と @ との
関係に似ていますが、GOTO と $ に関しては同じ関数内にある必要があります。
GOTO INPUT_LOOP で $INPUT_LOOP に移動すると再び INPUT を実行するため、
この一連の処理は0か1かを入力するまで繰り返されることになります。

また、一つの関数内で複数の $ と GOTO の組み合わせを使用すると
『IF に対応しない ELSEIF, ELSE, ENDIF が〜』というエラーが発生することがあります。
この場合、2つ目の入力処理を別の関数に移すなどの工夫をしましょう。
 (関連記事:ERB編集における代表的なエラー#GOTOで飛ぶと自分がいた場所を忘れます。
 (関連記事:ERB編集における代表的なエラー#同じGOTOラベル名は使わない。(INPUT_LOOPに関するバグ)


7)その他注意点など

キャラの追加と削除

 キャラの追加と削除には、ADDCHARA と DELCHARA を使用します。
ADDCHARA 1
ADDCHARA 5
ADDCHARA 9
 Emueraでは次のように書くことができます。
ADDCHARA 1, 5, 9
 ADDCHARAではCSVにあるキャラ番号が参照されます。
DELCHARA 3
DELCHARA 1
 DELCHARAではキャラ番号ではなく、キャラの登録番号が参照されます。
 ここまでの処理でキャラ番号1、5、9のキャラが追加され、
 次に登録番号3番、つまりキャラ番号9のキャラが削除、
 その後登録番号1番、つまりキャラ番号1番のキャラが削除され、
 キャラ番号5番のキャラのみが残る状態になります。
 DELCHARAを続けて使用する際には、削除された登録番号より後のキャラは
 それぞれ前に詰められることに注意しましょう。

 また、キャラの追加・削除をする場合は調教中のキャラ、助手などの状態を
 確認しましょう。例えば助手をやっていたキャラがDELCHARAで削除されても
 助手の登録番号を保存しているASSIは変化しません。しかし全体の登録番号は
 前にずれてしまうため、助手になる条件を満たしていないキャラが助手に
 なってしまうこともあります。

グラフ表示

 BAR(BARL)を使用することで数値の表示を視覚的に行うことができます。
 BAR (数値or変数),(数値or変数),(グラフの長さ)のように記述し
A = 80
B = 100
BAR A, B, 10
 では
[********..]
 と表示されます。
 Aに現在の値、Bにその最大値を入れることで、現在の値が最大値の
 どのくらいの割合かを示す際によく使用されます。
 BARLでは表示後に改行されることも覚えておきましょう。

小数の乗算

 era basicでは変数などは全て整数で処理されますが、例外として
 TIMESを使用することで小数の計算を行うことができます。
A = 1000
TIMES A, 1.5
 これで変数Aは1000×1.5の1500となります。
 なお、TIMESを使用した結果が小数になっても整数に丸められます。

その他の命令

 WAIT…入力待ちのみを行います。RESULTに値は格納されません。
 QUIT…eramakerを終了させます。主にゲームオーバー時などに使用します。



特別編へ進む

Menu

メニュー

過去スレ


初めて遊ぶ時、
何か困った時や
わからない時は
まず下を読んでください


本体・パッチ関連






リンク

スレッド

各スレッドは、こちらを読んでから書き込むことをおすすめします。
eratohoスレ(era板 避難所)
【調教SLG】eratoho総合スレ【戦闘経験307】

避難所スレ(したらばのちゅっちゅ板)
eratoho避難所スレ

eraシリーズ総合スレ(2chのエロ同人板)
【調教SLG】eraシリーズを語るスレ24【サークル獏】


【スレッド編集】

どなたでも編集できます