2022年12月6日火曜日

Fallout4 備忘録

Fallout4のModを弄り回してた時に気づいた点やあまり他サイトで触れられてないような事に関するメモ。

SkyrimにあったGame.GetCurrentCrosshairRef関数について

Fallout4には標準機能として存在しない。(だがGetCurrentConsoleRefというConsole Utilを使わない限りデバッグにしかほぼ用途が無いものはしっかりと残してる)
後述するLL FourPlay communityというスクリプト拡張プラグインにてほぼ同じ機能のLastCrossHairRef関数とLastCrossHairActor関数が使えるようになる。

特定対象のアクティベート時にRキーで追加コマンドを実行するタイプのModについて

これはダミーPerkにAdd Activate Choiceを設定してプレイヤーに持たせる事で実現させてるが
このAdd Activate Choiceが設定されてるPerkを複数取得した場合、
発動条件を満たした追加コマンドが2つ以上あるとコマンドが表示されなくなり、Rキーを押しても追加コマンドが実行できないという問題が発生する。
(A、B、Cのコマンド追加Perkをプレイヤーが所有し、AとCの条件に一致した対象にクロスヘアを合わせてもRキーコマンドが表示されなくなる)
おまけにこの追加コマンドを実行するキーの指定が不能なため競合した時の解決もかなり困難となる。(最悪どちらかの追加コマンドModを切る必要がある)

このPerkによる追加コマンドはSkyrimにあったGame.GetCurrentCrosshairRef関数が消えた事によってクロスヘア上のアクターを取得できる手段が無くなったため
その代打手段として使われていたが現在はLL FourPlay communityというスクリプト拡張プラグインでGame.GetCurrentCrosshairRef関数と同機能の関数が使えるようになったため
目の前の対象に特殊な事をやりたいModを作る場合は上記の問題回避のためにもLL FourPlay communityの関数とOnKeyDownの組み合わせでModを制作するのが安全。

スクリプト拡張プラグインについて

Fallout4のスクリプト拡張プラグインは自分が見つけた範囲では下記の通り。
(Skyrimだと前提Modにスクリプト拡張プラグインを指定したものがあるのと色んな所で解説してる所が多いため見つけやすいがFalloutだとスクリプト拡張プラグインを前提Modにしたものが少なく知名度がかなり低いから見つけづらい。)

  • SUP F4SE

Jsonファイルの読み書きや一時保存用の変数の仕様が可能になる。
現状だと、唯一外部ファイルを使用できるようになるスクリプト拡張プラグインであるため
SkyrimのPapyrusUtil SEを使ったModにあるようなMod設定の保存や読込、ゲームのロード時にMod設定の自動読込を作成したい時は必須。

ちなみにこの拡張プラグインはSkyrimにもSUP SKSEという名前で存在する。

  • Console Util

コンソールコマンドをスクリプトから実行する関数を追加する。
SkyrimのConsole Utilと同機能。

  • LL FourPlay community

Skyrimで存在してFallout4で何故か消えた関数の一部がこの拡張プラグインで使えるようになる。
クロスヘア上のアクターに対して特定のキーを押す事で何かのアクションをするというスクリプトを作る場合は必須。
(ただ、ダウンロードサイトはnexusとは別サイトでそちらもダウンロードのためにアカウント登録する必要がある)

Game.GetPlayerFollowers関数の仕様

現在コンパニオンになっているアクターではなくプレイヤーに追従しているアクター達を配列で返す。だが、待機命令で待機してたり戦闘中だと配列に含まれないためOblivionやSkyrim(要powerofthree's papyrus extender)の類似関数と同じ感覚で使うと痛い目を見る。(OblivionのGetNumFollowersはちゃんと取得できてたのに…GetCurrentCrosshairRef関数の件もそうだがスクリプト関連は何で一部退化しとるんだ…)

SUP F4SEがあれば周囲のアクターを取得できる関数が存在するため下記のコードで取得できる。(スクリプトエンジンもSkyrimよりマシになった感じはするが負荷がありそうだから多様は禁物。)

Actor[] Function GetFollowers()
    Cell pCell = Game.GetPlayer().GetParentCell()
    Actor[] followers = new Actor[0]
    Actor[] acts = SUP_F4SE.GetActorsInCell(pCell)
    int i = 0
    while (i < acts.length)
        if acts[i].IsPlayerTeammate()
            followers.add(acts[i])
        endif
        i += 1
    endWhile
    return followers
EndFunction