#============================================================================== # [ZTBS] -Zenith Tactical Battle System- タクティカルバトルシステム #  〜6:ZTBS エリア&ルート検索〜   by 水夜 #  ver1.30  Zenith Creation (http://zenith.ifdef.jp/) #------------------------------------------------------------------------------ # マップ上での戦略的なバトルを実現。 #============================================================================== #============================================================================== # ■ Scene_Map #============================================================================== class Scene_Map #-------------------------------------------------------------------------- # ● 移動エリア & ルート検索 #-------------------------------------------------------------------------- def search_route if $game_system.tactics_actors.keys.include?(@battler.id) battler = $game_system.tactics_actors[@battler.id] else battler = $game_system.tactics_enemies[@battler.id] end @position = [[@battler.x, @battler.y]] @route = [[]] more_step = [0] for i in more_step x = @position[i][0] y = @position[i][1] # 下 if !@position.include?([x, y + 1]) and @battler.passable?(x, y, 2) @position.push([x, y + 1]) @route.push(@route[i] + [2]) if @route[i].size + 1 < battler.movable more_step.push(@route.index(@route[i] + [2])) end end # 左 if !@position.include?([x - 1, y]) and @battler.passable?(x, y, 4) @position.push([x - 1, y]) @route.push(@route[i] + [4]) if @route[i].size + 1 < battler.movable more_step.push(@route.index(@route[i] + [4])) end end # 右 if !@position.include?([x + 1, y]) and @battler.passable?(x, y, 6) @position.push([x + 1, y]) @route.push(@route[i] + [6]) if @route[i].size + 1 < battler.movable more_step.push(@route.index(@route[i] + [6])) end end # 上 if !@position.include?([x, y - 1]) and @battler.passable?(x, y, 8) @position.push([x, y - 1]) @route.push(@route[i] + [8]) if @route[i].size + 1 < battler.movable more_step.push(@route.index(@route[i] + [8])) end end end end #-------------------------------------------------------------------------- # ● 攻撃エリア検索 #-------------------------------------------------------------------------- def search_attack_area position = [[@battler.x, @battler.y]] if $game_system.tactics_actors.keys.include?(@battler.id) battler = $game_system.tactics_actors[@battler.id] else battler = $game_system.tactics_enemies[@battler.id] end case battler.current_action.kind when 0 if (defined? ACTOR_RANGE and @attacker.is_a?(Game_Actor)) or (defined? ENEMY_RANGE and @attacker.is_a?(Game_Enemy)) form = battler.attack_range[0][0] max = battler.attack_range[0][1] through = battler.attack_range[0][2] cannot_near = battler.attack_range[0][3] if cannot_near == nil cannot_near = false end else form = 0 max = 1 through = false cannot_near = false end if battler.is_a?(Game_Actor) type = 1 else type = 0 end when 1 skill = $data_skills[battler.current_action.skill_id] form = skill.range[0][0] max = skill.range[0][1] through = skill.range[0][2] cannot_near = skill.range[0][3] if cannot_near == nil cannot_near = false end return position if max == 0 case skill.scope when 0, 5, 6 type = 4 when 1, 2 if battler.is_a?(Game_Actor) type = 1 else type = 0 end when 3, 4 if battler.is_a?(Game_Actor) type = 0 else type = 1 end when 7 return position end when 2 item = $data_items[battler.current_action.item_id] form = item.range[0][0] max = item.range[0][1] through = item.range[0][2] cannot_near = item.range[0][3] if cannot_near == nil cannot_near = false end return position if max == 0 case item.scope when 0, 5, 6 type = 4 when 1, 2 if battler.is_a?(Game_Actor) type = 1 else type = 0 end when 3, 4 if battler.is_a?(Game_Actor) type = 0 else type = 1 end when 7 return position end end more_step = [0] route = [[]] case form # ひし形or四角形の場合 when 0, 2, 3 if form == 2 or form == 3 max *= 2 end for i in more_step x = position[i][0] y = position[i][1] # 障害物無視の場合 if through # 下 if !position.include?([x, y + 1]) position.push([x, y + 1]) route.push(route[i] + [2]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [2])) end end # 左 if !position.include?([x - 1, y]) position.push([x - 1, y]) route.push(route[i] + [4]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [4])) end end # 右 if !position.include?([x + 1, y]) position.push([x + 1, y]) route.push(route[i] + [6]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [6])) end end # 上 if !position.include?([x, y - 1]) position.push([x, y - 1]) route.push(route[i] + [8]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [8])) end end # 障害物無視でない場合 else # 下 if !position.include?([x, y + 1]) and !on_area?(x, y, type) and (@battler.passable?(x, y, 2) or (on_area?(x, y + 1, type) and type != 4)) position.push([x, y + 1]) route.push(route[i] + [2]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [2])) end end # 左 if !position.include?([x - 1, y]) and !on_area?(x, y, type) and (@battler.passable?(x, y, 4) or (on_area?(x - 1, y, type) and type != 4)) position.push([x - 1, y]) route.push(route[i] + [4]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [4])) end end # 右 if !position.include?([x + 1, y]) and !on_area?(x, y, type) and (@battler.passable?(x, y, 6) or (on_area?(x + 1, y, type) and type != 4)) position.push([x + 1, y]) route.push(route[i] + [6]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [6])) end end # 上 if !position.include?([x, y - 1]) and !on_area?(x, y, type) and (@battler.passable?(x, y, 8) or (on_area?(x, y - 1, type) and type != 4)) position.push([x, y - 1]) route.push(route[i] + [8]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [8])) end end end end # 四角形の場合 case form when 2 delete = [] for pos in position if (pos[0] - @battler.x).abs > max/2 or (pos[1] - @battler.y).abs > max/2 delete.push(pos) end end for i in delete position.delete(i) end when 3 delete = [] for pos in position if (pos[0] - @battler.x).abs != max/2 and (pos[1] - @battler.y).abs != max/2 delete.push(pos) end end for i in delete position.delete(i) end return position end # 十字形の場合 when 1 for i in 1..max x = position[0][0] y = position[0][1] # 障害物無視の場合 if through position.push([x, y + i]) position.push([x - i, y]) position.push([x + i, y]) position.push([x, y - i]) # 障害物無視でない場合 else if position.include?([x, y + i - 1]) and !on_area?(x, y + i - 1, type) and (@battler.passable?(x, y + i - 1, 2) or on_area?(x, y + i, type)) position.push([x, y + i]) end if position.include?([x - i + 1, y]) and !on_area?(x - i + 1, y, type) and (@battler.passable?(x - i + 1, y, 4) or on_area?(x - i, y, type)) position.push([x - i, y]) end if position.include?([x + i - 1, y]) and !on_area?(x + i - 1, y, type) and (@battler.passable?(x + i - 1, y, 6) or on_area?(x + i, y, type)) position.push([x + i, y]) end if position.include?([x, y - i + 1]) and !on_area?(x, y - i + 1, type) and (@battler.passable?(x, y - i + 1, 8) or on_area?(x, y - i, type)) position.push([x, y - i]) end end end end # 自分を除くかどうか case battler.current_action.kind when 0 position.shift when 1 if [1, 2, 5, 6].include?(skill.scope) position.shift end when 2 if [1, 2, 5, 6].include?(item.scope) position.shift end end # 近接不可の場合 if cannot_near position.delete([@battler.x, @battler.y + 1]) position.delete([@battler.x - 1, @battler.y]) position.delete([@battler.x + 1, @battler.y]) position.delete([@battler.x, @battler.y - 1]) end return position end #-------------------------------------------------------------------------- # ● 対象エリア検索 #-------------------------------------------------------------------------- def search_target_area(sx = @battler.x, sy = @battler.y) position = [[sx, sy]] if $game_system.tactics_actors.keys.include?(@battler.id) battler = $game_system.tactics_actors[@battler.id] else battler = $game_system.tactics_enemies[@battler.id] end case battler.current_action.kind when 0 if (defined? ACTOR_RANGE and @attacker.is_a?(Game_Actor)) or (defined? ENEMY_RANGE and @attacker.is_a?(Game_Enemy)) form = battler.attack_range[1][0] max = battler.attack_range[1][1] else max = 0 end return position if max == 0 when 1 skill = $data_skills[battler.current_action.skill_id] form = skill.range[1][0] max = skill.range[1][1] return position if max == 0 when 2 item = $data_items[battler.current_action.item_id] form = item.range[1][0] max = item.range[1][1] return position if max == 0 end more_step = [0] route = [[]] case form # ひし形or四角形の場合 when 0, 2, 3 if form == 2 or form == 3 max *= 2 end for i in more_step x = position[i][0] y = position[i][1] # 下 if !position.include?([x, y + 1]) position.push([x, y + 1]) route.push(route[i] + [2]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [2])) end end # 左 if !position.include?([x - 1, y]) position.push([x - 1, y]) route.push(route[i] + [4]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [4])) end end # 右 if !position.include?([x + 1, y]) position.push([x + 1, y]) route.push(route[i] + [6]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [6])) end end # 上 if !position.include?([x, y - 1]) position.push([x, y - 1]) route.push(route[i] + [8]) if route[i].size + 1 < max more_step.push(route.index(route[i] + [8])) end end end # 四角形の場合 case form when 2 delete = [] for pos in position if (pos[0] - sx).abs > max/2 or (pos[1] - sy).abs > max/2 delete.push(pos) end end for i in delete position.delete(i) end when 3 delete = [] for pos in position if (pos[0] - sx).abs != max/2 and (pos[1] - sy).abs != max/2 delete.push(pos) end end for i in delete position.delete(i) end return position end when 1 for i in 1..max x = position[0][0] y = position[0][1] position.push([x, y + i]) position.push([x - i, y]) position.push([x + i, y]) position.push([x, y - i]) end end return position end #-------------------------------------------------------------------------- # ● 移動エリアセット #-------------------------------------------------------------------------- def set_movable_area(type) search_route for i in 0...@position.size x = @position[i][0] y = @position[i][1] sprite = Sprite_Area.new(@spriteset.viewport1, type, x, y) @spriteset.area_sprites.push(sprite) end end #-------------------------------------------------------------------------- # ● 攻撃エリアセット #-------------------------------------------------------------------------- def set_attack_area(type, invisible = false) position = search_attack_area for i in 0...position.size x = position[i][0] y = position[i][1] sprite = Sprite_Area.new(@spriteset.viewport1, type, x, y, invisible) @spriteset.area_sprites.push(sprite) end position = search_target_area for i in 0...position.size x = position[i][0] y = position[i][1] sprite = Sprite_Range.new(@spriteset.viewport1, type, x, y, invisible) @spriteset.range_sprites.push(sprite) end end #-------------------------------------------------------------------------- # ● エリア解放 #-------------------------------------------------------------------------- def dispose_area for sprite in @spriteset.area_sprites + @spriteset.range_sprites sprite.dispose sprite = nil end @spriteset.area_sprites.clear @spriteset.range_sprites.clear end #-------------------------------------------------------------------------- # ● エリア内判定 #-------------------------------------------------------------------------- def in_area?(x, y) for sprite in @spriteset.area_sprites if sprite.map_x == x and sprite.map_y == y return true end end return false end #-------------------------------------------------------------------------- # ● 攻撃エリア内ターゲット #-------------------------------------------------------------------------- def target_in_area(list) battlers = [] for i in list target = $game_map.events[i] for sprite in @spriteset.range_sprites if sprite.map_x == target.x and sprite.map_y == target.y battlers.push(i) end end end return battlers end #-------------------------------------------------------------------------- # ● バトラー存在判定 #-------------------------------------------------------------------------- def on_area?(x, y, type = 2) case type when 0 battler = $game_system.tactics_actors.keys when 1 battler = $game_system.tactics_enemies.keys when 2, 4 battler = $game_system.tactics_actors.keys + $game_system.tactics_enemies.keys when 3 return false end if @active_battler != nil battler -= [@active_battler.id] end for i in battler if $game_map.events[i].x == x and $game_map.events[i].y == y return true end end return false end end