MCOの環境を作る

環境構築

MCOに手を出してみたので構築作業についてまとめます。

MCOについて

Attack MCO-DXP (MCO)はプレイヤーがコンボ攻撃を可能にするModです。さらにアイススケート現象を廃止する機能もあります。

Skyrim Combos AI Revolution (SCAR)はNPCもコンボ攻撃を可能にします。

今となっては日本語で解説してくれているブログ記事や動画がいくつもあるので、導入にはさして困らないと思います。実際のところ、アッサリと導入できてしまいました。

少し大変なのは、Skyrimのバージョン選びで、バージョンによって導入すべきModが変わったり、使えないModがあったりするところです。

参考にした情報源を紹介します。

MCO導入の是非について

個人的に最大の懸念事項が、Requiemに合わないから、という点です。

技術的な問題ではなく、ポリシーやモチベーション的に、Requiemの環境にコンボやパリー、バックスタブなどの戦闘系Modを入れると、Requiemが本来目指しているところから離れていきます。

結局のところ、遊んでいる本人が納得できて楽しければそれでいいと思います。

ドッジ

現在のドッジModは大きく分けて3つになるかと思います。

  • TK Dodge
  • The Ultimate Dodge Mod (TUDM)
  • Dodge – MCO|DXP (DMCO)

さらに、ドッジのモーションを変更するModもあります。

  • Dynamic Dodge Animation

私はThe Ultimate Dodge Modを使っており、TUDMありきで環境を構築していて、さらにTUDMにもかなり手を入れて改造しているため、他のドッジModにはなかなか移行しにくい状況です。

試しにDMCOを試してみたのですが、どういうわけか動作させられませんでした。

TUDMの問題が、攻撃をドッジでキャンセルできないということです。これを何とかしてみました。

TUDMで攻撃をドッジでキャンセル可能にする

正確にはTUDMはあまり関係なく、攻撃をキャンセルするModを作ってみた、という内容になります。

TUDMが攻撃をキャンセルできない理由は、TUDMのドッジが内部的にスニークだということです。スニークのモーションをドッジにすることで、「スニークする=ドッジする」としています。これがスクリプトフリーで遅延無しのドッジを可能にしています。

バニラでは攻撃を出している最中はスニークできません。なのでTUMDでも「スニークできない=ドッジできない」となるわけです。

良さそうな実装

リコイルを発生させ、即座に停止します。これで攻撃中ではなくなります。ここからならTUDMのドッジを再生可能なようです。再生するのはNPC用に用意されているRollStartイベントです。

TUDMのUDSKSEFunctionsScript.pscに実装してみた例です。

event OnKeyDown(int KeyCode)
	; メニューモードなら何もしない
	if Utility.IsInMenuMode()
		return
	endif

	; 押されたキーがドッジキーでないなら何もしない
	if KeyCode != DodgeKey
		return
	endif

	; プレイヤーの状態を確認する
	if PlayerRef.GetAnimationVariableBool("IsAttacking")
		; OK
		Debug.Trace("UDSKSEFunctionsScript OnKeyDown: OK (IsAttacking == true)")
	elseif PlayerRef.GetAnimationVariableBool("IsStaggering")
		; OK
		Debug.Trace("UDSKSEFunctionsScript OnKeyDown: OK (IsStaggering == true)")
	;/
	elseif PlayerRef.GetAnimationVariableBool("IsRecoiling")
		; OK
		Debug.Trace("UDSKSEFunctionsScript OnKeyDown: OK (IsRecoiling == true)")
	/;
	else
		; NG
		Debug.Trace("UDSKSEFunctionsScript OnKeyDown: NG")
		return
	endif

	; ラグドール中なら何もしない
	;if PO3_SKSEFunctions.GetActorKnockState(akTarget) != 0
	;	return
	;endif

	; ステートを移行してキー入力を無視する
	goToState("busy")

	; 無敵を開始
	PlayerRef.SetGhost(true)

	; アニメーションを変化させる
	UDPlayerIsGhost.SetValueInt(1)

	; 攻撃を止める
	Debug.SendAnimationEvent(PlayerRef, "recoilStart")
	Debug.SendAnimationEvent(PlayerRef, "recoilStop")

	; のけぞりを止める
	Debug.SendAnimationEvent(PlayerRef, "staggerStop")

	; ドッジ開始
	Debug.SendAnimationEvent(PlayerRef, "rollStart")

	; スタミナを消費
	PlayerRef.DamageActorValue("Stamina", StaminaCostS)

	; 無敵の終了を予約
	RegisterForSingleUpdate(IFrameS)

	Utility.Wait(1.5)

	; アニメーションを元に戻す
	UDPlayerIsGhost.SetValueInt(0)

	; ステートを元に戻す
	goToState("gamepad")
