# 局地戦略イベント記述用スクリプト Lua版

Luaによるイベントスクリプトの仕様です。 スクリプトファイルの名前が *.lua ならLuaスクリプトとして動作し、それ以外(*.c|*.txt)は旧版スクリプトとして動作します。 Lua版イベントスクリプトと旧版イベントスクリプトは全く別のスクリプトエンジンで動作するため、混在させることはできません。

Luaの方が扱いやすいのでこちらが主流になるかもしれません。 Luaの文法についてはGoogleで"Lua"を検索してください。

情報取得系の関数は、思考ルーチンと同じ物が使えます。それらはここでは解説しません。 ただしks_set_attack(),ks_set_unload(),ks_set_create()は思考ルーチンで呼び出されることが前提になっているので、 イベントでは使用できるタイミングが限られるかもしれません（動作未確認）。

思考ルーチンと同じく関数には戻り値があるものがありますが、引数が間違っているなどの致命的なエラーの場合、戻り値はなし(nil)となります.

関数のネーミング方法が思考ルーチン系のAPIと異なります。 これは、当初別々の言語で実装されたものを後からLuaで統一したための単純ミスです。 また関数の名前やインターフェースは旧版と同じものもありますが、全く違うものも少なくありません。 これは本体プログラムをオブジェクト指向できちんと書き直したなど、内部仕様の変更によるものです。 旧版スクリプトは旧版スクリプトで従来通り動作するはずです。

require
標準で用意されているスクリプトファイル
標準で用意されている関数
  デバッグのための設定
  イベントドリブン
  イベントウィンドウ
  ゲームの状況を得る
  ユニットを設置する／削除する／状態を変更する
  地形の情報を得る／設定する
  陣営の情報を得る／設定する
  陣営同士の関係を得る／設定する
  変数の保存

## require

他のスクリプトファイルをロードして実行します。一度ロードして実行されたファイルは、二回目のrequireではロードされません。 require されるスクリプトファイルは、まずマップと同じフォルダから探され、 見つからなければ 局地戦略インストールフォルダ\System\Lua が探されます。

## 標準で用意されているスクリプトファイル

com_*.lua
頭にcom_が付いているスクリプトファイルは思考ルーチン用ですが、イベントスクリプトで使うこともできます。 イベントで役に立つものがあるかどうかは疑問ですが。

event_api.lua
スクリプトの実行を中断して制御をいったん本体に戻すための"ks_yield()"という関数があるのですが、 ks_window_msg_out()などの関数を呼び出した後に"ks_yield()"する必要があります。 event_api.lua の関数は、こういった関数を適切に呼び出すようになっています。 でもks_yield()を自分で呼び出した方がいいかも。

## 標準で用意されている関数

スクリプトがロードされた状態で、既に使用可能な関数です。 特に説明がない場合は原則的に、 戻り値は正常終了が何かの値（数値や真偽値）, 何かエラーが起きるとnilです （エラーというのはそもそも呼び出し方が間違っているという時に起きるものです）。

### デバッグの設定など

特にありません。エラーが起きた場合はマップと同じ場所の _lualog.txt に出力されます（思考ルーチンと同じ）。

### イベントドリブン

スクリプトは、イベントドリブンで実行されます。イベントドリブンとは、例えばボタンが押されたとか、音声を再生し終わったなどの 「イベント」が起きたときに、あらかじめ決められていた処理が呼び出される方式です。 局地戦略では、例えば新規ゲームが開始された、フェイズが始まった、ユニットが動いたなどのタイミングで スクリプトを実行することになります。

ks_on_newgame()
新規ゲームが開始された時に呼び出されます。 マップの初期化処理などが終わり、プレイヤーが操作を始める直前のタイミングです。

ks_on_phasestart()
ある陣営のフェイズが始まった時に呼び出されます。その陣営のプレイヤーが操作を始める直前のタイミングです。 新規ゲーム開始時は、ks_on_newgame() の後に呼び出されます。

### イベントウィンドウ

#### ks_window_show(title as string)

メッセージなどを表示するためのイベントウィンドウを表示します。

    例：
    ks_window_show("イベント");

#### ks_window_hide()

イベントウィンドウを閉じます。この関数を使わなくても、スクリプトの実行が終了した時点で自動的に閉じられます。

#### ks_window_size_set(width as number, height as number)

ウィンドウの大きさを変更します。 ウィンドウの描画内容は破棄されます。

    例：
    ks_window_size_set(640, 480);

#### ks_window_size_get()

ウィンドウの大きさを取得します。

    例：
    local w,h = window_size_get();

