mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-05 16:49:04 +00:00
Merge branch 'master' of git@github.com:ryleykimmel/apollo.git
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
!.gitignore
|
!.gitignore
|
||||||
|
!.rubocop.yml
|
||||||
|
|
||||||
.*
|
.*
|
||||||
*~
|
*~
|
||||||
*.class
|
*.class
|
||||||
@@ -7,3 +9,4 @@
|
|||||||
/data/fs
|
/data/fs
|
||||||
/data/savedGames
|
/data/savedGames
|
||||||
/lib/
|
/lib/
|
||||||
|
*/target/
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
Style/GlobalVars:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/EmptyLinesAroundBlockBody:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Performance/ParallelAssignment:
|
||||||
|
Enabled: false
|
||||||
@@ -3,18 +3,14 @@ require 'java'
|
|||||||
java_import 'org.apollo.game.message.impl.DisplayCrossbonesMessage'
|
java_import 'org.apollo.game.message.impl.DisplayCrossbonesMessage'
|
||||||
java_import 'org.apollo.game.model.entity.Player'
|
java_import 'org.apollo.game.model.entity.Player'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Registers an area action.
|
# Registers an area action.
|
||||||
def area_action(name, &block)
|
def area_action(name, &block)
|
||||||
AREA_ACTIONS[name] = action = AreaAction.new
|
AREA_ACTIONS[name] = action = AreaAction.new
|
||||||
action.instance_eval(&block)
|
action.instance_eval(&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
AREA_ACTIONS = {}
|
AREA_ACTIONS = {}
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# An action that is called when a player enters or exits an area.
|
# An action that is called when a player enters or exits an area.
|
||||||
|
|||||||
+15
-16
@@ -4,19 +4,18 @@ java_import 'org.apollo.game.model.Position'
|
|||||||
java_import 'org.apollo.game.model.entity.EntityType'
|
java_import 'org.apollo.game.model.entity.EntityType'
|
||||||
java_import 'org.apollo.game.model.entity.Player'
|
java_import 'org.apollo.game.model.entity.Player'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Creates a new area and registers it with the supplied coordinates.
|
# Creates a new area and registers it with the supplied coordinates.
|
||||||
def area(hash)
|
def area(hash)
|
||||||
raise 'Hash must contain a name, coordinates, and actions pair.' unless hash.has_keys?(:name, :coordinates, :actions)
|
failure_message = 'Hash must contain a name, coordinates, and actions pair.'
|
||||||
name = hash[:name]; coordinates = hash[:coordinates]; actions = hash[:actions]
|
fail failure_message unless hash.has_keys?(:name, :coordinates, :actions)
|
||||||
|
|
||||||
actions = [ actions ] if actions.is_a?(Symbol)
|
name, coordinates, actions = hash[:name], hash[:coordinates], hash[:actions]
|
||||||
actions.map! { |action| AREA_ACTIONS[action]}
|
|
||||||
|
actions = [actions] if actions.is_a?(Symbol)
|
||||||
|
actions.map! { |action| AREA_ACTIONS[action] }
|
||||||
@areas << Area.new(name, coordinates, actions)
|
@areas << Area.new(name, coordinates, actions)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# A map of coordinates (as an array) to areas.
|
# A map of coordinates (as an array) to areas.
|
||||||
@@ -31,23 +30,23 @@ class Area
|
|||||||
@actions = actions
|
@actions = actions
|
||||||
end
|
end
|
||||||
|
|
||||||
def min_x() # TODO better data structure and methods than this
|
def min_x # TODO: better data structure and methods than this
|
||||||
@coordinates[0]
|
@coordinates[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
def min_y()
|
def min_y
|
||||||
@coordinates[1]
|
@coordinates[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_x()
|
def max_x
|
||||||
@coordinates[2]
|
@coordinates[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
def max_y()
|
def max_y
|
||||||
@coordinates[3]
|
@coordinates[3]
|
||||||
end
|
end
|
||||||
|
|
||||||
def height()
|
def height
|
||||||
@coordinates[4]
|
@coordinates[4]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -79,7 +78,7 @@ on :mob_position_update do |event|
|
|||||||
next_inside = event.next.inside(area)
|
next_inside = event.next.inside(area)
|
||||||
|
|
||||||
if was_inside
|
if was_inside
|
||||||
if next_inside then area.inside(mob) else area.exited(mob) end
|
next_inside ? area.inside(mob) : area.exited(mob)
|
||||||
else
|
else
|
||||||
area.entered(mob) if next_inside
|
area.entered(mob) if next_inside
|
||||||
end
|
end
|
||||||
@@ -91,10 +90,10 @@ class Position
|
|||||||
|
|
||||||
# Returns whether or not this Position is inside the specified Area.
|
# Returns whether or not this Position is inside the specified Area.
|
||||||
def inside(area)
|
def inside(area)
|
||||||
return false if (x < area.min_x() || x > area.max_x() || y < area.min_y() || y > area.max_y())
|
return false if x < area.min_x || x > area.max_x || y < area.min_y || y > area.max_y
|
||||||
z = area.height()
|
z = area.height
|
||||||
|
|
||||||
return true if (z.nil? || z == height)
|
z.nil? || z == height
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -7,7 +7,8 @@ BANK_BOOTH_ID = 2213
|
|||||||
BANK_BOOTH_SIZE = 1
|
BANK_BOOTH_SIZE = 1
|
||||||
|
|
||||||
# The npcs with a 'bank' menu action.
|
# The npcs with a 'bank' menu action.
|
||||||
BANKER_NPCS = [ 166, 494, 495, 496, 497, 498, 499, 1036, 1360, 1702, 2163, 2164, 2354, 2355, 2568, 2569, 2570 ]
|
BANKER_NPCS = [166, 494, 495, 496, 497, 498, 499, 1036, 1360, 1702, 2163, 2164, 2354, 2355, 2568,
|
||||||
|
2569, 2570]
|
||||||
|
|
||||||
# A distanced action to open a new bank.
|
# A distanced action to open a new bank.
|
||||||
class BankAction < DistancedAction
|
class BankAction < DistancedAction
|
||||||
@@ -25,7 +26,7 @@ class BankAction < DistancedAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @position == other.position)
|
get_class == other.get_class && @position == other.position
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+24
-24
@@ -1,7 +1,5 @@
|
|||||||
# A script to 'bootstrap' all of the other plugins, wrapping Apollo's verbose
|
# A script bootstrapper for the rest of the plugins, which wraps Apollo's
|
||||||
# Java-style API in a Ruby-style API.
|
# verbose Java-style API in a Ruby-style API.
|
||||||
#
|
|
||||||
# Written by Graham.
|
|
||||||
|
|
||||||
# ********************************** WARNING **********************************
|
# ********************************** WARNING **********************************
|
||||||
# * If you do not really understand what this is for, do not edit it without *
|
# * If you do not really understand what this is for, do not edit it without *
|
||||||
@@ -34,7 +32,7 @@ RIGHTS_STANDARD = PrivilegeLevel::STANDARD
|
|||||||
class String
|
class String
|
||||||
|
|
||||||
# Converts a ruby snake_case string to camel-case.
|
# Converts a ruby snake_case string to camel-case.
|
||||||
def camelize()
|
def camelize
|
||||||
gsub(/(?:^|_)(.)/) { $1.upcase }
|
gsub(/(?:^|_)(.)/) { $1.upcase }
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -68,8 +66,8 @@ class ProcEventListener
|
|||||||
|
|
||||||
# Executes the block handling the Event.
|
# Executes the block handling the Event.
|
||||||
def handle(event)
|
def handle(event)
|
||||||
args = [ event ]
|
args = [event]
|
||||||
args << event.player if event.kind_of?(PlayerEvent)
|
args << event.player if event.is_a?(PlayerEvent)
|
||||||
@block.call(*args)
|
@block.call(*args)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -87,7 +85,7 @@ class ProcMessageHandler < MessageHandler
|
|||||||
|
|
||||||
# Handles the message.
|
# Handles the message.
|
||||||
def handle(player, message)
|
def handle(player, message)
|
||||||
@block.call(player, message) if (@option == 0 || @option == message.option)
|
@block.call(player, message) if @option == 0 || @option == message.option
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -119,14 +117,15 @@ end
|
|||||||
# behaviour is undefined (and most likely it'll be bad).
|
# behaviour is undefined (and most likely it'll be bad).
|
||||||
def schedule(*args, &block)
|
def schedule(*args, &block)
|
||||||
if block_given?
|
if block_given?
|
||||||
raise 'Invalid combination of arguments.' unless (1..2).include?(args.length)
|
fail 'Invalid combination of arguments.' unless (1..2).include?(args.length)
|
||||||
delay = args[0]
|
delay = args[0]
|
||||||
|
|
||||||
immediate = args.length == 2 ? args[1] : false
|
immediate = args.length == 2 ? args[1] : false
|
||||||
$world.schedule(ProcScheduledTask.new(delay, immediate, block))
|
$world.schedule(ProcScheduledTask.new(delay, immediate, block))
|
||||||
elsif args.length == 1
|
elsif args.length == 1
|
||||||
$world.schedule(args[0])
|
$world.schedule(args[0])
|
||||||
else
|
else
|
||||||
raise 'Invalid combination of arguments.'
|
fail 'Invalid combination of arguments.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -153,15 +152,15 @@ def on(type, *args, &block)
|
|||||||
when :message then on_message(args, block)
|
when :message then on_message(args, block)
|
||||||
when :button then on_button(args, block)
|
when :button then on_button(args, block)
|
||||||
else
|
else
|
||||||
class_name = type.to_s.camelize.concat('Event')
|
class_name = type.to_s.camelize.concat('Event')
|
||||||
type = Java::JavaClass.for_name("org.apollo.game.model.event.impl.#{class_name}")
|
type = Java::JavaClass.for_name("org.apollo.game.model.event.impl.#{class_name}")
|
||||||
$world.listen_for(type, ProcEventListener.new(block))
|
$world.listen_for(type, ProcEventListener.new(block))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines an action to be taken upon a button press.
|
# Defines an action to be taken upon a button press.
|
||||||
def on_button(args, proc)
|
def on_button(args, proc)
|
||||||
raise 'Button must have one argument.' unless args.length == 1
|
fail 'Button must have one argument.' unless args.length == 1
|
||||||
|
|
||||||
id = args[0].to_i
|
id = args[0].to_i
|
||||||
|
|
||||||
@@ -171,24 +170,25 @@ def on_button(args, proc)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Defines an action to be taken upon a message.
|
# Defines an action to be taken upon a message.
|
||||||
# The message can either be a symbol with the lower-case underscored class name, or the class itself.
|
# The message can either be a symbol with the lowercase underscored class name, or the class itself.
|
||||||
def on_message(args, proc)
|
def on_message(args, proc)
|
||||||
raise 'Message must have one or two arguments.' unless (1..2).include?(args.length)
|
fail 'Message must have one or two arguments.' unless (1..2).include?(args.length)
|
||||||
numbers = [ 'first', 'second', 'third', 'fourth', 'fifth' ]
|
|
||||||
message = args[0]; option = 0
|
|
||||||
|
|
||||||
numbers.each_index do |index|
|
numbers = %w(first second third fourth fifth)
|
||||||
|
message = args[0].to_s
|
||||||
|
option = 0
|
||||||
|
|
||||||
|
(0..numbers.length).each do |index|
|
||||||
number = numbers[index]
|
number = numbers[index]
|
||||||
|
|
||||||
if message.to_s.start_with?(number)
|
if message.start_with?(number)
|
||||||
option = index + 1
|
option = index + 1
|
||||||
message = message[number.length + 1, message.length].to_sym
|
message = message[number.length + 1, message.length]
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class_name = message.camelize.concat('Message')
|
||||||
class_name = message.to_s.camelize.concat('Message')
|
|
||||||
message = Java::JavaClass.for_name("org.apollo.game.message.impl.#{class_name}")
|
message = Java::JavaClass.for_name("org.apollo.game.message.impl.#{class_name}")
|
||||||
|
|
||||||
$ctx.add_message_handler(message, ProcMessageHandler.new(proc, option))
|
$ctx.add_message_handler(message, ProcMessageHandler.new(proc, option))
|
||||||
@@ -196,7 +196,7 @@ end
|
|||||||
|
|
||||||
# Defines an action to be taken upon a command.
|
# Defines an action to be taken upon a command.
|
||||||
def on_command(args, proc)
|
def on_command(args, proc)
|
||||||
raise 'Command message must have one or two arguments.' unless (1..2).include?(args.length)
|
fail 'Command message must have one or two arguments.' unless (1..2).include?(args.length)
|
||||||
|
|
||||||
rights = args.length == 2 ? args[1] : RIGHTS_STANDARD
|
rights = args.length == 2 ? args[1] : RIGHTS_STANDARD
|
||||||
$world.command_dispatcher.register(args[0].to_s, ProcCommandListener.new(rights, proc))
|
$world.command_dispatcher.register(args[0].to_s, ProcCommandListener.new(rights, proc))
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ java_import 'org.apollo.game.model.entity.setting.ServerStatus'
|
|||||||
java_import 'org.apollo.game.model.entity.setting.PrivacyState'
|
java_import 'org.apollo.game.model.entity.setting.PrivacyState'
|
||||||
java_import 'org.apollo.game.model.entity.Player'
|
java_import 'org.apollo.game.model.entity.Player'
|
||||||
|
|
||||||
|
# Processes an add friend message, updating the logged-in status of the player (and the person they
|
||||||
|
# added) if necessary.
|
||||||
# Processes an add friend message, updating the logged-in status of the player (and the person they added) if necessary.
|
|
||||||
on :message, :add_friend do |player, message|
|
on :message, :add_friend do |player, message|
|
||||||
friend_username = message.username
|
friend_username = message.username
|
||||||
player_username = player.username
|
player_username = player.username
|
||||||
@@ -18,14 +17,23 @@ on :message, :add_friend do |player, message|
|
|||||||
player.add_friend(friend_username)
|
player.add_friend(friend_username)
|
||||||
friend = $world.get_player(friend_username)
|
friend = $world.get_player(friend_username)
|
||||||
|
|
||||||
if friend == nil # the friend the player added is offline
|
if friend.nil? # the friend the player added is offline
|
||||||
player.send(SendFriendMessage.new(friend_username, 0))
|
player.send(SendFriendMessage.new(friend_username, 0))
|
||||||
elsif friend.friends_with(player_username) # new friend already has the player added
|
elsif friend.friends_with(player_username)
|
||||||
friend.send(SendFriendMessage.new(player_username, player.world_id)) unless player.friend_privacy == PrivacyState::OFF # player's private chat state is not off, so notify the friend
|
|
||||||
|
|
||||||
player.send(SendFriendMessage.new(friend_username, friend.world_id)) unless friend.friend_privacy == PrivacyState::OFF # new friend's private chat state is not off, so notify the player
|
# player's private chat state is not off, so notify the friend
|
||||||
elsif friend.friend_privacy == PrivacyState::ON # new friend doesn't have the player added but their private chat state is on
|
unless player.friend_privacy == PrivacyState::OFF
|
||||||
player.send(SendFriendMessage.new(friend_username, friend.world_id)) # so we can let the player know what world they're on
|
friend.send(SendFriendMessage.new(player_username, player.world_id))
|
||||||
|
end
|
||||||
|
|
||||||
|
# new friend's private chat state is not off, so notify the player
|
||||||
|
unless friend.friend_privacy == PrivacyState::OFF
|
||||||
|
player.send(SendFriendMessage.new(friend_username, friend.world_id))
|
||||||
|
end
|
||||||
|
elsif friend.friend_privacy == PrivacyState::ON
|
||||||
|
# new friend doesn't have the player added but their private chat state is on, so inform the
|
||||||
|
# player of the world they are on.
|
||||||
|
player.send(SendFriendMessage.new(friend_username, friend.world_id))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -35,24 +43,28 @@ on :message, :remove_friend do |player, message|
|
|||||||
player_username = player.username
|
player_username = player.username
|
||||||
|
|
||||||
player.remove_friend(friend_username)
|
player.remove_friend(friend_username)
|
||||||
if ($world.is_player_online(friend_username))
|
if $world.is_player_online(friend_username)
|
||||||
friend = $world.get_player(friend_username)
|
friend = $world.get_player(friend_username)
|
||||||
friend.send(SendFriendMessage.new(player_username, 0)) if (friend.friends_with(player_username) && player.friend_privacy != PrivacyState::ON)
|
|
||||||
|
remove = friend.friends_with(player_username) && player.friend_privacy != PrivacyState::ON
|
||||||
|
friend.send(SendFriendMessage.new(player_username, 0)) if remove
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Update the friend server status and send the friend/ignore lists of the player logging in.
|
# Update the friend server status and send the friend/ignore lists of the player logging in.
|
||||||
on :login do |event, player|
|
on :login do |_event, player|
|
||||||
player.send(FriendServerStatusMessage.new(ServerStatus::CONNECTING))
|
player.send(FriendServerStatusMessage.new(ServerStatus::CONNECTING))
|
||||||
player.send(IgnoreListMessage.new(player.ignored_usernames)) if player.ignored_usernames.size > 0
|
player.send(IgnoreListMessage.new(player.ignored_usernames)) if player.ignored_usernames.size > 0
|
||||||
|
|
||||||
username = player.username
|
username = player.username
|
||||||
world = $world
|
world = $world
|
||||||
iterator = player.friend_usernames.iterator # Iterate the player's friend list and notify the player that they are online if they are
|
iterator = player.friend_usernames.iterator
|
||||||
|
|
||||||
|
# Iterate the player's friend list and notify the player that they are online if they are
|
||||||
while iterator.has_next
|
while iterator.has_next
|
||||||
friend_username = iterator.next
|
friend_username = iterator.next
|
||||||
friend = world.get_player(friend_username)
|
friend = world.get_player(friend_username)
|
||||||
friend_world_id = (friend == nil || !viewable?(friend, username)) ? 0 : friend.world_id
|
friend_world_id = (friend.nil? || !viewable?(friend, username)) ? 0 : friend.world_id
|
||||||
|
|
||||||
player.send(SendFriendMessage.new(friend_username, friend_world_id))
|
player.send(SendFriendMessage.new(friend_username, friend_world_id))
|
||||||
end
|
end
|
||||||
@@ -62,14 +74,13 @@ on :login do |event, player|
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Notifies the player's friends that the player has logged out.
|
# Notifies the player's friends that the player has logged out.
|
||||||
on :logout do |event, player|
|
on :logout do |_event, player|
|
||||||
update_friends(player, 0)
|
update_friends(player, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Notifies the currently logged in players that the specified player has logged into the specified
|
||||||
# Notifies the currently logged in players that the specified player has logged into the specified world, unless the
|
# world, unless the newly logged-in player has their friend privacy state set to 'off'.
|
||||||
# newly logged-in player has their friend privacy state set to 'off'.
|
def update_friends(player, world = 0)
|
||||||
def update_friends(player, world=0)
|
|
||||||
privacy = player.friend_privacy
|
privacy = player.friend_privacy
|
||||||
|
|
||||||
iterator = $world.player_repository.iterator
|
iterator = $world.player_repository.iterator
|
||||||
@@ -77,7 +88,7 @@ def update_friends(player, world=0)
|
|||||||
|
|
||||||
while iterator.has_next
|
while iterator.has_next
|
||||||
other = iterator.next
|
other = iterator.next
|
||||||
next if (!other.friends_with(username) || other == player)
|
next if !other.friends_with(username) || other == player
|
||||||
|
|
||||||
world = viewable?(player, other.username) ? world : 0
|
world = viewable?(player, other.username) ? world : 0
|
||||||
other.send(SendFriendMessage.new(username, world))
|
other.send(SendFriendMessage.new(username, world))
|
||||||
@@ -87,5 +98,5 @@ end
|
|||||||
# Checks if the specified player can be viewed by the player with the specified other username
|
# Checks if the specified player can be viewed by the player with the specified other username
|
||||||
def viewable?(player, other_username)
|
def viewable?(player, other_username)
|
||||||
privacy = player.friend_privacy
|
privacy = player.friend_privacy
|
||||||
return privacy != PrivacyState::OFF && player.friends_with(other_username) || privacy == PrivacyState::ON
|
privacy != PrivacyState::OFF && player.friends_with(other_username) || privacy == PrivacyState::ON
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,14 +6,18 @@ java_import 'org.apollo.game.model.entity.setting.PrivacyState'
|
|||||||
|
|
||||||
on :message, :private_chat do |player, message|
|
on :message, :private_chat do |player, message|
|
||||||
friend = $world.get_player(message.username)
|
friend = $world.get_player(message.username)
|
||||||
friend.send(ForwardPrivateChatMessage.new(player.username, player.privilege_level, message.compressed_chat)) if interaction_permitted(player, friend)
|
|
||||||
|
if interaction_permitted(player, friend)
|
||||||
|
chat = message.compressed_chat
|
||||||
|
friend.send(ForwardPrivateChatMessage.new(player.username, player.privilege_level, chat))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if the sender is permitted to interact with the friend they have added:
|
# Checks if the sender is permitted to interact with the friend they have added:
|
||||||
def interaction_permitted(sender, friend)
|
def interaction_permitted(sender, friend)
|
||||||
if friend.nil? || friend.has_ignored(sender.username)
|
username = sender.username
|
||||||
return false
|
return false if friend.nil? || friend.has_ignored(username)
|
||||||
end
|
|
||||||
|
|
||||||
return friend.friends_with(sender.username) ? (friend.friend_privacy != PrivacyState::OFF) : (friend.friend_privacy == PrivacyState::ON)
|
privacy = friend.friend_privacy
|
||||||
|
friend.friends_with(username) ? (privacy != PrivacyState::OFF) : (privacy == PrivacyState::ON)
|
||||||
end
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
require 'java'
|
require 'java'
|
||||||
|
|
||||||
# Opens the player's bank.
|
# Opens the player's bank.
|
||||||
on :command, :bank, RIGHTS_ADMIN do |player, command|
|
on :command, :bank, RIGHTS_ADMIN do |player, _command|
|
||||||
player.open_bank
|
player.open_bank
|
||||||
end
|
end
|
||||||
@@ -9,7 +9,8 @@ on :command, :item, RIGHTS_ADMIN do |player, command|
|
|||||||
|
|
||||||
id = args[0].to_i
|
id = args[0].to_i
|
||||||
amount = args.length == 2 ? args[1].to_i : 1
|
amount = args.length == 2 ? args[1].to_i : 1
|
||||||
if (id < 0 || id >= ItemDefinition.count)
|
|
||||||
|
if id < 0 || id >= ItemDefinition.count
|
||||||
player.send_message('The item id you specified is out of bounds!')
|
player.send_message('The item id you specified is out of bounds!')
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
@@ -24,7 +25,8 @@ on :command, :remove, RIGHTS_MOD do |player, command|
|
|||||||
|
|
||||||
id = args[0].to_i
|
id = args[0].to_i
|
||||||
amount = args.length == 2 ? args[1].to_i : 1
|
amount = args.length == 2 ? args[1].to_i : 1
|
||||||
if (id < 0 || id >= ItemDefinition.count)
|
|
||||||
|
if id < 0 || id >= ItemDefinition.count
|
||||||
player.send_message('The item id you specified is out of bounds!')
|
player.send_message('The item id you specified is out of bounds!')
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
@@ -33,11 +35,11 @@ on :command, :remove, RIGHTS_MOD do |player, command|
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Clears the player's inventory.
|
# Clears the player's inventory.
|
||||||
on :command, :empty, RIGHTS_MOD do |player, command|
|
on :command, :empty, RIGHTS_MOD do |player, _command|
|
||||||
player.inventory.clear
|
player.inventory.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gives the player 1,000 of each rune.
|
# Gives the player 1,000 of each rune.
|
||||||
on :command, :runes, RIGHTS_ADMIN do |player, command|
|
on :command, :runes, RIGHTS_ADMIN do |player, _command|
|
||||||
(554..566).each { |item| player.inventory.add(item, 1000) }
|
(554..566).each { |item| player.inventory.add(item, 1000) }
|
||||||
end
|
end
|
||||||
@@ -9,20 +9,22 @@ java_import 'org.apollo.game.model.entity.Player'
|
|||||||
|
|
||||||
on :command, :lookup, RIGHTS_ADMIN do |player, command|
|
on :command, :lookup, RIGHTS_ADMIN do |player, command|
|
||||||
args = command.arguments.to_a
|
args = command.arguments.to_a
|
||||||
next unless valid_arg_length(args, (1..10), player, 'Invalid syntax - ::lookup [npc/object/item] [name]')
|
message = 'Invalid syntax - ::lookup [npc/object/item] [name]'
|
||||||
|
next unless valid_arg_length(args, (1..10), player, message)
|
||||||
|
|
||||||
type = args.shift.downcase
|
type = args.shift.downcase
|
||||||
limit = args.first.to_i == 0 ? 5 : args.shift.to_i;
|
limit = args.first.to_i == 0 ? 5 : args.shift.to_i
|
||||||
name = args.join(' ').downcase
|
name = args.join(' ').downcase
|
||||||
|
|
||||||
if ['npc', 'object', 'item'].index(type) == nil
|
if %w(npc object item).index(type).nil?
|
||||||
player.send_message('Invalid syntax - ::lookup [npc/object/item] [name]')
|
player.send_message('Invalid syntax - ::lookup [npc/object/item] [name]')
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
ids = find_entities(type, name, limit).join(', ')
|
ids = find_entities(type, name, limit).join(', ')
|
||||||
|
|
||||||
message = ids.empty? ? "Could not find an #{type} called #{name}." : "Possible ids for \"#{name}\" are: #{ids}."
|
message = ids.empty? ? "Could not find an #{type} called #{name}." :
|
||||||
|
"Possible ids for \"#{name}\" are: #{ids}."
|
||||||
player.send_message(message)
|
player.send_message(message)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -35,7 +37,8 @@ on :command, :iteminfo, RIGHTS_ADMIN do |player, command|
|
|||||||
definition = ItemDefinition.lookup(id)
|
definition = ItemDefinition.lookup(id)
|
||||||
members = definition.is_members_only ? 'members' : 'not members'
|
members = definition.is_members_only ? 'members' : 'not members'
|
||||||
|
|
||||||
player.send_message("Item #{id} is called #{definition.name}, is #{members} only, and has a team of #{definition.team}.")
|
player.send_message("Item #{id} is called #{definition.name}, is #{members} only, and has a "\
|
||||||
|
"team of #{definition.team}.")
|
||||||
player.send_message("Its description is \"#{definition.description}\".")
|
player.send_message("Its description is \"#{definition.description}\".")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -46,7 +49,8 @@ on :command, :npcinfo, RIGHTS_ADMIN do |player, command|
|
|||||||
|
|
||||||
id = args[0].to_i
|
id = args[0].to_i
|
||||||
definition = NpcDefinition.lookup(id)
|
definition = NpcDefinition.lookup(id)
|
||||||
is_combative = definition.has_combat_level ? "has a combat level of #{definition.combat_level}" : "does not have a combat level"
|
is_combative = definition.has_combat_level ? "has a combat level of #{definition.combat_level}" :
|
||||||
|
'does not have a combat level'
|
||||||
|
|
||||||
player.send_message("Npc #{id} is called #{definition.name} and #{is_combative}.")
|
player.send_message("Npc #{id} is called #{definition.name} and #{is_combative}.")
|
||||||
player.send_message("Its description is \"#{definition.description}\".")
|
player.send_message("Its description is \"#{definition.description}\".")
|
||||||
@@ -59,6 +63,7 @@ on :command, :objectinfo, RIGHTS_ADMIN do |player, command|
|
|||||||
|
|
||||||
id = args[0].to_i
|
id = args[0].to_i
|
||||||
definition = ObjectDefinition.lookup(id)
|
definition = ObjectDefinition.lookup(id)
|
||||||
player.send_message("Object #{id} is called #{definition.name} and its description is \"#{definition.description}\".")
|
player.send_message("Object #{id} is called #{definition.name} and its description is "\
|
||||||
|
"\"#{definition.description}\".")
|
||||||
player.send_message("Its width is #{definition.width} and its length is #{definition.length}.")
|
player.send_message("Its width is #{definition.width} and its length is #{definition.length}.")
|
||||||
end
|
end
|
||||||
@@ -5,7 +5,8 @@ java_import 'org.apollo.game.model.entity.Player'
|
|||||||
|
|
||||||
# Adds a command to broadcast a message to every player on the server.
|
# Adds a command to broadcast a message to every player on the server.
|
||||||
on :command, :broadcast, RIGHTS_ADMIN do |player, command|
|
on :command, :broadcast, RIGHTS_ADMIN do |player, command|
|
||||||
message = command.arguments.to_a.join(" ")
|
message = command.arguments.to_a.join(' ')
|
||||||
broadcast = "[Broadcast] #{player.get_username.capitalize}: #{message}"
|
broadcast = "[Broadcast] #{player.get_username.capitalize}: #{message}"
|
||||||
$world.player_repository.each { |player| player.send_message(broadcast) }
|
|
||||||
|
$world.player_repository.each { |other| other.send_message(broadcast) }
|
||||||
end
|
end
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
require 'java'
|
require 'java'
|
||||||
|
|
||||||
on :command, :filter do |player, command|
|
on :command, :filter do |player, command|
|
||||||
player.send_message('Your message filter is now ' + (player.toggle_message_filter ? 'enabled.' : 'disabled.'))
|
status = player.toggle_message_filter ? 'enabled' : 'disabled'
|
||||||
|
player.send_message('Your message filter is now ' + status + '.')
|
||||||
end
|
end
|
||||||
@@ -7,11 +7,12 @@ java_import 'org.apollo.game.model.entity.Npc'
|
|||||||
# An array of npcs that cannot be spawned.
|
# An array of npcs that cannot be spawned.
|
||||||
blacklist = []
|
blacklist = []
|
||||||
|
|
||||||
# Spawns a non-blacklisted npc in the specified position, or the player's position if both 'x' and 'y' are not supplied.
|
# Spawns a non-blacklisted npc in the specified position, or the player's position if both 'x' and
|
||||||
|
# 'y' are not supplied.
|
||||||
on :command, :spawn, RIGHTS_ADMIN do |player, command|
|
on :command, :spawn, RIGHTS_ADMIN do |player, command|
|
||||||
args = command.arguments
|
args = command.arguments
|
||||||
unless [1, 3].include?(args.length) and (id = args[0].to_i) > -1
|
unless [1, 3, 4].include?(args.length) && (id = args[0].to_i) > -1
|
||||||
player.send_message('Invalid syntax - ::spawn [npc id] [optional-x] [optional-y]')
|
player.send_message('Invalid syntax - ::spawn [npc id] [optional-x] [optional-y] [optional-z]')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -20,7 +21,12 @@ on :command, :spawn, RIGHTS_ADMIN do |player, command|
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
position = args.length == 1 ? player.position : Position.new(args[1].to_i, args[2].to_i, player.position.height)
|
if args.length == 1
|
||||||
|
position = player.position
|
||||||
|
else
|
||||||
|
height = args.length == 4 ? args[3].to_i : player.position.height
|
||||||
|
position = Position.new(args[1].to_i, args[2].to_i, height)
|
||||||
|
end
|
||||||
|
|
||||||
$world.register(Npc.new(id, position))
|
$world.register(Npc.new(id, position))
|
||||||
end
|
end
|
||||||
@@ -28,7 +34,7 @@ end
|
|||||||
# Mass spawns npcs around the player.
|
# Mass spawns npcs around the player.
|
||||||
on :command, :mass, RIGHTS_ADMIN do |player, command|
|
on :command, :mass, RIGHTS_ADMIN do |player, command|
|
||||||
args = command.arguments
|
args = command.arguments
|
||||||
unless args.length == 2 and (id = args[0].to_i) > -1 and (1..5).include?(range = args[1].to_i)
|
unless args.length == 2 && (id = args[0].to_i) > -1 && (1..5).include?(range = args[1].to_i)
|
||||||
player.send_message('Invalid syntax - ::spawn [npc id] [range (1-5)]')
|
player.send_message('Invalid syntax - ::spawn [npc id] [range (1-5)]')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -40,22 +46,23 @@ on :command, :mass, RIGHTS_ADMIN do |player, command|
|
|||||||
|
|
||||||
center_position = player.position
|
center_position = player.position
|
||||||
|
|
||||||
minX = center_position.x - range
|
min_x = center_position.x - range
|
||||||
minY = center_position.y - range
|
min_y = center_position.y - range
|
||||||
maxX = center_position.x + range
|
max_x = center_position.x + range
|
||||||
maxY = center_position.y + range
|
max_y = center_position.y + range
|
||||||
z = center_position.height
|
z = center_position.height
|
||||||
|
|
||||||
for x in minX..maxX do
|
(min_x..max_x).each do |x|
|
||||||
for y in minY..maxY do
|
(min_y..max_y).each do |y|
|
||||||
$world.register(Npc.new(id, Position.new(x, y, z)))
|
$world.register(Npc.new(id, Position.new(x, y, z)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
player.send_message("Mass spawning npcs with id #{id}.")
|
player.send_message("Mass spawning npcs with id #{id}.")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Unregisters all npcs from the world npc repository.
|
# Unregisters all npcs from the world npc repository.
|
||||||
on :command, :clearnpcs, RIGHTS_ADMIN do |player, command|
|
on :command, :clearnpcs, RIGHTS_ADMIN do |player, _command|
|
||||||
$world.npc_repository.each { |npc| $world.unregister(npc) }
|
$world.npc_repository.each { |npc| $world.unregister(npc) }
|
||||||
player.send_message('Unregistered all npcs from the world.')
|
player.send_message('Unregistered all npcs from the world.')
|
||||||
end
|
end
|
||||||
@@ -3,8 +3,9 @@ java_import 'org.apollo.game.model.entity.SkillSet'
|
|||||||
java_import 'org.apollo.game.model.entity.Skill'
|
java_import 'org.apollo.game.model.entity.Skill'
|
||||||
|
|
||||||
# Maximises the player's skill set.
|
# Maximises the player's skill set.
|
||||||
on :command, :max, RIGHTS_ADMIN do |player, command|
|
on :command, :max, RIGHTS_ADMIN do |player, _command|
|
||||||
skills = player.skill_set
|
skills = player.skill_set
|
||||||
|
|
||||||
(0...skills.size).each do |skill|
|
(0...skills.size).each do |skill|
|
||||||
skills.add_experience(skill, SkillSet::MAXIMUM_EXP)
|
skills.add_experience(skill, SkillSet::MAXIMUM_EXP)
|
||||||
end
|
end
|
||||||
@@ -13,15 +14,16 @@ end
|
|||||||
# Levels the specified skill to the specified level, optionally updating the current level as well.
|
# Levels the specified skill to the specified level, optionally updating the current level as well.
|
||||||
on :command, :level, RIGHTS_ADMIN do |player, command|
|
on :command, :level, RIGHTS_ADMIN do |player, command|
|
||||||
args = command.arguments
|
args = command.arguments
|
||||||
unless (2..3).include?(args.length) && (0..20).include?(skill_id = args[0].to_i) && (1..99).include?(level = args[1].to_i)
|
unless (2..3).include?(args.length) && (0..20).include?(skill_id = args[0].to_i) &&
|
||||||
player.send_message("Invalid syntax - ::level [skill-id] [level]")
|
(1..99).include?(level = args[1].to_i)
|
||||||
|
player.send_message('Invalid syntax - ::level [skill-id] [level]')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
experience = SkillSet.experience_for_level(level)
|
experience = SkillSet.experience_for_level(level)
|
||||||
current = level
|
current = level
|
||||||
|
|
||||||
if args.length == 3 && args[2].to_s == "old"
|
if args.length == 3 && args[2].to_s == 'old'
|
||||||
skill = player.skill_set.skill(skill_id)
|
skill = player.skill_set.skill(skill_id)
|
||||||
current = skill.current_level
|
current = skill.current_level
|
||||||
end
|
end
|
||||||
@@ -32,8 +34,9 @@ end
|
|||||||
# Adds the specified amount of experience to the specified skill.
|
# Adds the specified amount of experience to the specified skill.
|
||||||
on :command, :xp, RIGHTS_ADMIN do |player, command|
|
on :command, :xp, RIGHTS_ADMIN do |player, command|
|
||||||
args = command.arguments
|
args = command.arguments
|
||||||
unless args.length == 2 && (0..20).include?(skill_id = args[0].to_i) && (experience = args[1].to_i) >= 0
|
unless args.length == 2 && (0..20).include?(skill_id = args[0].to_i) &&
|
||||||
player.send_message("Invalid syntax - ::xp [skill-id] [experience]")
|
(experience = args[1].to_i) >= 0
|
||||||
|
player.send_message('Invalid syntax - ::xp [skill-id] [experience]')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ require 'java'
|
|||||||
java_import 'org.apollo.game.model.Position'
|
java_import 'org.apollo.game.model.Position'
|
||||||
|
|
||||||
# Sends the player's position.
|
# Sends the player's position.
|
||||||
on :command, :pos, RIGHTS_MOD do |player, command|
|
on :command, :pos, RIGHTS_MOD do |player, _command|
|
||||||
position = player.position
|
player.send_message("You are at: #{player.position}.")
|
||||||
player.send_message("You are at: #{position}.")
|
|
||||||
player.send_message("Local coordinates: (#{position.get_local_x}, #{position.get_local_y}).")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Teleports the player to the specified position.
|
# Teleports the player to the specified position.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ java_import 'org.apollo.game.model.entity.Player'
|
|||||||
java_import 'org.apollo.game.message.impl.SetWidgetTextMessage'
|
java_import 'org.apollo.game.message.impl.SetWidgetTextMessage'
|
||||||
java_import 'org.apollo.game.message.impl.OpenOverlayMessage'
|
java_import 'org.apollo.game.message.impl.OpenOverlayMessage'
|
||||||
|
|
||||||
|
declare_attribute(:wilderness_level, 0, :transient)
|
||||||
|
|
||||||
# Constants constants related to the wilderness
|
# Constants constants related to the wilderness
|
||||||
module WildernessConstants
|
module WildernessConstants
|
||||||
@@ -16,47 +17,50 @@ module WildernessConstants
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
declare_attribute(:wilderness_level, 0, :transient)
|
|
||||||
|
|
||||||
# Determines the wilderness level for the specified player's position
|
# Determines the wilderness level for the specified player's position
|
||||||
def wilderness_level(player)
|
def wilderness_level(player)
|
||||||
return ((player.position.y - 3520) / 8).ceil
|
((player.position.y - 3520) / 8).ceil
|
||||||
end
|
end
|
||||||
|
|
||||||
area_action :wilderness_level do
|
area_action :wilderness_level do
|
||||||
|
|
||||||
on_entry do |player|
|
on_entry do |player|
|
||||||
player.wilderness_level = wilderness_level(player)
|
player.wilderness_level = wilderness_level(player)
|
||||||
player.interface_set.open_overlay(WildernessConstants::OVERLAY_INTERFACE_ID)
|
player.interface_set.open_overlay(WildernessConstants::OVERLAY_INTERFACE_ID)
|
||||||
player.send(SetWidgetTextMessage.new(WildernessConstants::LEVEL_STRING_ID, "Level: #{player.wilderness_level}"))
|
|
||||||
|
id = WildernessConstants::LEVEL_STRING_ID
|
||||||
|
player.send(SetWidgetTextMessage.new(id, "Level: #{player.wilderness_level}"))
|
||||||
show_action(player, ATTACK_ACTION)
|
show_action(player, ATTACK_ACTION)
|
||||||
end
|
end
|
||||||
|
|
||||||
while_in do |player|
|
while_in do |player|
|
||||||
current = player.wilderness_level
|
current = player.wilderness_level
|
||||||
updated = wilderness_level(player)
|
updated = wilderness_level(player)
|
||||||
if (current != updated)
|
|
||||||
player.wilderness_level = updated
|
if current != updated
|
||||||
player.send(SetWidgetTextMessage.new(WildernessConstants::LEVEL_STRING_ID, "Level: #{player.wilderness_level}"))
|
player.wilderness_level = updated
|
||||||
|
|
||||||
|
id = WildernessConstants::LEVEL_STRING_ID
|
||||||
|
player.send(SetWidgetTextMessage.new(id, "Level: #{player.wilderness_level}"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
on_exit do |player|
|
on_exit do |player|
|
||||||
player.wilderness_level = 0
|
player.wilderness_level = 0
|
||||||
player.interface_set.close()
|
player.interface_set.close
|
||||||
|
|
||||||
player.send(OpenOverlayMessage.new(-1))
|
player.send(OpenOverlayMessage.new(-1))
|
||||||
hide_action(player, ATTACK_ACTION)
|
hide_action(player, ATTACK_ACTION)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Monkey patch the existing player class to add method of checking whether or not a player is within the wilderness
|
# Monkey patch the existing player class to add method of checking whether or not a player is
|
||||||
|
# within the wilderness
|
||||||
class Player
|
class Player
|
||||||
|
|
||||||
def in_wilderness
|
def in_wilderness
|
||||||
self.wilderness_level > 0
|
wilderness_level > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
area :name => :wilderness, :coordinates => [ 2945, 3522, 3390, 3972, 0 ], :actions => :wilderness_level
|
area name: :wilderness, coordinates: [2945, 3522, 3390, 3972, 0], actions: :wilderness_level
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ require 'java'
|
|||||||
# A map of item ids to consumables.
|
# A map of item ids to consumables.
|
||||||
CONSUMABLES = {}
|
CONSUMABLES = {}
|
||||||
|
|
||||||
|
# The id of the food consumption animation.
|
||||||
CONSUME_ANIMATION_ID = 829
|
CONSUME_ANIMATION_ID = 829
|
||||||
|
|
||||||
# An item that can be consumed to produce a skill effect.
|
# An item that can be consumed to produce a skill effect.
|
||||||
@@ -15,8 +16,8 @@ class Consumable
|
|||||||
@sound = sound
|
@sound = sound
|
||||||
end
|
end
|
||||||
|
|
||||||
def consume(player)
|
def consume(_player)
|
||||||
# Override to provide specific functionality.
|
# Override to provide specific functionality.
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -26,6 +27,7 @@ def append_consumable(consumable)
|
|||||||
CONSUMABLES[consumable.id] = consumable
|
CONSUMABLES[consumable.id] = consumable
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# An Action used for food consumption.
|
||||||
class ConsumeAction < Action
|
class ConsumeAction < Action
|
||||||
attr_reader :consumable
|
attr_reader :consumable
|
||||||
|
|
||||||
@@ -36,10 +38,11 @@ class ConsumeAction < Action
|
|||||||
@executions = 0
|
@executions = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute()
|
def execute
|
||||||
if @executions == 0
|
if @executions == 0
|
||||||
mob.inventory.reset(@slot)
|
mob.inventory.reset(@slot)
|
||||||
@consumable.consume(mob)
|
@consumable.consume(mob)
|
||||||
|
|
||||||
mob.play_animation(Animation.new(CONSUME_ANIMATION_ID))
|
mob.play_animation(Animation.new(CONSUME_ANIMATION_ID))
|
||||||
@executions += 1
|
@executions += 1
|
||||||
else
|
else
|
||||||
@@ -48,7 +51,7 @@ class ConsumeAction < Action
|
|||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (mob == other.mob && @consumable.id == other.consumable.id)
|
mob == other.mob && @consumable.id == other.consumable.id
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+183
-178
@@ -6,10 +6,11 @@ java_import 'org.apollo.game.model.entity.Player'
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
# The id the of the sound made when eating food.
|
||||||
EAT_FOOD_SOUND = 317
|
EAT_FOOD_SOUND = 317
|
||||||
|
|
||||||
# Represents an edible piece of food, such as bread or fish.
|
# Represents an edible piece of food, such as bread or fish.
|
||||||
# TODO delay eating times
|
# TODO: delay eating times
|
||||||
class Food < Consumable
|
class Food < Consumable
|
||||||
|
|
||||||
def initialize(name, id, restoration, replace)
|
def initialize(name, id, restoration, replace)
|
||||||
@@ -21,221 +22,225 @@ class Food < Consumable
|
|||||||
# Restore the appropriate amount of hitpoints when consumed.
|
# Restore the appropriate amount of hitpoints when consumed.
|
||||||
def consume(player)
|
def consume(player)
|
||||||
hitpoints = player.skill_set.skill(Skill::HITPOINTS)
|
hitpoints = player.skill_set.skill(Skill::HITPOINTS)
|
||||||
new_curr = [ hitpoints.current_level + @restoration, hitpoints.maximum_level ].min
|
new_curr = [hitpoints.current_level + @restoration, hitpoints.maximum_level].min
|
||||||
|
|
||||||
player.inventory.add(@replace) unless (@replace == -1)
|
player.inventory.add(@replace) unless @replace == -1
|
||||||
|
|
||||||
player.send_message("You eat the #{name}.", true)
|
player.send_message("You eat the #{name}.", true)
|
||||||
player.send_message("It heals some health.", true) if new_curr == hitpoints
|
player.send_message('It heals some health.', true) if new_curr == hitpoints
|
||||||
|
|
||||||
player.skill_set.set_skill(Skill::HITPOINTS, Skill.new(hitpoints.experience, new_curr, hitpoints.maximum_level))
|
skill = Skill.new(hitpoints.experience, new_curr, hitpoints.maximum_level)
|
||||||
|
player.skill_set.set_skill(Skill::HITPOINTS, skill)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The default delay before a piece of food is eaten
|
||||||
|
DEFAULT_DELAY = 3
|
||||||
|
|
||||||
# Appends a food item to the list of consumables.
|
# Appends a food item to the list of consumables.
|
||||||
def food(hash)
|
def food(hash)
|
||||||
raise 'Hash must contain a name, id, and a restoration value.' unless (hash.has_keys?(:name, :id, :restoration))
|
unless hash.has_keys?(:name, :id, :restoration)
|
||||||
name = hash[:name]; id = hash[:id]; restoration = hash[:restoration]; replace = hash[:replace] || -1; @delay = hash[:delay] || 3
|
fail 'Hash must contain a name, id, and a restoration value.'
|
||||||
|
end
|
||||||
|
|
||||||
|
name, id, restoration = hash[:name], hash[:id], hash[:restoration];
|
||||||
|
replace = hash[:replace] || -1
|
||||||
|
delay = hash[:delay] || DEFAULT_DELAY # TODO: ??
|
||||||
|
|
||||||
append_consumable(Food.new(name, id, restoration, replace))
|
append_consumable(Food.new(name, id, restoration, replace))
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO special effects
|
# TODO: special effects
|
||||||
food :name => :cooked_slimy_eel, :id => 3381, :restoration => 6 # this has a chance to heal 6 to 10 hp
|
food name: :cooked_slimy_eel, id: 3381, restoration: 6 # this has a chance to heal 6 to 10 hp
|
||||||
food :name => :thin_snail_meat, :id => 3369, :restoration => 5 # this has a chance to heal 5 to 7 hp
|
food name: :thin_snail_meat, id: 3369, restoration: 5 # this has a chance to heal 5 to 7 hp
|
||||||
food :name => :fat_snail_meat, :id => 3373, :restoration => 2 # this has a chance to heal 7 to 9 hp
|
food name: :fat_snail_meat, id: 3373, restoration: 2 # this has a chance to heal 7 to 9 hp
|
||||||
food :name => :watermelon_slice, :id => 5984, :restoration => 0 # this heals 5% of player's life
|
food name: :watermelon_slice, id: 5984, restoration: 0 # this heals 5% of player's life
|
||||||
food :name => :cooked_karambwan, :id => 3146, :restoration => 0 # poisons player(50)
|
food name: :cooked_karambwan, id: 3146, restoration: 0 # poisons player(50)
|
||||||
food :name => :spider_on_stick, :id => 6297, :restoration => 7 # heals between 7 and 10
|
food name: :spider_on_stick, id: 6297, restoration: 7 # heals between 7 and 10
|
||||||
food :name => :spider_on_shaft, :id => 6299, :restoration => 7 # heals between 7 and 10
|
food name: :spider_on_shaft, id: 6299, restoration: 7 # heals between 7 and 10
|
||||||
|
|
||||||
# Meats/Fish
|
# Meats/Fish
|
||||||
food :name => :anchovies, :id => 319, :restoration => 1
|
food name: :anchovies, id: 319, restoration: 1
|
||||||
food :name => :crab_meat, :id => 7521, :restoration => 2, :replace => 7523
|
food name: :crab_meat, id: 7521, restoration: 2, replace: 7523
|
||||||
food :name => :crab_meat, :id => 7523, :restoration => 2, :replace => 7524
|
food name: :crab_meat, id: 7523, restoration: 2, replace: 7524
|
||||||
food :name => :crab_meat, :id => 7524, :restoration => 2, :replace => 7525
|
food name: :crab_meat, id: 7524, restoration: 2, replace: 7525
|
||||||
food :name => :crab_meat, :id => 7525, :restoration => 2, :replace => 7526
|
food name: :crab_meat, id: 7525, restoration: 2, replace: 7526
|
||||||
food :name => :crab_meat, :id => 7526, :restoration => 2
|
food name: :crab_meat, id: 7526, restoration: 2
|
||||||
food :name => :shrimp, :id => 315, :restoration => 3
|
food name: :shrimp, id: 315, restoration: 3
|
||||||
food :name => :sardine, :id => 325, :restoration => 3
|
food name: :sardine, id: 325, restoration: 3
|
||||||
food :name => :cooked_meat, :id => 2142, :restoration => 3
|
food name: :cooked_meat, id: 2142, restoration: 3
|
||||||
food :name => :cooked_chicken, :id => 2140, :restoration => 3
|
food name: :cooked_chicken, id: 2140, restoration: 3
|
||||||
food :name => :ugthanki_meat, :id => 1861, :restoration => 3
|
food name: :ugthanki_meat, id: 1861, restoration: 3
|
||||||
food :name => :karambwanji, :id => 3151, :restoration => 3
|
food name: :karambwanji, id: 3151, restoration: 3
|
||||||
food :name => :cooked_rabbit, :id => 3228, :restoration => 5
|
food name: :cooked_rabbit, id: 3228, restoration: 5
|
||||||
food :name => :herring, :id => 347, :restoration => 6
|
food name: :herring, id: 347, restoration: 6
|
||||||
food :name => :trout, :id => 333, :restoration => 7
|
food name: :trout, id: 333, restoration: 7
|
||||||
food :name => :cod, :id => 339, :restoration => 7
|
food name: :cod, id: 339, restoration: 7
|
||||||
food :name => :mackeral, :id => 355, :restoration => 7
|
food name: :mackeral, id: 355, restoration: 7
|
||||||
food :name => :roast_rabbit, :id => 7223, :restoration => 7
|
food name: :roast_rabbit, id: 7223, restoration: 7
|
||||||
food :name => :pike, :id => 351, :restoration => 8
|
food name: :pike, id: 351, restoration: 8
|
||||||
food :name => :lean_snail_meat, :id => 3371, :restoration => 8
|
food name: :lean_snail_meat, id: 3371, restoration: 8
|
||||||
food :name => :salmon, :id => 329, :restoration => 9
|
food name: :salmon, id: 329, restoration: 9
|
||||||
food :name => :tuna, :id => 361, :restoration => 10
|
food name: :tuna, id: 361, restoration: 10
|
||||||
food :name => :lobster, :id => 379, :restoration => 12
|
food name: :lobster, id: 379, restoration: 12
|
||||||
food :name => :bass, :id => 365, :restoration => 13
|
food name: :bass, id: 365, restoration: 13
|
||||||
food :name => :swordfish, :id => 373, :restoration => 14
|
food name: :swordfish, id: 373, restoration: 14
|
||||||
food :name => :cooked_jubbly, :id => 7568, :restoration => 15
|
food name: :cooked_jubbly, id: 7568, restoration: 15
|
||||||
food :name => :monkfish, :id => 7946, :restoration => 16
|
food name: :monkfish, id: 7946, restoration: 16
|
||||||
food :name => :cooked_karambwan, :id => 3144, :restoration => 18
|
food name: :cooked_karambwan, id: 3144, restoration: 18
|
||||||
food :name => :shark, :id => 385, :restoration => 20
|
food name: :shark, id: 385, restoration: 20
|
||||||
food :name => :sea_turtle, :id => 397, :restoration => 21
|
food name: :sea_turtle, id: 397, restoration: 21
|
||||||
food :name => :manta_ray, :id => 391, :restoration => 22
|
food name: :manta_ray, id: 391, restoration: 22
|
||||||
|
|
||||||
# Breads/Wraps
|
# Breads/Wraps
|
||||||
food :name => :bread, :id => 2309, :restoration => 5
|
food name: :bread, id: 2309, restoration: 5
|
||||||
food :name => :oomlie_wrap, :id => 2343, :restoration => 14
|
food name: :oomlie_wrap, id: 2343, restoration: 14
|
||||||
food :name => :ugthanki_kebab, :id => 1883, :restoration => 19
|
food name: :ugthanki_kebab, id: 1883, restoration: 19
|
||||||
|
|
||||||
# Fruits
|
# Fruits
|
||||||
food :name => :banana, :id => 1963, :restoration => 2
|
food name: :banana, id: 1963, restoration: 2
|
||||||
food :name => :sliced_banana, :id => 3162, :restoration => 2
|
food name: :sliced_banana, id: 3162, restoration: 2
|
||||||
food :name => :lemon, :id => 2102, :restoration => 2
|
food name: :lemon, id: 2102, restoration: 2
|
||||||
food :name => :lemon_chunks, :id => 2104, :restoration => 2
|
food name: :lemon_chunks, id: 2104, restoration: 2
|
||||||
food :name => :lemon_slices, :id => 2106, :restoration => 2
|
food name: :lemon_slices, id: 2106, restoration: 2
|
||||||
food :name => :lime, :id => 2120, :restoration => 2
|
food name: :lime, id: 2120, restoration: 2
|
||||||
food :name => :lime_chunks, :id => 2122, :restoration => 2
|
food name: :lime_chunks, id: 2122, restoration: 2
|
||||||
food :name => :lime_slices, :id => 2124, :restoration => 2
|
food name: :lime_slices, id: 2124, restoration: 2
|
||||||
food :name => :strawberry, :id => 5504, :restoration => 5
|
food name: :strawberry, id: 5504, restoration: 5
|
||||||
food :name => :papaya_fruit, :id => 5972, :restoration => 8
|
food name: :papaya_fruit, id: 5972, restoration: 8
|
||||||
food :name => :pineapple_chunks, :id => 2116, :restoration => 2
|
food name: :pineapple_chunks, id: 2116, restoration: 2
|
||||||
food :name => :pineapple_ring, :id => 2118, :restoration => 2
|
food name: :pineapple_ring, id: 2118, restoration: 2
|
||||||
food :name => :orange, :id => 2108, :restoration => 2
|
food name: :orange, id: 2108, restoration: 2
|
||||||
food :name => :orange_rings, :id => 2110, :restoration => 2
|
food name: :orange_rings, id: 2110, restoration: 2
|
||||||
food :name => :orange_slices, :id => 2112, :restoration => 2
|
food name: :orange_slices, id: 2112, restoration: 2
|
||||||
|
|
||||||
|
# Pies
|
||||||
|
# TODO: pie special effects (e.g. fish pie raises fishing level)
|
||||||
|
food name: :redberry_pie, id: 2325, restoration: 5, replace: 2333, delay: 1
|
||||||
|
food name: :redberry_pie, id: 2333, restoration: 5, delay: 1
|
||||||
|
|
||||||
# Pies
|
food name: :meat_pie, id: 2327, restoration: 6, replace: 2331, delay: 1
|
||||||
#TODO Special Effects on pies (i.e.fish pie raises fishing level)
|
food name: :meat_pie, id: 2331, restoration: 6, delay: 1
|
||||||
food :name => :redberry_pie, :id => 2325, :restoration => 5, :replace => 2333, :delay => 1
|
|
||||||
food :name => :redberry_pie, :id => 2333, :restoration => 5, :delay => 1
|
|
||||||
|
|
||||||
food :name => :meat_pie, :id => 2327, :restoration => 6, :replace => 2331, :delay => 1
|
food name: :apple_pie, id: 2323, restoration: 7, replace: 2335, delay: 1
|
||||||
food :name => :meat_pie, :id => 2331, :restoration => 6, :delay => 1
|
food name: :apple_pie, id: 2335, restoration: 7, delay: 1
|
||||||
|
|
||||||
food :name => :apple_pie, :id => 2323, :restoration => 7, :replace => 2335, :delay => 1
|
food name: :fish_pie, id: 7188, restoration: 6, replace: 7190, delay: 1
|
||||||
food :name => :apple_pie, :id => 2335, :restoration => 7, :delay => 1
|
food name: :fish_pie, id: 7190, restoration: 6, delay: 1
|
||||||
|
|
||||||
food :name => :fish_pie, :id => 7188, :restoration => 6, :replace => 7190, :delay => 1
|
food name: :admiral_pie, id: 7198, restoration: 8, replace: 7200, delay: 1
|
||||||
food :name => :fish_pie, :id => 7190, :restoration => 6, :delay => 1
|
food name: :admiral_pie, id: 7200, restoration: 8, delay: 1
|
||||||
|
|
||||||
food :name => :admiral_pie, :id => 7198, :restoration => 8, :replace => 7200, :delay => 1
|
food name: :wild_pie, id: 7208, restoration: 11, replace: 7210, delay: 1
|
||||||
food :name => :admiral_pie, :id => 7200, :restoration => 8, :delay => 1
|
food name: :wild_pie, id: 7210, restoration: 11, delay: 1
|
||||||
|
|
||||||
food :name => :wild_pie, :id => 7208, :restoration => 11, :replace => 7210, :delay => 1
|
food name: :summer_pie, id: 7218, restoration: 11, replace: 7220, delay: 1
|
||||||
food :name => :wild_pie, :id => 7210, :restoration => 11, :delay => 1
|
food name: :summer_pie, id: 7220, restoration: 11, delay: 1
|
||||||
|
|
||||||
food :name => :summer_pie, :id => 7218, :restoration => 11, :replace => 7220, :delay => 1
|
# Stews
|
||||||
food :name => :summer_pie, :id => 7220, :restoration => 11, :delay => 1
|
food name: :stew, id: 2003, restoration: 11
|
||||||
|
food name: :banana_stew, id: 4016, restoration: 11
|
||||||
|
food name: :curry, id: 2011, restoration: 19
|
||||||
|
|
||||||
# Stews
|
# Pizzas
|
||||||
food :name => :stew, :id => 2003, :restoration => 11
|
food name: :plain_pizza, id: 2289, restoration: 7, replace: 2291
|
||||||
food :name => :banana_stew, :id => 4016, :restoration => 11
|
food name: :plain_pizza, id: 2291, restoration: 7
|
||||||
food :name => :curry, :id => 2011, :restoration => 19
|
|
||||||
|
|
||||||
# Pizzas
|
food name: :meat_pizza, id: 2293, restoration: 8, replace: 2295
|
||||||
food :name => :plain_pizza, :id => 2289, :restoration => 7, :replace => 2291
|
food name: :meat_pizza, id: 2295, restoration: 8
|
||||||
food :name => :plain_pizza, :id => 2291, :restoration => 7
|
|
||||||
|
|
||||||
food :name => :meat_pizza, :id => 2293, :restoration => 8, :replace => 2295
|
food name: :anchovy_pizza, id: 2297, restoration: 9, replace: 2299
|
||||||
food :name => :meat_pizza, :id => 2295, :restoration => 8
|
food name: :anchovy_pizza, id: 2299, restoration: 9
|
||||||
|
|
||||||
food :name => :anchovy_pizza, :id => 2297, :restoration => 9, :replace => 2299
|
food name: :pineapple_pizza, id: 2301, restoration: 11, replace: 2303
|
||||||
food :name => :anchovy_pizza, :id => 2299, :restoration => 9
|
food name: :pineapple_pizza, id: 2303, restoration: 11
|
||||||
|
|
||||||
food :name => :pineapple_pizza, :id => 2301, :restoration => 11, :replace => 2303
|
# Cakes
|
||||||
food :name => :pineapple_pizza, :id => 2303, :restoration => 11
|
food name: :fishcake, id: 7530, restoration: 11
|
||||||
|
|
||||||
# Cakes
|
food name: :cake, id: 1891, restoration: 4, replace: 1893
|
||||||
food :name => :fishcake, :id => 7530, :restoration => 11
|
food name: :cake, id: 1893, restoration: 4, replace: 1895
|
||||||
|
food name: :cake, id: 1895, restoration: 4
|
||||||
|
|
||||||
food :name => :cake, :id => 1891, :restoration => 4, :replace => 1893
|
food name: :chocolate_cake, id: 1897, restoration: 5, replace: 1899
|
||||||
food :name => :cake, :id => 1893, :restoration => 4, :replace => 1895
|
food name: :chocolate_cake, id: 1899, restoration: 5, replace: 1901
|
||||||
food :name => :cake, :id => 1895, :restoration => 4
|
food name: :chocolate_cake, id: 1901, restoration: 5
|
||||||
|
|
||||||
food :name => :chocolate_cake, :id => 1897, :restoration => 5, :replace => 1899
|
# Wine
|
||||||
food :name => :chocolate_cake, :id => 1899, :restoration => 5, :replace => 1901
|
# TODO: Add to drinks.rb?
|
||||||
food :name => :chocolate_cake, :id => 1901, :restoration => 5
|
food name: :jug_of_wine, id: 1993, restoration: 11
|
||||||
|
|
||||||
# Wine
|
# Hot Drinks
|
||||||
# Add to drinks.rb?
|
# TODO: Add to drinks.rb?
|
||||||
food :name => :jug_of_wine, :id => 1993, :restoration => 11
|
food name: :nettle_tea, id: 4239, restoration: 3
|
||||||
|
food name: :nettle_tea, id: 4240, restoration: 3
|
||||||
|
|
||||||
# Hot Drinks
|
# Vegetables
|
||||||
# Add to drinks.rb?
|
food name: :potato, id: 1942, restoration: 1
|
||||||
food :name => :nettle_tea, :id => 4239, :restoration => 3
|
food name: :spinach_roll, id: 1969, restoration: 2
|
||||||
food :name => :nettle_tea, :id => 4240, :restoration => 3
|
food name: :baked_potato, id: 6701, restoration: 4
|
||||||
|
food name: :sweetcorn, id: 5988, restoration: 10
|
||||||
|
food name: :sweetcorn_bowl, id: 7088, restoration: 13
|
||||||
|
food name: :potato_with_butter, id: 6703, restoration: 14
|
||||||
|
food name: :chili_potato, id: 7054, restoration: 14
|
||||||
|
food name: :potato_with_cheese, id: 6705, restoration: 16
|
||||||
|
food name: :egg_potato, id: 7056, restoration: 16
|
||||||
|
food name: :mushroom_potato, id: 7058, restoration: 20
|
||||||
|
food name: :tuna_potato, id: 7060, restoration: 22
|
||||||
|
|
||||||
# Vegetables
|
# Dairy
|
||||||
food :name => :potato, :id => 1942, :restoration => 1
|
food name: :cheese, id: 1985, restoration: 2
|
||||||
food :name => :spinach_roll, :id => 1969, :restoration => 2
|
food name: :pot_of_cream, id: 2130, restoration: 1
|
||||||
food :name => :baked_potato, :id => 6701, :restoration => 4
|
|
||||||
food :name => :sweetcorn, :id => 5988, :restoration => 10
|
|
||||||
food :name => :sweetcorn_bowl, :id => 7088, :restoration => 13
|
|
||||||
food :name => :potato_with_butter, :id => 6703, :restoration => 14
|
|
||||||
food :name => :chili_potato, :id => 7054, :restoration => 14
|
|
||||||
food :name => :potato_with_cheese, :id => 6705, :restoration => 16
|
|
||||||
food :name => :egg_potato, :id => 7056, :restoration => 16
|
|
||||||
food :name => :mushroom_potato, :id => 7058, :restoration => 20
|
|
||||||
food :name => :tuna_potato, :id => 7060, :restoration => 22
|
|
||||||
|
|
||||||
# Dairy
|
# Gnome Food
|
||||||
food :name => :cheese, :id => 1985, :restoration => 2
|
food name: :toads_legs, id: 2152, restoration: 3
|
||||||
food :name => :pot_of_cream, :id => 2130, :restoration => 1
|
|
||||||
|
|
||||||
# Gnome Food
|
# Gnome Bowls
|
||||||
food :name => :toads_legs, :id => 2152, :restoration => 3
|
food name: :worm_hole, id: 2191, restoration: 12
|
||||||
|
food name: :worm_hole, id: 2233, restoration: 12
|
||||||
|
food name: :vegetable_ball, id: 2195, restoration: 12
|
||||||
|
food name: :vegetable_ball, id: 2235, restoration: 12
|
||||||
|
food name: :tangled_toads_legs, id: 2187, restoration: 15
|
||||||
|
food name: :tangled_toads_legs, id: 2231, restoration: 15
|
||||||
|
food name: :chocolate_bomb, id: 2185, restoration: 15
|
||||||
|
food name: :chocolate_bomb, id: 2229, restoration: 15
|
||||||
|
|
||||||
# Gnome Bowls
|
# Gnome Crunchies
|
||||||
food :name => :worm_hole, :id => 2191, :restoration => 12
|
food name: :toad_crunchies, id: 2217, restoration: 7
|
||||||
food :name => :worm_hole, :id => 2233, :restoration => 12
|
food name: :toad_crunchies, id: 2243, restoration: 7
|
||||||
food :name => :vegetable_ball, :id => 2195, :restoration => 12
|
food name: :spicy_crunchies, id: 2213, restoration: 7
|
||||||
food :name => :vegetable_ball, :id => 2235, :restoration => 12
|
food name: :spicy_crunchies, id: 2241, restoration: 7
|
||||||
food :name => :tangled_toads_legs, :id => 2187, :restoration => 15
|
food name: :worm_crunchies, id: 2205, restoration: 8
|
||||||
food :name => :tangled_toads_legs, :id => 2231, :restoration => 15
|
food name: :worm_crunchies, id: 2237, restoration: 8
|
||||||
food :name => :chocolate_bomb, :id => 2185, :restoration => 15
|
food name: :chocchip_crunchies, id: 2209, restoration: 7
|
||||||
food :name => :chocolate_bomb, :id => 2229, :restoration => 15
|
food name: :chocchip_crunchies, id: 2239, restoration: 7
|
||||||
|
|
||||||
# Gnome Crunchies
|
|
||||||
food :name => :toad_crunchies, :id => 2217, :restoration => 7
|
|
||||||
food :name => :toad_crunchies, :id => 2243, :restoration => 7
|
|
||||||
food :name => :spicy_crunchies, :id => 2213, :restoration => 7
|
|
||||||
food :name => :spicy_crunchies, :id => 2241, :restoration => 7
|
|
||||||
food :name => :worm_crunchies, :id => 2205, :restoration => 8
|
|
||||||
food :name => :worm_crunchies, :id => 2237, :restoration => 8
|
|
||||||
food :name => :chocchip_crunchies, :id => 2209, :restoration => 7
|
|
||||||
food :name => :chocchip_crunchies, :id => 2239, :restoration => 7
|
|
||||||
|
|
||||||
# Gnome Battas
|
|
||||||
food :name => :fruit_batta, :id => 2225, :restoration => 11
|
|
||||||
food :name => :fruit_batta, :id => 2277, :restoration => 11
|
|
||||||
food :name => :toad_batta, :id => 2221, :restoration => 11
|
|
||||||
food :name => :toad_batta, :id => 2255, :restoration => 11
|
|
||||||
food :name => :worm_batta, :id => 2219, :restoration => 11
|
|
||||||
food :name => :worm_batta, :id => 2253, :restoration => 11
|
|
||||||
food :name => :vegetable_batta, :id => 2227, :restoration => 11
|
|
||||||
food :name => :vegetable_batta, :id => 2281, :restoration => 11
|
|
||||||
food :name => :cheese_tom_batta, :id => 2223, :restoration => 11
|
|
||||||
food :name => :cheese_tom_batta, :id => 2259, :restoration => 11
|
|
||||||
|
|
||||||
# Gnome Cocktails
|
|
||||||
# Make new drink.rb file for drinks? That way it's seperated from food and says You drink, instead of you eat :{name}.
|
|
||||||
food :name => :fruit_blast, :id => 2034, :restoration => 9
|
|
||||||
food :name => :fruit_blast, :id => 2084, :restoration => 9
|
|
||||||
food :name => :pineapple_punch, :id => 2036, :restoration => 9
|
|
||||||
food :name => :pineapple_punch, :id => 2048, :restoration => 9
|
|
||||||
food :name => :wizard_blizzard, :id => 2040, :restoration => 5 # -4attack,+5strength also
|
|
||||||
food :name => :wizard_blizzard, :id => 2054, :restoration => 5 # -4attack,+5strength also
|
|
||||||
food :name => :short_green_guy, :id => 2038, :restoration => 5 # -4attack,+5strength also
|
|
||||||
food :name => :short_green_guy, :id => 2080, :restoration => 5 # -4attack,+5strength also
|
|
||||||
food :name => :drunk_dragon, :id => 2032, :restoration => 5 # -4attack,+6strength also
|
|
||||||
food :name => :drunk_dragon, :id => 2092, :restoration => 5 # -4attack,+6strength also
|
|
||||||
food :name => :chocolate_saturday, :id => 2030, :restoration => 7 # -4attack,+6strength also
|
|
||||||
food :name => :chocolate_saturday, :id => 2074, :restoration => 7 # -4attack,+6strength also
|
|
||||||
food :name => :blurberry_special, :id => 2028, :restoration => 7 # -4attack,+6strength also
|
|
||||||
food :name => :blurberry_special, :id => 2064, :restoration => 7 # -4attack,+6strength also
|
|
||||||
|
|
||||||
# Misc
|
|
||||||
|
|
||||||
|
# Gnome Battas
|
||||||
|
food name: :fruit_batta, id: 2225, restoration: 11
|
||||||
|
food name: :fruit_batta, id: 2277, restoration: 11
|
||||||
|
food name: :toad_batta, id: 2221, restoration: 11
|
||||||
|
food name: :toad_batta, id: 2255, restoration: 11
|
||||||
|
food name: :worm_batta, id: 2219, restoration: 11
|
||||||
|
food name: :worm_batta, id: 2253, restoration: 11
|
||||||
|
food name: :vegetable_batta, id: 2227, restoration: 11
|
||||||
|
food name: :vegetable_batta, id: 2281, restoration: 11
|
||||||
|
food name: :cheese_tom_batta, id: 2223, restoration: 11
|
||||||
|
food name: :cheese_tom_batta, id: 2259, restoration: 11
|
||||||
|
|
||||||
|
# Gnome Cocktails
|
||||||
|
# TODO: seperate from food, should say 'You drink' instead of 'You eat'.
|
||||||
|
food name: :fruit_blast, id: 2034, restoration: 9
|
||||||
|
food name: :fruit_blast, id: 2084, restoration: 9
|
||||||
|
food name: :pineapple_punch, id: 2036, restoration: 9
|
||||||
|
food name: :pineapple_punch, id: 2048, restoration: 9
|
||||||
|
food name: :wizard_blizzard, id: 2040, restoration: 5 # -4 attack, +5 strength also
|
||||||
|
food name: :wizard_blizzard, id: 2054, restoration: 5 # -4 attack, +5 strength also
|
||||||
|
food name: :short_green_guy, id: 2038, restoration: 5 # -4 attack, +5 strength also
|
||||||
|
food name: :short_green_guy, id: 2080, restoration: 5 # -4 attack, +5 strength also
|
||||||
|
food name: :drunk_dragon, id: 2032, restoration: 5 # -4 attack, +6 strength also
|
||||||
|
food name: :drunk_dragon, id: 2092, restoration: 5 # -4 attack, +6 strength also
|
||||||
|
food name: :chocolate_saturday, id: 2030, restoration: 7 # -4 attack, +6 strength also
|
||||||
|
food name: :chocolate_saturday, id: 2074, restoration: 7 # -4 attack, +6 strength also
|
||||||
|
food name: :blurberry_special, id: 2028, restoration: 7 # -4 attack, +6 strength also
|
||||||
|
food name: :blurberry_special, id: 2064, restoration: 7 # -4 attack, +6 strength also
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ java_import 'org.apollo.game.model.entity.Skill'
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
# Contains potion-related constants.
|
||||||
module Constants
|
module Constants
|
||||||
|
|
||||||
# The sound made when drinking a potion.
|
# The id of the sound made when drinking a potion.
|
||||||
DRINK_POTION_SOUND = 334
|
DRINK_POTION_SOUND = 334
|
||||||
|
|
||||||
# The id of an empty vial.
|
# The id of an empty vial.
|
||||||
@@ -25,10 +26,12 @@ class Potion < Consumable
|
|||||||
def consume(player)
|
def consume(player)
|
||||||
index = @doses.find_index(id) + 1
|
index = @doses.find_index(id) + 1
|
||||||
|
|
||||||
unless index == @doses.length # Consumable removes the previous potion for us, so we don't do it here.
|
if index != @doses.length # Consumable removes the old potion for us, so don't do it here.
|
||||||
player.inventory.add(@doses[index])
|
player.inventory.add(@doses[index])
|
||||||
player.send_message("You drink some of your #{name} potion.", true)
|
player.send_message("You drink some of your #{name} potion.", true)
|
||||||
player.send_message("You have #{ @doses.length - index } dose#{ "s" unless index == 3 } of potion left.", true)
|
|
||||||
|
remaining = "You have #{@doses.length - index} dose#{'s' unless index == 3} of potion left."
|
||||||
|
player.send_message(remaining, true)
|
||||||
else
|
else
|
||||||
player.send_message('You drink the last of your potion.', true)
|
player.send_message('You drink the last of your potion.', true)
|
||||||
player.inventory.add(Constants::EMPTY_VIAL_ID)
|
player.inventory.add(Constants::EMPTY_VIAL_ID)
|
||||||
@@ -37,7 +40,7 @@ class Potion < Consumable
|
|||||||
drink(player)
|
drink(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
def drink(player)
|
def drink(_player)
|
||||||
# Override to provide functionality
|
# Override to provide functionality
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -48,7 +51,7 @@ class BoostingPotion < Potion
|
|||||||
|
|
||||||
def initialize(id, name, doses, skills, boost)
|
def initialize(id, name, doses, skills, boost)
|
||||||
super(id, name, doses)
|
super(id, name, doses)
|
||||||
@skill_ids = skills.kind_of?(Array) ? skills : [ skills ]
|
@skill_ids = skills.is_a?(Array) ? skills : [skills]
|
||||||
@boost = boost
|
@boost = boost
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -56,7 +59,7 @@ class BoostingPotion < Potion
|
|||||||
@skill_ids.each do |id|
|
@skill_ids.each do |id|
|
||||||
skill = player.skill_set.skill(id)
|
skill = player.skill_set.skill(id)
|
||||||
max = skill.maximum_level
|
max = skill.maximum_level
|
||||||
level = [ skill.current_level, max ].min
|
level = [skill.current_level, max].min
|
||||||
|
|
||||||
new_current = @boost.call(max, level).floor
|
new_current = @boost.call(max, level).floor
|
||||||
player.skill_set.set_skill(id, Skill.new(skill.experience, new_current, max))
|
player.skill_set.set_skill(id, Skill.new(skill.experience, new_current, max))
|
||||||
@@ -65,17 +68,18 @@ class BoostingPotion < Potion
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the parameters for the potion, as an array. Raises if any of the specified keys do not exist
|
# Returns the parameters for the potion, as an array. Fails if any of the specified keys do not
|
||||||
|
# exist.
|
||||||
def get_parameters(hash, keys)
|
def get_parameters(hash, keys)
|
||||||
raise "Hash must contain the following keys: #{ keys.join(", ") }." unless hash.has_keys?(*keys)
|
fail "Hash must contain the following keys: #{keys.join(', ')}." unless hash.has_keys?(*keys)
|
||||||
|
|
||||||
return keys.map {|key| hash[key] }
|
keys.map { |key| hash[key] }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends a potion to the list of consumables.
|
# Appends a potion to the list of consumables.
|
||||||
def append_potion(hash)
|
def potion(hash)
|
||||||
class_name = 'Potion'
|
class_name = 'Potion'
|
||||||
keys = [ :name, :doses ]
|
keys = [:name, :doses]
|
||||||
|
|
||||||
unless (hash.size == 2)
|
unless (hash.size == 2)
|
||||||
keys << :skills << :boost
|
keys << :skills << :boost
|
||||||
@@ -83,36 +87,48 @@ def append_potion(hash)
|
|||||||
end
|
end
|
||||||
|
|
||||||
parameters = get_parameters(hash, keys)
|
parameters = get_parameters(hash, keys)
|
||||||
|
doses = hash[:doses]
|
||||||
hash[:doses].each { |dose| append_consumable(Object.const_get(class_name).new(dose, *parameters)) }
|
doses.each { |dose| append_consumable(Object.const_get(class_name).new(dose, *parameters)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Some frequently-used boosts and skills
|
# Some frequently-used boosts and skills
|
||||||
# Lambda parameters are | maximum_skill_level, current_skill_level |
|
# Lambda parameters are | maximum_skill_level, current_skill_level |
|
||||||
basic_combat_boost = lambda { |max, level| level * 1.10 + 3 }
|
basic_combat_boost = ->(_, level) { level * 1.10 + 3 }
|
||||||
super_combat_boost = lambda { |max, level| level * 1.15 + 5 }
|
super_combat_boost = ->(_, level) { level * 1.15 + 5 }
|
||||||
non_combat_boost = lambda { |max, level| level + 3 }
|
non_combat_boost = ->(_, level) { level + 3 }
|
||||||
|
|
||||||
|
ATTACK, STRENGTH, DEFENCE = Skill::ATTACK, Skill::STRENGTH, Skill::DEFENCE
|
||||||
|
MAGIC, RANGED, PRAYER = Skill::MAGIC, Skill::RANGED, Skill::PRAYER
|
||||||
|
|
||||||
all_skills = (Skill::ATTACK..Skill::RUNECRAFT).to_a
|
all_skills = (Skill::ATTACK..Skill::RUNECRAFT).to_a
|
||||||
combat_skills = [ Skill::ATTACK, Skill::STRENGTH, Skill::DEFENCE, Skill::MAGIC, Skill::RANGED ]
|
combat_skills = [ATTACK, STRENGTH, DEFENCE, MAGIC, RANGED]
|
||||||
|
|
||||||
|
|
||||||
# Boosting potions:
|
# Boosting potions:
|
||||||
# Note that the order of the elements must be: :name, :doses, :skills, :boost.
|
# Note that the order of the elements must be: :name, :doses, :skills, :boost.
|
||||||
append_potion :name => :attack, :doses => [ 2428, 121, 123, 125 ], :skills => Skill::ATTACK, :boost => basic_combat_boost
|
potion name: :attack, doses: [2428, 121, 123, 125], skills: ATTACK, boost: basic_combat_boost
|
||||||
append_potion :name => :strength, :doses => [ 113, 115, 117, 119 ], :skills => Skill::STRENGTH, :boost => basic_combat_boost
|
potion name: :strength, doses: [113, 115, 117, 119], skills: STRENGTH, boost: basic_combat_boost
|
||||||
append_potion :name => :defence, :doses => [ 2432, 133, 135, 137 ], :skills => Skill::DEFENCE, :boost => basic_combat_boost
|
potion name: :defence, doses: [2432, 133, 135, 137], skills: DEFENCE, boost: basic_combat_boost
|
||||||
|
|
||||||
append_potion :name => :agility, :doses => [ 3032, 3034, 3036, 3038 ], :skills => Skill::AGILITY, :boost => non_combat_boost
|
potion name: :agility, doses: [3032, 3034, 3036, 3038], skills: Skill::AGILITY,
|
||||||
append_potion :name => :fishing, :doses => [ 2438, 151, 153, 155 ], :skills => Skill::FISHING, :boost => non_combat_boost
|
boost: non_combat_boost
|
||||||
append_potion :name => :prayer, :doses => [ 2434, 139, 141, 143 ], :skills => Skill::PRAYER, :boost => lambda { |max, level| level / 4 + 7 }
|
potion name: :fishing, doses: [2438, 151, 153, 155], skills: Skill::FISHING,
|
||||||
|
boost: non_combat_boost
|
||||||
|
potion name: :prayer, doses: [2434, 139, 141, 143], skills: Skill::PRAYER,
|
||||||
|
boost: ->(_, level) { level / 4 + 7 }
|
||||||
|
|
||||||
append_potion :name => :restore, :doses => [ 2430, 127, 129, 131 ], :skills => combat_skills, :boost => lambda { |max, level| [ level * 1.3 + 10, max ].min }
|
potion name: :restore, doses: [2430, 127, 129, 131], skills: combat_skills,
|
||||||
append_potion :name => :super_restore, :doses => [ 3024, 3026, 3028, 3030 ], :skills => all_skills, :boost => lambda { |max, level| [ level * 1.25 + 8, max ].min }
|
boost: ->(_, level) { [level * 1.3 + 10, max].min }
|
||||||
|
potion name: :super_restore, doses: [3024, 3026, 3028, 3030], skills: all_skills,
|
||||||
|
boost: ->(_, level) { [level * 1.25 + 8, max].min }
|
||||||
|
|
||||||
append_potion :name => :super_attack, :doses => [ 2436, 145, 147, 149 ], :skills => Skill::ATTACK, :boost => super_combat_boost
|
potion name: :super_attack, doses: [2436, 145, 147, 149], skills: ATTACK, boost: super_combat_boost
|
||||||
append_potion :name => :super_strength, :doses => [ 2440, 157, 159, 161 ], :skills => Skill::STRENGTH, :boost => super_combat_boost
|
potion name: :super_strength, doses: [2440, 157, 159, 161], skills: STRENGTH,
|
||||||
append_potion :name => :super_defence, :doses => [ 2442, 163, 165, 167 ], :skills => Skill::DEFENCE, :boost => super_combat_boost
|
boost: super_combat_boost
|
||||||
append_potion :name => :ranging, :doses => [ 2444, 169, 171, 173 ], :skills => Skill::RANGED, :boost => lambda { |max, level| level * 1.10 + 4 }
|
potion name: :super_defence, doses: [2442, 163, 165, 167], skills: DEFENCE,
|
||||||
append_potion :name => :magic, :doses => [ 3040, 3042, 3044, 3046 ], :skills => Skill::MAGIC, :boost => lambda { |max, level| level + 4 }
|
boost: super_combat_boost
|
||||||
|
|
||||||
|
potion name: :ranging, doses: [2444, 169, 171, 173], skills: RANGED,
|
||||||
|
boost: ->(_, level) { level * 1.10 + 4 }
|
||||||
|
|
||||||
|
potion name: :magic, doses: [3040, 3042, 3044, 3046], skills: MAGIC,
|
||||||
|
boost: ->(_, level) { level + 4 }
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ ANIMATION_PULSES = 0
|
|||||||
LEVEL_THRESHOLD = 8
|
LEVEL_THRESHOLD = 8
|
||||||
EXP_PER_HIT = 5
|
EXP_PER_HIT = 5
|
||||||
|
|
||||||
|
# A DistancedAction for attacking a training dummy.
|
||||||
class DummyAction < DistancedAction
|
class DummyAction < DistancedAction
|
||||||
attr_reader :position
|
attr_reader :position
|
||||||
|
|
||||||
@@ -21,13 +22,7 @@ class DummyAction < DistancedAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
def executeAction
|
def executeAction
|
||||||
unless @started
|
if @started
|
||||||
@started = true
|
|
||||||
|
|
||||||
mob.send_message('You hit the dummy.', true)
|
|
||||||
mob.turn_to(position)
|
|
||||||
mob.play_animation(PUNCH_ANIMATION)
|
|
||||||
else
|
|
||||||
skills = mob.skill_set
|
skills = mob.skill_set
|
||||||
|
|
||||||
if (skills.skill(ATTACK_SKILL_ID).maximum_level >= LEVEL_THRESHOLD)
|
if (skills.skill(ATTACK_SKILL_ID).maximum_level >= LEVEL_THRESHOLD)
|
||||||
@@ -37,11 +32,17 @@ class DummyAction < DistancedAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
stop
|
stop
|
||||||
|
else
|
||||||
|
@started = true
|
||||||
|
|
||||||
|
mob.send_message('You hit the dummy.', true)
|
||||||
|
mob.turn_to(position)
|
||||||
|
mob.play_animation(PUNCH_ANIMATION)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @position == other.position)
|
get_class == other.get_class && @position == other.position
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
require 'java'
|
|
||||||
|
|
||||||
java_import 'org.apollo.game.model.Animation'
|
|
||||||
|
|
||||||
ANIMATIONS = {
|
|
||||||
162 => Animation::THINKING, 6503 => Animation::CLIMB_ROPE, 169 => Animation::NO, 164 => Animation::BOW, 13384 => Animation::GOBLIN_DANCE,
|
|
||||||
161 => Animation::CRY, 170 => Animation::LAUGH, 171 => Animation::CHEER, 163 => Animation::WAVE, 167 => Animation::BECKON,
|
|
||||||
3362 => Animation::PANIC, 172 => Animation::CLAP, 166 => Animation::DANCE, 13363 => Animation::JIG, 13364 => Animation::SPIN,
|
|
||||||
13365 => Animation::HEAD_BANG, 6506 => Animation::LEAN, 165 => Animation::ANGRY, 13368 => Animation::YAWN, 13366 => Animation::JOY_JUMP,
|
|
||||||
667 => Animation::GLASS_BOX, 13367 => Animation::RASPBERRY, 13369 => Animation::SALUTE, 13370 => Animation::SHRUG, 11100 => Animation::BLOW_KISS,
|
|
||||||
666 => Animation::GLASS_WALL, 168 => Animation::YES, 13383 => Animation::GOBLIN_BOW
|
|
||||||
}
|
|
||||||
|
|
||||||
# Intercept the button message.
|
|
||||||
on :message, :button do |player, message|
|
|
||||||
anim = ANIMATIONS[message.widget_id]
|
|
||||||
unless anim == nil
|
|
||||||
player.play_animation(anim)
|
|
||||||
message.terminate
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
require 'java'
|
||||||
|
|
||||||
|
java_import 'org.apollo.game.model.Animation'
|
||||||
|
|
||||||
|
ANIMATIONS = {
|
||||||
|
162 => Animation::THINKING, 6_503 => Animation::CLIMB_ROPE, 169 => Animation::NO,
|
||||||
|
164 => Animation::BOW, 13_384 => Animation::GOBLIN_DANCE, 161 => Animation::CRY,
|
||||||
|
170 => Animation::LAUGH, 171 => Animation::CHEER, 163 => Animation::WAVE,
|
||||||
|
167 => Animation::BECKON, 3_362 => Animation::PANIC, 172 => Animation::CLAP,
|
||||||
|
166 => Animation::DANCE, 13_363 => Animation::JIG, 13_364 => Animation::SPIN,
|
||||||
|
13_365 => Animation::HEAD_BANG, 6_506 => Animation::LEAN, 165 => Animation::ANGRY,
|
||||||
|
13_368 => Animation::YAWN, 13_366 => Animation::JOY_JUMP, 667 => Animation::GLASS_BOX,
|
||||||
|
13_367 => Animation::RASPBERRY, 13_369 => Animation::SALUTE, 13_370 => Animation::SHRUG,
|
||||||
|
11_100 => Animation::BLOW_KISS, 666 => Animation::GLASS_WALL, 168 => Animation::YES,
|
||||||
|
13_383 => Animation::GOBLIN_BOW
|
||||||
|
}
|
||||||
|
|
||||||
|
# Intercept the button message.
|
||||||
|
on :message, :button do |player, message|
|
||||||
|
anim = ANIMATIONS[message.widget_id]
|
||||||
|
|
||||||
|
unless anim.nil?
|
||||||
|
player.play_animation(anim)
|
||||||
|
message.terminate
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<author>Major</author>
|
<author>Major</author>
|
||||||
</authors>
|
</authors>
|
||||||
<scripts>
|
<scripts>
|
||||||
<script>emote-tab.rb</script>
|
<script>emote_tab.rb</script>
|
||||||
</scripts>
|
</scripts>
|
||||||
<dependencies />
|
<dependencies />
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -12,13 +12,15 @@ java_import 'org.apollo.game.model.entity.attr.BooleanAttribute'
|
|||||||
java_import 'org.apollo.game.model.entity.attr.NumericalAttribute'
|
java_import 'org.apollo.game.model.entity.attr.NumericalAttribute'
|
||||||
java_import 'org.apollo.game.model.entity.attr.StringAttribute'
|
java_import 'org.apollo.game.model.entity.attr.StringAttribute'
|
||||||
|
|
||||||
|
|
||||||
# Declares an attribute and adds its definition.
|
# Declares an attribute and adds its definition.
|
||||||
def declare_attribute(name, default, persistence=:transient)
|
def declare_attribute(name, default, persistence = :transient)
|
||||||
raise "Attribute #{name} clashes with an existing variable." if (Player.method_defined?(name) || Mob.method_defined?(name) || Npc.method_defined?(name))
|
if Player.method_defined?(name) || Mob.method_defined?(name) || Npc.method_defined?(name)
|
||||||
AttributeMap::define(name.to_s, AttributeDefinition.new(default, get_persistence(persistence), get_type(default)))
|
fail "Attribute #{name} clashes with an existing variable."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
definition = AttributeDefinition.new(default, get_persistence(persistence), get_type(default))
|
||||||
|
AttributeMap::define(name.to_s, definition)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
@@ -29,8 +31,8 @@ class Mob
|
|||||||
def method_missing(symbol, *args)
|
def method_missing(symbol, *args)
|
||||||
name = symbol.to_s.strip
|
name = symbol.to_s.strip
|
||||||
|
|
||||||
if name[-1] == "="
|
if name[-1] == '='
|
||||||
raise "Expected argument count of 1, received #{args.length}" unless args.length == 1
|
fail "Expected argument count of 1, received #{args.length}" unless args.length == 1
|
||||||
|
|
||||||
name = name[0...-1].strip # Drop the equals and trim whitespace.
|
name = name[0...-1].strip # Drop the equals and trim whitespace.
|
||||||
set_attribute(name, to_attribute(args[0]))
|
set_attribute(name, to_attribute(args[0]))
|
||||||
@@ -39,20 +41,19 @@ class Mob
|
|||||||
else
|
else
|
||||||
attribute = get_attribute(name)
|
attribute = get_attribute(name)
|
||||||
value = attribute.value
|
value = attribute.value
|
||||||
return (attribute.type == AttributeType::SYMBOL) ? value.to_sym : value
|
(attribute.type == AttributeType::SYMBOL) ? value.to_sym : value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Gets the appropriate attribute for the specified value.
|
||||||
# Gets the appropriate attribute for the specified value.
|
|
||||||
def to_attribute(value)
|
def to_attribute(value)
|
||||||
case value
|
case value
|
||||||
when String, Symbol then return StringAttribute.new(value.to_s, value.is_a?(Symbol))
|
when String, Symbol then return StringAttribute.new(value.to_s, value.is_a?(Symbol))
|
||||||
when Integer, Float then return NumericalAttribute.new(value)
|
when Integer, Float then return NumericalAttribute.new(value)
|
||||||
when TrueClass, FalseClass then return BooleanAttribute.new(value)
|
when TrueClass, FalseClass then return BooleanAttribute.new(value)
|
||||||
else raise "Undefined attribute type #{value.class}."
|
else fail "Undefined attribute type #{value.class}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -64,13 +65,15 @@ def get_type(value)
|
|||||||
when Integer then return AttributeType::LONG
|
when Integer then return AttributeType::LONG
|
||||||
when Float then return AttributeType::DOUBLE
|
when Float then return AttributeType::DOUBLE
|
||||||
when TrueClass, FalseClass then return AttributeType::BOOLEAN
|
when TrueClass, FalseClass then return AttributeType::BOOLEAN
|
||||||
else raise "Undefined attribute type #{value.class}."
|
else fail "Undefined attribute type #{value.class}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets the Persistence type of the specified value.
|
# Gets the Persistence type of the specified value.
|
||||||
def get_persistence(persistence)
|
def get_persistence(persistence)
|
||||||
raise "Undefined persistence type #{persistence}." unless [ :persistent, :transient ].include?(persistence)
|
unless [:persistent, :transient].include?(persistence)
|
||||||
|
fail "Undefined persistence type #{persistence}."
|
||||||
|
end
|
||||||
|
|
||||||
return (persistence == :persistent) ? AttributePersistence::PERSISTENT : AttributePersistence::TRANSIENT
|
(persistence == :persistent) ? AttributePersistence::PERSISTENT : AttributePersistence::TRANSIENT
|
||||||
end
|
end
|
||||||
@@ -10,22 +10,29 @@ java_import 'org.apollo.game.model.entity.Npc'
|
|||||||
|
|
||||||
# Information about npc spawning
|
# Information about npc spawning
|
||||||
#
|
#
|
||||||
# Npcs are passed to spawn npc as a hash. Every key and every non-integer value must be a Symbol. Every hash must implement the following:
|
# Npcs are passed to spawn npc as a hash. Every key and every non-integer value must be a Symbol.
|
||||||
# :name - the name of the npc. If this npc shares its name with another, append the specific id after the name (e.g. :woman_4)
|
# Every hash must implement the following:
|
||||||
|
# :name - the name of the npc. If this npc shares its name with another, append the specific id
|
||||||
|
# after the name (e.g. :woman_4)
|
||||||
# :x - the x coordinate where the npc will spawn.
|
# :x - the x coordinate where the npc will spawn.
|
||||||
# :y - the y coordinate where the npc will spawn.
|
# :y - the y coordinate where the npc will spawn.
|
||||||
# Optional arguments are as follows:
|
# Optional arguments are as follows:
|
||||||
# :face - the direction the npc should face when it spawns. Supported options are :north, :north_east, :east, :south_east, :south, :south_west, :west, and :north_west
|
# :face - the direction the npc should face when it spawns. Supported options are :north,
|
||||||
# :bounds - the rectangular bound that the npc can wander about in. Order is [bottom-left x-coordinate, bottom-left y-coordinate, top-right x-coordinate, top-right y-coordinate]
|
# :north_east, :east, :south_east, :south, :south_west, :west, and :north_west
|
||||||
# :delta_bounds - the rectangular bound that the npc can wander about in, as a difference from the spawn point. Order is [x-delta, y-delta]. Should not be used with :bounds.
|
# :bounds - the rectangular bound that the npc can wander about in. Order is
|
||||||
|
# [bottom-left x-coordinate, bottom-left y-coordinate, top-right x-coordinate,
|
||||||
|
# top-right y-coordinate]
|
||||||
|
# :delta_bounds - the rectangular bound that the npc can wander about in, as a difference from
|
||||||
|
# the spawn point. Order is [x-delta, y-delta]. Should not be used with :bounds.
|
||||||
# :spawn_animation - the animation that will be played when the npc spawns.
|
# :spawn_animation - the animation that will be played when the npc spawns.
|
||||||
# :spawn_graphic - the graphic that will be played when the npc spawns.
|
# :spawn_graphic - the graphic that will be played when the npc spawns.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Spawns an npc with the properties specified in the hash.
|
# Spawns an npc with the properties specified in the hash.
|
||||||
def spawn_npc(hash)
|
def spawn_npc(hash)
|
||||||
raise 'A name (or id), x coordinate, and y coordinate must be specified to spawn an npc.' unless (hash.has_key?(:name) || hash.has_key?(:id)) && hash.has_keys?(:x, :y)
|
unless (hash.key?(:name) || hash.key?(:id)) && hash.has_keys?(:x, :y)
|
||||||
|
fail 'A name (or id), x coordinate, and y coordinate must be specified to spawn an npc.'
|
||||||
|
end
|
||||||
|
|
||||||
npc = get_npc(hash)
|
npc = get_npc(hash)
|
||||||
spawn(npc, hash)
|
spawn(npc, hash)
|
||||||
npc
|
npc
|
||||||
@@ -46,8 +53,8 @@ def get_npc(hash)
|
|||||||
id = lookup_npc(hash.delete(:name))
|
id = lookup_npc(hash.delete(:name))
|
||||||
|
|
||||||
z = hash.delete(:z)
|
z = hash.delete(:z)
|
||||||
position = Position.new(hash.delete(:x), hash.delete(:y), z == nil ? 0 : z)
|
position = Position.new(hash.delete(:x), hash.delete(:y), z.nil? ? 0 : z)
|
||||||
return Npc.new($world, id, position)
|
Npc.new($world, id, position)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Applies a decoded hash (one aquired using parse_hash) to the specified npc.
|
# Applies a decoded hash (one aquired using parse_hash) to the specified npc.
|
||||||
@@ -58,7 +65,7 @@ def apply_decoded_hash(npc, hash)
|
|||||||
when :boundary then npc.boundaries = value
|
when :boundary then npc.boundaries = value
|
||||||
when :spawn_animation then npc.play_animation(Animation.new(value))
|
when :spawn_animation then npc.play_animation(Animation.new(value))
|
||||||
when :spawn_graphic then npc.play_graphic(Graphic.new(value))
|
when :spawn_graphic then npc.play_graphic(Graphic.new(value))
|
||||||
else raise "Unrecognised key #{key} - value #{value}."
|
else fail "Unrecognised key #{key} - value #{value}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -72,27 +79,27 @@ def decode_hash(position, hash)
|
|||||||
when :face
|
when :face
|
||||||
decoded[:face] = direction_to_position(value, position)
|
decoded[:face] = direction_to_position(value, position)
|
||||||
when :delta_bounds
|
when :delta_bounds
|
||||||
raise ':delta_bounds must have two values.' unless value.length == 2
|
fail ':delta_bounds must have two values.' unless value.length == 2
|
||||||
dx, dy, x, y, z = value[0], value[1], position.x, position.y, position.height
|
dx, dy, x, y, z = value[0], value[1], position.x, position.y, position.height
|
||||||
raise 'Delta values cannot be less than 0.' if (dx < 0 || dy < 0)
|
fail 'Delta values cannot be less than 0.' if dx < 0 || dy < 0
|
||||||
|
|
||||||
decoded[:boundary] = [ Position.new(x - dx, y - dy, z), Position.new(x + dx, y + dy, z) ]
|
decoded[:boundary] = [Position.new(x - dx, y - dy, z), Position.new(x + dx, y + dy, z)]
|
||||||
when :bounds
|
when :bounds
|
||||||
raise ':bounds must have four values.' unless value.length == 4
|
fail ':bounds must have four values.' unless value.length == 4
|
||||||
min_x, min_y, max_x, max_y = value[0], value[1], value[2], value[3]
|
min_x, min_y, max_x, max_y = value[0], value[1], value[2], value[3]
|
||||||
|
|
||||||
decoded[:boundary] = [ Position.new(min_x, min_y), Position.new(max_x, max_y) ]
|
decoded[:boundary] = [Position.new(min_x, min_y), Position.new(max_x, max_y)]
|
||||||
when :spawn_animation then decoded[:spawn_animation] = Animation.new(value)
|
when :spawn_animation then decoded[:spawn_animation] = Animation.new(value)
|
||||||
when :spawn_graphic then decoded[:spawn_graphic ] = Graphic.new(value)
|
when :spawn_graphic then decoded[:spawn_graphic] = Graphic.new(value)
|
||||||
else raise "Unrecognised key #{key} - value #{value}."
|
else fail "Unrecognised key #{key} - value #{value}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return decoded
|
decoded
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns a position that an entity at the specified position should be facing towards if they are
|
||||||
# Returns a position that an entity at the specified position should be facing towards if they are looking in the specified direction.
|
# looking in the specified direction.
|
||||||
def direction_to_position(direction, position)
|
def direction_to_position(direction, position)
|
||||||
x, y, z = position.x, position.y, position.height
|
x, y, z = position.x, position.y, position.height
|
||||||
|
|
||||||
@@ -121,13 +128,14 @@ class TemporaryNpcAction < Action
|
|||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
if executions == 0
|
if @executions == 0
|
||||||
spawn(mob, @hash)
|
spawn(mob, @hash)
|
||||||
execute_spawn_action
|
execute_spawn_action
|
||||||
else
|
else
|
||||||
execute_action
|
execute_action
|
||||||
end
|
end
|
||||||
executions += 1
|
|
||||||
|
@executions += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_action
|
def execute_action
|
||||||
@@ -168,17 +176,19 @@ RANDOM_EVENTS = []
|
|||||||
# Spawns a random event for the specified player.
|
# Spawns a random event for the specified player.
|
||||||
def send_random_event(player)
|
def send_random_event(player)
|
||||||
position = player.position
|
position = player.position
|
||||||
npc_position = Position.new(position.x + 1, position.y, position.height) # TODO Find an unoccupied tile instead of the assumption that (x + 1) is traversable!!
|
npc_position = Position.new(position.x + 1, position.y, position.height)
|
||||||
|
# TODO: Find an unoccupied tile instead of the assumption that (x + 1) is traversable!!
|
||||||
|
|
||||||
spawn_random_event(npc_position, false)
|
spawn_random_event(npc_position, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Spawns a random event in the specified position.
|
# Spawns a random event in the specified position.
|
||||||
# If 'combat' is false, only non-combat events will be spawned.
|
# If 'combat' is false, only non-combat events will be spawned.
|
||||||
def spawn_random_event(position, combat)
|
def spawn_random_event(_position, _combat)
|
||||||
event = RANDOM_EVENTS[rand(RANDOM_EVENTS.size)]
|
event = RANDOM_EVENTS[rand(RANDOM_EVENTS.size)]
|
||||||
attempts = 0
|
attempts = 0
|
||||||
while (event.combative && attempts < 5)
|
|
||||||
|
while event.combative && attempts < 5
|
||||||
event = RANDOM_EVENTS[rand(RANDOM_EVENTS.size)]
|
event = RANDOM_EVENTS[rand(RANDOM_EVENTS.size)]
|
||||||
attempts += 1
|
attempts += 1
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,66 +1,55 @@
|
|||||||
# Information about npc spawning
|
|
||||||
#
|
|
||||||
# Npcs are passed to spawn npc as a hash. Every key and every non-integer value must be a Symbol. Every hash must implement the following:
|
|
||||||
# :name - the name of the npc. If this npc shares its name with another, append the specific id after the name (e.g. :woman_4)
|
|
||||||
# :x - the x coordinate where the npc will spawn.
|
|
||||||
# :y - the y coordinate where the npc will spawn.
|
|
||||||
# Optional arguments are as follows:
|
|
||||||
# :face - the direction the npc should face when it spawns. Supported options are :north, :north_east, :east, :south_east, :south, :south_west, :west, and :north_west
|
|
||||||
# :bounds - the rectangular bound that the npc can wander about in. Order is [bottom-left x-coordinate, bottom-left y-coordinate, top-right x-coordinate, top-right y-coordinate]
|
|
||||||
# :delta_bounds - the rectangular bound that the npc can wander about in, as a difference from the spawn point. Order is [x-delta, y-delta]. Should not be used with :bounds.
|
|
||||||
# :spawn_animation - the animation that will be played when the npc spawns.
|
|
||||||
# :spawn_graphic - the graphic that will be played when the npc spawns.
|
|
||||||
|
|
||||||
|
|
||||||
# Generic npcs
|
# Generic npcs
|
||||||
|
|
||||||
spawn_npc :name => :man, :x => 3276, :y => 3186
|
spawn_npc name: :man, x: 3276, y: 3186
|
||||||
|
|
||||||
# Palace guards
|
# Palace guards
|
||||||
|
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3283, :y => 3161 # String must be used here because the actual npc name is 'Al-Kharid warrior', and symbols don't support hyphens.
|
spawn_npc name: 'Al-Kharid warrior', x: 3283, y: 3161
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3285, :y => 3174
|
spawn_npc name: 'Al-Kharid warrior', x: 3285, y: 3174
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3286, :y => 3164
|
spawn_npc name: 'Al-Kharid warrior', x: 3286, y: 3164
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3287, :y => 3168
|
spawn_npc name: 'Al-Kharid warrior', x: 3287, y: 3168
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3288, :y => 3169
|
spawn_npc name: 'Al-Kharid warrior', x: 3288, y: 3169
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3290, :y => 3162
|
spawn_npc name: 'Al-Kharid warrior', x: 3290, y: 3162
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3295, :y => 3162
|
spawn_npc name: 'Al-Kharid warrior', x: 3295, y: 3162
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3295, :y => 3170
|
spawn_npc name: 'Al-Kharid warrior', x: 3295, y: 3170
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3297, :y => 3175
|
spawn_npc name: 'Al-Kharid warrior', x: 3297, y: 3175
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3300, :y => 3171
|
spawn_npc name: 'Al-Kharid warrior', x: 3300, y: 3171
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3301, :y => 3164
|
spawn_npc name: 'Al-Kharid warrior', x: 3301, y: 3164
|
||||||
spawn_npc :name => "Al-Kharid warrior", :x => 3301, :y => 3168
|
spawn_npc name: 'Al-Kharid warrior', x: 3301, y: 3168
|
||||||
|
|
||||||
spawn_npc :name => :shantay_guard_838, :x => 3301, :y => 3120
|
spawn_npc name: :shantay_guard_838, x: 3301, y: 3120
|
||||||
spawn_npc :name => :shantay_guard, :x => 3304, :y => 3119
|
spawn_npc name: :shantay_guard, x: 3304, y: 3119
|
||||||
spawn_npc :name => :shantay_guard_838, :x => 3307, :y => 3122
|
spawn_npc name: :shantay_guard_838, x: 3307, y: 3122
|
||||||
|
|
||||||
# Mine
|
# Mine
|
||||||
|
|
||||||
spawn_npc :name => :scorpion, :x => 3296, :y => 3294
|
spawn_npc name: :scorpion, x: 3296, y: 3294
|
||||||
spawn_npc :name => :scorpion, :x => 3298, :y => 3280
|
spawn_npc name: :scorpion, x: 3298, y: 3280
|
||||||
spawn_npc :name => :scorpion, :x => 3299, :y => 3299
|
spawn_npc name: :scorpion, x: 3299, y: 3299
|
||||||
spawn_npc :name => :scorpion, :x => 3299, :y => 3309
|
spawn_npc name: :scorpion, x: 3299, y: 3309
|
||||||
spawn_npc :name => :scorpion, :x => 3300, :y => 3287
|
spawn_npc name: :scorpion, x: 3300, y: 3287
|
||||||
spawn_npc :name => :scorpion, :x => 3301, :y => 3305
|
spawn_npc name: :scorpion, x: 3301, y: 3305
|
||||||
|
|
||||||
|
|
||||||
# Functional npcs
|
# Functional npcs
|
||||||
|
|
||||||
spawn_npc :name => :gnome_pilot, :x => 3279, :y => 3213
|
spawn_npc name: :gnome_pilot, x: 3279, y: 3213
|
||||||
|
|
||||||
spawn_npc :name => :banker_496, :x => 3267, :y => 3164, :face => :east # TODO are these the correct banker ids?
|
# TODO: are these the correct banker ids?
|
||||||
spawn_npc :name => :banker_497, :x => 3267, :y => 3166, :face => :east
|
spawn_npc name: :banker_496, x: 3267, y: 3164, face: :east
|
||||||
spawn_npc :name => :banker_496, :x => 3267, :y => 3167, :face => :east
|
spawn_npc name: :banker_497, x: 3267, y: 3166, face: :east
|
||||||
spawn_npc :name => :banker_497, :x => 3267, :y => 3168, :face => :east
|
spawn_npc name: :banker_496, x: 3267, y: 3167, face: :east
|
||||||
spawn_npc :name => :banker_496, :x => 3267, :y => 3169, :face => :east
|
spawn_npc name: :banker_497, x: 3267, y: 3168, face: :east
|
||||||
|
spawn_npc name: :banker_496, x: 3267, y: 3169, face: :east
|
||||||
|
|
||||||
spawn_npc :name => :gem_trader, :x => 3287, :y => 3210
|
spawn_npc name: :gem_trader, x: 3287, y: 3210
|
||||||
spawn_npc :name => :zeke, :x => 3289, :y => 3189
|
spawn_npc name: :zeke, x: 3289, y: 3189
|
||||||
spawn_npc :name => :shantay, :x => 3304, :y => 3124
|
spawn_npc name: :shantay, x: 3304, y: 3124
|
||||||
|
|
||||||
spawn_npc :name => :rug_merchant_2296, :x => 3311, :y => 3109, :face => :west
|
spawn_npc name: :rug_merchant_2296, x: 3311, y: 3109, face: :west
|
||||||
spawn_npc :name => :ranael, :x => 3315, :y => 3163, :face => :north
|
spawn_npc name: :ranael, x: 3315, y: 3163, face: :north
|
||||||
spawn_npc :name => :shop_assistant_525, :x => 3315, :y => 3178, :face => :north # TODO are these the correct shop staff ids?
|
|
||||||
spawn_npc :name => :shop_keeper_524, :x => 3315, :y => 3180, :face => :west
|
# TODO: are these the correct shop staff ids?
|
||||||
spawn_npc :name => :louie_legs, :x => 3316, :y => 3175, :face => :west
|
spawn_npc name: :shop_assistant_525, x: 3315, y: 3178, face: :north
|
||||||
|
spawn_npc name: :shop_keeper_524, x: 3315, y: 3180, face: :west
|
||||||
|
spawn_npc name: :louie_legs, x: 3316, y: 3175, face: :west
|
||||||
|
|||||||
@@ -1,53 +1,39 @@
|
|||||||
# Information about npc spawning
|
|
||||||
#
|
|
||||||
# Npcs are passed to spawn npc as a hash. Every key and every non-integer value must be a Symbol. Every hash must implement the following:
|
|
||||||
# :name - the name of the npc. If this npc shares its name with another, append the specific id after the name (e.g. :woman_4)
|
|
||||||
# :x - the x coordinate where the npc will spawn.
|
|
||||||
# :y - the y coordinate where the npc will spawn.
|
|
||||||
# Optional arguments are as follows:
|
|
||||||
# :face - the direction the npc should face when it spawns. Supported options are :north, :north_east, :east, :south_east, :south, :south_west, :west, and :north_west
|
|
||||||
# :bounds - the rectangular bound that the npc can wander about in. Order is [bottom-left x-coordinate, bottom-left y-coordinate, top-right x-coordinate, top-right y-coordinate]
|
|
||||||
# :delta_bounds - the rectangular bound that the npc can wander about in, as a difference from the spawn point. Order is [x-delta, y-delta]. Should not be used with :bounds.
|
|
||||||
# :spawn_animation - the animation that will be played when the npc spawns.
|
|
||||||
# :spawn_graphic - the graphic that will be played when the npc spawns.
|
|
||||||
|
|
||||||
|
|
||||||
# Generic npcs
|
# Generic npcs
|
||||||
|
|
||||||
spawn_npc :name => :man, :x => 3095, :y => 3508
|
spawn_npc name: :man, x: 3095, y: 3508
|
||||||
spawn_npc :name => :man, :x => 3095, :y => 3511
|
spawn_npc name: :man, x: 3095, y: 3511
|
||||||
spawn_npc :name => :man, :x => 3098, :y => 3509
|
spawn_npc name: :man, x: 3098, y: 3509
|
||||||
|
|
||||||
spawn_npc :name => :guard, :x => 3108, :y => 3514
|
spawn_npc name: :guard, x: 3108, y: 3514
|
||||||
spawn_npc :name => :guard, :x => 3110, :y => 3514
|
spawn_npc name: :guard, x: 3110, y: 3514
|
||||||
spawn_npc :name => :guard, :x => 3113, :y => 3514
|
spawn_npc name: :guard, x: 3113, y: 3514
|
||||||
spawn_npc :name => :guard, :x => 3113, :y => 3516
|
spawn_npc name: :guard, x: 3113, y: 3516
|
||||||
|
|
||||||
spawn_npc :name => :sheep_43, :x => 3053, :y => 3514
|
spawn_npc name: :sheep_43, x: 3053, y: 3514
|
||||||
spawn_npc :name => :sheep_43, :x => 3053, :y => 3517
|
spawn_npc name: :sheep_43, x: 3053, y: 3517
|
||||||
spawn_npc :name => :sheep_43, :x => 3053, :y => 3518
|
spawn_npc name: :sheep_43, x: 3053, y: 3518
|
||||||
spawn_npc :name => :sheep_43, :x => 3056, :y => 3517
|
spawn_npc name: :sheep_43, x: 3056, y: 3517
|
||||||
|
|
||||||
spawn_npc :name => :mugger, :x => 3076, :y => 3504
|
spawn_npc name: :mugger, x: 3076, y: 3504
|
||||||
|
|
||||||
spawn_npc :name => :monk, :x => 3044, :y => 3491
|
|
||||||
spawn_npc :name => :monk, :x => 3045, :y => 3483
|
|
||||||
spawn_npc :name => :monk, :x => 3045, :y => 3497
|
|
||||||
spawn_npc :name => :monk, :x => 3050, :y => 3490
|
|
||||||
spawn_npc :name => :monk, :x => 3054, :y => 3490
|
|
||||||
spawn_npc :name => :monk, :x => 3058, :y => 3497
|
|
||||||
|
|
||||||
|
spawn_npc name: :monk, x: 3044, y: 3491
|
||||||
|
spawn_npc name: :monk, x: 3045, y: 3483
|
||||||
|
spawn_npc name: :monk, x: 3045, y: 3497
|
||||||
|
spawn_npc name: :monk, x: 3050, y: 3490
|
||||||
|
spawn_npc name: :monk, x: 3054, y: 3490
|
||||||
|
spawn_npc name: :monk, x: 3058, y: 3497
|
||||||
|
|
||||||
# Functional npcs
|
# Functional npcs
|
||||||
|
|
||||||
spawn_npc :name => :brother_jered, :x => 3045, :y => 3488
|
spawn_npc name: :brother_jered, x: 3045, y: 3488
|
||||||
spawn_npc :name => :brother_althric, :x => 3054, :y => 3504
|
spawn_npc name: :brother_althric, x: 3054, y: 3504
|
||||||
spawn_npc :name => :abbot_langley, :x => 3059, :y => 3484
|
spawn_npc name: :abbot_langley, x: 3059, y: 3484
|
||||||
spawn_npc :name => :oziach, :x => 3067, :y => 3518, :face => :east
|
spawn_npc name: :oziach, x: 3067, y: 3518, face: :east
|
||||||
spawn_npc :name => :shop_assistant, :x => 3079, :y => 3509
|
spawn_npc name: :shop_assistant, x: 3079, y: 3509
|
||||||
spawn_npc :name => :shop_keeper, :x => 3082, :y => 3513
|
spawn_npc name: :shop_keeper, x: 3082, y: 3513
|
||||||
spawn_npc :name => :banker, :x => 3096, :y => 3489, :face => :west # TODO probably not all the same bankers.
|
# TODO: probably not all the same bankers.
|
||||||
spawn_npc :name => :banker, :x => 3096, :y => 3491, :face => :west
|
spawn_npc name: :banker, x: 3096, y: 3489, face: :west
|
||||||
spawn_npc :name => :banker, :x => 3096, :y => 3492, :face => :north
|
spawn_npc name: :banker, x: 3096, y: 3491, face: :west
|
||||||
spawn_npc :name => :banker, :x => 3098, :y => 3492, :face => :north
|
spawn_npc name: :banker, x: 3096, y: 3492, face: :north
|
||||||
spawn_npc :name => :mage_of_zamorak, :x => 3106, :y => 3560
|
spawn_npc name: :banker, x: 3098, y: 3492, face: :north
|
||||||
|
spawn_npc name: :mage_of_zamorak, x: 3106, y: 3560
|
||||||
|
|||||||
@@ -1,29 +1,16 @@
|
|||||||
# Information about npc spawning
|
|
||||||
#
|
|
||||||
# Npcs are passed to spawn npc as a hash. Every key and every non-integer value must be a Symbol. Every hash must implement the following:
|
|
||||||
# :name - the name of the npc. If this npc shares its name with another, append the specific id after the name (e.g. :woman_4)
|
|
||||||
# :x - the x coordinate where the npc will spawn.
|
|
||||||
# :y - the y coordinate where the npc will spawn.
|
|
||||||
# Optional arguments are as follows:
|
|
||||||
# :face - the direction the npc should face when it spawns. Supported options are :north, :north_east, :east, :south_east, :south, :south_west, :west, and :north_west
|
|
||||||
# :bounds - the rectangular bound that the npc can wander about in. Order is [bottom-left x-coordinate, bottom-left y-coordinate, top-right x-coordinate, top-right y-coordinate]
|
|
||||||
# :delta_bounds - the rectangular bound that the npc can wander about in, as a difference from the spawn point. Order is [x-delta, y-delta]. Should not be used with :bounds.
|
|
||||||
# :spawn_animation - the animation that will be played when the npc spawns.
|
|
||||||
# :spawn_graphic - the graphic that will be played when the npc spawns.
|
|
||||||
|
|
||||||
|
|
||||||
# Generic npcs
|
# Generic npcs
|
||||||
|
|
||||||
spawn_npc :name => :woman_4, :x => 3232, :y => 3207 # southernmost house
|
spawn_npc name: :woman_4, x: 3232, y: 3207 # southernmost house
|
||||||
spawn_npc :name => :man_1, :x => 3231, :y => 3237 # house by willow tree
|
spawn_npc name: :man_1, x: 3231, y: 3237 # house by willow tree
|
||||||
spawn_npc :name => :man_2, :x => 3224, :y => 3240 # house by willow tree
|
spawn_npc name: :man_2, x: 3224, y: 3240 # house by willow tree
|
||||||
spawn_npc :name => :woman_5, :x => 3229, :y => 2329 # house by willow tree
|
spawn_npc name: :woman_5, x: 3229, y: 2329 # house by willow tree
|
||||||
|
|
||||||
# Functional npcs
|
# Functional npcs
|
||||||
|
|
||||||
spawn_npc :name => :hans, :x => 3221, :y => 3221
|
spawn_npc name: :hans, x: 3221, y: 3221
|
||||||
spawn_npc :name => :father_aereck, :x => 3243, :y => 3210
|
spawn_npc name: :father_aereck, x: 3243, y: 3210
|
||||||
spawn_npc :name => :bob, :x => 3231, :y => 3203
|
spawn_npc name: :bob, x: 3231, y: 3203
|
||||||
spawn_npc :name => :shop_keeper, :x => 3212, :y => 3247
|
spawn_npc name: :shop_keeper, x: 3212, y: 3247
|
||||||
spawn_npc :name => :shop_assistant, :x => 3211, :y => 3245
|
spawn_npc name: :shop_assistant, x: 3211, y: 3245
|
||||||
spawn_npc :name => :lumbridge_guide, :x => 3232, :y => 3229
|
spawn_npc name: :lumbridge_guide, x: 3232, y: 3229
|
||||||
|
|||||||
@@ -3,32 +3,33 @@ require 'java'
|
|||||||
java_import 'org.apollo.game.message.impl.HintIconMessage'
|
java_import 'org.apollo.game.message.impl.HintIconMessage'
|
||||||
java_import 'org.apollo.game.message.impl.SwitchTabInterfaceMessage'
|
java_import 'org.apollo.game.message.impl.SwitchTabInterfaceMessage'
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# The ids of tabs that are displayed when the player has yet to start the tutorial.
|
# The ids of tabs that are displayed when the player has yet to start the tutorial.
|
||||||
INITIAL_TABS = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2449, 904, -1, -1 ]
|
INITIAL_TABS = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2449, 904, -1, -1]
|
||||||
|
|
||||||
# The character design interface id.
|
# The character design interface id.
|
||||||
CHARACTER_DESIGN = 3559
|
CHARACTER_DESIGN = 3559
|
||||||
|
|
||||||
# The Runescape guide Npc
|
# The Runescape guide Npc
|
||||||
@runescape_guide = spawn_npc :name => :runescape_guide, :x => 3093, :y => 3107
|
@runescape_guide = spawn_npc name: :runescape_guide, x: 3093, y: 3107
|
||||||
|
|
||||||
# Sends the appropriate data to the client when the player logs in to the game.
|
# Sends the appropriate data to the client when the player logs in to the game.
|
||||||
on :login do |event, player|
|
on :login do |_event, player|
|
||||||
if player.in_tutorial_island
|
if player.in_tutorial_island && player.privilege_level != RIGHTS_ADMIN
|
||||||
# TutorialInstructions::show_instruction(player)
|
TutorialInstructions.show_instruction(player)
|
||||||
# INITIAL_TABS.each_with_index { |tab, index| player.send(SwitchTabInterfaceMessage.new(index, tab)) }
|
|
||||||
|
|
||||||
if (player.tutorial_island_progress == :not_started)
|
INITIAL_TABS.each_with_index do |tab, index|
|
||||||
|
player.send(SwitchTabInterfaceMessage.new(index, tab))
|
||||||
|
end
|
||||||
|
|
||||||
|
if player.tutorial_island_progress == :not_started
|
||||||
show_hint_icon(player)
|
show_hint_icon(player)
|
||||||
player.interface_set.open_window(CHARACTER_DESIGN)
|
player.interface_set.open_window(CHARACTER_DESIGN)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# The conversation with the Runescape Guide, when on tutorial island.
|
# The conversation with the Runescape Guide, when on tutorial island.
|
||||||
conversation :tutorial_runescape_guide do
|
conversation :tutorial_runescape_guide do
|
||||||
|
|
||||||
@@ -39,60 +40,63 @@ conversation :tutorial_runescape_guide do
|
|||||||
|
|
||||||
precondition { |player| player.tutorial_island_progress == :not_started }
|
precondition { |player| player.tutorial_island_progress == :not_started }
|
||||||
|
|
||||||
text "Greetings! I see you are a new arrival to this land. My job is to welcome all new visitors. So welcome!"
|
text 'Greetings! I see you are a new arrival to this land. My job is to welcome all new '\
|
||||||
|
'visitors. So welcome!'
|
||||||
|
|
||||||
continue :dialogue => :talk_to_people do |player|
|
continue dialogue: :talk_to_people do |player|
|
||||||
player.tutorial_island_progress = :talk_to_people
|
player.tutorial_island_progress = :talk_to_people
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The Guide welcomes back the Player if they speak to him after they have already gone through
|
||||||
# The Guide welcomes back the Player if they speak to him after they have already gone through the conversation once.
|
# the conversation once.
|
||||||
dialogue :welcome_back do
|
dialogue :welcome_back do
|
||||||
type :npc_speech
|
type :npc_speech
|
||||||
npc :runescape_guide
|
npc :runescape_guide
|
||||||
|
|
||||||
precondition { |player| player.tutorial_island_progress != :not_started }
|
precondition { |player| player.tutorial_island_progress != :not_started }
|
||||||
|
|
||||||
text "Welcome back."
|
text 'Welcome back.'
|
||||||
|
|
||||||
continue :dialogue => :talk_to_people
|
continue dialogue: :talk_to_people
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# The Guide tells Players to speak to people in order to succeed.
|
# The Guide tells Players to speak to people in order to succeed.
|
||||||
dialogue :talk_to_people do
|
dialogue :talk_to_people do
|
||||||
type :npc_speech
|
type :npc_speech
|
||||||
npc :runescape_guide
|
npc :runescape_guide
|
||||||
|
|
||||||
text "You have already learned the first thing you need to succeed in this world: talking to people!",
|
text 'You have already learned the first thing you need to succeed in this world: talking to '\
|
||||||
"You will find many inhabitants of this world have useful things to say to you. By clicking on them with your mouse you can talk to them.",
|
'people!',
|
||||||
"I would also suggest reading through some of the supporting information on the website. There you can find maps, a bestiary, and much more."
|
'You will find many inhabitants of this world have useful things to say to you. By '\
|
||||||
|
'clicking on them with your mouse you can talk to them.',
|
||||||
|
'I would also suggest reading through some of the supporting information on the website.'\
|
||||||
|
' There you can find maps, a bestiary, and much more.'
|
||||||
|
|
||||||
continue :dialogue => :go_through_door
|
continue dialogue: :go_through_door
|
||||||
end
|
end
|
||||||
|
|
||||||
# The Guide tells Players to go through the door, advancing the tutorial progress if this is the first time the Player has heard this.
|
# The Guide tells Players to go through the door, advancing the tutorial progress if this is the
|
||||||
|
# first time the Player has heard this.
|
||||||
dialogue :go_through_door do
|
dialogue :go_through_door do
|
||||||
type :npc_speech
|
type :npc_speech
|
||||||
npc :runescape_guide
|
npc :runescape_guide
|
||||||
|
|
||||||
text "To continue the tutorial go through that door over there, and speak to your first instructor."
|
text 'To continue the tutorial go through that door over there, and speak to your first '\
|
||||||
|
'instructor.'
|
||||||
|
|
||||||
close do |player|
|
close do |player|
|
||||||
if (player.tutorial_island_progress < :runescape_guide_finished)
|
if player.tutorial_island_progress < :runescape_guide_finished
|
||||||
reset_hint_icon(player)
|
reset_hint_icon(player)
|
||||||
# TODO door hint icon
|
# TODO: door hint icon
|
||||||
player.tutorial_island_progress = :runescape_guide_finished
|
player.tutorial_island_progress = :runescape_guide_finished
|
||||||
end
|
end
|
||||||
|
|
||||||
TutorialInstructions.show_instruction(player)
|
TutorialInstructions.show_instruction(player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Enables the hint icon above the Runescape guide.
|
# Enables the hint icon above the Runescape guide.
|
||||||
def show_hint_icon(player)
|
def show_hint_icon(player)
|
||||||
player.send(HintIconMessage.for_npc(@runescape_guide.index))
|
player.send(HintIconMessage.for_npc(@runescape_guide.index))
|
||||||
@@ -100,5 +104,5 @@ end
|
|||||||
|
|
||||||
# Resets the hint icon.
|
# Resets the hint icon.
|
||||||
def reset_hint_icon(player)
|
def reset_hint_icon(player)
|
||||||
player.send(HintIconMessage.reset_npc())
|
player.send(HintIconMessage.reset_npc)
|
||||||
end
|
end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# TODO update the status to :moving_around when the door is opened
|
# TODO: update the status to :moving_around when the door is opened
|
||||||
|
|
||||||
# Contains members related to the instructions issues during tutorial island.
|
# Contains members related to the instructions issues during tutorial island.
|
||||||
module TutorialInstructions
|
module TutorialInstructions
|
||||||
@@ -18,104 +18,115 @@ module TutorialInstructions
|
|||||||
when :given_axe then :viewing_items
|
when :given_axe then :viewing_items
|
||||||
when :cut_tree then :cut_tree
|
when :cut_tree then :cut_tree
|
||||||
when :cutting_tree then :please_wait
|
when :cutting_tree then :please_wait
|
||||||
else raise "No dialogue for current stage #{progress} exists."
|
else fail 'No dialogue for current stage #{progress} exists.'
|
||||||
end
|
end
|
||||||
|
|
||||||
dialogue = instructions.part(name)
|
dialogue = instructions.part(name)
|
||||||
send_dialogue(player, dialogue)
|
send_dialogue(player, dialogue)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# The one-sided 'conversation' of instruction instructions.
|
# The one-sided 'conversation' of instruction instructions.
|
||||||
conversation :tutorial_island_instructions do
|
conversation :tutorial_island_instructions do
|
||||||
|
|
||||||
# The initial instruction displayed when the player logs in, before they have spoken to the guide.
|
# The initial instruction displayed when the player logs in, before they have spoken to the
|
||||||
|
# guide.
|
||||||
dialogue :getting_started do
|
dialogue :getting_started do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Getting started"
|
title 'Getting started'
|
||||||
text "To start the tutorial, use your left mouse button to click on the Runescape Guide in this room. He is indicated by "\
|
text 'To start the tutorial, use your left mouse button to click on the Runescape Guide in '\
|
||||||
"a flashing yellow arrow above his head. If you can't see him, use your keyboard's arrow keys to rotate the view."
|
'this room. He is indicated by a flashing yellow arrow above his head. If you can\'t '\
|
||||||
|
'see him, use your keyboard\'s arrow keys to rotate the view.'
|
||||||
end
|
end
|
||||||
|
|
||||||
# The instruction displayed after the player has spoken to the Runescape Guide.
|
# The instruction displayed after the player has spoken to the Runescape Guide.
|
||||||
dialogue :scenery do
|
dialogue :scenery do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Interacting with scenery"
|
title 'Interacting with scenery'
|
||||||
text "You can interact with many items of the scenery by simply clicking on them. Right clicking will also give more options. "\
|
text 'You can interact with many items of the scenery by simply clicking on them. Right '\
|
||||||
"Click on the door indicated with the yellow arrow to go through to the next area and speak with your next instructor."
|
'clicking will also give more options. Click on the door indicated with the yellow '\
|
||||||
|
'arrow to go through to the next area and speak with your next instructor.'
|
||||||
end
|
end
|
||||||
|
|
||||||
## TODO !! When we have door support, the player's tutorial island progress needs to be set to :moving_around when they walk through the door !!
|
# TODO: The player's tutorial island progress needs to be set to :moving_around when they walk
|
||||||
|
# through the door !!
|
||||||
|
|
||||||
# The instruction displayed after the player has left the initial building.
|
# The instruction displayed after the player has left the initial building.
|
||||||
dialogue :moving_around do
|
dialogue :moving_around do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Moving around"
|
title 'Moving around'
|
||||||
text "Follow the path to find the next instructor. Clicking on the ground will walk you to that point. Talk to the survival expert "\
|
text 'Follow the path to find the next instructor. Clicking on the ground will walk you to '\
|
||||||
"by the pond to continue the tutorial. Remember you can rotate the view by pressing the arrow keys."
|
'that point. Talk to the survival expert by the pond to continue the tutorial. '\
|
||||||
|
'Remember you can rotate the view by pressing the arrow keys.'
|
||||||
end
|
end
|
||||||
|
|
||||||
# The instruction displayed after the player has been given the tinderbox and bronze axe by the Survival Guide.
|
# The instruction displayed after the player has been given the tinderbox and bronze axe by the
|
||||||
|
# Survival Guide.
|
||||||
dialogue :viewing_items do
|
dialogue :viewing_items do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Viewing the items you were given"
|
title 'Viewing the items you were given'
|
||||||
text "Click on the flashing backpack icon to the right side of the main window to view your inventory. Your inventory is a list of "\
|
text 'Click on the flashing backpack icon to the right side of the main window to view your '\
|
||||||
"everything you have in your backpack."
|
'inventory. Your inventory is a list of everything you have in your backpack.'
|
||||||
end
|
end
|
||||||
|
|
||||||
# The instruction displayed before the player has begun to cut the tree.
|
# The instruction displayed before the player has begun to cut the tree.
|
||||||
dialogue :cut_tree do
|
dialogue :cut_tree do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Cut down a tree"
|
title 'Cut down a tree'
|
||||||
text "You can click on the backpack icon at any time to view the items that you currently have in your inventory. You will see that you "\
|
text 'You can click on the backpack icon at any time to view the items that you currently '\
|
||||||
"now have an axe in your inventory. Use this to get some logs by clicking on the indicated tree."
|
'have in your inventory. You will see that you now have an axe in your inventory. '\
|
||||||
end
|
'Use this to get some logs by clicking on the indicated tree.'
|
||||||
|
end
|
||||||
|
|
||||||
# The instruction displayed when the player begins to cut the tree.
|
# The instruction displayed when the player begins to cut the tree.
|
||||||
dialogue :please_wait do
|
dialogue :please_wait do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Please wait..."
|
title 'Please wait...'
|
||||||
text "Your character is now attempting to cut down the tree. Sit back for a moment whilst he does all the hard work." # TODO she instead of he if applicable
|
text 'Your character is now attempting to cut down the tree. Sit back for a moment whilst '\
|
||||||
end
|
'he does all the hard work.' # TODO: she instead of he if applicable
|
||||||
|
end
|
||||||
|
|
||||||
# The instruction displayed after the player has successfully cut logs from the tree.
|
# The instruction displayed after the player has successfully cut logs from the tree.
|
||||||
dialogue :make_a_fire do
|
dialogue :make_a_fire do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Making a fire"
|
title 'Making a fire'
|
||||||
text "Well done! You managed to cut some logs from the tree! Next, use the tinderbox in your inventory to light the logs. First click on the "\
|
text 'Well done! You managed to cut some logs from the tree! Next, use the tinderbox in '\
|
||||||
"tinderbox to 'use' it. Then click on the logs in your inventory to light them."
|
'your inventory to light the logs. First click on the tinderbox to \'use\' it.'\
|
||||||
end
|
'Then click on the logs in your inventory to light them.'
|
||||||
|
end
|
||||||
|
|
||||||
# The instruction displayed when the player begins to light the fire.
|
# The instruction displayed when the player begins to light the fire.
|
||||||
dialogue :lighting_fire do
|
dialogue :lighting_fire do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Please wait..."
|
title 'Please wait...'
|
||||||
text "Your character is now attempting to light the logs. Sit back for a moment whilst he does all the hard work." # TODO she instead of he if applicable
|
# TODO: she instead of he if applicable
|
||||||
end
|
text 'Your character is now attempting to light the logs. Sit back for a moment whilst he '\
|
||||||
|
'does all the hard work.'
|
||||||
|
end
|
||||||
|
|
||||||
# The instruction displayed when the has lit the logs.
|
# The instruction displayed when the has lit the logs.
|
||||||
dialogue :gained_experience do
|
dialogue :gained_experience do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
text "You gained some experience."\
|
text 'You gained some experience.'\
|
||||||
"Click on the flashing bar graph icon near the inventory button to see your skill stats."
|
'Click on the flashing bar graph icon near the inventory button to see your skill '\
|
||||||
end
|
'stats.'
|
||||||
|
end
|
||||||
|
|
||||||
# The dialogue displayed when the Player has clicked the flashing skill tab icon.
|
# The dialogue displayed when the Player has clicked the flashing skill tab icon.
|
||||||
dialogue :skill_stats do
|
dialogue :skill_stats do
|
||||||
type :text
|
type :text
|
||||||
|
|
||||||
title "Your skill stats."
|
title 'Your skill stats.'
|
||||||
text "" # TODO !!
|
text '' # TODO: this !!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,52 +1,40 @@
|
|||||||
# Information about npc spawning
|
|
||||||
#
|
|
||||||
# Npcs are passed to spawn npc as a hash. Every key and every non-integer value must be a Symbol. Every hash must implement the following:
|
|
||||||
# :name - the name of the npc. If this npc shares its name with another, append the specific id after the name (e.g. :woman_4)
|
|
||||||
# :x - the x coordinate where the npc will spawn.
|
|
||||||
# :y - the y coordinate where the npc will spawn.
|
|
||||||
# Optional arguments are as follows:
|
|
||||||
# :face - the direction the npc should face when it spawns. Supported options are :north, :north_east, :east, :south_east, :south, :south_west, :west, and :north_west
|
|
||||||
# :bounds - the rectangular bound that the npc can wander about in. Order is [bottom-left x-coordinate, bottom-left y-coordinate, top-right x-coordinate, top-right y-coordinate]
|
|
||||||
# :delta_bounds - the rectangular bound that the npc can wander about in, as a difference from the spawn point. Order is [x-delta, y-delta]. Should not be used with :bounds.
|
|
||||||
# :spawn_animation - the animation that will be played when the npc spawns.
|
|
||||||
# :spawn_graphic - the graphic that will be played when the npc spawns.
|
|
||||||
|
|
||||||
|
|
||||||
# Functional npcs
|
# Functional npcs
|
||||||
|
|
||||||
# 'Above-ground' npcs
|
# 'Above-ground' npcs
|
||||||
|
|
||||||
spawn_npc :name => :master_chef, :x => 3076, :y => 3085
|
spawn_npc name: :master_chef, x: 3076, y: 3085
|
||||||
spawn_npc :name => :quest_guide, :x => 3086, :y => 3122, :face => :north
|
spawn_npc name: :quest_guide, x: 3086, y: 3122, face: :north
|
||||||
spawn_npc :name => :financial_advisor, :x => 3127, :y => 3124, :face => :west
|
spawn_npc name: :financial_advisor, x: 3127, y: 3124, face: :west
|
||||||
spawn_npc :name => :brother_brace, :x => 3124, :y => 3107, :face => :east
|
spawn_npc name: :brother_brace, x: 3124, y: 3107, face: :east
|
||||||
spawn_npc :name => :magic_instructor, :x => 3140, :y => 3085
|
spawn_npc name: :magic_instructor, x: 3140, y: 3085
|
||||||
|
|
||||||
# 'Below-ground' npcs
|
# 'Below-ground' npcs
|
||||||
# Note: They aren't actually on a different plane, they're just in a different location that pretends to be underground.
|
# Note: They aren't actually on a different plane, they're just in a different location that
|
||||||
|
# pretends to be underground.
|
||||||
|
|
||||||
spawn_npc :name => :mining_instructor, :x => 3081, :y => 9504
|
spawn_npc name: :mining_instructor, x: 3081, y: 9504
|
||||||
spawn_npc :name => :combat_instructor, :x => 3104, :y => 9506
|
spawn_npc name: :combat_instructor, x: 3104, y: 9506
|
||||||
|
|
||||||
# Non-humanoid npcs
|
# Non-humanoid npcs
|
||||||
|
|
||||||
spawn_npc :name => :fishing_spot_316, :x => 3102, :y => 3093
|
spawn_npc name: :fishing_spot_316, x: 3102, y: 3093
|
||||||
|
|
||||||
spawn_npc :name => :chicken, :x => 3140, :y => 3095
|
|
||||||
spawn_npc :name => :chicken, :x => 3140, :y => 3093
|
|
||||||
spawn_npc :name => :chicken, :x => 3138, :y => 3092
|
|
||||||
spawn_npc :name => :chicken, :x => 3137, :y => 3094
|
|
||||||
spawn_npc :name => :chicken, :x => 3138, :y => 3095
|
|
||||||
|
|
||||||
|
spawn_npc name: :chicken, x: 3140, y: 3095
|
||||||
|
spawn_npc name: :chicken, x: 3140, y: 3093
|
||||||
|
spawn_npc name: :chicken, x: 3138, y: 3092
|
||||||
|
spawn_npc name: :chicken, x: 3137, y: 3094
|
||||||
|
spawn_npc name: :chicken, x: 3138, y: 3095
|
||||||
|
|
||||||
# 'Below-ground' npcs
|
# 'Below-ground' npcs
|
||||||
# Note: They aren't actually on a different plane, they're just in a different location that pretends to be underground.
|
# Note: They aren't actually on a different plane, they're just in a different location that
|
||||||
|
# pretends to be underground.
|
||||||
|
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3105, :y => 9514
|
spawn_npc name: :giant_rat_87, x: 3105, y: 9514
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3105, :y => 9517
|
spawn_npc name: :giant_rat_87, x: 3105, y: 9517
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3106, :y => 9514
|
spawn_npc name: :giant_rat_87, x: 3106, y: 9514
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3104, :y => 9514
|
spawn_npc name: :giant_rat_87, x: 3104, y: 9514
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3105, :y => 9519
|
spawn_npc name: :giant_rat_87, x: 3105, y: 9519
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3109, :y => 9516
|
spawn_npc name: :giant_rat_87, x: 3109, y: 9516
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3108, :y => 9520
|
spawn_npc name: :giant_rat_87, x: 3108, y: 9520
|
||||||
spawn_npc :name => :giant_rat_87, :x => 3102, :y => 9517
|
spawn_npc name: :giant_rat_87, x: 3102, y: 9517
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ private
|
|||||||
STAGES = []
|
STAGES = []
|
||||||
|
|
||||||
# The stages that are used when interacting with the Runescape Guide.
|
# The stages that are used when interacting with the Runescape Guide.
|
||||||
RUNESCAPE_GUIDE = [ :not_started, :talk_to_people, :go_through_door, :runescape_guide_finished, :moving_around ]
|
RUNESCAPE_GUIDE = [:not_started, :talk_to_people, :go_through_door, :runescape_guide_finished,
|
||||||
|
:moving_around]
|
||||||
STAGES.concat(RUNESCAPE_GUIDE)
|
STAGES.concat(RUNESCAPE_GUIDE)
|
||||||
|
|
||||||
# The stages that are used when interacting with the Survival Expert.
|
# The stages that are used when interacting with the Survival Expert.
|
||||||
SURVIVAL_EXPERT = [ :given_axe, :cut_tree, :cutting_tree, ]
|
SURVIVAL_EXPERT = [:given_axe, :cut_tree, :cutting_tree]
|
||||||
STAGES.concat(SURVIVAL_EXPERT)
|
STAGES.concat(SURVIVAL_EXPERT)
|
||||||
|
|
||||||
quest :tutorial_island, STAGES
|
quest :tutorial_island, STAGES
|
||||||
@@ -10,7 +10,7 @@ private
|
|||||||
module SurvivalConstants
|
module SurvivalConstants
|
||||||
|
|
||||||
# The Survival Expert Npc.
|
# The Survival Expert Npc.
|
||||||
@survival_expert = spawn_npc :name => :survival_expert, :x => 3104, :y => 3095, :face => :north
|
@survival_expert = spawn_npc name: :survival_expert, x: 3104, y: 3095, face: :north
|
||||||
|
|
||||||
# The inventory tab index.
|
# The inventory tab index.
|
||||||
INVENTORY_TAB_INDEX = 3
|
INVENTORY_TAB_INDEX = 3
|
||||||
@@ -29,7 +29,6 @@ module SurvivalConstants
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# The conversation with the Survival Expert, when on tutorial island.
|
# The conversation with the Survival Expert, when on tutorial island.
|
||||||
conversation :tutorial_surivival_expert do
|
conversation :tutorial_surivival_expert do
|
||||||
|
|
||||||
@@ -39,23 +38,23 @@ conversation :tutorial_surivival_expert do
|
|||||||
|
|
||||||
precondition { |player| player.tutorial_island_progress == :moving_around }
|
precondition { |player| player.tutorial_island_progress == :moving_around }
|
||||||
|
|
||||||
text "Hello there, newcomer. My name is Brynna. My job is to teach you a few survival tips and tricks. First off we're "\
|
text 'Hello there, newcomer. My name is Brynna. My job is to teach you a few survival tips and'\
|
||||||
"going to start with the most basic survival skill of all: making a fire."
|
' tricks. First off we\'re going to start with the most basic survival skill of all: '\
|
||||||
|
'making a fire.'
|
||||||
|
|
||||||
close &:add_survival_items
|
close(&:add_survival_items)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
dialogue :hello_again do
|
dialogue :hello_again do
|
||||||
type :npc_speech
|
type :npc_speech
|
||||||
npc :survival_expert
|
npc :survival_expert
|
||||||
|
|
||||||
precondition { |player| player.tutorial_island_progress == :moving_around }
|
precondition { |player| player.tutorial_island_progress == :moving_around }
|
||||||
|
|
||||||
text "Hello again. I'm here to teach you a few survival tips and tricks. First off we're going to start with the most "\
|
text 'Hello again. I\'m here to teach you a few survival tips and tricks. First off we\'re '\
|
||||||
"basic survival skill of all: making a fire."
|
'going to start with the most basic survival skill of all: making a fire.'
|
||||||
|
|
||||||
close &:add_survival_items
|
close(&:add_survival_items)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The dialogue displayed when the Survival Expert gives the player a bronze axe.
|
# The dialogue displayed when the Survival Expert gives the player a bronze axe.
|
||||||
@@ -63,7 +62,7 @@ conversation :tutorial_surivival_expert do
|
|||||||
type :message_with_item
|
type :message_with_item
|
||||||
item :bronze_axe
|
item :bronze_axe
|
||||||
|
|
||||||
text "The Survival Expert gives you a bronze axe!"
|
text 'The Survival Expert gives you a bronze axe!'
|
||||||
|
|
||||||
close { |player| TutorialInstructions.show_instruction(player) }
|
close { |player| TutorialInstructions.show_instruction(player) }
|
||||||
end
|
end
|
||||||
@@ -73,23 +72,28 @@ conversation :tutorial_surivival_expert do
|
|||||||
type :message_with_item
|
type :message_with_item
|
||||||
item :tinderbox
|
item :tinderbox
|
||||||
|
|
||||||
text "The Survival Expert gives you a tinderbox!"
|
text 'The Survival Expert gives you a tinderbox!'
|
||||||
|
|
||||||
close { |player| TutorialInstructions.show_instruction(player) }
|
close { |player| TutorialInstructions.show_instruction(player) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# The dialogue displayed when the Survival Expert gives the player both a bronze axe and a tinderbox.
|
# The dialogue displayed when the Survival Expert gives the player both a bronze axe and a
|
||||||
|
# tinderbox.
|
||||||
dialogue :give_axe_and_tinderbox do
|
dialogue :give_axe_and_tinderbox do
|
||||||
type :message_with_item
|
type :message_with_item
|
||||||
item :bronze_axe # TODO the tinderbox is also displayed - find this dialogue id. Scale looks like the default http://i.imgur.com/i1abN5X.png
|
item :bronze_axe
|
||||||
|
# TODO: the tinderbox is also displayed - find this dialogue id. Scale looks like the default
|
||||||
|
# http://i.imgur.com/i1abN5X.png
|
||||||
|
|
||||||
text "The Survival Expert gives you a tinderbox and a bronze axe!"
|
text 'The Survival Expert gives you a tinderbox and a bronze axe!'
|
||||||
|
|
||||||
close do |player|
|
close do |player|
|
||||||
if (player.tutorial_island_progress < :given_axe)
|
if player.tutorial_island_progress < :given_axe
|
||||||
player.tutorial_island_progress = :given_axe
|
player.tutorial_island_progress = :given_axe
|
||||||
player.send(SwitchTabInterfaceMessage.new(SurvivalConstants::INVENTORY_TAB_INDEX, SurvivalConstants::INVENTORY_TAB_ID))
|
|
||||||
player.send(FlashTabInterfaceMessage.new(SurvivalConstants::INVENTORY_TAB_INDEX))
|
index = SurvivalConstants::INVENTORY_TAB_INDEX
|
||||||
|
player.send(SwitchTabInterfaceMessage.new(index, SurvivalConstants::INVENTORY_TAB_ID))
|
||||||
|
player.send(FlashTabInterfaceMessage.new(index))
|
||||||
end
|
end
|
||||||
|
|
||||||
TutorialInstructions.show_instruction(player)
|
TutorialInstructions.show_instruction(player)
|
||||||
@@ -101,14 +105,14 @@ conversation :tutorial_surivival_expert do
|
|||||||
type :message_with_item
|
type :message_with_item
|
||||||
item :logs
|
item :logs
|
||||||
|
|
||||||
text "You get some logs."
|
text 'You get some logs.'
|
||||||
close { |player| TutorialInstructions.show_instruction(player) }
|
close { |player| TutorialInstructions.show_instruction(player) }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add the survival items (bronze axe and tinderbox) to the inventory of the player, if they do not
|
||||||
# Add the survival items (bronze axe and tinderbox) to the inventory of the player, if they do not already have them.
|
# already have them.
|
||||||
def add_survival_items(player)
|
def add_survival_items(player)
|
||||||
inventory = player.inventory
|
inventory = player.inventory
|
||||||
|
|
||||||
@@ -125,21 +129,25 @@ def add_survival_items(player)
|
|||||||
send_dialogue(player, get_dialogue(:tutorial_surivival_expert, dialogue))
|
send_dialogue(player, get_dialogue(:tutorial_surivival_expert, dialogue))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Intercept the FirstObjectActionMessage to send tutorial-only events if the player is chopping down a tree.
|
# Intercept the FirstObjectActionMessage to send tutorial-only events if the player is chopping
|
||||||
|
# down a tree.
|
||||||
on :message, :first_object_action do |player, message|
|
on :message, :first_object_action do |player, message|
|
||||||
if (player.in_tutorial_island && message.id == SurvivalConstants::TREE_ID)
|
if player.in_tutorial_island && message.id == SurvivalConstants::TREE_ID
|
||||||
progress = player.tutorial_island_progress
|
progress = player.tutorial_island_progress
|
||||||
if (progress < :cut_tree)
|
|
||||||
# TODO display "You cannot cut down this tree; you must first follow the guide's instructions."
|
if progress < :cut_tree
|
||||||
elsif (player.tutorial_island_progress == :cut_tree)
|
# TODO: 'You cannot cut down this tree; you must first follow the guide's instructions.'
|
||||||
player.tutorial_island_progress = :cutting_tree # Don't break the chain, so that the Woodcutting event actually happens.
|
elsif player.tutorial_island_progress == :cut_tree
|
||||||
|
# Don't break the chain, so that the Woodcutting event actually happens.
|
||||||
|
player.tutorial_island_progress = :cutting_tree
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Intercept the FlashingTabClickedMessage to update the player's progress, if applicable.
|
# Intercept the FlashingTabClickedMessage to update the player's progress, if applicable.
|
||||||
on :message, :flashing_tab_clicked do |player, message|
|
on :message, :flashing_tab_clicked do |player, message|
|
||||||
if (player.in_tutorial_island && message.tab == SurvivalConstants::INVENTORY_TAB_INDEX && player.tutorial_island_progress == :given_axe)
|
if player.in_tutorial_island && message.tab == SurvivalConstants::INVENTORY_TAB_INDEX &&
|
||||||
|
player.tutorial_island_progress == :given_axe
|
||||||
player.tutorial_island_progress = :cut_tree
|
player.tutorial_island_progress = :cut_tree
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,30 +5,26 @@ java_import 'org.apollo.game.model.entity.Player'
|
|||||||
# Declare the tutorial island progress attribute.
|
# Declare the tutorial island progress attribute.
|
||||||
declare_attribute(:tutorial_island_progress, :not_started, :persistent)
|
declare_attribute(:tutorial_island_progress, :not_started, :persistent)
|
||||||
|
|
||||||
|
|
||||||
# The existing player class.
|
# The existing player class.
|
||||||
class Player
|
class Player
|
||||||
|
|
||||||
# Returns whether or not this Player is currently on tutorial island.
|
# Returns whether or not this Player is currently on tutorial island.
|
||||||
def in_tutorial_island
|
def in_tutorial_island
|
||||||
x, y = self.position.x, self.position.y
|
x = position.x
|
||||||
|
y = position.y
|
||||||
return above_ground(x, y) || below_ground(x, y)
|
above_ground(x, y) || below_ground(x, y)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
||||||
# Returns whether or not the specified coordinate pair is above ground on tutorial island.
|
# Returns whether or not the specified coordinate pair is above ground on tutorial island.
|
||||||
def above_ground(x, y)
|
def above_ground(x, y)
|
||||||
return (x >= 3053 && x <= 3156 && y >= 3056 && y <= 3136)
|
x >= 3053 && x <= 3156 && y >= 3056 && y <= 3136
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Returns whether or not the specified coordinate pair is 'below' ground on tutorial island.
|
# Returns whether or not the specified coordinate pair is 'below' ground on tutorial island.
|
||||||
def below_ground(x, y)
|
def below_ground(x, y)
|
||||||
return (x >= 3072 && x <= 3118 && y >= 9492 && y <= 9535)
|
x >= 3072 && x <= 3118 && y >= 9492 && y <= 9535
|
||||||
end
|
end
|
||||||
@@ -4,6 +4,7 @@ require 'set'
|
|||||||
module DoorConstants
|
module DoorConstants
|
||||||
|
|
||||||
# TODO: GameObjectOrientation enumeration in Apollo's core?
|
# TODO: GameObjectOrientation enumeration in Apollo's core?
|
||||||
|
# The orientation of a door.
|
||||||
module Orientation
|
module Orientation
|
||||||
WEST = 0
|
WEST = 0
|
||||||
NORTH = 1
|
NORTH = 1
|
||||||
@@ -15,29 +16,29 @@ module DoorConstants
|
|||||||
DOOR_SIZE = 1
|
DOOR_SIZE = 1
|
||||||
|
|
||||||
# Door object ids that have a hinge on the left side.
|
# Door object ids that have a hinge on the left side.
|
||||||
LEFT_HINGE_DOORS = Set.new [ 1516, 1536, 1533 ]
|
LEFT_HINGE_DOORS = Set.new [1516, 1536, 1533]
|
||||||
|
|
||||||
# Door object ids that have a hinge on the right side.
|
# Door object ids that have a hinge on the right side.
|
||||||
RIGHT_HINGE_DOORS = Set.new [ 1519, 1530, 4465, 4467, 3014, 3017, 3018, 3019 ]
|
RIGHT_HINGE_DOORS = Set.new [1519, 1530, 4465, 4467, 3014, 3017, 3018, 3019]
|
||||||
|
|
||||||
# The hash of orientations that a door will translate to when opened.
|
# The hash of orientations that a door will translate to when opened.
|
||||||
ORIENTATIONS = {
|
ORIENTATIONS = {
|
||||||
|
|
||||||
# Orientations for doors that have a hinge on the left side.
|
# Orientations for doors that have a hinge on the left side.
|
||||||
:left_side_hinge => {
|
left_side_hinge: {
|
||||||
Orientation::NORTH => Orientation::WEST,
|
Orientation::NORTH => Orientation::WEST,
|
||||||
Orientation::SOUTH => Orientation::EAST,
|
Orientation::SOUTH => Orientation::EAST,
|
||||||
Orientation::WEST => Orientation::SOUTH,
|
Orientation::WEST => Orientation::SOUTH,
|
||||||
Orientation::EAST => Orientation::NORTH
|
Orientation::EAST => Orientation::NORTH
|
||||||
},
|
},
|
||||||
|
|
||||||
# Orientations for doors that have a hinge on the right side.
|
# Orientations for doors that have a hinge on the right side.
|
||||||
:right_side_hinge => {
|
right_side_hinge: {
|
||||||
Orientation::NORTH => Orientation::EAST,
|
Orientation::NORTH => Orientation::EAST,
|
||||||
Orientation::SOUTH => Orientation::WEST,
|
Orientation::SOUTH => Orientation::WEST,
|
||||||
Orientation::WEST => Orientation::NORTH,
|
Orientation::WEST => Orientation::NORTH,
|
||||||
Orientation::EAST => Orientation::SOUTH
|
Orientation::EAST => Orientation::SOUTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
java_import 'org.apollo.game.action.DistancedAction'
|
java_import 'org.apollo.game.action.DistancedAction'
|
||||||
|
|
||||||
# A distanced action which opens a door.
|
# A distanced action which opens a door.
|
||||||
@@ -13,20 +14,20 @@ class OpenDoorAction < DistancedAction
|
|||||||
|
|
||||||
def executeAction
|
def executeAction
|
||||||
mob.turn_to(@door.position)
|
mob.turn_to(@door.position)
|
||||||
DoorUtil::toggle(@door)
|
DoorUtil.toggle(@door)
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class && @door == other.door)
|
get_class == other.get_class && @door == other.door
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# MessageListener for opening and closing doors.
|
# MessageListener for opening and closing doors.
|
||||||
on :message, :first_object_action do |player, message|
|
on :message, :first_object_action do |player, message|
|
||||||
if DoorUtil::is_door?(message.id)
|
if DoorUtil.door?(message.id)
|
||||||
door = DoorUtil::get_door_object(message.position, message.id)
|
door = DoorUtil.get_door_object(message.position, message.id)
|
||||||
player.start_action(OpenDoorAction.new(player, door)) unless door.nil?
|
player.start_action(OpenDoorAction.new(player, door)) unless door.nil?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -15,20 +15,18 @@ module DoorUtil
|
|||||||
# Translates a door's position in the direction of its orientation.
|
# Translates a door's position in the direction of its orientation.
|
||||||
def self.translate_door_position(door)
|
def self.translate_door_position(door)
|
||||||
position = door.position
|
position = door.position
|
||||||
orientation = door.orientation
|
|
||||||
|
|
||||||
case orientation
|
case door.orientation
|
||||||
when Orientation::WEST
|
when Orientation::WEST
|
||||||
return Position.new(position.x - 1, position.y, position.height)
|
Position.new(position.x - 1, position.y, position.height)
|
||||||
when Orientation::EAST
|
when Orientation::EAST
|
||||||
return Position.new(position.x + 1, position.y, position.height)
|
Position.new(position.x + 1, position.y, position.height)
|
||||||
when Orientation::NORTH
|
when Orientation::NORTH
|
||||||
return Position.new(position.x, position.y + 1, position.height)
|
Position.new(position.x, position.y + 1, position.height)
|
||||||
when Orientation::SOUTH
|
when Orientation::SOUTH
|
||||||
return Position.new(position.x, position.y - 1, position.height)
|
Position.new(position.x, position.y - 1, position.height)
|
||||||
|
else fail "Unsupported orientation #{door.orientation}."
|
||||||
end
|
end
|
||||||
|
|
||||||
raise 'Invalid orientation for door!'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Translates the orientation of a door to a toggled position.
|
# Translates the orientation of a door to a toggled position.
|
||||||
@@ -42,13 +40,12 @@ module DoorUtil
|
|||||||
return ORIENTATIONS[:left_side_hinge][orientation]
|
return ORIENTATIONS[:left_side_hinge][orientation]
|
||||||
end
|
end
|
||||||
|
|
||||||
raise 'Given object was not registered as a door.'
|
fail 'Given object was not registered as a door.'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Toggles the given door.
|
# Toggles the given door.
|
||||||
def self.toggle(door)
|
def self.toggle(door)
|
||||||
position = door.position
|
region = $world.region_repository.from_position(door.position)
|
||||||
region = $world.region_repository.from_position(position)
|
|
||||||
region.remove_entity(door)
|
region.remove_entity(door)
|
||||||
|
|
||||||
if TOGGLED_DOORS.include?(door)
|
if TOGGLED_DOORS.include?(door)
|
||||||
@@ -57,11 +54,13 @@ module DoorUtil
|
|||||||
original_region = $world.region_repository.from_position(original_door.position)
|
original_region = $world.region_repository.from_position(original_door.position)
|
||||||
original_region.add_entity(original_door)
|
original_region.add_entity(original_door)
|
||||||
else
|
else
|
||||||
toggled_position = translate_door_position(door)
|
position = translate_door_position(door)
|
||||||
toggled_orientation = translate_door_orientation(door)
|
orientation = translate_door_orientation(door)
|
||||||
toggled_door = DynamicGameObject.create_public($world, door.id, toggled_position, door.type, toggled_orientation)
|
type = door.type
|
||||||
|
|
||||||
toggled_region = $world.region_repository.from_position(toggled_position)
|
toggled_door = DynamicGameObject.create_public($world, door.id, position, type, orientation)
|
||||||
|
|
||||||
|
toggled_region = $world.region_repository.from_position(position)
|
||||||
toggled_region.add_entity(toggled_door)
|
toggled_region.add_entity(toggled_door)
|
||||||
|
|
||||||
TOGGLED_DOORS[toggled_door] = door
|
TOGGLED_DOORS[toggled_door] = door
|
||||||
@@ -70,13 +69,14 @@ module DoorUtil
|
|||||||
|
|
||||||
# Gets the door object at the given position, if it exists.
|
# Gets the door object at the given position, if it exists.
|
||||||
def self.get_door_object(position, object_id)
|
def self.get_door_object(position, object_id)
|
||||||
game_objects = $world.region_repository.from_position(position).get_entities(position, EntityType::DYNAMIC_OBJECT, EntityType::STATIC_OBJECT)
|
region = $world.region_repository.from_position(position)
|
||||||
game_objects.each { |game_object| return game_object if game_object.id == object_id }
|
objects = region.get_entities(position, EntityType::DYNAMIC_OBJECT, EntityType::STATIC_OBJECT)
|
||||||
return nil
|
objects.each { |game_object| return game_object if game_object.id == object_id }
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if the given game object id is a door.
|
# Checks if the given game object id is a door.
|
||||||
def self.is_door?(object_id)
|
def self.door?(object_id)
|
||||||
RIGHT_HINGE_DOORS.include?(object_id) || LEFT_HINGE_DOORS.include?(object_id)
|
RIGHT_HINGE_DOORS.include?(object_id) || LEFT_HINGE_DOORS.include?(object_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,13 @@ require 'java'
|
|||||||
java_import 'org.apollo.game.message.impl.SetPlayerActionMessage'
|
java_import 'org.apollo.game.message.impl.SetPlayerActionMessage'
|
||||||
java_import 'org.apollo.game.model.entity.Player'
|
java_import 'org.apollo.game.model.entity.Player'
|
||||||
|
|
||||||
|
# A right-click action for a Player.
|
||||||
|
|
||||||
class PlayerAction
|
class PlayerAction
|
||||||
attr_reader :slot, :primary, :name
|
attr_reader :slot, :primary, :name
|
||||||
|
|
||||||
def initialize(slot, primary, name)
|
def initialize(slot, primary, name)
|
||||||
index = [ :first, :second, :third, :fourth, :fifth ].find_index(slot)
|
index = [:first, :second, :third, :fourth, :fifth].find_index(slot)
|
||||||
raise "Unsupported action slot #{slot}." if index.nil?
|
fail "Unsupported action slot #{slot}." if index.nil?
|
||||||
|
|
||||||
@slot = index
|
@slot = index
|
||||||
@primary = primary
|
@primary = primary
|
||||||
@@ -26,7 +25,7 @@ FOLLOW_ACTION = PlayerAction.new(:fifth, true, 'Follow')
|
|||||||
|
|
||||||
# Shows multiple context menu action for the specified player
|
# Shows multiple context menu action for the specified player
|
||||||
def show_actions(player, *actions)
|
def show_actions(player, *actions)
|
||||||
raise 'Must specify at least one action' if actions.nil?
|
fail 'Must specify at least one action.' if actions.nil?
|
||||||
|
|
||||||
actions.each do |action|
|
actions.each do |action|
|
||||||
player.add_action(action)
|
player.add_action(action)
|
||||||
@@ -44,6 +43,7 @@ def hide_action(player, action)
|
|||||||
show_action(player, PlayerAction.new(action.slot, action.primary, 'null'))
|
show_action(player, PlayerAction.new(action.slot, action.primary, 'null'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Monkey-patch Player to provide action utility methods.
|
||||||
class Player
|
class Player
|
||||||
|
|
||||||
def actions
|
def actions
|
||||||
@@ -54,7 +54,7 @@ class Player
|
|||||||
actions[action.slot] = action.name
|
actions[action.slot] = action.name
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_action(action)
|
def action?(action)
|
||||||
actions[action.slot] == action.name
|
actions[action.slot] == action.name
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
java_import 'org.apollo.game.model.entity.Player'
|
java_import 'org.apollo.game.model.entity.Player'
|
||||||
|
|
||||||
on :login do |event, player|
|
on :login do |_event, player|
|
||||||
show_action(player, TRADE_ACTION)
|
show_action(player, TRADE_ACTION)
|
||||||
show_action(player, FOLLOW_ACTION)
|
show_action(player, FOLLOW_ACTION)
|
||||||
end
|
end
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<author>Ryley</author>
|
<author>Ryley</author>
|
||||||
</authors>
|
</authors>
|
||||||
<scripts>
|
<scripts>
|
||||||
<script>player-action.rb</script>
|
<script>action.rb</script>
|
||||||
<script>login.rb</script>
|
<script>login.rb</script>
|
||||||
</scripts>
|
</scripts>
|
||||||
<dependencies />
|
<dependencies />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# Defines a quest with the specified name.
|
# Defines a quest with the specified name.
|
||||||
def quest(name, stage_names)
|
def quest(name, stage_names)
|
||||||
stages = { }
|
stages = {}
|
||||||
stage_names.each_with_index { |stage, index| stages[stage] = QuestStage.new(stage, index, name) }
|
stage_names.each_with_index { |stage, index| stages[stage] = QuestStage.new(stage, index, name) }
|
||||||
|
|
||||||
QUESTS[name] = Quest.new(name, stages)
|
QUESTS[name] = Quest.new(name, stages)
|
||||||
@@ -18,25 +18,26 @@ class Quest
|
|||||||
|
|
||||||
# Creates the Quest.
|
# Creates the Quest.
|
||||||
def initialize(name, stages)
|
def initialize(name, stages)
|
||||||
raise "Quest name must be a symbol, received '#{name}'." unless name.kind_of?(Symbol)
|
fail "Quest name must be a symbol, received '#{name}'." unless name.is_a?(Symbol)
|
||||||
@name = name
|
@name = name
|
||||||
@stages = stages
|
@stages = stages
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets the finishing quest stage (i.e. the stage that indicates the Player has completed the quest).
|
# Gets the finishing quest stage (i.e. the stage that indicates the Player has completed the
|
||||||
def final_stage()
|
# quest).
|
||||||
|
def final_stage
|
||||||
@stages.last
|
@stages.last
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets the starting quest stage.
|
# Gets the starting quest stage.
|
||||||
def initial_stage()
|
def initial_stage
|
||||||
@stages.first
|
@stages.first
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets the QuestStage with the specified name.
|
# Gets the QuestStage with the specified name.
|
||||||
def stage(name)
|
def stage(name)
|
||||||
stage = @stages[name]
|
stage = @stages[name]
|
||||||
raise "No stage named #{name} exists in #{@name}." if stage.nil?
|
fail "No stage named #{name} exists in #{@name}." if stage.nil?
|
||||||
stage
|
stage
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ class QuestStage
|
|||||||
attr_reader :name, :index
|
attr_reader :name, :index
|
||||||
|
|
||||||
# Creates the QuestProgress.
|
# Creates the QuestProgress.
|
||||||
def initialize(name, index, quest, log_text=nil)
|
def initialize(name, index, quest, log_text = nil)
|
||||||
@name = name
|
@name = name
|
||||||
@index = index
|
@index = index
|
||||||
@quest = quest
|
@quest = quest
|
||||||
@@ -61,41 +62,40 @@ class QuestStage
|
|||||||
|
|
||||||
# Gets the log text for this stage.
|
# Gets the log text for this stage.
|
||||||
def log_text
|
def log_text
|
||||||
raise "Cannot get the log text from an unlogged quest stage." unless logged
|
fail 'Cannot get the log text from an unlogged quest stage.' unless logged
|
||||||
@log_text
|
@log_text
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines the equality operator.
|
# Defines the equality operator.
|
||||||
def ==(name)
|
def ==(other)
|
||||||
@index == index_of(name)
|
@index == index_of(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines the not equal operator.
|
# Defines the not equal operator.
|
||||||
def !=(name)
|
def !=(other)
|
||||||
@index != index_of(name)
|
@index != index_of(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines the greater than or equal to operator.
|
# Defines the greater than or equal to operator.
|
||||||
def >=(name)
|
def >=(other)
|
||||||
@index >= index_of(name)
|
@index >= index_of(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines the greater than operator.
|
# Defines the greater than operator.
|
||||||
def >(name)
|
def >(other)
|
||||||
@index > index_of(name)
|
@index > index_of(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines the less than operator.
|
# Defines the less than operator.
|
||||||
def <(name)
|
def <(other)
|
||||||
@index < index_of(name)
|
@index < index_of(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines the less than or equal to operator.
|
# Defines the less than or equal to operator.
|
||||||
def <=(name)
|
def <=(other)
|
||||||
@index <= index_of(name)
|
@index <= index_of(other)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Gets the index of the QuestStage with the specified name.
|
# Gets the index of the QuestStage with the specified name.
|
||||||
@@ -105,7 +105,6 @@ class QuestStage
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Define method_missing for player
|
# Define method_missing for player
|
||||||
class Player
|
class Player
|
||||||
|
|
||||||
@@ -113,16 +112,16 @@ class Player
|
|||||||
def method_missing(symbol, *args)
|
def method_missing(symbol, *args)
|
||||||
unless args.nil?
|
unless args.nil?
|
||||||
arg = args[0]
|
arg = args[0]
|
||||||
args[0] = arg.name if arg.kind_of?(QuestStage)
|
args[0] = arg.name if arg.is_a?(QuestStage)
|
||||||
end
|
end
|
||||||
|
|
||||||
result = super(symbol, *args)
|
result = super(symbol, *args)
|
||||||
string = symbol.to_s
|
string = symbol.to_s
|
||||||
|
|
||||||
if (string.end_with?('_progress'))
|
if string.end_with?('_progress')
|
||||||
name = string[0..-10] # Cut the '_progress' from the end
|
name = string[0..-10] # Cut the '_progress' from the end
|
||||||
quest = QUESTS[name.to_sym]
|
quest = QUESTS[name.to_sym]
|
||||||
raise "No Quest with the name '#{name}' exists." if quest.nil?
|
fail "No Quest with the name '#{name}' exists." if quest.nil?
|
||||||
|
|
||||||
result = quest.stage(result)
|
result = quest.stage(result)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,28 +11,31 @@ class Fish
|
|||||||
@id = id
|
@id = id
|
||||||
@level = level
|
@level = level
|
||||||
@experience = experience
|
@experience = experience
|
||||||
|
|
||||||
@name = name_of(:item, id)
|
@name = name_of(:item, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends a Fish to the hash.
|
# Appends a Fish to the hash.
|
||||||
def append_fish(name, fish)
|
def append_fish(name, hash)
|
||||||
CATCHABLE_FISH[name] = fish
|
unless hash.has_keys?(:id, :level, :experience)
|
||||||
|
fail 'Hash must contain an id, level, and experience.'
|
||||||
|
end
|
||||||
|
|
||||||
|
CATCHABLE_FISH[name] = Fish.new(hash[:id], hash[:level], hash[:experience])
|
||||||
end
|
end
|
||||||
|
|
||||||
append_fish(:shrimp, Fish.new(317, 1, 10))
|
append_fish :shrimp, id: 317, level: 1, experience: 10
|
||||||
append_fish(:sardine, Fish.new(327, 5, 20))
|
append_fish :sardine, id: 327, level: 5, experience: 20
|
||||||
append_fish(:herring, Fish.new(345, 10, 30))
|
append_fish :herring, id: 345, level: 10, experience: 30
|
||||||
append_fish(:anchovy, Fish.new(321, 15, 40))
|
append_fish :anchovy, id: 321, level: 15, experience: 40
|
||||||
append_fish(:mackerel, Fish.new(353, 16, 20))
|
append_fish :mackerel, id: 353, level: 16, experience: 20
|
||||||
append_fish(:trout, Fish.new(335, 20, 50))
|
append_fish :trout, id: 335, level: 20, experience: 50
|
||||||
append_fish(:cod, Fish.new(341, 23, 45))
|
append_fish :cod, id: 341, level: 23, experience: 45
|
||||||
append_fish(:pike, Fish.new(349, 25, 60))
|
append_fish :pike, id: 349, level: 25, experience: 60
|
||||||
append_fish(:salmon, Fish.new(331, 30, 70))
|
append_fish :salmon, id: 331, level: 30, experience: 70
|
||||||
append_fish(:tuna, Fish.new(359, 35, 80))
|
append_fish :tuna, id: 359, level: 35, experience: 80
|
||||||
append_fish(:lobster, Fish.new(377, 40, 90))
|
append_fish :lobster, id: 377, level: 40, experience: 90
|
||||||
append_fish(:bass, Fish.new(363, 46, 100))
|
append_fish :bass, id: 363, level: 46, experience: 100
|
||||||
append_fish(:swordfish, Fish.new(371, 50, 100))
|
append_fish :swordfish, id: 371, level: 50, experience: 100
|
||||||
append_fish(:shark, Fish.new(383, 76, 110))
|
append_fish :shark, id: 383, level: 76, experience: 110
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ java_import 'org.apollo.game.model.entity.Skill'
|
|||||||
|
|
||||||
# An action that causes a mob to fish at a spot.
|
# An action that causes a mob to fish at a spot.
|
||||||
class FishingAction < DistancedAction
|
class FishingAction < DistancedAction
|
||||||
attr_reader :spot, :tool, :position, :started
|
attr_reader :position, :options, :spot, :started, :tool
|
||||||
|
|
||||||
# Creates the FishingAction.
|
# Creates the FishingAction.
|
||||||
def initialize(mob, position, spot, option)
|
def initialize(mob, position, spot, option)
|
||||||
@@ -15,28 +15,28 @@ class FishingAction < DistancedAction
|
|||||||
@spot = spot
|
@spot = spot
|
||||||
@tool = spot.tools[option - 1]
|
@tool = spot.tools[option - 1]
|
||||||
|
|
||||||
@options = (option == 1) ? spot.first_option : spot.second_option
|
@options = (option == 1) ? spot.first_fish : spot.second_fish
|
||||||
@minimum_level = options.map { |fish| fish.level }.min
|
@minimum_level = @options.map(&:level).min
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns whether or not a catch is successful.
|
# Returns whether or not a catch is successful.
|
||||||
def successful_catch(level, requirement)
|
def successful_catch(level, requirement)
|
||||||
return [level - requirement, 30].min > rand(40)
|
[level - requirement + 5, 30].min > rand(40)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Starts the fishing process.
|
# Starts the fishing process.
|
||||||
def start_fishing()
|
def start_fishing
|
||||||
@started = true
|
@started = true
|
||||||
mob.send_message(tool.message, true)
|
mob.send_message(tool.message, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Executes the action.
|
# Executes the action.
|
||||||
def executeAction()
|
def executeAction
|
||||||
skills = mob.skill_set
|
skills = mob.skill_set
|
||||||
fishing_level = skills.get_skill(Skill::FISHING).current_level
|
fishing_level = skills.get_skill(Skill::FISHING).current_level
|
||||||
mob.turn_to(position)
|
mob.turn_to(position)
|
||||||
|
|
||||||
if (@minimum_level > fishing_level)
|
if @minimum_level > fishing_level
|
||||||
mob.send_message("You need a fishing level of #{@minimum_level} to fish at this spot.")
|
mob.send_message("You need a fishing level of #{@minimum_level} to fish at this spot.")
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
@@ -49,52 +49,61 @@ class FishingAction < DistancedAction
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
unless inventory.contains(@tool.id)
|
unless inventory.contains(@tool.id)
|
||||||
mob.send_message("You need a #{@tool.name} to fish at this spot.")
|
mob.send_message("You need a #{@tool.name.downcase} to fish at this spot.")
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
bait = @tool.bait
|
bait = find_bait
|
||||||
if (bait.empty? && !mob.inventory.contains(bait))
|
if bait == -1
|
||||||
mob.send_message("You need #{name_of(:item, bait)}s to fish at this spot.")
|
mob.send_message("You need #{name_of(:item, bait).downcase}s to fish at this spot.")
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
unless @started
|
if @started
|
||||||
start_fishing
|
options = @options.reject { |fish| fish.level > fishing_level }
|
||||||
else
|
# Player may level up mid-action so reject here, not at initialisation.
|
||||||
options = @options.reject { |fish| fish.level > fishing_level } # Player may level up mid-action so reject here, not at initialisation.
|
fish = options.sample # TODO: it's a ~70/30 chance, not 50/50
|
||||||
fish = options.sample # TODO it's a ~70/30 chance, not 50/50
|
|
||||||
|
|
||||||
if successful_catch(fishing_level, fish.level)
|
if successful_catch(fishing_level, fish.level)
|
||||||
inventory.remove(bait) unless bait.empty?
|
inventory.remove(bait) unless bait.nil?
|
||||||
inventory.add(type.id)
|
inventory.add(fish.id)
|
||||||
|
|
||||||
name = fish.name
|
name = fish.name
|
||||||
mob.send_message("You catch #{name.end_with?('s') ? 'some' : 'a'} #{name}.", true)
|
mob.send_message("You catch #{name.end_with?('s') ? 'some' : 'a'} #{name.downcase}.", true)
|
||||||
skills.add_experience(Skill::FISHING, fish.experience)
|
skills.add_experience(Skill::FISHING, fish.experience)
|
||||||
|
|
||||||
unless (bait != -1 && !mob.inventory.contains(bait))
|
if find_bait == -1
|
||||||
mob.send_message("You need more #{name_of(:item, bait)}s to fish at this spot.")
|
mob.send_message("You need more #{name_of(:item, bait).downcase}s to fish at this spot.")
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
start_fishing
|
||||||
end
|
end
|
||||||
|
|
||||||
mob.play_animation(@tool.animation)
|
mob.play_animation(@tool.animation)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Finds the id of the first piece of bait in the player's inventory, or nil if no bait is
|
||||||
|
# required, or -1 if the player's inventory does not contain any valid bait.
|
||||||
|
def find_bait
|
||||||
|
baits = @tool.bait
|
||||||
|
baits.empty? ? nil : baits.find(-1) { |bait| mob.inventory.contains(bait) }
|
||||||
|
end
|
||||||
|
|
||||||
# Stops this action.
|
# Stops this action.
|
||||||
def stop()
|
def stop
|
||||||
super
|
super
|
||||||
mob.stop_animation
|
mob.stop_animation
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @spot == other.spot and @position == other.position && @options == @other.options)
|
get_class == other.get_class && @spot == other.spot && @position == other.position &&
|
||||||
|
@options == @other.options
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -104,8 +113,8 @@ on :message, :npc_action do |player, message|
|
|||||||
npc = $world.npc_repository.get(message.index)
|
npc = $world.npc_repository.get(message.index)
|
||||||
spot = FISHING_SPOTS[npc.id]
|
spot = FISHING_SPOTS[npc.id]
|
||||||
|
|
||||||
unless spot.nil?
|
unless spot.nil?
|
||||||
player.start_action(FishingAction.new(player, npc.position, spot, message.option))
|
player.start_action(FishingAction.new(player, npc.position, spot, message.option))
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -7,10 +7,10 @@ FISHING_TOOLS = {}
|
|||||||
|
|
||||||
# A fishing tool.
|
# A fishing tool.
|
||||||
class Tool
|
class Tool
|
||||||
attr_reader :id, :bait, :animation, :message, :name
|
attr_reader :animation, :bait, :id, :message, :name
|
||||||
|
|
||||||
# Creates the tool.
|
# Creates the tool.
|
||||||
def initialize(id, bait=[], animation, message)
|
def initialize(id, animation, message, bait)
|
||||||
@id = id
|
@id = id
|
||||||
@bait = bait
|
@bait = bait
|
||||||
@animation = Animation.new(animation)
|
@animation = Animation.new(animation)
|
||||||
@@ -21,27 +21,40 @@ class Tool
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Appends a tool with the specified name to the hash.
|
# Appends a tool with the specified name to the hash.
|
||||||
def append_tool(name, tool)
|
def tool(name, hash)
|
||||||
FISHING_TOOLS[name] = tool
|
unless hash.has_keys?(:id, :animation, :message)
|
||||||
|
fail 'Hash must contain an id, animation, and message.'
|
||||||
|
end
|
||||||
|
|
||||||
|
bait = hash[:bait] || []
|
||||||
|
FISHING_TOOLS[name] = Tool.new(hash[:id], hash[:animation], hash[:message], bait)
|
||||||
end
|
end
|
||||||
|
|
||||||
HARPOON_ANIMATION_ID = 618
|
# The harpoon fishing animation id.
|
||||||
CAGE_ANIMATION_ID = 619
|
HARPOON_ANIMATION = 618
|
||||||
NET_ANIMATION_ID = 620
|
|
||||||
ROD_ANIMATION_ID = 622
|
|
||||||
|
|
||||||
# TODO The other feathers that can be used
|
# The cage fishing animation id.
|
||||||
FISHING_ROD_BAIT = [ 313 ]
|
CAGE_ANIMATION = 619
|
||||||
FLY_FISHING_ROD_BAIT = [ 314 ]
|
|
||||||
|
|
||||||
append_tool(:lobster_cage, Tool.new(301, CAGE_ANIMATION_ID, 'You attempt to catch a lobster...'))
|
# The net fishing animation id.
|
||||||
append_tool(:small_net, Tool.new(303, NET_ANIMATION_ID, 'You cast out your net...'))
|
NET_ANIMATION = 620
|
||||||
append_tool(:big_net, Tool.new(305, NET_ANIMATION_ID, 'You cast out your net...'))
|
|
||||||
append_tool(:harpoon, Tool.new(311, HARPOON_ANIMATION_ID, 'You start harpooning fish...'))
|
|
||||||
|
|
||||||
append_tool(:fishing_rod, Tool.new(307, FISHING_ROD_BAIT, ROD_ANIMATION_ID, 'You attempt to catch a fish...'))
|
# The rod fishing animation id.
|
||||||
append_tool(:fly_fishing_rod, Tool.new(309, FLY_FISHING_ROD_BAIT, ROD_ANIMATION_ID, 'You attempt to catch a fish...'))
|
ROD_ANIMATION = 622
|
||||||
|
|
||||||
|
# TODO: The other feathers that can be used
|
||||||
|
FISHING_ROD_BAIT = [313]
|
||||||
|
FLY_FISHING_ROD_BAIT = [314]
|
||||||
|
|
||||||
|
tool :lobster_cage, id: 301, animation: CAGE_ANIMATION, message: 'You attempt to catch a lobster...'
|
||||||
|
tool :small_net, id: 303, animation: NET_ANIMATION, message: 'You cast out your net...'
|
||||||
|
tool :big_net, id: 305, animation: NET_ANIMATION, message: 'You cast out your net...'
|
||||||
|
tool :harpoon, id: 311, animation: HARPOON_ANIMATION, message: 'You start harpooning fish...'
|
||||||
|
|
||||||
|
tool :fishing_rod, id: 307, animation: ROD_ANIMATION, message: 'You attempt to catch a fish...',
|
||||||
|
bait: FISHING_ROD_BAIT
|
||||||
|
tool :fly_fishing_rod, id: 309, animation: ROD_ANIMATION, message: 'You attempt to catch a fish...',
|
||||||
|
bait: FLY_FISHING_ROD_BAIT
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class Herb < Ingredient
|
|||||||
@experience = experience
|
@experience = experience
|
||||||
end
|
end
|
||||||
|
|
||||||
def invoke(player, id, slot)
|
def invoke(player, _id, slot)
|
||||||
item = player.inventory.get(slot)
|
item = player.inventory.get(slot)
|
||||||
player.start_action(HerbIdentificationAction.new(player, self, slot, item))
|
player.start_action(HerbIdentificationAction.new(player, self, slot, item))
|
||||||
end
|
end
|
||||||
@@ -37,11 +37,12 @@ class HerbIdentificationAction < Action
|
|||||||
|
|
||||||
def execute
|
def execute
|
||||||
if @pulses == 0
|
if @pulses == 0
|
||||||
unless check_skill(mob, @herb.level, "identify this herb")
|
unless check_skill(mob, @herb.level, 'identify this herb')
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_action
|
execute_action
|
||||||
@pulses += 1
|
@pulses += 1
|
||||||
end
|
end
|
||||||
@@ -56,12 +57,14 @@ class HerbIdentificationAction < Action
|
|||||||
inventory.add(identified)
|
inventory.add(identified)
|
||||||
player.skill_set.add_experience(HERBLORE_ID, @herb.experience)
|
player.skill_set.add_experience(HERBLORE_ID, @herb.experience)
|
||||||
player.send_message("You identify the herb as a #{identified.definition.name}.", true)
|
player.send_message("You identify the herb as a #{identified.definition.name}.", true)
|
||||||
|
# TODO: 'as an' in some cases
|
||||||
end
|
end
|
||||||
|
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and slot == other.slot and herb == other.herb)
|
get_class == other.get_class && slot == other.slot && herb == other.herb
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -69,7 +72,7 @@ end
|
|||||||
def append_herb(item_id, unidentified, level, experience)
|
def append_herb(item_id, unidentified, level, experience)
|
||||||
herb = Herb.new(item_id, unidentified, level, experience)
|
herb = Herb.new(item_id, unidentified, level, experience)
|
||||||
append_herblore_item(herb, unidentified)
|
append_herblore_item(herb, unidentified)
|
||||||
return herb
|
herb
|
||||||
end
|
end
|
||||||
|
|
||||||
# Herbs
|
# Herbs
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Thanks to Sillhouette <http://www.rune-server.org/members/silhouette/> for posting
|
# 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.
|
# a large amount of Herblore skill data which has been thankfully used in this plugin.
|
||||||
|
|
||||||
require 'java'
|
require 'java'
|
||||||
@@ -13,15 +13,14 @@ HERBLORE_ITEM_ON_ITEM = {}
|
|||||||
|
|
||||||
DRINK_ITEM = {}
|
DRINK_ITEM = {}
|
||||||
|
|
||||||
|
|
||||||
# A module which describes an invocable method of the Herblore skill.
|
# A module which describes an invocable method of the Herblore skill.
|
||||||
module HerbloreMethod
|
module HerbloreMethod
|
||||||
def self.new
|
def self.new
|
||||||
raise 'You cannot instantiate this module!'
|
fail 'You cannot instantiate this module!'
|
||||||
end
|
end
|
||||||
|
|
||||||
def invoke(player, primary, secondary)
|
def invoke(_player, _primary, _secondary)
|
||||||
raise NotImplementedError.new('You must implement the invocation of HerbloreMethod!')
|
fail 'You must implement the invocation of HerbloreMethod!'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -76,24 +75,27 @@ def append_herblore_item(method, key, secondary = -1)
|
|||||||
end
|
end
|
||||||
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.
|
# Utility method for checking if a player's inventory has a of the specified id, with optionally
|
||||||
|
# the specified amount (1 by default), at the specified slot.
|
||||||
def check_slot(player, slot, id, amount = 1)
|
def check_slot(player, slot, id, amount = 1)
|
||||||
item = player.inventory.get(slot)
|
item = player.inventory.get(slot)
|
||||||
return (!item.nil? and item.id == id and item.amount >= amount)
|
!item.nil? && item.id == id && item.amount >= amount
|
||||||
end
|
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
|
# Utility method for checking if a player's Herblore (maximum) level is at the required level. Also
|
||||||
# variable, like so: "You need a Herblore level of at least #{required.to_s} to #{action}."
|
# 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)
|
def check_skill(player, required, action)
|
||||||
if (required > player.skill_set.get_skill(Skill::HERBLORE).current_level)
|
if required > player.skill_set.get_skill(Skill::HERBLORE).current_level
|
||||||
player.send_message("You need a Herblore level of at least #{required} to #{action}.")
|
player.send_message("You need a Herblore level of at least #{required} to #{action}.")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# Opens a 'make' dialogue for the specified player, displaying the specified item. Optionally, a listener can be used for the dialogue.
|
# 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)
|
def open_dialogue(player, item, listener = nil)
|
||||||
player.send(SetWidgetItemModelMessage.new(1746, item, 170))
|
player.send(SetWidgetItemModelMessage.new(1746, item, 170))
|
||||||
player.interface_set.open_dialogue(listener, HERBLORE_DIALOGUE)
|
player.interface_set.open_dialogue(listener, HERBLORE_DIALOGUE)
|
||||||
|
|||||||
@@ -18,16 +18,15 @@ class Ingredient
|
|||||||
@item = Item.new(item) # Share item instances.
|
@item = Item.new(item) # Share item instances.
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if the specified player has the specified amount of this ingredient. Optionally, they can immediately be removed if that
|
# Checks if the specified player has the specified amount of this ingredient. Optionally, they
|
||||||
# amount was indeed found.
|
# can immediately be removed if that amount was indeed found.
|
||||||
def check_remove(player, amount, remove)
|
def check_remove(player, amount, remove)
|
||||||
inventory = player.inventory
|
inventory = player.inventory
|
||||||
counter = 0
|
counter = 0
|
||||||
|
|
||||||
inventory.items.each do |inv_item|
|
inventory.items.each do |inv_item|
|
||||||
break unless counter < amount
|
break unless counter < amount
|
||||||
|
next if inv_item.nil?
|
||||||
next if inv_item == nil
|
|
||||||
|
|
||||||
id = inv_item.id
|
id = inv_item.id
|
||||||
inventory_amount = inv_item.amount
|
inventory_amount = inv_item.amount
|
||||||
@@ -47,7 +46,7 @@ class Ingredient
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -59,11 +58,10 @@ class GroundIngredient < Ingredient
|
|||||||
|
|
||||||
def initialize(item_id, raw)
|
def initialize(item_id, raw)
|
||||||
super(item_id)
|
super(item_id)
|
||||||
|
|
||||||
@raw = raw
|
@raw = raw
|
||||||
end
|
end
|
||||||
|
|
||||||
def invoke(player, pestle_mortar, ingredient)
|
def invoke(player, _pestle_mortar, _ingredient)
|
||||||
action = GrindingAction.new(player, self)
|
action = GrindingAction.new(player, self)
|
||||||
listener = GrindingDialogueListener.new(player, action)
|
listener = GrindingDialogueListener.new(player, action)
|
||||||
|
|
||||||
@@ -71,7 +69,8 @@ class GroundIngredient < Ingredient
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A DialogueAdapter used for grinding ingredients. It is also used as an EnterAmountListener for the amount of grinding actions.
|
# A DialogueAdapter used for grinding ingredients. It is also used as an EnterAmountListener for
|
||||||
|
# the amount of grinding actions.
|
||||||
class GrindingDialogueListener < DialogueAdapter
|
class GrindingDialogueListener < DialogueAdapter
|
||||||
include EnterAmountListener
|
include EnterAmountListener
|
||||||
|
|
||||||
@@ -79,7 +78,6 @@ class GrindingDialogueListener < DialogueAdapter
|
|||||||
|
|
||||||
def initialize(player, action)
|
def initialize(player, action)
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@player = player
|
@player = player
|
||||||
@action = action
|
@action = action
|
||||||
end
|
end
|
||||||
@@ -103,7 +101,7 @@ class GrindingDialogueListener < DialogueAdapter
|
|||||||
|
|
||||||
# Called when an amount of grinding actions has been entered.
|
# Called when an amount of grinding actions has been entered.
|
||||||
def amountEntered(amount)
|
def amountEntered(amount)
|
||||||
if amount <= 0 then return else execute(amount) end
|
execute(amount) if amount > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# Called to set the action(s) in motion.
|
# Called to set the action(s) in motion.
|
||||||
@@ -129,7 +127,7 @@ class GrindingAction < Action
|
|||||||
attr_reader :ingredient, :amount, :pulses, :slot, :listener
|
attr_reader :ingredient, :amount, :pulses, :slot, :listener
|
||||||
|
|
||||||
def initialize(player, ingredient)
|
def initialize(player, ingredient)
|
||||||
super 0, true, player
|
super(0, true, player)
|
||||||
|
|
||||||
@ingredient = ingredient
|
@ingredient = ingredient
|
||||||
@pulses = 0
|
@pulses = 0
|
||||||
@@ -145,7 +143,7 @@ class GrindingAction < Action
|
|||||||
if @pulses == 0
|
if @pulses == 0
|
||||||
mob.play_animation GRINDING_ANIM
|
mob.play_animation GRINDING_ANIM
|
||||||
elsif @pulses == 1
|
elsif @pulses == 1
|
||||||
if not gather_materials
|
unless gather_materials
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -163,7 +161,7 @@ class GrindingAction < Action
|
|||||||
set_delay(1)
|
set_delay(1)
|
||||||
elsif @pulses == 2
|
elsif @pulses == 2
|
||||||
mob.stop_animation
|
mob.stop_animation
|
||||||
continue()
|
continue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -176,21 +174,21 @@ class GrindingAction < Action
|
|||||||
raw = @ingredient.raw
|
raw = @ingredient.raw
|
||||||
(0...items.length).each do |slot|
|
(0...items.length).each do |slot|
|
||||||
item = items[slot]
|
item = items[slot]
|
||||||
next if item == nil
|
next if item.nil?
|
||||||
|
|
||||||
id = item.id
|
id = item.id
|
||||||
if id == PESTLE_MORTAR and !pst_mrt
|
if id == PESTLE_MORTAR && !pst_mrt
|
||||||
pst_mrt = true
|
pst_mrt = true
|
||||||
elsif id == raw and !ingr
|
elsif id == raw && !ingr
|
||||||
ingr = true
|
ingr = true
|
||||||
@slot = slot
|
@slot = slot
|
||||||
end
|
end
|
||||||
|
|
||||||
return true if pst_mrt and ingr
|
return true if pst_mrt && ingr
|
||||||
end
|
end
|
||||||
|
|
||||||
mob.send_message("You do not have any more #{name_of(raw).downcase}s.")
|
mob.send_message("You do not have any more #{name_of(raw).downcase}s.")
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Either invokes the stop() method in Action to shut it down
|
# Either invokes the stop() method in Action to shut it down
|
||||||
@@ -213,11 +211,11 @@ class GrindingAction < Action
|
|||||||
|
|
||||||
def stop
|
def stop
|
||||||
super
|
super
|
||||||
mob.inventory.remove_listener(@listener) unless listener == nil
|
mob.inventory.remove_listener(@listener) unless listener.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @ingredient == other.ingredient)
|
get_class == other.get_class && @ingredient == other.ingredient
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -225,7 +223,7 @@ end
|
|||||||
def append_ground(id, raw)
|
def append_ground(id, raw)
|
||||||
ground = GroundIngredient.new(id, raw)
|
ground = GroundIngredient.new(id, raw)
|
||||||
append_herblore_item(ground, PESTLE_MORTAR, raw)
|
append_herblore_item(ground, PESTLE_MORTAR, raw)
|
||||||
return ground
|
ground
|
||||||
end
|
end
|
||||||
|
|
||||||
# Normal ingredients
|
# Normal ingredients
|
||||||
@@ -250,4 +248,4 @@ MAGIC_ROOTS = Ingredient.new(6051)
|
|||||||
UNICORN_HORN_DUST = append_ground(235, 237)
|
UNICORN_HORN_DUST = append_ground(235, 237)
|
||||||
DRAGON_SCALE_DUST = append_ground(241, 243)
|
DRAGON_SCALE_DUST = append_ground(241, 243)
|
||||||
CHOCOLATE_DUST = append_ground(1975, 1973)
|
CHOCOLATE_DUST = append_ground(1975, 1973)
|
||||||
# CRUSHED_NEST = append_ground(6693, 5075)
|
# CRUSHED_NEST = append_ground(6693, 5075) # TODO: only in 377
|
||||||
|
|||||||
@@ -13,25 +13,26 @@ EMPTY_VIAL_ID = 229
|
|||||||
|
|
||||||
MIXING_ANIM = Animation.new(363)
|
MIXING_ANIM = Animation.new(363)
|
||||||
|
|
||||||
# Represents an unfinished potion which can be invoked as a HerbloreMethod and used as an ingredient.
|
# Represents an unfinished potion which can be invoked as a HerbloreMethod and used as an
|
||||||
|
# ingredient.
|
||||||
class UnfinishedPotion < Ingredient
|
class UnfinishedPotion < Ingredient
|
||||||
include HerbloreMethod
|
include HerbloreMethod
|
||||||
|
|
||||||
attr_reader :herb, :level
|
attr_reader :herb, :level
|
||||||
|
|
||||||
def initialize(item_id, herb, level)
|
def initialize(item_id, herb, level)
|
||||||
super item_id
|
super(item_id)
|
||||||
|
|
||||||
@herb = herb
|
@herb = herb
|
||||||
@level = level
|
@level = level
|
||||||
end
|
end
|
||||||
|
|
||||||
def invoke(player, primary, secondary)
|
def invoke(player, _primary, _secondary)
|
||||||
action = UnfinishedMixingAction.new(player, self)
|
action = UnfinishedMixingAction.new(player, self)
|
||||||
listener = UnfinishedMixingDialogueListener.new(player, action)
|
listener = UnfinishedMixingDialogueListener.new(player, action)
|
||||||
|
|
||||||
open_dialogue(player, @item_id, listener)
|
open_dialogue(player, @item_id, listener)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Represents a finished potion which can be invoked as a HerbloreMethod.
|
# Represents a finished potion which can be invoked as a HerbloreMethod.
|
||||||
@@ -55,7 +56,8 @@ class FinishedPotion
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A DialogueAdapter used for mixing potions. It is also used as an EnterAmountListener for the amount of mixing actions.
|
# A DialogueAdapter used for mixing potions. It is also used as an EnterAmountListener for the
|
||||||
|
# amount of mixing actions.
|
||||||
class MixingDialogueListener < DialogueAdapter
|
class MixingDialogueListener < DialogueAdapter
|
||||||
include EnterAmountListener
|
include EnterAmountListener
|
||||||
|
|
||||||
@@ -85,12 +87,12 @@ class MixingDialogueListener < DialogueAdapter
|
|||||||
amount = calculate_maximum if amount == -2
|
amount = calculate_maximum if amount == -2
|
||||||
|
|
||||||
execute(amount)
|
execute(amount)
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# Called when an amount of mixing actions has been entered.
|
# Called when an amount of mixing actions has been entered.
|
||||||
def amountEntered(amount)
|
def amountEntered(amount)
|
||||||
if amount <= 0 then return else execute(amount) end
|
execute(amount) if amount > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# Called to set the action(s) in motion.
|
# Called to set the action(s) in motion.
|
||||||
@@ -99,7 +101,7 @@ class MixingDialogueListener < DialogueAdapter
|
|||||||
@player.start_action(@action)
|
@player.start_action(@action)
|
||||||
end
|
end
|
||||||
|
|
||||||
def calculate_maximum(code)
|
def calculate_maximum(_code)
|
||||||
# Override for potion-specific amount calculation.
|
# Override for potion-specific amount calculation.
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -118,18 +120,17 @@ end
|
|||||||
|
|
||||||
# A MixingDialogueListener used for mixing unfinished potions.
|
# A MixingDialogueListener used for mixing unfinished potions.
|
||||||
class UnfinishedMixingDialogueListener < MixingDialogueListener
|
class UnfinishedMixingDialogueListener < MixingDialogueListener
|
||||||
|
|
||||||
def calculate_maximum
|
def calculate_maximum
|
||||||
inventory = @player.inventory
|
inventory = @player.inventory
|
||||||
|
|
||||||
amount = inventory.get_amount(WATER_VIAL_ID)
|
amount = inventory.get_amount(WATER_VIAL_ID)
|
||||||
|
|
||||||
return 0 if amount <= 0
|
return 0 if amount <= 0
|
||||||
|
|
||||||
herbs = inventory.get_amount(@action.potion.herb.item.id)
|
herbs = inventory.get_amount(@action.potion.herb.item.id)
|
||||||
amount = herbs if amount > herbs
|
[herbs, amount].min
|
||||||
|
|
||||||
return amount
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A MixingDialogueListener used for mixing finished potions.
|
# A MixingDialogueListener used for mixing finished potions.
|
||||||
@@ -144,7 +145,7 @@ class FinishedMixingDialogueListener < MixingDialogueListener
|
|||||||
amount = item_amount if amount > item_amount
|
amount = item_amount if amount > item_amount
|
||||||
end
|
end
|
||||||
|
|
||||||
return amount
|
amount
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -170,6 +171,7 @@ class MixingAction < Action
|
|||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@started = true
|
@started = true
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -178,15 +180,17 @@ class MixingAction < Action
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mob.play_animation(MIXING_ANIM)
|
mob.play_animation(MIXING_ANIM)
|
||||||
execute_action
|
execute_action
|
||||||
|
|
||||||
if (@amount -= 1) > 0 then @pulses = 0 else stop end
|
@amount -= 1
|
||||||
|
@amount > 0 ? @pulses = 0 : stop
|
||||||
end
|
end
|
||||||
|
|
||||||
def stop
|
def stop
|
||||||
super()
|
super()
|
||||||
mob.inventory.remove_listener(@listener) unless @listener == nil
|
mob.inventory.remove_listener(@listener) unless @listener.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_action
|
def execute_action
|
||||||
@@ -195,7 +199,7 @@ class MixingAction < Action
|
|||||||
|
|
||||||
def gather_materials
|
def gather_materials
|
||||||
# Override for ingredient checking and gathering
|
# Override for ingredient checking and gathering
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the amount of actions.
|
# Sets the amount of actions.
|
||||||
@@ -204,7 +208,7 @@ class MixingAction < Action
|
|||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @potion == other.potion)
|
get_class == other.get_class && @potion == other.potion
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -213,7 +217,7 @@ class UnfinishedMixingAction < MixingAction
|
|||||||
attr_reader :slots
|
attr_reader :slots
|
||||||
|
|
||||||
def initialize(player, potion)
|
def initialize(player, potion)
|
||||||
super(player, potion, "use this herb.")
|
super(player, potion, 'use this herb.')
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_action
|
def execute_action
|
||||||
@@ -221,7 +225,9 @@ class UnfinishedMixingAction < MixingAction
|
|||||||
player = mob
|
player = mob
|
||||||
inventory = player.inventory
|
inventory = player.inventory
|
||||||
|
|
||||||
player.send_message("You put the #{name} in the water to make an unfinished #{name.sub(/ leaf$/, "")} potion.", true)
|
created = name.sub(/ leaf$/, '')
|
||||||
|
message = "You put the #{name} in the water to make an unfinished #{created} potion."
|
||||||
|
player.send_message(message, true)
|
||||||
|
|
||||||
@slots.each do |slot, amount|
|
@slots.each do |slot, amount|
|
||||||
unless inventory.remove_slot(slot, amount)
|
unless inventory.remove_slot(slot, amount)
|
||||||
@@ -253,8 +259,9 @@ class UnfinishedMixingAction < MixingAction
|
|||||||
@slots[vial_slot] = 1
|
@slots[vial_slot] = 1
|
||||||
@slots[herb_slot] = 1
|
@slots[herb_slot] = 1
|
||||||
|
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A MixingAction which handles the execution of making FinishedPotions.
|
# A MixingAction which handles the execution of making FinishedPotions.
|
||||||
@@ -262,13 +269,12 @@ class FinishedMixingAction < MixingAction
|
|||||||
attr_reader :unfinished, :ingredient, :slots
|
attr_reader :unfinished, :ingredient, :slots
|
||||||
|
|
||||||
def initialize(player, unfinished, ingredient, potion)
|
def initialize(player, unfinished, ingredient, potion)
|
||||||
super(player, potion, "mix this potion")
|
super(player, potion, 'mix this potion')
|
||||||
|
|
||||||
@unfinished = unfinished
|
@unfinished = unfinished
|
||||||
@ingredient = ingredient
|
@ingredient = ingredient
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_action
|
def executeAction
|
||||||
player = mob
|
player = mob
|
||||||
ingredient = name_of(@ingredient).downcase
|
ingredient = name_of(@ingredient).downcase
|
||||||
name = @potion.item.definition.name.sub('(3)', '')
|
name = @potion.item.definition.name.sub('(3)', '')
|
||||||
@@ -279,7 +285,7 @@ class FinishedMixingAction < MixingAction
|
|||||||
inventory = player.inventory
|
inventory = player.inventory
|
||||||
|
|
||||||
@slots.each do |slot, amount|
|
@slots.each do |slot, amount|
|
||||||
if not inventory.remove_slot(slot, amount)
|
unless inventory.remove_slot(slot, amount) # TODO: will this remove stuff incorrectly?
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -307,60 +313,59 @@ class FinishedMixingAction < MixingAction
|
|||||||
@slots[vial_slot] = 1
|
@slots[vial_slot] = 1
|
||||||
@slots[ingredient_slot] = 1
|
@slots[ingredient_slot] = 1
|
||||||
|
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends a finished potion to the ItemOnItemMessage handling interception.
|
# Appends a finished potion to the ItemOnItemMessage handling interception.
|
||||||
def append_finished_potion(item, unfinished, ingredient, level, experience)
|
def finished_potion(item, unfinished, ingredient, level, experience)
|
||||||
potion = FinishedPotion.new(item, [ unfinished, ingredient ], level, experience)
|
potion = FinishedPotion.new(item, [unfinished, ingredient], level, experience)
|
||||||
append_herblore_item(potion, unfinished.item_id, ingredient.item_id)
|
append_herblore_item(potion, unfinished.item_id, ingredient.item_id)
|
||||||
return potion
|
potion
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends an unfinished potion to the ItemOnItemMessage handling interception.
|
# Appends an unfinished potion to the ItemOnItemMessage handling interception.
|
||||||
def append_unfinished_potion(item, herb, level)
|
def unfinished_potion(item, herb, level)
|
||||||
potion = UnfinishedPotion.new(item, herb, level)
|
potion = UnfinishedPotion.new(item, herb, level)
|
||||||
append_herblore_item(potion, herb.item_id, WATER_VIAL_ID)
|
append_herblore_item(potion, herb.item_id, WATER_VIAL_ID)
|
||||||
return potion
|
potion
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Unfinished potions
|
# Unfinished potions
|
||||||
UNF_GUAM = append_unfinished_potion(91, GUAM_LEAF, 1) # 3
|
UNF_GUAM = unfinished_potion(91, GUAM_LEAF, 1) # 3
|
||||||
UNF_MARRENTILL = append_unfinished_potion(93, MARRENTILL, 5)
|
UNF_MARRENTILL = unfinished_potion(93, MARRENTILL, 5)
|
||||||
UNF_TARROMIN = append_unfinished_potion(95, TARROMIN, 12)
|
UNF_TARROMIN = unfinished_potion(95, TARROMIN, 12)
|
||||||
UNF_HARRALANDER = append_unfinished_potion(97, HARRALANDER, 22)
|
UNF_HARRALANDER = unfinished_potion(97, HARRALANDER, 22)
|
||||||
UNF_RANARR = append_unfinished_potion(99, RANARR, 30)
|
UNF_RANARR = unfinished_potion(99, RANARR, 30)
|
||||||
UNF_TOADFLAX = append_unfinished_potion(3002, TOADFLAX, 34)
|
UNF_TOADFLAX = unfinished_potion(3002, TOADFLAX, 34)
|
||||||
UNF_IRIT = append_unfinished_potion(101, IRIT_LEAF, 45)
|
UNF_IRIT = unfinished_potion(101, IRIT_LEAF, 45)
|
||||||
UNF_AVANTOE = append_unfinished_potion(103, AVANTOE, 50)
|
UNF_AVANTOE = unfinished_potion(103, AVANTOE, 50)
|
||||||
UNF_KWUARM = append_unfinished_potion(105, KWUARM, 55)
|
UNF_KWUARM = unfinished_potion(105, KWUARM, 55)
|
||||||
UNF_SNAPDRAGON = append_unfinished_potion(3004, SNAPDRAGON, 63)
|
UNF_SNAPDRAGON = unfinished_potion(3004, SNAPDRAGON, 63)
|
||||||
UNF_CADANTINE = append_unfinished_potion(107, CADANTINE, 66)
|
UNF_CADANTINE = unfinished_potion(107, CADANTINE, 66)
|
||||||
UNF_LANTADYME = append_unfinished_potion(2483, LANTADYME, 69)
|
UNF_LANTADYME = unfinished_potion(2483, LANTADYME, 69)
|
||||||
UNF_DWARF_WEED = append_unfinished_potion(109, DWARF_WEED, 72)
|
UNF_DWARF_WEED = unfinished_potion(109, DWARF_WEED, 72)
|
||||||
UNF_TORSTOL = append_unfinished_potion(111, TORSTOL, 78)
|
UNF_TORSTOL = unfinished_potion(111, TORSTOL, 78)
|
||||||
|
|
||||||
|
|
||||||
# Finished potions
|
# Finished potions
|
||||||
ATTACK_POT = append_finished_potion(121, UNF_GUAM, EYE_NEWT, 1, 25) # 3, 25
|
ATTACK_POT = finished_potion(121, UNF_GUAM, EYE_NEWT, 1, 25) # 3
|
||||||
ANTIPOISON_POT = append_finished_potion(175, UNF_MARRENTILL, UNICORN_HORN_DUST, 5, 37.5)
|
ANTIPOISON_POT = finished_potion(175, UNF_MARRENTILL, UNICORN_HORN_DUST, 5, 37.5)
|
||||||
STRENGTH_POT = append_finished_potion(115, UNF_TARROMIN, LIMPWURT_ROOT, 12, 50)
|
STRENGTH_POT = finished_potion(115, UNF_TARROMIN, LIMPWURT_ROOT, 12, 50)
|
||||||
RESTORE_POT = append_finished_potion(127, UNF_HARRALANDER, RED_SPIDERS_EGGS, 18, 62.5)
|
RESTORE_POT = finished_potion(127, UNF_HARRALANDER, RED_SPIDERS_EGGS, 18, 62.5)
|
||||||
ENERGY_POT = append_finished_potion(3010, UNF_HARRALANDER, CHOCOLATE_DUST, 26, 67.5)
|
ENERGY_POT = finished_potion(3010, UNF_HARRALANDER, CHOCOLATE_DUST, 26, 67.5)
|
||||||
DEFENCE_POT = append_finished_potion(133, UNF_RANARR, WHITE_BERRIES, 30, 75)
|
DEFENCE_POT = finished_potion(133, UNF_RANARR, WHITE_BERRIES, 30, 75)
|
||||||
AGILITY_POT = append_finished_potion(3034, UNF_TOADFLAX, TOADS_LEGS, 34, 80)
|
AGILITY_POT = finished_potion(3034, UNF_TOADFLAX, TOADS_LEGS, 34, 80)
|
||||||
PRAYER_POT = append_finished_potion(139, UNF_RANARR, SNAPE_GRASS, 38, 87.5)
|
PRAYER_POT = finished_potion(139, UNF_RANARR, SNAPE_GRASS, 38, 87.5)
|
||||||
SUPER_ATTACK_POT = append_finished_potion(145, UNF_IRIT, EYE_NEWT, 45, 100)
|
SUPER_ATTACK_POT = finished_potion(145, UNF_IRIT, EYE_NEWT, 45, 100)
|
||||||
SUPER_ANTIPOISON_POT = append_finished_potion(181, UNF_IRIT, UNICORN_HORN_DUST, 48, 106.3)
|
SUPER_ANTIPOISON_POT = finished_potion(181, UNF_IRIT, UNICORN_HORN_DUST, 48, 106.3)
|
||||||
FISHING_POT = append_finished_potion(151, UNF_AVANTOE, SNAPE_GRASS, 50, 112.5)
|
FISHING_POT = 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_ENERGY_POT = finished_potion(3018, UNF_AVANTOE, MORT_MYRE_FUNGI, 52, 117.5)
|
||||||
SUPER_STRENGTH_POT = append_finished_potion(157, UNF_KWUARM, LIMPWURT_ROOT, 55, 125)
|
SUPER_STRENGTH_POT = finished_potion(157, UNF_KWUARM, LIMPWURT_ROOT, 55, 125)
|
||||||
WEAPON_POISON = append_finished_potion(187, UNF_KWUARM, DRAGON_SCALE_DUST, 60, 137.5)
|
WEAPON_POISON = 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_RESTORE_POT = finished_potion(3026, UNF_SNAPDRAGON, RED_SPIDERS_EGGS, 63, 142.5)
|
||||||
SUPER_DEFENCE_POT = append_finished_potion(163, UNF_CADANTINE, WHITE_BERRIES, 66, 150)
|
SUPER_DEFENCE_POT = finished_potion(163, UNF_CADANTINE, WHITE_BERRIES, 66, 150)
|
||||||
ANTIFIRE_POT = append_finished_potion(2428, UNF_LANTADYME, DRAGON_SCALE_DUST, 69, 157.5)
|
ANTIFIRE_POT = 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)
|
RANGING_POT = finished_potion(169, UNF_DWARF_WEED, WINE_ZAMORAK, 72, 162.5)
|
||||||
MAGIC_POT = append_finished_potion(3042, UNF_LANTADYME, POTATO_CACTUS, 76, 172.5)
|
MAGIC_POT = finished_potion(3042, UNF_LANTADYME, POTATO_CACTUS, 76, 172.5)
|
||||||
ZAMORAK_BREW = append_finished_potion(189, UNF_TORSTOL, JANGERBERRIES, 78, 175)
|
ZAMORAK_BREW = finished_potion(189, UNF_TORSTOL, JANGERBERRIES, 78, 175)
|
||||||
|
|||||||
@@ -2,33 +2,26 @@ require 'java'
|
|||||||
|
|
||||||
java_import 'org.apollo.game.model.Animation'
|
java_import 'org.apollo.game.model.Animation'
|
||||||
java_import 'org.apollo.game.model.Graphic'
|
java_import 'org.apollo.game.model.Graphic'
|
||||||
|
java_import 'org.apollo.game.model.entity.Skill'
|
||||||
|
|
||||||
ALCHEMY_SPELLS = {}
|
ALCHEMY_SPELLS = {}
|
||||||
|
|
||||||
LOW_ALCH_ANIM = Animation.new(712)
|
ILLEGAL_ALCH_ITEMS = [995, 6529, 6306, 6307, 6308, 6309, 6310]
|
||||||
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 ]
|
|
||||||
|
|
||||||
|
# A spell that alchemises an item.
|
||||||
class AlchemySpell < Spell
|
class AlchemySpell < Spell
|
||||||
attr_reader :high, :animation, :graphic, :multiplier, :experience, :delay
|
attr_reader :animation, :graphic, :multiplier, :experience
|
||||||
|
|
||||||
def initialize(level, elements, high, animation, graphic, multiplier, experience, delay)
|
def initialize(level, elements, experience, animation, graphic, multiplier)
|
||||||
super(level, elements, experience)
|
super(level, elements, experience)
|
||||||
@high = high
|
|
||||||
@animation = animation
|
@animation = animation
|
||||||
@graphic = graphic
|
@graphic = graphic
|
||||||
@multiplier = multiplier
|
@multiplier = multiplier
|
||||||
@delay = delay
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# An Action that performs an AlchemySpell.
|
||||||
class AlchemyAction < ItemSpellAction
|
class AlchemyAction < ItemSpellAction
|
||||||
|
|
||||||
def initialize(player, alchemy, slot, item)
|
def initialize(player, alchemy, slot, item)
|
||||||
@@ -36,10 +29,10 @@ class AlchemyAction < ItemSpellAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
def illegal_item?
|
def illegal_item?
|
||||||
return ILLEGAL_ALCH_ITEMS.include?(@item.id)
|
ILLEGAL_ALCH_ITEMS.include?(@item.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_action
|
def executeAction
|
||||||
if @pulses == 0
|
if @pulses == 0
|
||||||
mob.play_animation(@spell.animation)
|
mob.play_animation(@spell.animation)
|
||||||
mob.play_graphic(@spell.graphic)
|
mob.play_graphic(@spell.graphic)
|
||||||
@@ -51,8 +44,8 @@ class AlchemyAction < ItemSpellAction
|
|||||||
inventory.remove(inventory.get(@slot).id, 1)
|
inventory.remove(inventory.get(@slot).id, 1)
|
||||||
inventory.add(995, gold)
|
inventory.add(995, gold)
|
||||||
|
|
||||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
mob.skill_set.add_experience(Skill::MAGIC, @spell.experience)
|
||||||
set_delay(@spell.delay)
|
set_delay(ALCHEMY_DELAY)
|
||||||
elsif @pulses == 1
|
elsif @pulses == 1
|
||||||
mob.stop_animation
|
mob.stop_animation
|
||||||
mob.stop_graphic
|
mob.stop_graphic
|
||||||
@@ -62,9 +55,31 @@ class AlchemyAction < ItemSpellAction
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_alchemy(button, level, elements, high, animation, graphic, multiplier, experience, delay)
|
private
|
||||||
ALCHEMY_SPELLS[button] = AlchemySpell.new(level, elements, high, animation, graphic, multiplier, experience, delay)
|
|
||||||
|
# The delay of an alchemy spell.
|
||||||
|
ALCHEMY_DELAY = 4
|
||||||
|
|
||||||
|
# The height of the graphic.
|
||||||
|
GRAPHIC_HEIGHT = 100
|
||||||
|
|
||||||
|
# Inserts an `AlchemySpell` into the hash of available alchemy spells.
|
||||||
|
def alchemy(_name, hash)
|
||||||
|
unless hash.has_keys?(:button, :level, :runes, :animation, :graphic, :multiplier, :experience)
|
||||||
|
fail 'Hash must have button, level, runes, animation, graphic, multiplier, experience keys.'
|
||||||
|
end
|
||||||
|
|
||||||
|
id, multiplier = hash[:button], hash[:multiplier]
|
||||||
|
level, runes, experience = hash[:level], hash[:runes], hash[:experience]
|
||||||
|
|
||||||
|
animation = Animation.new(hash[:animation])
|
||||||
|
graphic = Graphic.new(hash[:graphic], 0, GRAPHIC_HEIGHT)
|
||||||
|
|
||||||
|
ALCHEMY_SPELLS[id] = AlchemySpell.new(level, runes, experience, animation, graphic, multiplier)
|
||||||
end
|
end
|
||||||
|
|
||||||
append_alchemy(1162, 21, { FIRE => 3, NATURE => 1 }, false, LOW_ALCH_ANIM, LOW_ALCH_GRAPHIC, 0.48, 31, 1) # Low level alchemy
|
alchemy :low_level, button: 1_162, level: 21, runes: { FIRE => 3, NATURE => 1 }, animation: 712,
|
||||||
append_alchemy(1178, 55, { FIRE => 5, NATURE => 1 }, true, HIGH_ALCH_ANIM, HIGH_ALCH_GRAPHIC, 0.72, 65, 4) # High level alchemy
|
graphic: 112, multiplier: 0.48, experience: 31
|
||||||
|
|
||||||
|
alchemy :high_level, button: 1_178, level: 55, runes: { FIRE => 5, NATURE => 1 }, animation: 713,
|
||||||
|
graphic: 113, multiplier: 0.72, experience: 65
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ require 'java'
|
|||||||
java_import 'org.apollo.game.model.Animation'
|
java_import 'org.apollo.game.model.Animation'
|
||||||
java_import 'org.apollo.game.model.Graphic'
|
java_import 'org.apollo.game.model.Graphic'
|
||||||
java_import 'org.apollo.game.model.Item'
|
java_import 'org.apollo.game.model.Item'
|
||||||
|
java_import 'org.apollo.game.model.entity.Skill'
|
||||||
|
|
||||||
CONVERT_SPELLS = {}
|
CONVERT_SPELLS = {}
|
||||||
BONES_ID = 526
|
BONES_ID = 526
|
||||||
@@ -10,6 +11,7 @@ BONES_ID = 526
|
|||||||
CONVERT_ANIM = Animation.new(722)
|
CONVERT_ANIM = Animation.new(722)
|
||||||
CONVERT_GRAPHIC = Graphic.new(141, 0, 100)
|
CONVERT_GRAPHIC = Graphic.new(141, 0, 100)
|
||||||
|
|
||||||
|
# A `Spell` for converting items.
|
||||||
class ConvertSpell < Spell
|
class ConvertSpell < Spell
|
||||||
attr_reader :reward
|
attr_reader :reward
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ class ConvertSpell < Spell
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A `SpellAction` for a `ConvertSpell`.
|
||||||
class ConvertingAction < SpellAction
|
class ConvertingAction < SpellAction
|
||||||
attr_reader :slots
|
attr_reader :slots
|
||||||
|
|
||||||
@@ -36,19 +39,17 @@ class ConvertingAction < SpellAction
|
|||||||
inventory = mob.inventory
|
inventory = mob.inventory
|
||||||
firing = (@slots.length * 2) < inventory.capacity
|
firing = (@slots.length * 2) < inventory.capacity
|
||||||
|
|
||||||
inventory.stop_firing_events unless firing # In the case of many changes, wait with firing events
|
inventory.stop_firing_events unless firing # In case of many changes, wait with firing events
|
||||||
|
|
||||||
reward = @spell.reward
|
reward = @spell.reward
|
||||||
@slots.each do |slot|
|
@slots.each { |slot| inventory.set(slot, reward) }
|
||||||
inventory.set(slot, reward) # Share the instance
|
|
||||||
end
|
|
||||||
|
|
||||||
unless firing # If we waited with firing events, restore it now and force a refresh
|
unless firing # If we waited with firing events, restore it now and force a refresh
|
||||||
inventory.start_firing_events
|
inventory.start_firing_events
|
||||||
inventory.force_refresh
|
inventory.force_refresh
|
||||||
end
|
end
|
||||||
|
|
||||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
mob.skill_set.add_experience(Skill::MAGIC, @spell.experience)
|
||||||
set_delay(2)
|
set_delay(2)
|
||||||
elsif @pulses == 1
|
elsif @pulses == 1
|
||||||
mob.stop_animation
|
mob.stop_animation
|
||||||
@@ -66,21 +67,22 @@ def bone_slots(player)
|
|||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
slots = []
|
slots = []
|
||||||
|
|
||||||
(0...inventory.capacity).each do |slot|
|
(0...inventory.capacity).each do |slot|
|
||||||
break unless counter <= size
|
break unless counter <= size
|
||||||
|
|
||||||
item = items[slot]
|
item = items[slot]
|
||||||
slots << slot if (item != nil and item.id == BONES_ID)
|
slots << slot if !item.nil? && item.id == BONES_ID
|
||||||
|
|
||||||
counter += 1
|
counter += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
return slots
|
slots
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_convert(button, level, elements, experience, reward)
|
def convert(button, level, elements, experience, reward)
|
||||||
CONVERT_SPELLS[button] = ConvertSpell.new(level, elements, experience, reward)
|
CONVERT_SPELLS[button] = ConvertSpell.new(level, elements, experience, reward)
|
||||||
end
|
end
|
||||||
|
|
||||||
append_convert 1159, 15, { EARTH => 2, WATER => 2, NATURE => 1 }, 25, 1963 # Bones to bananas
|
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
|
# convert 15877, 60, { NATURE => 2, WATER => 4, EARTH => 4 }, 35.5, 6883 # Bones to peaches
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ MUD_RUNE = 4698
|
|||||||
STEAM_RUNE = 4694
|
STEAM_RUNE = 4694
|
||||||
LAVA_RUNE = 4699
|
LAVA_RUNE = 4699
|
||||||
|
|
||||||
|
# An element of a spell.
|
||||||
class Element
|
class Element
|
||||||
attr_reader :runes, :staffs, :name
|
attr_reader :runes, :staffs, :name
|
||||||
|
|
||||||
def initialize(runes, staffs, name="Null")
|
def initialize(runes, staffs, name = 'Null')
|
||||||
@runes = runes
|
@runes = runes
|
||||||
@staffs = staffs
|
@staffs = staffs
|
||||||
@name = name
|
@name = name
|
||||||
@@ -40,10 +41,8 @@ class Element
|
|||||||
|
|
||||||
def check_remove(player, amount, remove)
|
def check_remove(player, amount, remove)
|
||||||
weapon = player.equipment.get(EquipmentConstants::WEAPON)
|
weapon = player.equipment.get(EquipmentConstants::WEAPON)
|
||||||
if @staffs != nil && weapon != nil
|
unless @staffs.nil? || weapon.nil?
|
||||||
@staffs.each do |staff|
|
@staffs.each { |staff| return true if weapon.id == staff }
|
||||||
return true if weapon.id == staff
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
inventory = player.inventory
|
inventory = player.inventory
|
||||||
@@ -53,7 +52,7 @@ class Element
|
|||||||
|
|
||||||
inventory.items.each do |item|
|
inventory.items.each do |item|
|
||||||
break unless counter < amount
|
break unless counter < amount
|
||||||
next if item == nil
|
next if item.nil?
|
||||||
|
|
||||||
amt = item.amount
|
amt = item.amount
|
||||||
@runes.each do |rune|
|
@runes.each do |rune|
|
||||||
@@ -73,40 +72,36 @@ class Element
|
|||||||
end
|
end
|
||||||
|
|
||||||
if counter >= amount
|
if counter >= amount
|
||||||
if remove
|
found.each { |id, amt| inventory.remove(id, amt) } if remove
|
||||||
found.each do |id, amt|
|
|
||||||
inventory.remove(id, amt)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
AIR_RUNES = [ 556, 4695, 4696, 4697 ]
|
AIR_RUNES = [556, 4695, 4696, 4697]
|
||||||
WATER_RUNES = [ 555, 4695, 4698, 4694 ]
|
WATER_RUNES = [555, 4695, 4698, 4694]
|
||||||
EARTH_RUNES = [ 557, 4696, 4697, 4698 ]
|
EARTH_RUNES = [557, 4696, 4697, 4698]
|
||||||
FIRE_RUNES = [ 554, 4697, 4694, 4699 ]
|
FIRE_RUNES = [554, 4697, 4694, 4699]
|
||||||
|
|
||||||
AIR_STAFFS = [ 1381, 1397, 1405 ]
|
AIR_STAFFS = [1381, 1397, 1405]
|
||||||
WATER_STAFFS = [ 1383, 1395, 1403 ]
|
WATER_STAFFS = [1383, 1395, 1403]
|
||||||
EARTH_STAFFS = [ 1385, 1399, 1407, 3053, 3054 ]
|
EARTH_STAFFS = [1385, 1399, 1407, 3053, 3054]
|
||||||
FIRE_STAFFS = [ 1387, 1393, 1401, 3053, 3054 ]
|
FIRE_STAFFS = [1387, 1393, 1401, 3053, 3054]
|
||||||
|
|
||||||
AIR = Element.new(AIR_RUNES, AIR_STAFFS, "Air rune")
|
AIR = Element.new(AIR_RUNES, AIR_STAFFS, 'Air rune')
|
||||||
WATER = Element.new(WATER_RUNES, WATER_STAFFS, "Water rune")
|
WATER = Element.new(WATER_RUNES, WATER_STAFFS, 'Water rune')
|
||||||
EARTH = Element.new(EARTH_RUNES, EARTH_STAFFS, "Earth rune")
|
EARTH = Element.new(EARTH_RUNES, EARTH_STAFFS, 'Earth rune')
|
||||||
FIRE = Element.new(FIRE_RUNES, FIRE_STAFFS, "Fire rune")
|
FIRE = Element.new(FIRE_RUNES, FIRE_STAFFS, 'Fire rune')
|
||||||
|
|
||||||
MIND = Element.new([MIND_RUNE], nil, "Mind rune")
|
MIND = Element.new([MIND_RUNE], nil, 'Mind rune')
|
||||||
CHAOS = Element.new([CHAOS_RUNE], nil, "Chaos rune")
|
CHAOS = Element.new([CHAOS_RUNE], nil, 'Chaos rune')
|
||||||
DEATH = Element.new([DEATH_RUNE], nil, "Death rune")
|
DEATH = Element.new([DEATH_RUNE], nil, 'Death rune')
|
||||||
BLOOD = Element.new([BLOOD_RUNE], nil, "Blood rune")
|
BLOOD = Element.new([BLOOD_RUNE], nil, 'Blood rune')
|
||||||
|
|
||||||
COSMIC = Element.new([COSMIC_RUNE], nil, "Cosmic rune")
|
COSMIC = Element.new([COSMIC_RUNE], nil, 'Cosmic rune')
|
||||||
LAW = Element.new([LAW_RUNE], nil, "Law rune")
|
LAW = Element.new([LAW_RUNE], nil, 'Law rune')
|
||||||
NATURE = Element.new([NATURE_RUNE], nil, "Nature rune")
|
NATURE = Element.new([NATURE_RUNE], nil, 'Nature rune')
|
||||||
SOUL = Element.new([SOUL_RUNE], nil, "Soul rune")
|
SOUL = Element.new([SOUL_RUNE], nil, 'Soul rune')
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ ENCHANT_SPELLS = {}
|
|||||||
ENCHANT_ITEMS = {}
|
ENCHANT_ITEMS = {}
|
||||||
|
|
||||||
RING_GFX = Graphic.new(238, 0, 100)
|
RING_GFX = Graphic.new(238, 0, 100)
|
||||||
RING_ANIM = Animation.new(713) # TODO: No way we need one of the alchemy anims for enchanting...
|
RING_ANIM = Animation.new(713) # TODO: an alchemy animation for enchanting?
|
||||||
|
|
||||||
LOW_NECK_GFX = Graphic.new(114, 0, 100)
|
LOW_NECK_GFX = Graphic.new(114, 0, 100)
|
||||||
LOW_NECK_ANIM = Animation.new(719)
|
LOW_NECK_ANIM = Animation.new(719)
|
||||||
@@ -21,6 +21,7 @@ HIGH_NECK_ANIM = Animation.new(721)
|
|||||||
|
|
||||||
ONYX_NECK_GFX = Graphic.new(452, 0, 100)
|
ONYX_NECK_GFX = Graphic.new(452, 0, 100)
|
||||||
|
|
||||||
|
# A `Spell` for enchanting an item.
|
||||||
class EnchantSpell < Spell
|
class EnchantSpell < Spell
|
||||||
attr_reader :button, :animation, :graphic, :delay
|
attr_reader :button, :animation, :graphic, :delay
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ class EnchantSpell < Spell
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A `SpellAction` for an `EnchantSpell`.
|
||||||
class EnchantAction < ItemSpellAction
|
class EnchantAction < ItemSpellAction
|
||||||
attr_reader :reward
|
attr_reader :reward
|
||||||
|
|
||||||
@@ -43,10 +45,10 @@ class EnchantAction < ItemSpellAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
def illegal_item?
|
def illegal_item?
|
||||||
return ENCHANT_ITEMS[@item.id] == nil
|
ENCHANT_ITEMS[@item.id].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_action
|
def executeAction
|
||||||
if @pulses == 0
|
if @pulses == 0
|
||||||
mob.play_animation(@spell.animation)
|
mob.play_animation(@spell.animation)
|
||||||
mob.play_graphic(@spell.graphic)
|
mob.play_graphic(@spell.graphic)
|
||||||
@@ -65,7 +67,7 @@ class EnchantAction < ItemSpellAction
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_enchant(button, level, elements, item, animation, graphic, delay, experience, reward)
|
def enchant(button, level, elements, item, animation, graphic, delay, experience, reward)
|
||||||
enchant = EnchantSpell.new(button, level, elements, animation, graphic, delay, experience)
|
enchant = EnchantSpell.new(button, level, elements, animation, graphic, delay, experience)
|
||||||
ENCHANT_SPELLS[item] = enchant
|
ENCHANT_SPELLS[item] = enchant
|
||||||
ENCHANT_ITEMS[item] = reward
|
ENCHANT_ITEMS[item] = reward
|
||||||
@@ -79,31 +81,27 @@ DSTONE_ELEMENTS = { WATER => 15, EARTH => 15, COSMIC => 1 }
|
|||||||
ONYX_ELEMENTS = { EARTH => 20, FIRE => 20, COSMIC => 1 }
|
ONYX_ELEMENTS = { EARTH => 20, FIRE => 20, COSMIC => 1 }
|
||||||
|
|
||||||
# Sapphire
|
# Sapphire
|
||||||
append_enchant 1155, 7, SAPPHIRE_ELEMENTS, 1637, RING_ANIM, RING_GFX, 2, 17.5, 2550 # Ring
|
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
|
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
|
enchant 1155, 7, SAPPHIRE_ELEMENTS, 1692, LOW_NECK_ANIM, LOW_NECK_GFX, 1, 17.5, 1727 # Amulet
|
||||||
|
|
||||||
# Emerald
|
# Emerald
|
||||||
append_enchant 1165, 27, EMERALD_ELEMENTS, 1639, RING_ANIM, RING_GFX, 2, 37, 2552 # Ring
|
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
|
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
|
enchant 1165, 27, EMERALD_ELEMENTS, 1696, LOW_NECK_ANIM, LOW_NECK_GFX, 1, 37, 1729 # Amulet
|
||||||
|
|
||||||
# Ruby
|
# Ruby
|
||||||
append_enchant 1176, 49, RUBY_ELEMENTS, 1641, RING_ANIM, RING_GFX, 2, 59, 2568 # Ring
|
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
|
enchant 1176, 49, RUBY_ELEMENTS, 1698, MED_NECK_ANIM, MED_NECK_GFX, 2, 59, 1725 # Amulet
|
||||||
append_enchant 1176, 49, RUBY_ELEMENTS, 1698, MED_NECK_ANIM, MED_NECK_GFX, 2, 59, 1725 # Amulet
|
|
||||||
|
|
||||||
# Diamond
|
# Diamond
|
||||||
append_enchant 1180, 57, DIAMOND_ELEMENTS, 1643, RING_ANIM, RING_GFX, 2, 67, 2570 # Ring
|
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
|
enchant 1180, 57, DIAMOND_ELEMENTS, 1700, MED_NECK_ANIM, MED_NECK_GFX, 2, 67, 1731 # Amulet
|
||||||
append_enchant 1180, 57, DIAMOND_ELEMENTS, 1700, MED_NECK_ANIM, MED_NECK_GFX, 2, 67, 1731 # Amulet
|
|
||||||
|
|
||||||
# Dragonstone
|
# Dragonstone
|
||||||
append_enchant 1187, 68, DSTONE_ELEMENTS, 1645, RING_ANIM, RING_GFX, 2, 78, 2572 # Ring
|
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
|
enchant 1187, 68, DSTONE_ELEMENTS, 1702, HIGH_NECK_ANIM, HIGH_NECK_GFX, 3, 78, 1712 # Amulet
|
||||||
append_enchant 1187, 68, DSTONE_ELEMENTS, 1702, HIGH_NECK_ANIM, HIGH_NECK_GFX, 3, 78, 1712 # Amulet
|
|
||||||
|
|
||||||
# Onyx
|
# Onyx
|
||||||
append_enchant 6003, 87, ONYX_ELEMENTS, 6575, RING_ANIM, RING_GFX, 2, 97, 6583 # Ring
|
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
|
enchant 6003, 87, ONYX_ELEMENTS, 6581, HIGH_NECK_ANIM, ONYX_NECK_GFX, 2, 97, 6585 # Amulet
|
||||||
append_enchant 6003, 87, ONYX_ELEMENTS, 6581, HIGH_NECK_ANIM, ONYX_NECK_GFX, 2, 97, 6585 # Amulet
|
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ java_import 'org.apollo.game.message.impl.DisplayTabInterfaceMessage'
|
|||||||
java_import 'org.apollo.game.model.entity.EquipmentConstants'
|
java_import 'org.apollo.game.model.entity.EquipmentConstants'
|
||||||
java_import 'org.apollo.game.model.entity.Skill'
|
java_import 'org.apollo.game.model.entity.Skill'
|
||||||
|
|
||||||
|
# A `Message` to display the magic spellbook.
|
||||||
DISPLAY_SPELLBOOK = DisplayTabInterfaceMessage.new(6)
|
DISPLAY_SPELLBOOK = DisplayTabInterfaceMessage.new(6)
|
||||||
|
|
||||||
|
# A spell that can be cast.
|
||||||
class Spell
|
class Spell
|
||||||
attr_reader :level, :elements, :experience
|
attr_reader :level, :elements, :experience
|
||||||
|
|
||||||
@@ -18,23 +20,24 @@ class Spell
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# An `Action` for casting a `Spell`.
|
||||||
class SpellAction < Action
|
class SpellAction < Action
|
||||||
attr_reader :spell, :pulses
|
attr_reader :spell, :pulses
|
||||||
|
|
||||||
def initialize(mob, spell)
|
def initialize(mob, spell)
|
||||||
super(0, true, mob)
|
super(0, true, mob)
|
||||||
|
|
||||||
@spell = spell
|
@spell = spell
|
||||||
@pulses = 0
|
@pulses = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
if @pulses == 0
|
if @pulses == 0
|
||||||
unless (check_skill and process_elements)
|
unless check_skill && process_elements
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_action
|
execute_action
|
||||||
@pulses += 1
|
@pulses += 1
|
||||||
end
|
end
|
||||||
@@ -50,7 +53,7 @@ class SpellAction < Action
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_elements
|
def process_elements
|
||||||
@@ -64,16 +67,16 @@ class SpellAction < Action
|
|||||||
end
|
end
|
||||||
|
|
||||||
elements.each { |element, amount| element.check_remove(mob, amount, true) }
|
elements.each { |element, amount| element.check_remove(mob, amount, true) }
|
||||||
|
true
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @spell == other.spell)
|
get_class == other.get_class && @spell == other.spell
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A `SpellAction` that verifies an input `Item` is legal.
|
||||||
class ItemSpellAction < SpellAction
|
class ItemSpellAction < SpellAction
|
||||||
attr_reader :slot, :item
|
attr_reader :slot, :item
|
||||||
|
|
||||||
@@ -112,7 +115,7 @@ class ItemSpellAction < SpellAction
|
|||||||
|
|
||||||
def illegal_item?
|
def illegal_item?
|
||||||
# Override this method if necessary
|
# Override this method if necessary
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -131,7 +134,7 @@ on :message, :magic_on_item do |player, message|
|
|||||||
end
|
end
|
||||||
|
|
||||||
ench = ENCHANT_SPELLS[message.id]
|
ench = ENCHANT_SPELLS[message.id]
|
||||||
if !ench.nil? and ench.button == spell
|
if !ench.nil? && ench.button == spell
|
||||||
slot = message.slot
|
slot = message.slot
|
||||||
item = player.inventory.get(slot)
|
item = player.inventory.get(slot)
|
||||||
player.start_action(EnchantAction.new(player, ench, slot, item, ENCHANT_ITEMS[item.id]))
|
player.start_action(EnchantAction.new(player, ench, slot, item, ENCHANT_ITEMS[item.id]))
|
||||||
@@ -152,9 +155,15 @@ on :message, :button do |player, message|
|
|||||||
|
|
||||||
conv = CONVERT_SPELLS[button]
|
conv = CONVERT_SPELLS[button]
|
||||||
unless conv.nil?
|
unless conv.nil?
|
||||||
slots = bone_slots player
|
slots = bone_slots(player)
|
||||||
|
|
||||||
|
if slots.length == 0
|
||||||
|
player.send_message("You can't convert these bones!")
|
||||||
|
else
|
||||||
|
player.start_action(ConvertingAction.new(player, conv, slots))
|
||||||
|
end
|
||||||
|
|
||||||
if slots.length == 0 then player.send_message("You can't convert these bones!") else player.start_action(ConvertingAction.new(player, conv, slots)) end
|
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
# Thanks to phl0w <http://www.rune-server.org/members/phl0w/> for providing
|
# Thanks to phl0w <http://www.rune-server.org/members/phl0w> for providing
|
||||||
# the correct destination coordinates of the ancient teleports.
|
# the correct destination coordinates of the ancient teleports.
|
||||||
|
|
||||||
require 'java'
|
require 'java'
|
||||||
|
|
||||||
java_import 'org.apollo.game.model.Animation'
|
java_import 'org.apollo.game.model.Animation'
|
||||||
java_import 'org.apollo.game.model.Graphic'
|
java_import 'org.apollo.game.model.Graphic'
|
||||||
java_import 'org.apollo.game.model.Position'
|
java_import 'org.apollo.game.model.Position'
|
||||||
|
java_import 'org.apollo.game.model.entity.Skill'
|
||||||
|
|
||||||
TELEPORT_SPELLS = {}
|
TELEPORT_SPELLS = {}
|
||||||
|
|
||||||
@@ -16,6 +18,7 @@ ANCIENT_TELE_END_GRAPHIC = Graphic.new(455)
|
|||||||
ANCIENT_TELE_ANIM = Animation.new(1979)
|
ANCIENT_TELE_ANIM = Animation.new(1979)
|
||||||
ANCIENT_TELE_GRAPHIC = Graphic.new(392)
|
ANCIENT_TELE_GRAPHIC = Graphic.new(392)
|
||||||
|
|
||||||
|
# A `Spell` that teleports a `Player` to another `Position`.
|
||||||
class TeleportSpell < Spell
|
class TeleportSpell < Spell
|
||||||
attr_reader :ancient, :destination, :experience, :name
|
attr_reader :ancient, :destination, :experience, :name
|
||||||
|
|
||||||
@@ -28,6 +31,7 @@ class TeleportSpell < Spell
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A `SpellAction` for a `TeleportSpell`.
|
||||||
class TeleportingAction < SpellAction
|
class TeleportingAction < SpellAction
|
||||||
|
|
||||||
def initialize(mob, spell)
|
def initialize(mob, spell)
|
||||||
@@ -43,7 +47,7 @@ class TeleportingAction < SpellAction
|
|||||||
mob.play_animation(MODERN_TELE_ANIM)
|
mob.play_animation(MODERN_TELE_ANIM)
|
||||||
elsif @pulses == 1
|
elsif @pulses == 1
|
||||||
mob.play_graphic(MODERN_TELE_GRAPHIC)
|
mob.play_graphic(MODERN_TELE_GRAPHIC)
|
||||||
delay = 1
|
set_delay(1)
|
||||||
elsif @pulses == 2
|
elsif @pulses == 2
|
||||||
mob.stop_graphic
|
mob.stop_graphic
|
||||||
mob.play_animation(MODERN_TELE_END_ANIM)
|
mob.play_animation(MODERN_TELE_END_ANIM)
|
||||||
@@ -57,38 +61,44 @@ class TeleportingAction < SpellAction
|
|||||||
if @pulses == 0
|
if @pulses == 0
|
||||||
mob.play_graphic(ANCIENT_TELE_GRAPHIC)
|
mob.play_graphic(ANCIENT_TELE_GRAPHIC)
|
||||||
mob.play_animation(ANCIENT_TELE_ANIM)
|
mob.play_animation(ANCIENT_TELE_ANIM)
|
||||||
delay = 2
|
set_delay(2)
|
||||||
elsif @pulses == 2
|
elsif @pulses == 2
|
||||||
mob.stop_graphic
|
mob.stop_graphic
|
||||||
mob.stop_animation
|
mob.stop_animation
|
||||||
mob.teleport(@spell.destination)
|
mob.teleport(@spell.destination)
|
||||||
mob.skill_set.add_experience(MAGIC_SKILL_ID, @spell.experience)
|
mob.skill_set.add_experience(Skill::MAGIC, @spell.experience)
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_tele(ancient, button, level, elements, x, y, experience, name)
|
def tele(ancient = false, button, level, elements, x, y, experience, name)
|
||||||
TELEPORT_SPELLS[button] = TeleportSpell.new(ancient, level, elements, Position.new(x, y), experience, name)
|
position = Position.new(x, y)
|
||||||
|
TELEPORT_SPELLS[button] = TeleportSpell.new(ancient, level, elements, position, experience, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ancient_tele(*args)
|
||||||
|
tele(true, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Modern teleports
|
# Modern teleports
|
||||||
append_tele(false, 1164, 25, { FIRE => 1, AIR => 3, LAW => 1 }, 3213, 3424, 35, "Varrock")
|
tele 1_164, 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")
|
tele 1_167, 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")
|
tele 1_170, 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")
|
tele 1_174, 45, { AIR => 5, LAW => 1 }, 2757, 3478, 55.5, 'Camelot'
|
||||||
append_tele(false, 1540, 51, { WATER => 2, LAW => 2 }, 2662, 3306, 61, "Ardougne")
|
tele 1_540, 51, { WATER => 2, LAW => 2 }, 2662, 3306, 61, 'Ardougne'
|
||||||
append_tele(false, 1541, 58, { EARTH => 2, LAW => 2 }, 2549, 3114, 68, "the Watchtower")
|
tele 1_541, 58, { EARTH => 2, LAW => 2 }, 2549, 3114, 68, 'the Watchtower'
|
||||||
append_tele(false, 7455, 61, { FIRE => 2, LAW => 2 }, 2871, 3590, 68, "Trollheim")
|
tele 7_455, 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")
|
tele 18_470, 64, { FIRE => 2, WATER => 2, LAW => 2, Element.new([1963], nil, 'Banana') => 1 },
|
||||||
|
2_754, 2_785, 76, 'Ape Atoll'
|
||||||
|
|
||||||
# Ancient teleports
|
# Ancient teleports
|
||||||
append_tele(true, 13035, 54, { LAW => 2, FIRE => 1, AIR => 1 }, 3098, 9882, 64, "Paddewwa")
|
ancient_tele 13_035, 54, { LAW => 2, FIRE => 1, AIR => 1 }, 3098, 9882, 64, 'Paddewwa'
|
||||||
append_tele(true, 13045, 60, { LAW => 2, SOUL => 2 }, 3320, 3338, 70, "Senntisten")
|
ancient_tele 13_045, 60, { LAW => 2, SOUL => 2 }, 3320, 3338, 70, 'Senntisten'
|
||||||
append_tele(true, 13053, 66, { LAW => 2, BLOOD => 1 }, 3493, 3472, 76, "Kharyll")
|
ancient_tele 13_053, 66, { LAW => 2, BLOOD => 1 }, 3493, 3472, 76, 'Kharyll'
|
||||||
append_tele(true, 13061, 72, { LAW => 2, WATER => 4 }, 3003, 3470, 82, "Lassar")
|
ancient_tele 13_061, 72, { LAW => 2, WATER => 4 }, 3003, 3470, 82, 'Lassar'
|
||||||
append_tele(true, 13069, 78, { LAW => 2, FIRE => 3, AIR => 2 }, 2966, 3696, 88, "Dareeyak")
|
ancient_tele 13_069, 78, { LAW => 2, FIRE => 3, AIR => 2 }, 2966, 3_696, 88, 'Dareeyak'
|
||||||
append_tele(true, 13079, 84, { LAW => 2, SOUL => 2 }, 3163, 3664, 94, "Carrallangar")
|
ancient_tele 13_079, 84, { LAW => 2, SOUL => 2 }, 3163, 3664, 94, 'Carrallangar'
|
||||||
append_tele(true, 13087, 90, { LAW => 2, BLOOD => 2 }, 3287, 3883, 100, "Annakarl")
|
ancient_tele 13_087, 90, { LAW => 2, BLOOD => 2 }, 3287, 3883, 100, 'Annakarl'
|
||||||
append_tele(true, 13095, 96, { LAW => 2, WATER => 8 }, 2972, 3873, 106, "Ghorrock")
|
ancient_tele 13_095, 96, { LAW => 2, WATER => 8 }, 2972, 3873, 106, 'Ghorrock'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
GEMSTONES = {}
|
GEMSTONES = {}
|
||||||
|
|
||||||
|
# A gemstone that can be received when mining.
|
||||||
class Gemstone
|
class Gemstone
|
||||||
attr_reader :id, :chance
|
attr_reader :id, :chance
|
||||||
|
|
||||||
@@ -9,11 +10,11 @@ class Gemstone
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_gem(gem)
|
def gem(gem)
|
||||||
GEMSTONES[gem.id] = gem
|
GEMSTONES[gem.id] = gem
|
||||||
end
|
end
|
||||||
|
|
||||||
append_gem(Gemstone.new(1623, 0)) # uncut sapphire
|
gem(Gemstone.new(1623, 0)) # uncut sapphire
|
||||||
append_gem(Gemstone.new(1605, 0)) # uncut emerald
|
gem(Gemstone.new(1605, 0)) # uncut emerald
|
||||||
append_gem(Gemstone.new(1619, 0)) # uncut ruby
|
gem(Gemstone.new(1619, 0)) # uncut ruby
|
||||||
append_gem(Gemstone.new(1617, 0)) # uncut diamond
|
gem(Gemstone.new(1617, 0)) # uncut diamond
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ PROSPECT_PULSES = 3
|
|||||||
ORE_SIZE = 1
|
ORE_SIZE = 1
|
||||||
|
|
||||||
# TODO: finish implementing this
|
# TODO: finish implementing this
|
||||||
|
# A `DistancedAction` for mining ore.
|
||||||
class MiningAction < DistancedAction
|
class MiningAction < DistancedAction
|
||||||
attr_reader :position, :ore, :counter, :started
|
attr_reader :position, :ore, :counter, :started
|
||||||
|
|
||||||
@@ -21,9 +22,11 @@ class MiningAction < DistancedAction
|
|||||||
|
|
||||||
def find_pickaxe
|
def find_pickaxe
|
||||||
weapon = mob.equipment.get(EquipmentConstants::WEAPON)
|
weapon = mob.equipment.get(EquipmentConstants::WEAPON)
|
||||||
PICKAXE_IDS.each { |id| return PICKAXES[id] if (!weapon.nil? && weapon.id == id) || mob.inventory.contains(id) }
|
PICKAXE_IDS.each do |id|
|
||||||
|
return PICKAXES[id] if (!weapon.nil? && weapon.id == id) || mob.inventory.contains(id)
|
||||||
|
end
|
||||||
|
|
||||||
return nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# starts the mining animation, sets counters/flags and turns the mob to
|
# starts the mining animation, sets counters/flags and turns the mob to
|
||||||
@@ -42,7 +45,7 @@ class MiningAction < DistancedAction
|
|||||||
mob.turn_to(@position)
|
mob.turn_to(@position)
|
||||||
|
|
||||||
# verify the mob can mine with their pickaxe
|
# verify the mob can mine with their pickaxe
|
||||||
unless (!pickaxe.nil? and level >= pickaxe.level)
|
if pickaxe.nil? || level < pickaxe.level
|
||||||
mob.send_message('You do not have a pickaxe for which you have the level to use.')
|
mob.send_message('You do not have a pickaxe for which you have the level to use.')
|
||||||
stop
|
stop
|
||||||
return
|
return
|
||||||
@@ -56,9 +59,7 @@ class MiningAction < DistancedAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
# check if we need to kick start things
|
# check if we need to kick start things
|
||||||
unless @started
|
if @started
|
||||||
start_mine(pickaxe)
|
|
||||||
else
|
|
||||||
# count down and check if we can have a chance at some ore now
|
# count down and check if we can have a chance at some ore now
|
||||||
if @counter == 0
|
if @counter == 0
|
||||||
# TODO: calculate the chance that the player can actually get the rock
|
# TODO: calculate the chance that the player can actually get the rock
|
||||||
@@ -73,16 +74,20 @@ class MiningAction < DistancedAction
|
|||||||
|
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
@counter -= 1
|
|
||||||
end
|
|
||||||
|
|
||||||
|
@counter -= 1
|
||||||
|
else
|
||||||
|
start_mine(pickaxe)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @position == other.position and @ore == other.ore)
|
get_class == other.get_class && @position == other.position && @ore == other.ore
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A `DistancedAction` for a rock with no available ore.
|
||||||
class ExpiredProspectingAction < DistancedAction
|
class ExpiredProspectingAction < DistancedAction
|
||||||
attr_reader :position
|
attr_reader :position
|
||||||
|
|
||||||
@@ -96,11 +101,12 @@ class ExpiredProspectingAction < DistancedAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @position == other.position)
|
get_class == other.get_class && @position == other.position
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A `DistancedAction` for prospecting a rock.
|
||||||
class ProspectingAction < DistancedAction
|
class ProspectingAction < DistancedAction
|
||||||
attr_reader :position, :ore
|
attr_reader :position, :ore
|
||||||
|
|
||||||
@@ -112,22 +118,22 @@ class ProspectingAction < DistancedAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
def executeAction
|
def executeAction
|
||||||
unless @started
|
if @started
|
||||||
@started = true
|
|
||||||
|
|
||||||
mob.send_message('You examine the rock for ores...')
|
|
||||||
mob.turn_to(@position)
|
|
||||||
else
|
|
||||||
ore_def = ItemDefinition.lookup(@ore.id)
|
ore_def = ItemDefinition.lookup(@ore.id)
|
||||||
name = ore_def.name.sub(/ ore$/, '').downcase
|
name = ore_def.name.sub(/ ore$/, '').downcase
|
||||||
|
|
||||||
mob.send_message("This rock contains #{name}.")
|
mob.send_message("This rock contains #{name}.")
|
||||||
stop
|
stop
|
||||||
|
else
|
||||||
|
@started = true
|
||||||
|
|
||||||
|
mob.send_message('You examine the rock for ores...')
|
||||||
|
mob.turn_to(@position)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @position == other.position and @ore == other.ore)
|
get_class == other.get_class && @position == other.position && @ore == other.ore
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -135,9 +141,7 @@ end
|
|||||||
on :message, :first_object_action do |mob, message|
|
on :message, :first_object_action do |mob, message|
|
||||||
ore = ORES[message.id]
|
ore = ORES[message.id]
|
||||||
|
|
||||||
unless ore.nil?
|
mob.start_action(MiningAction.new(mob, message.position, ore)) unless ore.nil?
|
||||||
mob.start_action(MiningAction.new(mob, message.position, ore))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
on :message, :second_object_action do |mob, message|
|
on :message, :second_object_action do |mob, message|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
ORES = {}
|
ORES = {}
|
||||||
EXPIRED_ORES = {}
|
EXPIRED_ORES = {}
|
||||||
|
|
||||||
|
# An ore that can be mined.
|
||||||
class Ore
|
class Ore
|
||||||
attr_reader :id, :objects, :level, :exp, :respawn
|
attr_reader :id, :objects, :level, :exp, :respawn
|
||||||
|
|
||||||
@@ -27,70 +28,68 @@ def append_ore(ore)
|
|||||||
end
|
end
|
||||||
|
|
||||||
CLAY_OBJECTS = {
|
CLAY_OBJECTS = {
|
||||||
2180 => 450 , 2109 => 451 , 14904 => 14896, 14905 => 14897
|
2180 => 450, 2109 => 451, 14_904 => 14_896, 14_905 => 14_897
|
||||||
}
|
}
|
||||||
|
|
||||||
COPPER_OBJECTS = {
|
COPPER_OBJECTS = {
|
||||||
11960 => 11555, 11961 => 11556, 11962 => 11557, 11936 => 11552,
|
11_960 => 11_555, 11_961 => 11_556, 11_962 => 11_557, 11_936 => 11_552,
|
||||||
11937 => 11553, 11938 => 11554, 2090 => 450 , 2091 => 451 ,
|
11_937 => 11_553, 11_938 => 11_554, 2090 => 450, 2091 => 451,
|
||||||
14906 => 14898, 14907 => 14899, 14856 => 14832, 14857 => 14833,
|
14_906 => 14_898, 14_907 => 14_899, 14_856 => 14_832, 14_857 => 14_833,
|
||||||
14858 => 14834
|
14_858 => 14_834
|
||||||
}
|
}
|
||||||
|
|
||||||
TIN_OBJECTS = {
|
TIN_OBJECTS = {
|
||||||
11597 => 11555, 11958 => 11556, 11959 => 11557, 11933 => 11552,
|
11_597 => 11_555, 11_958 => 11_556, 11_959 => 11_557, 11_933 => 11_552,
|
||||||
11934 => 11553, 11935 => 11554, 2094 => 450 , 2095 => 451 ,
|
11_934 => 11_553, 11_935 => 11_554, 2094 => 450, 2095 => 451,
|
||||||
14092 => 14894, 14903 => 14895
|
14_092 => 14_894, 14_903 => 14_895
|
||||||
}
|
}
|
||||||
|
|
||||||
IRON_OBJECTS = {
|
IRON_OBJECTS = {
|
||||||
11954 => 11555, 11955 => 11556, 11956 => 11557, 2092 => 450 ,
|
11_954 => 11_555, 11_955 => 11_556, 11_956 => 11_557, 2092 => 450,
|
||||||
2093 => 451 , 14900 => 14892, 14901 => 14893, 14913 => 14915,
|
2093 => 451, 14_900 => 14_892, 14_901 => 14_893, 14_913 => 14_915,
|
||||||
14914 => 14916
|
14_914 => 14_916
|
||||||
}
|
}
|
||||||
|
|
||||||
COAL_OBJECTS = {
|
COAL_OBJECTS = {
|
||||||
11963 => 11555, 11964 => 11556, 11965 => 11557, 11930 => 11552,
|
11_963 => 11_555, 11_964 => 11_556, 11_965 => 11_557, 11_930 => 11_552,
|
||||||
11931 => 11553, 11932 => 11554, 2096 => 450 , 2097 => 451 ,
|
11_931 => 11_553, 11_932 => 11_554, 2096 => 450, 2097 => 451,
|
||||||
14850 => 14832, 14851 => 14833, 14852 => 14834
|
14_850 => 14_832, 14_851 => 14_833, 14_852 => 14_834
|
||||||
}
|
}
|
||||||
|
|
||||||
SILVER_OBJECTS = {
|
SILVER_OBJECTS = {
|
||||||
11948 => 11555, 11949 => 11556, 11950 => 11557, 2100 => 450 ,
|
11_948 => 11_555, 11_949 => 11_556, 11_950 => 11_557, 2100 => 450, 2101 => 451
|
||||||
2101 => 451
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GOLD_OBJECTS = {
|
GOLD_OBJECTS = {
|
||||||
11951 => 11555, 11952 => 11556, 11953 => 11557, 2098 => 450 ,
|
11_951 => 11_555, 11_952 => 11_556, 11_953 => 11_557, 2098 => 450, 2099 => 451
|
||||||
2099 => 451
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MITHRIL_OBJECTS = {
|
MITHRIL_OBJECTS = {
|
||||||
11945 => 11555, 11946 => 11556, 11947 => 11557, 11942 => 11552,
|
11_945 => 11_555, 11_946 => 11_556, 11_947 => 11_557, 11_942 => 11_552,
|
||||||
11943 => 11553, 11944 => 11554, 2102 => 450 , 2103 => 451 ,
|
11_943 => 11_553, 11_944 => 11_554, 2102 => 450, 2103 => 451,
|
||||||
14853 => 14832, 14854 => 14833, 14855 => 14834
|
14_853 => 14_832, 14_854 => 14_833, 14_855 => 14_834
|
||||||
}
|
}
|
||||||
|
|
||||||
ADAMANT_OBJECTS = {
|
ADAMANT_OBJECTS = {
|
||||||
11939 => 11552, 11940 => 11553, 11941 => 11554, 2104 => 450 ,
|
11_939 => 11_552, 11_940 => 11_553, 11_941 => 11_554, 2104 => 450,
|
||||||
2105 => 451 , 14862 => 14832, 14863 => 14833, 14864 => 14834
|
2105 => 451, 14_862 => 14_832, 14_863 => 14_833, 14_864 => 14_834
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNITE_OBJECTS = {
|
RUNITE_OBJECTS = {
|
||||||
2106 => 450 , 2107 => 451 , 14859 => 14832, 14860 => 14833,
|
2106 => 450, 2107 => 451, 14_859 => 14_832, 14_860 => 14_833,
|
||||||
14861 => 14834
|
14_861 => 14_834
|
||||||
}
|
}
|
||||||
|
|
||||||
append_ore Ore.new(434, CLAY_OBJECTS, 1, 5, 3 ) # clay
|
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 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 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 440, IRON_OBJECTS, 15, 35, 16 # iron ore
|
||||||
append_ore Ore.new(453, COAL_OBJECTS, 30, 50, 100 ) # coal
|
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 444, GOLD_OBJECTS, 40, 65, 200 # gold ore
|
||||||
append_ore Ore.new(442, SILVER_OBJECTS, 20, 40, 200 ) # silver 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 447, MITHRIL_OBJECTS, 55, 80, 400 # mithril ore
|
||||||
append_ore Ore.new(449, ADAMANT_OBJECTS, 70, 95, 800 ) # adamant 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
|
append_ore Ore.new 451, RUNITE_OBJECTS, 85, 125, 2500 # runite ore
|
||||||
|
|
||||||
# TODO: rune essence object id = 2491
|
# TODO: rune essence object id = 2491
|
||||||
# level 1, exp 5, rune ess = 1436, pure ess = 7936
|
# level 1, exp 5, rune ess = 1436, pure ess = 7936
|
||||||
@@ -5,6 +5,7 @@ java_import 'org.apollo.game.model.Animation'
|
|||||||
PICKAXES = {}
|
PICKAXES = {}
|
||||||
PICKAXE_IDS = []
|
PICKAXE_IDS = []
|
||||||
|
|
||||||
|
# A pickaxe that can be mined with.
|
||||||
class Pickaxe
|
class Pickaxe
|
||||||
attr_reader :id, :level, :animation, :pulses
|
attr_reader :id, :level, :animation, :pulses
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ java_import 'org.apollo.game.action.Action'
|
|||||||
java_import 'org.apollo.game.model.Animation'
|
java_import 'org.apollo.game.model.Animation'
|
||||||
java_import 'org.apollo.game.model.entity.Skill'
|
java_import 'org.apollo.game.model.entity.Skill'
|
||||||
|
|
||||||
BURY_BONE_ANIMATION = 827
|
BURY_BONE_ANIMATION = Animation.new(827)
|
||||||
BONES = {}
|
BONES = {}
|
||||||
|
|
||||||
# A bone with an id and experience value.
|
# A bone with an id and experience value.
|
||||||
class Bone
|
class Bone
|
||||||
attr_reader :id, :experience
|
attr_reader :id, :experience
|
||||||
|
|
||||||
def initialize(id, experience)
|
def initialize(id, experience)
|
||||||
@id = id
|
@id = id
|
||||||
@@ -18,7 +18,6 @@ class Bone
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# An action where a bone in a player's inventory is buried.
|
# An action where a bone in a player's inventory is buried.
|
||||||
class BuryBoneAction < Action
|
class BuryBoneAction < Action
|
||||||
attr_reader :slot, :bone
|
attr_reader :slot, :bone
|
||||||
@@ -36,24 +35,28 @@ class BuryBoneAction < Action
|
|||||||
@executions += 1
|
@executions += 1
|
||||||
elsif @executions == 1
|
elsif @executions == 1
|
||||||
if mob.inventory.get(@slot).id == @bone.id
|
if mob.inventory.get(@slot).id == @bone.id
|
||||||
mob.play_animation(Animation.new(BURY_BONE_ANIMATION))
|
mob.play_animation(BURY_BONE_ANIMATION)
|
||||||
mob.send_message('You bury the bones.')
|
mob.send_message('You bury the bones.')
|
||||||
|
|
||||||
mob.inventory.reset(@slot)
|
mob.inventory.reset(@slot)
|
||||||
mob.skill_set.add_experience(Skill::PRAYER, @bone.experience)
|
mob.skill_set.add_experience(Skill::PRAYER, @bone.experience)
|
||||||
end
|
end
|
||||||
|
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class and @bone == other.bone)
|
get_class == other.get_class && @bone == other.bone
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Intercepts the first item option message.
|
# Intercepts the first item option message.
|
||||||
on :message, :first_item_option do |player, message|
|
on :message, :first_item_option do |player, message|
|
||||||
bone = BONES[message.id]
|
bone = BONES[message.id]
|
||||||
unless bone == nil
|
|
||||||
|
unless bone.nil?
|
||||||
player.start_action(BuryBoneAction.new(player, message.slot, bone))
|
player.start_action(BuryBoneAction.new(player, message.slot, bone))
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
@@ -61,28 +64,28 @@ end
|
|||||||
|
|
||||||
# Appends a bone to the array
|
# Appends a bone to the array
|
||||||
def append_bone(hash)
|
def append_bone(hash)
|
||||||
raise 'Hash must contain an id and an experience value.' unless hash.has_key?(:id) && hash.has_key?(:experience)
|
fail 'Hash must contain an id and an experience value.' unless hash.has_keys?(:id, :experience)
|
||||||
id = hash[:id]
|
id = hash[:id]
|
||||||
BONES[id] = Bone.new(id, hash[:experience])
|
BONES[id] = Bone.new(id, hash[:experience])
|
||||||
end
|
end
|
||||||
|
|
||||||
append_bone :name => :regular_bones, :id => 526, :experience => 5
|
append_bone name: :regular_bones, id: 526, experience: 5
|
||||||
append_bone :name => :burnt_bones, :id => 528, :experience => 5
|
append_bone name: :burnt_bones, id: 528, experience: 5
|
||||||
append_bone :name => :bat_bones, :id => 530, :experience => 4
|
append_bone name: :bat_bones, id: 530, experience: 4
|
||||||
append_bone :name => :big_bones, :id => 532, :experience => 45
|
append_bone name: :big_bones, id: 532, experience: 45
|
||||||
append_bone :name => :babydragon_bones, :id => 534, :experience => 30
|
append_bone name: :babydragon_bones, id: 534, experience: 30
|
||||||
append_bone :name => :dragon_bones, :id => 536, :experience => 72
|
append_bone name: :dragon_bones, id: 536, experience: 72
|
||||||
append_bone :name => :wolf_bones, :id => 2859, :experience => 14
|
append_bone name: :wolf_bones, id: 2859, experience: 14
|
||||||
append_bone :name => :shaikahan_bones, :id => 3123, :experience => 25
|
append_bone name: :shaikahan_bones, id: 3123, experience: 25
|
||||||
append_bone :name => :jogre_bones, :id => 3125, :experience => 15
|
append_bone name: :jogre_bones, id: 3125, experience: 15
|
||||||
append_bone :name => :burnt_zogre_bones, :id => 3127, :experience => 25
|
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: 3179, experience: 14 # smallish
|
||||||
append_bone :name => :monkey_bones, :id => 3180, :experience => 14 # medium
|
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: 3181, experience: 14 # quite large
|
||||||
append_bone :name => :monkey_bones, :id => 3182, :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: :monkey_bones, id: 3183, experience: 14 # small
|
||||||
append_bone :name => :shaking_bones, :id => 3187, :experience => 14
|
append_bone name: :shaking_bones, id: 3187, experience: 14
|
||||||
append_bone :name => :zogre_bones, :id => 4812, :experience => 23
|
append_bone name: :zogre_bones, id: 4812, experience: 23
|
||||||
append_bone :name => :fayrg_bones, :id => 4830, :experience => 84
|
append_bone name: :fayrg_bones, id: 4830, experience: 84
|
||||||
append_bone :name => :raurg_bones, :id => 4832, :experience => 96
|
append_bone name: :raurg_bones, id: 4832, experience: 96
|
||||||
append_bone :name => :ourg_bones, :id => 4834, :experience => 140
|
append_bone name: :ourg_bones, id: 4834, experience: 140
|
||||||
|
|||||||
@@ -4,86 +4,85 @@ java_import 'org.apollo.game.message.impl.ConfigMessage'
|
|||||||
# Declares the active prayer attribute.
|
# Declares the active prayer attribute.
|
||||||
declare_attribute(:active_prayer, -1, :persistent)
|
declare_attribute(:active_prayer, -1, :persistent)
|
||||||
|
|
||||||
|
|
||||||
# The hash of button ids to prayers.
|
# The hash of button ids to prayers.
|
||||||
PRAYERS = {}
|
PRAYERS = {}
|
||||||
|
|
||||||
# Intercept the ButtonMessage to toggle a prayer.
|
# Intercept the ButtonMessage to toggle a prayer.
|
||||||
on :message, :button do |player, message|
|
on :message, :button do |player, message|
|
||||||
button = message.widget_id
|
button = message.widget_id
|
||||||
prayer = PRAYERS[button]
|
prayer = PRAYERS[button]
|
||||||
|
|
||||||
unless prayer.nil?
|
unless prayer.nil?
|
||||||
if (prayer.level > player.skill_set.get_maximum_level(Skill::PRAYER))
|
if prayer.level > player.skill_set.get_maximum_level(Skill::PRAYER)
|
||||||
update_setting(player, prayer, :off)
|
update_setting(player, prayer, :off)
|
||||||
next
|
next
|
||||||
end
|
|
||||||
player.send_message("after level check")
|
|
||||||
|
|
||||||
previous = player.active_prayer
|
|
||||||
|
|
||||||
unless previous == -1
|
|
||||||
update_setting(player, PRAYERS[previous], :off)
|
|
||||||
end
|
|
||||||
|
|
||||||
if previous != button
|
|
||||||
player.send_message("Previous: #{previous}, new: #{button}.")
|
|
||||||
update_setting(player, prayer, :on)
|
|
||||||
player.active_prayer = button
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
player.send_message('after level check')
|
||||||
|
previous = player.active_prayer
|
||||||
|
|
||||||
|
update_setting(player, PRAYERS[previous], :off) unless previous == -1
|
||||||
|
|
||||||
|
if previous != button
|
||||||
|
player.send_message("Previous: #{previous}, new: #{button}.")
|
||||||
|
update_setting(player, prayer, :on)
|
||||||
|
player.active_prayer = button
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# A Prayer that can be activated by a player.
|
# A Prayer that can be activated by a player.
|
||||||
class Prayer
|
class Prayer
|
||||||
attr_reader :name, :level, :button, :setting, :drain
|
attr_reader :name, :level, :button, :setting, :drain
|
||||||
|
|
||||||
def initialize(name, level, button, setting, drain)
|
def initialize(name, level, button, setting, drain)
|
||||||
@name = name
|
@name = name
|
||||||
@level = level
|
@level = level
|
||||||
@button = button
|
@button = button
|
||||||
@setting = setting
|
@setting = setting
|
||||||
@drain = drain
|
@drain = drain
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_setting(player, prayer, state)
|
def update_setting(player, prayer, state)
|
||||||
value = (state == :on) ? 1 : 0
|
value = (state == :on) ? 1 : 0
|
||||||
player.send_message("Toggling prayer #{prayer.name}, state: #{state}.")
|
player.send_message("Toggling prayer #{prayer.name}, state: #{state}.")
|
||||||
player.send(ConfigMessage.new(prayer.setting, value))
|
player.send(ConfigMessage.new(prayer.setting, value))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends a Prayer to the hash.
|
# Appends a Prayer to the hash.
|
||||||
def append_prayer(properties)
|
def append_prayer(name, hash)
|
||||||
raise 'Error: prayer properties hash must contain a name, level, button, setting, and drain.' unless properties.has_keys?(:name, :level, :button, :setting, :drain)
|
unless hash.has_keys?(:level, :button, :setting, :drain)
|
||||||
|
fail 'Error: prayer hash hash must contain a level, button, setting, and drain.'
|
||||||
|
end
|
||||||
|
|
||||||
button = properties[:button]
|
button = hash[:button]
|
||||||
PRAYERS[button] = Prayer.new(properties[:name], properties[:level], button, properties[:setting], properties[:drain])
|
PRAYERS[button] = Prayer.new(name, hash[:level], button, hash[:setting], hash[:drain])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Don't deal with the actual effect here to avoid mess (TODO do it, but with attributes?).
|
# Don't deal with the actual effect here to avoid mess (TODO do it, but with attributes?).
|
||||||
append_prayer name: :thick_skin, level: 1, button: 5609, setting: 83, drain: 0.01
|
append_prayer :thick_skin, level: 1, button: 5609, setting: 83, drain: 0.01
|
||||||
append_prayer name: :burst_of_strength, level: 4, button: 5610, setting: 84, drain: 0.01
|
append_prayer :burst_of_strength, level: 4, button: 5610, setting: 84, drain: 0.01
|
||||||
append_prayer name: :clarity_of_thought, level: 7, button: 5611, setting: 85, drain: 0.01
|
append_prayer :clarity_of_thought, level: 7, button: 5611, setting: 85, drain: 0.01
|
||||||
append_prayer name: :rock_skin, level: 10, button: 5612, setting: 86, drain: 0.04
|
append_prayer :rock_skin, level: 10, button: 5612, setting: 86, drain: 0.04
|
||||||
append_prayer name: :superhuman_strength, level: 13, button: 5613, setting: 87, drain: 0.04
|
append_prayer :superhuman_strength, level: 13, button: 5613, setting: 87, drain: 0.04
|
||||||
append_prayer name: :improved_reflexes, level: 16, button: 5614, setting: 88, drain: 0.04
|
append_prayer :improved_reflexes, level: 16, button: 5614, setting: 88, drain: 0.04
|
||||||
|
|
||||||
append_prayer name: :rapid_restore, level: 19, button: 5615, setting: 89, drain: 0.01
|
append_prayer :rapid_restore, level: 19, button: 5615, setting: 89, drain: 0.01
|
||||||
append_prayer name: :rapid_heal, level: 22, button: 5615, setting: 90, drain: 0.01
|
append_prayer :rapid_heal, level: 22, button: 5615, setting: 90, drain: 0.01
|
||||||
append_prayer name: :protect_item, level: 25, button: 5617, setting: 91, drain: 0.01
|
append_prayer :protect_item, level: 25, button: 5617, setting: 91, drain: 0.01
|
||||||
|
|
||||||
append_prayer name: :steel_skin, level: 28, button: 5618, setting: 92, drain: 0.1
|
append_prayer :steel_skin, level: 28, button: 5618, setting: 92, drain: 0.1
|
||||||
append_prayer name: :ultimate_strength, level: 31, button: 5619, setting: 93, drain: 0.1
|
append_prayer :ultimate_strength, level: 31, button: 5619, setting: 93, drain: 0.1
|
||||||
append_prayer name: :incredible_reflexes, level: 34, button: 5620, setting: 94, drain: 0.1
|
append_prayer :incredible_reflexes, level: 34, button: 5620, setting: 94, drain: 0.1
|
||||||
|
|
||||||
append_prayer name: :protect_from_magic, level: 37, button: 5621, setting: 95, drain: 0.15
|
append_prayer :protect_from_magic, level: 37, button: 5621, setting: 95, drain: 0.15
|
||||||
append_prayer name: :protect_from_missiles, level: 40, button: 5622, setting: 96, drain: 0.15
|
append_prayer :protect_from_missiles, level: 40, button: 5622, setting: 96, drain: 0.15
|
||||||
append_prayer name: :protect_from_melee, level: 43, button: 5633, setting: 97, drain: 0.15
|
append_prayer :protect_from_melee, level: 43, button: 5633, setting: 97, drain: 0.15
|
||||||
|
|
||||||
append_prayer name: :retribution, level: 46, button: 683, setting: 98, drain: 0.15
|
append_prayer :retribution, level: 46, button: 683, setting: 98, drain: 0.15
|
||||||
append_prayer name: :redemption, level: 49, button: 684, setting: 99, drain: 0.15
|
append_prayer :redemption, level: 49, button: 684, setting: 99, drain: 0.15
|
||||||
append_prayer name: :smite, level: 52, button: 685, setting: 100, drain: 0.2
|
append_prayer :smite, level: 52, button: 685, setting: 100, drain: 0.2
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ CRAFTING_ALTARS = {}
|
|||||||
|
|
||||||
# Represents a runecrafting altar.
|
# Represents a runecrafting altar.
|
||||||
class Altar
|
class Altar
|
||||||
attr_reader :entrance_altar, :crafting_altar, :portal_id, :entrance_position, :exit_position, :crafting_centre
|
attr_reader :entrance_altar, :crafting, :portal_id, :entrance, :exit, :crafting_centre
|
||||||
|
|
||||||
def initialize(entrance_altar, crafting_altar, portal_id, entrance_position, exit_position,crafting_centre)
|
def initialize(entrance_altar, crafting, portal_id, entrance_position, exit_position,
|
||||||
|
crafting_centre)
|
||||||
@entrance_altar = entrance_altar
|
@entrance_altar = entrance_altar
|
||||||
@altar = crafting_altar
|
@altar = crafting
|
||||||
@portal_id = portal_id
|
@portal_id = portal_id
|
||||||
@entrance_position = entrance_position
|
@entrance_position = entrance_position
|
||||||
@exit_position = exit_position
|
@exit_position = exit_position
|
||||||
@@ -22,11 +23,12 @@ class Altar
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Intercepts the item on object message.
|
# Intercepts the item on object message.
|
||||||
on :message, :item_on_object do |player, message|
|
on :message, :item_on_object do |player, message|
|
||||||
talisman = TALISMANS[message.id]; altar = ENTRANCE_ALTARS[message.object_id]
|
talisman = TALISMANS[message.id]
|
||||||
unless (talisman.nil? || altar.nil?)
|
altar = ENTRANCE_ALTARS[message.object_id]
|
||||||
|
|
||||||
|
unless talisman.nil? || altar.nil?
|
||||||
player.start_action(TeleportAction.new(player, message.position, 2, altar.entrance_position))
|
player.start_action(TeleportAction.new(player, message.position, 2, altar.entrance_position))
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
@@ -34,22 +36,27 @@ end
|
|||||||
|
|
||||||
# Intercepts the first object action message.
|
# Intercepts the first object action message.
|
||||||
on :message, :object_action do |player, message|
|
on :message, :object_action do |player, message|
|
||||||
if (message.option == 1)
|
if message.option == 1
|
||||||
object_id = message.id
|
object_id = message.id
|
||||||
|
|
||||||
if (altar = PORTALS[object_id]) != nil # Get the altar associated with this exit portal.
|
if PORTALS.key?(object_id)
|
||||||
player.start_action(TeleportAction.new(player, altar.entrance_position, 1, altar.exit_position))
|
altar = PORTALS[object_id]
|
||||||
|
entrance = altar.entrance_position
|
||||||
|
|
||||||
|
player.start_action(TeleportAction.new(player, entrance, 1, altar.exit_position))
|
||||||
message.terminate
|
message.terminate
|
||||||
elsif (rune = RUNES[object_id]) != nil # Get the rune associated with this altar.
|
elsif RUNES.key?(object_id)
|
||||||
|
rune = RUNES[object_id]
|
||||||
altar = CRAFTING_ALTARS[object_id]
|
altar = CRAFTING_ALTARS[object_id]
|
||||||
|
|
||||||
player.start_action(RunecraftingAction.new(player, rune, altar.crafting_centre))
|
player.start_action(RunecraftingAction.new(player, rune, altar.crafting_centre))
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# An action that causes a mob to teleport when it comes within the specified distance of a
|
||||||
# An action that causes a mob to teleport when it comes within the specified distance of a specified position.
|
# specified position.
|
||||||
class TeleportAction < DistancedAction
|
class TeleportAction < DistancedAction
|
||||||
attr_reader :teleport_position
|
attr_reader :teleport_position
|
||||||
|
|
||||||
@@ -64,28 +71,59 @@ class TeleportAction < DistancedAction
|
|||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class && mob == other.mob && @teleport_position == other.teleport_position)
|
get_class == other.get_class && mob == other.mob &&
|
||||||
|
@teleport_position == other.teleport_position
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends an altar to the list.
|
# Appends an altar to the list.
|
||||||
def append_altar(hash)
|
def altar(name, hash)
|
||||||
#raise 'Hash must contain an entrance altar id, crafting altar id, entrance portal position, and altar centre position.'
|
unless hash.has_keys?(:entrance_altar, :crafting, :portal, :entrance, :exit, :altar_centre)
|
||||||
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]
|
fail "#{name} is missing one of: entrance altar id, crafting altar id, entrance portal position, "\
|
||||||
|
"and altar centre position."
|
||||||
|
end
|
||||||
|
|
||||||
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))
|
entrance_altar, crafting = hash[:entrance_altar], hash[:crafting]
|
||||||
|
portal_id = hash[:portal]
|
||||||
|
|
||||||
|
entrance = Position.new(*hash[:entrance])
|
||||||
|
exit_position = Position.new(*hash[:exit])
|
||||||
|
centre = Position.new(*hash[:altar_centre])
|
||||||
|
|
||||||
|
altar = Altar.new(entrance_altar, crafting, portal_id, entrance, exit_position, centre)
|
||||||
|
PORTALS[portal_id] = ENTRANCE_ALTARS[entrance_altar] = CRAFTING_ALTARS[crafting] = altar
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends an altar to the list.
|
altar :air, entrance_altar: 2452, crafting: 2478, portal: 2465,
|
||||||
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 ]
|
entrance: [2841, 4829], exit: [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 ]
|
altar :mind, entrance_altar: 2453, crafting: 2479, portal: 2466,
|
||||||
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 ]
|
entrance: [2793, 4828], exit: [2980, 3514], altar_centre: [2786, 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 ]
|
altar :water, entrance_altar: 2454, crafting: 2480, portal: 2467,
|
||||||
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 ]
|
entrance: [2726, 4832], exit: [3187, 3166], altar_centre: [2716, 4836]
|
||||||
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 ]
|
altar :earth, entrance_altar: 2455, crafting: 2481, portal: 2468,
|
||||||
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 ]
|
entrance: [2655, 4830], exit: [3304, 3474], altar_centre: [2658, 4841]
|
||||||
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 ]
|
|
||||||
|
altar :fire, entrance_altar: 2456, crafting: 2482, portal: 2469,
|
||||||
|
entrance: [2574, 4849], exit: [3311, 3256], altar_centre: [2585, 4838]
|
||||||
|
|
||||||
|
altar :body, entrance_altar: 2457, crafting: 2483, portal: 2470,
|
||||||
|
entrance: [2524, 4825], exit: [3051, 3445], altar_centre: [2525, 4832]
|
||||||
|
|
||||||
|
altar :cosmic, entrance_altar: 2458, crafting: 2484, portal: 2471,
|
||||||
|
entrance: [2142, 4813], exit: [2408, 4379], altar_centre: [2142, 4833]
|
||||||
|
|
||||||
|
altar :law, entrance_altar: 2459, crafting: 2485, portal: 2472,
|
||||||
|
entrance: [2464, 4818], exit: [2858, 3379], altar_centre: [2464, 4832]
|
||||||
|
|
||||||
|
altar :nature, entrance_altar: 2460, crafting: 2486, portal: 2473,
|
||||||
|
entrance: [2400, 4835], exit: [2867, 3019], altar_centre: [2400, 4841]
|
||||||
|
|
||||||
|
altar :chaos, entrance_altar: 2461, crafting: 2487, portal: 2474,
|
||||||
|
entrance: [2268, 4842], exit: [3058, 3591], altar_centre: [2271, 4842]
|
||||||
|
|
||||||
|
altar :death, entrance_altar: 2462, crafting: 2488, portal: 2475,
|
||||||
|
entrance: [2208, 4830], exit: [3222, 3222], altar_centre: [2205, 4836]
|
||||||
|
|||||||
@@ -15,32 +15,38 @@ class Rune
|
|||||||
@multiplier = multiplier
|
@multiplier = multiplier
|
||||||
end
|
end
|
||||||
|
|
||||||
def multiplier(level)
|
def equals(other)
|
||||||
return @multiplier.call(level)
|
get_class == other.get_class && id == other.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def multiplier(level)
|
||||||
return (get_class == other.get_class && id == other.id)
|
@multiplier.call(level)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends a rune to the list.
|
# Appends a rune to the list.
|
||||||
def append_rune(hash)
|
def rune(name, hash)
|
||||||
raise 'Hash must contain an id, level, experience, and multiplier.' unless hash.has_keys?(:id, :level, :experience, :multiplier)
|
unless hash.has_keys?(:altar, :id, :level, :reward)
|
||||||
id = hash[:id]; altar = hash[:altar]; level = hash[:level]; experience = hash[:experience]; multiplier = hash[:multiplier]
|
fail "#{name} is missing one of id, altar, level, or reward."
|
||||||
|
end
|
||||||
|
|
||||||
RUNES[altar] = Rune.new(id, level, experience, multiplier)
|
id, altar, level, experience = hash[:id], hash[:altar], hash[:level], hash[:reward]
|
||||||
|
bonus = hash[:bonus] || ->(_) { 1 }
|
||||||
|
|
||||||
|
RUNES[altar] = Rune.new(id, level, experience, bonus)
|
||||||
end
|
end
|
||||||
|
|
||||||
append_rune(:name => :air_rune, :altar => 2478, :id => 556, :level => 1, :experience => 5, :multiplier => lambda { |level| (level / 11).floor + 1 })
|
rune :air, altar: 2478, id: 556, level: 1, reward: 5, bonus: ->(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 })
|
rune :mind, altar: 2479, id: 558, level: 1, reward: 5.5, bonus: ->(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 })
|
rune :water, altar: 2480, id: 555, level: 5, reward: 6, bonus: ->(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 })
|
rune :earth, altar: 2481, id: 557, level: 9, reward: 6.5,
|
||||||
append_rune(:name => :fire_rune, :altar => 2482, :id => 554, :level => 14, :experience => 7, :multiplier => lambda { |level| (level / 35).floor + 1 })
|
bonus: ->(level) { (level / 26).floor + 1 }
|
||||||
append_rune(:name => :body_rune, :altar => 2483, :id => 559, :level => 20, :experience => 7.5, :multiplier => lambda { |level| (level / 46).floor + 1 })
|
rune :fire, altar: 2482, id: 554, level: 14, reward: 7, bonus: ->(level) { (level / 35).floor + 1 }
|
||||||
append_rune(:name => :cosmic_rune, :altar => 2484, :id => 564, :level => 27, :experience => 8, :multiplier => lambda { |level| level >= 59 ? 2 : 1 })
|
rune :body, altar: 2483, id: 559, level: 20, reward: 7.5,
|
||||||
append_rune(:name => :chaos_rune, :altar => 2487, :id => 562, :level => 35, :experience => 8.5, :multiplier => lambda { |level| level >= 74 ? 2 : 1 })
|
bonus: ->(level) { (level / 46).floor + 1 }
|
||||||
append_rune(:name => :nature_rune, :altar => 2486, :id => 561, :level => 44, :experience => 9, :multiplier => lambda { |level| level >= 91 ? 2 : 1 })
|
rune :cosmic, altar: 2484, id: 564, level: 27, reward: 8, bonus: ->(level) { level >= 59 ? 2 : 1 }
|
||||||
append_rune(:name => :law_rune, :altar => 2485, :id => 563, :level => 54, :experience => 9.5, :multiplier => lambda { |level| 1 })
|
rune :chaos, altar: 2487, id: 562, level: 35, reward: 8.5, bonus: ->(level) { level >= 74 ? 2 : 1 }
|
||||||
append_rune(:name => :death_rune, :altar => 2488, :id => 560, :level => 65, :experience => 10, :multiplier => lambda { |level| 1 })
|
rune :nature, altar: 2486, id: 561, level: 44, reward: 9, bonus: ->(level) { level >= 91 ? 2 : 1 }
|
||||||
|
rune :law, altar: 2485, id: 563, level: 54, reward: 9.5
|
||||||
|
rune :death, altar: 2488, id: 560, level: 65, reward: 10
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class RunecraftingAction < DistancedAction
|
|||||||
def executeAction
|
def executeAction
|
||||||
runecrafting_level = @player.skill_set.get_skill(Skill::RUNECRAFT).current_level
|
runecrafting_level = @player.skill_set.get_skill(Skill::RUNECRAFT).current_level
|
||||||
|
|
||||||
if (runecrafting_level < @rune.level)
|
if runecrafting_level < @rune.level
|
||||||
@player.send_message("You need a runecrafting level of #{@rune.level} to craft this rune.")
|
@player.send_message("You need a runecrafting level of #{@rune.level} to craft this rune.")
|
||||||
stop
|
stop
|
||||||
elsif !@player.inventory.contains(RUNE_ESSENCE_ID)
|
elsif !@player.inventory.contains(RUNE_ESSENCE_ID)
|
||||||
@@ -37,18 +37,22 @@ class RunecraftingAction < DistancedAction
|
|||||||
@player.play_graphic(RUNECRAFTING_GRAPHIC)
|
@player.play_graphic(RUNECRAFTING_GRAPHIC)
|
||||||
@executions += 1
|
@executions += 1
|
||||||
elsif @executions == 1
|
elsif @executions == 1
|
||||||
removed = @player.inventory.remove(RUNE_ESSENCE_ID, @player.inventory.get_amount(RUNE_ESSENCE_ID))
|
inventory = @player.inventory
|
||||||
added = removed * @rune.multiplier(runecrafting_level)
|
removed = inventory.remove(RUNE_ESSENCE_ID, inventory.get_amount(RUNE_ESSENCE_ID))
|
||||||
@player.inventory.add(@rune.id, added)
|
|
||||||
|
added = removed * @rune.multiplier(runecrafting_level)
|
||||||
|
inventory.add(@rune.id, added)
|
||||||
|
|
||||||
|
name = added > 1 ? 'some ' + @rune.name + 's' : 'an ' + @rune.name
|
||||||
|
@player.send_message("Your craft the rune essence into #{name}.", true)
|
||||||
|
|
||||||
@player.send_message("Your craft the rune essence into #{added > 1 ? 'some ' + @rune.name + 's' : 'an ' + @rune.name}.", true)
|
|
||||||
@player.skill_set.add_experience(Skill::RUNECRAFT, removed * @rune.experience)
|
@player.skill_set.add_experience(Skill::RUNECRAFT, removed * @rune.experience)
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class && @player == other.player && @rune == other.rune)
|
get_class == other.get_class && @player == other.player && @rune == other.rune
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -12,41 +12,43 @@ class Talisman
|
|||||||
@locate_position = entrance_altar_position
|
@locate_position = entrance_altar_position
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_message(player_position)
|
def get_message(position)
|
||||||
return 'Your talisman glows brightly.' if player_position.is_within_distance(@locate_position, 10)
|
return 'Your talisman glows brightly.' if position.is_within_distance(@locate_position, 10)
|
||||||
|
|
||||||
direction = (player_position.y > @locate_position.y ? 'North' : 'South') + '-' + (player_position.x > @locate_position.x ? 'East' : 'West')
|
direction = (position.y > @locate_position.y ? 'North' : 'South') + '-'
|
||||||
return "The talisman pulls toward the #{direction}."
|
direction += (position.x > @locate_position.x ? 'East' : 'West')
|
||||||
|
|
||||||
|
"The talisman pulls toward the #{direction}."
|
||||||
end
|
end
|
||||||
|
|
||||||
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 message.
|
# Intercepts the item option message.
|
||||||
on :message, :fourth_item_option do |player, message|
|
on :message, :fourth_item_option do |player, message|
|
||||||
talisman = TALISMANS[message.id]
|
talisman = TALISMANS[message.id]
|
||||||
if (talisman != nil)
|
|
||||||
|
unless talisman.nil?
|
||||||
player.send_message(talisman.get_message(player.position))
|
player.send_message(talisman.get_message(player.position))
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends talismans to the list.
|
# Appends a talisman to the list.
|
||||||
append_talisman :name => :air_talisman, :id => 1438, :altar => [ 2985, 3292 ]
|
def talisman(name, hash)
|
||||||
append_talisman :name => :earth_talisman, :id => 1440, :altar => [ 3306, 3474 ]
|
fail 'Hash must contain an id and an altar position.' unless hash.has_keys?(:id, :altar)
|
||||||
append_talisman :name => :fire_talisman, :id => 1442, :altar => [ 3313, 3255 ]
|
id, altar_position = hash[:id], Position.new(*hash[:altar])
|
||||||
append_talisman :name => :water_talisman, :id => 1444, :altar => [ 3185, 3165 ]
|
|
||||||
append_talisman :name => :body_talisman, :id => 1446, :altar => [ 3053, 3445 ]
|
TALISMANS[id] = Talisman.new(altar_position)
|
||||||
append_talisman :name => :mind_talisman, :id => 1448, :altar => [ 2982, 3514 ]
|
end
|
||||||
append_talisman :name => :chaos_talisman, :id => 1452, :altar => [ 3059, 3590 ]
|
|
||||||
append_talisman :name => :cosmic_talisman, :id => 1454, :altar => [ 2408, 4377 ]
|
talisman :air_talisman, id: 1438, altar: [2985, 3292]
|
||||||
append_talisman :name => :death_talisman, :id => 1456, :altar => [ 0, 0 ]
|
talisman :earth_talisman, id: 1440, altar: [3306, 3474]
|
||||||
append_talisman :name => :law_talisman, :id => 1458, :altar => [ 2858, 3381 ]
|
talisman :fire_talisman, id: 1442, altar: [3313, 3255]
|
||||||
append_talisman :name => :nature_talisman, :id => 1462, :altar => [ 2869, 3019 ]
|
talisman :water_talisman, id: 1444, altar: [3185, 3165]
|
||||||
|
talisman :body_talisman, id: 1446, altar: [3053, 3445]
|
||||||
|
talisman :mind_talisman, id: 1448, altar: [2982, 3514]
|
||||||
|
talisman :chaos_talisman, id: 1452, altar: [3059, 3590]
|
||||||
|
talisman :cosmic_talisman, id: 1454, altar: [2408, 4377]
|
||||||
|
talisman :death_talisman, id: 1456, altar: [0, 0]
|
||||||
|
talisman :law_talisman, id: 1458, altar: [2858, 3381]
|
||||||
|
talisman :nature_talisman, id: 1462, altar: [2869, 3019]
|
||||||
|
|||||||
@@ -4,27 +4,27 @@ java_import 'org.apollo.game.message.impl.ConfigMessage'
|
|||||||
java_import 'org.apollo.game.model.entity.EquipmentConstants'
|
java_import 'org.apollo.game.model.entity.EquipmentConstants'
|
||||||
java_import 'org.apollo.game.action.DistancedAction'
|
java_import 'org.apollo.game.action.DistancedAction'
|
||||||
|
|
||||||
# The list of tiaras.
|
# The hash of tiaras.
|
||||||
TIARAS_BY_ALTAR = {}
|
TIARAS_BY_ALTAR = {}
|
||||||
TIARAS_BY_ID = {}
|
TIARAS_BY_ID = {}
|
||||||
TIARAS_BY_TALISMAN = {}
|
TIARAS_BY_TALISMAN = {}
|
||||||
|
|
||||||
# A tiara will make an altar accessible with 1 click
|
# A tiara will make an altar accessible with a single click.
|
||||||
class Tiara
|
class Tiara
|
||||||
attr_reader :altar, :bitshift, :tiara_id, :experience, :talisman
|
attr_reader :altar, :bitshift, :tiara_id, :experience, :talisman
|
||||||
|
|
||||||
def initialize(tiara_id, altar, talisman, bitshift, experience)
|
def initialize(tiara_id, altar, talisman, bitshift, experience)
|
||||||
@tiara_id = tiara_id
|
@tiara_id = tiara_id
|
||||||
@name = name_of(:item, tiara_id)
|
@name = name_of(:item, tiara_id)
|
||||||
@altar = altar
|
@altar = altar
|
||||||
@talisman = talisman
|
@talisman = talisman
|
||||||
@bitshift = bitshift
|
@bitshift = bitshift
|
||||||
@experience = experience
|
@experience = experience
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends a config message to change the altar object.
|
# Sends a config message to change the altar object.
|
||||||
def send_config(player)
|
def send_config(player)
|
||||||
player.send(ConfigMessage.new(CHANGE_ALTAR_OBJECT_CONFIG, 1 << @bitshift))
|
player.send(ConfigMessage.new(CHANGE_ALTAR_OBJECT_CONFIG, 1 << @bitshift))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -42,26 +42,18 @@ def send_empty_config(player)
|
|||||||
player.send(ConfigMessage.new(CHANGE_ALTAR_OBJECT_CONFIG, 0))
|
player.send(ConfigMessage.new(CHANGE_ALTAR_OBJECT_CONFIG, 0))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Appends a tiara to the list.
|
|
||||||
def append_tiara(hash)
|
|
||||||
raise 'Hash must contain a tiara id, altar id, talisman id, a bitshift number, and experience.' unless hash.has_keys?(:altar, :bitshift, :experience, :talisman, :tiara_id)
|
|
||||||
tiara_id = hash[:tiara_id]; altar = hash[:altar]; talisman = hash[:talisman]; bitshift = hash[:bitshift]; experience = hash[:experience]
|
|
||||||
|
|
||||||
TIARAS_BY_TALISMAN[talisman] = TIARAS_BY_ID[tiara_id] = TIARAS_BY_ALTAR[altar] = Tiara.new(tiara_id, altar, talisman, bitshift, experience)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sets the correct config upon login, if the player is wearing a tiara.
|
# Sets the correct config upon login, if the player is wearing a tiara.
|
||||||
on :login do |event, player|
|
on :login do |_event, player|
|
||||||
player = event.player
|
|
||||||
hat = player.equipment.get(EquipmentConstants::HAT)
|
hat = player.equipment.get(EquipmentConstants::HAT)
|
||||||
|
|
||||||
unless hat.nil?
|
unless hat.nil?
|
||||||
tiara = TIARAS_BY_ID[hat]
|
tiara = TIARAS_BY_ID[hat]
|
||||||
if tiara.nil? then send_empty_config(player) else tiara.send_config end
|
tiara.nil? ? send_empty_config(player) : tiara.send_config
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Intercepts the SecondObjectAction message to support left-click access to the altar when wielding the correct tiara.
|
# Intercepts the SecondObjectAction message to support left-click access to the altar when wielding
|
||||||
|
# the correct tiara.
|
||||||
on :message, :second_object_action do |player, message|
|
on :message, :second_object_action do |player, message|
|
||||||
object_id = message.id
|
object_id = message.id
|
||||||
tiara = TIARAS_BY_ALTAR[object_id]
|
tiara = TIARAS_BY_ALTAR[object_id]
|
||||||
@@ -69,11 +61,13 @@ on :message, :second_object_action do |player, message|
|
|||||||
|
|
||||||
hat = player.equipment.get(EquipmentConstants::HAT)
|
hat = player.equipment.get(EquipmentConstants::HAT)
|
||||||
|
|
||||||
if (!hat.nil? && hat.id == tiara.tiara_id)
|
if !hat.nil? && hat.id == tiara.tiara_id
|
||||||
altar = ENTRANCE_ALTARS[tiara.altar]
|
altar = ENTRANCE_ALTARS[tiara.altar]
|
||||||
player.start_action(TeleportAction.new(player, message.position, 2, altar.entrance_position)) unless altar.nil?
|
|
||||||
|
|
||||||
message.terminate
|
message.terminate
|
||||||
|
|
||||||
|
unless altar.nil?
|
||||||
|
player.start_action(TeleportAction.new(player, message.position, 2, altar.entrance_position))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -99,14 +93,15 @@ end
|
|||||||
|
|
||||||
# Intercepts the ItemOnObject message to create the tiara.
|
# Intercepts the ItemOnObject message to create the tiara.
|
||||||
on :message, :item_on_object do |player, message|
|
on :message, :item_on_object do |player, message|
|
||||||
tiara= TIARAS_BY_TALISMAN[message.id]; altar = CRAFTING_ALTARS[message.object_id]
|
tiara, altar = TIARAS_BY_TALISMAN[message.id], CRAFTING_ALTARS[message.object_id]
|
||||||
return if (tiara.nil? || altar.nil?)
|
return if tiara.nil? || altar.nil?
|
||||||
|
|
||||||
player.start_action(CreateTiaraAction.new(player, message.position, tiara, altar))
|
player.start_action(CreateTiaraAction.new(player, message.position, tiara, altar))
|
||||||
message.terminate
|
message.terminate
|
||||||
end
|
end
|
||||||
|
|
||||||
# An action lets the player create a tiara when it comes within the specified distance of a specified position.
|
# An action lets the player create a tiara when it comes within the specified distance of a
|
||||||
|
# specified position.
|
||||||
# noinspection JRubyImplementInterfaceInspection
|
# noinspection JRubyImplementInterfaceInspection
|
||||||
class CreateTiaraAction < DistancedAction
|
class CreateTiaraAction < DistancedAction
|
||||||
|
|
||||||
@@ -122,7 +117,7 @@ class CreateTiaraAction < DistancedAction
|
|||||||
inventory = @player.inventory
|
inventory = @player.inventory
|
||||||
|
|
||||||
if inventory.contains_all(TIARA_ITEM_ID, @tiara.talisman)
|
if inventory.contains_all(TIARA_ITEM_ID, @tiara.talisman)
|
||||||
if (@tiara.altar == @altar.entrance_altar)
|
if @tiara.altar == @altar.entrance_altar
|
||||||
inventory.remove(@tiara.talisman, TIARA_ITEM_ID)
|
inventory.remove(@tiara.talisman, TIARA_ITEM_ID)
|
||||||
inventory.add(@tiara.tiara_id)
|
inventory.add(@tiara.tiara_id)
|
||||||
|
|
||||||
@@ -130,30 +125,43 @@ class CreateTiaraAction < DistancedAction
|
|||||||
@player.play_animation(RUNECRAFTING_ANIMATION)
|
@player.play_animation(RUNECRAFTING_ANIMATION)
|
||||||
@player.play_graphic(RUNECRAFTING_GRAPHIC)
|
@player.play_graphic(RUNECRAFTING_GRAPHIC)
|
||||||
else
|
else
|
||||||
@player.send_message("You can't use that talisman on this altar.")
|
@player.send_message('You can\'t use that talisman on this altar.')
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@player.send_message("You need to have a talisman and blank tiara to enchant a tiara.")
|
@player.send_message('You need to have a talisman and blank tiara to enchant a tiara.')
|
||||||
end
|
end
|
||||||
|
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class && @player == other.player && @tiara == other.tiara)
|
get_class == other.get_class && @player == other.player && @tiara == other.tiara
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
append_tiara :name => :air_tiara, :tiara_id => 5527, :altar => 2452, :talisman => 1438, :bitshift => 0, :experience => 25
|
# Appends a tiara to the list.
|
||||||
append_tiara :name => :mind_tiara, :tiara_id => 5529, :altar => 2453, :talisman => 1448, :bitshift => 1, :experience => 27.5
|
def tiara(_name, hash)
|
||||||
append_tiara :name => :water_tiara, :tiara_id => 5531, :altar => 2454, :talisman => 1444, :bitshift => 2, :experience => 30
|
unless hash.has_keys?(:altar, :bitshift, :experience, :talisman, :tiara_id)
|
||||||
append_tiara :name => :body_tiara, :tiara_id => 5533, :altar => 2457, :talisman => 1446, :bitshift => 5, :experience => 37.5
|
fail 'Hash must contain a tiara id, altar id, talisman id, a bitshift number, and experience.'
|
||||||
append_tiara :name => :earth_tiara, :tiara_id => 5535, :altar => 2455, :talisman => 1440, :bitshift => 3, :experience => 32.5
|
end
|
||||||
append_tiara :name => :fire_tiara, :tiara_id => 5537, :altar => 2456, :talisman => 1442, :bitshift => 4, :experience => 35
|
|
||||||
append_tiara :name => :cosmic_tiara, :tiara_id => 5539, :altar => 2458, :talisman => 1454, :bitshift => 6, :experience => 40
|
tiara_id, altar, talisman = hash[:tiara_id], hash[:altar], hash[:talisman]
|
||||||
append_tiara :name => :nature_tiara, :tiara_id => 5541, :altar => 2460, :talisman => 1462, :bitshift => 8, :experience => 45
|
bitshift, experience = hash[:bitshift], hash[:experience]
|
||||||
append_tiara :name => :chaos_tiara, :tiara_id => 5543, :altar => 2461, :talisman => 1452, :bitshift => 9, :experience => 42.5
|
|
||||||
append_tiara :name => :law_tiara, :tiara_id => 5545, :altar => 2459, :talisman => 1458, :bitshift => 7, :experience => 47.5
|
tiara = Tiara.new(tiara_id, altar, talisman, bitshift, experience)
|
||||||
append_tiara :name => :death_tiara, :tiara_id => 5548, :altar => 2462, :talisman => 1456, :bitshift => 10, :experience => 50
|
TIARAS_BY_TALISMAN[talisman] = TIARAS_BY_ID[tiara_id] = TIARAS_BY_ALTAR[altar] = tiara
|
||||||
# TODO there are 2 other altars, which probably just aren't spawned on the map
|
end
|
||||||
|
|
||||||
|
tiara :air_tiara, tiara_id: 5527, altar: 2452, talisman: 1438, bitshift: 0, experience: 25
|
||||||
|
tiara :mind_tiara, tiara_id: 5529, altar: 2453, talisman: 1448, bitshift: 1, experience: 27.5
|
||||||
|
tiara :water_tiara, tiara_id: 5531, altar: 2454, talisman: 1444, bitshift: 2, experience: 30
|
||||||
|
tiara :body_tiara, tiara_id: 5533, altar: 2457, talisman: 1446, bitshift: 5, experience: 37.5
|
||||||
|
tiara :earth_tiara, tiara_id: 5535, altar: 2455, talisman: 1440, bitshift: 3, experience: 32.5
|
||||||
|
tiara :fire_tiara, tiara_id: 5537, altar: 2456, talisman: 1442, bitshift: 4, experience: 35
|
||||||
|
tiara :cosmic_tiara, tiara_id: 5539, altar: 2458, talisman: 1454, bitshift: 6, experience: 40
|
||||||
|
tiara :nature_tiara, tiara_id: 5541, altar: 2460, talisman: 1462, bitshift: 8, experience: 45
|
||||||
|
tiara :chaos_tiara, tiara_id: 5543, altar: 2461, talisman: 1452, bitshift: 9, experience: 42.5
|
||||||
|
tiara :law_tiara, tiara_id: 5545, altar: 2459, talisman: 1458, bitshift: 7, experience: 47.5
|
||||||
|
tiara :death_tiara, tiara_id: 5548, altar: 2462, talisman: 1456, bitshift: 10, experience: 50
|
||||||
|
# TODO: there are 2 other altars, which probably just aren't spawned on the map
|
||||||
|
|||||||
@@ -4,40 +4,41 @@ java_import 'org.apollo.cache.def.ItemDefinition'
|
|||||||
java_import 'org.apollo.cache.def.NpcDefinition'
|
java_import 'org.apollo.cache.def.NpcDefinition'
|
||||||
java_import 'org.apollo.cache.def.ObjectDefinition'
|
java_import 'org.apollo.cache.def.ObjectDefinition'
|
||||||
|
|
||||||
|
# Checks whether the amount of arguments provided is correct, sending the player the specified
|
||||||
# Checks whether the amount of arguments provided is correct, sending the player the specified message if not.
|
# message if not.
|
||||||
def valid_arg_length(args, length, player, message)
|
def valid_arg_length(args, length, player, message)
|
||||||
valid = length.kind_of?(Range) ? length.include?(args.length) : length == args.length
|
valid = length.is_a?(Range) ? length.include?(args.length) : length == args.length
|
||||||
|
|
||||||
player.send_message(message) if !valid
|
player.send_message(message) unless valid
|
||||||
return valid
|
valid
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the name of the Object, Npc, or Item with the specified id.
|
# Returns the name of the Object, Npc, or Item with the specified id.
|
||||||
def name_of(type, id)
|
def name_of(type, id)
|
||||||
types = [ :object, :item, :npc ]
|
types = [:object, :item, :npc]
|
||||||
unless types.include?(type)
|
unless types.include?(type)
|
||||||
raise "Invalid type of #{type} specified, must be one of #{types}"
|
fail "Invalid type of #{type} specified, must be one of #{types}"
|
||||||
end
|
end
|
||||||
|
|
||||||
return Kernel.const_get("#{type.capitalize}Definition").lookup(id).name.to_s
|
Kernel.const_get("#{type.capitalize}Definition").lookup(id).name.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add a has_keys? method to hash
|
# Monkey-patches Hash to add a has_keys? method.
|
||||||
class Hash
|
class Hash
|
||||||
|
|
||||||
def has_keys?(*keys)
|
def has_keys?(*keys)
|
||||||
keys.each { |key| return false unless has_key?(key) }
|
keys.all? { |key| self.key?(key) }
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Monkey-patches Player to add a hash_level? method.
|
||||||
class Player
|
class Player
|
||||||
|
|
||||||
# Returns whether or not the player's current level is greater than or equal to the specified level.
|
# Returns whether or not the player's current level is greater than or equal to the specified
|
||||||
def has_level(skill, level)
|
# level.
|
||||||
return skill_set.get_skill(skill).current_level >= level
|
def level?(skill, level)
|
||||||
|
skill_set.get_skill(skill).current_level >= level
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Essentially a wrapper for specific message types to make them easier to use. Only supports the interception of a message type once (for good reason - this is supposed to
|
|
||||||
# be a utility, not a chain of interceptors inside the existing chain).
|
|
||||||
#
|
|
||||||
# Plugins that wish to expand the list of available message types (you probably don't) should use the add_interception method - see the item-on-item script for example usage.
|
|
||||||
#
|
|
||||||
# If you only wish to intercept a message, use the intercept method, e.g.
|
|
||||||
#
|
|
||||||
# intercept :item_on_item, used_id, target_id, :irreversible do |player, message|
|
|
||||||
# # code here
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
# Calls the registered interception(s), if applicable.
|
|
||||||
def intercept(message, *args, &block)
|
|
||||||
raise 'Error - interceptions must provide a block.' unless block_given?
|
|
||||||
interception = INTERCEPTIONS[message]
|
|
||||||
|
|
||||||
if interception == nil then raise "No interception for message #{message}" else interception.call(*args, block) end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Adds an interception.
|
|
||||||
def add_interception(message, &block)
|
|
||||||
INTERCEPTIONS[message] = block
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
INTERCEPTIONS = {}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
|
|
||||||
# Adds an interception for the ItemOnItem message
|
|
||||||
add_interception :item_on_item do |used, target, reversible, block|
|
|
||||||
interception = ItemOnItemPair.new(used, target)
|
|
||||||
|
|
||||||
ITEM_PAIRS[interception] = block
|
|
||||||
ITEM_PAIRS[interception.reverse] = block if reversible == :reversible
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# A hash of ItemOnItemPairs to blocks.
|
|
||||||
ITEM_PAIRS = {}
|
|
||||||
|
|
||||||
# A pair of items that will cause a block to be executed if one (the 'used' item) is used on the other (the 'target' item).
|
|
||||||
class ItemOnItemPair
|
|
||||||
attr_reader :used, :target
|
|
||||||
|
|
||||||
def initialize(used, target)
|
|
||||||
@used = used
|
|
||||||
@target = target
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns a new ItemOnItemPair that is the reverse of this.
|
|
||||||
def reverse
|
|
||||||
return ItemOnItemPair.new(@target, @used)
|
|
||||||
end
|
|
||||||
|
|
||||||
def eql?(other)
|
|
||||||
return (other.kind_of?(ItemOnItemPair) && @used == other.used && @target == other.target)
|
|
||||||
end
|
|
||||||
|
|
||||||
def hash
|
|
||||||
return @used << 16 | @target
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# Adds a message listener to the item on item message.
|
|
||||||
on :message, :item_on_item do |player, message|
|
|
||||||
used, target = message.id, message.target_id
|
|
||||||
pair = ItemOnItemPair.new(used, target)
|
|
||||||
block = ITEM_PAIRS[pair]
|
|
||||||
|
|
||||||
block.call(player, message) unless block == nil
|
|
||||||
end
|
|
||||||
@@ -2,17 +2,17 @@ require 'java'
|
|||||||
|
|
||||||
# Looks up the id of the npc with the specified name.
|
# Looks up the id of the npc with the specified name.
|
||||||
def lookup_npc(name)
|
def lookup_npc(name)
|
||||||
return lookup_entity(:npc, name)
|
lookup_entity(:npc, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Looks up the id of the item with the specified name.
|
# Looks up the id of the item with the specified name.
|
||||||
def lookup_item(name)
|
def lookup_item(name)
|
||||||
return lookup_entity(:item, name)
|
lookup_entity(:item, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Looks up the id of the object with the specified name.
|
# Looks up the id of the object with the specified name.
|
||||||
def lookup_object(name)
|
def lookup_object(name)
|
||||||
return lookup_entity(:object, name)
|
lookup_entity(:object, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Looks up the id of an entity of the specified type (either :npc, :item, or :object)
|
# Looks up the id of an entity of the specified type (either :npc, :item, or :object)
|
||||||
@@ -24,26 +24,27 @@ def lookup_entity(type, name)
|
|||||||
return cached unless cached.nil?
|
return cached unless cached.nil?
|
||||||
|
|
||||||
id = name[name.rindex(' ') + 1, name.length - 1].to_i if name.include?(' ')
|
id = name[name.rindex(' ') + 1, name.length - 1].to_i if name.include?(' ')
|
||||||
id = find_entities(type, name, 1).first if (id.nil? || id.zero?)
|
id = find_entities(type, name, 1).first if id.nil? || id.zero?
|
||||||
|
|
||||||
raise "The #{type} called #{name} could not be identified." if id.nil?
|
fail "The #{type} called #{name} could not be identified." if id.nil?
|
||||||
|
|
||||||
NAME_CACHE[type + name] = id
|
NAME_CACHE[type + name] = id
|
||||||
return id
|
id
|
||||||
end
|
end
|
||||||
|
|
||||||
# Finds entities with the specified type (e.g. npc) and name, returning possible ids as an array.
|
# Finds entities with the specified type (e.g. npc) and name, returning possible ids as an array.
|
||||||
def find_entities(type, name, limit=5)
|
def find_entities(type, name, limit = 5)
|
||||||
ids = []
|
ids = []
|
||||||
name.downcase!
|
name.downcase!
|
||||||
|
|
||||||
Kernel.const_get("#{type.capitalize}Definition").definitions.each do |definition|
|
Kernel.const_get("#{type.capitalize}Definition").definitions.each do |definition|
|
||||||
break if (ids.length == limit)
|
break if (ids.length == limit)
|
||||||
ids << definition.id.to_i if (definition.name.to_s.downcase == name)
|
ids << definition.id.to_i if definition.name.to_s.downcase == name
|
||||||
end
|
end
|
||||||
|
|
||||||
return ids
|
ids
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
NAME_CACHE = {} # Primitive, caching all may not be desirable.
|
NAME_CACHE = {} # Primitive, caching all may not be desirable.
|
||||||
@@ -9,9 +9,7 @@
|
|||||||
</authors>
|
</authors>
|
||||||
<scripts>
|
<scripts>
|
||||||
<script>command.rb</script>
|
<script>command.rb</script>
|
||||||
<script>intercept.rb</script>
|
<script>name_lookup.rb</script>
|
||||||
<script>item-on-item-intercept.rb</script>
|
|
||||||
<script>name-lookup.rb</script>
|
|
||||||
</scripts>
|
</scripts>
|
||||||
<dependencies /> <!-- This plugin should _NOT_ depend on anything. -->
|
<dependencies /> <!-- This plugin should _NOT_ depend on anything. -->
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -213,8 +213,9 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
|
|||||||
private void writeResponseCode(ChannelHandlerContext ctx, int response) {
|
private void writeResponseCode(ChannelHandlerContext ctx, int response) {
|
||||||
ByteBuf buffer = ctx.alloc().buffer(Byte.BYTES);
|
ByteBuf buffer = ctx.alloc().buffer(Byte.BYTES);
|
||||||
buffer.writeByte(response);
|
buffer.writeByte(response);
|
||||||
|
System.out.println("Sending response: " + response);
|
||||||
|
|
||||||
ctx.write(buffer).addListener(ChannelFutureListener.CLOSE);
|
ctx.writeAndFlush(buffer).addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user