ページ 1 / 1
【RGSS3】faida様の敵行動用のターンカウントについて
Posted: 2021年3月25日(木) 02:39
by Rento
http://faida.blog92.fc2.com/blog-entry-177.html
faida様の ☆enemy_turn_count(敵行動用のターンカウントを敵別にする)について
条件に該当する行動がない場合、条件に該当するターンまでカウントを加算し
新たに戦闘行動を選択するには、どのように記述すればよいでしょうか。
ターン経過毎に 1→2→3→1→2→3 のスキルを使用するエネミーが
1のスキルを封印された場合、
【現在の挙動】
行動しない→2→3→行動しない→2→3→行動しない→・・・
【理想の状態】
2→3→2→3→2→3→・・・
封印された状態を条件に2→3→2→3のローテーションで戦闘行動を追加したりもしてみましたが
封印解除のタイミングで 1→2→2→3 等イレギュラーなローテーションに移行したりもあり
悩んでおります。
どなたかご教示いただきたく、何卒宜しくお願い致します。
Re: 【RGSS3】faida様の敵行動用のターンカウントについて
Posted: 2021年3月25日(木) 16:12
by 名無し蛙
どうもこんにちは
まず大前提なんですけど元のスクリプトが機能していませんね…
①行動作成処理から半端に移植した為、行動再作成処理が実行されない
②そもそも行動再作成処理をしても元の行動作成処理がそのままなので上書きされて意味が無い
競合リスクがやや高くなりますがScene_Battle#process_actionに処理を挿入するのが自然だと思います
コード: 全て選択
class Game_Enemy < Game_Battler
#--------------------------------------------------------------------------
# ○ オブジェクト初期化
#--------------------------------------------------------------------------
alias :etc_initialize :initialize
def initialize(index, enemy_id)
etc_initialize(index, enemy_id)
@turn_count = 0
end
#--------------------------------------------------------------------------
# ○ 行動条件合致判定[ターン数]
#--------------------------------------------------------------------------
def conditions_met_turns?(param1, param2)
n = @turn_count # ☆
if param2 == 0
n == param1
else
n > 0 && n >= param1 && n % param2 == param1 % param2
end
end
#--------------------------------------------------------------------------
# ○ 戦闘行動の作成
#--------------------------------------------------------------------------
alias :etc_make_actions :make_actions
def make_actions
etc_make_actions
@turn_count += 1
end
end
class Scene_Battle < Scene_Base
#--------------------------------------------------------------------------
# ○ 戦闘行動の処理
#--------------------------------------------------------------------------
def process_action
return if scene_changing?
if !@subject || !@subject.current_action
@subject = BattleManager.next_subject
end
return turn_end unless @subject
remake_actions # ☆
if @subject.current_action
@subject.current_action.prepare
if @subject.current_action.valid?
@status_window.open
execute_action
end
@subject.remove_current_action
end
process_action_end unless @subject.current_action
end
#--------------------------------------------------------------------------
# ● 戦闘行動の再作成
#--------------------------------------------------------------------------
def remake_actions
trial_count = 5
until @subject.current_action && @subject.current_action.valid? && 0 <= trial_count do
@subject.make_actions
trial_count -= 1
end
end
end
ターンカウントの個別化に加えて行動直前に最大5回だけ行動作成を試行しています
改造としては単純な部類なので後は適宜使いやすく修正してください
Re: 【RGSS3】faida様の敵行動用のターンカウントについて
Posted: 2021年3月25日(木) 18:52
by faida
こんばんは。
そもそもこれ、大前提として「1ターンの間に2回以上行動する場合」のスクリプトですので、
行動再作成処理が実行されるのが2回以上行動の2回目以降なのは(当時では)正常な動作です。
あと、行動作成処理のほうではなく「行動条件」のほうを再定義しているため、
上書きはされていないと思います。
それを「機能していない」って言い切られると困るんですが……まあ「機能していない」スクリプト書くほうが悪いんでそこは受け止めます。
Rento様のおっしゃるような仕様で、かつどのエネミーに関しても
1ターンの間に2回以上行動することがない、または2回以上行動しても
1ターンの間にローテーションが進まないようにしたいのであれば、
名無し蛙様のスクリプトが最適だと思います。
紛らわしい名称で大変申し訳ありません。
※追記
だとしても行動不能時にターンカウントを進めず、そのままの状態というのは
好みの分かれる仕様かなと思ったので修正しておきます。
コード: 全て選択
# 設定項目:行動不可時にターンカウントを進める
COUNT_TURN_NOT_MOVABLE = true
class Game_Enemy
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias etc_initialize initialize
def initialize(index, enemy_id)
etc_initialize(index, enemy_id)
@turn_count = 0
end
#--------------------------------------------------------------------------
# ● 現在の戦闘行動を除去
#--------------------------------------------------------------------------
alias etc_remove_current_action remove_current_action
def remove_current_action
etc_remove_current_action
@turn_count += 1
reset_actions
end
#--------------------------------------------------------------------------
# ● 行動条件合致判定[ターン数]
#--------------------------------------------------------------------------
def conditions_met_turns?(param1, param2)
n = @turn_count # ☆
if param2 == 0
n == param1
else
n > 0 && n >= param1 && n % param2 == param1 % param2
end
end
#--------------------------------------------------------------------------
# ● 戦闘行動の作成
#--------------------------------------------------------------------------
alias etc_make_actions make_actions
def make_actions
etc_make_actions
@turn_count += 1 if COUNT_TURN_NOT_MOVABLE && @actions.empty?
end
#--------------------------------------------------------------------------
# ● 戦闘行動の再作成
#--------------------------------------------------------------------------
def reset_actions
return if @actions.empty?
action_list = enemy.actions.select {|a| action_valid?(a) }
return if action_list.empty?
rating_max = action_list.collect {|a| a.rating }.max
rating_zero = rating_max - 3
action_list.reject! {|a| a.rating <= rating_zero }
@actions.each do |action|
action.set_enemy_action(select_enemy_action(action_list, rating_zero))
end
end
end
Re: 【RGSS3】faida様の敵行動用のターンカウントについて
Posted: 2021年3月25日(木) 19:47
by 名無し蛙
あーなるほど
普通に使用したら@actionsは空になるだろうと思ったんですけど使用に際して前提条件があったんですか
確かに複数回行動の二回目以降には適用されますね
個別ターンカウントなんて何に使うんだろうと思っていたんですけど二回行動敵を想定していたと
スクリプトの意図を誤読した事を謹んでお詫びして訂正いたします
Re: 【RGSS3】faida様の敵行動用のターンカウントについて
Posted: 2021年3月26日(金) 03:18
by Rento
名無し蛙様
faida様
早々にアドバイスとスクリプト案や修正まで頂き、ありがとうございます!
私自身もスクリプトの意図・内容を誤認しており、お二方がお話された内容から
誤った認識だった旨理解することができました。
改めてお伺いなのですが、
【例】1ターンに複数回追加行動を行うエネミーが下記行動パターン
(ターンカウントに基づいたローテーション)で行動。行動条件はそれぞれn+8x
【挙動】攻撃→魔法→攻撃→魔法→特技1→魔法→魔法→特技1→最初に戻る
上記エネミーがスキルの行動条件を満たさない場合(封印等)、当該スクリプトでは下記のような
挙動・判定を行うものではないという事でしょうか。
【例】魔法を封じられ行動選択が無い場合、ターンカウントを加算しローテーションをすっとばして改めて判定
【挙動】攻撃→ 攻撃→ 特技1→ 魔法→特技1→最初に戻る
(DQ3のバ○モスやまほうおばば(1回行動ですが)のような挙動)
拙い説明で申しわけございません。
恐れ入りますが、ご確認いただけましたら幸いです。
何卒宜しくお願い致します。
Re: 【RGSS3】faida様の敵行動用のターンカウントについて
Posted: 2021年3月26日(金) 17:47
by 名無し蛙
行動前再設定に加えて複数回行動まで絡む感じですか
エネミーの行動内容は通常、ターン開始時に決定されるので
ターン開始~行動実行までの状態変化に対応する場合は行動直前にも行動内容の設定が必要になります。
①ターンカウントの個別化②複数回行動の対応③実行直前の設定の三つの要素を満たす必要があり
現状私のコードは①③、faida氏のコードは①②しか条件を満たしていないと思います。
これはあっちを立てればこっちが立たずなので
どちらをベースにするにせよ三つ目を上乗せするのはちょっと骨が折れますね。
いっそ完全に行動ルーチンを特殊化した方が楽なのでは。とりあえず実装の一例です。
対象エネミーのメモ欄に<ローテーションルーチン>と記述する事で行動を特殊化します
コード: 全て選択
# 試行回数
TRIAL_COUNT = 8
module EnemyEx
#--------------------------------------------------------------------------
# ○ 行動速度の決定
#--------------------------------------------------------------------------
def make_speed
@speed = agi + rand(5 + agi / 4)
end
#--------------------------------------------------------------------------
# ○ 行動条件合致判定[ターン数]
#--------------------------------------------------------------------------
def conditions_met_turns?(param1, param2)
n = @turn_count # ☆
if param2 == 0
n == param1
else
n > 0 && n >= param1 && n % param2 == param1 % param2
end
end
#--------------------------------------------------------------------------
# ○ 戦闘行動の作成
#--------------------------------------------------------------------------
def make_actions
clear_actions
return unless movable?
@actions = Array.new(make_action_times) { Game_Action.new(self) }
end
#--------------------------------------------------------------------------
# ● 現在行動の設定
#--------------------------------------------------------------------------
def setting_current_action
action_list = []
TRIAL_COUNT.times do
action_list = enemy.actions.select {|a| action_valid?(a) }
@turn_count += 1
action_list.empty? ? next : break
end
return if action_list.empty?
rating_max = action_list.collect {|a| a.rating }.max
rating_zero = rating_max - 3
action_list.reject! {|a| a.rating <= rating_zero }
current_action.set_enemy_action(select_enemy_action(action_list, rating_zero))
end
end
class Game_Enemy < Game_Battler
#--------------------------------------------------------------------------
# ○ オブジェクト初期化
#--------------------------------------------------------------------------
alias :etc_initialize :initialize
def initialize(index, enemy_id)
etc_initialize(index, enemy_id)
if enemy.note.include?("<ローテーションルーチン>")
extend EnemyEx
@turn_count = 0 # 実装上module側のinitializeに移せない
end
end
end
class Game_Action
#--------------------------------------------------------------------------
# ○ 行動準備
#--------------------------------------------------------------------------
alias :etc_prepare :prepare
def prepare
subject.setting_current_action if @subject.is_a?(EnemyEx)
etc_prepare
end
end
Re: 【RGSS3】faida様の敵行動用のターンカウントについて
Posted: 2021年3月27日(土) 08:24
by Rento
名無し蛙様
faida様
何度も修正スクリプト作成や、わかりやすくご説明いただいた事感謝致します。
おかげさまで理想通りの挙動とする事ができ感無量でございます。
また、faida様のスクリプトは以前から利用させていただいており、
この場を借りて改めてお礼申し上げます。本当にありがとうございます。