特殊ヒット研究室(2009/11/27 TargetDropを削除、persistentについて加筆・修正など、12/01 ヘルパー対策を追加)

特殊なヒットステートに移行させる攻撃を設定する時、よく使われているのがHitDefステート内のP2StateNoです。
元々Mugenの仕様からして、これを使うのは当然であるはずなのですが、実はこの部分にはバグがあります。
ブロッキングなどによく使われるHitOverrideステートとかち合った場合、両方の処理が無視されてしまうのです。

そこで推奨するのが、P2StateNo設定部分を削除し、代わりにTargetStateステートを使う方法です。
(「対投げ技用ブロッキング」などは作成されないでしょうから、投げ技にこの処理を行う必要はないでしょう)
しかし、適当にステートを組んでみたところ、
複数の相手に攻撃を当てた際、一人にでもガードされると、ヒットした相手のステート移行も妨がれてしまうとか、
複数の相手に攻撃を当てた際、一人でもヒットしていると、ガードした相手までステート移行されてしまうとか、
恐ろしい事に、同じ状況でも攻撃のタイミングによって全く違った(しかも矛盾した)複数のバグが発生する事態に。
これを修正する方法として、


などといった方法も考えたのですが、本質的に上と同じ問題が立ちはだかり難航しましたorz

どういうことかと言いますと、実は相手が複数の場合、参照先が複数になりえるトリガーやリダイレクト機能、
例えばP2StateNoやTarget,StateTypeなどは参照先を特定せず、適当に情報を送り返してくるのです。
MoveHitやMoveGuardedも同様で、例えば1人ガード、1人ヒットした時には両方とも0か1を適当に返してきます。
(正確には「処理順が後になった方の情報で上書き」ですが、その処理順が固定ではないのが原因のようです)
これでは情報が混ざってしまい、正確な処理が行えなくなってしまいます。
ステートが自動的に、相手ごとの情報を特定して処理してくれれば楽だったのですが。


その上、複数のTargetを区別する代表的な方法・GetHitVar()はMoveTypeがHでなければ使えず、
プレイヤーIDを取得することもできず、バグで強制終了されるものさえあります。
(EnemyNear,GetHitVar()のようにリダイレクトすれば、その参照先のMoveTypeがHの場合は使えるようです)
……これがまた、よりによってGetHitVar(HitID)……!(同じ情報を返す、GetHitVar(ChainID)は使えるようです)
正規に相手のステートを変更する方法はTargetによるものしか存在しないのに、本当に頭の痛いところです。
MUGENの開発が進んでいれば、この辺もちゃんと整理されたんでしょうに、残念ですね。
どうしようもないバグは他にもあるし、誰かMUGEN本体を直してください……。←おい


という事で前置きが長くなりましたが、ステート例を掲載しておきます。
通常のシングル戦では問題ないはずです。
上記の問題があるため、タッグ戦などへの完全な対応は(MUGEN本体を何とかしない限り)不可能でしょう。


;☆攻撃ステート・HitDefの後に追加
[State TargetState]
type = TargetState
triggerall = NumTarget
trigger1 = MoveContact;必要ならトリガーの追加・整理を行ってください
value = 299;P2StateNoで指定していたステート番号です
persistent = 0;相手を何度も特殊ステートに送らないようにします
ignorehitpause = 1;ヒットストップ時にも動作します

NumTargetは、「NumTarget(290)」のようにIDを指定する事が可能です。
ここで指定するIDは、HitDefで設定するヒットIDです。プレイヤーIDとは違うので注意してください。
これによって、複数のHitDefがある場合でも、特定のHitDefだけを選別することができる……はずなのですが、
例によって相手が複数だとうまく機能しません。使用は断念しました。
トリガーでの条件設定は、相手の情報を参照しないなら完全に動作します。状況に応じて追加してください。
(例えば、多段ヒット技の特定の攻撃判定のみに適用するなら、トリガーでAnimElemTime()を限定するなど)
ヒット直前の相手の情報を参照するトリガーでは、結局のところ不正確なTarget,PrevStateNoなどを使用するしかないようです。
また、Target,StateTypeやTarget,MoveTypeはヒット後の情報(5000番などのステートに一度飛んでしまう)を参照するため、
無意味になってしまいます。何かいい方法はないものでしょうか……。

今回の肝はMoveContactです。
ガードしてても飛ばされることがあるのなら、いっそ最初から問答無用で飛ばしてしまおうという発想です。
この後、飛ばされた先のステートで、ガードしていた場合は元に戻すようになっています。

ちなみに、ここでは「persistent = 0」設定になっています。
手元の資料では省略可能とあったのですが、省略すると「persistent = 1」設定になってしまうようです。
「persistent = 1」設定にすることは、大変なバグを引き起こす原因になるため推奨しません。
例えばこの技で相手を吹き飛ばし、復帰前にもう一度この技を出すと、
たとえ空振りでもまた相手を吹き飛ばしてしまうという事態が起こり得ます。注意してください。
また、MoveHitResetを使用する場合は、TargetStateよりも後に(下に)設置しないと、ヒット確認ができなくなることがあります。
MoveHitResetが常時監視ステートなどになっている場合は、TargetStateも常時監視ステート(-2)に設置するのがいいでしょう。

次は、移動先ステートです。


;☆移動先ステート
[Statedef 299]



movetype= H;必ずHにしてください



[State SelfState]
type = SelfState
trigger1 = GetHitVar(Guarded);ガードしていた場合
trigger2 = IsHelper;ヘルパーの場合
value = PrevStateNo;元のステートに戻る

ここではGetHitVar()を使用するために、必ずmovetypeがHになっていなければなりません。
とは言え特殊ヒットステートなのですから、普通はHになっていると思います。
GetHitVar(Guarded)は最後の肝。本当に丁度いいトリガーがあったものです。

応用として、ここから通常のヒットステート(5000番など)に戻す手法もあります。
その場合は、TargetStateステートのトリガーに「Target,PrevStateNo != 299(特殊ステート番号)」を指定する必要があります。
ただし、Target,PrevStateNoは(存在するだけで)デバッグモードでエラーを垂れ流します。
おそらく実害はありませんが、鬱陶しいバグです。

追記:Target,PrevStateNoのバグは、トリガーにNumTargetを使うことで回避できるとのことです。。
   実は手元のキャラではNumTargetも使っていたのですが、
   「NumTarget && Target,PrevStateNo != 〜」と、2つを同じ行にまとめていたのが問題だったようです。
   Target,PrevStateNoを次の行のトリガーに隔離したら直りました。
   FeSiXさん、情報提供どうもありがとうございましたm(_ _)m

IsHelperは、自分がヘルパーであるかどうかを判断するトリガーです。
特殊ヒットステートにヘルパーを巻き込んでしまうと分身バグの原因となりますので、ここでヘルパーにはお帰り願います。



おまけ:P2StateNo、TargetStateの指定先ステートでの注意事項

参考:クリエイターズJAPAN2様


MUGEN研究所へ戻る
MENUへ戻る