module AdventureRL::Modifiers::Pusher

A Modifiers::Pusher is a Modifers::Solid Mask, which has the ability to __push other solid Masks__ (that are _not static_) out of the way when moving with move_by.

Public Instance Methods

move_by(*args) click to toggle source

Overwrite Modifiers::Solid#move_by to add the :pushed_by_pusher option. This skips pushing the Pusher that pushed this Pusher, to avoid an endless pushing of Pushers, where one Pusher pushes the other Pusher before that Pusher pushes the first Pusher, …

Calls superclass method
# File lib/AdventureRL/Modifiers/Pusher.rb, line 14
def move_by *args
  return  if (is_static?)

  if (args.last.is_a?(Hash))
    @pushed_by_pusher = [args.last[:pushed_by_pusher], self].flatten.reject { |x| !x }
  else
    @pushed_by_pusher = [self]
  end
  super
  @pushed_by_pusher = false
end

Private Instance Methods

get_position_difference_from(previous_position) click to toggle source
# File lib/AdventureRL/Modifiers/Pusher.rb, line 46
def get_position_difference_from previous_position
  return get_position.map do |axis, position|
    next [axis, (position - previous_position[axis])]
  end .to_h
end
move_by_handle_collision_with_previous_position(previous_position) click to toggle source
# File lib/AdventureRL/Modifiers/Pusher.rb, line 28
def move_by_handle_collision_with_previous_position previous_position
  colliding_objects = get_colliding_objects
  if (colliding_objects.any?)
    if (colliding_objects.any? &:is_static?)
      @position = previous_position
      return false
    end
    direction = get_position_difference_from previous_position
    if (push_objects(colliding_objects, direction))
      return true
    else
      @position = previous_position
      return false
    end
  end
  return true
end
push_objects(objects, direction) click to toggle source
# File lib/AdventureRL/Modifiers/Pusher.rb, line 52
def push_objects objects, direction
  direction[:precision_over_performance] = @precision_over_performance
  return objects.all? do |object|
    next true  if (@pushed_by_pusher && @pushed_by_pusher.include?(object))
    next object.move_by(direction.merge(pushed_by_pusher: @pushed_by_pusher))
  end
end