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