デスペナルティModとは
死んだらゲームオーバーになって最後のセーブデータをロードすることになります。すると獲得したアイテムやダメージを与えたのがなかったことになります。難易度をあげていくとすぐに死んでしまうので、何度も巻き戻ることになります。
そこで、死んでもゲームがそのまま続行して復帰地点から再スタートできるようにします。
候補となるMod
- Knockout Framework (Death Alternative)
- Death Penalty – An immersive death mod
- Respawn Relays – An Alternative Death Mod
結局のところ、自分が納得いく形にするには、改造するか自作するしかないです。
改造について
SkyrimでもデスペナルティModを自作してさんざんいじってきましたので、だいたいのことはわかっていたつもりだったのですが、Fallout 4ならではの問題があって、すんなりとはいきませんでした。
Skyrimでは、PapyrusのPushActorAway関数を使うと、対象を強制的にラグドール状態にして吹っ飛ばすことができます。これと麻痺を組み合わせることで死亡を演出できていました。
Fallout 4ではPushActorAwayが効きづらくなっているようです。再生中のアニメーションによっては受け付けずプレイヤーがその場に固定化されてしまいます。リロードアニメーションなどがこうなりやすいようでした。
Knockout FrameworkはF4SEのDLLプラグインで機能を実装しており、このあたりを解決しているみたいです。ModderがデスペナルティModを作れるようにAPIを公開しているので、これを利用するのがいいかもしれません。
いずれのModも、死亡後の復帰地点が最後に寝たベッドだったり、事前に設定した地点だったりします。これはエリア移動直後の場所(ダンジョンの入り口)にしたかったので、手を入れる必要がありました。もし復帰地点が近すぎる場合はレスキルされる可能性があるので、前々回のエリア移動直後の地点を第2候補として用意するといいです。
Death Penalty
すべてPapyrusだけで実装しています。倒された時に、スティムパックで復帰するか諦めて戻るかを選択できるのが面白いです。
ただ、Papyrusベースだからか、倒れる処理がSetUnconsciousフラグの付与とEssentialDownStartというアニメーションの再生になっています。これだと瀕死なので気絶したという感じにはならないですね。抜けるのはEssentialDownExitです。
PushActorAwayで無理矢理寝かせても、動作が安定しないのと、SkyrimにおけるMfg FixのようなModがないので目を閉じさせることができません。
Knockout Framework
多くの機能を実装したF4SEのDLLプラグインと、それを利用して書かれたPapyrusコードのセットになっています。
しばらく遊んでみましたが、死亡処理が安定しています。また、死亡時にアイテムが盗まれて回収クエストが始まるのも、なかなか歯ごたえがあって面白いと思います。
ただし問題もあって、盗まれる量や確率が調整できず、しきい値(価格)を超えたものはすべて盗まれてしまうようです。ですので復帰が難しくなるというか、とても面倒になります。グラディウスで中盤以降に死んでしまうと、立て直しが絶望的になるのに似ています。このあたりの処理はDLLで実装されているので、調整しようにも手が出せません。
復帰時に毎回怪我をしているのですが、寝れば治るので面倒なだけです。これはParyrusをいじって改善できます。
Buffout 4の作者による、このModのDLLはゲームがある程度経過するとゲームの動作を不安定にするという報告があります。
簡単なデスペナルティModの作成
多くのModで採用されている実装です。Horizonもデスペナルティを用意しています。
PlayerRef.SetEssential(true)
プレイヤーの不死属性をオンにします。これで死なないNPCと同様の処理になります。動作もまったく同じです。
気絶時間はGame SettingのfEssentialCompanionDeathTimeになります。バニラだと5秒です。重要なNPC、入植者、コンパニオン、プレイヤーも含めたすべてのNPCで共有されます。
ゲームエンジンレベルで処理されているので、何もしなくともアニメーションが破綻することもありません。むしろ下手に操作しないほうがいいです。
気絶中はラグドール中となるのでカメラが固定され、基本的な操作ができません。MCMで設定したホットキーは使えます。
気絶の検知
気絶を検知するにはOnEnterBleedoutを使います。
; イベントの捕捉を開始する RegisterForRemoteEvent(PlayerRef, "OnEnterBleedout") ; すると以下の関数が呼ばれるようになる Event Actor.OnEnterBleedout(Actor akActorRef) EndEvent
OnDeathと違って殺害者は取れないので、取りたいのであればOnHitを使って記録しておく必要があります。
復帰の検知
気絶から復帰したことを検知するための、ズバリの方法は見つけられませんでした。かわりとなるいくつか方法があります。
OnPlayerCameraState
気絶中はカメラが制御される仕様を利用した方法です。負荷も少なく検知漏れもないのでオススメです。
; 気絶したらカメラの変更の検知を開始する RegisterForCameraState() ; カメラが切り替わると呼ばれる Event OnPlayerCameraState(int aiOldState, int aiNewState) EndEvent ; 用が済んだら検知を終了する UnregisterForCameraState()
OnAnimationEvent
アニメーションイベントを見る方法もありますが、EssentialDownExitはアノテーションが設定されていないのか、イベントは検知できませんでした。
その他
あとは定期的にIsBleedoutを見るとか、Bleedout中だけ発動するスペルのOnEffectFinishを使うなどが考えられます。
キー入力
気絶中はOnKeyDownが効かないようです。
MCMのホットキーは使えるので、こちらであらかじめキーを設定しておくと、気絶中に何らかの操作をさせることができます。
気絶から強制的に復帰させる
コンパニオンの場合はスティムパックを使えばいいのですが、プレイヤーは自分に使えないようです。EquipItemでもダメでした。
fEssentialCompanionDeathTimeを動的に変更してみても、気絶の開始を持ってActorに時間が設定されるようで、気絶後にfEssentialCompanionDeathTimeを変更しても意味はありませんでした。
EssentialDownExitを再生させてもすぐにまた座ってしまいます。あくまでも起き上がるアニメーションをするだけで、内部的に設定されているであろうBleedout中であるフラグは初期化されないのでしょう。
気絶から復帰させないことで擬似的に実現する
ActorのSetNoBleedoutRecoveryをtrueに設定すると、fEssentialCompanionDeathTimeの時間が過ぎても、そのActorはBleedoutから復帰しなくなります。
SetNoBleedoutRecoveryをfalseに設定すると、fEssentialCompanionDeathTimeの時間が過ぎていればBleedoutから復帰します。
これを使うと、何らかのアクションを持って復帰するように見せかけることができます。
まず、fEssentialCompanionDeathTimeは十分に短い時間にしておきます。長すぎるとそれまでの間は復帰できないからです。
それから、あらかじめプレイヤーのSetNoBleedoutRecoveryをtrueに設定しておきます。
何らかのアクションがあったらプレイヤーのSetNoBleedoutRecoveryをfalseにして、プレイヤーが復帰するのを待ちます。
復帰したらプレイヤーのSetNoBleedoutRecoveryを再びtrueに設定します。
問題として、fEssentialCompanionDeathTimeは全NPCで共有しているため、NPCの復帰が早くなってしまいます。対策としては、NPC側でもスクリプトで同様の制御をすることです。