消費MPを減らす装備の効果の計算について

えるまめ
記事: 15
登録日時: 2018年11月09日(金) 01:43

消費MPを減らす装備の効果の計算について

投稿記事by えるまめ » 2019年1月24日(木) 20:57

お世話になっております。
わかりやすそうなタイトルが思いつきませんでした・・・。

例えば消費MPが100のスキルがあるとします。
消費MPを10%減らす装備(特徴:MP消費率90%)をつけるとスキルの消費MPは90になります。
ここに更に消費MPを20%減らす装備(特徴:MP消費率80%)をつけると
合計で消費MPは30%減りスキルの消費MPは70になりそうな気がします。

しかしスキルの消費MPは72になりました。

これは元々の消費MP100から装備効果の合計30%を減らしているのではなく、
10%減った状態のMP90から、20%消費を減らす計算をしているために
起きていると思うのですが、これを元々の消費MP-装備品の効果を足した数字
にするにはどうしたらいいでしょうか?
(もしかしたらこの計算を変更すると色々な処理に影響を及ぼしたりするのでしょうか)

新規プロジェクトで再現しましたので仕様だと思いますが
なにか違和感を感じたので対策案やプラグインがありましたら
教えていただきたいです。

アバター
剣崎 宗二
記事: 681
登録日時: 2016年11月12日(土) 20:36
連絡を取る:

Re: 消費MPを減らす装備の効果の計算について

投稿記事by 剣崎 宗二 » 2019年1月26日(土) 14:22

(ある程度プログラムの知識がある物と仮定して回答しております)

キャラクターのパラメーターには、加算系(命中回避など。Game_BattlerBase.prototype.xparamで計算)と乗算系(回復率、MPやTP消費率等。Game_BattlerBase.prototype.sparamで計算)があります。

で、変更の方法は以下の2つがありますが…(何れも新規プラグインを作る前提です)
・sparamの内容を変更する
仰る通り、普通にやると「この計算を変更すると色々な処理に影響を及ぼし」ます。
他のパラメーターも参照してますからね。
ただ、全ての乗算を加算にしたい場合(HP回復率なども)したい場合はこちらが良いかと。

・新規のfunctionを立ててその中で変更を行い、mcrにそれを適用する
例えばvparamとしましょう。このfunctionを作った上で、お好きな処理を行い、その上で

コード: 全て選択

mcr: { get: function() { return this.vparam(4); }, configurable: true },

とする訳です。
ただこちらはJavascriptの仕様から、プラグイン化がやや難しい仕様ですね。(getterのoverloadが困難)
直接コアスクリプトを書き換えるか、さもなくばObject.definePropertiesを丸ごと上書きする事に成るかと…



では、このvparam、或いは変更したsparamの内容をどうするかですが…
取り急ぎのヒントとしては
・Array.reduceの仕様を調べてみてください。
・消費率が80%(*0.8)の場合、実際に「減っている量」は1-0.8 = 0.2です。これから類推して、減っている量を全部加算した上で(1-合計)とするのが良いかと。


どうしてもダメな場合はまたお問い合わせください。
----
-出先に居る場合回答が未テスト状態である事が多い為、テストは重々にお願いいたします。
-基本自分や友人の問題解決は自分で1からプラグインを書いているので、「こういうプラグインはありますか」に対しては助けになれません。ご了承ください。
アバター
飯尾隼人
記事: 19
登録日時: 2018年3月05日(月) 16:57
連絡を取る:

Re: 消費MPを減らす装備の効果の計算について

投稿記事by 飯尾隼人 » 2019年1月26日(土) 16:31

えるまめさん

 こんにちは! 面白そうな質問内容でしたので、ちょっと調べて見ました。
 スキルを使用したときのコストの計算は下記となっていました。

コード: 全て選択

Game_BattlerBase.prototype.skillMpCost = function(skill) {
    return Math.floor(skill.mpCost * this.mcr);
};

