ほかふた 2023/05/26 17:22

【雑記】VXAce_スキル計算式について

おはこんばんちは、ほかふたです。

今回は進捗報告ではなく雑記のみで
主にツクラーさん向けの記事となります。
ツクールのデータベースにあるスキル計算式に関して載せておきます。

ちょうどこの部分ですね。
簡単設定を行えば基礎ダメージをベースに打撃(魔法)関係度を
いじって計算式を決定することができます。

単純な計算ならこれだけで事足りると思いますが、
計算式項目欄には様々な計算式を入力することが可能です。

VXAce自体12年くらい前のツールなのでネットを散策すれば
既出な部分もあるかもしれないですが、自分用としても使いたいので
ここではどのような計算式が使えるのか…というのを載せています。
書いていたら滅茶苦茶長くなってしまったので流し程度に…
あと、ゲーム制作の参考にできたら嬉しいです。

まず、基礎として…
――――――――――――――――――――――――――
mhp :最大HP mmp :最大MP
hp :現在HP mp :現在MP tp :現在TP 
atk :攻撃力 def :防御力
mat :魔法力 mdf :魔法防御
agi :敏捷性 luk :運
level :レベル

a.atk の場合は、使用者の攻撃力
b.def の場合は、対象者の防御力

v[X] :変数nの値 v[1]の場合は変数1の値
―――――――――――――――――――――――――
ここまではツクールのスキル計算式にカーソルを合わせると
ヘルプで出てくるやつですね。

~他に使える能力値参照~
―――――――――――――――――――――――――
hit :命中率 eva :回避率
cri :会心率 cev :会心回避率
mev :魔法回避率 mrf :魔法反射率
cnt :反撃率
hrg :HP再生率 mrg :MP再生率 trp :TP再生率

―――――――――――――――――――――――――
追加能力値も計算式として使用することができます。
注意点として…
aの命中率が100の場合、a.hitと入力した場合は 1 が入ります。 
aの会心率が3の場合、a.criと入力した場合は 0.03 が入ります。
スキル計算の最終結果は小数点以下切り捨てになるので、
これらを実数値として出す場合は×100させてあげる必要があります。

―――――――――――――――――――――――――
tgr :狙われ率 grd :防御効果率
rec :回復効果率 pha :薬の知識
mcr :MP消費率 tcr :TPチャージ率
pdr :物理ダメージ率 mdr :魔法ダメージ率
fdr :床ダメージ率 exr :経験獲得率

―――――――――――――――――――――――――
特殊能力値も追加能力値と同様です。
デフォルトだと100が初期値だと思うので、その場合は 1 が入ります。
特殊能力値で狙われ率を 90% にした場合は 0.9 になります。
武具等の特徴欄で設定する特殊能力値の重複計算は乗算なので
これらを設定する場合は注意が必要かも…

―――――――――――――――――――――――――
a.element_rate(X)
―――――――――――――――――――――――――
属性IDの有効度を取得します。カッコ内の X は属性IDが入ります。
100が初期値だと思うので、その場合は 1 が入ります。

―――――――――――――――――――――――――
a.state_rate(X)
―――――――――――――――――――――――――
ステートIDの有効度を取得します。カッコ内の X はステートIDが入ります。
100が初期値だと思うので、その場合は 1 が入ります。

―――――――――――――――――――――――――
a.states.size
―――――――――――――――――――――――――
現在得ているステートの数を取得します。
能力強化・弱体はカウントに含まれません。
バフ、デバフ構わずカウントするので使い方に注意…

―――――――――――――――――――――――――
a.hp_rate
a.mp_rate
a.tp_rate
―――――――――――――――――――――――――
対象者の現在の割合値を取得します。
上からHP、MP、TPの残り割合値となります。
最大HPが100で残りHPが38の場合は0.38が入ります。
MPに関しては最大MPが0の際は0が入り、割る数も考慮されています。
ただし、TPに関してはtp_rateの呼び先を見ると割る数が100に
なっている為、何らかの操作で最大TPが可変になる場合は注意が必要です。

~他に使えそうなもの~
―――――――――――――――――――――――――
$game_switches[X]
―――――――――――――――――――――――――
スイッチのX番の状態を取得します。
単品では使用できず、後記にある条件演算子と組み合わせる必要があります。
ONの場合は真、OFFの場合は偽になります。