#### ks_window_msg_view(index as number, x1 as number, y1 as number, x2 as number, y2 as number)

イベントウィンドウ上のメッセージ表示領域を矩形(x1,y1)-(x2,y2)で指定します。 index はメッセージ表示領域の番号です。-1を指定した場合、新しいメッセージ表示領域が作られます。 戻り値はメッセージ表示領域の番号です。 作成できるメッセージ表示領域の数に特に制限はありません。

    例：
    local index = ks_window_msg_view(-1, 80, 0, 480, 160)

#### ks_window_msg_remove(index as number)

メッセージ表示領域を削除します。 index はメッセージ表示領域の番号（ks_window_msg_view()の戻り値）です。

    例：
    local index = ks_window_msg_view(-1, 0, 0, 320, 240)
    ks_window_msg_remove(index)

#### ks_window_msg_out(index as number, message as string)

イベントウィンドウにメッセージを表示します。上から下に表示され、はみ出しそうになるとスクロールします。 index はメッセージ表示領域の番号（ks_window_msg_view()の戻り値）です。

    例：
    local index = ks_window_msg_view(-1, 0, 0, 320, 240)
    ks_window_msg_out(index, "メッセージ")

#### ks_window_msg_clear(index as number)

イベントウィンドウ上のメッセージを消去します。 index はメッセージ表示領域の番号（ks_window_msg_view()の戻り値）です。

#### ks_window_msg_setdraw(index as number, bgcolor as number, bgalpha as number, fontcolor as number, fontheight as number)

メッセージ表示領域の描画方法を指定します。 index はメッセージ表示領域の番号（ks_window_msg_view()の戻り値）です。 bgalpha は表示領域の背景色のアルファ値です。bgalpha が零の時、bgcolor は無視されます。

#### ks_window_rgb(r as number, g as number, b as number)

色を表す値を返します。戻り値は r*256*256 + g*256 + b です。
R,G,Bを0〜255で指定します。

    例：color_red = ks_window_rgb(255,0,0);

#### ks_window_clear(color as number)

イベントウィンドウ全体を color で塗りつぶします。

    例：
    ks_window_clear(ks_window_rgb(255, 0, 0)) -- 赤で塗りつぶす

#### ks_window_rectangle(x1 as number, y1 as number, x2 as number, y2 as number, pencolor as number, brushcolor as number)

イベントウィンドウ上の矩形(x1,y1)-(x2,y2)を塗りつぶします。 pencolor は外枠の色、brushcolor は内側の色です。

    例：
    ks_window_rectangle(0, 0, 32, 32, ks_window_rgb(255, 0, 0), ks_window_rgb(255, 0, 0)) -- 赤で塗りつぶす

#### ks_window_framerect(x1 as number, y1 as number, x2 as number, y2 as number, color as number, alpha as number)

イベントウィンドウ上の矩形(x1,y1)-(x2,y2)に幅１ピクセルで四角形を描きます。 color は色、alpha は透明度（0〜256, 256で不透明）です。

    例：
    ks_window_framerect(0, 0, 32, 32, ks_window_rgb(255, 0, 0), 256) -- 不透明な赤で四角形を描く

#### ks_window_boxfill(x1 as number, y1 as number, x2 as number, y2 as number, color as number, alpha as number)

イベントウィンドウ上の矩形(x1,y1)-(x2,y2)を塗りつぶします。 color は塗りつぶす色、alpha は透明度（0〜256, 256で不透明）です。

    例：
    ks_window_boxfill(0, 0, 32, 32, ks_window_rgb(255, 0, 0), 256) -- 不透明な赤で塗りつぶす

#### ks_window_img_load(filename as string)

画像をメモリに読み込みます。戻り値は画像番号です。 ks_window_img_unload() で画像を破棄するとき、この画像番号を渡します。 ファイルが見つからない、読み込めないフォーマットだったなどの理由でエラーになった場合の戻り値は nil です。 読み込める画像の数に特に制限はありません。

    例：
    local image1_num = ks_window_img_load("image1.png")

#### ks_window_img_unload(image_number as number)

ks_window_img_load() でメモリに読み込んだ画像をメモリ上から破棄します。 なお読み込んだ画像は、局地戦略本体が終了する時に自動的に破棄されます。

#### ks_window_img_copy(dest_image as number, destx as number, desty as number, src_image as number, srcx1 as number, srcy1 as number, srcx2 as number, srcy2 as number) as number

