概要
前の記事で使った wand_good_1
を初期装備とする最低限のコードを書きました。haxeで。
大事なとこだけ読みたい人は本題まで読み飛ばしてください。
Haxe?
ActionScriptっぽい構文で色々な言語のソースコードを吐き出せるやつです。
今回はLuaが辛そうだったので、Luaを隠蔽するためにHaxeを使っています。
あとXMLを吐くためにnodejsを使っています。これはなんの言語でも構いません。
NoitaのLuaライブラリ->Haxe->Lua
Haxeでそのまま何でも書けるわけではありません。
Externという機能を使って、外部ライブラリのHaxeでのインターフェースっぽいのを書くと書けるようになります。 TypeScriptの型定義が似てるらしいです。
- このHaxeクラスはどのライブラリのクラスと対応があるか
- このクラスはどんな関数/変数があるか
- この関数の型と戻り値は何か
- この変数の型とアクセス権限はどうなっているか
あたりを記述します。
これは別にすべてを網羅する必要は必ずしもなく、実際に使う関数/変数だけを記述すればよいです。
hxnoita
今回私はhxnoita
という名前でnoitaのluaライブラリ?のhaxe externを書いています。
とりあえずEntityとComponentを接頭辞とする関数群だけまとめてあるていどです。
あと既存のPerk名と既存のSpell名。
本題
前の記事で使った wand_good_1
を初期装備とする最低限のコードを書きました。
最低限のファイル構成
modは最低以下の2ファイルから構成されます。
mod.xmlには、noitaのmod設定画面で表示される名前と説明を記述します。 それ以外の役目は私は今のところ分かっていません。
init.luaではmodのふるまいを記述します。今のところOnPlayerSpawned
関数内に書いた処理が、プレイヤーキャラクターの出現時に実行されることがわかっています。
今回のファイル構成
杖を読み込むべく、前回の記事で読み込んだwand_good_1*
な名前のファイル群がまるっとコピーしてあります。これらはまだHaxeから生成していません。
もうちょっと詳しくなったら適当なファイルと置き換える予定です。
init.luaはMain.hxから、mod.xmlはXmlInit.hxから生成しています。
処理の流れ
- inventoryのEntityIdを取得する
- inventoryを空にする
- 杖をファイルから読み込む
- 杖をinventoryにいれる
- 水ボトルをファイルから読み込む
- 水ボトルをinventoryにいれる
- 水ボトルをファイルから読み込む
- 水ボトルをinventoryにいれる
処理の解説
内容はすべて、私がやってきた中で感じた憶測になります。Noitaのmod APIはほぼ説明なく公開されている状態ですので、既存のコードや誰かが書いたコードを読んで感じ取るしかなかったからです。
事前知識
基本的にNoita内に存在するすべてのモノにはEntityIDが割り振られています。 Entityに対して直接操作をすることはできず、常にEntityIdを使ってやりとりをします。
inventoryのEntityIdを取得する
プレイヤーエンティティの子要素のどれかがInventoryということだけはわかっています。
なので総当たりで名前がinventory_quick
かどうかを調査し、inventory_quick
だったらinventoryとしてEntityIdを記録します。
inventoryを空にする
この処理は今回は杖と水ボトル2個を追加するだけなので、消しても動くかもしれません(試していない)。
Inventoryの子要素は所持している杖もしくはアイテムです。 全て置き換えたい場合は、すべての子を取得して、すべて削除します。
杖を読み込む
杖のXMLファイルを読み込みます。 それだけです。
このあとに杖の数値の変更をする関数を実行しても問題ありません。
杖をinventoryにいれる
取得処理です。子要素として追加するだけですね。
水ボトル
杖と基本的には一緒です。
2回取得処理をしているのは、同一EntityIdだとまずいという考えです。たぶん失敗するんじゃないかと思います(試していない)。
余談ですが、potion_water.xmlがあるフォルダにはほかのポーションが並んでいます。
〆
定義済みの任意の杖を初期装備として始めるModがかけました。
余談
noita.gun.procedural.GunActionUtilsの下に、AddGunAction()とAddGunActionPermanent()が定義してあります。 第一引数は杖のEntityId、第二引数は今のところSpellsです。Spellsは実体はStringで、既存の魔法を列挙してあります。
使用例は以下です。
GunActionUtils.AddGunActionPermanent(wand1,Spells.SPIRAL_SHOT);
これを杖情報を取得した後に実行すると、このコードであればwand1が常時詠唱魔法としてスパイラルショットを持ちます。 Spells.まで打ち込むとサジェストがあるはずなので、適当なスペルを当ててみてください。
AddGunActionであれば通常の魔法として杖に追加されます。