―――――――――――――――――――――――――
$game_troop.turn_count
―――――――――――――――――――――――――
現在のターン数を取得します。
バトル以外で使用した場合、直前のバトルの最終ターン数を取得します。

―――――――――――――――――――――――――
$game_party.gold
―――――――――――――――――――――――――
現在の所持金を取得します。

―――――――――――――――――――――――――
$game_party.item_number($data_items[X])
―――――――――――――――――――――――――
アイテムの所持数を取得します。XにはアイテムIDが入ります。
「$data_items」の部分を「$data_weapons」「$data_armors」に
変えれば武器、防具のIDを取得できます。
ただ、これだけで入力可能文字数の
4割は持っていかれるのであまりお勧めはしません…

―――――――――――――――――――――――――
$game_party.steps
―――――――――――――――――――――――――
現在の歩数を取得します。

―――――――――――――――――――――――――
$game_system.save_count
―――――――――――――――――――――――――
現在のセーブ回数を取得します。

―――――――――――――――――――――――――
$game_system.battle_count
―――――――――――――――――――――――――
現在の戦闘回数を取得します。
逃走回数は(多分)内部的に持っていないみたいなので、
イベントコマンドのバトルの処理内にある「逃げた場合」や、
スクリプト内の逃走処理の中身に変数として加算していけば
チキンナイフ的な計算式も作ることが可能です。


演算子

―――――――――――――――――――――――――
a.atk ** 3
―――――――――――――――――――――――――
あまり使わないかもですが、累乗が使用可能です。
上記の場合だとa.atkの3乗、つまり「a.atk × a.atk × a.atk」になります。
攻撃力の3乗は考えただけで恐ろしいですね…

―――――――――――――――――――――――――
a.atk % 5
―――――――――――――――――――――――――
これもあまり使わないかもですが、余剰も使用できます。
上記だと、a.atkを5で割った余りが算出されます。
後記で説明する条件演算子と組み合わせると
○○の倍数の場合といった条件式を作ることが可能です。

―――――――――――――――――――――――――
X == Y ? M : N
―――――――――――――――――――――――――
条件演算子が使えます。
プログラム言語が分からん人向けに一応細かく書いておきます。

「?」を境目に、左辺が条件式、右辺が分岐結果になります。
右辺の「:」を境目に、「M」が真(TRUE)、「N」が偽(FALSE)です。

簡単な例として…
「a.mhp == a.hp ? a.atk * 10 : a.atk * 4」
この式だと、使用者の最大HPと現在HPを比較して同じだった場合、
「a.atk × 10」、それ以外の場合は「a.atk × 4」を見ます。

左辺の条件式ですが、ここも色々な使い方ができます。
まず、比較演算子ですが…
== :値が等しければTRUE
!= :値が等しくなければTRUE
> :値が大きければTRUE
< :値が小さければTRUE
>= :値が同じか大きければTRUE
<= :値が同じが小さければTRUE

とりあえずこれだけ覚えておけばOKかなと。

調べてみたら、論理演算子も使用可能です。
&& :条件が両方成立すればTRUE (AND)
|| :どちらかの条件が成立すればTRUE (OR)

論理演算子の使い方は説明すると長くなるので
以下のような感じで使えばOKです。

「a.mhp == a.hp && a.mmp == a.mp ? a.atk * 10 : a.atk * 4」

使用者の最大HPと現在HPが同値、使用者の最大MPと現在MPが同値ならば
「a.atk × 10」、それ以外の場合は「a.atk × 4」を見ます。

「a.mhp == a.hp || a.mmp == a.mp ? a.atk * 10 : a.atk * 4」

この場合は、どちらか片方を満たしていれば「a.atk × 10」を見ます。

条件演算子は使いこなせると
色んなバリエーションができると思いますので、
細かい計算を作りたい場合は是非ともマスターしてください。

関数

―――――――――――――――――――――――――
a.state?(X) ? M : N
―――――――――――――――――――――――――
使用者はステートID「X」に
なっている場合に真、そうでない場合に偽を見ます。

―――――――――――――――――――――――――
a.skill_learn?($data_skills[X]) ? M : N
―――――――――――――――――――――――――
使用者はスキルID「X」を
取得している場合に真、そうでない場合に偽を見ます。

