Files
apollo/data/plugins/entity-spawning/npc-spawn.rb
T

85 lines
2.7 KiB
Ruby

require 'java'
java_import 'org.apollo.game.model.Animation'
java_import 'org.apollo.game.model.Graphic'
java_import 'org.apollo.game.model.Npc'
java_import 'org.apollo.game.model.Position'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.def.NpcDefinition'
# Spawns an npc with the properties specified in the hash.
def spawn_npc(hash)
raise 'A name or id must be specified to spawn an npc.' if !(hash.has_key?(:name) || hash.has_key?(:id))
id = hash.delete(:id)
if id == nil
name = hash.delete(:name).to_s.gsub('_', ' ')
if name.include?(' ')
id = name[name.rindex(' ') + 1, name.length - 1].to_i
end
id = locate_entity('npc', name, 1).first if id == nil || id == 0
end
raise "The npc called #{name} could not be identified." if id == nil
z = hash.delete(:z)
position = Position.new(hash.delete(:x), hash.delete(:y), z == nil ? 0 : z)
npc = Npc.new(id, position)
World.world.register(npc)
parse_hash(npc, hash) unless hash.empty?
end
# Parses the remaining key-value pairs in the hash.
def parse_hash(npc, hash)
hash.each do |key, value|
if key == :face
facing_position = direction_to_position(value, npc.position)
npc.turn_to(facing_position)
elsif key == :bounds
# TODO
elsif key == :delta_bounds
# TODO
elsif key == :circular_bounds
radius = value
# TODO
elsif key == :spawn_animation
npc.play_animation(Animation.new(value))
elsif key == :spawn_graphic
npc.play_graphic(Graphic.new(value))
else
raise "Unrecognised key #{key} - value #{value}."
end
end
end
# Returns a position that an entity at the specified position should be facing towards if they are looking in the specified direction.
def direction_to_position(direction, position)
x = position.x
y = position.y
z = position.height
case direction
when :north then return Position.new(x, y + 1, z)
when :north_east then return Position.new(x + 1, y + 1, z)
when :east then return Position.new(x + 1, y, z)
when :south_east then return Position.new(x + 1, y - 1, z)
when :south then return Position.new(x, y - 1, z)
when :south_west then return Position.new(x - 1, y - 1, z)
when :west then return Position.new(x - 1, y, z)
when :north_west then return Position.new(x - 1, y + 1, z)
else return position
end
end
# Locates an entity with the specified type (e.g. npc) and name, returning possible ids as an array.
def locate_entity(type, name, limit=5)
ids = []
name.downcase!
Kernel.const_get("#{type.capitalize}Definition").definitions.each do |definition|
break if ids.length == limit
ids << definition.id.to_i if definition.name.to_s.downcase == name
end
return ids
end