仕様かバグか分からないもの

2、3、4は私も悩まされたところでした!

2に関してはメルサイアさんのおっしゃるとおり、トリアコンタンさんに助けていただきました。:kaoluv:
4はKpoalさんと同じく、プラグインで対処しました。

3はいまだに解決しておりませんが、以前ツイッターでfukuさんに助言をいただきましたので、参考になれば。
「各キャラのターン終了処理(ここでステートのターンが経過する)」→「ターン終了イベントの起動」で処理してますが、ここで行動強制すると進行状態が「ターン終了」から「ターン処理中」に差し戻されターン終了処理が再度行われます。
私もスクリプトは素人なので手が出せていない状況です。:kaoswt:
知識のある方に解決していただけたら嬉しいところ……。


戦闘行動の強制に関しては、もうひとつ気になる動作があります。
ターン開始時に戦闘行動の強制を行うと、そのあとそのキャラが敏捷性にかかわらず最速で行動するんですよね。
最速すぎて防御すら不可能になります。:kaoeh:
どうやら戦闘行動の強制によって、次に行動するキャラが固定されてしまうようです。
たぶんバグなんじゃないかなーと思っています。
これを回避するために、別の透明なエネミーを一瞬だけ登場(あるいは復活)させて強制行動させ、
すぐに戦闘不能にする…という回りくどい手を使いました。
 
>チョコワ部さん
補足ありがとうございます! なるほど、「ターン処理中」に差し戻される、という現象だったのですね。納得です!

あと、もう一つの点。これも私にとってタイムリーでした! ターン開始時に戦闘行動の強制、よく使うので…。
5.ターン開始時に戦闘行動の強制を行うと、そのあとそのキャラが敏捷性にかかわらず最速で行動する
解決策も合わせて教えてくださり、ありがとうございます。
どなたかスクリプトに詳しい方に修正してもらえるのが一番ですが、どうにもならないときは試してみます。
 
最後に編集:

Kpoal

ユーザー
>チョコワ部さん
私も、現象からの推測でしかありませんが恐らくその流れで間違いないと思います。
解決に関してですが、「戦闘行動の処理」でターン処理中フラグが立つのは
恐らくどうしようもないと思うので、
(これがないと、普通に「戦闘行動の強制」をした場合でも元のターン処理に戻れなくなる)
修正するなら
「処理の優先度をバトルイベント>ターン終了時処理」
とするのが適切ではないかと思います。
デフォルトでは処理の方が優先度が高いため、

(全員の行動終了・turnendフラグON)→(処理)→(バトルイベント・戦闘行動の強制によりturnendフラグOFF)
→(全員の行動は終わっているため再びturnendフラグON)→(処理)

となっているのを、優先度を変えれば

(全員の行動終了・turnendフラグON))→(バトルイベント・戦闘行動の強制によりturnendフラグOFF)
→(turnendフラグON)→(処理)

とできるのではないかと考えました。
該当部は恐らくrpg_manager.jsのBattleManager.update部
BattleManager.update = function() {
if (!this.isBusy() && !this.updateEvent()) {
switch (this._phase) {
case 'start':
this.startInput();
break;
case 'turn':
this.updateTurn();
break;
case 'action':
this.updateAction();
break;
case 'turnEnd':
this.updateTurnEnd();
break;
case 'battleEnd':
this.updateBattleEnd();
break;
}
}
};
ここを適切に書き換えればいい気がするのですが、
そうするとまた別のバグが発生しそうで非常に怖いですね。
やはり、知識のある方に見てもらった方がいいのかもしれません。

追記
該当部間違ってたかもしれません。
これを見ると元からイベントの方が優先度が高いように見えますね。
また分からなくなってきました。

