更新 2006-05-14
フリーウェアSLG『ファーレントゥーガ』の著作権は作者あとあと様に帰属します。
『ファーレントゥーガ』のHP : ふぁらんくす
ESSにおけるマクロとは、
EventScriptの作成を支援する事を目的としたESS独自のスクリプトです。
ESSは独自のマクロ文とファーレントゥーガのEventScript文を組み合わせて記述された
スクリプトを解読し、ファーレントゥーガ本体で実行可能な
EventScript形式に変換する機能を持っています。
マクロを利用してEventScript製作者にとって保守し易い形式で記述を行い、 ESSで展開したスクリプトを本体向けのEventScriptファイルとして使う という使い方を想定しています。
例:左がマクロを含んだ文、右がマクロを展開した後のスクリプト
関連:マクロ関数 #PATH
マクロを使い、マクロ展開時に外部ファイルを読み込む事ができます。
#INCLUDE "(読込みたいファイルへのパス)"
パスは必ず""で囲むようにしてください。
※それ以外の文字列(マクロ含む)では構文エラーとなります。
この文を記述すると、マクロを展開する際に指定したファイルの内容に置き換わり出力されます。
【使用例】
こちらが読み込まれる側のスクリプトです。
メッセージラベルというマクロを使用しています。
#INCLUDE文で上のスクリプトを読み込もうとしています。
上のスクリプトを展開した結果。
インクルードしたスクリプトにマクロがあれば
そのマクロも展開されて出力されます。
ここでいう「フラグ」とは、 ファーレントゥーガのイベントスクリプトにおける変数 Flag[n]とLeague[m][n]の事です。
これら変数は配列のように番号で指定する必要がありますが、 あるイベントを起こす為のフラグが何番だったか、 まだ未使用のフラグの番号は何番だったか、 わからなくなる場合があります。
このような問題を減らす為のアプローチとして、 未使用の番号の変数を自動で払い出し、名前をつけ、 再び同じ名前で呼び出されたら同じ番号のフラグを返す機能を追加しました。
$(名前)
$$(名前)
先頭に"$"とつけた場合はFlagを、
"$$"を付けた場合はLeague変数を出力します。
"$"と"$$"で別の名前空間を持ちますので、名前が同じでも別々に扱われます。
未登録の名前である場合は新しい番号のフラグとして新規に登録され、出力されます。
登録済みの名前である場合は、登録した番号のフラグを出力します。
また、どちらの変数も使用可能な数に限りがあります。
今後、フラグが限界に達した場合の制御等を実装の予定です。
【使用例】
新しい名前のフラグを作り、それを後でもう一度呼び出そうとしています。
展開した結果です。二度呼び出された名前の所に、同じ番号のフラグが置き換えられています。
FTのイベントスクリプトを自作する際、
一般的には会話イベントがその大半を占めます。
会話イベントのスクリプトは比較的単純ですが、
内容の割に記述するスクリプトの量が多いです。
それに伴い全体の作業量も肥大化しています。
メッセージラベル構文はこのような作業負荷を
少しでも軽減しようという意図のもと実装されたマクロです。
打ち方は以下の通りになります。
(%ID):{
"メッセージ"とそれ以外のスクリプト
}
":"を使うと画面上部(Window 0)のウィンドウを表示します。
"::"を使うと画面下部(Window 1)のウィンドウを表示するスクリプトに変換されます。
メッセージラベルのキーワードはコロン(":"または"::")です。
":"の後に続くブロックの中に単独で存在する文字列や変数を"メッセージ"とみなし
":"の前にある変数をIDとするキャラのConversationとして出力するスクリプトに変換されます。
":"の前のIDを省略する、もしくは空文字(""等)にすると Conversationではなく、プレーンなウィンドウを使った メッセージを出力するスクリプトに変換されます。
":"の後は"{}"で囲んだブロック構文を記述しなければいけません。
例外として、ラベルの本文にスクリプトが無く
"メッセージ"だけを記述する場合はブロック構文でなくても認識できます。
よって、以下の形式での打ち方も可能です。
(%ID):"メッセージ"
【注意:メッセージラベルの欠点】
メッセージラベルを使うと、PrintやWindowOnの記述をほとんど省略できます。
しかし、メッセージラベルはその言語仕様の為に
「最後の"WindowOff"を自動出力できない」
ので、記述しないといけないという事を覚えておいてください。
これは、メッセージラベルが自分が"最後"かどうかを認識できないのが理由です。
メッセージラベルにメッセージ出力の中断、終了を認識させる手段として、
セミコロン";"または#END_MESSAGE()が用意されています。
このように、メッセージラベルは実装が複雑な分融通の利かない所があります。
【使用例】
基本的なメッセージラベルの書き方です。
メッセージラベルの中に、メッセージとスクリプトを混在させる事ができます。
上のメッセージラベルを展開した結果です。
簡単な制御であれば、改行、改ページを含めて自動で処理してくれます。
ただし、最後のWindowOffだけは自動では出力しませんので注意してください。
メッセージラベルの記述に"::"を使うと、そのメッセージはWindow 1を利用して出力されます。
メッセージラベルは上下のウィンドウを個別に管理することができます。
上のメッセージラベルを展開した結果です。
Window 0とWindow 1の切り替えが行われています。
メッセージラベルの内容がメッセージだけであれば、
さらに省略された以下のような記述が可能です。
上のメッセージラベルを展開した結果です。
マクロの中だけで宣言・代入の可能な変数を使用できます。
打ち方は以下の通りです。
@(変数名)
一般的な変数のような形式で、代入したり、使用したりする事ができます。
マクロ変数のスコープはグローバルです。
一度宣言したら、以降はマクロ内のあらゆる場所で使用できます。
後述のテンプレートと組み合わせる事で、思わぬ上書きが発生する事もありますので気をつけてください。
マクロ変数は、文法上は「文字列」に位置付けられますが、その型は曖昧です。
抽象的な存在なので通常の文法では問題とされる部分も、
マクロ変数に置き換えると問題無く処理される場合があります。
また、その逆もありえます。
※例えば、あるマクロ変数の内容が「Flag[n]」であっても、それは"Flag型の値"としては扱われない事に注意してください。
【使用例】
マクロ変数の使用例です。
マクロ変数を宣言し、別の値を代入し、利用します。
ちなみに文字列は演算子"+"で連結できます。
上のマクロを展開した結果です。
マクロ変数が代入した値に置き換えられています。
イベントスクリプトでシステム的な制御を行う場合に、
ごく一部が異なるだけで、同じようなスクリプトを何度も繰り返し記述する事があります。
テンプレートはそのような場合の作業を省力化する事を目的としています。
テンプレートの定義は以下のように記述します。
#TEMPLATE #テンプレート名(@引数1,@引数2...){
(本文)
}
引数はマクロ変数の形式でなければいけません。
テンプレートの引数として定義したマクロ変数はローカル変数です。
その値は呼び出す際に初めて定義され、テンプレートの内部でのみ使用できます。
同じ名前のグローバル変数があっても、
テンプレートの中ではローカル変数が優先されます。
テンプレートを呼び出す場合は以下の通りです。
#テンプレート名(引数1,引数2...)
テンプレート名、引数の数が同じでないとエラーとなります。
逆に、テンプレートの名前が同じでも、
引数が異なれば別のテンプレートとして定義できます。
テンプレートは#INCLUDEする外部ファイルに定義しても有効です。
注意点として、テンプレートはスクリプトの読み込まれる順番に依存します。
つまり、必ず呼び出す前に定義しないといけません。
【使用例】
テンプレートの使用例です。
定型的なメッセージラベルをテンプレートとして定義し、
下の本文で呼び出しています。
上のマクロを展開した結果です。
テンプレートを呼び出していた部分が、テンプレートの内容に置き換えられています。
ESS内部で定義されたマクロ関数を使用し、
マクロの動きを制御する事ができます。
書式は以下の通りです。(テンプレートを呼び出す時と同じです。)
#関数名((引数1),(引数2)...)
以下、各マクロ関数の機能について説明します。
引数には""で囲んだディレクトリへのフルパスを指定します。
引数に指定したパスを、
この関数以降で#INCLUDEするファイルの基準パスとする事ができます。
#INCLUDE側では、この関数で指定したパスの相対パスを記述する事ができます。
メッセージウィンドウのサイズ、表示時間を変更します。
#MSGSET(表示時間,ウィンドウ幅,ウインドウ高さ,ウィンドウ位置)
2番目以降の引数は省略できます。
現在、4番目の引数は指定しても動作しません。
ウィンドウ位置はメッセージラベルでより簡単に指定できるようになったからで、
この機能を残しておくと逆に問題の原因となるからです。
ウィンドウのサイズは通常メッセージの場合のみ適用されます。
ウィンドウの幅、高さに数値以外の値を設定するとエラーとなります。 これは数値以外の値を許してしまうと自動改行・改ページ機能の実装に支障が出るからです。
例:#MSGSETの使用
引数は必要ありません。
メッセージラベルによるメッセージ制御の終了を宣言します。
まず、まだ出力しようとしているメッセージに対する
WindowOnが行われていない場合はWindowOnを出力します。
その後、WindowOnをしている場合はWindowOffを出力します。
メッセージ出力が行われていない場合、 既に終了している場合は何もしません。
また、セミコロン";"もこのマクロと同様の動作をします。