Housekeeping

This commit is contained in:
KeepBotting
2019-03-26 14:05:40 -04:00
parent a0c78ced90
commit 739c331860
135 changed files with 4 additions and 4 deletions
+95
View File
@@ -0,0 +1,95 @@
require 'java'
java_import 'org.apollo.game.action.Action'
java_import 'org.apollo.util.LanguageUtil'
# A herb is an ingredient that requires identification before being used.
class Herb < Ingredient
include HerbloreMethod
attr_reader :unidentified, :level, :experience
def initialize(item_id, unidentified, level, experience)
super item_id
@unidentified = unidentified
@level = level
@experience = experience
end
def invoke(player, _id, slot)
item = player.inventory.get(slot)
player.start_action(HerbIdentificationAction.new(player, self, slot, item))
end
end
# An action that makes a player identify a herb.
class HerbIdentificationAction < Action
attr_reader :herb, :slot, :item, :pulses
def initialize(player, herb, slot, item)
super(0, true, player)
@herb = herb
@slot = slot
@item = item
@pulses = 0
end
def execute
if @pulses == 0
unless check_skill(mob, @herb.level, 'identify this herb')
stop
return
end
end
execute_action
@pulses += 1
end
def execute_action
player = mob
inventory = player.inventory
if inventory.remove_slot(@slot, 1) == 1
identified = @herb.item
inventory.add(identified)
article = LanguageUtil.getIndefiniteArticle(identified.definition.name)
player.skill_set.add_experience(Skill::HERBLORE, @herb.experience)
player.send_message("This herb is #{article} #{identified.definition.name}.")
end
stop
end
def equals(other)
get_class == other.get_class && slot == other.slot && herb == other.herb
end
end
# Appends a herb to the InventoryItemMessage interception.
def append_herb(item_id, unidentified, level, experience)
herb = Herb.new(item_id, unidentified, level, experience)
append_herblore_item(herb, unidentified)
herb
end
# Herbs
GUAM_LEAF = append_herb(249, 199, 1, 2.5)
MARRENTILL = append_herb(251, 201, 5, 3.8)
TARROMIN = append_herb(253, 203, 11, 5)
HARRALANDER = append_herb(255, 205, 20, 6.3)
RANARR = append_herb(257, 207, 25, 7.5)
TOADFLAX = append_herb(2998, 3049, 30, 8)
IRIT_LEAF = append_herb(259, 209, 40, 8.8)
AVANTOE = append_herb(261, 211, 48, 10)
KWUARM = append_herb(263, 213, 54, 11.3)
SNAPDRAGON = append_herb(3000, 3051, 59, 11.8)
CADANTINE = append_herb(265, 215, 65, 12.5)
LANTADYME = append_herb(2481, 2485, 67, 13.1)
DWARF_WEED = append_herb(267, 217, 70, 13.8)
TORSTOL = append_herb(269, 219, 75, 15)
@@ -0,0 +1,102 @@
# Thanks to Sillhouette <http://www.rune-server.org/members/silhouette> for posting
# a large amount of Herblore skill data which has been thankfully used in this plugin.
require 'java'
java_import 'org.apollo.game.message.impl.SetWidgetItemModelMessage'
java_import 'org.apollo.game.model.entity.Skill'
HERBLORE_DIALOGUE = 4429
HERBLORE_ITEM = {}
HERBLORE_ITEM_ON_ITEM = {}
DRINK_ITEM = {}
# A module which describes an invocable method of the Herblore skill.
module HerbloreMethod
def self.new
fail 'You cannot instantiate this module!'
end
def invoke(_player, _primary, _secondary)
fail 'You must implement the invocation of HerbloreMethod!'
end
end
# The ItemOnItemMessage listener for all Herblore-related functions.
on :message, :item_on_item do |player, message|
primary = message.id
secondary = message.target_id
hash = HERBLORE_ITEM_ON_ITEM[primary]
if hash.nil?
secondary = message.id
primary = message.target_id
hash = HERBLORE_ITEM_ON_ITEM[primary]
end
unless hash.nil?
method = hash[secondary]
unless method.nil?
method.invoke(player, primary, secondary)
message.terminate
end
end
end
# The ItemOptionMessage listener for all Herblore-related functions.
on :message, :first_item_option do |player, message|
id = message.id
method = HERBLORE_ITEM[id]
unless method.nil?
method.invoke(player, id, message.slot)
message.terminate
end
method = DRINK_ITEM[id]
unless method.nil?
method.invoke(player, id, message.slot)
message.terminate
end
end
# Utility for adding the various Herblore methods to the handled constant arrays.
def append_herblore_item(method, key, secondary = -1)
if secondary == -1
HERBLORE_ITEM[key] = method
else
hash = HERBLORE_ITEM_ON_ITEM[key]
hash = {} if hash.nil?
hash[secondary] = method
HERBLORE_ITEM_ON_ITEM[key] = hash
end
end
# Utility method for checking if a player's inventory has a of the specified id, with optionally
# the specified amount (1 by default), at the specified slot.
def check_slot(player, slot, id, amount = 1)
item = player.inventory.get(slot)
!item.nil? && item.id == id && item.amount >= amount
end
# Utility method for checking if a player's Herblore (maximum) level is at the required level. Also
# informs the player if this is not the case with use of the action variable, like so:
# "You need a Herblore level of at least #{required.to_s} to #{action}."
def check_skill(player, required, action)
if required > player.skill_set.get_skill(Skill::HERBLORE).current_level
player.send_message("You need a Herblore level of at least #{required} to #{action}.")
return false
end
true
end
# Opens a 'make' dialogue for the specified player, displaying the specified item. Optionally, a
# listener can be used for the dialogue.
def open_dialogue(player, item, listener = nil)
player.send(SetWidgetItemModelMessage.new(1746, item, 170))
player.interface_set.open_dialogue(listener, HERBLORE_DIALOGUE)
end
@@ -0,0 +1,251 @@
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)
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<plugin>
<id>skill-herblore</id>
<version>0.9</version>
<name>Herblore</name>
<description>Adds the Herblore skill.</description>
<authors>
<author>Chris Fletcher</author>
<author>Major</author>
</authors>
<scripts>
<script>herblore.rb</script>
<script>ingredient.rb</script>
<script>herb.rb</script>
<script>potion.rb</script>
</scripts>
<dependencies />
</plugin>
+372
View File
@@ -0,0 +1,372 @@
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.entity.Skill'
java_import 'org.apollo.game.model.inter.EnterAmountListener'
java_import 'org.apollo.game.model.inter.dialogue.DialogueAdapter'
private
WATER_VIAL_ID = 227
EMPTY_VIAL_ID = 229
MIXING_ANIM = Animation.new(363)
# Represents an unfinished potion which can be invoked as a HerbloreMethod and used as an
# ingredient.
class UnfinishedPotion < Ingredient
include HerbloreMethod
attr_reader :herb, :level
def initialize(item_id, herb, level)
super(item_id)
@herb = herb
@level = level
end
def invoke(player, _primary, _secondary)
action = UnfinishedMixingAction.new(player, self)
listener = UnfinishedMixingDialogueListener.new(player, action)
open_dialogue(player, @item_id, listener)
end
end
# Represents a finished potion which can be invoked as a HerbloreMethod.
class FinishedPotion
include HerbloreMethod
attr_reader :item, :ingredients, :level, :experience
def initialize(item, ingredients, level, experience)
@item = Item.new(item)
@ingredients = ingredients
@level = level
@experience = experience
end
def invoke(player, primary, secondary)
action = FinishedMixingAction.new(player, primary, secondary, self)
listener = FinishedMixingDialogueListener.new(player, action)
open_dialogue(player, @item.id, listener)
end
end
# A DialogueAdapter used for mixing potions. It is also used as an EnterAmountListener for the
# amount of mixing actions.
class MixingDialogueListener < 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 = calculate_maximum if amount == -2
execute(amount)
true
end
# Called when an amount of mixing 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
def calculate_maximum(_code)
# Override for potion-specific amount calculation.
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
# A MixingDialogueListener used for mixing unfinished potions.
class UnfinishedMixingDialogueListener < MixingDialogueListener
def calculate_maximum
inventory = @player.inventory
amount = inventory.get_amount(WATER_VIAL_ID)
return 0 if amount <= 0
herbs = inventory.get_amount(@action.potion.herb.item.id)
[herbs, amount].min
end
end
# A MixingDialogueListener used for mixing finished potions.
class FinishedMixingDialogueListener < MixingDialogueListener
def calculate_maximum
inventory = @player.inventory
amount = inventory.capacity
@action.potion.ingredients.each do |ingredient|
item_amount = inventory.get_amount(ingredient.item.id)
amount = item_amount if amount > item_amount
end
amount
end
end
# An Action which handles the none-finished-dependent mixing.
class MixingAction < Action
attr_reader :potion, :amount, :started, :pulses, :action, :listener
def initialize(player, potion, action)
super(1, true, player)
@potion = potion
@started = false
@pulses = 0
@action = action
@action.freeze
end
def execute
if @pulses == 0
unless @started
unless check_skill(mob, @potion.level, @action)
stop
return
end
@started = true
end
unless gather_materials
stop
return
end
end
mob.play_animation(MIXING_ANIM)
execute_action
@amount -= 1
@amount > 0 ? @pulses = 0 : stop
end
def stop
super()
mob.inventory.remove_listener(@listener) unless @listener.nil?
end
def execute_action
# Override for action execution.
end
def gather_materials
# Override for ingredient checking and gathering
false
end
# Sets the amount of actions.
def set_amount(amount)
@amount = amount
end
def equals(other)
get_class == other.get_class && @potion == other.potion
end
end
# A MixingAction which handles the execution of making UnfinishedPotions.
class UnfinishedMixingAction < MixingAction
attr_reader :slots
def initialize(player, potion)
super(player, potion, 'use this herb.')
end
def execute_action
name = @potion.herb.item.definition.name
player = mob
inventory = player.inventory
created = name.sub(/ leaf$/, '')
message = "You put the #{name} in the water to make an unfinished #{created} potion."
player.send_message(message)
@slots.each do |slot, amount|
unless inventory.remove_slot(slot, amount)
stop
return
end
end
inventory.add(@potion.item)
end
def gather_materials
@slots = {}
inventory = mob.inventory
vial_slot = inventory.slot_of(WATER_VIAL_ID)
if vial_slot == -1
mob.send_message('You do not have any more vials of water.')
return false
end
item = @potion.herb.item
herb_slot = inventory.slot_of(item.id)
if herb_slot == -1
mob.send_message("You do not have any more #{item.definition.name}.")
return false
end
@slots[vial_slot] = 1
@slots[herb_slot] = 1
true
end
end
# A MixingAction which handles the execution of making FinishedPotions.
class FinishedMixingAction < MixingAction
attr_reader :unfinished, :ingredient, :slots
def initialize(player, unfinished, ingredient, potion)
super(player, potion, 'mix this potion')
@unfinished = unfinished
@ingredient = ingredient
end
def execute_action
ingredient = name_of(:item, @ingredient).downcase
name = @potion.item.definition.name.sub('(3)', '')
name = "#{LanguageUtil.get_indefinite_article(name)} #{name}"
mob.send_message("You add the #{ingredient} to the mixture to make #{name}.")
mob.skill_set.add_experience(Skill::HERBLORE, @potion.experience)
inventory = mob.inventory
@slots.each do |slot, amount|
unless inventory.remove_slot(slot, amount) # TODO: will this remove stuff incorrectly?
stop
return
end
end
inventory.add(@potion.item)
end
def gather_materials
@slots = {}
inventory = mob.inventory
vial_slot = inventory.slot_of(@unfinished)
if vial_slot == -1
mob.send_message('You do not have enough unfinished potions.')
return false
end
ingredient_slot = inventory.slot_of(@ingredient)
if ingredient_slot == -1
mob.send_message('You do not have enough ingredients.')
return false
end
@slots[vial_slot] = 1
@slots[ingredient_slot] = 1
true
end
end
# Appends a finished potion to the ItemOnItemMessage handling interception.
def finished_potion(item, unfinished, ingredient, level, experience)
potion = FinishedPotion.new(item, [unfinished, ingredient], level, experience)
append_herblore_item(potion, unfinished.item_id, ingredient.item_id)
potion
end
# Appends an unfinished potion to the ItemOnItemMessage handling interception.
def unfinished_potion(item, herb, level)
potion = UnfinishedPotion.new(item, herb, level)
append_herblore_item(potion, herb.item_id, WATER_VIAL_ID)
potion
end
# Unfinished potions
UNF_GUAM = unfinished_potion(91, GUAM_LEAF, 1) # 3
UNF_MARRENTILL = unfinished_potion(93, MARRENTILL, 5)
UNF_TARROMIN = unfinished_potion(95, TARROMIN, 12)
UNF_HARRALANDER = unfinished_potion(97, HARRALANDER, 22)
UNF_RANARR = unfinished_potion(99, RANARR, 30)
UNF_TOADFLAX = unfinished_potion(3002, TOADFLAX, 34)
UNF_IRIT = unfinished_potion(101, IRIT_LEAF, 45)
UNF_AVANTOE = unfinished_potion(103, AVANTOE, 50)
UNF_KWUARM = unfinished_potion(105, KWUARM, 55)
UNF_SNAPDRAGON = unfinished_potion(3004, SNAPDRAGON, 63)
UNF_CADANTINE = unfinished_potion(107, CADANTINE, 66)
UNF_LANTADYME = unfinished_potion(2483, LANTADYME, 69)
UNF_DWARF_WEED = unfinished_potion(109, DWARF_WEED, 72)
UNF_TORSTOL = unfinished_potion(111, TORSTOL, 78)
# Finished potions
ATTACK_POT = finished_potion(121, UNF_GUAM, EYE_NEWT, 1, 25) # 3
ANTIPOISON_POT = finished_potion(175, UNF_MARRENTILL, UNICORN_HORN_DUST, 5, 37.5)
STRENGTH_POT = finished_potion(115, UNF_TARROMIN, LIMPWURT_ROOT, 12, 50)
RESTORE_POT = finished_potion(127, UNF_HARRALANDER, RED_SPIDERS_EGGS, 18, 62.5)
ENERGY_POT = finished_potion(3010, UNF_HARRALANDER, CHOCOLATE_DUST, 26, 67.5)
DEFENCE_POT = finished_potion(133, UNF_RANARR, WHITE_BERRIES, 30, 75)
AGILITY_POT = finished_potion(3034, UNF_TOADFLAX, TOADS_LEGS, 34, 80)
PRAYER_POT = finished_potion(139, UNF_RANARR, SNAPE_GRASS, 38, 87.5)
SUPER_ATTACK_POT = finished_potion(145, UNF_IRIT, EYE_NEWT, 45, 100)
SUPER_ANTIPOISON_POT = finished_potion(181, UNF_IRIT, UNICORN_HORN_DUST, 48, 106.3)
FISHING_POT = finished_potion(151, UNF_AVANTOE, SNAPE_GRASS, 50, 112.5)
SUPER_ENERGY_POT = finished_potion(3018, UNF_AVANTOE, MORT_MYRE_FUNGI, 52, 117.5)
SUPER_STRENGTH_POT = finished_potion(157, UNF_KWUARM, LIMPWURT_ROOT, 55, 125)
WEAPON_POISON = finished_potion(187, UNF_KWUARM, DRAGON_SCALE_DUST, 60, 137.5)
SUPER_RESTORE_POT = finished_potion(3026, UNF_SNAPDRAGON, RED_SPIDERS_EGGS, 63, 142.5)
SUPER_DEFENCE_POT = finished_potion(163, UNF_CADANTINE, WHITE_BERRIES, 66, 150)
ANTIFIRE_POT = finished_potion(2428, UNF_LANTADYME, DRAGON_SCALE_DUST, 69, 157.5)
RANGING_POT = finished_potion(169, UNF_DWARF_WEED, WINE_ZAMORAK, 72, 162.5)
MAGIC_POT = finished_potion(3042, UNF_LANTADYME, POTATO_CACTUS, 76, 172.5)
ZAMORAK_BREW = finished_potion(189, UNF_TORSTOL, JANGERBERRIES, 78, 175)