追記2
やっぱり無理です。
そもそもがステート等の更新はturnEndフラグによって呼び出されているのではなく、ターン中・全員の行動が終わった状態で実行されるendturnによるものでした。
この二つの優先度を変えるのは楽ではないので、
いっそのこと
battler.onTurnEnd();
this.refreshStatus();
を別の場所に移す事を考えた方がいいように思います。
それはそれでバグが怖いですが。

追記3
ひとまずプラグインを作るだけ作ってみました。
これにより少なくともこの問題は解決できることを確認しています。
ただし、追加でバグが出る可能性も十分考えられるので
その点はご注意を。
 

Attachments

最後に編集:

剣崎宗二

ユーザー
.お疲れ様です。横から失礼します。
当方の方で2.について解析した所、原理や関連する各functionについては把握したので、暫定の解決策を。
(原理はKpoalさんの既に掲示している物に近いですが…)

コード:
var BattleManager_startTurn = BattleManager.startTurn;
BattleManager.startTurn = function() {
    this._newturn = true;
    BattleManager_startTurn.call(this);
};

var BattleManager_endTurn = BattleManager.endTurn;
BattleManager.endTurn = function() {
    this._phase = 'turnEnd';
    this._preemptive = false;
    this._surprise = false;
    if (this._newturn)
    {
       this._newturn = false;
       BattleManager_endTurn.call(this);
    }
};

尚参考までに、今回の問題に関連する諸箇所は、
(蛇足にも程があるので隠しておきます。プログラムに興味のない方は見なくても…)
BattleManager.endTurn 
→(this._phase = 'turnEnd' でフェイズ確定。同時にターン終了時refresh系が起動、ステータスの持続数前進)

Game_Troop.prototype.meetsConditions
→(各ページの条件チェックでBattleManager.isTurnEndを呼び出し、phaseが'turnEnd'だった場合true返却。
この為BattleManager.endTurnとsetupBattleEventの優先度を反転する訳には行かない。
phaseがturnEndにならない限りイベントは実行されない→endTurnが先に動かないと全てが止まる)

Game_Troop.prototype.setupBattleEvent
→上記Game_Troop.prototype.meetsConditionsがtrueだった場合イベントをInterpreterに押し込む

BattleManager.update → BattleManager.updateEvent → BattleManager.updateEventMain
(上記Game_Troop.prototype.setupBattleEventを呼び出す。このルートは強制戦闘発動中にもう一度経由するが、その際はthis.isActionForced()がtrueになっておりprocessForcedActionを経由する。このprocessForcedAction終了時にもう一度BattleManager.endTurnが発動し…ターン終了時refresh系が起動、ステータスの持続数前進)
 

Kpoal

ユーザー
>剣崎宗二さん
詳しい解説ありがとうございます。
ところで、いただいたコードを入れてみても挙動に変化がなかったようなのですが、
どこか間違えてはいませんか?
知識不足で箇所の指摘ができず申し訳ありません。

追記
BattleManager.startTurnの方を競合回避処理をしていないもの
BattleManager.startTurn = function() {
this._newturn = true;
this._phase = 'turn';
this.clearActor();
$gameTroop.increaseTurn();
this.makeActionOrders();
$gameParty.requestMotionRefresh();
this._logWindow.startTurn();
};
に自分で置き換えたところちゃんと動作したので、ここに何か文法ミス等ありそうな気がします。

追記2
分かりました。
1行目
var BattleManager_startTurn = BattleManager.startTurn;
の最後だけ、セミコロンが全角文字になっています。
そこだけ直したところ正しく動作しました。
 
最後に編集:
>剣崎宗二さん
ありがとうございます!!
やはりスクリプトに詳しい人に手伝ってもらえると、解決が早くなり、とてもありがたいです。