消費MPにMP消費率を乗算しています。
ここで、剣崎宗二さんがおっしゃっている通りレート計算を加算系にしてあげれば良いと考えます。
skill.mpCostはデータベースにて設定した消費量です。
では、this.mcrのレート(倍率)の計算方法は?

1.mcrはGame_BattlerBaseのObject.definePropertiesにて定義されています。

コード: 全て選択

Object.defineProperties(Game_BattlerBase.prototype, {
・・・
   // Mp Cost Rate
   mcr: { get: function() { return this.sparam(4); }, configurable: true },
・・・
});

 コスト計算の際にthis.mcrと呼び出すことでfunction() { return this.sparam(4); }のレートが帰ってきます。

2.sparam関数とは何か。
剣崎宗二さんがおっしゃっている通り、乗算系のレート計算です。
考え方は簡単で、MP消費率が40%と50%の装備品AとBを装備していた場合、MP消費率は20%と計算します。
逆にxparam関数の場合は、命中率が30%と70%の装備品AとBを装備していた場合、命中率は100%と計算します。

コード: 全て選択

Game_BattlerBase.prototype.sparam = function(sparamId) {
    return this.traitsPi(Game_BattlerBase.TRAIT_SPARAM, sparamId);
};

Game_BattlerBase.prototype.traitsPi = function(code, id) {
    return this.traitsWithId(code, id).reduce(function(r, trait) {
        return r * trait.value;
    }, 1);
};

Game_BattlerBase.prototype.traitsWithId = function(code, id) {
    return this.allTraits().filter(function(trait) {
        return trait.code === code && trait.dataId === id;
    });
};

コードを見てみると上記の様になっています。

ざっくりですが、そのアクターが持っている全ての特徴からcodeとidに一致している特徴を全て抽出し、
全て乗算して最終的なレートを計算していると考えられます。
ここでcodeは乗算系か加算系か、idは特徴の種類(命中率、MP消費率・・・)の識別をしています。

さて、ここで特徴にMP消費率50%の装備品を試しに作成してみて、dataにあるArmors.jsonを覗くと下記の様になっています。

{"id":4,"atypeId":1,"description":"","etypeId":5,"traits":[{"code":23,"dataId":4,"value":0.5}],"iconIndex":145,"name":"指輪","note":"","params":[0,0,0,0,10,0,0,0],"price":300}

注目すべきは下記の点です。

traits":[{"code":23,"dataId":4,"value":0.5}]

参考までにMP消費率を50%に変更する特徴のcodeとidは23と4ということが分かりますね。
結論として、プラグインを作成するしかありません。
一番ベストなのは、下記の様に乗算系のレート計算を加算で計算する新しいレート計算の関数を作り、
mcrをまるごと再定義してあげれば良いと思われますが、下記のコードでmcrだけを再定義できるのかはちょっと分かりません。
(1/26)コード変更しました。これで問題ないはずです!

コード: 全て選択

Game_BattlerBase.prototype.sxparam = function(sparamId) {
    return this.traitsSum(Game_BattlerBase.TRAIT_SPARAM, sparamId);
};

Object.defineProperty(Game_BattlerBase.prototype, 'mcr',{
   // Mp Cost Rate Special
   get: function() { return this.sxparam(4); },
   configurable: true
});

以上です。長文失礼しました。
考え方の記述のみで申し訳ありませんが、何分内容が難しいためご容赦願います。
________________________________________
「渡り鳥の楽園」
飯尾隼人
HP: http://wataridori-rakuen.jp/Elves/
twitter: https://twitter.com/wataridori_raku
Ci-en: https://ci-en.jp/creator/2449
________________________________________
えるまめ
記事: 15
登録日時: 2018年11月09日(金) 01:43

Re: 消費MPを減らす装備の効果の計算について

投稿記事by えるまめ » 2019年1月27日(日) 00:52

剣崎宗二様

こんばんは。
ご回答頂きましてありがとうございます。
剣崎様のご回答は見かけることが多く、いつも勉強になっております。

