毒ステートのダメージ投下で少し問題が……

返信する
アバター
みたしや
記事: 37
登録日時: 2017年2月08日(水) 22:39
連絡する:

毒ステートのダメージ投下で少し問題が……

投稿記事 by みたしや »

スキル【デスペラード】を発生させて、5ターン目で【敵に与えた総ダメージ】を敵に付加する毒ステートを作っています。

ステート:デスペラード
効果:自分の攻撃ターンが5回まわってくるまでに与えた総ダメージ量が、敵の毒のダメージに代入される。
キャプチャ1.JPG
ある程度の所まで出来ていますが、少し問題が……。

仕様としては
1.デスペラードを使う。
2.自分のターンが5回まわってくる間に敵にダメージを与える。
3.自分のターン5回目で総ダメージ量の毒ダメージが付加される。
4.総ダメージは重ね掛けが出来る。
そんな仕組みです。

問題は仕様に書いてある3と4で起きています。
ソースコードはGame_Battler.prototype.regenerateHpを書き換えていて

コード: 全て選択

Game_Battler.prototype.regenerateHp = function() {

    if (this.isStateAffected(16) && $gameVariables.value(45) == -1) {
      var newvalue = $gameVariables.value(44);
      console.log('デスぺラnewDamage_'+newvalue);
      if (newvalue !== oldvalue) {
        var oldvalue = oldvalue + newvalue;
        console.log('デスぺラoldDamage_'+oldvalue);
      }
      this.gainHp(-oldvalue);
    }

    var value = Math.floor(this.mhp * this.hrg);
    value = Math.max(value, -this.maxSlipDamage());
    if (value !== 0) {
      this.gainHp(value);
    }

  };
ちなみにこれを作動させると
キャプチャ2.JPG
キャプチャ2.JPG (42.03 KiB) 閲覧された回数 3032 回
この場合、oldvalueが見つからない と 返ってきました。

動いたり、動かなかったりしています。
・varをconstに変えてもエラーが出る。



ここでやりたい事は
・newvalueに与えた総ダメージ(変数44番)に代入する。
・oldvalueに今まであった総ダメージ(oldvalue)と新しく入ってきた総ダメージ(newvalue)を代入する。
この二つの工程です。

どなたかこの問題を解決できそうな方。
回答の方をよろしくお願いします。
アバター
Plasma Dark
記事: 736
登録日時: 2020年2月08日(土) 02:29
連絡する:

Re: 毒ステートのダメージ投下で少し問題が……

投稿記事 by Plasma Dark »

こういう書き方ができるので、varはやめたほうが良いのです。
再代入を許すとしても、letを用いたほうが直感的になります。

regenerateHp 内で oldvalue を宣言する前に参照してしまっています。
var は関数スコープなので undefined になるだけですが、 let はブロックスコープなのでちゃんとエラーにしてくれます。
1.デスペラードを使う。
2.自分のターンが5回まわってくる間に敵にダメージを与える。
3.自分のターン5回目で総ダメージ量の毒ダメージが付加される。
4.総ダメージは重ね掛けが出来る。
仕様の説明がまだ少し曖昧な気がします。

ステート: デスペラード に関わる登場人物から整理しましょう。
ここで 自分 と表現されているのは、 ステート: デスペラード を付与するスキル(スキル: デスペラード)の使い手アクターであるという認識で合っていますか?
そして、2での 敵 とは、ステート: デスペラード 状態にかかった敵単体のことでしょうか。それとも、敵全体のことでしょうか。

それから、重ね掛けの意図するところがうまく理解できませんでした。
ステート: デスペラード は5ターン目にダメージを与え、その時点で解除されるのでしょうか。それとも、永続的に続いて5ターンごとにダメージを与えるものでしょうか。

コード中のnewvalueとoldvalueも、よくわかりません。
前回までのデスペラードステートによる処理で与えたダメージに、今回の5ターン分を加算する、ということでしょうか。
もしそうであれば、前回分のダメージをどこかに保持しておく必要があります。
今のコードでは、突如として初期化されないoldvalueなる変数が生えてきており、意図が謎です。
アバター
みたしや
記事: 37
登録日時: 2017年2月08日(水) 22:39
連絡する:

Re: 毒ステートのダメージ投下で少し問題が……

投稿記事 by みたしや »

Plasma Dark 様

説明の仕方が下手くそでした。(人に説明するのはあまり慣れていない物で……。)
質問された部分の説明をします。
ステート: デスペラード に関わる登場人物から整理しましょう。
ここで 自分 と表現されているのは、 ステート: デスペラード を付与するスキル(スキル: デスペラード)の使い手アクターであるという認識で合っていますか?
はい。デスペラードの使用者(ナツメ)で合っています。
デスペラードを使用して(ナツメ)のターンが回ってくる毎に
ステート:デスペラード発動までのカウント(変数45)が1ずつ減っていく仕組みです。
スキル発動前にコモンイベント13を発動させて、決め台詞を言ってカウント(変数45)に5を代入します。

このように書いています。
・【Game_Action.prototype.apply】で【Game_Action.prototype.executeHpDamage】にあるコモンイベント発動の為に変数21(変数名:CharacterSpesialAbirity)に3(コモンイベントに入れているNo3を動かす)を入れている。

(本当は、【Game_Action.prototype.apply】のナツメ専用技の条件で敵がステートNo(16):デスペラードにかかっている時としたかった……。やり方が分からない。)

コード: 全て選択

Game_Action.prototype.apply = function(target) {
    var result = target.result();
    this.subject().clearResult();
    result.clear();
    result.used = this.testApply(target);
    result.missed = (result.used && Math.random() >= this.itemHit(target));
    result.evaded = (!result.missed && Math.random() < this.itemEva(target));
    result.physical = this.isPhysical();
    result.drain = this.isDrain();

    if (result.isHit()) {
      if (this.item().damage.type > 0) {
        result.critical = (Math.random() < this.itemCri(target));
        var value = this.makeDamageValue(target, result.critical);
        //ナツメ専用技
        //敵がデスペラード時、ナツメのターンが回ってくるとデスペラード発生までのカウントが減る
        if (this.subject().isActor() && this.subject().actorId() === 6) {
          $gameVariables.setValue(21, 3)

          console.log("ナツメ_デスペラード処理");
        }

        this.executeDamage(target, value);
      }
      this.item().effects.forEach(function(effect) {
        this.applyItemEffect(target, effect);
      }, this);
      this.applyItemUserEffect(target);
    }
  };
・Game_Action.prototype.executeHpDamageの内部で$gameTemp.reserveCommonEvent(10)のNo3を発動させて
カウント(変数45)を1減らします。

コード: 全て選択

const _Game_Action_executeHpDamage = Game_Action.prototype.executeHpDamage;
  Game_Action.prototype.executeHpDamage = function(target, value) {
    _Game_Action_executeHpDamage.call(this, target, value);
    if(this.isSkill() && target.isEnemy() && $gameVariables.value(45) >= 0){
      //デスペラードに代入
      $gameVariables.setValue(44,$gameVariables.value(44) + value);
      console.log($gameVariables.value(44))
    }
    if (this.isSkill() && target.isEnemy() && !this.item().meta.noExpcount) {

      $gameParty.gainExp(value);
      //CharacterSpesialAbirity用のコモンイベント
      $gameTemp.reserveCommonEvent(10)
    }
  }
そして、
2での 敵 とは、ステート: デスペラード 状態にかかった敵単体のことでしょうか。それとも、敵全体のことでしょうか。
スキル:デスペラードの効果は敵全体にステート:デスペラードを付加します。
敵全体に付加状態させた状態からデスペラード発動までのカウント(変数45)が減っていきます。
キャプチャ.JPG
キャプチャ2.JPG
それから、重ね掛けの意図するところがうまく理解できませんでした。
ステート: デスペラード は5ターン目にダメージを与え、その時点で解除されるのでしょうか。
それとも、永続的に続いて5ターンごとにダメージを与えるものでしょうか。
ごめんなさい。【重ね掛け】の使い方を間違っていました。

正しくはステート:デスペラードが発動して、バトルが終わるまで永続的に【効果発動までの5ターンで敵に与えた総ダメージ量】を発動後1ターン毎に与え続けます。

その上、デスペラード(2回目)に使用するにあたって
1回目のデスペラードで与えたダメージ量に、今回の新たな2回目のデスペラードを加算する
(2回目のデスペラードで与えたダメージ量に、今回の新たな3回目のデスペラードを加算する)
という仕組みにしたいです。

Plasma Dark 様のおっしゃる通り
実をいうと、前回分のダメージを保存して置く書き方が分からず。
よく分からない書き方となっております。