>Kpoalさん
1行目のセミコロン全角は、私も気づきませんでした。Kpoalさんすごい!
私の方でもテストしたところ、症状が治りました(先ほどの動画で、TPが二重で回復しなくなった)。
これで気にせずに「ターン終了時」に戦闘行動の強制できますね!
もし可能でしたら、多くの人にバグ修正プラグインとわかるように、他のプラグイン開発者の方の慣習に倣って
・BugFix_***.jsという名前のプラグインで
・説明文に「ツクールアップデートver.1.5.0にて」を追加して
・MITライセンスで
改めてjsファイル化して添付もらえると、大変助かります。
 
最後に編集:

Kpoal

ユーザー
>メルサイアさん
分かりました。
そのようにして添付します。
一応剣崎宗二さんのものも同様にしてプラグイン化しておきます
(BugFix_New_turnend_update2.jsの方です)
が、もし問題があれば言って下さい。

二つあるうちどちらでもバグを回避できることは変わりませんが、
剣崎宗二様のものの方が競合はしにくく、
自分の物は競合しやすく、またターン終了時処理がバトルイベント終了後に実行される
という特徴があります。

一応、自分の処理はプレイヤーが防御を選んでいた場合、
イベント行動が終わってから防御が解除されるので
敵の攻撃を防御で防ぎやすくなるという利点がありますが、
競合回避が難しいのでどっちがいいかはプレイヤー次第だと思います。
 

Attachments

Kpoal

ユーザー
おまけ
大して役に立たない(役に立つ場合の少ない)仕様の話です。
乗り物に乗って移動している時、
内部処理的にはプレイヤーを透明化して船のグラフィックの上に乗せ、
それを移動させているのですが、
このプレイヤーの透明化、普通にイベントコマンドで行う「透明状態」と
同じフラグを使っている事が分かりました。
そのため、船に乗っている時にうっかり「透明状態のOFF」を実行したりするとこうなります。
MVship.png
この状態でも普通に移動もできますし、見えてはいけないものが見えている以外は
挙動は普段と変わりないんですけどね。
一応、船に乗った状態でプレイヤーを見えなくしたいイベントを起こす場合、
「乗り物のグラフィック変更」を使う様にしましょう。
 

剣崎宗二

ユーザー
>Kpoalさん
失礼いたしました…ツクール環境のない出先で応答したため、1行目全角のままでした…申し訳ありません。
プラグイン化については、こちらも異論はございません。
 
「選択肢の表示」で「デフォルト」を「なし」に設定したものは、無選択の状態から上キーを押すと、下から2番目の選択肢にカーソルが出ます。これは一番下の間違いでは…? バグなら、アップデートで修正して頂かなくては…
 

Kpoal

ユーザー
現象を確認して来ました。
恐らく原因は、選択肢のカーソル移動で上端から上を押したときに、
現在地が0の場合の例外処理を入れていないためだと思われます。
choice_zukai1.gif
該当するプログラム部分は
rpg_windows.jsの
Window_Selectable.prototype.cursorUp
だと思われますが、
これは「選択肢の表示」以外にもかなり多くの場所から参照されている部分なので、
修正の為に手を出すのは怖いですね。

詳しい方に見ていただくか、公式のアップデートを待つべきだと思います。
(幸い、そこまで致命的バグというわけでもないようですし)
 

ツミオ

ユーザー
コード:
(function() {

    var _Window_ChoiceList_cursorUp = Window_ChoiceList.prototype.cursorUp;
    Window_ChoiceList.prototype.cursorUp = function(wrap) {
        if(this.index() === -1 && $gameMessage.choiceDefaultType() === -1){
            this.select(this.maxItems()-1);
            return;
        }

        _Window_ChoiceList_cursorUp.call(this, wrap);
    };

})();
暫定的にですが、修正してみました(もっと詳しい方に修正していただきたいです)。
上記のコードをプラグインとして取り込めば動作します。
デフォルトの状態なら問題ないと思いますが、選択肢を改造する系のプラグインを追加している場合、競合するかもしれません。

追記:
プラグイン化したので、これを普通のプラグインと同じように導入すれば使用可能です。
 

Attachments