挙げていただいた箇所を確認してみると
どのパラメータが加算か乗算かがわかりました。
変更するならMP消費率を加算にするだけでなく別のパラメータも
統一したほうがわかりやすいかもしれませんね・・・
テストプレイを重ねてみて検討いたします。

ヒントのご提示もありがとうございました。
参考にさせていただきます。
えるまめ
記事: 15
登録日時: 2018年11月09日(金) 01:43

Re: 消費MPを減らす装備の効果の計算について

投稿記事by えるまめ » 2019年1月27日(日) 00:56

飯尾隼人様

こんばんは。
順番に解説していただいてありがとうございます。
大変わかりやすかったです。

ご提示いただいたコードをプラグイン化してみたのですが、
問題が発生してしまいました。いずれも新規プロジェクトで確認しました。

①MP消費率の特徴のついた装備をふたつ装備するまで
スキル画面や戦闘画面でMPが表示されなくなってしまう。

②仮にMP100のスキルがあったとしてMP消費率80%と90%の装備をした場合
 MPコストが170になってしまう。

①はMPコストが表示されないということなのでDrawやcostで
rpg_○○.js内を検索してみましたが見当違いな気がしてきたので
別の解決案を考えてみました。
あらかじめ職業の特徴にMP消費率100%をふたつ入れておくと表示されるようです。
追記:この状態でMP消費率の特徴のついた装備をつけるとMPコストが増えます。
この案は使えません。

②の問題は

コード: 全て選択

 Game_BattlerBase.prototype.skillMpCost = function(skill) {
    return Math.floor(skill.mpCost * this.mcr)-skill.mpCost;
};

のようにすることで正常な消費MPが表示されるようになりましたが
素人がいじくったのでこれで大丈夫なのかと不安です;
何かの拍子に計算がおかしくなるかもと・・・。

以上の問題は応急処置的なもので、
プラグインのみで正常に動きそうでしたらそのほうが望ましいので
解決案がありましたら教えていただけると嬉しいです。
こちらでも引き続き解決案を探してみます。

以下プラグインのコードです

コード: 全て選択

(function() {

Game_BattlerBase.prototype.sxparam = function(sparamId) {
    return this.traitsSum(Game_BattlerBase.TRAIT_SPARAM, sparamId);
};

Object.defineProperty(Game_BattlerBase.prototype, 'mcr',{
   // Mp Cost Rate Special
   get: function() { return this.sxparam(4); },
   configurable: true   
   
});
   
 Game_BattlerBase.prototype.skillMpCost = function(skill) {
    return Math.floor(skill.mpCost * this.mcr)-skill.mpCost;
};   
   
}());


プラグインに関してライセンスや利用規約などございましたら
ご提示いただけますと幸いです。
アバター
飯尾隼人
記事: 19
登録日時: 2018年3月05日(月) 16:57
連絡を取る:

Re: 消費MPを減らす装備の効果の計算について

投稿記事by 飯尾隼人 » 2019年1月27日(日) 15:14

えるまめさん

 こんにちは! 問題の内容把握しました。

①消費MPが表示されない問題点は下記コードによるものです。

コード: 全て選択

 Game_BattlerBase.prototype.skillMpCost = function(skill) {
    return Math.floor(skill.mpCost * this.mcr)-skill.mpCost;
};

おそらく、消費MPがマイナスになってしまったためにバグが起きたのだと思われます。



>仮にMP100のスキルがあったとしてMP消費率80%と90%の装備をした場合
 MPコストが170になってしまう。

 ①のコードを削除してレートの計算方法を下記のように変えてみてください。

コード: 全て選択

Game_BattlerBase.prototype.sxparam = function(sparamId) {
    return this.traitsSumEx(Game_BattlerBase.TRAIT_SPARAM, sparamId);
};

Game_BattlerBase.prototype.traitsSumEx = function(code, id) {
    var num = this.traitsWithId(code, id).length - 1;
   var scale = this.traitsWithId(code, id).reduce(function(r, trait) {
        return r + trait.value;
    }, 0) - num;
    return scale >= 0 ? scale : 0;
};


 これでMP消費率80%と90%の装備をした場合MP消費率が70%になるはずです。
 私自身がプラグインを作成したわけではないので、参考のコードは自由に使用して頂いて問題ありません。
 結果報告お待ちしております!
