確率は操っても操られるな

今週から迷惑メールがめっちゃくるかげろうです。

一日20通くらいくる。何が起こった。
でも面白いからいいや。面白いの抜粋。

「引っ越し完了!麻衣です♪」
お前おとといも引っ越してただろ

「先祖は藤原家みたいです!近衛あやか」
だからなんだ

「件名:2億6000万と私」
2億6千万のせいで一家離散するらしい。
円なのか、それすらもわからない。瞳だったりして

「怖かったよね・・・あれから家の鍵二重にした?早めにした方が良いよ!! 」
お前が怖えよwww誰だよwww

「プラネットモード突入で脅威の99999PT追加!」
プラネットモード中はメールが無料になり、ポイントが0になったら終了するらしい。
しかしポイントがどうやったら減るのかの説明なし。
しかもよく見たら驚異じゃなくて脅威。

「あなたのオーラが幸せと共鳴しております 江原【スピリチュアルオーラ】」
江原啓之キター

「細木です。ズバリ言うわよ!!」
なついな

「貴方様に笑顔になって頂きたい・・・ 酒井美紀」
酒井さんなにやってんすか
心配するな俺はいつでも満面の笑みだ

「地域夕方速報 確認はコチラ」
ざっくりした速報www
しかも朝に来た

「香港で金関係の仕事をしている高梨昇一です。今年度の利益の一部を日本に寄付するにあたり、処理が行えなくなってしまいました。すでに日本向け送金口座へ入金してしまい、7300万円だけ戻すことができない状況です。このままでは所得隠しになりますが、日本に取引先もなく知人もいない為送金が行えません。ご自由に使っていただいて構いませんので受け取ってもらえないでしょうか。」
何度読み返しても7300万円くれる理由が理解できない。
そんなことより日本に一人も友達がいないというぼっち発言に注目すべきか。


まあこんな面白いメールならいいんですが、
「softbankの端末をご利用のお客様」っていう割と巧妙なやつもあったので来た人は注意してくだされ。

さて、これ以上脱線しないうちに、「確率を操る」その2。



今日は、「命中率」「回避率」「クリティカル率」のいじり方。
「攻撃力」「防御力」「精神力」「敏捷性」は容易に変えられるのに、
なぜか確率がからむ上記3つのパラメータはいじりにくいようになっているので、それを変えてしまいます。

まずそれぞれの取得箇所から。
Game_Actorの中を見ます。
値取得

まず命中率から。

#--------------------------------------------------------------------------
# ● 命中率の取得
#--------------------------------------------------------------------------
def hit
 if two_swords_style
   n1 = weapons[0] == nil ? 95 : weapons[0].hit
   n2 = weapons[1] == nil ? 95 : weapons[1].hit
   n = [n1, n2].min
 else
   n = weapons[0] == nil ? 95 : weapons[0].hit
 end
 return n
end

簡単に言うと、
「武器を装備していたら武器の命中率を取得」
素手ならば命中率を95%にする
二刀流の場合、低い武器に合わせる
ということをしています。(たぶん)

二刀流の扱いひでえな。せめて平均にしろよ

95のところを好きな数字に変えれば素手の命中率が変わります。
n = [n1, n2].min  のところを
n = [n1, n2].max にすれば命中率が高い方の武器に合わせます。
n = (n1 + n2) / 2 にすれば、たぶん平均になるはず・・・
本当ならそれぞれの武器の命中率をそれぞれの一撃に適用したいところですが、それは結構めんどいことになるためここでは割愛します。(要望があればなんとかしますが)

というか、二刀流って2回攻撃するんだよな?そういや二刀流キャラを作ったことがねえ・・・
強制的に二刀流だった家庭用ツクール3のクソ仕様は除く

次に、回避率です。

#--------------------------------------------------------------------------
# ● 回避率の取得
#--------------------------------------------------------------------------
def eva
 n = 5
 for item in armors.compact do n += item.eva end
 return n
end

えーっと、たぶん
5 + 装備している防具の回避率の合計」
ですね。
道理で回避率0%でも避けると思ったよ
何も装備していなくても5%の確率で避けます。注意。
もちろん n = 5 の5を変更すれば、基本回避率を変えられます。

最後に、クリティカル率。

#--------------------------------------------------------------------------
# ● クリティカル率の取得
#--------------------------------------------------------------------------
def cri
 n = 4
 n += 4 if actor.critical_bonus
 for weapon in weapons.compact
   n += 4 if weapon.critical_bonus
 end
 return n
end

何も装備していなければ4%
『クリティカル頻発』のアクターならさらに4%プラス
『クリティカル頻発』の武器を装備している数だけ4%プラス
です。なんで4%・・・?
というか、武器を複数装備できるのって二刀流だけだよな?
つまりクリティカル率は最大で16%になるってことか。
もはや言うまでもないですが、該当する4のところをいじればそれぞれ変更できます。

ちなみに、今までの説明はすべて味方(アクター)のものです。
敵(エネミー)の場合は、また見る場所が違います。