最後に編集:
別のネタです。
スキルの「命中タイプ」を「必中」にして「使用効果」に「ステート付加」を付けると、対象の「ステート有効度」を無視して必ずステートに罹っちゃうんですよね。
コレ、困るんですよねぇ…毒付加のブレスが、毒防止アクセサリーでも防げなくなったりして。
かと言ってブレスを「物理攻撃」や「魔法攻撃」にするのも違うんですよね…回避したり反射したりできちゃうし。
なんとかならないもんでしょうか??
 
別のネタです。
スキルの「命中タイプ」を「必中」にして「使用効果」に「ステート付加」を付けると、対象の「ステート有効度」を無視して必ずステートに罹っちゃうんですよね。
コレ、困るんですよねぇ…毒付加のブレスが、毒防止アクセサリーでも防げなくなったりして。
かと言ってブレスを「物理攻撃」や「魔法攻撃」にするのも違うんですよね…回避したり反射したりできちゃうし。
なんとかならないもんでしょうか??
個人的には「ブレスをかわす」ことは違和感がなかったりします。
ただ、遠距離攻撃に対して剣でカウンターを仕掛けたりできるのはちょっと困りますね。
というわけで、「カウンターされない物理攻撃」や「反射されない魔法」を作ることができる
プラグインを作っていたのでアップロードします。
 

Attachments

Kpoal

ユーザー
>アリヒコットさん
ありがとうございます。
「必中スキルでは相手のステート有効度を無視する」について
このスレッドで前にも一度出ていましたが、改めまして。

この問題はバグなのか意図された仕様なのか、正直よく分かりません。
基本的には不便で問題になる事の方が多いですが、
『耐性のある敵でも確実にステートにする事ができる』チートスキルを作る上では便利だったり、
システム的に絶対にステートにしたくないのであれば『ステートの無効化』が使えたりしますし、
そもそもVXAceまではこんな仕様はなかったのに、
MVになってから新しく付け加えた開発の意図も分かりません。

ただ、やはりこんな仕様はない方がいいという方がほとんどでしょうし、
そういった方は前の方でメルサイアさんが紹介されている
トリアコンタンさん作成のバグ修正プラグインを入れるべきかと思います。
 

Kpoal

ユーザー
>アリヒコットさん
確かに、即死に関してはその通りですね。
それ以前に必中の即死ステートの存在自体が問題ではありますが。
(FF6のバニシュデス並みのボスキラーになってしまいます)

やはり、まずはこういった仕様があるという事を周知しておく事が第一でしょう。
知ってさえいれば意図して回避する事もプラグインで防ぐ事も出来ますが、
こんな仕様があると知らなければかなりの確率で
バランス崩壊級のバグを起こしてしまう事になりかねませんので。
影響が大きいだけに、より多くの人に知れ渡るべき仕様(バグ?)だと思います。


ここからは別件になりますが、乗り物関連で一つ。
少し前で船に乗っている時の透明化処理について書きました。
船での移動中はプレイヤーを透明化して船のグラフィックの上に乗せており、
その透明化処理は普通の「プレイヤーの透明化」と同じフラグを利用しているという話でしたが、
これに関連して、飛行船でも似たような事をしていると分かりました。

飛行船に乗っている間は、地形を無視し、
イベントとも接触する事がない状態で移動ができますが、
この時の(飛行船に乗り込む際の)処理で、プレイヤーのすり抜けをONにしている、
すなわち「移動ルートの設定」における「すり抜けON」と同じものを
プレイヤーに適用しているようです。

ただ、飛行船での移動中はそれとは別に地形を無視するフラグが立っているようなので、
すり抜けをOFFにしても海や山の上を飛べる事は変わりません。
では何が変わるのかと言いますと、
実はこれによって「プライオリティ:通常キャラと同じ」のイベントだけは
通過できなくなるのです。