―――――――――――――――――――――――――
b.movable? ? M : N
―――――――――――――――――――――――――
対象者が行動可能状態の場合は真、そうでない場合に偽を見ます。

―――――――――――――――――――――――――
b.guard? ? M : N
―――――――――――――――――――――――――
対象者が防御状態の場合は真、そうでない場合に偽を見ます。

―――――――――――――――――――――――――
a.weapons.include?($data_weapons[X]) ? M : N
a.armors.include?($data_armors[X]) ? M : N
―――――――――――――――――――――――――
使用者は武器ID「X」、下記は防具ID「X」を
装備している場合に真、そうでない場合に偽を見ます。
参照できるのは使用者だけかなと…敵は装備という概念がないので
対象者(b)を使用する場合は注意が必要です。

―――――――――――――――――――――――――
rand(N)
―――――――――――――――――――――――――
0~N-1までの数値をランダムに算出します。
「rand(5)+1」で1~5のうちランダムに算出します。
そのまま使うと0も抽選されちゃうので0を含めたくない場合はこのように。

―――――――――――――――――――――――――
[M, N].max
―――――――――――――――――――――――――
比較関数というやつで、MとNを比較して高い方を取得します。
「[a.atk, a.mat].max」と入力すれば
攻撃力と魔法力を比較して高い方を取得できます。

―――――――――――――――――――――――――
[M, N].min
―――――――――――――――――――――――――
上記とは逆で、MとNを比較して低い方を取得します。

―――――――――――――――――――――――――
$tm = a.atk * 4 - b.def * 2; $tm * rand(2)+1
―――――――――――――――――――――――――
関数という類ではないですが、ローカル変数やセミコロンも使用できます。
上記の場合だと、先に攻撃力と防御力の計算をさせて
$tmに退避させたのち、$tmに1~2倍させるといった式であり、
$tmに入った数値が最終的な計算結果となります。
プログラム言語だとセミコロンで区切って改行を挟むのが主ですが、
スキル計算式はこのように連なって連続した式を作ることが可能です。

とまあ、色々とこんなのが使えるよと書いていきましたが、
ここまで覚えておけば色んな計算式を作ることが可能かなと思います。


計算式の例

組み合わせの一例をここに載せておきます。
あれこれ考えるのが大変なら参考にしてください。

b.hp / 4 * 3

HPを4分の1にする割合ダメージ系。
味方を対象に回復にした場合は割合回復になります。
完全な固定ダメージにしたい場合は分散度を0に。
自分はこう使ってますけどもっといい方法がありそう…

b.hp - rand(9) + 1

HPを一桁にするデスクロー的なやつ。

[a.atk, a.mat].max * 4 - b.def * 2

上記にもありましたが、Pure_Fultzに登場している「高値依存」は
このような式をベースに使っています。

(a.mat * 4 - b.mdf * 2) * (a.hp <= a.mhp / 2 ? 1.5 : 1)

使用者の現在HPが最大HPの半分以下の場合、
技のダメージに1.5倍されます。
この式の1.5倍判定は防御力の減算後になっていますが
判定式の位置を変えれば減算前に1.5倍判定することもできます。
そこはお好みなのでご自由にって感じです。

(a.atk * 4 - b.def * 2) * (rand(5) == 0 ? 1.5 : 1)

一定確率でどうする系の条件分岐はこちら。
この場合は0~4のうちランダムなので20%の確率になりますね。
確率はrandの括弧内をいじれば調整可能です。

(a.atk * 4 - b.def * 2) * (b.state?(X) ? 2 : 1)

通常の計算の後に、対象者のステートを見て
そのステートに掛かっている場合に2倍ダメージを与えます。
対象が毒状態の場合、ダメージが2倍になる
ベノムショック的なやつを作ることが可能です。

(a.atk * 4 - b.def * 2) * (b.element_rate(X) < 1 ? 2 : 1)

通常の計算の後に、対象者の属性有効度を見て
耐性を持っている場合(99%以下)に2倍ダメージを与えます。
有効度が 0% になっている場合はダメージは与えられないです。

$tm = (100 * a.hp_rate - 100) * -1;
(a.mat * 4 - b.mdf * 2) * (1 + ($tm*0.02))

使用者の残りHPの割合(パーセント)を算出して
その割合値の倍率を算出してダメージに付与します。
上記の場合、割合(パーセント)を算出後、-100して
パーセントを逆転させ、-1を掛算して正数に変えている為、
残りHPが低いほど与えるダメージが大きくなる式となります。

