ToSにおけるlua - JTosAddon/JTosAddonWiki GitHub Wiki

ToSにおけるlua

そもそもluaって

テキストで書かれたスクリプト言語です。
luaスクリプト自体はToSと関係ない汎用的なものです。
内部ではluaVMが動いて、それらを実行します。
詳しくは、自力で調べてください。

luaで関数を書き換える

luaコード上ではあらゆる関数は「関数というオブジェクト」です。
localでないオブジェクトはグローバル(_G)テーブルに設定された変数に格納されています。

「function XXX() ... end」は、「_G["XXX"] = function() ... end 」と等価です。
ここからもう1歩踏み込むと、下のコードが可能です。
function XXX() ... end
function XXX() ... end
ただ、単純にこれをやると、1つ目のfunctionは、参照カウンタを失い消滅します。

一般的には、HOOKは以下の動作をしています。
XXX = A;
YYY = XXX;
XXX = B;

ここで重要なのは「Aという関数」と「XXXという変数」は根本的に別物ということです。
XXXを書き換えても、Aの内容は変わりませんが、
皆が呼び出すのはXXXなので、Aが書き換わったように見えます。

ToSにおけるluaスクリプト

Tosにおいて、luaスクリプトが主に担当している機能というのは、
「UIの一部の描画および入力」にかかわる部分となります。

全体構造は以下のような感じと予想されます。
◆C++層(内部コード)
├◆通信層
├◆描画層
└◆lua層

luaスクリプトによりできること

  • 多くのウィンドウ(Frame)の表示操作
  • 多くのウィンドウ(Frame)の入力操作 (AlchemyやCloverFinderは自動で入力をします)
  • 通常ユーザーに示されないデータ(一部)の展開
  • ユーザー入力における一部限界の突破 (Zoomyは距離の限界を突破します)
  • 新しいウィンドウ(Frame)の作成

###luaスクリプトによりできないこと

  • 3Dオブジェクトにかかわる操作
  • C++層や描画層の改変

###luaスクリプト以外で何とかできるもの

  • 3Dオブジェクトのテクスチャやモデルの改変

luaスクリプトとC++

前項にて、入力や出力をluaスクリプトでできると書きましたが、
正確にはそれらを実行するのはC++層です。
Frameを作るのもTextを作るのもC++層です。

ただ、lua層からはC++層の関数の一部を呼び出すことができ、
C++層からはlua層の関数を呼び出すことができます。
例えば、C++層で「ui::GetFrame」という関数は、
lua層で「ui.GetFrame」にラッパが格納されています。
Frame内のButtonにLBtnUpScpが「XXX_ON_CLICK」となっていれば、
C++層でクリックを検知したとき、lua層の「XXX_ON_CLICK」を呼び出します。

フレームを定義するXML

XMLに書かれたフレーム定義は、C++層でFrameオブジェクトに置き換えられます。
この際、「XXX_ON_INIT」がC++層から実行される他、
XMLに書かれたイベント時のスクリプト(先述のLBtnUpScpなど)がC++層から実行されるようになります。
この流れが、実際のUIとlua層のスクリプト実行の受け渡しを行う形になります。
※この2パターンに該当しなくてもC++層が名前指定で呼び出すlua層の関数は多数あります。

ui.XXXの書き換えについて

lua層で「ui.XXX」という関数は、別の関数で置き換えることができます。(所謂HOOK)
しかし、C++層の「ui::XXX」は書き換えることができません。
「ui.XXX」を書き換えるということは、以下の3パターンのいずれか(もしくは全部)を行うことを指します。

  • (条件次第で)lua層がui::XXX呼び出し機能を失わせる
  • (条件次第で)lua層がui::XXX呼び出す前に何かをする
  • (条件次第で)lua層がui::XXX呼び出した後で何かをする

ただし、「C++層が自身のui::XXXを直接呼び出すケース」にはこれらの置き換えは無力です。
lua層を経過しないので、一切の手出しができなくなります。

luaスクリプトにより本当にできること

結果として、lua層に定義できる動作は、以下になります。

  • C++層が固定的に呼び出してくる関数の実行
  • lua層で参照できるC++層の関数の実行
  • C++層がイベント登録を受け付けている部分に関する関数登録と実行

C++層が固定的に呼び出してくる関数

  • Frameに対するXXX_ON_INIT
  • CHAT_SYSTEM

lua層で参照できるC++層の関数の実行

lua上の関数 C++上のクラス宣言
option.XXX namespace option
addon.XXX namespace addon
session.XXX namespace session
ui.XXX namespace ui
CObject:XXX namespace ui class CObject
CFrame:XXX namespace ui class CFrame : CObject
CContextMenuFrame:XXX namespace ui class CContextMenuFrame : CObject
CGroupBox:XXX namespace ui class CGroupBox : CObject
CListBox:XXX namespace ui class CListBox : CObject
CDropList:XXX namespace ui class CDropList : CObject
CGauge:XXX namespace ui class CGauge : CObject
CRichText:XXX namespace ui class CRichText : CObject
CEditControl:XXX namespace ui class CEditControl : CObject
CButton:XXX namespace ui class CButton : CObject
CPicture:XXX namespace ui class CPicture : CObject
CControlSet:XXX namespace ui class CControlSet : CObject

※ごく一部のみ 詳細はscriptapi.ipf参照 (ただしこれも現状の完璧ではない模様)

C++層がイベント登録を受け付けている部分

  • HotKey処理
  • 自分で登録依頼したイベント
XML名称 クラス SetEventScriptの引数 備考
LBtnDownScp CObject ui.LBUTTONDOWN =0 lua上にSet関数
LBtnUpScp CObject ui.LBUTTONUP =1 lua上にSet関数
LBtnDblClickScp CObject ui.LBUTTONDBLCLICK =2
ui.LBUTTONPRESSED =3
RBtnDownScp CObject ui.RBUTTONDOWN =4 lua上にSet関数
ui.RBUTTONUP =5
ui.RBUTTONDBLCLICK =6 lua上にSet関数
ui.RBUTTONPRESSED =7
MouseMoveScp CObject ui.MOUSEMOVE =8
MouseWheelScp CObject ui.MOUSEWHEEL =9
ui.ROLLOVER =10
ui.ROLLOUT =11
EnterKeyScp CEditControl ui.ENTERKEY =12 lua上にSet関数
DropScp ui.DROP =13
PopScp ui.POP =14
ui.LOST_FOCUS =15
ScrollScp CObject ui.SCROLL =16
ResizeScp CObject ui.RESIZE =17
ui.EVENTCOUNT =18
OpenScp CFrame xmlでの定義のみ?
CloseScp CFrame xmlでの定義のみ?
DragScp CObject lua上にSet関数
FocusingScp CEditControl lua上にSet関数
LostFocusingScp CEditControl lua上にSet関数
TypingScp CEditControl lua上にSet関数
SlideScp
UpdateScp
SimonyListScp CDropList lua上にSet関数
SelectedScp CDropList lua上にSet関数
NumChangeScp CNumUpDown lua上にSet関数
OnCoolTimeEndScp CIcon lua上にSet関数
OnCoolTimeUpdateScp CIcon lua上にSet関数
OnEnableScp CIcon lua上にSet関数
OnCoolTimeEndScp CIcon lua上にSet関数
DumpScp CIcon lua上にSet関数
EnableUpdateScp CIcon lua上にSet関数
SelectScp
UpdateScp
fadeoutScp
imagechangescp
itemtooltipscp
nextScp
selectScp
opencheck
lockopenscript

※一部イベントはCObject:SetEventScriptで設定可能