Add magic plugin, more decoders and commands.

This commit is contained in:
Major-
2013-11-03 23:48:17 +00:00
parent ac4c8408a3
commit 82b12e30a2
58 changed files with 1730 additions and 96 deletions
+70
View File
@@ -0,0 +1,70 @@
require 'java'
java_import 'org.apollo.game.model.Animation'
java_import 'org.apollo.game.model.Graphic'
ALCHEMY_SPELLS = {}
LOW_ALC_ANIM = Animation.new(712)
LOW_ALC_GFX = Graphic.new(112, 0, 100)
LOW_ALC_MULTIPLIER = 0.4
HIGH_ALC_ANIM = Animation.new(713)
HIGH_ALC_GFX = Graphic.new(113, 0, 100)
HIGH_ALC_MULTIPLIER = 0.6
ILLEGAL_ALC_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_ALC_ITEMS.include? @item.id
end
def execute_action
player = character
if @pulses == 0
player.play_animation(@spell.animation)
player.play_graphic(@spell.graphic)
player.send(DISPLAY_SPELLBOOK)
inventory = player.inventory
gold = (item.definition.value * @spell.multiplier)
inventory.remove(inventory.get(@slot).id, 1)
inventory.add(995, gold)
player.skill_set.add_experience(MAGIC_ID, @spell.experience)
set_delay(@spell.delay)
elsif @pulses == 1
player.stop_animation
player.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_ALC_ANIM, LOW_ALC_GFX, 0.48, 31, 1) # Low level alchemy
append_alchemy(1178, 55, { FIRE => 5, NATURE => 1 }, true, HIGH_ALC_ANIM, HIGH_ALC_GFX, 0.72, 65, 4) # High level alchemy
+91
View File
@@ -0,0 +1,91 @@
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_GFX = 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
player = character
if @pulses == 0
player.play_animation CONVERT_ANIM
player.play_graphic CONVERT_GFX
inventory = player.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
player.skill_set.add_experience MAGIC_ID, @spell.experience
set_delay 2
elsif @pulses == 1
player.stop_animation
player.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]
if item != nil and item.id == BONES_ID
slots << slot
end
counter += 1
end
return slots
end
def append_convert(button, level, elements, experience, reward)
convert = ConvertSpell.new(level, elements, experience, reward)
CONVERT_SPELLS[button] = convert
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
+110
View File
@@ -0,0 +1,110 @@
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")
+111
View File
@@ -0,0 +1,111 @@
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
player = character
if @pulses == 0
player.play_animation @spell.animation
player.play_graphic @spell.graphic
player.send DISPLAY_SPELLBOOK
player.inventory.set @slot, @reward
player.skill_set.add_experience MAGIC_ID, @spell.experience
set_delay @spell.delay
elsif @pulses == 1
player.stop_animation
player.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
+159
View File
@@ -0,0 +1,159 @@
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'
MAGIC_ID = Skill::MAGIC
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(character, spell)
super(0, true, character)
@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 > character.skill_set.skill(MAGIC_ID).maximum_level
character.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(character, amount, false)
character.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(character, 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(character, spell, slot, item)
super(character, 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?
character.send_message "You cannot use that spell on this item!"
stop
return
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(character, amount + 1, false)
character.send_message("You do not have enough " + element.name + "s to cast this spell.")
stop
return
end
end
end
end
super
end
def illegal_item?
# Override this method if necessary
return false
end
end
# MagicOnItemEvent handling
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
# ButtonEvent handling
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
+20
View File
@@ -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>
+96
View File
@@ -0,0 +1,96 @@
# 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_GFX = Graphic.new(308, 15, 100)
ANCIENT_TELE_END_GFX = Graphic.new(455)
ANCIENT_TELE_ANIM = Animation.new(1979)
ANCIENT_TELE_GFX = 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(character, spell)
super(character, spell)
end
def execute_action
@spell.ancient ? execute_modern : execute_ancient
end
def execute_modern
player = character
if @pulses == 0
player.play_animation(MODERN_TELE_ANIM)
elsif @pulses == 1
player.play_graphic(MODERN_TELE_GFX)
delay = 1
elsif @pulses == 2
player.stop_graphic
player.play_animation(MODERN_TELE_END_ANIM)
destination = @spell.destination
player.teleport(destination)
player.skill_set.add_experience(MAGIC_ID, @spell.experience)
stop
end
end
def execute_ancient
player = character
if @pulses == 0
player.play_graphic(ANCIENT_TELE_GFX)
player.play_animation(ANCIENT_TELE_ANIM)
delay = 2
elsif @pulses == 1
player.stop_graphic
player.stop_animation
player.teleport(@spell.destination)
player.skill_set.add_experience(MAGIC_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")