mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Recursive plugin loading.
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.action.Action'
|
||||
|
||||
# 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)
|
||||
player.skill_set.add_experience(HERBLORE_ID, @herb.experience)
|
||||
player.send_message("You identify the herb as a #{identified.definition.name}.", true)
|
||||
end
|
||||
stop
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class and slot == other.slot and herb == other.herb)
|
||||
end
|
||||
end
|
||||
|
||||
# Appends a herb to the InventoryItemEvent interception.
|
||||
def append_herb(item_id, unidentified, level, experience)
|
||||
herb = Herb.new(item_id, unidentified, level, experience)
|
||||
append_herblore_item(herb, unidentified)
|
||||
return herb
|
||||
end
|
||||
|
||||
# Herbs
|
||||
|
||||
GUAM_LEAF = append_herb(249, 199, 1, 2.5) # 3, 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,101 @@
|
||||
# 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.event.impl.SetWidgetItemModelEvent'
|
||||
java_import 'org.apollo.game.model.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
|
||||
raise 'You cannot instantiate this module!'
|
||||
end
|
||||
|
||||
def invoke(player, primary, secondary)
|
||||
raise NotImplementedError.new('You must implement the invocation of HerbloreMethod!')
|
||||
end
|
||||
end
|
||||
|
||||
# The ItemOnItemEvent handler for all Herblore-related functions.
|
||||
on :event, :item_on_item do |ctx, player, event|
|
||||
primary = event.id
|
||||
secondary = event.target_id
|
||||
hash = HERBLORE_ITEM_ON_ITEM[primary]
|
||||
|
||||
if hash == nil
|
||||
secondary = event.id
|
||||
primary = event.target_id
|
||||
hash = HERBLORE_ITEM_ON_ITEM[primary]
|
||||
end
|
||||
|
||||
if hash != nil
|
||||
method = hash[secondary]
|
||||
if method != nil
|
||||
method.invoke(player, primary, secondary)
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The ItemOptionEvent handler for all Herblore-related functions.
|
||||
on :event, :item_option do |ctx, player, event|
|
||||
if event.option == 1
|
||||
id = event.id
|
||||
method = HERBLORE_ITEM[id]
|
||||
|
||||
if method != nil
|
||||
method.invoke(player, id, event.slot)
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
method = DRINK_ITEM[id]
|
||||
|
||||
if method != nil
|
||||
method.invoke(player, id, event.slot)
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
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 an item 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)
|
||||
return (item != nil and item.id == id and item.amount >= amount)
|
||||
end
|
||||
|
||||
# Utility method for checking if a player's Herblore (maximum) level is at a required height. 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.skill(HERBLORE_SKILL_ID).current_level
|
||||
player.send_message("You need a Herblore level of at least #{required} to #{action}.")
|
||||
return false
|
||||
end
|
||||
return 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(SetWidgetItemModelEvent.new(1746, item, 170))
|
||||
player.interface_set.open_dialogue(listener, HERBLORE_DIALOGUE)
|
||||
end
|
||||
@@ -0,0 +1,255 @@
|
||||
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.def.ItemDefinition'
|
||||
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
|
||||
|
||||
return 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)
|
||||
if amount <= 0 then return else execute(amount) end
|
||||
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
|
||||
if not 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.", true)
|
||||
|
||||
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 and !pst_mrt
|
||||
pst_mrt = true
|
||||
elsif id == raw and !ingr
|
||||
ingr = true
|
||||
@slot = slot
|
||||
end
|
||||
|
||||
return true if pst_mrt and ingr
|
||||
end
|
||||
|
||||
ingr = ItemDefinition.lookup(raw).name.downcase
|
||||
mob.send_message("You do not have any more #{ingr}s.")
|
||||
return 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)
|
||||
return (get_class == other.get_class and @ingredient == other.ingredient)
|
||||
end
|
||||
end
|
||||
|
||||
# Appends a grinded ingredient to the ItemOnItemEvent handler interception.
|
||||
def append_ground(id, raw)
|
||||
grinded = GroundIngredient.new(id, raw)
|
||||
append_herblore_item(grinded, PESTLE_MORTAR, raw)
|
||||
return grinded
|
||||
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>
|
||||
@@ -0,0 +1,365 @@
|
||||
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.def.ItemDefinition'
|
||||
java_import 'org.apollo.game.model.inter.EnterAmountListener'
|
||||
java_import 'org.apollo.game.model.inter.dialogue.DialogueAdapter'
|
||||
|
||||
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)
|
||||
return true
|
||||
end
|
||||
|
||||
# Called when an amount of mixing actions has been entered.
|
||||
def amountEntered(amount)
|
||||
if amount <= 0 then return else execute(amount) end
|
||||
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)
|
||||
amount = herbs if amount > herbs
|
||||
|
||||
return amount
|
||||
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
|
||||
|
||||
return 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
|
||||
|
||||
if (@amount -= 1) > 0 then @pulses = 0 else stop end
|
||||
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
|
||||
return false
|
||||
end
|
||||
|
||||
# Sets the amount of actions.
|
||||
def set_amount(amount)
|
||||
@amount = amount
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class and @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
|
||||
|
||||
player.send_message("You put the #{name} in the water to make an unfinished #{name.sub(/ leaf$/, "")} potion.", true)
|
||||
|
||||
@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
|
||||
|
||||
return 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
|
||||
player = mob
|
||||
ingredient = ItemDefinition.lookup(@ingredient).name.downcase
|
||||
name = @potion.item.definition.name.sub('(3)', '')
|
||||
|
||||
player.send_message("You add the #{ingredient} to the mixture to make an #{name}.", true)
|
||||
player.skill_set.add_experience(HERBLORE_SKILL_ID, @potion.experience)
|
||||
|
||||
inventory = player.inventory
|
||||
|
||||
@slots.each do |slot, amount|
|
||||
if not 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(@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
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
# Appends a finished potion to the ItemOnItemEvent handling interception.
|
||||
def append_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)
|
||||
return potion
|
||||
end
|
||||
|
||||
# Appends an unfinished potion to the ItemOnItemEvent handling interception.
|
||||
def append_unfinished_potion(item, herb, level)
|
||||
potion = UnfinishedPotion.new(item, herb, level)
|
||||
append_herblore_item(potion, herb.item_id, WATER_VIAL_ID)
|
||||
return potion
|
||||
end
|
||||
|
||||
|
||||
# Unfinished potions
|
||||
UNF_GUAM = append_unfinished_potion(91, GUAM_LEAF, 1) # 3
|
||||
UNF_MARRENTILL = append_unfinished_potion(93, MARRENTILL, 5)
|
||||
UNF_TARROMIN = append_unfinished_potion(95, TARROMIN, 12)
|
||||
UNF_HARRALANDER = append_unfinished_potion(97, HARRALANDER, 22)
|
||||
UNF_RANARR = append_unfinished_potion(99, RANARR, 30)
|
||||
UNF_TOADFLAX = append_unfinished_potion(3002, TOADFLAX, 34)
|
||||
UNF_IRIT = append_unfinished_potion(101, IRIT_LEAF, 45)
|
||||
UNF_AVANTOE = append_unfinished_potion(103, AVANTOE, 50)
|
||||
UNF_KWUARM = append_unfinished_potion(105, KWUARM, 55)
|
||||
UNF_SNAPDRAGON = append_unfinished_potion(3004, SNAPDRAGON, 63)
|
||||
UNF_CADANTINE = append_unfinished_potion(107, CADANTINE, 66)
|
||||
UNF_LANTADYME = append_unfinished_potion(2483, LANTADYME, 69)
|
||||
UNF_DWARF_WEED = append_unfinished_potion(109, DWARF_WEED, 72)
|
||||
UNF_TORSTOL = append_unfinished_potion(111, TORSTOL, 78)
|
||||
|
||||
|
||||
# Finished potions
|
||||
ATTACK_POT = append_finished_potion(121, UNF_GUAM, EYE_NEWT, 1, 25) # 3, 25
|
||||
ANTIPOISON_POT = append_finished_potion(175, UNF_MARRENTILL, UNICORN_HORN_DUST, 5, 37.5)
|
||||
STRENGTH_POT = append_finished_potion(115, UNF_TARROMIN, LIMPWURT_ROOT, 12, 50)
|
||||
RESTORE_POT = append_finished_potion(127, UNF_HARRALANDER, RED_SPIDERS_EGGS, 18, 62.5)
|
||||
ENERGY_POT = append_finished_potion(3010, UNF_HARRALANDER, CHOCOLATE_DUST, 26, 67.5)
|
||||
DEFENCE_POT = append_finished_potion(133, UNF_RANARR, WHITE_BERRIES, 30, 75)
|
||||
AGILITY_POT = append_finished_potion(3034, UNF_TOADFLAX, TOADS_LEGS, 34, 80)
|
||||
PRAYER_POT = append_finished_potion(139, UNF_RANARR, SNAPE_GRASS, 38, 87.5)
|
||||
SUPER_ATTACK_POT = append_finished_potion(145, UNF_IRIT, EYE_NEWT, 45, 100)
|
||||
SUPER_ANTIPOISON_POT = append_finished_potion(181, UNF_IRIT, UNICORN_HORN_DUST, 48, 106.3)
|
||||
FISHING_POT = append_finished_potion(151, UNF_AVANTOE, SNAPE_GRASS, 50, 112.5)
|
||||
SUPER_ENERGY_POT = append_finished_potion(3018, UNF_AVANTOE, MORT_MYRE_FUNGI, 52, 117.5)
|
||||
SUPER_STRENGTH_POT = append_finished_potion(157, UNF_KWUARM, LIMPWURT_ROOT, 55, 125)
|
||||
WEAPON_POISON = append_finished_potion(187, UNF_KWUARM, DRAGON_SCALE_DUST, 60, 137.5)
|
||||
SUPER_RESTORE_POT = append_finished_potion(3026, UNF_SNAPDRAGON, RED_SPIDERS_EGGS, 63, 142.5)
|
||||
SUPER_DEFENCE_POT = append_finished_potion(163, UNF_CADANTINE, WHITE_BERRIES, 66, 150)
|
||||
ANTIFIRE_POT = append_finished_potion(2428, UNF_LANTADYME, DRAGON_SCALE_DUST, 69, 157.5)
|
||||
RANGING_POT = append_finished_potion(169, UNF_DWARF_WEED, WINE_ZAMORAK, 72, 162.5)
|
||||
MAGIC_POT = append_finished_potion(3042, UNF_LANTADYME, POTATO_CACTUS, 76, 172.5)
|
||||
ZAMORAK_BREW = append_finished_potion(189, UNF_TORSTOL, JANGERBERRIES, 78, 175)
|
||||
@@ -0,0 +1,70 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Graphic'
|
||||
|
||||
ALCHEMY_SPELLS = {}
|
||||
|
||||
LOW_ALCH_ANIM = Animation.new(712)
|
||||
LOW_ALCH_GRAPHIC = Graphic.new(112, 0, 100)
|
||||
LOW_ALCH_MULTIPLIER = 0.4
|
||||
|
||||
HIGH_ALCH_ANIM = Animation.new(713)
|
||||
HIGH_ALCH_GRAPHIC = Graphic.new(113, 0, 100)
|
||||
HIGH_ALCH_MULTIPLIER = 0.6
|
||||
|
||||
ILLEGAL_ALCH_ITEMS = [ 995, 6529, 6306, 6307, 6308, 6309, 6310 ]
|
||||
|
||||
class AlchemySpell < Spell
|
||||
attr_reader :high, :animation, :graphic, :multiplier, :experience, :delay
|
||||
|
||||
def initialize(level, elements, high, animation, graphic, multiplier, experience, delay)
|
||||
super(level, elements, experience)
|
||||
@high = high
|
||||
@animation = animation
|
||||
@graphic = graphic
|
||||
@multiplier = multiplier
|
||||
@delay = delay
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class AlchemyAction < ItemSpellAction
|
||||
|
||||
def initialize(player, alchemy, slot, item)
|
||||
super(player, alchemy, slot, item)
|
||||
end
|
||||
|
||||
def illegal_item?
|
||||
return ILLEGAL_ALCH_ITEMS.include?(@item.id)
|
||||
end
|
||||
|
||||
def execute_action
|
||||
if @pulses == 0
|
||||
mob.play_animation(@spell.animation)
|
||||
mob.play_graphic(@spell.graphic)
|
||||
mob.send(DISPLAY_SPELLBOOK)
|
||||
|
||||
inventory = mob.inventory
|
||||
gold = (item.definition.value * @spell.multiplier) + 1
|
||||
|
||||
inventory.remove(inventory.get(@slot).id, 1)
|
||||
inventory.add(995, gold)
|
||||
|
||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
||||
set_delay(@spell.delay)
|
||||
elsif @pulses == 1
|
||||
mob.stop_animation
|
||||
mob.stop_graphic
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def append_alchemy(button, level, elements, high, animation, graphic, multiplier, experience, delay)
|
||||
ALCHEMY_SPELLS[button] = AlchemySpell.new(level, elements, high, animation, graphic, multiplier, experience, delay)
|
||||
end
|
||||
|
||||
append_alchemy(1162, 21, { FIRE => 3, NATURE => 1 }, false, LOW_ALCH_ANIM, LOW_ALCH_GRAPHIC, 0.48, 31, 1) # Low level alchemy
|
||||
append_alchemy(1178, 55, { FIRE => 5, NATURE => 1 }, true, HIGH_ALCH_ANIM, HIGH_ALCH_GRAPHIC, 0.72, 65, 4) # High level alchemy
|
||||
@@ -0,0 +1,86 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Graphic'
|
||||
java_import 'org.apollo.game.model.Item'
|
||||
|
||||
CONVERT_SPELLS = {}
|
||||
BONES_ID = 526
|
||||
|
||||
CONVERT_ANIM = Animation.new(722)
|
||||
CONVERT_GRAPHIC = Graphic.new(141, 0, 100)
|
||||
|
||||
class ConvertSpell < Spell
|
||||
attr_reader :reward
|
||||
|
||||
def initialize(level, elements, experience, reward)
|
||||
super(level, elements, experience)
|
||||
@reward = Item.new(reward)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ConvertingAction < SpellAction
|
||||
attr_reader :slots
|
||||
|
||||
def initialize(player, spell, slots)
|
||||
super(player, spell)
|
||||
@slots = slots
|
||||
end
|
||||
|
||||
def execute_action
|
||||
if @pulses == 0
|
||||
mob.play_animation(CONVERT_ANIM)
|
||||
mob.play_graphic(CONVERT_GRAPHIC)
|
||||
|
||||
inventory = mob.inventory
|
||||
firing = (@slots.length * 2) < inventory.capacity
|
||||
|
||||
inventory.stop_firing_events unless firing # In the case of many changes, wait with firing events
|
||||
|
||||
reward = @spell.reward
|
||||
@slots.each do |slot|
|
||||
inventory.set(slot, reward) # Share the instance
|
||||
end
|
||||
|
||||
unless firing # If we waited with firing events, restore it now and force a refresh
|
||||
inventory.start_firing_events
|
||||
inventory.force_refresh
|
||||
end
|
||||
|
||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
||||
set_delay(2)
|
||||
elsif @pulses == 1
|
||||
mob.stop_animation
|
||||
mob.stop_graphic
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def bone_slots(player)
|
||||
inventory = player.inventory
|
||||
items = inventory.items
|
||||
size = inventory.size
|
||||
|
||||
counter = 0
|
||||
slots = []
|
||||
(0...inventory.capacity).each do |slot|
|
||||
break unless counter <= size
|
||||
|
||||
item = items[slot]
|
||||
slots << slot if (item != nil and item.id == BONES_ID)
|
||||
|
||||
counter += 1
|
||||
end
|
||||
|
||||
return slots
|
||||
end
|
||||
|
||||
def append_convert(button, level, elements, experience, reward)
|
||||
CONVERT_SPELLS[button] = ConvertSpell.new(level, elements, experience, reward)
|
||||
end
|
||||
|
||||
append_convert 1159, 15, { EARTH => 2, WATER => 2, NATURE => 1 }, 25, 1963 # Bones to bananas
|
||||
#append_convert 15877, 60, { NATURE => 2, WATER => 4, EARTH => 4 }, 35.5, 6883 # Bones to peaches
|
||||
@@ -0,0 +1,112 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.EquipmentConstants'
|
||||
|
||||
AIR_ELEMENTS = {}
|
||||
WATER_ELEMENTS = {}
|
||||
EARTH_ELEMENTS = {}
|
||||
FIRE_ELEMENTS = {}
|
||||
|
||||
AIR_RUNE = 556
|
||||
WATER_RUNE = 555
|
||||
EARTH_RUNE = 557
|
||||
FIRE_RUNE = 554
|
||||
|
||||
MIND_RUNE = 558
|
||||
CHAOS_RUNE = 562
|
||||
DEATH_RUNE = 560
|
||||
BLOOD_RUNE = 565
|
||||
|
||||
COSMIC_RUNE = 564
|
||||
LAW_RUNE = 563
|
||||
NATURE_RUNE = 561
|
||||
SOUL_RUNE = 566
|
||||
|
||||
MIST_RUNE = 4695
|
||||
DUST_RUNE = 4696
|
||||
SMOKE_RUNE = 4697
|
||||
MUD_RUNE = 4698
|
||||
STEAM_RUNE = 4694
|
||||
LAVA_RUNE = 4699
|
||||
|
||||
class Element
|
||||
attr_reader :runes, :staffs, :name
|
||||
|
||||
def initialize(runes, staffs, name="Null")
|
||||
@runes = runes
|
||||
@staffs = staffs
|
||||
@name = name
|
||||
end
|
||||
|
||||
def check_remove(player, amount, remove)
|
||||
weapon = player.equipment.get(EquipmentConstants::WEAPON)
|
||||
if @staffs != nil && weapon != nil
|
||||
@staffs.each do |staff|
|
||||
return true if weapon.id == staff
|
||||
end
|
||||
end
|
||||
|
||||
inventory = player.inventory
|
||||
|
||||
found = {}
|
||||
counter = 0
|
||||
|
||||
inventory.items.each do |item|
|
||||
break unless counter < amount
|
||||
next if item == nil
|
||||
|
||||
amt = item.amount
|
||||
@runes.each do |rune|
|
||||
break unless counter < amount
|
||||
|
||||
id = item.id
|
||||
if id == rune
|
||||
if amt >= amount
|
||||
inventory.remove(id, amount) if remove
|
||||
return true
|
||||
else
|
||||
found[id] = amt
|
||||
counter += amt
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if counter >= amount
|
||||
if remove
|
||||
found.each do |id, amt|
|
||||
inventory.remove(id, amt)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
AIR_RUNES = [ 556, 4695, 4696, 4697 ]
|
||||
WATER_RUNES = [ 555, 4695, 4698, 4694 ]
|
||||
EARTH_RUNES = [ 557, 4696, 4697, 4698 ]
|
||||
FIRE_RUNES = [ 554, 4697, 4694, 4699 ]
|
||||
|
||||
AIR_STAFFS = [ 1381, 1397, 1405 ]
|
||||
WATER_STAFFS = [ 1383, 1395, 1403 ]
|
||||
EARTH_STAFFS = [ 1385, 1399, 1407, 3053, 3054 ]
|
||||
FIRE_STAFFS = [ 1387, 1393, 1401, 3053, 3054 ]
|
||||
|
||||
AIR = Element.new(AIR_RUNES, AIR_STAFFS, "Air rune")
|
||||
WATER = Element.new(WATER_RUNES, WATER_STAFFS, "Water rune")
|
||||
EARTH = Element.new(EARTH_RUNES, EARTH_STAFFS, "Earth rune")
|
||||
FIRE = Element.new(FIRE_RUNES, FIRE_STAFFS, "Fire rune")
|
||||
|
||||
MIND = Element.new([MIND_RUNE], nil, "Mind rune")
|
||||
CHAOS = Element.new([CHAOS_RUNE], nil, "Chaos rune")
|
||||
DEATH = Element.new([DEATH_RUNE], nil, "Death rune")
|
||||
BLOOD = Element.new([BLOOD_RUNE], nil, "Blood rune")
|
||||
|
||||
COSMIC = Element.new([COSMIC_RUNE], nil, "Cosmic rune")
|
||||
LAW = Element.new([LAW_RUNE], nil, "Law rune")
|
||||
NATURE = Element.new([NATURE_RUNE], nil, "Nature rune")
|
||||
SOUL = Element.new([SOUL_RUNE], nil, "Soul rune")
|
||||
@@ -0,0 +1,109 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Graphic'
|
||||
java_import 'org.apollo.game.model.Item'
|
||||
|
||||
ENCHANT_SPELLS = {}
|
||||
ENCHANT_ITEMS = {}
|
||||
|
||||
RING_GFX = Graphic.new(238, 0, 100)
|
||||
RING_ANIM = Animation.new(713) # TODO: No way we need one of the alchemy anims for enchanting...
|
||||
|
||||
LOW_NECK_GFX = Graphic.new(114, 0, 100)
|
||||
LOW_NECK_ANIM = Animation.new(719)
|
||||
|
||||
MED_NECK_GFX = Graphic.new(115, 0, 100)
|
||||
MED_NECK_ANIM = Animation.new(720)
|
||||
|
||||
HIGH_NECK_GFX = Graphic.new(116, 0, 100)
|
||||
HIGH_NECK_ANIM = Animation.new(721)
|
||||
|
||||
ONYX_NECK_GFX = Graphic.new(452, 0, 100)
|
||||
|
||||
class EnchantSpell < Spell
|
||||
attr_reader :button, :animation, :graphic, :delay
|
||||
|
||||
def initialize(button, level, elements, animation, graphic, delay, experience)
|
||||
super(level, elements, experience)
|
||||
@button = button
|
||||
@animation = animation
|
||||
@graphic = graphic
|
||||
@delay = delay
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class EnchantAction < ItemSpellAction
|
||||
attr_reader :reward
|
||||
|
||||
def initialize(player, enchant, slot, item, reward)
|
||||
super(player, enchant, slot, item)
|
||||
@reward = Item.new(reward)
|
||||
end
|
||||
|
||||
def illegal_item?
|
||||
return ENCHANT_ITEMS[@item.id] == nil
|
||||
end
|
||||
|
||||
def execute_action
|
||||
if @pulses == 0
|
||||
mob.play_animation(@spell.animation)
|
||||
mob.play_graphic(@spell.graphic)
|
||||
mob.send(DISPLAY_SPELLBOOK)
|
||||
|
||||
mob.inventory.set(@slot, @reward)
|
||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
||||
|
||||
set_delay(@spell.delay)
|
||||
elsif @pulses == 1
|
||||
mob.stop_animation
|
||||
mob.stop_graphic
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def append_enchant(button, level, elements, item, animation, graphic, delay, experience, reward)
|
||||
enchant = EnchantSpell.new(button, level, elements, animation, graphic, delay, experience)
|
||||
ENCHANT_SPELLS[item] = enchant
|
||||
ENCHANT_ITEMS[item] = reward
|
||||
end
|
||||
|
||||
SAPPHIRE_ELEMENTS = { WATER => 1, COSMIC => 1 }
|
||||
EMERALD_ELEMENTS = { AIR => 1, COSMIC => 1 }
|
||||
RUBY_ELEMENTS = { FIRE => 5, COSMIC => 1 }
|
||||
DIAMOND_ELEMENTS = { EARTH => 10, COSMIC => 1 }
|
||||
DSTONE_ELEMENTS = { WATER => 15, EARTH => 15, COSMIC => 1 }
|
||||
ONYX_ELEMENTS = { EARTH => 20, FIRE => 20, COSMIC => 1 }
|
||||
|
||||
# Sapphire
|
||||
append_enchant 1155, 7, SAPPHIRE_ELEMENTS, 1637, RING_ANIM, RING_GFX, 2, 17.5, 2550 # Ring
|
||||
append_enchant 1155, 7, SAPPHIRE_ELEMENTS, 1656, LOW_NECK_ANIM, LOW_NECK_GFX, 1, 17.5, 3853 # Necklace
|
||||
append_enchant 1155, 7, SAPPHIRE_ELEMENTS, 1692, LOW_NECK_ANIM, LOW_NECK_GFX, 1, 17.5, 1727 # Amulet
|
||||
|
||||
# Emerald
|
||||
append_enchant 1165, 27, EMERALD_ELEMENTS, 1639, RING_ANIM, RING_GFX, 2, 37, 2552 # Ring
|
||||
append_enchant 1165, 27, EMERALD_ELEMENTS, 1658, LOW_NECK_ANIM, LOW_NECK_GFX, 1, 37, 5521 # Necklace
|
||||
append_enchant 1165, 27, EMERALD_ELEMENTS, 1696, LOW_NECK_ANIM, LOW_NECK_GFX, 1, 37, 1729 # Amulet
|
||||
|
||||
# Ruby
|
||||
append_enchant 1176, 49, RUBY_ELEMENTS, 1641, RING_ANIM, RING_GFX, 2, 59, 2568 # Ring
|
||||
# append_enchant 1176, 49, RUBY_ELEMENTS, 1660, MED_NECK_ANIM, MED_NECK_GFX, 2, 59, # Necklace - not found in 317 or 377
|
||||
append_enchant 1176, 49, RUBY_ELEMENTS, 1698, MED_NECK_ANIM, MED_NECK_GFX, 2, 59, 1725 # Amulet
|
||||
|
||||
# Diamond
|
||||
append_enchant 1180, 57, DIAMOND_ELEMENTS, 1643, RING_ANIM, RING_GFX, 2, 67, 2570 # Ring
|
||||
# append_enchant 1180, 57, DIAMOND_ELEMENTS, 1662, MED_NECK_ANIM, MED_NECK_GFX, 2, 67, # Necklace - not found in 317 or 377
|
||||
append_enchant 1180, 57, DIAMOND_ELEMENTS, 1700, MED_NECK_ANIM, MED_NECK_GFX, 2, 67, 1731 # Amulet
|
||||
|
||||
# Dragonstone
|
||||
append_enchant 1187, 68, DSTONE_ELEMENTS, 1645, RING_ANIM, RING_GFX, 2, 78, 2572 # Ring
|
||||
# append_enchant 1187, 68, DSTONE_ELEMENTS, 1664, HIGH_NECK_ANIM, HIGH_NECK_GFX, 3, 78, # Necklace - not found in 317 or 377
|
||||
append_enchant 1187, 68, DSTONE_ELEMENTS, 1702, HIGH_NECK_ANIM, HIGH_NECK_GFX, 3, 78, 1712 # Amulet
|
||||
|
||||
# Onyx
|
||||
append_enchant 6003, 87, ONYX_ELEMENTS, 6575, RING_ANIM, RING_GFX, 2, 97, 6583 # Ring
|
||||
# append_enchant 6003, 87, ONYX_ELEMENTS, 6577, HIGH_NECK_ANIM, ONYX_NECK_GFX, 3, 97, # Necklace - not found in 317 or 377
|
||||
append_enchant 6003, 87, ONYX_ELEMENTS, 6581, HIGH_NECK_ANIM, ONYX_NECK_GFX, 2, 97, 6585 # Amulet
|
||||
@@ -0,0 +1,161 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.action.Action'
|
||||
java_import 'org.apollo.game.event.impl.DisplayTabInterfaceEvent'
|
||||
java_import 'org.apollo.game.model.EquipmentConstants'
|
||||
java_import 'org.apollo.game.model.Skill'
|
||||
|
||||
DISPLAY_SPELLBOOK = DisplayTabInterfaceEvent.new(6)
|
||||
|
||||
class Spell
|
||||
attr_reader :level, :elements, :experience
|
||||
|
||||
def initialize(level, elements, experience)
|
||||
@level = level
|
||||
@elements = elements
|
||||
@experience = experience
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class SpellAction < Action
|
||||
attr_reader :spell, :pulses
|
||||
|
||||
def initialize(mob, spell)
|
||||
super(0, true, mob)
|
||||
|
||||
@spell = spell
|
||||
@pulses = 0
|
||||
end
|
||||
|
||||
def execute
|
||||
if @pulses == 0
|
||||
unless (check_skill and process_elements)
|
||||
stop
|
||||
return
|
||||
end
|
||||
end
|
||||
execute_action
|
||||
@pulses += 1
|
||||
end
|
||||
|
||||
def execute_action
|
||||
stop
|
||||
end
|
||||
|
||||
def check_skill
|
||||
required = @spell.level
|
||||
if required > mob.skill_set.skill(MAGIC_SKILL_ID).maximum_level
|
||||
mob.send_message("You need a Magic level of at least #{required} to cast this spell.")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def process_elements
|
||||
elements = @spell.elements
|
||||
|
||||
elements.each do |element, amount|
|
||||
unless element.check_remove(mob, amount, false)
|
||||
mob.send_message("You do not have enough #{element.name}s to cast this spell.")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
elements.each do |element, amount|
|
||||
element.check_remove(mob, amount, true)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class and @spell == other.spell)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ItemSpellAction < SpellAction
|
||||
attr_reader :slot, :item
|
||||
|
||||
def initialize(mob, spell, slot, item)
|
||||
super(mob, spell)
|
||||
@slot = slot
|
||||
@item = item
|
||||
end
|
||||
|
||||
# We override SpellAction#execute to implement an illegal item check (e.g. coins for alchemy)
|
||||
def execute
|
||||
if @pulses == 0
|
||||
if illegal_item?
|
||||
mob.send_message('You cannot use that spell on this item!')
|
||||
stop
|
||||
next
|
||||
end
|
||||
|
||||
id = @item.id
|
||||
|
||||
# TODO: There has to be a better way to do this.
|
||||
@spell.elements.each do |element, amount|
|
||||
element.runes.each do |rune|
|
||||
if id == rune && !element.check_remove(mob, amount + 1, false)
|
||||
mob.send_message("You do not have enough #{element.name}s to cast this spell.")
|
||||
stop
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def illegal_item?
|
||||
# Override this method if necessary
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Intercepts the magic on item event.
|
||||
on :event, :magic_on_item do |ctx, player, event|
|
||||
spell = event.spell_id
|
||||
|
||||
alch = ALCHEMY_SPELLS[spell]
|
||||
if alch != nil
|
||||
slot = event.slot
|
||||
item = player.inventory.get(slot)
|
||||
player.start_action(AlchemyAction.new(player, alch, slot, item))
|
||||
ctx.break_handler_chain
|
||||
return
|
||||
end
|
||||
|
||||
ench = ENCHANT_SPELLS[event.id]
|
||||
if ench != nil and ench.button == spell
|
||||
slot = event.slot
|
||||
item = player.inventory.get(slot)
|
||||
player.start_action(EnchantAction.new(player, ench, slot, item, ENCHANT_ITEMS[item.id]))
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
end
|
||||
|
||||
# Intercepts the button event
|
||||
on :event, :button do |ctx, player, event|
|
||||
button = event.widget_id
|
||||
|
||||
tele = TELEPORT_SPELLS[button]
|
||||
if tele != nil
|
||||
player.start_action(TeleportingAction.new(player, tele))
|
||||
ctx.break_handler_chain
|
||||
return
|
||||
end
|
||||
|
||||
conv = CONVERT_SPELLS[button]
|
||||
if conv != nil
|
||||
slots = bone_slots player
|
||||
if slots.length == 0 then player.send_message("You cant convert these bones!") else player.start_action(ConvertingAction.new(player, conv, slots)) end
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<plugin>
|
||||
<id>skill-magic</id>
|
||||
<version>1</version>
|
||||
<name>Magic</name>
|
||||
<description>Adds the Magic skill.</description>
|
||||
<authors>
|
||||
<author>Chris Fletcher</author>
|
||||
<author>Major</author>
|
||||
</authors>
|
||||
<scripts>
|
||||
<script>magic.rb</script>
|
||||
<script>element.rb</script>
|
||||
<script>teleport.rb</script>
|
||||
<script>alchemy.rb</script>
|
||||
<script>enchant.rb</script>
|
||||
<script>convert.rb</script>
|
||||
</scripts>
|
||||
<dependencies />
|
||||
</plugin>
|
||||
@@ -0,0 +1,94 @@
|
||||
# Thanks to phl0w <http://www.rune-server.org/members/phl0w/> for providing
|
||||
# the correct destination coordinates of the ancient teleports.
|
||||
|
||||
require 'java'
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Graphic'
|
||||
java_import 'org.apollo.game.model.Position'
|
||||
|
||||
TELEPORT_SPELLS = {}
|
||||
|
||||
MODERN_TELE_ANIM = Animation.new(714)
|
||||
MODERN_TELE_END_ANIM = Animation.new(715)
|
||||
MODERN_TELE_GRAPHIC = Graphic.new(308, 15, 100)
|
||||
|
||||
ANCIENT_TELE_END_GRAPHIC = Graphic.new(455)
|
||||
ANCIENT_TELE_ANIM = Animation.new(1979)
|
||||
ANCIENT_TELE_GRAPHIC = Graphic.new(392)
|
||||
|
||||
class TeleportSpell < Spell
|
||||
attr_reader :ancient, :destination, :experience, :name
|
||||
|
||||
def initialize(ancient, level, elements, destination, experience, name)
|
||||
super(level, elements, experience)
|
||||
@ancient = ancient
|
||||
@destination = destination
|
||||
@name = name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class TeleportingAction < SpellAction
|
||||
|
||||
def initialize(mob, spell)
|
||||
super(mob, spell)
|
||||
end
|
||||
|
||||
def execute_action
|
||||
@spell.ancient ? execute_ancient : execute_modern
|
||||
end
|
||||
|
||||
def execute_modern
|
||||
if @pulses == 0
|
||||
mob.play_animation(MODERN_TELE_ANIM)
|
||||
elsif @pulses == 1
|
||||
mob.play_graphic(MODERN_TELE_GRAPHIC)
|
||||
delay = 1
|
||||
elsif @pulses == 2
|
||||
mob.stop_graphic
|
||||
mob.play_animation(MODERN_TELE_END_ANIM)
|
||||
mob.teleport(@spell.destination)
|
||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
def execute_ancient
|
||||
if @pulses == 0
|
||||
mob.play_graphic(ANCIENT_TELE_GRAPHIC)
|
||||
mob.play_animation(ANCIENT_TELE_ANIM)
|
||||
delay = 2
|
||||
elsif @pulses == 2
|
||||
mob.stop_graphic
|
||||
mob.stop_animation
|
||||
mob.teleport(@spell.destination)
|
||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def append_tele(ancient, button, level, elements, x, y, experience, name)
|
||||
TELEPORT_SPELLS[button] = TeleportSpell.new(ancient, level, elements, Position.new(x, y), experience, name)
|
||||
end
|
||||
|
||||
# Modern teleports
|
||||
append_tele(false, 1164, 25, { FIRE => 1, AIR => 3, LAW => 1 }, 3213, 3424, 35, "Varrock")
|
||||
append_tele(false, 1167, 31, { EARTH => 1, AIR => 3, LAW => 1 }, 3222, 3219, 41, "Lumbridge")
|
||||
append_tele(false, 1170, 37, { WATER => 1, AIR => 3, LAW => 1 }, 2965, 3379, 47, "Falador")
|
||||
append_tele(false, 1174, 45, { AIR => 5, LAW => 1 }, 2757, 3478, 55.5, "Camelot")
|
||||
append_tele(false, 1540, 51, { WATER => 2, LAW => 2 }, 2662, 3306, 61, "Ardougne")
|
||||
append_tele(false, 1541, 58, { EARTH => 2, LAW => 2 }, 2549, 3114, 68, "the Watchtower")
|
||||
append_tele(false, 7455, 61, { FIRE => 2, LAW => 2 }, 2871, 3590, 68, "Trollheim")
|
||||
append_tele(false, 18470, 64, { FIRE => 2, WATER => 2, LAW => 2, Element.new([1963], nil, "Banana") => 1 }, 2754, 2785, 76, "Ape Atoll")
|
||||
|
||||
# Ancient teleports
|
||||
append_tele(true, 13035, 54, { LAW => 2, FIRE => 1, AIR => 1 }, 3098, 9882, 64, "Paddewwa")
|
||||
append_tele(true, 13045, 60, { LAW => 2, SOUL => 2 }, 3320, 3338, 70, "Senntisten")
|
||||
append_tele(true, 13053, 66, { LAW => 2, BLOOD => 1 }, 3493, 3472, 76, "Kharyll")
|
||||
append_tele(true, 13061, 72, { LAW => 2, WATER => 4 }, 3003, 3470, 82, "Lassar")
|
||||
append_tele(true, 13069, 78, { LAW => 2, FIRE => 3, AIR => 2 }, 2966, 3696, 88, "Dareeyak")
|
||||
append_tele(true, 13079, 84, { LAW => 2, SOUL => 2 }, 3163, 3664, 94, "Carrallangar")
|
||||
append_tele(true, 13087, 90, { LAW => 2, BLOOD => 2 }, 3287, 3883, 100, "Annakarl")
|
||||
append_tele(true, 13095, 96, { LAW => 2, WATER => 8 }, 2972, 3873, 106, "Ghorrock")
|
||||
@@ -0,0 +1,19 @@
|
||||
GEMSTONES = {}
|
||||
|
||||
class Gemstone
|
||||
attr_reader :id, :chance
|
||||
|
||||
def initialize(id, chance)
|
||||
@id = id
|
||||
@chance = chance
|
||||
end
|
||||
end
|
||||
|
||||
def append_gem(gem)
|
||||
GEMSTONES[gem.id] = gem
|
||||
end
|
||||
|
||||
append_gem(Gemstone.new(1623, 0)) # uncut sapphire
|
||||
append_gem(Gemstone.new(1605, 0)) # uncut emerald
|
||||
append_gem(Gemstone.new(1619, 0)) # uncut ruby
|
||||
append_gem(Gemstone.new(1617, 0)) # uncut diamond
|
||||
@@ -0,0 +1,162 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.action.DistancedAction'
|
||||
java_import 'org.apollo.game.model.EquipmentConstants'
|
||||
java_import 'org.apollo.game.model.def.ItemDefinition'
|
||||
|
||||
PROSPECT_PULSES = 3
|
||||
ORE_SIZE = 1
|
||||
|
||||
# TODO: finish implementing this
|
||||
class MiningAction < DistancedAction
|
||||
attr_reader :position, :ore, :counter, :started
|
||||
|
||||
def initialize(mob, position, ore)
|
||||
super(0, true, mob, position, ORE_SIZE)
|
||||
@position = position
|
||||
@ore = ore
|
||||
@started = false
|
||||
@counter = 0
|
||||
end
|
||||
|
||||
def find_pickaxe
|
||||
PICKAXE_IDS.each do |id|
|
||||
weapon = mob.equipment.get(EquipmentConstants::WEAPON)
|
||||
if weapon != nil && weapon.id == id
|
||||
return PICKAXES[id]
|
||||
end
|
||||
|
||||
if mob.inventory.contains(id)
|
||||
return PICKAXES[id]
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
# starts the mining animation, sets counters/flags and turns the mob to
|
||||
# the ore
|
||||
def start_mine(pickaxe)
|
||||
@started = true
|
||||
mob.send_message('You swing your pick at the rock.', true)
|
||||
mob.turn_to(@position)
|
||||
mob.play_animation(pickaxe.animation)
|
||||
@counter = pickaxe.pulses
|
||||
end
|
||||
|
||||
def executeAction
|
||||
skills = mob.skill_set
|
||||
level = skills.get_skill(MINING_SKILL_ID).current_level
|
||||
pickaxe = find_pickaxe
|
||||
|
||||
# verify the mob can mine with their pickaxe
|
||||
unless (pickaxe != nil and level >= pickaxe.level)
|
||||
mob.send_message('You do not have a pickaxe for which you have the level to use.')
|
||||
stop
|
||||
return
|
||||
end
|
||||
|
||||
# verify the mob can mine the ore
|
||||
if ore.level > level
|
||||
mob.send_message('You do not have the required level to mine this rock.')
|
||||
stop
|
||||
return
|
||||
end
|
||||
|
||||
# check if we need to kick start things
|
||||
unless @started
|
||||
start_mine(pickaxe)
|
||||
else
|
||||
# count down and check if we can have a chance at some ore now
|
||||
if @counter == 0
|
||||
# TODO: calculate the chance that the mob can actually get the rock
|
||||
|
||||
if mob.inventory.add(ore.id)
|
||||
ore_def = ItemDefinition.lookup(@ore.id) # TODO: split off into some method
|
||||
name = ore_def.name.sub(/ ore$/, '').downcase
|
||||
|
||||
mob.send_message("You manage to mine some #{name}.")
|
||||
skills.add_experience(MINING_SKILL_ID, ore.exp)
|
||||
# TODO: expire the rock
|
||||
end
|
||||
|
||||
stop
|
||||
end
|
||||
@counter -= 1
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class and @position == other.position and @ore == other.ore)
|
||||
end
|
||||
end
|
||||
|
||||
class ExpiredProspectingAction < DistancedAction
|
||||
attr_reader :position
|
||||
|
||||
def initialize(mob, position)
|
||||
super(0, true, mob, position, ORE_SIZE)
|
||||
end
|
||||
|
||||
def executeAction
|
||||
mob.send_message('There is currently no ore available in this rock.')
|
||||
stop
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class and @position == other.position)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ProspectingAction < DistancedAction
|
||||
attr_reader :position, :ore
|
||||
|
||||
def initialize(mob, position, ore)
|
||||
super(PROSPECT_PULSES, true, mob, position, ORE_SIZE)
|
||||
@position = position
|
||||
@ore = ore
|
||||
@started = false
|
||||
end
|
||||
|
||||
def executeAction
|
||||
if not @started
|
||||
@started = true
|
||||
|
||||
mob.send_message('You examine the rock for ores...')
|
||||
mob.turn_to(@position)
|
||||
else
|
||||
ore_def = ItemDefinition.lookup(@ore.id)
|
||||
name = ore_def.name.sub(/ ore$/, '').downcase
|
||||
|
||||
mob.send_message("This rock contains #{name}.")
|
||||
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class and @position == other.position and @ore == other.ore)
|
||||
end
|
||||
end
|
||||
|
||||
on :event, :object_action do |ctx, mob, event|
|
||||
if event.option == 1
|
||||
ore = ORES[event.id]
|
||||
if ore != nil
|
||||
mob.start_action(MiningAction.new(mob, event.position, ore))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
on :event, :object_action do |ctx, mob, event|
|
||||
if event.option == 2
|
||||
ore = ORES[event.id]
|
||||
if ore != nil
|
||||
mob.start_action(ProspectingAction.new(mob, event.position, ore))
|
||||
elsif EXPIRED_ORES[event.id] != nil
|
||||
mob.start_action(ExpiredProspectingAction.new(mob, event.position))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,96 @@
|
||||
# Thanks to Mikey` <http://www.rune-server.org/members/mikey%60/> for helping
|
||||
# to find some of the item/object IDs, minimum levels and experiences.
|
||||
#
|
||||
# Thanks to Clifton <http://www.rune-server.org/members/clifton/> for helping
|
||||
# to find some of the expired object IDs.
|
||||
|
||||
ORES = {}
|
||||
EXPIRED_ORES = {}
|
||||
|
||||
class Ore
|
||||
attr_reader :id, :objects, :level, :exp, :respawn
|
||||
|
||||
def initialize(id, objects, level, exp, respawn)
|
||||
@id = id
|
||||
@objects = objects
|
||||
@level = level
|
||||
@exp = exp
|
||||
@respawn = respawn
|
||||
end
|
||||
end
|
||||
|
||||
def append_ore(ore)
|
||||
ore.objects.each do |obj, expired_obj|
|
||||
ORES[obj] = ore
|
||||
EXPIRED_ORES[expired_obj] = true
|
||||
end
|
||||
end
|
||||
|
||||
CLAY_OBJECTS = {
|
||||
2180 => 450 , 2109 => 451 , 14904 => 14896, 14905 => 14897
|
||||
}
|
||||
|
||||
COPPER_OBJECTS = {
|
||||
11960 => 11555, 11961 => 11556, 11962 => 11557, 11936 => 11552,
|
||||
11937 => 11553, 11938 => 11554, 2090 => 450 , 2091 => 451 ,
|
||||
14906 => 14898, 14907 => 14899, 14856 => 14832, 14857 => 14833,
|
||||
14858 => 14834
|
||||
}
|
||||
|
||||
TIN_OBJECTS = {
|
||||
11597 => 11555, 11958 => 11556, 11959 => 11557, 11933 => 11552,
|
||||
11934 => 11553, 11935 => 11554, 2094 => 450 , 2095 => 451 ,
|
||||
14092 => 14894, 14903 => 14895
|
||||
}
|
||||
|
||||
IRON_OBJECTS = {
|
||||
11954 => 11555, 11955 => 11556, 11956 => 11557, 2092 => 450 ,
|
||||
2093 => 451 , 14900 => 14892, 14901 => 14893, 14913 => 14915,
|
||||
14914 => 14916
|
||||
}
|
||||
|
||||
COAL_OBJECTS = {
|
||||
11963 => 11555, 11964 => 11556, 11965 => 11557, 11930 => 11552,
|
||||
11931 => 11553, 11932 => 11554, 2096 => 450 , 2097 => 451 ,
|
||||
14850 => 14832, 14851 => 14833, 14852 => 14834
|
||||
}
|
||||
|
||||
SILVER_OBJECTS = {
|
||||
11948 => 11555, 11949 => 11556, 11950 => 11557, 2100 => 450 ,
|
||||
2101 => 451
|
||||
}
|
||||
|
||||
GOLD_OBJECTS = {
|
||||
11951 => 11555, 11952 => 11556, 11953 => 11557, 2098 => 450 ,
|
||||
2099 => 451
|
||||
}
|
||||
|
||||
MITHRIL_OBJECTS = {
|
||||
11945 => 11555, 11946 => 11556, 11947 => 11557, 11942 => 11552,
|
||||
11943 => 11553, 11944 => 11554, 2102 => 450 , 2103 => 451 ,
|
||||
14853 => 14832, 14854 => 14833, 14855 => 14834
|
||||
}
|
||||
|
||||
ADAMANT_OBJECTS = {
|
||||
11939 => 11552, 11940 => 11553, 11941 => 11554, 2104 => 450 ,
|
||||
2105 => 451 , 14862 => 14832, 14863 => 14833, 14864 => 14834
|
||||
}
|
||||
|
||||
RUNITE_OBJECTS = {
|
||||
2106 => 450 , 2107 => 451 , 14859 => 14832, 14860 => 14833,
|
||||
14861 => 14834
|
||||
}
|
||||
|
||||
append_ore Ore.new(434, CLAY_OBJECTS, 1, 5, 3 ) # clay
|
||||
append_ore Ore.new(436, COPPER_OBJECTS, 1, 17.5, 6 ) # copper ore
|
||||
append_ore Ore.new(438, TIN_OBJECTS, 1, 17.5, 6 ) # tin ore
|
||||
append_ore Ore.new(440, IRON_OBJECTS, 15, 35, 16 ) # iron ore
|
||||
append_ore Ore.new(453, COAL_OBJECTS, 30, 50, 100 ) # coal
|
||||
append_ore Ore.new(444, GOLD_OBJECTS, 40, 65, 200 ) # gold ore
|
||||
append_ore Ore.new(442, SILVER_OBJECTS, 20, 40, 200 ) # silver ore
|
||||
append_ore Ore.new(447, MITHRIL_OBJECTS, 55, 80, 400 ) # mithril ore
|
||||
append_ore Ore.new(449, ADAMANT_OBJECTS, 70, 95, 800 ) # adamant ore
|
||||
append_ore Ore.new(451, RUNITE_OBJECTS, 85, 125, 2500) # runite ore
|
||||
|
||||
# TODO: rune essence object id = 2491
|
||||
# level 1, exp 5, rune ess = 1436, pure ess = 7936
|
||||
@@ -0,0 +1,32 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
|
||||
PICKAXES = {}
|
||||
PICKAXE_IDS = []
|
||||
|
||||
class Pickaxe
|
||||
attr_reader :id, :level, :animation, :pulses
|
||||
|
||||
def initialize(id, level, animation, pulses)
|
||||
@id = id
|
||||
@level = level
|
||||
@animation = Animation.new(animation)
|
||||
@pulses = pulses
|
||||
end
|
||||
end
|
||||
|
||||
def append_pickaxe(pickaxe)
|
||||
PICKAXES[pickaxe.id] = pickaxe
|
||||
PICKAXE_IDS << pickaxe.id # tacky way of keeping things in order
|
||||
end
|
||||
|
||||
# NOTE: ADD LOWER LEVEL PICKAXES FIRST
|
||||
append_pickaxe(Pickaxe.new(1265, 1, 625, 8)) # bronze pickaxe
|
||||
append_pickaxe(Pickaxe.new(1267, 1, 626, 7)) # iron pickaxe
|
||||
append_pickaxe(Pickaxe.new(1269, 1, 627, 6)) # steel pickaxe
|
||||
append_pickaxe(Pickaxe.new(1273, 21, 629, 5)) # mithril pickaxe
|
||||
append_pickaxe(Pickaxe.new(1271, 31, 628, 4)) # adamant pickaxe
|
||||
append_pickaxe(Pickaxe.new(1275, 41, 624, 3)) # rune pickaxe
|
||||
|
||||
PICKAXE_IDS.reverse!
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0"?>
|
||||
<plugin>
|
||||
<id>skill-mining</id>
|
||||
<version>1</version>
|
||||
<name>Mining</name>
|
||||
<description>Adds the mining skill.</description>
|
||||
<authors>
|
||||
<author>Graham</author>
|
||||
<author>Mikey`</author>
|
||||
<author>WH:II:DOW</author>
|
||||
<author>Requa</author>
|
||||
<author>Clifton</author>
|
||||
</authors>
|
||||
<scripts>
|
||||
<script>pickaxe.rb</script>
|
||||
<script>ore.rb</script>
|
||||
<script>gem.rb</script>
|
||||
<script>respawn.rb</script>
|
||||
<script>mining.rb</script>
|
||||
</scripts>
|
||||
<dependencies />
|
||||
</plugin>
|
||||
@@ -0,0 +1,16 @@
|
||||
# Calculates the number of pulses it takes for an ore to respawn based on the
|
||||
# number of players currently online.
|
||||
#
|
||||
# The 'base' argument is the number of pulses it takes with no players online.
|
||||
# The 'players' argument is the number of players currently logged into the
|
||||
# current world.
|
||||
#
|
||||
# The base times can be found on this website:
|
||||
# http://runescape.salmoneus.net/mining.html#respawn
|
||||
#
|
||||
# These must be converted to pulses (seconds * 10 / 6) to work with this
|
||||
# function. The rest of the mining plugin rounds the base respawn times in
|
||||
# pulses down where appropriate.
|
||||
def respawn_pulses(base, players)
|
||||
base - players * base / (World.world.player_repository.size * 2)
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.action.Action'
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Skill'
|
||||
|
||||
BURY_BONE_ANIMATION = 827
|
||||
BONES = {}
|
||||
|
||||
# Represents a bone with a name, id, and experience.
|
||||
class Bone
|
||||
attr_reader :id, :exp
|
||||
|
||||
def initialize(id, exp)
|
||||
@id = id
|
||||
@exp = exp
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# An action where a bone in a player's inventory is buried.
|
||||
class BuryBoneAction < Action
|
||||
|
||||
def initialize(mob, slot, bone)
|
||||
super(1, false, mob)
|
||||
@slot = slot
|
||||
@bone = bone
|
||||
|
||||
mob.play_animation(Animation.new(BURY_BONE_ANIMATION))
|
||||
mob.send_message('You dig a hole in the ground...')
|
||||
end
|
||||
|
||||
def execute
|
||||
if mob.inventory.get(@slot).id == @bone.id
|
||||
mob.send_message('You bury the bones.')
|
||||
mob.inventory.reset(@slot)
|
||||
mob.skill_set.add_experience(Skill::PRAYER, @bone.exp)
|
||||
end
|
||||
stop
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Intercepts the first item option event,
|
||||
on :event, :item_option do |ctx, player, event|
|
||||
if event.option == 1
|
||||
bone = BONES[event.id]
|
||||
unless bone == nil
|
||||
player.start_action(BuryBoneAction.new(player, event.slot, bone))
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Appends a bone to the array
|
||||
def append_bone(hash)
|
||||
raise 'Hash must contain an id and an experience value.' unless hash.has_key?(:id) && hash.has_key?(:experience)
|
||||
id = hash[:id]
|
||||
BONES[id] = Bone.new(id, hash[:experience])
|
||||
end
|
||||
|
||||
append_bone :name => :regular_bones, :id => 526, :experience => 5
|
||||
append_bone :name => :burnt_bones, :id => 528, :experience => 5
|
||||
append_bone :name => :bat_bones, :id => 530, :experience => 4
|
||||
append_bone :name => :big_bones, :id => 532, :experience => 45
|
||||
append_bone :name => :babydragon_bones, :id => 534, :experience => 30
|
||||
append_bone :name => :dragon_bones, :id => 536, :experience => 72
|
||||
append_bone :name => :wolf_bones, :id => 2859, :experience => 14
|
||||
append_bone :name => :shaikahan_bones, :id => 3123, :experience => 25
|
||||
append_bone :name => :jogre_bones, :id => 3125, :experience => 15
|
||||
append_bone :name => :burnt_zogre_bones, :id => 3127, :experience => 25
|
||||
append_bone :name => :monkey_bones, :id => 3179, :experience => 14 # smallish
|
||||
append_bone :name => :monkey_bones, :id => 3180, :experience => 14 # medium
|
||||
append_bone :name => :monkey_bones, :id => 3181, :experience => 14 # quite large
|
||||
append_bone :name => :monkey_bones, :id => 3182, :experience => 14 # quite large
|
||||
append_bone :name => :monkey_bones, :id => 3183, :experience => 14 # small
|
||||
append_bone :name => :shaking_bones, :id => 3187, :experience => 14
|
||||
append_bone :name => :zogre_bones, :id => 4812, :experience => 23
|
||||
append_bone :name => :fayrg_bones, :id => 4830, :experience => 84
|
||||
append_bone :name => :raurg_bones, :id => 4832, :experience => 96
|
||||
append_bone :name => :ourg_bones, :id => 4834, :experience => 140
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<plugin>
|
||||
<id>skill-prayer</id>
|
||||
<version>1</version>
|
||||
<name>Prayer</name>
|
||||
<description>Adds the Prayer skill.</description>
|
||||
<authors>
|
||||
<author>Major</author>
|
||||
<author>010253</author>
|
||||
</authors>
|
||||
<scripts>
|
||||
<script>bury.rb</script>
|
||||
</scripts>
|
||||
<dependencies />
|
||||
</plugin>
|
||||
@@ -0,0 +1,89 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.action.DistancedAction'
|
||||
java_import 'org.apollo.game.model.Position'
|
||||
|
||||
PORTALS = {}
|
||||
ENTRANCE_ALTARS = {}
|
||||
CRAFTING_ALTARS = {}
|
||||
|
||||
# Represents a runecrafting altar.
|
||||
class Altar
|
||||
attr_reader :entrance_altar, :crafting_altar, :portal_id, :entrance_position, :exit_position, :crafting_centre
|
||||
|
||||
def initialize(entrance_altar, crafting_altar, portal_id, entrance_position, exit_position,crafting_centre)
|
||||
@entrance_altar = entrance_altar
|
||||
@altar = crafting_altar
|
||||
@portal_id = portal_id
|
||||
@entrance_position = entrance_position
|
||||
@exit_position = exit_position
|
||||
@crafting_centre = crafting_centre
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Intercepts the item on object event.
|
||||
on :event, :item_on_object do |ctx, player, event|
|
||||
talisman = TALISMANS[event.id]; altar = ENTRANCE_ALTARS[event.object_id]
|
||||
if (talisman != nil && altar != nil)
|
||||
player.start_action(TeleportAction.new(player, event.position, 2, altar.entrance_position))
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
end
|
||||
|
||||
# Intercepts the first object action event.
|
||||
on :event, :object_action do |ctx, player, event|
|
||||
if (event.option == 1)
|
||||
object_id = event.id
|
||||
if (altar = PORTALS[object_id]) != nil # Get the altar associated with this exit portal.
|
||||
player.start_action(TeleportAction.new(player, altar.entrance_position, 1, altar.exit_position))
|
||||
elsif (rune = RUNES[object_id]) != nil # Get the rune associated with this altar.
|
||||
altar = CRAFTING_ALTARS[object_id]
|
||||
player.start_action(RunecraftingAction.new(player, rune, altar.crafting_centre))
|
||||
end
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# An action that causes a mob to teleport when it comes within the specified distance of a specified position.
|
||||
class TeleportAction < DistancedAction
|
||||
attr_reader :teleport_position
|
||||
|
||||
def initialize(mob, position, distance, teleport_position)
|
||||
super(0, true, mob, position, distance)
|
||||
@teleport_position = teleport_position
|
||||
end
|
||||
|
||||
def executeAction
|
||||
mob.teleport(@teleport_position)
|
||||
stop
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class && mob == other.mob && @teleport_position == other.teleport_position)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Appends an altar to the list.
|
||||
def append_altar(hash)
|
||||
#raise 'Hash must contain an entrance altar id, crafting altar id, entrance portal position, and altar centre position.'
|
||||
entrance_altar = hash[:entrance_altar]; crafting_altar = hash[:crafting_altar]; portal_id = hash[:exit_portal]; entrance_position = hash[:entrance_position]; exit_position = hash[:exit_position]; altar_centre = hash[:altar_centre]
|
||||
|
||||
PORTALS[portal_id] = ENTRANCE_ALTARS[entrance_altar] = CRAFTING_ALTARS[crafting_altar] = Altar.new(entrance_altar, crafting_altar, portal_id, Position.new(*entrance_position), Position.new(*exit_position), Position.new(*altar_centre))
|
||||
end
|
||||
|
||||
# Appends an altar to the list.
|
||||
append_altar :name => :air_altar, :entrance_altar => 2452, :crafting_altar => 2478, :exit_portal => 2465, :entrance_position => [ 2841, 4829 ], :exit_position => [ 2983, 3292 ], :altar_centre => [ 2844, 4834 ]
|
||||
append_altar :name => :mind_altar, :entrance_altar => 2453, :crafting_altar => 2479, :exit_portal => 2466, :entrance_position => [ 2793, 4828 ], :exit_position => [ 2980, 3514 ], :altar_centre => [ 2786, 4841 ]
|
||||
append_altar :name => :water_altar, :entrance_altar => 2454, :crafting_altar => 2480, :exit_portal => 2467, :entrance_position => [ 2726, 4832 ], :exit_position => [ 3187, 3166 ], :altar_centre => [ 2716, 4836 ]
|
||||
append_altar :name => :earth_altar, :entrance_altar => 2455, :crafting_altar => 2481, :exit_portal => 2468, :entrance_position => [ 2655, 4830 ], :exit_position => [ 3304, 3474 ], :altar_centre => [ 2658, 4841 ]
|
||||
append_altar :name => :fire_altar, :entrance_altar => 2456, :crafting_altar => 2482, :exit_portal => 2469, :entrance_position => [ 2574, 4849 ], :exit_position => [ 3311, 3256 ], :altar_centre => [ 2585, 4838 ]
|
||||
append_altar :name => :body_altar, :entrance_altar => 2457, :crafting_altar => 2483, :exit_portal => 2470, :entrance_position => [ 2524, 4825 ], :exit_position => [ 3051, 3445 ], :altar_centre => [ 2525, 4832 ]
|
||||
append_altar :name => :cosmic_altar, :entrance_altar => 2458, :crafting_altar => 2484, :exit_portal => 2471, :entrance_position => [ 2142, 4813 ], :exit_position => [ 2408, 4379 ], :altar_centre => [ 2142, 4833 ]
|
||||
append_altar :name => :law_altar, :entrance_altar => 2459, :crafting_altar => 2485, :exit_portal => 2472, :entrance_position => [ 2464, 4818 ], :exit_position => [ 2858, 3379 ], :altar_centre => [ 2464, 4832 ]
|
||||
append_altar :name => :nature_altar, :entrance_altar => 2460, :crafting_altar => 2486, :exit_portal => 2473, :entrance_position => [ 2400, 4835 ], :exit_position => [ 2867, 3019 ], :altar_centre => [ 2400, 4841 ]
|
||||
append_altar :name => :chaos_altar, :entrance_altar => 2461, :crafting_altar => 2487, :exit_portal => 2474, :entrance_position => [ 2268, 4842 ], :exit_position => [ 3058, 3591 ], :altar_centre => [ 2271, 4842 ]
|
||||
append_altar :name => :death_altar, :entrance_altar => 2462, :crafting_altar => 2488, :exit_portal => 2475, :entrance_position => [ 2208, 4830 ], :exit_position => [ 3222, 3222 ], :altar_centre => [ 2205, 4836 ]
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<plugin>
|
||||
<id>skill-runecraft</id>
|
||||
<version>0.9</version>
|
||||
<name>Runecraft</name>
|
||||
<description>Adds the Runecraft skill.</description>
|
||||
<authors>
|
||||
<author>Major</author>
|
||||
</authors>
|
||||
<scripts>
|
||||
<script>altar.rb</script>
|
||||
<script>rune.rb</script>
|
||||
<script>runecraft.rb</script>
|
||||
<script>talisman.rb</script>
|
||||
</scripts>
|
||||
<dependencies />
|
||||
</plugin>
|
||||
@@ -0,0 +1,47 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.def.ItemDefinition'
|
||||
|
||||
# The list of runes.
|
||||
RUNES = {}
|
||||
|
||||
# Represents a rune that can be crafted.
|
||||
class Rune
|
||||
attr_reader :name, :id, :level, :experience
|
||||
|
||||
def initialize(id, level, experience, multiplier)
|
||||
@id = id
|
||||
@name = ItemDefinition.lookup(id).name.downcase
|
||||
@level = level
|
||||
@experience = experience
|
||||
@multiplier = multiplier
|
||||
end
|
||||
|
||||
def multiplier(level)
|
||||
return @multiplier.call(level)
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class && id == other.id)
|
||||
end
|
||||
end
|
||||
|
||||
# Appends a rune to the list.
|
||||
def append_rune(hash)
|
||||
raise 'Hash must contain an id, experience, .' unless hash.has_key?(:id) && hash.has_key?(:level) && hash.has_key?(:experience) && hash.has_key?(:multiplier)
|
||||
id = hash[:id]; altar = hash[:altar]; level = hash[:level]; experience = hash[:experience]; multiplier = hash[:multiplier]
|
||||
|
||||
RUNES[altar] = Rune.new(id, level, experience, multiplier)
|
||||
end
|
||||
|
||||
append_rune :name => :air_rune, :altar => 2478, :id => 556, :level => 1, :experience => 5, :multiplier => lambda { |level| (level / 11).floor + 1 }
|
||||
append_rune :name => :mind_rune, :altar => 2479, :id => 558, :level => 1, :experience => 5.5, :multiplier => lambda { |level| (level / 14).floor + 1 }
|
||||
append_rune :name => :water_rune, :altar => 2480, :id => 555, :level => 5, :experience => 6, :multiplier => lambda { |level| (level / 19).floor + 1 }
|
||||
append_rune :name => :earth_rune, :altar => 2481, :id => 557, :level => 9, :experience => 6.5, :multiplier => lambda { |level| (level / 26).floor + 1 }
|
||||
append_rune :name => :fire_rune, :altar => 2482, :id => 554, :level => 14, :experience => 7, :multiplier => lambda { |level| (level / 35).floor + 1 }
|
||||
append_rune :name => :body_rune, :altar => 2483, :id => 559, :level => 20, :experience => 7.5, :multiplier => lambda { |level| (level / 46).floor + 1 }
|
||||
append_rune :name => :cosmic_rune, :altar => 2484, :id => 564, :level => 27, :experience => 8, :multiplier => lambda { |level| level >= 59 ? 2 : 1 }
|
||||
append_rune :name => :chaos_rune, :altar => 2487, :id => 562, :level => 35, :experience => 8.5, :multiplier => lambda { |level| level >= 74 ? 2 : 1 }
|
||||
append_rune :name => :nature_rune, :altar => 2486, :id => 561, :level => 44, :experience => 9, :multiplier => lambda { |level| level >= 91 ? 2 : 1 }
|
||||
append_rune :name => :law_rune, :altar => 2485, :id => 563, :level => 54, :experience => 9.5, :multiplier => lambda { |level| 1 }
|
||||
append_rune :name => :death_rune, :altar => 2488, :id => 560, :level => 65, :experience => 10, :multiplier => lambda { |level| 1 }
|
||||
@@ -0,0 +1,53 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.action.DistancedAction'
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Graphic'
|
||||
|
||||
RUNECRAFTING_ANIMATION = Animation.new(791)
|
||||
RUNECRAFTING_GRAPHIC = Graphic.new(186, 0, 100)
|
||||
|
||||
RUNE_ESSENCE_ID = 1436
|
||||
|
||||
# An action when the player crafts a rune.
|
||||
class RunecraftingAction < DistancedAction
|
||||
attr_reader :player, :rune
|
||||
|
||||
def initialize(player, rune, object_position)
|
||||
super(1, true, player, object_position, 3)
|
||||
@player = player
|
||||
@rune = rune
|
||||
@position = object_position
|
||||
@executions = 0
|
||||
end
|
||||
|
||||
def executeAction
|
||||
runecrafting_level = @player.skill_set.get_skill(RUNECRAFT_SKILL_ID).current_level
|
||||
|
||||
if (runecrafting_level < @rune.level)
|
||||
@player.send_message("You need a runecrafting level of #{@rune.level} to craft this rune.")
|
||||
stop
|
||||
elsif !@player.inventory.contains(RUNE_ESSENCE_ID)
|
||||
@player.send_message('You need rune essence to craft runes.')
|
||||
stop
|
||||
elsif @executions == 0
|
||||
@player.turn_to(@position)
|
||||
@player.play_animation(RUNECRAFTING_ANIMATION)
|
||||
@player.play_graphic(RUNECRAFTING_GRAPHIC)
|
||||
@executions += 1
|
||||
elsif @executions == 1
|
||||
removed = @player.inventory.remove(RUNE_ESSENCE_ID, @player.inventory.get_amount(RUNE_ESSENCE_ID))
|
||||
added = removed * @rune.multiplier(runecrafting_level)
|
||||
@player.inventory.add(@rune.id, added)
|
||||
|
||||
@player.send_message("Your craft the rune essence into #{added > 1 ? 'some ' + @rune.name + 's' : 'an ' + @rune.name}.", true)
|
||||
@player.skill_set.add_experience(RUNECRAFT_SKILL_ID, removed * @rune.experience)
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
def equals(other)
|
||||
return (get_class == other.get_class && @player == other.player && @rune == other.rune)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Position'
|
||||
|
||||
# The list of talismans.
|
||||
TALISMANS = {}
|
||||
|
||||
# A talisman that will indicate a direction when activated.
|
||||
class Talisman
|
||||
|
||||
def initialize(entrance_altar_position)
|
||||
@locate_position = entrance_altar_position
|
||||
end
|
||||
|
||||
def get_message(player_position)
|
||||
return 'Your talisman glows brightly.' if player_position.is_within_distance(@locate_position, 10)
|
||||
|
||||
direction = (player_position.y > @locate_position.y ? 'North' : 'South') + '-' + (player_position.x > @locate_position.x ? 'East' : 'West')
|
||||
return "The talisman pulls toward the #{direction}."
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Appends a talisman to the list.
|
||||
def append_talisman(hash)
|
||||
raise 'Hash must contain an id and an altar position.' unless hash.has_key?(:id) && hash.has_key?(:altar)
|
||||
id = hash[:id]; altar_position = Position.new(*hash[:altar])
|
||||
|
||||
TALISMANS[id] = Talisman.new(altar_position)
|
||||
end
|
||||
|
||||
# Intercepts the item option event.
|
||||
on :event, :item_option do |ctx, player, event|
|
||||
if (event.option == 4)
|
||||
talisman = TALISMANS[event.id]
|
||||
if (talisman != nil)
|
||||
player.send_message(talisman.get_message(player.position))
|
||||
ctx.break_handler_chain
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Appends talismans to the list.
|
||||
append_talisman :name => :air_talisman, :id => 1438, :altar => [ 2985, 3292 ]
|
||||
append_talisman :name => :earth_talisman, :id => 1440, :altar => [ 3306, 3474 ]
|
||||
append_talisman :name => :fire_talisman, :id => 1442, :altar => [ 3313, 3255 ]
|
||||
append_talisman :name => :water_talisman, :id => 1444, :altar => [ 3185, 3165 ]
|
||||
append_talisman :name => :body_talisman, :id => 1446, :altar => [ 3053, 3445 ]
|
||||
append_talisman :name => :mind_talisman, :id => 1448, :altar => [ 2982, 3514 ]
|
||||
append_talisman :name => :chaos_talisman, :id => 1452, :altar => [ 3059, 3590 ]
|
||||
append_talisman :name => :cosmic_talisman, :id => 1454, :altar => [ 2408, 4377 ]
|
||||
append_talisman :name => :death_talisman, :id => 1456, :altar => [ 0, 0 ]
|
||||
append_talisman :name => :law_talisman, :id => 1458, :altar => [ 2858, 3381 ]
|
||||
append_talisman :name => :nature_talisman, :id => 1462, :altar => [ 2869, 3019 ]
|
||||
Reference in New Issue
Block a user