仮想アクターに装備品を仮装備させてその能力値パラメーターを取得

返信する
累積比率パレートマン
記事: 33
登録日時: 2022年1月12日(水) 01:12

仮想アクターに装備品を仮装備させてその能力値パラメーターを取得

投稿記事 by 累積比率パレートマン »

エンジニアの皆様


お疲れ様です。

本日、ご質問させていただいた、以下ページに関連した内容になります。

【装備画面ステータス表示の計算式について】
viewtopic.php?f=23&t=12717

上記の質問で

「装備画面における能力値パラメーターの上昇値は、

 カーソルで選択中の装備品を仮想のアクターに仮装備させ、

 その能力値と実物のアクターの能力値との差分を取って表示させている」

という仕様を教わりました。


それを処理している関数(Window_EquipItem.prototype.updateHelp)を確認すると

コード: 全て選択


//①選択したアクターを、オブジェクトとしてディープコピーする
var actor = JsonEx.makeDeepCopy(this._actor);

//②指定スロットの装備を(持ち物に戻さず)強制的に変更する
actor.forceChangeEquip(this._slotId, this.item());

//③装備の着脱後のアクターを設定する
this._statusWindow.setTempActor(actor);

と、なっているので

トリアコンタン様の、「カスタムメニュー作成プラグイン」を利用して

this._actorには、カスタムメニューで選択したアクターオブジェクト([this._actor])を割り当て、

this._slotIdには、カスタムメニューで選択したアクターの装備スロットID(this._actor.equipSlots()[※カーソルインデックス変数])を割り当て

this.item()には、所持装備品一覧で選択した装備品オブジェクトを割り当てました。

しかし、③this._statusWindow.setTempActor(actor);は

ツクールの装備画面ウインドウを指定しなければならないのか、

エラーを回避できなかったため、②actor.forceChangeEquip(this._slotId, this.item());まで走らせ

console.log(actor);で、仮想アクターの装備品を確認しましたが、装備品に変化はありませんでした。


説明が長くなって申し訳ないです。

本題は、「仮想のアクター(ディープコピーしたアクターオブジェクト)に、

指定の装備オブジェクトを仮装備させ、その状態の能力値パラメーターを取得すること」です。

恐らく、上記で示したような簡単なやり方では実現できない気がしておりますが、

別の方法で、こうすれば可能、という案にお心当たりがございましたら

助言いただけますと幸いに存じます。

どうか、よろしくお願いいたします。
名無し蛙
記事: 352
登録日時: 2015年11月23日(月) 02:46

Re: 仮想アクターに装備品を仮装備させてその能力値パラメーターを取得

投稿記事 by 名無し蛙 »

カスタムメニュー作成プラグインの仕様の方をよく知らないんですけど本題の
累積比率パレートマン さんが書きました:本題は、「仮想のアクター(ディープコピーしたアクターオブジェクト)に、
指定の装備オブジェクトを仮装備させ、その状態の能力値パラメーターを取得すること」です。
の方なら.atkや.def等で普通に取得出来ますよ。

コード: 全て選択

// アクター1のディープコピー
const actor = JsonEx.makeDeepCopy($gameActors.actor(1));
console.log(`変化前atk:${actor.atk}`);
// スロット0を武器ID4に強制変更
actor.forceChangeEquip(0, $dataWeapons[4]);
console.log(`変化後atk:${actor.atk}`);
// paramでまとめて表示(差分値)
[...Array(8)].map((_, i) =>
    console.log(`${TextManager.param(i)}:${actor.param(i)}(${actor.param(i) - $gameActors.actor(1).param(i)})`)
);
ディープコピーしようとアクターはアクターなので機能は変わらないです。
変化後のパラメータから変化前のパラメータを減算すればそれが上昇(下降)値になります。
累積比率パレートマン
記事: 33
登録日時: 2022年1月12日(水) 01:12

Re: 仮想アクターに装備品を仮装備させてその能力値パラメーターを取得

投稿記事 by 累積比率パレートマン »

名無し鮭様


早速のご返答、誠にありがとうございます。

また、とても素晴らしいコードをご教授くださり、重ねてお礼申し上げます。

ただ、私の参照方法が悪いと思うのですが、どう修正しても正しい値が返ってこない(微妙に違う)ため、

仮想アクターに、actor.changeEquipByIdを使って、実際に装備させ

その結果を取りだすと、正しい能力値が得られましたので、

都度、変更元と変更先の装備品をgainItemとloseItemで増減させることで、対応いたしました。

