class Gingham::PathFinder
Public Class Methods
find_adjacent_cells(space, cell, jump_power = 999)
click to toggle source
# File lib/gingham/path_finder.rb, line 141 def self.find_adjacent_cells(space, cell, jump_power = 999) raise unless space && space.is_a?(Gingham::Space) raise unless cell && cell.is_a?(Gingham::Cell) adjacent_list = [] w, d, h = space.width, space.depth, space.height x, y, z = cell.x, cell.y, cell.z if x + 1 < w target_cell = space.ground_at(x + 1, y) if target_cell if !target_cell.occupied? || (z - target_cell.z).abs <= jump_power adjacent_list << target_cell end end end if x - 1 >= 0 target_cell = space.ground_at(x - 1, y) if target_cell if !target_cell.occupied? || (z - target_cell.z).abs <= jump_power adjacent_list << target_cell end end end if y + 1 < d target_cell = space.ground_at(x, y + 1) if target_cell if !target_cell.occupied? || (z - target_cell.z).abs <= jump_power adjacent_list << target_cell end end end if y - 1 >= 0 target_cell = space.ground_at(x, y - 1) if target_cell if !target_cell.occupied? || (z - target_cell.z).abs <= jump_power adjacent_list << target_cell end end end adjacent_list end
find_adjacent_waypoints(space, wp, jump_power = 999)
click to toggle source
# File lib/gingham/path_finder.rb, line 122 def self.find_adjacent_waypoints(space, wp, jump_power = 999) raise unless space && space.is_a?(Gingham::Space) raise unless wp && wp.is_a?(Gingham::Waypoint) adjacent_list = [] adjacent_cells = Gingham::PathFinder.find_adjacent_cells(space, wp.cell, jump_power) adjacent_cells.each do |cell| move_direction = Gingham::Waypoint.detect_direction(wp, cell) parent = wp if move_direction != wp.direction turn_wp = Gingham::Waypoint.new(wp.cell, move_direction, wp) parent = turn_wp end move_to = Gingham::Waypoint.new(cell, move_direction, parent) adjacent_list << move_to end adjacent_list end
find_move_path(space, from, to, move_power = 999, jump_power = 999)
click to toggle source
# File lib/gingham/path_finder.rb, line 4 def find_move_path(space, from, to, move_power = 999, jump_power = 999) raise ArgumentError unless space && space.is_a?(Gingham::Space) raise ArgumentError unless from && from.is_a?(Gingham::Waypoint) && to && to.is_a?(Gingham::Waypoint) open_list = [from] return open_list if from.cell == to.cell close_list = [] loop_limit = 0 while open_list.size > 0 && loop_limit < 1000 do current_wp = open_list.first close_list << current_wp open_list = open_list.drop 1 adjacent_waypoints = Gingham::PathFinder.find_adjacent_waypoints(space, current_wp, jump_power) adjacent_waypoints.each do |wp| if wp.sum_cost < move_power open_list << wp unless close_list.include? wp end end loop_limit += 1 end shortest_chains = [from] end_points = close_list.select { |closed| closed.cell == to.cell } unless end_points.size.zero? shortest_cost = 999 end_points.each do |end_wp| if end_wp.sum_cost < shortest_cost shortest_cost = end_wp.sum_cost shortest_chains = end_wp.chains end end end shortest_chains end
find_skill_path(space, from, to, max_height = 999)
click to toggle source
# File lib/gingham/path_finder.rb, line 42 def find_skill_path(space, from, to, max_height = 999) path = [from] should_move_y = from.direction == Gingham::Direction::D8 || from.direction == Gingham::Direction::D2 loop_limit = 0 while path.last.cell.x != to.cell.x || path.last.cell.y != to.cell.y loop_limit += 1 break if loop_limit > 30 if should_move_y && path.last.cell.y != to.cell.y if path.last.cell.y < to.cell.y if path.last.cell.y + 1 != space.depth height = space.height_at(path.last.cell.x, path.last.cell.y + 1) cell = space.cells[path.last.cell.x][path.last.cell.y + 1][height] break unless cell.passable? if path.last.direction != 8 path << Gingham::Waypoint.new(path.last.cell, 8, path.last) end break if cell.z > max_height path << Gingham::Waypoint.new(cell, 8, path.last) end elsif path.last.cell.y > to.cell.y if path.last.cell.y - 1 >= 0 height = space.height_at(path.last.cell.x, path.last.cell.y - 1) cell = space.cells[path.last.cell.x][path.last.cell.y - 1][height] break unless cell.passable? if path.last.direction != 2 path << Gingham::Waypoint.new(path.last.cell, 2, path.last) end break if cell.z > max_height path << Gingham::Waypoint.new(cell, 2, path.last) end end should_move_y = false next else should_move_y = false end if !should_move_y && path.last.cell.x != to.cell.x if path.last.cell.x < to.cell.x if path.last.cell.x + 1 != space.width height = space.height_at(path.last.cell.x + 1, path.last.cell.y) cell = space.cells[path.last.cell.x + 1][path.last.cell.y][height] break unless cell.passable? if path.last.direction != 6 path << Gingham::Waypoint.new(path.last.cell, 6, path.last) end break if cell.z > max_height path << Gingham::Waypoint.new(cell, 6, path.last) end elsif path.last.cell.x > to.cell.x if path.last.cell.x - 1 >= 0 height = space.height_at(path.last.cell.x - 1, path.last.cell.y) cell = space.cells[path.last.cell.x - 1][path.last.cell.y][height] break unless cell.passable? if path.last.direction != 4 path << Gingham::Waypoint.new(path.last.cell, 4, path.last) end break if cell.z > max_height path << Gingham::Waypoint.new(cell, 4, path.last) end end end should_move_y = true end path.compact end