diff --git a/data/plugins/cmd/lookup/lookup.rb b/data/plugins/cmd/lookup/lookup.rb index 85b0370b..fa9d863f 100644 --- a/data/plugins/cmd/lookup/lookup.rb +++ b/data/plugins/cmd/lookup/lookup.rb @@ -23,7 +23,7 @@ on :command, :lookup, RIGHTS_ADMIN do |player, command| next end - ids = locate_entity(type, name, limit).join(', ') + ids = find_entities(type, name, limit).join(', ') message = ids.empty? ? "Could not find an #{type} called #{name}." : "Possible ids are: #{ids}." player.send_message(message) diff --git a/data/plugins/entity/spawning/npc-spawn.rb b/data/plugins/entity/spawning/npc-spawn.rb index b7a43023..c4bbd788 100644 --- a/data/plugins/entity/spawning/npc-spawn.rb +++ b/data/plugins/entity/spawning/npc-spawn.rb @@ -41,17 +41,7 @@ end # Returns an npc with the id and position specified by the hash. def get_npc(hash) - 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 + id = hash.delete(:id) || lookup_npc(hash.delete(:name)) z = hash.delete(:z) position = Position.new(hash.delete(:x), hash.delete(:y), z == nil ? 0 : z) @@ -111,21 +101,6 @@ def direction_to_position(direction, 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 - - # An action that spawns an npc temporarily, before executing an action. class TemporaryNpcAction < Action attr_reader :executions, :combative diff --git a/data/plugins/entity/spawning/plugin.xml b/data/plugins/entity/spawning/plugin.xml index ffd4ec9f..ac3b0b79 100644 --- a/data/plugins/entity/spawning/plugin.xml +++ b/data/plugins/entity/spawning/plugin.xml @@ -10,5 +10,7 @@ - + + util + \ No newline at end of file diff --git a/data/plugins/util/command.rb b/data/plugins/util/command.rb new file mode 100644 index 00000000..0676a372 --- /dev/null +++ b/data/plugins/util/command.rb @@ -0,0 +1,11 @@ + +# Checks whether the amount of arguments provided is correct, sending the player the specified message if not. +def valid_arg_length(args, length, player, message) + valid = length.kind_of?(Range) ? length.include?(args.length) : length == args.length + + if (!valid) + player.send_message(message) + return false + end + return true +end \ No newline at end of file diff --git a/data/plugins/util/intercept.rb b/data/plugins/util/intercept.rb new file mode 100644 index 00000000..b2c570de --- /dev/null +++ b/data/plugins/util/intercept.rb @@ -0,0 +1,27 @@ +# Essentially a wrapper for specific message types to make them easier to use. Only supports the interception of a message type once (for good reason - this is supposed to +# be a utility, not a chain of interceptors inside the existing chain). +# +# Plugins that wish to expand the list of available message types (you probably don't) should use the add_interception method - see the item-on-item script for example usage. +# +# If you only wish to intercept a message, use the intercept method, e.g. +# +# intercept :item_on_item, used_id, target_id, :irreversible do |ctx, player, message| +# # code here +# end + + +# Calls the registered interception(s), if applicable. +def intercept(message, *args, &block) + raise 'Error - interceptions must provide a block.' unless block_given? + interception = INTERCEPTIONS[message] + + if interception == nil then raise "No interception for message #{message}" else interception.call(*args, block) end +end + +# Adds an interception. +def add_interception(message, &block) + INTERCEPTIONS[message] = block +end + +private +INTERCEPTIONS = {} \ No newline at end of file diff --git a/data/plugins/util/item-on-item-intercept.rb b/data/plugins/util/item-on-item-intercept.rb new file mode 100644 index 00000000..ac46bed3 --- /dev/null +++ b/data/plugins/util/item-on-item-intercept.rb @@ -0,0 +1,46 @@ + +# Adds an interception for the ItemOnItem message +add_interception :item_on_item do |used, target, reversible, block| + interception = ItemOnItemPair.new(used, target) + + ITEM_PAIRS[interception] = block + ITEM_PAIRS[interception.reverse] = block if reversible == :reversible +end + +private + +# A hash of ItemOnItemPairs to blocks. +ITEM_PAIRS = {} + +# A pair of items that will cause a block to be executed if one (the 'used' item) is used on the other (the 'target' item). +class ItemOnItemPair + attr_reader :used, :target + + def initialize(used, target) + @used = used + @target = target + end + + # Returns a new ItemOnItemPair that is the reverse of this. + def reverse + return ItemOnItemPair.new(@target, @used) + end + + def eql?(other) + return (other.kind_of?(ItemOnItemPair) && @used == other.used && @target == other.target) + end + + def hash + return @used << 16 | @target + end + +end + +# Adds a message handler to the item on item message. +on :message, :item_on_item do |ctx, player, message| + used, target = message.id, message.target_id + pair = ItemOnItemPair.new(used, target) + block = ITEM_PAIRS[pair] + + block.call(ctx, player, message) unless block == nil +end \ No newline at end of file diff --git a/data/plugins/util/name-lookup.rb b/data/plugins/util/name-lookup.rb new file mode 100644 index 00000000..c3e570d3 --- /dev/null +++ b/data/plugins/util/name-lookup.rb @@ -0,0 +1,51 @@ +require 'java' + +# Looks up the id of the npc with the specified name. +def lookup_npc(name) + return lookup_entity('npc', name) +end + +# Looks up the id of the item with the specified name. +def lookup_item(name) + return lookup_entity('item', name) +end + +# Looks up the id of the object with the specified name. +def lookup_object(name) + return lookup_entity('object', name) +end + +# Looks up the id of an entity of the specified type (either 'npc', 'item', or 'object') +def lookup_entity(type, symbol) + symbol = symbol.to_s + cached = NAME_CACHE[type + symbol] + return cached unless cached == nil + + name = symbol.to_s.gsub('_', ' ') + if name.include?(' ') + id = name[name.rindex(' ') + 1, name.length - 1].to_i + end + id = find_entities(type, name, 1).first if id == nil || id == 0 + + if id == nil + raise "The #{type} called #{name} could not be identified." + end + + NAME_CACHE[type + symbol] = id + return id +end + +# Finds entities with the specified type (e.g. npc) and name, returning possible ids as an array. +def find_entities(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 + +private +NAME_CACHE = {} \ No newline at end of file diff --git a/data/plugins/util/plugin.xml b/data/plugins/util/plugin.xml new file mode 100644 index 00000000..b3e1d491 --- /dev/null +++ b/data/plugins/util/plugin.xml @@ -0,0 +1,17 @@ + + + util + 1 + Util + Adds utility methods for plugins. + + Major + + + + + + + + + \ No newline at end of file