#============================================================================== # [ZTBS] -Zenith Tactical Battle System- タクティカルバトルシステム #  〜CP3:ZTBS メイン処理&各種メソッド〜   by 水夜 #  ver1.10  Zenith Creation (http://zenith.ifdef.jp/) #------------------------------------------------------------------------------ # マップ上での戦略的なバトルを実現。 #  ※「CP制御ターンシステム」・・・スクリプトシェルフ(桜雅在土氏) #                   http://scriptshelf.jpn.org/x/ #============================================================================== #============================================================================== # ■ Scene_Map #============================================================================== class Scene_Map #-------------------------------------------------------------------------- # ● メイン処理 #-------------------------------------------------------------------------- alias ztbs_main main def main # ウェイトカウント @wait_count = 0 if $game_system.in_tactics and $game_system.tactics_setup and @help_window == nil # ヘルプウィンドウを作成 @help_window = Window_Help.new @help_window.back_opacity = 160 @help_window.visible = false end # 呼び戻す ztbs_main # ヘルプウィンドウを解放 if @help_window != nil @help_window.dispose @help_window = nil end # コマンドウィンドウ解放 dispose_command_window dispose_select_window end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- alias ztbs_update update def update if $game_system.in_tactics # 初期セットアップがされていない場合は実行 if !$game_system.tactics_setup setup start_phase0 end # ループ loop do # マップ、インタプリタ、プレイヤーの順に更新 # (この更新順序は、イベントを実行する条件が満たされているときに # プレイヤーに一瞬移動する機会を与えないなどの理由で重要) $game_map.update $game_system.map_interpreter.update $game_player.update if !$game_player.not_update and !effect? # システム (タイマー)、画面を更新 $game_system.update $game_screen.update # プレイヤーの場所移動中でなければループを中断 unless $game_temp.player_transferring break end # 場所移動を実行 transfer_player # トランジション処理中の場合、ループを中断 if $game_temp.transition_processing break end end # スプライトセットを更新 @spriteset.update # メッセージウィンドウを更新 @message_window.update # その他ウィンドウを更新 update_windows # ウェイト中の場合 if @wait_count > 0 # ウェイトカウントを減らす @wait_count -= 1 return end # エフェクト表示中の場合 if @spriteset.effect? return end # ゲームオーバーの場合 if $game_temp.gameover # ゲームオーバー画面に切り替え $scene = Scene_Gameover.new return end # タイトル画面に戻す場合 if $game_temp.to_title # タイトル画面に切り替え $scene = Scene_Title.new return end # トランジション処理中の場合 if $game_temp.transition_processing # トランジション処理中フラグをクリア $game_temp.transition_processing = false # トランジション実行 if $game_temp.transition_name == "" Graphics.transition(20) else Graphics.transition(40, "Graphics/Transitions/" + $game_temp.transition_name) end end # メッセージウィンドウ表示中の場合 if $game_temp.message_window_showing return end if $game_system.in_tactics # フェーズに応じて更新 case $game_system.tactics_phase when 0 update_phase0 when 1 update_phase1 when 2 update_phase2 when 3 update_phase3 when 4 update_phase4 end end # プレイヤーの移動中ではない場合 unless $game_player.moving? # 各種画面の呼び出しを実行 if $game_temp.battle_calling call_battle elsif $game_temp.shop_calling call_shop elsif $game_temp.name_calling call_name elsif $game_temp.menu_calling call_menu elsif $game_temp.save_calling call_save elsif $game_temp.debug_calling call_debug end end else ztbs_update end end #-------------------------------------------------------------------------- # ● プレイヤーの場所移動 #-------------------------------------------------------------------------- alias ztbs_transfer_player transfer_player def transfer_player # 移動先が現在のマップと異なる場合 if $game_map.map_id != $game_temp.player_new_map_id and $game_system.in_tactics # タクティクス終了処理 end_tactics end # 呼び戻す ztbs_transfer_player end #-------------------------------------------------------------------------- # ● タクティクス初期セットアップ #-------------------------------------------------------------------------- def setup # ターンカウント初期化 $game_system.tactics_turn = 0 # すり抜け状態と移動速度を記憶 $game_player.through_original = $game_player.through $game_player.speed_original = $game_player.move_speed # すり抜け ON と 速度 $game_player.through = true $game_player.move_speed = ZTBS::CURSOR_SPEED # ヘルプウィンドウを作成 @help_window = Window_Help.new @help_window.back_opacity = 160 @help_window.visible = false # アクターとエネミーのセットアップ clear_battler setup_actors setup_enemies # ダメージをクリア for actor in $game_system.tactics_actors.values + $game_system.tactics_dead_actors.values actor.damage = nil end # フェーズを 0 に設定 $game_system.tactics_phase = 0 $game_system.tactics_step = 0 # カーソル固定 $game_player.not_update = true # 初期セットアップ完了フラグ $game_system.tactics_setup = true @select = nil @revival = nil @end_map = nil @level_up = nil @gold = nil @treasures = nil end #-------------------------------------------------------------------------- # ● コマンドウィンドウ作成 #-------------------------------------------------------------------------- def make_command_window(index = 0) case $game_system.tactics_step when 0 if ZTBS::POSSIBLE_SAVE s1 = "アクター一覧" s2 = "セーブ" s3 = "タイトルへ" @command_window = Window_Command.new(170, [s1, s2, s3]) else s1 = "アクター一覧" s2 = "タイトルへ" @command_window = Window_Command.new(170, [s1, s2]) end @command_window.x = 0 @command_window.y = 64 when 2 s1 = "移動" s2 = $data_system.words.attack s3 = $data_system.words.skill s4 = $data_system.words.item s5 = "待機" @command_window = Window_Command.new(120, [s1, s2, s3, s4, s5]) @command_window.x = 0 @command_window.y = 64 when 5 s1 = $data_system.words.attack s2 = $data_system.words.skill s3 = $data_system.words.item s4 = "待機" @command_window = Window_Command.new(120, [s1, s2, s3, s4]) @command_window.x = 0 @command_window.y = 64 end if @command_window != nil @command_window.back_opacity = 160 @command_window.index = index if $game_player.y < 4 @command_window.y = 416 - @command_window.height end if $game_player.x < 10 @command_window.x = 640 - @command_window.width end end end #-------------------------------------------------------------------------- # ● コマンドウィンドウ解放 #-------------------------------------------------------------------------- def dispose_command_window if @command_window != nil @command_window.dispose @command_window = nil end end #-------------------------------------------------------------------------- # ● セレクトウィンドウ作成 #-------------------------------------------------------------------------- def make_select_window(type, actor = nil, index = 0) case type # アクター一覧 when 0 @select_window = Window_TActors.new # スキル when 1 @select_window = Window_TSkill.new(actor) if index != 0 @select_window.index = @select_window.data.index(index) end # アイテム when 2 @select_window = Window_TItem.new if index != 0 @select_window.index = @select_window.data.index(index) end end if @select_window != nil @select_window.help_window = @help_window @select_window.back_opacity = 160 end end #-------------------------------------------------------------------------- # ● セレクトウィンドウ解放 #-------------------------------------------------------------------------- def dispose_select_window if @select_window != nil @select_window.dispose @select_window = nil end end #-------------------------------------------------------------------------- # ● 各種ウィンドウ更新 #-------------------------------------------------------------------------- def update_windows if @command_window != nil @command_window.update end if @select_window != nil @select_window.update end end #-------------------------------------------------------------------------- # ● タクティクス終了処理 #-------------------------------------------------------------------------- def end_tactics for actor in $game_system.tactics_actors.values + $game_system.tactics_dead_actors.values # DamageEX に対応 if defined? XRXS19 # 特殊効果をクリア actor.current_action.clear_xrxs19_special_effect end # ダメージをクリア actor.damage = nil # バトル用ステートを解除 actor.remove_states_battle end # バトラーのクリア clear_battler # ヘルプウィンドウを解放 if @help_window != nil @help_window.dispose @help_window = nil end # コマンドウィンドウ解放 dispose_command_window dispose_select_window # すり抜け状態と移動速度を復帰 $game_player.through = $game_player.through_original $game_player.move_speed = $game_player.speed_original # カーソル固定を解除 $game_player.not_update = false # 初期セットアップをクリア $game_system.tactics_setup = false @select = nil @revival = nil @end_map = nil @level_up = nil @gold = nil @treasures = nil end #-------------------------------------------------------------------------- # ● アクターのセットアップ #-------------------------------------------------------------------------- def setup_actors $game_system.tactics_actors = {} for event in $game_map.events.values if event.name.include?("actor") actor_id = event.name.delete("actor").to_i if $game_actors[actor_id].dead? event.erase # アクターをハッシュに格納 $game_system.tactics_dead_actors[event.id] = $game_actors[actor_id] else # アクターをハッシュに格納 $game_system.tactics_actors[event.id] = $game_actors[actor_id] end end end end #-------------------------------------------------------------------------- # ● エネミーのセットアップ #-------------------------------------------------------------------------- def setup_enemies $game_system.tactics_enemies = {} for event in $game_map.events.values if event.name.include?("enemy") enemy_id = event.name.delete("enemy").to_i # エネミーをハッシュに格納 $game_system.tactics_enemies[event.id] = Game_Enemy.new(0, enemy_id) end end end #-------------------------------------------------------------------------- # ● バトラーのクリア #-------------------------------------------------------------------------- def clear_battler $game_system.tactics_actors.clear $game_system.tactics_enemies.clear $game_system.tactics_dead_actors.clear end #-------------------------------------------------------------------------- # ● 消去バトラーセット #-------------------------------------------------------------------------- def set_erase_battler @erase = [] common_event = [] for i in $game_system.tactics_actors.keys battler = $game_system.tactics_actors[i] # 戦闘不能か? if battler.dead? # コラプス $game_map.events[i].collapse = 1 # 消去対象に入れる @erase.push($game_map.events[i]) # 撃破イベントセット if defined? beat_event common_event += set_beat_event(i) end end end for i in $game_system.tactics_enemies.keys battler = $game_system.tactics_enemies[i] # 戦闘不能か? if battler.dead? # コラプス $game_map.events[i].collapse = 2 # 消去対象に入れる @erase.push($game_map.events[i]) # 撃破イベントセット if defined? beat_event common_event += set_beat_event(i) end end end # 撃破イベント実行 if common_event.size > 0 $game_system.map_interpreter.setup(common_event, 0) end end #-------------------------------------------------------------------------- # ● アクター復活 #-------------------------------------------------------------------------- def battler_revival for i in $game_system.tactics_dead_actors.keys battler = $game_system.tactics_dead_actors[i] # 戦闘不能か? if !battler.dead? $game_map.events[i].cancel_erase $game_system.tactics_actors[i] = $game_system.tactics_dead_actors[i] $game_system.tactics_dead_actors.delete(i) end end end #-------------------------------------------------------------------------- # ● 勝敗判定 #-------------------------------------------------------------------------- def judge # 消去対象を消す if @erase != nil for battler in @erase if battler.invisible battler.erase if $game_system.tactics_actors.keys.include?(battler.id) $game_system.tactics_dead_actors[battler.id] = $game_system.tactics_actors[battler.id] $game_system.tactics_actors.delete(battler.id) else $game_system.tactics_enemies.delete(battler.id) end @battler = nil if @battler == battler end end @erase = nil end # エネミー全滅で勝利 if $game_system.in_tactics and $game_system.tactics_enemies.size == 0 start_phase3(0) return true end # アクター全滅で敗北 if $game_system.in_tactics and $game_system.tactics_actors.size == 0 start_phase3(1) return true end return false end #-------------------------------------------------------------------------- # ● 終了後場所移動 #-------------------------------------------------------------------------- def tactics_end_transfer(parameters) # ゲームオーバーの場合 if parameters[0] == 0 $game_temp.gameover = true return end # 場所移動フラグをセット $game_temp.player_transferring = true # 移動先をセット $game_temp.player_new_map_id = parameters[0] $game_temp.player_new_x = parameters[1] $game_temp.player_new_y = parameters[2] # トランジション準備 Graphics.freeze # 色調変更を開始 if parameters[3] $game_screen.start_tone_change(Tone.new(-255, -255, -255), 0) end # トランジション処理中フラグをセット $game_temp.transition_processing = true $game_temp.transition_name = "" end #-------------------------------------------------------------------------- # ● ウィンドウ位置調整 #-------------------------------------------------------------------------- def move_window if $game_player.y < 4 @help_window.y = 416 else @help_window.y = 0 end end #-------------------------------------------------------------------------- # ● 前のアクターへ #-------------------------------------------------------------------------- def back_actor n = $game_system.tactics_actors.keys.index(@battler.id) if n > 0 actor = $game_map.events[$game_system.tactics_actors.keys[n - 1]] else actor = $game_map.events[$game_system.tactics_actors.keys[$game_system.tactics_actors.keys.size - 1]] end $game_player.moveto(actor.x, actor.y) end #-------------------------------------------------------------------------- # ● 次のアクターへ #-------------------------------------------------------------------------- def next_actor n = $game_system.tactics_actors.keys.index(@battler.id) if n < $game_system.tactics_actors.keys.size - 1 actor = $game_map.events[$game_system.tactics_actors.keys[n + 1]] else actor = $game_map.events[$game_system.tactics_actors.keys[0]] end $game_player.moveto(actor.x, actor.y) end #-------------------------------------------------------------------------- # ● カーソル位置を戻す #-------------------------------------------------------------------------- def back_cursor if @active_battler != nil # カーソル位置を戻す $game_player.moveto(@active_battler.x, @active_battler.y) get_cursor_battler # ヘルプウィンドウ更新 set_battler_info @help_window.visible = true end end #-------------------------------------------------------------------------- # ● カーソル位置のバトラー(イベント)取得 #-------------------------------------------------------------------------- def get_cursor_battler for event_id in $game_system.tactics_actors.keys + $game_system.tactics_enemies.keys @battler = $game_map.events[event_id] if @battler != nil if $game_player.x == @battler.x and $game_player.y == @battler.y break else @battler = nil end else @battler = nil end end end #-------------------------------------------------------------------------- # ● カーソルに最も近いバトラー取得 #-------------------------------------------------------------------------- def nearest_battler(list) nr = nil for i in list battler = $game_map.events[i] r = ($game_player.x - battler.x).abs + ($game_player.y - battler.y).abs if nr == nil or r < nr nr = r nearest = i elsif r == nr srand if rand(2) == 0 nr = r nearest = i end end end return nearest end #-------------------------------------------------------------------------- # ● 対象に最も近いポジション取得 #-------------------------------------------------------------------------- def nearest_position(target_pos, pos_list) nr = nil for position in pos_list r = (target_pos[0] - position[0]).abs + (target_pos[1] - position[1]).abs if nr == nil or r < nr nr = r nearest = position elsif r == nr srand if rand(2) == 0 nr = r nearest = position end end end return nearest end #-------------------------------------------------------------------------- # ● 対象から最も遠いポジション取得 #-------------------------------------------------------------------------- def far_away_position(target_pos, pos_list) nr = nil for position in pos_list r = (target_pos[0] - position[0]).abs + (target_pos[1] - position[1]).abs if nr == nil or r > nr nr = r far_away = position elsif r == nr srand if rand(2) == 0 nr = r far_away = position end end end return far_away end #-------------------------------------------------------------------------- # ● バトラー情報セット #-------------------------------------------------------------------------- def set_battler_info if @battler != nil # ヘルプウィンドウにアクター or エネミーをセット if $game_system.tactics_actors.keys.include?(@battler.id) @help_window.set_actor($game_system.tactics_actors[@battler.id]) elsif $game_system.tactics_enemies.keys.include?(@battler.id) @help_window.set_enemy($game_system.tactics_enemies[@battler.id]) else @help_window.visible = false return end # ヘルプウィンドウを可視化 @help_window.visible = true else @help_window.visible = false end end #-------------------------------------------------------------------------- # ● バトラー情報リフレッシュ #-------------------------------------------------------------------------- def refresh_battler_info if @battler != nil # ヘルプウィンドウにアクター or エネミーをセット if $game_system.tactics_actors.keys.include?(@battler.id) @help_window.refresh_actor($game_system.tactics_actors[@battler.id]) else @help_window.refresh_enemy($game_system.tactics_enemies[@battler.id]) end # ヘルプウィンドウを可視化 @help_window.visible = true else @help_window.visible = false end end #-------------------------------------------------------------------------- # ● エフェクト中判定 #-------------------------------------------------------------------------- def effect? for event_id in $game_system.tactics_actors.keys + $game_system.tactics_enemies.keys battler = $game_map.events[event_id] if battler.effect return true end end return false end #-------------------------------------------------------------------------- # ● 発動可能判定 #-------------------------------------------------------------------------- def possible_action? # 範囲内にカーソルがあるか判定 if !in_area?($game_player.x, $game_player.y) return false end # 効果範囲内に対象がいるか判定 case @attacker.current_action.kind when 0 @can_attack = target_in_area($game_system.tactics_enemies.keys) if defined? @attacker.attack_range and @attacker.attack_range != nil battler_exist = @attacker.attack_range[1][3] else battler_exist = true end when 1 skill = $data_skills[@attacker.current_action.skill_id] battler_exist = skill.range[1][3] case skill.scope when 0 return false when 1, 2 @can_attack = target_in_area($game_system.tactics_enemies.keys) when 3, 4 @can_attack = target_in_area($game_system.tactics_actors.keys) when 5, 6 return true end when 2 item = $data_items[@attacker.current_action.item_id] battler_exist = item.range[1][3] case item.scope when 0 return false when 1, 2 @can_attack = target_in_area($game_system.tactics_enemies.keys) when 3, 4 @can_attack = target_in_area($game_system.tactics_actors.keys) when 5, 6 return true end end if @can_attack.size == 0 @can_attack = nil return false end # カーソル位置に対象がいるか判定 if battler_exist and @battler == nil return false end return true end #-------------------------------------------------------------------------- # ● カーソル自動移動 (エネミーフェーズ) #-------------------------------------------------------------------------- def move_cursor_auto(position) @enemy_move_count = ZTBS::ENEMY_THINKING if @enemy_move_count == nil unless $game_player.moving? $game_player.move_toward_position(position[0], position[1]) if $game_player.x != position[0] or $game_player.y != position[1] return end end if $game_player.x == position[0] and $game_player.y == position[1] @enemy_move_count -= 1 # カーソル固定 $game_player.not_update = true end if @enemy_move_count == 0 @enemy_move_count = nil return true else return false end end #-------------------------------------------------------------------------- # ● バトラー存在判定 (エネミー用) #-------------------------------------------------------------------------- def battlers_in_area(position_list, type = 0) battlers = [] case type when 0 n = $game_system.tactics_actors.keys for i in n battlers.push($game_map.events[i]) end when 1 n = $game_system.tactics_enemies.keys for i in n battlers.push($game_map.events[i]) end when 2 n = $game_system.tactics_actors.keys + $game_system.tactics_enemies.keys for i in n battlers.push($game_map.events[i]) end end target_battlers = [] for target in battlers for position in position_list if target.x == position[0] and target.y == position[1] target_battlers.push(target.id) end end end return target_battlers end #-------------------------------------------------------------------------- # ● 対象ランダム選択 (エネミー用) #-------------------------------------------------------------------------- def decide_target(targets) n = rand(targets.size) return targets[n] end #-------------------------------------------------------------------------- # ● スキルターゲット判定 (エネミー用) #-------------------------------------------------------------------------- def check_skill_target(skill, position_list) # 対象の種類取得 battlers = [] case skill.scope when 1, 2 n = $game_system.tactics_actors.keys type = 0 for i in n battlers.push($game_map.events[i]) end when 3, 4, 7 n = $game_system.tactics_enemies.keys type = 1 for i in n battlers.push($game_map.events[i]) end end if skill.range[1][3] on_target = true else on_target = false end # 対象エリア検索 target_battlers = [[], [], false] for position in position_list next_position = 0 for target in battlers if (target.x != position[0] or target.y != position[1]) and on_target next_position += 1 end end if next_position == battlers.size next end target_positions = search_target_area(position[0], position[1]) battler_count = [] for area in target_positions for target in battlers if target.x == area[0] and target.y == area[1] battler_count.push(target.id) end end # まず、対象が多いところを優先 if battler_count.size > target_battlers[1].size target_battlers[0] = position target_battlers[1] = battler_count target_battlers[2] = on_area?(position[0], position[1], type) # 次に、カーソル位置にバトラーがいるところを優先 elsif battler_count.size == target_battlers[1].size if on_area?(position[0], position[1], type) if target_battlers[2] if rand(2) == 0 target_battlers[0] = position target_battlers[1] = battler_count target_battlers[2] = true end else target_battlers[0] = position target_battlers[1] = battler_count target_battlers[2] = true end end end end end return target_battlers end #-------------------------------------------------------------------------- # ● 経験値など獲得 #-------------------------------------------------------------------------- def get_exp_etc(target) @level_up = {} if @level_up == nil @gold = 0 if @gold == nil @treasures = [] if @treasures == nil # 経験値全員獲得の場合 if ZTBS::EXP_ALL exp = target.exp for actor in $game_system.tactics_actors.values if actor == @attacker pre_level = actor.level actor.exp += exp if !actor.cant_get_exp? if actor.level > pre_level if @level_up[actor] == nil @level_up[actor] = [pre_level, actor.level] else @level_up[actor][1] = actor.level end end else pre_level = actor.level actor.exp += Integer(exp * ZTBS::C_EXP) if !actor.cant_get_exp? if actor.level > pre_level if @level_up[actor] == nil @level_up[actor] = [pre_level, actor.level] else @level_up[actor][1] = actor.level end end end end # トドメをさしたアクターのみ経験値獲得の場合 elsif $game_system.tactics_step == 9 if @attacker.is_a?(Game_Actor) and !@attacker.cant_get_exp? pre_level = @attacker.level @attacker.exp += target.exp if @attacker.level > pre_level if @level_up[@attacker] == nil @level_up[@attacker] = [pre_level, @attacker.level] else @level_up[@attacker][1] = @attacker.level end end end end # ゴールド獲得 $game_party.gain_gold(target.gold) @gold += target.gold # トレジャー獲得 if target.item_id > 0 item = $data_items[target.item_id] end if target.weapon_id > 0 item = $data_weapons[target.weapon_id] end if target.armor_id > 0 item = $data_armors[target.armor_id] end if rand(100) < target.treasure_prob case item when RPG::Item @treasures.push(item) $game_party.gain_item(item.id, 1) when RPG::Weapon @treasures.push(item) $game_party.gain_weapon(item.id, 1) when RPG::Armor @treasures.push(item) $game_party.gain_armor(item.id, 1) end end if !defined? result_window @level_up = nil @gold = nil @treasures = nil end end #-------------------------------------------------------------------------- # ● 基本アクション 結果作成 #-------------------------------------------------------------------------- def make_basic_action_result # 攻撃の場合 if @attacker.current_action.basic == 0 # DamageEX に対応 if defined? XRXS19 # 使用者のダメージ値を nil でリセット @attacker.damage = nil # 使用する武器の特殊効果の取得 @attacker.set_xrxs19_special_effect(@attacker.equip_element_set) end # アニメーション ID を設定 @animation1_id = @attacker.animation1_id @animation2_id = @attacker.animation2_id # 通常攻撃の効果を適用 for target in @targets.values target.attack_effect(@attacker) end return end end #-------------------------------------------------------------------------- # ● スキルアクション 結果作成 #-------------------------------------------------------------------------- def make_skill_action_result # スキルを取得 @skill = $data_skills[@attacker.current_action.skill_id] # DamageEX に対応 if defined? XRXS19 # 使用者のダメージ値を nil でリセット @attacker.damage = nil # 使用するスキルの特殊効果の取得 @attacker.set_xrxs19_special_effect(@attacker.skill_element_set(@skill)) end # ヘルプウィンドウにスキル名を表示 @help_window.set_text(@skill.name, 1) @help_window.visible = true # SP 消費 @attacker.sp -= @skill.sp_cost # アニメーション ID を設定 @animation1_id = @skill.animation1_id @animation2_id = @skill.animation2_id # スキルの効果を適用 for target in @targets.values target.skill_effect(@attacker, @skill) end end #-------------------------------------------------------------------------- # ● アイテムアクション 結果作成 #-------------------------------------------------------------------------- def make_item_action_result # アイテムを取得 @item = $data_items[@attacker.current_action.item_id] # ヘルプウィンドウにアイテム名を表示 @help_window.set_text(@item.name, 1) @help_window.visible = true # 消耗品の場合 if @item.consumable # 使用したアイテムを 1 減らす $game_party.lose_item(@item.id, 1) end # アニメーション ID を設定 @animation1_id = @item.animation1_id @animation2_id = @item.animation2_id # アイテムの効果を適用 for target in @targets.values target.item_effect(@item) end end end