endEvent

event OnUpdate()
	PlayerRef.SetGhost(false)
endEvent

state busy
	event OnKeyDown(int KeyCode)
	endEvent
endState

UDPlayerIsGhostというグローバル変数を用意して、ドッジ中は1にするようにしました。これはOARで条件を指定するために使います。

OARの設定

OARで項目を追加して、条件を以下で作成します。

  • 対象がプレイヤー
  • グローバル変数UDPlayerIsGhostが1

あとはTUDMのアニメーションファイルをそのまま配置しました。sidestep_ で始まるファイルになります。

ダメだった実装

攻撃中にスニークを出せるようにするのは一筋縄ではいかないので、攻撃中にも出すことができるアニメーションをドッジモーションに置き換える手法を取ってみました。

TUDMのUDSKSEFunctionsScript.pscに実装してみた例です。

event OnKeyDown(int KeyCode)
	; メニューモードなら何もしない
	if Utility.IsInMenuMode()
		return
	endif

	; 押されたキーがドッジキーでないなら何もしない
	if KeyCode != DodgeKey
		return
	endif

	; ドッジ中なら何もしない
	if UDPlayerIsGhost.GetValueInt() != 0
		return
	endif

	; プレイヤーの状態を確認する
	if PlayerRef.GetAnimationVariableBool("IsAttacking")
		; 攻撃中なのでOK
	elseif PlayerRef.GetAnimationVariableBool("IsStaggering")
		; のけぞり中なのでOK
	else
		; それ以外なら何もしない
		return
	endif

	; ラグドール中に何もしない
	;if PO3_SKSEFunctions.GetActorKnockState(akTarget) != 0
	;	return
	;endif

	; 無敵を開始
	PlayerRef.SetGhost(true)
	UDPlayerIsGhost.SetValueInt(1)

	; 状態をリセットする
	Debug.SendAnimationEvent(PlayerRef, "staggerStop")

	; 後ろにのけぞるようにする
	PlayerRef.SetAnimationVariableFloat("StaggerDirection", 0.0)

	; のけぞりの大きさは概ね以下の通り
	; Small=0.1, Medium=0.5, Large=1.0
	PlayerRef.SetAnimationVariableFloat("StaggerMagnitude", 0.1)

	; ドッジアニメーションを再生
	Debug.SendAnimationEvent(PlayerRef, "staggerStart")

	; 無敵時間が経過するまで待つ
	; IFrameRを格納しているグローバル変数はMCMにある
	Utility.Wait(IFrameR)

	; 無敵を終了
	UDPlayerIsGhost.SetValueInt(0)
	PlayerRef.SetGhost(false)
endEvent

攻撃中にドッジキーを押すと、スニークが発動しないためTUDMの本来のドッジは出ませんが、このOnKeyDownイベントは常に発火しているため、攻撃中であるならSendAnimationEvent関数を使ってのけぞりを発生させます。

OARで置き換えるのけぞりのアニメーションは以下になります。ドッジのアニメーションをこの名前にかえて配置します。

1hm_staggerbacksmallest.hkx
2hm_staggerbacksmallest.hkx
2hw_staggerbacksmallest.hkx
h2h_staggerbacksmallest.hkx

ドッジのアニメーションはDynamic Dodge Animationのものを使いました。Dynamic Dodge AnimationはTUDMにも対応しており、攻撃キャンセルの条件も用意されているのですが、これを再生する方法がわかりませんでした。

これで後方ドッジができるようになります。

後方以外にもドッジできるようにするには、方向を指定するための仕組みが必要です。これにはdTry’s Key Utilsを使いました。

OARの項目を更に追加して、条件さらに加えます。

  • 対象がHasMagicEffect(Keytrace.espの0x802)を持つ

dTry’s Key UtilsのMagicEffectの一覧は以下になります。

方向FormID
0x801
0x803
0x802
0x804

前方ステップですが、Dynamic Dodge Animationの中身をみたところ、後ろステップのものになっており、そもそも前方ステップがないようです。紹介動画でも前方ステップを除いた7方向しか出しておらず、作っていないようです。

ステップの移動量が少ないと感じたため、hkanno64 Animation Annotation Tools for Skyrim SEを使ってanimmotionを編集して2倍にしました。

タイトルとURLをコピーしました