$tm = (100 * b.mp_rate - 100) * -1;
b.mhp * ($tm * 0.01) 

対象者の残りMPの割合(パーセント)を算出して
その割合値の倍率を算出してダメージに付与します。
上記の場合、MPが枯渇してるほど与えるダメージが大きくなります。
対象者の最大HPからその割合分のダメージを与えます。

$tm=[a.eva * 20 < 1 ? 1 : a.eva * 20, 3].min;
(a.atk * 4 - b.def * 2) * $tm

使用者の回避率を見て、回避率値に応じてダメージに倍率を付与します。
上記の場合、回避率が5以下だと等倍ダメージ、
10だとちょうど2倍、15以上だと3倍ダメージを付与します。
回避率がマイナスになることや、最低倍率を考慮して条件式を…
min関数を用いて倍率上限を設定していますが、
こういうストッパーをかけておかないとバランス崩壊につながるので
倍率ダメージを採用する際はその辺に注意しましょう。

(a.mat * 4 - b.mdf * 2) * (1+v[X]*0.1)

スキルレベルを変数で用いる際はこういう式が有効です。
変数値が1の場合1.1倍、2の場合1.2倍…という感じです。

b.level % 5 == 0 ? a.mat * 4 - b.mdf * 2 : 0

対象者のレベルが5の倍数の場合にダメージを与えます。

$tm = a.atk * 4 - b.def * 2;
$tm >= 1000 ? 1000 + a.atk / 2 : $tm

これは賛否両論あるかもしれないですが、
何らかの大ダメージが影響でバランス崩壊につながる場合、
ダメージ減衰を設けさせることができます。
ダメージ計算後、一定数値以上に達した場合、
伸びにブレーキをかける大まかな式となります。
上記の式は一定数値を固定値にしていますが
変数にしたりなどで上限値を変えたり
ブレーキの部分を三角関数とか使ってよりリアルな減速を
掛けたりとか色々とやり方はありそうですね。
因みに、「Math.cos(X)」とか三角関数も計算式に使えました。

$tm=[[$game_troop.turn_count/5,1].max,3].min;
(a.mat * 4 - b.mdf * 2) * $tm

ターン数に応じてダメージ倍率を算出します。
上記の場合、5ターン目までは等倍、5ターン目から徐々に倍率が上がり
15ターン目以降はずっと3倍になります。
このようにmax関数とmin関数を同時に用いて最低値と最大値を決定できます。

a.mhp == a.hp ? (a.mmp == a.mp ? a.atk * 10 : a.atk * 6) : a.atk * 4

あまりないパターンかもですが、条件演算子を重ねることもできます。
偽の式をそれぞれにしたい場合に使用しましょう。
ちょっと見ずらいのがネック。

注意事項

VXAceのスキル計算式には何故か文字数制限があります。
なんと100文字しか入りません…!

普通の計算だったら充分な文字数なのですが、
$tm=[a.atk, a.mat].max*10; a.mhp>=25000?25000+v[1013]+$tm:a.mhp+v[1013]+$tm)*(1+v[1014]*0.1)
こういう風なイミフで詰めっつめのような計算式も
自身のゲーム内に仕込んでおりまして
「やりたいことができないやーん」って遭遇することが多々あります。
なので長い計算式を組む際はExcelさんのLEN関数や
sakuraさんで文字数チェックしましょう。

あと、紹介した計算式は分かりやすいように半角スペースを
入れていますが、上記のように半角スペースが無くて
詰めっつめのような計算式もちゃんと機能します。

MVとかは文字数制限ないんですよね…いいなあ…

終わりに

計算式の例の中に既出となっている部分もあり
その既出となっているものをそのまま流用したり、
一部は自分の方でアレンジしているものもあります。
あと、VXAceと書きましたが、もしかしたらMVとかでも
使える計算式があるかもしれないです。
自分なりな計算式として載せておきますので、ご参考になれば幸いです。

「こういった計算式もできるよ!」といった意見や
アドバイス等ありましたら、お教えいただけると嬉しいです。

この記事が良かったらチップを贈って支援しましょう!

チップを贈るにはユーザー登録が必要です。チップについてはこちら

記事のタグから探す

月別アーカイブ

記事を検索