画像同士で矩形（長方形）領域のコピーを行います。 dest_image,src_image はそれぞれ、コピー先画像とコピー元画像の画像番号です。 コピー先画像に IMAGE_WINDOW を指定するとイベントウィンドウの画面を指定したことになります。
領域(srcx1,srcy1)-(srcx2,srcy2)を(destx,desty)にコピーします。
※領域の指定方法は Windows の習慣に従い、実際には(srcx2-1, srcy2-1)までがコピーされます。

    例："face.png"を読み込み、(64,64)-(128,128)をイベントウィンドウの(0,0)に表示する。

    local imgnum = ks_window_img_load("face.png");
    if imgnum ~= -1 then
        ks_window_img_copy(IMAGE_WINDOW, 0, 0, imgnum, 64, 64, 128, 128);
    end

#### ks_window_img_copy_colorkey_alpha(dest_image as number, destx as number, desty as number, src_image as number, srcx1 as number, srcy1 as number, srcx2 as number, srcy2 as number, maskcolor as number) as number

画像から画像に矩形（長方形）領域の透明色付きを行います。 ks_window_img_copy() の引数に透明色 maskcolor が増えただけです。 maskcolorで指定した色が透過します。

    例："face.png"を読み込み、(64,64)-(128,128)をイベントウィンドウの(0,0)に表示する。透過色はRGB=(255,0,0)。

    local imgnum = ks_window_img_load("face.png");
    if imgnum ~= -1 then
        ks_window_img_copy(IMAGE_WINDOW, 0, 0, imgnum, 64, 64, 128, 128, ks_window_rgb(255, 0, 0));
    end

#### ks_window_img_copy_colorkey_alpha(dest_image as number, destx as number, desty as number, src_image as number, srcx1 as number, srcy1 as number, srcx2 as number, srcy2 as number, maskcolor as number, alpha as number) as number

画像から画像に矩形（長方形）領域の半透明描画を行います。 ks_window_img_copy_colorkey() の引数に透明度 alpha が増えただけです。

#### ks_window_str(x as number, y as number, str as string, color as number)

イベントウィンドウ上の(x,y)座標を左上とする文字列を出力します。 color は文字色です。背景は透過します。

    例：
    ks_window_str(64, 32, "文字列", ks_window_rgb(255, 255, 255))

### ユーザーの操作を取得する関数

まだマウス操作だけです。 イベントドリブンにしようかとも思ったのですが、とりあえず状態を得る関数を作ってみました。 通常、ks_yield() を含むループの中で呼び出す形になるでしょう。

#### ks_window_mouse_left_clicked()

ウィンドウ上でマウスの左ボタンがクリックされたならば true を返します。 そうでなければ false を返します。 ウィンドウが表示された、またはこの関数を前回呼び出した時から１度でもクリックされていれば戻り値は true になります。
なお「クリック」とはウィンドウ上でボタンを押した後、同じウィンドウ上でボタンを離す操作を言います。

#### ks_window_mouse_left_downed()

ウィンドウ上でマウスの左ボタンが押されたならば true を返します。 そうでなければ false を返します。 ウィンドウが表示された、またはこの関数を前回呼び出した時から１度でもボタンが押されていれば戻り値は true になります。

#### ks_window_mouse_xy()

ウィンドウ上にマウスカーソルがある時、その座標を得ます。 マウスカーソルがウィンドウ外にあるならば戻り値は nil になります。
クリックされた位置を得るためにこの関数を使わないで下さい。実際にクリックした位置とずれることがあります。 代わりに ks_window_mouse_left_clicked_xy() などを使います。

    例：マウス座標をウィンドウに表示します。Luaでは文字列を..で連結します。

    local x,y = ks_window_mouse_xy()
    if x == nil then
    	ks_window_str(0, 0, "マウスがウィンドウ上にない", ks_window_rgb(255, 255, 255))
    else
    	ks_window_str(0, 0, "("..x..","..y..")", ks_window_rgb(255, 255, 255))
    end

#### ks_window_mouse_left_clicked_xy()

最後にクリックされた位置の座標を返します。ks_window_mouse_left_clicked() 関数が trueを返したら、この関数で座標を得るという使い方をします。

    例：クリックされた位置をウィンドウに表示します。

    if ks_window_mouse_left_clicked() then
    	local x,y = ks_window_mouse_left_clicked_xy()
    	ks_window_str(0, 0, "("..x..","..y..")", ks_window_rgb(255, 255, 255))
    end

#### ks_window_mouse_left_downed_xy()

最後にマウスの左ボタンが押された位置の座標を返します。ks_window_mouse_left_downed() 関数が trueを返したら、この関数で座標を得るという使い方をします。

#### ks_window_gettime() as number

プログラムが起動してからの時間をミリ秒で得ます。