今回、いただいたコードを拝見して、すごいと思ったのですが

以下のアロー関数は、どういう意味になるのでしょうか?

コード: 全て選択

[...Array(8)].map((_, i) =>
このような書き方を今まで見たことがないため、純粋な好奇心からご質問させていただきました。

...はHTMLでいうところの参照先を省略したものかと思うのですが

.map((__, i)の検討がまるでつきませんでした。


ともあれこの度は、大変参考になるコードをご提供くださり、改めて感謝申し上げます。

今後とも、どうぞよろしくお願い致します。
名無し蛙
記事: 352
登録日時: 2015年11月23日(月) 02:46

Re: 仮想アクターに装備品を仮装備させてその能力値パラメーターを取得

投稿記事 by 名無し蛙 »

累積比率パレートマン さんが書きました:ただ、私の参照方法が悪いと思うのですが、どう修正しても正しい値が返ってこない(微妙に違う)ため、

仮想アクターに、actor.changeEquipByIdを使って、実際に装備させ

その結果を取りだすと、正しい能力値が得られましたので、

都度、変更元と変更先の装備品をgainItemとloseItemで増減させることで、対応いたしました。
changeEquipByIdですか? changeEquipではなく?
まさかと思うんですけど装備タイプIDとスロットIDのズレを認識してないというオチでは。

コード: 全て選択

Game_Actor.prototype.changeEquipById = function(etypeId, itemId) {
    var slotId = etypeId - 1;
    if (this.equipSlots()[slotId] === 1) {
        this.changeEquip(slotId, $dataWeapons[itemId]);
    } else {
        this.changeEquip(slotId, $dataArmors[itemId]);
    }
};
これがchangeEquipById の内部処理ですけど受け取ったetypeIdを-1してchangeEquipに渡してるんですよ。
装備タイプはデータベースで管理している都合上、ID1から始まりますけど
装備スロットは配列で管理している都合上Index0から始まる為です。
forceChangeEquipはchangeEquipと同じく直接スロットIDで指定するので
最初から希望の装備タイプから-1の値を指定する必要があります。
もしもこれが理由で無いとしたら広範囲に影響を与えるプラグインと競合している、とかですかね。
累積比率パレートマン さんが書きました:以下のアロー関数は、どういう意味になるのでしょうか?
本題からズレるのであまりこういう場で書くべきではなかったですね。
[...Array(N)].map((_, i) => 処理)は他言語でいうところの
Range式やtimesと呼ばれる機構をjavascriptで表現する時に使う定型文です。
Array(N)で長さNの配列を生成
...スプレッド構文を使いN個のundefinedに分解
[]を使いN個のundefinedを要素に持つ配列に纏め直し
.map((_, i) => 処理)を使ってN回走査しindex値を利用する、という流れです。
要はfor(let i = 0; i < N; i++){ 処理 }と同じ意味です。
RubyだとN.times{|i| 処理}と非常に簡潔に済むので重宝するんですけど
サポートされていないJSで再現してまで利用する価値があるかと言えば多分無いです。
意地でもfor文を使いたくないという偏執的なこだわりがある人向けです。
累積比率パレートマン
記事: 33
登録日時: 2022年1月12日(水) 01:12

Re: 仮想アクターに装備品を仮装備させてその能力値パラメーターを取得

投稿記事 by 累積比率パレートマン »

名無し蛙様


お疲れ様です。

ご返答くださり、誠にありがとうございます。



>まさかと思うんですけど装備タイプIDとスロットIDのズレを認識してないというオチでは。

もちろん加味しております。

いただいたコードでは第一引数が、0になっておりましたので、その点は真っ先に気付いて対応いたしました。

血眼になって参照ミスを確認し、間違えようのない定数でトライするなどしましたが

半日費やしても微妙に数字が合わないため、結局あきらめてしまいました。

その他のプラグインもすべてoffにした状態で試したものの、changeEquipById以外ではどうにもうまくいきませんでした。



[...Array(N)].map((_, i) =>の件、ご解説くださり、ありがとうございます。

forやforEachに抵抗がある方が用いる稀有なコードなのですね。

私はすぐforと.lengthを使ってしまう横着者ですので、このような洗練されたコードを見ると感動いたします。

.map((_ の部分が一番の謎でしたので、あとは自力で調べてみたいと思います。

この度は貴重な情報をご提供くださり、本当にありがとうございました。
返信する

“MV:質問”に戻る