キルログ、ヒット音、バレットタイムを追加します。toounさんの作品です。
どんなModなのか
対象を倒した時に画面に表示と効果音が鳴ります。パターンがいくつかあって選べます。バトルフィールドやカウンターストライクのような感じです。
誰が誰をどの武器で倒したのかが表示されます。ただし、プレイヤーが倒した時だけです。武器はサポートされているものだけが表示されますが、多くの武器Modがサポートされているようです。
ヒット音は、プレイヤーが誰かに銃弾を当てた時に効果音が鳴ります。
バレットタイムは狙いを付けている時だけ発動できます。
修正が必要だった
キルログがうまく動作せず、トレースログにエラーがポロポロと出るので、スクリプトを精査しました。これで動くとは思えないような感じで大幅に修正が必要でした。
特にスクリプト配布が常時発動型のCloakスペルというやってはいけないパターンでした。また、ヒットの判定処理もフィルタリングがおかしくて、状況によっては高負荷の原因になります。この2つは要修正です。
改変はNexus内に限り再配布可能という条件だったので、修正方法の紹介だけに留めます。
スクリプトの配布を改善する
詳細はSkyrimで解説しています。Fallout 4もまったく同じです。
Constant Effectだと毎秒5~6回の判定になるので、下手するとスクリプトエンジンが過労死するので、Fire and ForgotにしてTimerを使い間隔をあけてCastしましょう、ということです。
スクリプトを配布する処理と、配布されたスペルの処理はわけて考えることができます。私は自作のModで周囲のActorにスクリプトを配布しているので、そこにこのModのスペルも加えて、このModのスクリプト配布処理は排除しました。
ヒットの判定処理を改善する
攻撃がヒットした時の判定は攻撃を受ける側のOnHitイベントを捕捉して行います。このために事前にプレイヤーの周囲のActorにスクリプトを配布しておく必要があるわけです。
Fallout 4はこのOnHitイベントが改善されていて、余分なOnHitを受け取らずに済むようになりました。このModはもともとプレイヤーが攻撃したときしか見ていないのに、OnHitはすべて受け取ってしまっています。例えば変異した敵は周囲にRADをばらまいていますが、Cloakスペルでばらまくので敵味方無関係にヒット判定が出ています。こういうのも全部拾ってしまっています。
修正前のコードはこうです。
KILLTIPS_Script.psc 修正前 (papyrus)
Event OnEffectStart(Actor akTarget, Actor akCaster)
RegisterForHitEvent(MySelf)
EndEvent
Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool bPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
; ヒット音とキルログの処理
EndEvent
修正後はこうなります。
KILLTIPS_Script.psc 修正後 (papyrus)
Event OnEffectStart(Actor akTarget, Actor akCaster)
RegisterForHitEvent(MySelf, PlayerRef)
EndEvent
Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool bPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
; ヒット音の処理
EndEvent
Event OnDying(Actor akKiller)
; キルログの処理(akKillerが加害者)
EndEvent
ヒット音はそもそもプレイヤーが攻撃した時限定なので、ヒットの判定もプレイヤーが攻撃したもののみ受け取るようにします。これだけで負荷が激減します。
キルログは対象が死んだ時に表示すればいいので、OnHitではなくOnDyingを使います。
OnDyingを使う注意点は、akKillerに加害者がはいるのですが、コンパニオンが加害者だった場合はすべてプレイヤーに置き換わるようです。それだとコンパニオンが倒してもプレイヤーが倒したと表示されてしまうので、OnHitで最後に攻撃を当てたActorを覚えておきます。
KILLTIPS_Script.psc (papyrus)
Actor MyAggressor
Event OnEffectStart(Actor akTarget, Actor akCaster)
RegisterForHitEvent(MySelf, PlayerRef)
RegisterForHitEvent(MySelf, CurrentCompanionFaction)
EndEvent
Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool bPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string apMaterial)
MyAggressor = akAggressor as Actor
EndEvent
Event OnDying(Actor akKiller)
if akKiller != PlayerRef
MyAggressor = akKiller
endif
; キルログの処理(MyAggressorが加害者)
EndEvent
キルログはもともと加害者がプレイヤーだった時だけ表示するようになっていますが、条件判定をなくせば加害者が誰であっても表示するようにできます。
ちなみに、OnDyingやOnDeathは被害者側のイベントですが、加害者側のOnKillイベントを使う方法もあります。プレイヤーおよびコンパニオンが誰かを殺したときだけキルログが出ればよいのであれば、プレイヤーのOnKillイベントだけを見ればよいです。周囲のActorにスペルをばらまく必要がなくなるため、実装がシンプルになります。
いらない機能はスクリプトから排除する
使わない機能でもキー入力の判定やヒットの判定をしています。
無駄でしかないので、自分が使わない機能はコメントアウトするなりして入力や判定をなくす方がいいと思います。