Game_Enemyの中を見ます。
敵の値取得
#--------------------------------------------------------------------------
# ● 命中率の取得
#--------------------------------------------------------------------------
def hit
 return enemy.hit
end
#--------------------------------------------------------------------------
# ● 回避率の取得
#--------------------------------------------------------------------------
def eva
 return enemy.eva
end
#--------------------------------------------------------------------------
# ● クリティカル率の取得
#--------------------------------------------------------------------------
def cri
 return enemy.has_critical ? 10 : 0
end

命中率と回避率は設定できるパラメータそのままなので説明は割愛します。問題はクリティカル率。

敵の場合、
「クリティカルありにチェックが入っていなければ0%」
クリティカルありにチェックが入っていれば10%
となっています。
つまり、クリティカル頻発アクターよりクリティカル率が高いです。
あなたがフェアなバトルを望むのなら、10を4にしておきましょう。


さて、値の取得のところを見てきましたが、
ここからは、その値を実際に適用しているところを見ます。

Game_Battlerの中を見ます。
計算式

まず命中率から。

#--------------------------------------------------------------------------
# ● 最終命中率の計算
# user : 攻撃者、スキルまたはアイテムの使用者
# obj : スキルまたはアイテム (通常攻撃の場合は nil)
#--------------------------------------------------------------------------
def calc_hit(user, obj = nil)
 if obj == nil # 通常攻撃の場合
  hit = user.hit # 命中率を取得
  physical = true
 elsif obj.is_a?(RPG::Skill) # スキルの場合
  hit = obj.hit # 成功率を取得
  physical = obj.physical_attack
 else # アイテムの場合
  hit = 100 # 命中率を 100% とする
  physical = obj.physical_attack
 end
 if physical # 物理攻撃の場合
  hit /= 4 if user.reduce_hit_ratio? # 使用者が暗闇なら 1/4 にする
 end
 return hit
end

コメントが豊富すぎて解説の隙がない。
一応要点をまとめると、
「通常攻撃の場合、先ほど設定した命中率になる」
「スキルの場合設定した成功率が適用され、命中率は関係ない
「アイテムの場合かならずヒットし、命中率は関係ない
「【命中率減少】のステート中の場合、命中率が4分の1になる」
となります。

スキル/アイテムについては、「物理攻撃」にチェックが入っていようがいまいが命中率は適用されませんでした。
そこで、「物理攻撃」にチェックが入っている場合のみ
命中率を適用する方法を伝授します。

elsif obj.is_a?(RPG::Skill) # スキルの場合
  hit = obj.hit # 成功率を取得
  if obj.physical_attack
    hit = user.hit # 命中率を取得
  end

  physical = obj.physical_attack
else # アイテムの場合
  hit = 100 # 命中率を 100% とする
  if obj.physical_attack
    hit = user.hit # 命中率を取得
  end

  physical = obj.physical_attack

この青文字の部分を追加すればOK。
いやー、びっくりするくらい簡単だった。

ちなみに【命中率減少】ステート中に命中率4分の1をいじりたければ、

hit /= 4 if user.reduce_hit_ratio? # 使用者が暗闇なら 1/4 にする

この hit /= 4 の部分を hit /= 2 にすれば2分の1になりますし、
hit = 0 にすれば一切攻撃が当たらなくなります。

次に回避率。

#--------------------------------------------------------------------------
# ● 最終回避率の計算
# user : 攻撃者、スキルまたはアイテムの使用者
# obj : スキルまたはアイテム (通常攻撃の場合は nil)
#--------------------------------------------------------------------------
def calc_eva(user, obj = nil)
 eva = self.eva
 unless obj == nil # 通常攻撃ではない場合
   eva = 0 unless obj.physical_attack # 物理攻撃以外なら 0% とする
 end
 unless parriable? # 回避不可能な状態の場合
   eva = 0 # 回避率を 0% とする
 end
 return eva
end

なんで回避率の方は「物理攻撃」チェックを見てるんだよ
なぜか命中率と違いスキル/アイテムに「物理攻撃」チェックがついている場合、ちゃんと回避率が適用されるようになっています。
(チェックがついていない場合は、回避率は無視され100%命中します)

また、「行動も回避もできない」ステートになっている場合、
回避率は無視されます。(命中率はおそらく適用される)

ちなみに、命中率と回避率の計算は個別に行われています。
つまり、命中率95%で回避率5%の敵を攻撃した場合、
実際に当たる確率は95 - 5=90%ではなく、
(95×95)÷(100×100)=90.25%です。

もうちょっとわかりやすく言うと、
命中率、回避率ともに50%なら、
50 - 50 = 0%ではなく、2分の1×2分の1=25%になります。
考えてみりゃ当たり前だ。


しかし、なんで敵の命中率や回避率は設定できるのに
味方は装備品でしか設定できないんでしょうな?
レベルアップで命中率とか回避率上げたいぜ!!
とかいう人のためにとっておきのテクニックを伝授。

