抜刀したまま、あるいはスニークしたままターミナルを使うと、使い終わった後は納刀したままだったりスニークを解除したままになってしまいます。毎度抜刀しなおすのは面倒なので、自動的に抜刀するようにしてみました。
サンプルコード
要件定義は、ターミナルの使用開始時の抜刀状態とスニーク状態を、ターミナルの使用終了後に再現することです。
ターミナル使用後に抜刀する (papyrus)
Scriptname SampleQuestScript Extends Quest
Actor PlayerRef
Bool LastSneaking
Bool LastWeaponDrawn
Event OnQuestInit()
PlayerRef = Game.GetPlayer()
RegisterForRemoteEvent(PlayerRef, "OnPlayerLoadGame")
EndEvent
Event Actor.OnPlayerLoadGame(Actor akActorRef)
RegisterForControl("Activate")
RegisterForMenuOpenCloseEvent("TerminalMenu")
EndEvent
Event OnControlDown(string asControl)
LastSneaking = PlayerRef.IsSneaking()
LastWeaponDrawn = PlayerRef.IsWeaponDrawn()
EndEvent
Event OnMenuOpenCloseEvent(string asMenuName, bool abOpening)
if !abOpening
Utility.Wait(0.5)
if LastSneaking && !PlayerRef.IsSneaking()
PlayerRef.StartSneaking()
endif
if LastWeaponDrawn
PlayerRef.DrawWeapon()
endif
endif
EndEvent
ターミナルの使用開始時に処理を行う
方法はいくつかあります。
RegisterForControlを使う
スクリプトだけで完結するので、とてもシンプルに実装できます。問題は、何かをアクティベートするたびにスクリプトが稼働してしまうことです。
PerkのEntry PointにActivateを指定して捕捉する
これはPerkが必要になるので少し面倒になります。作り方を間違えると他のModと競合したりターミナルを検出できないこともでてきます。
この方法はSkyrimでは問題なかったのですが、Fallout 4で同じように作ってみたところ、クロスヘアでターミナルを捉えている間にひたすらスクリプトのインスタンスが生成され続けるという、なんだかよくわからない致命的な問題が起きてしまいました。
RegisterForMenuOpenCloseEventを使う
このイベントが発火した時点では既に納刀が済んでしまっているので、抜刀していたのかを知ることができません。
その他
抜刀やスニークの切り替えの際に覚えておく方法もありますが、これは無駄な処理が多くなる気がします。
ターミナルの使用終了後に処理を行う
RegisterForMenuOpenCloseEventで大丈夫です。
最速で実行するとプレイヤーが処理を受け付けないので、少しだけ待ってからにします。