また何か不明な点がございましたら
返信をお願いします。
アバター
Plasma Dark
記事: 736
登録日時: 2020年2月08日(土) 02:29
連絡する:

Re: 毒ステートのダメージ投下で少し問題が……

投稿記事 by Plasma Dark »

実をいうと、前回分のダメージを保存して置く書き方が分からず。
よく分からない書き方となっております。
適当な変数を用意して、戦闘開始時に初期化、デスペラードの効果ダメージが発生するタイミングでダメージ量をその変数に格納して、次回以降のダメージ発生時に、ダメージ量にその値を加算すればできそうですね。
アバター
Plasma Dark
記事: 736
登録日時: 2020年2月08日(土) 02:29
連絡する:

Re: 毒ステートのダメージ投下で少し問題が……

投稿記事 by Plasma Dark »

本当は、【Game_Action.prototype.apply】のナツメ専用技の条件で敵がステートNo(16):デスペラードにかかっている時としたかった……。
target.isStateAffected(16) とかで判定できないでしょうか。
apply に渡される target は、 Game_Battler を継承したクラスのインスタンスなので、こういうことができるはずです。
アバター
Plasma Dark
記事: 736
登録日時: 2020年2月08日(土) 02:29
連絡する:

Re: 毒ステートのダメージ投下で少し問題が……

投稿記事 by Plasma Dark »

元の変数やステートを流用しつつ私ならこう書く、という形で書いてみました。
プロジェクトの状況を再現できないので、動作確認はしていませんが、だいたいこんな感じのコードになると思います。

仕様からコードの設計に落とし込む際の考え方を記しておきます。

1. 仕様の各要素について、主体(所有者)を明らかにする。

デスペラードというステートは、ステートにかかっている対象が主体です。
(そうであるからこそ、 target.isStateAffected(16) といった形でステートにかかっているかどうか判定ができます)
しかし、デスペラードステートによって与えるダメージ量は、仕様上デスペラードスキルの使用者を主体と考えるほうが自然です。

2. 主体についてインターフェースを設計する

デスペラードステートによって与えるダメージ量の主体は、デスペラードスキルの使用者、すなわちアクターです。
つまり、ダメージ量の計算やその操作のためのメソッドは Game_Actor が持つと良いだろうな、ということがわかります。
ダメージ量は戦闘開始時に初期化し、デスペラードカウントが0以上の時にダメージを与えると加算し、デスペラードステートのダメージ処理の際に取得する必要があります。

それらの操作を表すメソッド(addDesperadoDamage等)を Game_Actor に持たせるのです。

同じ考え方でダメージを受ける側が主体となる要素もインターフェースを作ります。

3. インターフェースを組み合わせる

2で作ったインターフェースを組み合わせれば、だいたいコードができます。
一つ一つのメソッドの内部実装は、しっかり設計できていればたいていの場合は単純になります。
今回アップしたプラグインも、それぞれのメソッドは中身が数行で完結しています。
添付ファイル
Desperado.js
(5.14 KiB) ダウンロード数: 4 回
アバター
みたしや
記事: 37
登録日時: 2017年2月08日(水) 22:39
連絡する:

Re: 毒ステートのダメージ投下で少し問題が……

投稿記事 by みたしや »

Plasma Dark 様
適当な変数を用意して、戦闘開始時に初期化、デスペラードの効果ダメージが発生するタイミングでダメージ量をその変数に格納して、次回以降のダメージ発生時に、ダメージ量にその値を加算すればできそうですね
新たに変数を加えて、実行してみたところ
上手く起動することが出来ました。ありがとうございます。
target.isStateAffected(16) とかで判定できないでしょうか。
apply に渡される target は、 Game_Battler を継承したクラスのインスタンスなので、こういうことができるはずです。
target.enemy().isStateAffected(16)と記述していたため、上手く起動しなかったようです。

はたまた、pluginまで作っていただけるとは
大切お時間を割いていただきましてありがとうございます。

それだけでなく、plugin作成の工程まで伝授していただけたのはかなり有り難いです。

折角だったので、作成工程や制作していただきましたpluginをもとに
私みたしやの作ったpluginを編集してみました。

結果無事に動かく事に成功いたしました。
技術を磨かせていただきありがとうございました。

あと、誠に勝手ながらPlasma Dark様のtwitterの方を発見し。フォローさせていただきました。
今は、作成されたゲームの方を楽しく遊ばせていただいております。
返信する

“MV:質問”に戻る