________________________________________
「渡り鳥の楽園」
飯尾隼人
HP: http://wataridori-rakuen.jp/Elves/
twitter: https://twitter.com/wataridori_raku
Ci-en: https://ci-en.jp/creator/2449
________________________________________
えるまめ
記事: 15
登録日時: 2018年11月09日(金) 01:43

Re: 消費MPを減らす装備の効果の計算について

投稿記事by えるまめ » 2019年1月27日(日) 20:43

飯尾隼人様

こんばんは。
お返事ありがとうございます。

ご指摘いただいたとおり修正しましたところ、
装備でのMP消費率の加算は無事動作しました!

以下プラグインのコードです

コード: 全て選択

(function() {
   
Game_BattlerBase.prototype.sxparam = function(sparamId) {
    return this.traitsSumEx(Game_BattlerBase.TRAIT_SPARAM, sparamId);
};

Game_BattlerBase.prototype.traitsSumEx = function(code, id) {
    var num = this.traitsWithId(code, id).length - 1;
   var scale = this.traitsWithId(code, id).reduce(function(r, trait) {
        return r + trait.value;
    }, 0) - num;
    return scale >= 0 ? scale : 0;
};

Object.defineProperty(Game_BattlerBase.prototype, 'mcr',{
   // Mp Cost Rate Special
   get: function() { return this.sxparam(4); },
   configurable: true
});   
   
})();

私はMP消費率を装備にて変更する仕様にしているので
現状で解決しているのですが、気づいた点があるので
後々ここを閲覧される方のためにも書かせていただきます。
(タイトルが装備についてなので趣旨とずれるかもです;)

前提:職業orアクターの特徴にMP消費率50%をつけて、スキルのMPコストは100
MP消費率90%の装備するとMPコストが39
MP消費率70%の装備するとMPコストが19
MP消費率90%と70%の装備するとMPコストが9に
MP消費率90%と80%の装備するとMPコストが20(正常)になりました。

一部で1足りない現象?が起きているようです。
ちなみにアクターの特徴にMP消費率50%と90%をつけるとMPコスト39になります。

職業やアクターで変更+装備で変更したい方は注意が必要です。
解決の糸口が見つかったら追記します。

参考コードの使用について承知いたしました。
大切に使用させていただくと共に応用もできないか考えてみたいと思います。
差し支えないようでしたらReadmeなどにお名前を記載させていただきたいです。

-------------------------------------------------------------------------------

ご回答くださいましたお二方、
この度は解決にご協力いただき、本当にありがとうございました。
アバター
飯尾隼人
記事: 19
登録日時: 2018年3月05日(月) 16:57
連絡を取る:

Re: 消費MPを減らす装備の効果の計算について

投稿記事by 飯尾隼人 » 2019年2月03日(日) 15:07

問題箇所修正しました! こちらのコードをお使いください!

コード: 全て選択

Game_BattlerBase.prototype.sxparam = function(sparamId) {
    return this.traitsSumEx(Game_BattlerBase.TRAIT_SPARAM, sparamId);
};

Game_BattlerBase.prototype.traitsSumEx = function(code, id) {
    var num = this.traitsWithId(code, id).length - 1;
   var scale = this.traitsWithId(code, id).reduce(function(r, trait) {
        return r + trait.value;
    }, 0) - num;
    return scale >= 0 ? scale.toFixed(4) : 0;
};

Object.defineProperty(Game_BattlerBase.prototype, 'mcr',{
   // Mp Cost Rate Special
   get: function() { return this.sxparam(4); },
   configurable: true
});
________________________________________
「渡り鳥の楽園」
飯尾隼人
HP: http://wataridori-rakuen.jp/Elves/
twitter: https://twitter.com/wataridori_raku
Ci-en: https://ci-en.jp/creator/2449
________________________________________

“MV:質問” へ戻る