基本飛行船は世界中どんな場所でも飛び回れる最終盤の乗り物で、
マップの果て以外にこの移動を妨げることはできませんが、
飛行船乗船後に何らかの方法ですり抜けをOFFにする事で、
「飛行船でも移動できない箇所」を作ることができるわけです。
高い山で飛行船でも飛び越えられない、といった場所に使えるのではないでしょうか。

ただし、プライオリティが同じイベントでも、
接触や決定ボタンにより起動できるわけではありません。
そこもまた、すり抜けフラグとは別に飛行船での移動中はイベント起動不可という
例外処理が組み込まれているようです。
(こうして見ると、飛行船乗船時にすり抜けフラグをONにする意味が
同プライオリティイベントの通過以外にないわけで非常に無駄な気がしてきますが)
 

Kpoal

ユーザー
以前ここで紹介した
ターン終了時イベントで「戦闘行動の強制」をさせると、ステートなどのターンカウントが2進む
というバグについて、
ちょっと自分で読んでいて分かりにくいかなと思うところがあったので、
改めて分かりやすいようにまとめてみます。



まず、ターン終了時処理について
 ・「ターン終了時に解除」ステートのターンカウント進行
 ・能力強化・弱体のターンカウント進行
 ・HP、MP、TP再生率による増減(毒・リジェネ効果など)
これらをまとめて行うのがBattle.onTurnEndで、
全員の通常行動が終わっていて、なおかつ実行のフェイズが'turnEnd'でないなら実行されます。
ひとまずこれを『ターン終了処理』と呼びます。

一方、実行条件を「ターン終了時」にしたバトルイベントは、
'turnEnd'フェイズであり、
なおかつスパンで定められた回数を満たしていなければ実行されます。

通常の流れでは、
---------------------------------------------------------------
敵味方の全員が、定められた通常行動を実行。

条件を満たしたので『ターン終了処理』を行う。
同時にフェイズ'turnEnd'に

'turnEnd'フェイズになったので
「ターン終了時」バトルイベントを実行。
スパンからして繰り返す必要がなければ次のターンへ移行
----------------------------------------------------------------
といった実行の流れになります。
turnEnd_zukai1.png

この通り、基本的にターン終了処理は「ターン終了時」バトルイベントよりも前に実行されます。
そのため、例えば溜め攻撃をターン終了時イベントで行動強制させる事で作ろうとした場合、
------------------------------------------
敵が溜める
→プレイヤー、攻撃に備え防御を選択
→ターン終了処理により先に防御解除
→バトルイベント・敵の溜め攻撃
------------------------------------------
といった理不尽な事態が発生してしまう事もあります。
一方で、ターンの最後にキャラのHPを取得して~などといったイベントを作る場合には、
HP再生率によるリジェネorスリップダメージが済んでからイベントでHPを取得する事になるので、
この仕様が便利に働きます。


ここまでは基本の流れなのですが、このバトルイベントの中で
「戦闘行動の強制」を行っていた場合、話が変わってきます。
戦闘行動の強制はその処理の都合上、
行動前に一度フェイズを'action'に変え、
その後通常の処理に戻すためにフェイズ'turn'に戻す、といった事をしています。
これが敵味方にまだ行動待機中のキャラがいる場合に実行するのであれば問題はなかったのですが、
全員の行動が済んだ後、「ターン終了時」イベントの中で実行した場合、
フェイズが'turnEnd'から'turn'に巻き戻る、という現象が発生します。

その結果、
全員の通常行動が終わっていて、なおかつ実行のフェイズが'turnEnd'でないという条件を再度満たした事になり、
『ターン終了処理』が再び実行されてしまう、というわけです。
turnEnd_zukai2.png

これを私は簡略化して
ターン終了時イベントで「戦闘行動の強制」をさせると、ステートなどのターンカウントが2進む
と書いており、少し誤解を招く表現になってしまっていました。
 
最後に編集:
トップ