いつもお世話になっております。
RPGツクールVXaceにて、効果範囲が
『敵2体ランダム』『敵3体ランダム』『敵4体ランダム』のスキルに対し
味方の攻撃回数を増やす&敵の攻撃回数を減らすステートや
装備すると攻撃回数が1回追加される装飾品等を作りたいのですが
ディフォルトで『効果範囲が敵n体ランダムの時に
ターゲット選択・命中判定・ダメージ計算の処理をn回連続で繰り返す』みたいなループ処理は
スクリプトのどの部分で行われているのでしょうか?
ご存じの方がおられましたら、お知恵をお借りしたくお願い申し上げます。
【RGSS3】『敵n体ランダム』の回数増減
Re: 【RGSS3】『敵n体ランダム』の回数増減
どうもこんにちは
でしょうね。
効果範囲の敵ランダムn体と連続回数と行動回数追加(特徴)とで該当処理が違うのでややこしいんですよね。
returnが省略されていますけどこれでn回分のランダムターゲットを格納した配列を返却します。
n回の部分はitem.number_of_targetsに格納されているので
Array.new()内の数値を増減する事で希望の処理を実現出来ると思います。ただし前提としてがあるので「装備すると攻撃回数が1回追加」は元がランダム攻撃じゃないと追加されませんが。
装備品やステートが付いている場合に挙動が変わるという処理は
以前自分が書いた独自特徴化を応用する方法をオススメしておきます。
取得メソッドを作るまでの適当な実装例ですが正規表現や特徴のフォーマットを覚えるとかなり応用が利くと思います。
追記で
こちらのtargetsを必要に応じて削る、という方法もありますけど増やすのが面倒なので
やはりGame_Actionの方を弄った方が良い気がしますね。
Game_Actionの178行目せくもん さんが書きました:ディフォルトで『効果範囲が敵n体ランダムの時に
ターゲット選択・命中判定・ダメージ計算の処理をn回連続で繰り返す』みたいなループ処理は
スクリプトのどの部分で行われているのでしょうか?
コード: 全て選択
Array.new(item.number_of_targets) { opponents_unit.random_target }
効果範囲の敵ランダムn体と連続回数と行動回数追加(特徴)とで該当処理が違うのでややこしいんですよね。
returnが省略されていますけどこれでn回分のランダムターゲットを格納した配列を返却します。
n回の部分はitem.number_of_targetsに格納されているので
Array.new()内の数値を増減する事で希望の処理を実現出来ると思います。ただし前提として
コード: 全て選択
if item.for_random?
装備品やステートが付いている場合に挙動が変わるという処理は
以前自分が書いた独自特徴化を応用する方法をオススメしておきます。
コード: 全て選択
module Test
FEATURE_RANDOM_ATK_NUM_EX = 101
end
class RPG::BaseItem
#--------------------------------------------------------------------------
# ● note解析
#--------------------------------------------------------------------------
def note_analyze
@note.each_line do |text|
case text.chomp
when /\<ランダム攻撃回数増加\:(\d+)\>/
@features.push Feature.new(Test::FEATURE_RANDOM_ATK_NUM_EX, 0, $1.to_i)
when /\<ランダム攻撃回数減少\:(\d+)\>/
@features.push Feature.new(Test::FEATURE_RANDOM_ATK_NUM_EX, 0, -($1.to_i))
end
end
end
end
class << DataManager
#--------------------------------------------------------------------------
# ○ 通常のデータベースをロード
#--------------------------------------------------------------------------
alias :_ex_features_load_normal_database :load_normal_database
def load_normal_database
_ex_features_load_normal_database
container = $data_actors + $data_enemies + $data_armors + $data_states
container.compact.each do |data_iterator|
data_iterator.note_analyze
end
end
end
class Game_BattlerBase
#--------------------------------------------------------------------------
# ● 拡張ランダム攻撃回数の総和の取得
#--------------------------------------------------------------------------
def random_attack_num_ex
features_sum_all(Test::FEATURE_RANDOM_ATK_NUM_EX)
end
end
追記で
上で生成したターゲット配列を実際に使用しているのはScene_Battleの579行目use_item内です。せくもん さんが書きました:ターゲット選択・命中判定・ダメージ計算の処理をn回連続で繰り返す』みたいなループ処理は
スクリプトのどの部分で行われているのでしょうか?
こちらのtargetsを必要に応じて削る、という方法もありますけど増やすのが面倒なので
やはりGame_Actionの方を弄った方が良い気がしますね。
Re: 【RGSS3】『敵n体ランダム』の回数増減
名無し蛙様、ご返答ありがとうございます。
添付いただいたスクリプトを導入したところ、以下のような
エラーメッセージが表示されました。
download/file.php?mode=view&id=18041
NoMethodErrorは何度か対処した事がありますが
こちらのエラーメッセージは初見なのでちょっと対処方法がわかりません。
お手数ですが、対処方法を教えていただけないでしょうか?
添付いただいたスクリプトを導入したところ、以下のような
エラーメッセージが表示されました。
download/file.php?mode=view&id=18041
NoMethodErrorは何度か対処した事がありますが
こちらのエラーメッセージは初見なのでちょっと対処方法がわかりません。
お手数ですが、対処方法を教えていただけないでしょうか?
Re: 【RGSS3】『敵n体ランダム』の回数増減
平たく言えば無限再帰ですね。
関数の中で関数を呼び脱出条件がなくスタックオーバーフローになった、って事だと思います。
aliasのバッティングなんかでそこそこ見掛けるエラーですね。
例えば以前、私が書いたコード(メモ欄解析)とは別に今回のコードを丸々コピペしたら
思いっきり競合するので内容を読み解いて適宜調整する必要があります。
というかサンプルコードとして渡した物だったのでそのまま使用する事は想定していませんでした。
Array.new(n) { m }と書いた場合、配列をnサイズで生成し初期値をmで埋める、という意味になります。
Array.new(item.number_of_targets) { opponents_unit.random_target }もやっている事は同じです。
もしも自分なりにこの処理に干渉する算段がついているのなら今回はそちらで実装した方が良いかもしれません。
具体的に何が分からないと聞かれれば答えますけど方法が多岐に渡る事を聞かれると答え辛いので。
関数の中で関数を呼び脱出条件がなくスタックオーバーフローになった、って事だと思います。
aliasのバッティングなんかでそこそこ見掛けるエラーですね。
例えば以前、私が書いたコード(メモ欄解析)とは別に今回のコードを丸々コピペしたら
思いっきり競合するので内容を読み解いて適宜調整する必要があります。
というかサンプルコードとして渡した物だったのでそのまま使用する事は想定していませんでした。
Array.new(n) { m }と書いた場合、配列をnサイズで生成し初期値をmで埋める、という意味になります。
Array.new(item.number_of_targets) { opponents_unit.random_target }もやっている事は同じです。
もしも自分なりにこの処理に干渉する算段がついているのなら今回はそちらで実装した方が良いかもしれません。
具体的に何が分からないと聞かれれば答えますけど方法が多岐に渡る事を聞かれると答え辛いので。
Re: 【RGSS3】『敵n体ランダム』の回数増減
名無し蛙様、ご返答ありがとうございます。
初めから干渉する算段がついていたわけではありませんが
名無し蛙様から教えていただいた情報を元にGame_Actionの173行目以降を
下記の通り改変しました。
9行目の『aaa』を『2』や『-1』に変えて敵n体ランダム(1体の場合は除く)の時に
攻撃回数を増減させられることは確認出来ましたが
どうやってステートや装備品の特徴で、この『aaa』の数値を設定すればいいのかが分かりません。
初めから干渉する算段がついていたわけではありませんが
名無し蛙様から教えていただいた情報を元にGame_Actionの173行目以降を
下記の通り改変しました。
コード: 全て選択
#--------------------------------------------------------------------------
# ● 敵に対するターゲット
#--------------------------------------------------------------------------
def targets_for_opponents
if item.for_random?
if item.number_of_targets == 1 #敵1体ランダムの時はそのまま
Array.new(item.number_of_targets) { opponents_unit.random_target }
else
Array.new(item.number_of_targets + aaa) { opponents_unit.random_target }
end
elsif item.for_one?
num = 1 + (attack? ? subject.atk_times_add.to_i : 0)
if @target_index < 0
[opponents_unit.random_target] * num
else
[opponents_unit.smooth_target(@target_index)] * num
end
else
opponents_unit.alive_members
end
end
攻撃回数を増減させられることは確認出来ましたが
どうやってステートや装備品の特徴で、この『aaa』の数値を設定すればいいのかが分かりません。
Re: 【RGSS3】『敵n体ランダム』の回数増減
独自特徴は自分自身でメンテナンス出来る程度にスキルが無いと扱いが難しいかもしれません
汎用性や実行効率、見通しが劣るのであまり好みではないのですが直接メモ欄を覗く方法もあります
下準備が不要で競合リスクが低い点がメリットですね
ついでに見通しが悪くなるのでitem.for_random?以外の処理はaliasに任せた方が良いかな
states...RPG::State配列を取得する
equips.compact...RPG::EquipItem配列を取得する(装備が無い部位はnilが入ってるのでcompactで除外する)
inject...配列の値を合算する為に使用するメソッド
/\<ランダム攻撃回数増減\:(\-?)(\d+)\>/...今回使用するパターン。$1に-符号の有無、$2に数値文字列が格納される
すっごい説明すっ飛ばしてるとは思うんですけど1から10まで書くと膨大になるんですよね
Rubyは実用的なメソッドが多く、プリセットスクリプト内でもかなり活用しているので暇があれば吸収した方が良いです
自分も正規表現には詳しくありませんが、それでも基礎を覚えれば今回の入力補助程度は融通が利きます。
これで装備品・ステートに<ランダム攻撃回数増減:-3>等と書いた場合、反映されるはずです。
実行テストまではしてませんが念の為1回攻撃保証は付けています。
汎用性や実行効率、見通しが劣るのであまり好みではないのですが直接メモ欄を覗く方法もあります
下準備が不要で競合リスクが低い点がメリットですね
ついでに見通しが悪くなるのでitem.for_random?以外の処理はaliasに任せた方が良いかな
states...RPG::State配列を取得する
equips.compact...RPG::EquipItem配列を取得する(装備が無い部位はnilが入ってるのでcompactで除外する)
inject...配列の値を合算する為に使用するメソッド
/\<ランダム攻撃回数増減\:(\-?)(\d+)\>/...今回使用するパターン。$1に-符号の有無、$2に数値文字列が格納される
すっごい説明すっ飛ばしてるとは思うんですけど1から10まで書くと膨大になるんですよね
Rubyは実用的なメソッドが多く、プリセットスクリプト内でもかなり活用しているので暇があれば吸収した方が良いです
自分も正規表現には詳しくありませんが、それでも基礎を覚えれば今回の入力補助程度は融通が利きます。
コード: 全て選択
class Game_Action
#--------------------------------------------------------------------------
# ○ 敵に対するターゲット
#--------------------------------------------------------------------------
alias :_old_targets_for_opponents :targets_for_opponents
def targets_for_opponents
if item.for_random?
objects = subject.states
objects += subject.equips.compact if subject.actor?
attack_num_ex = objects.inject(0) do |r, obj|
if obj.note =~ /\<ランダム攻撃回数増減\:(\-?)(\d+)\>/
r + (($1.empty? ? 1 : -1) * $2.to_i)
else
r
end
end
attack_number = [1, item.number_of_targets + attack_num_ex].max
Array.new(attack_number) { opponents_unit.random_target }
else
_old_targets_for_opponents
end
end
end
実行テストまではしてませんが念の為1回攻撃保証は付けています。
Re: 【RGSS3】『敵n体ランダム』の回数増減
焼け石に水ですが正規表現の補足説明
この辺の知識はメモ欄にタグを作る時によく使うところです
①文字列と正規表現(RegExp)が合致した場合trueが返る
判定方法は以下のどれでも良いです
②原則として正規表現中の記号には特殊な意味がある。
記号を文字として解釈する場合は直前に\を付ける。逆に記号以外の直前に\がある場合特殊な意味がある。
③()で括る事で(グループ化)ヒットした文字を$1に格納する事が出来る
グループが複数ある場合は$2$3と続いていく
④文字列をメタ文字に置き換える事で曖昧な表現が可能になる
例として\dを使用した場合0-9までの数値にヒットする
⑤文字の後に*を書く事で0回以上の繰り返し、+で1回以上の繰り返し、?で0か1回という表現になる
この辺の知識はメモ欄にタグを作る時によく使うところです
①文字列と正規表現(RegExp)が合致した場合trueが返る
判定方法は以下のどれでも良いです
コード: 全て選択
str = "テスト"
regexp = /テスト/
if str.match(regexp) # ヒット
if regexp.match(str) # ヒット
if str =~ regexp # ヒット
記号を文字として解釈する場合は直前に\を付ける。逆に記号以外の直前に\がある場合特殊な意味がある。
コード: 全て選択
str = "<テスト>"
regexp = /\<テスト\>/
if str =~ regexp # ヒット
グループが複数ある場合は$2$3と続いていく
コード: 全て選択
str = "<テスト:1>"
regexp = /\<テスト\:(1)\>/
if str =~ regexp # ヒットして$1に"1"が格納される
例として\dを使用した場合0-9までの数値にヒットする
コード: 全て選択
str1 = "<テスト:1>"
str2 = "<テスト:10>"
regexp = /\<テスト\:(\d)\>/
if str1 =~ regexp # ヒットして$1に"1"が格納される
if str2 =~ regexp # ヒットしない。二桁以上の数値を判定する為には後述の方法を使用する
コード: 全て選択
str2 = "<テスト:123456>"
regexp = /\<テスト\:(\d+)\>/
if str2 =~ regexp # \dを六回繰り返した6桁の数値にもヒットする。$1に"123456"が格納される
Re: 【RGSS3】『敵n体ランダム』の回数増減
名無し蛙様、ご返答ありがとうございます。
添付いただいたスクリプトを導入し、動作テストをした所
無事に想定通りに動く事を確認出来ました。
どうもありがとうございます。
当方の知識不足の為、余分にお手を煩わせてしまい
申し訳ありませんでした。
添付いただいたスクリプトを導入し、動作テストをした所
無事に想定通りに動く事を確認出来ました。
どうもありがとうございます。
当方の知識不足の為、余分にお手を煩わせてしまい
申し訳ありませんでした。