人生

やっていきましょう

1121日目

先日考えていた、戦闘中のキャラクターチェンジの際にHP/SPを引き継ぐ方法がついに解明した。問題の核心は「戦闘において変動した特定キャラのステータスの値をどこで取得し、どこで操作することができるのか」ということだった。そこが分かればどうにか実現可能なものになることはなんとなく想定がついていたが、戦闘システムが複雑で初めは何をどうすればいいか分からなかった。

結論から言えば、ステータスの取得はコモンイベント136、ステータスの操作はコモンイベント135で行えることが分かった。またこれらを用いてキャラクターチェンジの際、戦闘時において変動したHP/SPをそのまま維持するコモンイベントを実装した。以下に自分が理解できた範囲のことを記していく。

戦闘時における特定キャラのステータスを取得できるのはコモンイベント136【X[戦]パラメータ取得】である。このコモンイベントを起動し、求める情報を取得することで、誰のどのステータスがどのような値であるかを知ることができる。またコモンイベント135【X[戦]パラメータ増減】では対象となるキャラクターの対象となるステータスをどれだけ変更するかということを設定することができる。(これらは移動時のステータスとは異なる点に注意したい)。

厳密にいえば個別のキャラクターからそのまま情報を取得できるわけではない。コモンイベント131は「戦闘スロット」と呼ばれるキャラクターごとの枠で判別している。だから特定のキャラクターがどのスロットにいるのか、ということをまずは調べないといけない。

そのために活用できるコモンイベントは141【X[戦]スロットから主人公ID取得】である。このイベントを起動することで、対象となる戦闘スロットに属する主人公のIDを任意の変数に代入してくれる。この「主人公ID」とは、ゲームの設定時に可変データベースでキャラクターを登録する際に割り振られる番号である。例えば2番目の味方の主人公IDが5であった場合、戦闘スロット0に対して5を変数としてはじき出す。

しかし現段階では、戦闘スロットのどこに特定の主人公IDを持つキャラクターがいるのか分からない。そこで自分は戦闘スロット1~3(本当は0からあるが、0は主人公)についてそれぞれコモンイベント141を行い、弾き出した値が特定の主人公IDである戦闘スロットの番号を、新たな変数Xに代入することにした。例えば先ほどの例でいうと、味方の主人公IDは5で戦闘スロットの2番目に位置するので、戦闘スロット1の番号である1を変数Xに代入する。

この面倒な作業が意味するところは、以降の処理を単純化するためである。2キャラ分の最大HPとHP、最大SPとSPを取得、操作する際に求められる戦闘スロットの値を、常に変数Xの値であるようにすることで管理がずっと楽になる。

これで「戦闘において変動した特定キャラのステータスの値をどこで取得し、どこで操作することができるのか」という問題は解決した。つぎにこれらを用いて具体的にHP/SPを引き継ぐ方法を考えていく。

自分が先ほど最大HPと最大SPを記述したのには訳がある。メンバーチェンジの際、特定キャラの現時点でのHP/SPをそのまま引き継ぐという方法はなく、メンバーチェンジの際にHP/SPが満タンの状態から被ダメージ分だけ「減算」する必要があった。

どれだけ値が減少しているかを調べる公式は簡単で、(最大HP-現時点でのHP)、もしくは(最大SP-現時点でのSP)を求めれば良い。この値を変数Yに代入し、Yの値分だけHP/SPを減算させるという手法を取る。

しかし問題は、変数Yの値を減算させる方法だった。自分は多くの場合と同様、変数呼び出し値を用いて増減の値を2000000+Xとするはずだった。しかし通常の数とは異なり、変数呼び出し値の頭に-をつけてもそのまま減算されることがなかった-(2000000+X)は変数呼び出し値ではなかったのである。

この点に頭を悩ませていたが、どこかのネットの天才が変数 = 変数 * -1を行えば変数の値をマイナスにして自身に代入できるということを書いており、これを活用して簡単に問題を解決した。

最後にこの変数Yの値をコモンイベント135【X[戦]パラメータ増減】を変数呼び出し値として設定する。しかしこれだけやってもまだ不具合があった。メンバーが変わった瞬間ではなく、メンバーが変わったターンが終わるまでHP/SPは変動しなかったのである。

この問題については未だによくわかっていないが、コモンイベント142【X[戦]指定主人公更新処理】を行うことで解決した。このイベントは変更したパラメータの値を戦闘スロットに反映させるために用いるようである。ここではなぜか適用の対象を戦闘スロットではなく主人公IDで設定させるので、主人公IDの番号をそのまま入力した。このイベントはコモンイベント135【X[戦]パラメータ増減】の直後に置いた。

