class Demiurge::TiledLocation

A TiledLocation is a location that uses x,y format for positions for a 2D grid in the location. Something like a TMX file defines a TiledLocation, but so does an infinitely generated tiled space.

@since 0.3.0

Public Class Methods

position_to_coords(pos) click to toggle source

Parse a tiled position string and return the X and Y tile coordinates

@param pos [String] The position string to parse @return [Array<Integer,Integer>] The x, y coordinates @since 0.2.0

# File lib/demiurge/location.rb, line 107
def self.position_to_coords(pos)
  loc, x, y = position_to_loc_coords(pos)
  return x, y
end
position_to_loc_coords(pos) click to toggle source

Parse a tiled position string and return the location name and the X and Y tile coordinates

@param pos [String] The position string to parse @return [Array<String,Integer,Integer>] The location name and x, y coordinates @since 0.2.0

# File lib/demiurge/location.rb, line 117
def self.position_to_loc_coords(pos)
  loc, coords = pos.split("#",2)
  if coords
    x, y = coords.split(",")
    return loc, x.to_i, y.to_i
  else
    return loc, nil, nil
  end
end

Public Instance Methods

adjacent_positions(pos, options = {}) click to toggle source

Return the list of valid adjacent positions from this one

# File lib/demiurge/location.rb, line 232
def adjacent_positions(pos, options = {})
  location, pos_spec = pos.split("#", 2)
  loc = @engine.item_by_name(location)
  x, y = pos_spec.split(",").map(&:to_i)

  shape = options[:shape] || "humanoid"
  [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1]].select { |xp, yp| loc.can_accomodate_shape?(xp, yp, shape) }
end
can_accomodate_agent?(agent, position) click to toggle source

Determine whether this position can accomodate the given agent's shape and size.

@param agent [Demiurge::Agent] The agent being checked @param position [String] The position being checked @return [Boolean] Whether the position can accomodate the agent @since 0.2.0

# File lib/demiurge/location.rb, line 172
def can_accomodate_agent?(agent, position)
  loc, x, y = TiledLocation.position_to_loc_coords(position)
  raise "Location #{@name.inspect} asked about different location #{loc.inspect} in can_accomodate_agent!" if loc != @name
  shape = agent.state["shape"] || "humanoid"
  can_accomodate_shape?(x, y, shape)
end
can_accomodate_dimensions?(left_x, upper_y, width, height) click to toggle source

Whether the location can accomodate an object of this size.

@param left_x [Integer] The lower (leftmost) X coordinate @param upper_y [Integer] The higher (upper) Y coordinate @param width [Integer] How wide the checked object is @param height [Integer] How high the checked object is @return [Boolean] Whether the object can be accomodated @since 0.3.0

# File lib/demiurge/location.rb, line 197
def can_accomodate_dimensions?(left_x, upper_y, width, height)
  true
end
can_accomodate_shape?(left_x, upper_y, shape) click to toggle source

Determine whether this coordinate location can accomodate an item of the given shape.

For now, don't distinguish between walkable/swimmable or whatever, just say a collision value of 0 means valid, everything else is invalid.

@param left_x [Integer] The lower (leftmost) X coordinate @param upper_y [Integer] The higher (upper) Y coordinate @return [Boolean] Whether the object can be accomodated @since 0.3.0

# File lib/demiurge/location.rb, line 212
def can_accomodate_shape?(left_x, upper_y, shape)
  case shape
  when "humanoid"
    return can_accomodate_dimensions?(left_x, upper_y, 2, 1)
  when "tiny"
    return can_accomodate_dimensions?(left_x, upper_y, 1, 1)
  else
    raise "Unknown shape #{shape.inspect} passed to can_accomodate_shape!"
  end
end
item_change_position(item, old_pos, new_pos) click to toggle source

When an item changes position in a TiledLocation, check if the new position leads out an exit. If so, send them where the exit leads instead.

@param item [String] The item changing position @param old_pos [String] The position string the item is moving from @param new_pos [String] The position string the item is moving to @return [void] @since 0.2.0

# File lib/demiurge/location.rb, line 136
def item_change_position(item, old_pos, new_pos)
  exit = @state["exits"].detect { |e| e["from"] == new_pos }
  return super unless exit  # No exit? Do what you were going to.

  # Going to hit an exit? Cancel this motion and enqueue an
  # intention to do so? Or just send them through? If the former,
  # it's very hard to unblockably pass through an exit, even if
  # that's what's wanted. If the latter, it's very hard to make
  # going through an exit blockable.

  # Eh, just send them through for now. We'll figure out how to
  # make detecting and blocking exit intentions easy later.

  item_change_location(item, old_pos, exit["to"])
end
valid_coordinate?(x,y) click to toggle source

Whether the coordinate is valid

@param x [Integer] The X coordinate @param y [Integer] The Y coordinate @return [Boolean] Whether the coordinate is valid @since 0.3.0

# File lib/demiurge/location.rb, line 185
def valid_coordinate?(x,y)
  true
end
valid_position?(pos) click to toggle source

This just determines if the position is valid at all. It does not check walkable/swimmable or even if it's big enough for a humanoid to stand in.

@param pos [String] The position being checked @return [Boolean] Whether the position is valid @since 0.2.0

# File lib/demiurge/location.rb, line 159
def valid_position?(pos)
  return false unless pos[0...@name.size] == @name
  return false unless pos[@name.size] == "#"
  x, y = pos[(@name.size + 1)..-1].split(",", 2).map(&:to_i)
  valid_coordinate?(x, y)
end