はじめに
World of Warshipsは複数のプログラミング言語で構成されており、それぞれ以下のような役割を担っています
- ゲームの中核(オブジェクトのレンダリングやダメージ処理など): Python, C++
- UI(ダメージポップアップや艦艇名表示など): ActionScript3, Unbound, Unbound2, Gameface
ゲーム中核とUIの間でデータを橋渡しするのがDataHubというオブジェクトです。
詳細は公式ドキュメントにもありませんが、UI系Modの作成ではほぼ必須の知識になります。
今までのModderは公式のマークアップや他人のModを見て独学してます。この狂った連鎖を断ち切りたい
具体例なんかは次回以降(SoonTM)にします
必要なもの
- やる気と時間: 作ったModが思い通りに動かないこと多数。公式ドキュメントに記載されている手法も特定条件では動かなかったり(しかも条件書いてない)。Modテストのためにクライアント複数回起動するだけで1時間失ったりします。これはマジです
- FlashDevelop: .swcファイルを読み込めるFlash IDEなら他のものでもOKです
- SWCファイル: 下記リンクから最新バージョンのフォルダを選択、as3_library.zipをダウンロードしてください
ダウンロードした.swcファイルのパスをIDEに通してください。
FlashDevelopであれば、画面上部のProject→Properties...→Compiler Options→SWC Librariesから設定できます
この手順が完了すると、FlashDevelopのProjectカラムにあるRefences→Classesより、各Component(後述)の持つプロパティやイベントが確認できるようになります。
DataHubのデータ構造
定数について
Unbound系に共通する定数としてCC
(ComponentClass)が存在し、Component(後述)のクラスIDが保存されています。
例として、AccountNameコンポーネント(プレイヤーの名前が保持されている)のクラスIDはCC.accountName
のようにアクセスできます。
Collectionsについて
Collectionを格納するオブジェクトです。クラスID(CC.something
)を使用して特定のCollectionを取得できます。
Collectionについて
特定のComponentを持ったEntityへの参照を格納する配列です。
配列インデックスを指定して任意のEntityを取り出せます。
また、コレクションから要素を選択し、新たなコレクションを作成することも可能です。
例えばAccountNameコレクションには、AccountNameコンポーネントを含むEntityが全て保存されています。
Entityについて
Componentを格納するコンテナです。
全てのEntityはユニークなIDを持ち、これを用いて直接参照することができます。
Componentについて
数値、文字列、イベントなど、実態のあるデータを保持するオブジェクトです。
前出のAccountNameコンポーネントであれば
name
: プレイヤー名(IGN)nickName
: ニックネーム(クランタグを含むIGN)evChanged
: 上記どちらか変更された際トリガーされるイベント
が保存されています。
また、primaryKey
メソッドが存在する場合はユニークIDを持ちます。
ユニークIDは1つまたは複数の要素で構成されており、前者の場合は数値や文字列、後者の場合は'element1_element2'
のようにアンダーバーで各要素を結合した文字列がキーとなります。
オブジェクトの取得方法
Collection
variableName
にCC.something
のコレクションを代入します。
variableName[index]
で任意のインデックスにあるEntityを取り出すことができます
Unbound | <bind name="collectionDH" value="CC.something; 'variableName'"/> |
Unbound2 | (var variableName:gfx = "$datahub.getCollection(CC.something)") |
Entity
variableName
に任意のEntityを代入します。
EntityのユニークID(entity.id)から
Unbound | <bind name="entityDH" value="'variableName'; entityId"/> |
Unbound2 | (var variableName:gfx = "$datahub.getEntity(entityId)") |
ComponentのユニークIDから
複数の要素からなるIDの場合、自分で文字列を作成してgetPrimaryEntity
を使用するか、getPrimaryCompositeEntity
の引数に結合前の要素を与えることでEntityを得ることができます。
例1: ownSquadron
のユニークIDは、飛行中隊のインデックス(ロケット:0, 雷撃機:1, 爆撃機:2等)です。getPrimaryEntity(CC.ownSquadron, index)
例2: battleConsumable
のユニークIDは、消耗品タイプと飛行中隊インデックス(艦消耗品の場合-1)の結合文字列type_squadronId
です。
getPrimaryCompositeEntity(CC.battleConsumable, consumableType, squadronId)
はgetPrimaryEntity(CC.battleConsumable, 'consumableType_squadronId')
と等価です。
Unbound | <bind name="primaryEntityDH" value="'variableName'; CC.something; index"/> |
Unbound2 | (var variableName:gfx = "$datahub.getPrimaryEntity(CC.something, index)") |
(var variableName:gfx = "$datahub.getPrimaryCompositeEntity(CC.something, *args)") |
コレクションの最初のEntity
collections[CC.something][0]
と等価です。
Unbound | <bind name="firstEntityDH" value="'variableName'; CC.something"/> |
Unbound2 | (var variableName:gfx = "$datahub.getSingleEntity(CC.something)") |
Component
コレクション最初のEntityにあるComponent
collections[CC.something][0].something
またはgetSingleEntity(CC.something).something
と等価です。
Unbound2 | (var variableName:gfx = "$datahub.getSingleComponent(CC.something)") |