あとは互いにチェンジするキャラクターA,B分だけ分岐を作れば完成である。以下に簡単な過程を忘れないうちに記す。

 

◆用意するもの

・キャラクターA (主人公ID5) ・キャラクターB(主人公ID6)

・変数X (A,Bが属する戦闘スロットの番号を管理)

・変数P (AまたはBがパーティに属しているかどうかを判定した結果を管理)

・コモンセルフ変数1~3 (戦闘スロット1,2,3ごとに、該当する主人公のIDが見つかるかどうかの判定結果を管理)

・コモンセルフ変数10~17 (最大HP,HP,最大SP,SP,それらの差を管理)

・コモンイベント5,22,135,136,141,142 (後述)

 

ここからーーーー

▼コモンイベント22【▲メンバー情報取得[数値]】で、キャラクターAがパーティに属しているかどうかを判定。属していれば変数Pに1を代入、そうでなければ0を代入。

▼分岐【キャラクターAがパーティに属しているか】

 ●【Aがパーティに属している場合】

   戦闘スロット1~3にコモンイベント141【X[戦]スロットから主人公ID取得】を行う。

   その結果をセルフコモン変数1,2,3に代入。

   ▼分岐【セルフ1が5と同じ or セルフ2が5と同じ or セルフ3が5と同じ】

   1ならば変数Xに1、2ならば2、3ならば3を代入する。

   ここでHP/SPを演算

   ▼コモンイベント136【X[戦]パラメータ取得】

   コモンセルフ変数10にAの最大HP、11にHP、12に差を代入

   ▼変数操作 (セルフ12 = セルフ10 - セルフ11)

   ▼変数操作 (セルフ12 = セルフ12 * -1)

   コモンセルフ変数13にAの最大SP、14にSP、15に差を代入

   ▼変数操作 (セルフ15 = セルフ13 - セルフ14)

   ▼変数操作 (セルフ15 = セルフ15 * -1)

   キャラクターAを外し、キャラクターBを入れる

   ▼コモンイベント5【○メンバーの増減】 IN キャラB、OUTキャラA

   ここでキャラクターBの値をコモンセルフ16,17の値分だけ減少させる

   ▼コモンイベント135【X[戦]パラメータ増減】

    対象スロット:変数X、対象パラメータ:HP,SP、増減値:セルフ16,17

   ▼コモンイベント142【X[戦]指定主人公更新処理】主人公ID:6

    呼び出した後にコモンセルフ変数16,17を初期化

   ▼変数操作 セルフ16 = 0 + 0、セルフ17 = 0 + 0

 

 ●【Bがパーティに属している場合】

   戦闘スロット1~3にコモンイベント141【X[戦]スロットから主人公ID取得】を行う。

   その結果をセルフコモン変数1,2,3に代入。

   ▼分岐【セルフ1が6と同じ or セルフ2が6と同じ or セルフ3が6と同じ】

   1ならば変数Xに1、2ならば2、3ならば3を代入する。

   ここでHP/SPを演算

   ▼コモンイベント136【X[戦]パラメータ取得】

   コモンセルフ変数10にAの最大HP、11にHP、16に差を代入

   ▼変数操作 (セルフ16 = セルフ10 - セルフ11)

   ▼変数操作 (セルフ16 = セルフ16 * -1)

   コモンセルフ変数13にAの最大SP、14にSP、15に差を代入

   ▼変数操作 (セルフ17 = セルフ13 - セルフ14)

   ▼変数操作 (セルフ17 = セルフ17 * -1)

   キャラクターBを外し、キャラクターAを入れる

   ▼コモンイベント5【○メンバーの増減】 IN キャラA、OUTキャラB

   ここでキャラクターAの値をコモンセルフ12,15の値分だけ減少させる

   ▼コモンイベント135【X[戦]パラメータ増減】

    対象スロット:変数X、対象パラメータ:HP,SP、増減値:セルフ12,15

   ▼コモンイベント142【X[戦]指定主人公更新処理】主人公ID:5

    呼び出した後にコモンセルフ変数12,15を初期化

   ▼変数操作 セルフ12 = 0 + 0、セルフ15 = 0 + 0

 

すべての処理が終わったら変数、コモンセルフ変数10,11,13,14を初期化

▼変数操作 変数X = 0 + 0

▼変数操作 セルフ10,11,13,14 = 0 + 0

おわり

 

もっと他に良い方法があったかもしれない。パラメータ取得まわりの操作は元々のシステム上での操作では直接データベースから取得していたようだった。しかしその辺りが自分にはほとんどわからず、結局こうしたあまりきれいなやり方ではない方法で終わってしまった。しかしともかくこれで自分の求める動作が行えたことは良かった。初心者でもやればできるということが少しだけ自信になった。