#### ks_yield()

スクリプトの実行を一時停止します。これを呼び出さないとウィンドウ内容の更新などが行われません。

    例：１秒間ウェイトをとる。

    local t = ks_window_gettime()
    while ks_window_gettime() < t + 1000 do
    	ks_yield()
    end

### ゲームの状況を得る

大体は思考ルーチン用のものが使えると思います。

### ユニットを設置する／削除する／状態を変更する

スクリプトにおいて、ユニットは陣営番号とシリアルで識別されます。 過去のスクリプトではインデックスという識別方法がありましたが、廃止されました。 シリアルは本体が一意に付けた数値で、スクリプトが付け替えることはできません（これも過去から変更されています）。

#### ks_unit_append(x as number, y as number, side as number, id as number)

陣営とユニットＩＤを指定して新しいユニットを設置します。 動作確認が不十分なため、テキサクモードと相性が悪いかもしれません。
成功すればtrueが返ります。 陣営のユニット数が上限に達しているか、定義されていないユニットＩＤの場合は、ユニットは設置されず戻り値が false になります。

    例：(12,12)に戦闘工兵を設置

    ks_unit_append(12, 12, 1, 1)

#### ks_unit_remove(x as number, y as number)

(x,y)座標にいるユニットを削除します。 動作確認が不十分なため、テキサクモードと相性が悪いかもしれません。
成功すればtrueが返ります。 (x,y)座標にユニットがいない場合は戻り値がfalseになります。

#### ks_unit_set_status(side as number, serial as number, status as table)

指定した陣営の指定したユニットの状態を変更します。 ３番目の引数のテーブルに変更したい状態の値を格納します。 変更できる値は

###

####

###

####

####

###

####

###

####

####

####

    life：ライフ
    fuel：燃料
    level：レベル
    experience：経験値

    です。

    例：0番目の陣営のシリアル100001のユニットの状態を変更

    local side = 0
    local serial = 100001
    local tbl = {}

    tbl['life'] = 100
    tbl['fuel'] = 99
    tbl['level'] = 3
    tbl['experience'] = 50

    ks_unit_set_status(side, serial, tbl)

    地形を変更する

    ks_ground_status_set(x as number, y as number, id as number, life as number)

    (x,y)座標の地形を変更します。

    この関数を実行すると、ゲーム内部でデータが書き換わります。
    lifeが意味を持つのは施設においてのみです。
    実際に画面上の地形が更新されるのは、ks_yield() したかスクリプトの実行が終了した時になります。

    例：(12,12)を平地に変更

    ks_ground_status_set(12, 12, 1, 0)

    陣営の状態を変更する

    ks_side_status_set_money(side as number, money as number)

    陣営の資金を設定します。

    例：

    local side_status = ks_get_side()

    if(side_status[0]['money'] < 10000){
        message("資金が10000支給された！");
        ks_side_status_set_money(side_status[0]['money'] + 10000);
    }

    ks_side_status_set_income(side as number, income as number) as boolean

    陣営の収入を設定します。
    これによって、マップ上の施設数と矛盾する収入を設定することができます。
    戻り値は成功ならtrue、失敗ならfalseです。

    例：

    local side_status = ks_get_side()

    message("第２陣営は金脈を持っているため施設とは別に10000の収入を得ることができます");
    local result = ks_side_status_set_income(side_status[1]['income'] + 10000);

    陣営同士の関係を設定する
    ks_side_relation_set_friendly(side1 as number, side2 as number, friendly as number)

    side1 の side2 に対する友好度を設定します。

    零以下なら敵です。思考ルーチンに影響する。
    値が大きいと優先的に攻撃するかも？（現在は正が不戦、零が敵、負は零と同じ(^^;）

    一方的に友好視（敵視）するという関係も作れますが、多分あまりそういう機会はないでしょう。

    例：

    message("第１陣営と第３陣営は同盟を結びました。")
    ks_side_relation_set(0, 2, 1)
    ks_side_relation_set(2, 0, 1)

    message("第１陣営は第２陣営に宣戦布告しました。")
    ks_side_relation_set(0, 1, 0)
    ks_side_relation_set(1, 0, 0)

    変数の保存

    ks_var_set(key, value)

    セーブファイルに保存される変数を登録します。
    変数については、思考ルーチンでの解説と同じです。
    こちらは陣営単位ではなくマップ単位で保存されるところが違います。

    ks_var_get(key)

    ks_var_set で登録した変数の値を得ます。戻り値が変数の値です。

    ks_var_remove(key)

    ks_var_set で登録した変数を削除します。

    EOF