require 'java' java_import 'org.apollo.game.action.Action' java_import 'org.apollo.game.model.Animation' java_import 'org.apollo.game.model.Item' java_import 'org.apollo.game.model.inter.EnterAmountListener' java_import 'org.apollo.game.model.inter.dialogue.DialogueAdapter' GRINDING_ANIM = Animation.new(364) PESTLE_MORTAR = 233 # An ingredient which can be used for making (unfinished) potions. class Ingredient attr_reader :item_id, :item def initialize(item) @item_id = item @item = Item.new(item) # Share item instances. end # Checks if the specified player has the specified amount of this ingredient. Optionally, they # can immediately be removed if that amount was indeed found. def check_remove(player, amount, remove) inventory = player.inventory counter = 0 inventory.items.each do |inv_item| break unless counter < amount next if inv_item.nil? id = inv_item.id inventory_amount = inv_item.amount if id == @item_id if inventory_amount >= amount inventory.remove(@item_id, amount) if remove return true else counter += inventory_amount end end end if counter >= amount inventory.remove(@item_id, amount) if remove return true end false end end # An ingredient which needs to be grinded before being usable for Herblore. class GroundIngredient < Ingredient include HerbloreMethod attr_reader :raw def initialize(item_id, raw) super(item_id) @raw = raw end def invoke(player, _pestle_mortar, _ingredient) action = GrindingAction.new(player, self) listener = GrindingDialogueListener.new(player, action) open_dialogue(player, @item_id, listener) end end # A DialogueAdapter used for grinding ingredients. It is also used as an EnterAmountListener for # the amount of grinding actions. class GrindingDialogueListener < DialogueAdapter include EnterAmountListener attr_reader :player, :action def initialize(player, action) super() @player = player @action = action end # Called when a button has been clicked whilst the dialogue was opened. def buttonClicked(button) amount = get_amount(button) return false if amount == 0 interfaces = @player.interface_set interfaces.close if amount == -1 interfaces.open_enter_amount_dialogue(self) return true end amount = player.inventory.get_amount(@action.ingredient.raw) if amount == -2 execute(amount) end # Called when an amount of grinding actions has been entered. def amountEntered(amount) execute(amount) if amount > 0 end # Called to set the action(s) in motion. def execute(amount) @action.set_amount(amount) @player.start_action(@action) end # Gets the amount of actions based on the specified button id. def get_amount(button) case button when 2799 then return 1 when 2798 then return 5 when 1748 then return -1 when 1747 then return -2 else return 0 end end end # An action which makes the player grind one or more GrindedIngredients from their 'raw' form. class GrindingAction < Action attr_reader :ingredient, :amount, :pulses, :slot, :listener def initialize(player, ingredient) super(0, true, player) @ingredient = ingredient @pulses = 0 end def execute grind @pulses += 1 end # Performs the grinding action once the materials have been checked. def grind if @pulses == 0 mob.play_animation GRINDING_ANIM elsif @pulses == 1 unless gather_materials stop return end player = mob inventory = player.inventory item = inventory.get(@slot) name = item.definition.name.downcase player.send_message("You grind the #{name} to dust.") inventory.reset(@slot) inventory.add(@ingredient.item) set_delay(1) elsif @pulses == 2 mob.stop_animation continue end end # Checks if the player has the required materials to perform the (next) action. def gather_materials items = mob.inventory.items pst_mrt = false ingr = false raw = @ingredient.raw (0...items.length).each do |slot| item = items[slot] next if item.nil? id = item.id if id == PESTLE_MORTAR && !pst_mrt pst_mrt = true elsif id == raw && !ingr ingr = true @slot = slot end return true if pst_mrt && ingr end mob.send_message("You do not have any more #{name_of(raw).downcase}s.") false end # Either invokes the stop() method in Action to shut it down # or continues to the next ingredient. def continue @amount -= 1 if @amount > 0 set_delay(0) @pulses = -1 else stop end end # Sets the amount of actions. def set_amount(amount) @amount = amount end def stop super mob.inventory.remove_listener(@listener) unless listener.nil? end def equals(other) get_class == other.get_class && @ingredient == other.ingredient end end # Appends a ground ingredient to the ItemOnItemMessage listener interception. def append_ground(id, raw) ground = GroundIngredient.new(id, raw) append_herblore_item(ground, PESTLE_MORTAR, raw) ground end # Normal ingredients EYE_NEWT = Ingredient.new(221) RED_SPIDERS_EGGS = Ingredient.new(223) LIMPWURT_ROOT = Ingredient.new(225) SNAPE_GRASS = Ingredient.new(231) WHITE_BERRIES = Ingredient.new(239) WINE_ZAMORAK = Ingredient.new(245) JANGERBERRIES = Ingredient.new(247) TOADS_LEGS = Ingredient.new(2152) MORT_MYRE_FUNGI = Ingredient.new(2970) POTATO_CACTUS = Ingredient.new(3138) PHOENIX_FEATHER = Ingredient.new(4621) FROG_SPAWN = Ingredient.new(5004) PAPAYA_FRUIT = Ingredient.new(5972) POISON_IVY_BERRIES = Ingredient.new(6018) YEW_ROOTS = Ingredient.new(6049) MAGIC_ROOTS = Ingredient.new(6051) # Ground ingredients UNICORN_HORN_DUST = append_ground(235, 237) DRAGON_SCALE_DUST = append_ground(241, 243) CHOCOLATE_DUST = append_ground(1975, 1973) CRUSHED_NEST = append_ground(6693, 5075)