mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 16:49:11 +00:00
baa12ca446
Adds a new mob extension plugin which creates a walk_to() method on Mobs to allow walking to another entity (accounting for the size of the entity) with an optional facing position.
83 lines
2.9 KiB
Ruby
83 lines
2.9 KiB
Ruby
java_import 'org.apollo.game.model.entity.path.AStarPathfindingAlgorithm'
|
|
java_import 'org.apollo.game.model.entity.path.EuclideanHeuristic'
|
|
java_import 'org.apollo.game.model.entity.path.SimplePathfindingAlgorithm'
|
|
java_import 'org.apollo.game.model.entity.obj.GameObject'
|
|
java_import 'org.apollo.game.model.entity.Mob'
|
|
java_import 'org.apollo.game.model.entity.Player'
|
|
java_import 'org.apollo.game.model.entity.EntityType'
|
|
java_import 'org.apollo.game.model.Direction'
|
|
|
|
##
|
|
# A pathfinder used for simple following (i.e.: An NPC attacking a player).
|
|
SIMPLE_PATH_FINDER = SimplePathfindingAlgorithm.new($world.collision_manager)
|
|
|
|
##
|
|
# A pathfinder used for precise following (i.e.: A player attacking another player).
|
|
FOLLOW_PATH_FINDER = AStarPathfindingAlgorithm.new($world.collision_manager, EuclideanHeuristic.new)
|
|
|
|
##
|
|
# The directions that we use as a random offset when not walking to the facing direction.
|
|
OFFSET_DIRECTIONS = Direction::NESW.to_a
|
|
|
|
module WalkToMobExtension
|
|
def walk_to(entity, front: false, behind: false)
|
|
if [front, behind].count { |option| option == true } > 1
|
|
fail 'Can only specify one of "front" or "behind"'
|
|
end
|
|
|
|
position = self.position
|
|
target_position = entity.position
|
|
target_distance = position.get_distance(target_position)
|
|
target_offset = walk_to_offset(entity)
|
|
target_offset_direction = OFFSET_DIRECTIONS.sample
|
|
target_facing_direction = walk_to_facing_direction(entity)
|
|
|
|
unless target_facing_direction.nil?
|
|
if front
|
|
target_offset_direction = target_facing_direction
|
|
elsif behind
|
|
target_offset_direction = target_facing_direction.opposite
|
|
end
|
|
end
|
|
|
|
target_offset_position = target_position.step(target_offset, target_offset_direction)
|
|
return if target_offset_position.eql?(position)
|
|
|
|
pathfinder = FOLLOW_PATH_FINDER
|
|
path = pathfinder.find(position, target_offset_position)
|
|
path.each { |tile| self.walking_queue.add_step(tile) }
|
|
end
|
|
end
|
|
|
|
MobExtension::register(WalkToMobExtension)
|
|
|
|
private
|
|
|
|
##
|
|
# Gets the number of tiles away from an entity's actual origin that we can
|
|
# walk to.
|
|
def walk_to_offset(entity)
|
|
case entity.entity_type
|
|
when EntityType::DYNAMIC_OBJECT, EntityType::STATIC_OBJECT
|
|
return max(entity.definition.width, entity.definition.length) + 1
|
|
when EntityType::NPC
|
|
return entity.definition.size + 1
|
|
when EntityType::PLAYER
|
|
return 1
|
|
else
|
|
fail "walk_to_offset called with invalid entity type: #{type.to_s}"
|
|
end
|
|
end
|
|
|
|
##
|
|
# Gets the direction that an entity is facing, so a mob can walk up infront of them.
|
|
def walk_to_facing_direction(entity)
|
|
case entity.entity_type
|
|
when EntityType::DYNAMIC_OBJECT, EntityType::STATIC_OBJECT
|
|
return Direction::WNES[entity.orientation]
|
|
when EntityType::NPC, EntityType::PLAYER
|
|
return entity.last_direction
|
|
else
|
|
fail "walk_to_offset called with invalid entity type: #{type.to_s}"
|
|
end
|
|
end |