回避率を、敏捷性にします。

eva = self.eva のところを
eva = self.base_agi + @agi_plus
に変える。これだけです。
@agi_plus は、アイテムやイベントで変動した敏捷性です。
基本敏捷性とは別カウントだった。罠だ。


それでは最後に、クリティカル率です。
そのまま、回避率で見たところの下(ダメージ計算部分)を見ます。
クリティカル率
#--------------------------------------------------------------------------
# ● 通常攻撃によるダメージ計算
# attacker : 攻撃者
# 結果は @hp_damage に代入する。
#--------------------------------------------------------------------------
def make_attack_damage_value(attacker)
 damage = attacker.atk * 4 - self.def * 2 # 基本計算
 damage = 0 if damage < 0 # マイナスなら 0 に
 damage *= elements_max_rate(attacker.element_set) # 属性修正
 damage /= 100
 if damage == 0 # ダメージが 0
   damage = rand(2) # 1/2 の確率で 1 ダメージ
 els
if damage > 0 # ダメージが正の数
   @critical = (rand(100) < attacker.cri) # クリティカル判定
   @critical = false if prevent_critical # クリティカル防止?
   damage *= 3 if @critical # クリティカル修正
 end
 damage = apply_variance(damage, 20) # 分散
 damage = apply_guard(damage) # 防御修正
 @hp_damage = damage # HP にダメージ
end

クリティカル率は、そのまま使用されていました。
(クリティカル防止の防具をつけている場合は除く)

それ以外のポイントとしては、
ダメージが0だった場合、2分の1の確率で1ダメージを与える
クリティカル時は、3倍のダメージを与える
分散度は20
てとこですかね。
計算結果が0の場合固定0ダメージにしたければ、赤い部分を削除。
クリティカル時の倍率を変えるなら、青い部分の3を変更。
分散度を変えたければ、緑の部分の20を変更してください。

分散度はスキル/アイテムではこちらで設定できますが、
通常攻撃だと20固定なんですね。初めて知った。

一応分散度の説明をしておくと、
「ダメージ±(ダメージ×(分散度÷100)」です。
例えばダメージが100の場合、分散度が0なら固定100ダメージ、
分散度が100だと0~200までのランダムダメージ、
分散度が50だと50~150までのランダムダメージとなります。

また、クリティカル率は通常攻撃にしか適用されません。
もしスキル/アイテムでも適用したい場合、
もう少し下の「●スキルまたはアイテムによるダメージ計算」の部分に
以下の青い部分を追加してください。

#--------------------------------------------------------------------------
# ● スキルまたはアイテムによるダメージ計算
# user : スキルまたはアイテムの使用者
# obj : スキルまたはアイテム
# 結果は @hp_damage または @mp_damage に代入する。
#--------------------------------------------------------------------------
def make_obj_damage_value(user, obj)
 damage = obj.base_damage # 基本ダメージを取得
 if damage > 0 # ダメージが正の数
  damage += user.atk * 4 * obj.atk_f / 100 # 打撃関係度: 使用者
  damage += user.spi * 2 * obj.spi_f / 100 # 精神関係度: 使用者
  unless obj.ignore_defense # 防御力無視以外
   damage -= self.def * 2 * obj.atk_f / 100 # 打撃関係度: 対象者
   damage -= self.spi * 1 * obj.spi_f / 100 # 精神関係度: 対象者
  end
  damage = 0 if damage < 0 # マイナスなら 0 に
 elsif damage < 0 # ダメージが負の数
  damage -= user.atk * 4 * obj.atk_f / 100 # 打撃関係度: 使用者
  damage -= user.spi * 2 * obj.spi_f / 100 # 精神関係度: 使用者
 end
 damage *= elements_max_rate(obj.element_set) # 属性修正
 damage /= 100
 if damage > 0 # ダメージが正の数
  @critical = (rand(100) < user.cri) # クリティカル判定
  @critical = false if prevent_critical # クリティカル防止?
  damage *= 3 if @critical # クリティカル修正
 end

 damage = apply_variance(damage, obj.variance) # 分散
 damage = apply_guard(damage) # 防御修正
 if obj.damage_to_mp
  @mp_damage = damage # MP にダメージ
 else
  @hp_damage = damage # HP にダメージ
 end
end


以上で確率の話は終わりです!


長かった・・・

迷惑メールの話とかしてるからだ

ここまでお付き合いくださり、ありがとうございました。
もっと話したいパラメータのこととかあるんですが、
いちいち書いていたらきりがないので、
このパラメータをいじりたい!
というコメントがなければ、次はちょっと違う話をするかもしれません。

かげろうでした。



あれ?エンカウント率やるんだっけ・・・?


RGSS2講座目次

RGSS2講座第4回
スポンサーサイト

コメントの投稿

非公開コメント

Index

ブログ趣旨
メンバー紹介
制作ゲーム紹介
RGSS2講座

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR