【解決済み】自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

アバター
ビービー
記事: 303
登録日時: 2016年1月12日(火) 18:40

【解決済み】自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by ビービー » 2016年11月12日(土) 17:15

プラグインを作成してみたのですが、自分ではできない事が複数出てきてしまったので、お力をお借りしたく依頼することにしました。
BB_StateDamageSetup.js
(7.42 KiB) ダウンロード数: 12 回


まずはこのプラグインがどういう物なのかを説明します。
このプラグインは戦闘中ターン終了時にパラメータで指定した変数の値もしくはパラメーターで指定した値のダメージを与えるものです。
与えるダメージには乱数を足したり、クリティカル率を設けたり、クリティカル時の倍率を指定したりできます。
そしてダメージを与えた時と、クリティカルが発生した時にパラメータで指定したアニメーションを表示する事もできます。
ちなみに指定した値が正数の場合、回復もできます。


ここから追加していただきたい機能について説明します。
追加していただきたい機能は大きく分けて3つです。

一つ目は、ステートの効果が発生した際に、バトルログを表示できるようにしていただきたい。
バトルログは通常攻撃と同じように3段階の表示が好ましいです。
例:
〇〇〇〇〇〇〇〇(ステートの名前など指定した文字列)
会心の一撃!(クリティカルが発生した場合)
〇〇は△△のダメージを受けた

二つ目は、パラメータでの指定ではなく、ステートのメモ欄で指定できるようにしていただきたい。
メモ欄で指定したいのは
・敵に与える数値(変数ID)
・バトルログの1段目に表示される文字列
・乱数(メモ欄に記入がない場合は0)
・クリティカル発生率(変数ID、メモ欄に記入がない場合は発生率0%)
・ダメージを与えた時に表示するアニメーションID(メモ欄に記入がない場合は表示しない)
クリティカルダメージの倍率とクリティカル発生時に表示するアニメーションはパラメータでの指定のままでも問題ないと考えています。
それとこのメモ欄での指定で毒などのHP再生率系のステートにも、”バトルログの表示”と”ダメージを与えた時にアニメーションを表示”できるようにしていただきたいです。

三つ目は、毒などのHP再生率系のステートやこのプラグインで作成したステートの重ね掛けを可能にしていただきたい。
現在、このプラグインでは毒と同時にこのステートにかかっている場合こちらのステートが優先されてしまっています。
なのでターン終了時にステートのダメージを受けるタイミングでは、ステートのIDが若い順にひとつづつステートのダメージが入るようにしていただきたいです。
その際に、同じステートにかかっているキャラが複数いる場合は、Trbさんが作成された”全体攻撃スキルで全員同時にダメージを与えるプラグイン”PromptlyPopup.js(http://tm.lucky-duet.com/viewtopic.php?f=49&t=1216)と同じような挙動にしていただけるとありがたいです。

以上の三つが改変していただきたいことになります。


1から作った方が早い場合は改変でなくても問題ありません。
そして全部が全部私が言ったとおりにしていただかなくても問題ありません。

大変な改変になるかと思いますが、どうかよろしくお願いします。
最後に編集したユーザー ビービー on 2016年11月22日(火) 19:01 [ 編集 1 回目 ]

------------------------------------------------------
Twitterやってます。
https://twitter.com/BB_ENTER
ブログもやってます。
http://bb-entertainment-blog.blogspot.jp/
アバター
剣崎 宗二
記事: 437
登録日時: 2016年11月12日(土) 20:36
連絡を取る:

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by 剣崎 宗二 » 2016年11月18日(金) 00:29

どなたも応答していないようなので、先ずは提案と言うか、参考意見を。
(アイデアはあるのですが、現状自作ゲーム側が忙しく、今すぐに作ってデバッグはスケジュール上やや困難な為)

「ターン終了時、ステートが掛かっている場合自動的に指定されたスキルを使用する」
プラグインを作る、と言うのは如何でしょうか。
これにより実現できるのは以下です。



【既存機能の再現】
『自身に指定された式のダメージが発生する』
スキルの対象を使用者とし、HPダメージ効果を出せばできますし、数値等は該当スキルの計算式に記述すれば可能でしょう。
(http://ktnhmv.jugem.jp/?eid=9 kotonohaさんが様々な計算式の運用方法を解説してます)

『クリティカル』
発動するスキル自体にクリティカルを設定すれば可能かと思います。


【追加をお願いされた要件】
『バトルログの表示』
スキルの発動ですので、当然バトルログが表示されます。指定文字列はスキルデータに設定すれば済むかと。

『ステートのメモ欄での指定』
ステートのメモ欄にスキルIDを記述し、各種実データをスキル自体に仕込む事によって可能です。
クリティカル発生率についてはスキルのクリティカル率を変動させる各種プラグインを併用する事になりますが。
アニメーションもスキルのアニメーションが表示されます。
HP再生率系につきましては、デフォルトの『HP再生率』ではなく、発動するスキルの計算式でダメージをa.mhp * rate (rate = ダメージ率)にする事で可能かと。

『重ね掛け』
技の発動ですので、全ステートをループで確認していく動作の場合可能かと思います。
ただ、ステートを順に確認していくプロセス上、「全体攻撃スキルで全員同時にダメージを与える」ような挙動は難しいかも知れません。
(不可能ではありませんがかなりの作業を要し、労力に対する効果が少ないように思えます)



現状では飽く迄も「こうやればできるかも知れない」と言う提案ですので、若しもビービーさんが御自分でこう言った物が作れるようであれば直接作ってもらった方が早いですし、そうでなければ何れ自分の手が空き次第作る予定です。
無論、他にもっと良いアイデアがある方がいらっしゃれば、そちらを採っていただいた方がいい可能性もあります。
以上、ご参考までに。
----
-出先に居る場合回答が未テスト状態である事が多い為、テストは重々にお願いいたします。
アバター
ビービー
記事: 303
登録日時: 2016年1月12日(火) 18:40

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by ビービー » 2016年11月18日(金) 11:29

剣崎宗二さん、忙しい中返信ありがとうございます。

なるほどスキルにするとは盲点でした。
たしかにこちらの方がダメージ計算式で色々できたり都合が良さそうですね。
バトルログもアニメーションも会心もデフォルトの機能で実装できますし、本当に素晴らしいアイディアな気がします。

結構難易度高そうですが一度自力で挑戦してみます。

アドバイスありがとうございました。
------------------------------------------------------
Twitterやってます。
https://twitter.com/BB_ENTER
ブログもやってます。
http://bb-entertainment-blog.blogspot.jp/
アバター
ビービー
記事: 303
登録日時: 2016年1月12日(火) 18:40

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by ビービー » 2016年11月19日(土) 21:08

自力で何とかターン終了時にメモ欄に<state_skill:スキルのID>という記述があるステートにかかっている場合スキル発動というところまでできました。

しかしなぜか戦闘行動の強制で発動したスキルが何度もループしてしまいます。
どうすればループしないようにできますでしょうか?

またスキル発動時に一歩前に出るのを無くす方法も教えていただければありがたいです。

コード: 全て選択

var _Game_Battler_prototype_onTurnEnd = Game_Battler.prototype.onTurnEnd;
Game_Battler.prototype.onTurnEnd = function() {
    this.clearResult();
    this.regenerateAll();
    this.updateStateTurns();
    this.updateBuffTurns();
    this.removeStatesAuto(2);

    for (var i = BBSmin; i < BBSmax + 1; i++) {//パラメータで指定したステートの範囲を判定
        if (this.isStateAffected(i)) {//判定中にそのステートにかかっているバトラーがいた場合
            var SkillID = $dataStates[i].meta.state_skill;//ステートのメモに書いてあるIDをSkillIDに
            this.forceAction(SkillID, -2);
            BattleManager.forceAction(this);
        }
    }
};

ちなみに処理が軽くなればいいなと、パラメータで指定した範囲のステートのみを判定するようにしてみたのですが、意味はありますでしょうか?

よろしくお願いします。
添付ファイル
BB_TrunEndStateSkill.js
(2.59 KiB) ダウンロード数: 7 回
------------------------------------------------------
Twitterやってます。
https://twitter.com/BB_ENTER
ブログもやってます。
http://bb-entertainment-blog.blogspot.jp/
アバター
トリアコンタン
記事: 2116
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by トリアコンタン » 2016年11月20日(日) 00:45

お疲れさまです。
スキルが延々と実行されてしまう原因は、全員分の行動が終了した後に実行されるターン終了処理で
さらに行動を強制しているので、ターン終了処理が何度も実行されてしまうためです。

応急処置として、単純ですが、フラグを持たせてスキルが一度しか実行されないように修正するのもひとつの方法です。
こんな感じになります。

コード: 全て選択

    //=============================================================================
    // BattleManager
    //  ターン開始時にステートスキルフラグを解除
    //=============================================================================
    var _BattleManager_startTurn = BattleManager.startTurn;
    BattleManager.startTurn = function() {
        this._executeEndTrunSkill = false;
        _BattleManager_startTurn.apply(this, arguments);
    };

    var _BattleManager_endTurn = BattleManager.endTurn;
    BattleManager.endTurn = function() {
        _BattleManager_endTurn.apply(this, arguments);
        this._executeEndTrunSkill = true;
    };

    BattleManager.isExecuteEndTurnSkill = function() {
        return this._executeEndTrunSkill;
    };

    // ターン終了時ステート効果追加
    var _Game_Battler_prototype_onTurnEnd = Game_Battler.prototype.onTurnEnd;
    Game_Battler.prototype.onTurnEnd = function() {
        // ステートスキルフラグが設定されていれば終了
        if (BattleManager.isExecuteEndTurnSkill()) return;

        this.clearResult();
        this.regenerateAll();
        this.updateStateTurns();
        this.updateBuffTurns();
        this.removeStatesAuto(2);

        for (var i = BBSmin; i < BBSmax + 1; i++) {//パラメータで指定したステートの範囲を判定
            if (this.isStateAffected(i)) {//判定中にそのステートにかかっているバトラーがいた場合
                var SkillID = $dataStates[i].meta.state_skill;//ステートのメモに書いてあるIDをSkillIDに
                this.forceAction(SkillID, -2);
                BattleManager.forceAction(this);
            }
        }
    };
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
アバター
ビービー
記事: 303
登録日時: 2016年1月12日(火) 18:40

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by ビービー » 2016年11月20日(日) 02:04

トリアコンタンさん返信ありがとうございます。助かります。

トリアコンタンさんの書かれたコードをコピーしたところループしなくなりました。
ありがとうございます。


残る大きな問題はあと2つあります。

一つはステートにかかっているバトラーが複数いても一体しか反応しないという物です。
同じステートをアクター、エネミー全員に付与しても、エネミー一体にしか判定が入らないのです。
恐らく

コード: 全て選択

this.forceAction(SkillID, -2);
BattleManager.forceAction(this);

この部分が問題なのではないかと思っているのですがどうでしょうか?
もともと戦闘行動の強制は

コード: 全て選択

    this.iterateBattler(敵キャラかアクターか, 対象ID, function(battler) {
        if (!battler.isDeathStateAffected()) {
            battler.forceAction(スキルID, 対象指定);
            BattleManager.forceAction(battler);
            this.setWaitMode('action');
        }
    }.bind(this));

という物を、とにかくエラーが起きないようにしようとした産物で、自分でも何が何だかよくわかっていません。
色々やってみてはいるんですが、なにをやってもエラーになり困り果てているのが現状です。


次に二つ目の問題はこのステートによるスキル行動時に一歩前に出るのを抑制したいというものです。
こちらは別のプラグインを作りメモ欄に記載があるスキルは一歩前に出ないようにしようと
Sprite_Actor.prototype.updateTargetPositionをいじってみたのですがうまくいきませんでした。
そもそもメモ欄に記載がある場合というif文がよくわかってない始末なので、遅々として作業が進みません。


以上、二点のヒントやアドバイスなどいただけたらありがたいです。
もちろん私の書いたやり方でないものでもかまいませんので、情報提供おねがいします。
------------------------------------------------------
Twitterやってます。
https://twitter.com/BB_ENTER
ブログもやってます。
http://bb-entertainment-blog.blogspot.jp/
アバター
トリアコンタン
記事: 2116
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by トリアコンタン » 2016年11月20日(日) 11:57

お疲れさまです。
ひとりしかスキルを実行してくれない直接の原因は、
BattleManager.forceAction(this);を、条件を満たした全バトラーに対して実行することで、情報(BattleManager._actionForcedBattler)を上書きしてしまうためです。
そこで、一度強制実行を行ったバトラーに対しては、実行をしないように新たなフラグを設けます。

もともとループされていたことを利用して、条件を満たすバトラーがいなくなるまで何度も
「BattleManager.endTurn」を実行します。

ただし、1ターンに複数回「BattleManager.endTurn」が実行されることは、本来の動作からすると想定外です。
「Game_Battler.prototype.onTurnEnd」の既存処理が何度も実行されるのは問題なので
「強制実行を行った」フラグとは別に「onTurnEndを実行した」フラグも必要になります。

一歩前に出てしまう件については、一旦ツイッターであがっていたプラグインをお試しください。

コード: 全て選択

//=============================================================================
// BattleManager
//  ターン開始時にステートスキルフラグを解除
//=============================================================================
var _BattleManager_startTurn = BattleManager.startTurn;
BattleManager.startTurn = function() {
    _BattleManager_startTurn.apply(this, arguments);
    this.allBattleMembers().forEach(function(battler) {
        battler.clearExecuteOnTurnEnd();
    });
};

Game_Battler.prototype.clearExecuteOnTurnEnd = function() {
    this._executeOnTurnEnd = false;
    this._executeTurnEndSkill = false;
};

// ターン終了時ステート効果追加
var _Game_Battler_prototype_onTurnEnd = Game_Battler.prototype.onTurnEnd;
Game_Battler.prototype.onTurnEnd = function() {
    // ターンエンド実行フラグが設定されていれば既存処理はスキップ
    if (!this._executeOnTurnEnd) {
        this.clearResult();
        this.regenerateAll();
        this.updateStateTurns();
        this.updateBuffTurns();
        this.removeStatesAuto(2);
        this._executeOnTurnEnd = true;
    }

    // ターンエンドスキルの実行
    if (!this._executeTurnEndSkill && !BattleManager.isActionForced()) {
        this.applyTurnEndSkill();
    }
};

Game_Battler.prototype.applyTurnEndSkill = function() {
    for (var i = BBSmin; i < BBSmax + 1; i++) {//パラメータで指定したステートの範囲を判定
        if (this.isStateAffected(i)) {//判定中にそのステートにかかっているバトラーがいた場合
            var SkillID = $dataStates[i].meta.state_skill;//ステートのメモに書いてあるIDをSkillIDに
            this.forceAction(SkillID, -2);
            BattleManager.forceAction(this);
            this._executeTurnEndSkill = true;
        }
    }
};
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
アバター
剣崎 宗二
記事: 437
登録日時: 2016年11月12日(土) 20:36
連絡を取る:

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by 剣崎 宗二 » 2016年11月20日(日) 12:37

お疲れ様です。
すでにトリアコンタン様が回答を行っておりますが、自分は別ルートからのアプローチを。(自作ゲームでも「ターン終了時に敵全体にダメージを与えるフィールドスキル」という形で利用するので、時間をかけてみました :D

仕組みとしてはonTurnEndに於いてはアクションリストへの「登録」のみを行った後1アクションのみ起動し、endActionを利用してアクションリストが消化されるまでStartActionを連鎖させ、その後"action"に切り替わっていたphaseを元の"turnEnd"に戻し正常に続行させると言うものです。

BB_TrunEndStateSkill_v0.2.js
(4.4 KiB) ダウンロード数: 20 回


全体攻撃、複数State等一通りテストしてみましたが、他のプラグインとの兼ね合いまで手が回っておりませんので、そちらの方は可能であればよろしくお願いいたします。
----
-出先に居る場合回答が未テスト状態である事が多い為、テストは重々にお願いいたします。
アバター
ビービー
記事: 303
登録日時: 2016年1月12日(火) 18:40

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by ビービー » 2016年11月20日(日) 14:43

トリアコンタンさん、剣崎宗二さん、お二方ともありがとうございます。

さっそく二つとも使用してみました。
両方とも素晴らしいできでありがたい限りでした。

しかしどちらも少し不具合があったので報告しておきます。
まずどちらにも共通している不具合ですが、ステートで指定した継続ターン数より1ターン分削れてしまいます。
これはターン終了時にスキル発動の処理より早くステートの効果が切れる処理が入っているためでした。
なので順番を入れ替えてみたところ、剣崎宗二さんの作成されたプラグインでは問題なく動作しました。
しかしトリアコンタンさの作成していただいた方ではアクター1のみスキルが発動し他のバトラーはスキル発動前にステートが解除されてしまいました。
恐らくループ一巡目で全員のステートが解除されているからだと思います。
それで思いついた方法がステートのメモ欄に<state_skill:スキルのID>があるステートはスキル発動後にthis.updateStateTurns();をおこない、ないステートは今と同じくif (!this._executeOnTurnEnd) {の中でthis.updateStateTurns();をおこなえばいいのではないかと思ったのですが、メモ欄に記述があるかないかで分岐するif文がわからず手詰まりでした。

もう一つの不具合ですが、剣崎宗二さんの作成されたプラグインでは、過去のバージョンと同じく敵からスキルが発動するので敵がステートのダメージで死亡し敵が一体もいない状態でも戦闘終了にならず、その後アクターのスキルが発動したあとで戦闘終了となります。
これはこれで無しではないのですが、できれば敵が一体もいない場合は処理を中断する、もしくはアクターから先にスキルを発動する、という事ができればいいなと思いました。

以上が報告になります。
こちらでも色々試してみますが、お力お貸しいただけると助かります。
よろしくお願いします。
------------------------------------------------------
Twitterやってます。
https://twitter.com/BB_ENTER
ブログもやってます。
http://bb-entertainment-blog.blogspot.jp/
アバター
トリアコンタン
記事: 2116
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: 自作プラグイン改変依頼(ターン終了時のステート関連のプラグインです)

投稿記事by トリアコンタン » 2016年11月20日(日) 15:15

お疲れさまです。
なるほど。。
たしかにそうですね。

それでは、onTurnEnd内で無理にスキル実行するのを止めて、BattleManager.endTurnを実行する前に
全員分のバトラーのステートスキルを実行してしまう方法はどうでしょうか?

そして全員分のステートスキルの実行が完了したら、本来のBattleManager.endTurnを実行します。
これで、余分なターン経過はしなくなるはずです。

コード: 全て選択

//=============================================================================
// BattleManager
//  ターン終了直前にステートスキルの実行を呼び出します。
//=============================================================================
var _BattleManager_startTurn = BattleManager.startTurn;
BattleManager.startTurn = function() {
    _BattleManager_startTurn.apply(this, arguments);
    this.allBattleMembers().forEach(function(battler) {
        battler.clearExecuteTurnEndSkill();
    });
};

var _BattleManager_endTurn = BattleManager.endTurn;
BattleManager.endTurn = function() {
    this.allBattleMembers().some(function(battler) {
        return battler.applyTurnEndSkill();
    });
    // ステートスキルが実行された場合、本来のターン終了は行わずに終了する。
    if (this.isActionForced()) return;
    _BattleManager_endTurn.apply(this, arguments);
};

//=============================================================================
// Game_Battler
//  ターン終了ステートスキルを実行します。
//=============================================================================
Game_Battler.prototype.clearExecuteTurnEndSkill = function() {
    this._executeTurnEndSkill = false;
};

Game_Battler.prototype.applyTurnEndSkill = function() {
    if (this._executeTurnEndSkill) return false;
    for (var i = BBSmin; i < BBSmax + 1; i++) {//パラメータで指定したステートの範囲を判定
        if (this.isStateAffected(i)) {//判定中にそのステートにかかっているバトラーがいた場合
            var SkillID = $dataStates[i].meta.state_skill;//ステートのメモに書いてあるIDをSkillIDに
            this.forceAction(SkillID, -2);
            BattleManager.forceAction(this);
            this._executeTurnEndSkill = true;
            return true;
        }
    }
    return false;
};
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/

“MV:プラグイン素材のリクエスト” へ戻る