Elin Element Inspector VSCode拡張を作った

Elin Element InspectorというVSCode拡張を作りました。

機能の説明#

Elinのデコンパイルされたソースコードでは、ElementのIDが数値リテラルとして表現されています。おそらく元々のソースコードでは定数参照になっているものが、最適化によりその情報が抜け落ちているのだと思われます。 Elementを使用しているコードを読み解くには、IDの数値の意味を手動で調べる必要があり、かなり煩雑です。

このVSCode拡張はその問題を解決します。

Element IDの横にElement名を表示#

VSCodeのinlineDecorations APIを使用して、Element IDの横にそのElementの名前を表示します。

デコレーション機能の例
デコレーション機能の例

この機能は、特定の関数の引数としてElement IDが渡されている場合に機能します。 関数の一覧は手動で拡張に登録されています。関数を追加したい場合は、elinElementInspector.additionalTargets設定に関数名と引数の位置を追加してください。 また、GitHubなどでリクエストをいただければ、デフォルトの設定として組み込めるかもしれません。

任意の数値リテラルにホバー表示#

Element IDの数値が関数の引数以外の場所で現れることもあります。そのような場合のために、任意の数値リテラルに対してElementの情報をホバー表示する機能も提供しています。

ホバー機能の例
ホバー機能の例

この機能はElement以外の数値にも反応することに注意してください。hover時なのでそこまで邪魔にならないは予想しています。

設定など#

デコレーション機能として表示する文字列は、設定からElement sourceの任意の列を選択できます。elinElementInspector.format設定を変更してください。

elinElementInspector.enableInlineDecoration及びelinElementInspector.enableHoverfalseに設定することで、それぞれの機能を無効化できます。

デフォルトではこの拡張はC#のプロジェクト全てで有効になります。特定のプロジェクトでのみ有効化したい場合は、VSCode側の設定で、Workspaceごとに有効・無効を切り替えられます。

キャラクター生成時に装備が生成される仕組み

この記事では、キャラクター生成時に生成されたキャラクターに装備がどう生成されるのかを解説します。

TL;DR#

装備の生成ロジックを大まかにまとめると以下のとおりです。

  • キャラクターの種族によって、装備が生成されるか全く生成されないかが決まる
  • キャラクターの職業によって、近接・遠隔武器の種類が決まる
  • キャラクターのレベルによって、装備が生成される確率が上がる
  • キャラクターの種別によって、ユニーク武器などの生成がされている

以下で細かい内容を見ていきましょう。

装備生成の仕組み#

装備の生成はChara.RestockEquip関数で行われています。1

Chara.RestockEquip関数が呼ばれる条件#

Chara.RestockEquipChara.OnCreate関数から呼び出されています。この関数はrace.EQ.Length != 0 || !source.equip.IsEmpty()のときに呼び出されます。2

race.EQは、現在allが入っているか、空であるかのどちらかです。半数程度の種族がallを持っているようです。allがあれば基本的に装備が生成され、そうでなければ生成されません。

race.EQが空の種族でも、一部の種族はsource.equipに装備情報が入っているため、装備が生成されます。 source.equipはそのキャラクターがどのような種類の装備を持つか決めるための情報で、現在は遠隔武器を持つかどうかを決めるために主に使用されています。

source.equipに値が入っているキャラクターは非常に少なく、大道芸人、イーク、デュポンヌ、イゴーロナク、イモーロナク、ダゴンの6体のみです。

なお、source.equipに入っている値がnoneの場合はChara.RestockEquip関数が早期リターンするため、装備は生成されません。3現状これに該当するのはイークのみです。

Chara.RestockEquip関数の中身#

この関数内の処理はいくつかのステップに分かれています。

  • キャラクターのidに基づいて、装備を生成
  • キャラクターのid、equipフィールドに基づいて、遠隔武器を生成
  • キャラクターの種類を問わず、各部位の装備を生成
  • その他細かい処理

具体的にそれぞれの処理を見ていきましょう。

キャラクターidに基づく装備生成#

キャラクターのidを指定して、特定の装備を生成する処理です。主にユニークキャラクターの初期装備品を生成するのに使われている他、A.I.Rなどの固有装備の生成にも使われています。

例えばキリアにゼフィールの怒りを装備させる処理は以下のようになっています。4

switch (id)
{
// ...
case "adv_kiria":
  if (onCreate)
  {
    EQ_ID("sword_zephir");
  }
  break;
// ...
}

onCreateはキャラクターの初回生成時にのみtrueになるフラグです。これによってキャラクターの装備が再生成されるタイミングでゼフィールの怒りが再生成されるのを防いでいます。

遠隔武器の生成#

遠隔武器の生成はキャラクターidとequipフィールドに基づいて行われます。

まず、キャラクターidに基づいた処理では特定のキャラクターに特定の遠隔武器を持たせています。 具体的には、現在はティケ、トルーパー、スカラベにレーザーガンを、デーヴにパンツァーファウストを持たせる処理が書かれています。5

それ以外のキャラクターはequipフィールドに基づいて遠隔武器が決定されます(Chara.RestockEquipを呼ぶ判定をするのに使っているのと同じフィールドです)。 このフィールドはCharaJobにそれぞれ存在しており、Charaの方が優先されます。6

equipフィールドがarcherの場合はクロスボウか弓カテゴリから、inquisitorgunnerの場合は銃カテゴリから装備が生成されます。7

なお現段階ではequipフィールドがarcherの職業は遺跡荒らしと狩人が該当し、gunnerは機工兵と異端審問官が該当します。inquisitorは現在該当する職業がありません。8

キャラクター種別を問わない装備生成#

ここではキャラクターの種別を問わず、各部位の装備を生成する処理について説明します。

まず、num変数が定義されています。これはキャラクターのレベルに比例し、またキャラクターのレアリティが高いほど大きくなります。また冒険者の場合は3倍されます。9

このnum変数は装備が生成される確率を決めており、数値が大きいほど装備が生成されやすくなります。 キャラクターのレベルが高くなれば確率が上がるため、深層では基本的に全ての部位が埋まるようになるでしょう。

以下では武器と防具に分けて装備の生成ロジックを解説します。 なお、以下の処理は種族がカオスシェイプの場合はやや異なった実装になります(増える部位に合わせて装備生成判定の回数が増えます)。

武器の生成#

武器は、CharaのタグとJobweaponフィールドに基づいて生成されます。10

まず、Charaのタグにboxerが含まれる場合、格闘武器が生成されます。現在該当するのは毒の『ポイナ』、リザードマンの拳闘士、ミノタウロスの拳闘士のみです。

その他の場合、Jobweaponフィールドに基づいて武器が生成されます。このフィールドには武器のカテゴリが配列で格納されており、その中からランダムに選ばれた武器が生成されます。 現在のJobweaponフィールドの対応は以下のとおりです。

職業 weaponフィールドの値
戦士 sword,axe,blunt,polearm,scythe
遺跡荒らし sword,dagger
魔法使い staff
農民 scythe
狩人 dagger,axe
魔法戦士 sword,polearm
観光客 dagger,blunt,staff
ピアニスト dagger,blunt,staff
神官 blunt,staff
機工兵 blunt
異端審問官 sword
パラディン sword,blunt,polearm
魔女 staff
処刑人 scythe,axe
陰陽師 sword
プレデター (空)
唄い手 staff
錬金術師 staff
防衛者 sword
なし (空)

生成される武器の本数は基本的に1本ですが、二刀流スキルを持っているキャラクターの場合は1/2の確率で2本目が生成されます。11