mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Merge branch 'master' of git@bitbucket.org:Major-/apollo.git.
This commit is contained in:
@@ -49,7 +49,7 @@ end
|
||||
# Defines the pvp area action.
|
||||
area_action :pvp do
|
||||
on_entry { |player| player.in_pvp = true }
|
||||
on_exit { |player| player.in_pvp = true }
|
||||
on_exit { |player| player.in_pvp = false }
|
||||
end
|
||||
|
||||
# Defines the wilderness area action.
|
||||
|
||||
@@ -42,5 +42,5 @@ def area(hash)
|
||||
end
|
||||
|
||||
# Coordinates refer to the bottom-left position (min_x, min_y) and the top-right position (max_x, max_y), followed by the height (optional).
|
||||
area :name => :wilderness, :coordinates => [ 2944, 3520, 3391, 3967, 0 ], :actions => [ :pvp, :multicombat, :wilderness ]
|
||||
area :name => :wilderness, :coordinates => [ 2944, 3520, 3392, 6400, 0 ], :actions => [ :pvp, :multicombat, :wilderness ]
|
||||
area :name => :duel_arena, :coordinates => [ 3327, 3200, 3392, 3286 ], :actions => :pvp
|
||||
@@ -0,0 +1,426 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.inter.dialogue.DialogueAdapter'
|
||||
java_import 'org.apollo.game.message.impl.CloseInterfaceMessage'
|
||||
java_import 'org.apollo.game.message.impl.SetWidgetItemModelMessage'
|
||||
java_import 'org.apollo.game.message.impl.SetWidgetNpcModelMessage'
|
||||
java_import 'org.apollo.game.message.impl.SetWidgetPlayerModelMessage'
|
||||
java_import 'org.apollo.game.message.impl.SetWidgetTextMessage'
|
||||
|
||||
# Defines a dialogue, with the specified name and block.
|
||||
def dialogue(name, &block)
|
||||
raise 'Dialogues must have a name and block.' if (name.nil? || block.nil?)
|
||||
|
||||
dialogue = Dialogue.new(name)
|
||||
dialogue.instance_eval(&block)
|
||||
dialogue.wrap
|
||||
DIALOGUES[name] = dialogue
|
||||
end
|
||||
|
||||
# Defines an opening (i.e. conversation starter) dialogue, which hooks into the chain.
|
||||
# Allows for a lambda prerequisite to be passed, which takes one argument the player; if the prerequisite evaluates to false, the dialogue will not be opened.
|
||||
def opening_dialogue(name, prerequisite=nil, &block)
|
||||
dialogue = dialogue(name, &block)
|
||||
npc = dialogue.npc
|
||||
raise 'Npc cannot be null when opening a dialogue.' if npc.nil?
|
||||
|
||||
on :message, :first_npc_action, npc do |ctx, player, event|
|
||||
player.open_dialogue(name) if (prerequisite.nil? || prerequisite.call(player))
|
||||
end
|
||||
end
|
||||
|
||||
# Declares an emote, with the specified name and id.
|
||||
def declare_emote(name, id)
|
||||
EMOTES[name] = id
|
||||
end
|
||||
|
||||
|
||||
|
||||
private
|
||||
|
||||
# The hash of dialogue names to dialogues.
|
||||
DIALOGUES = {}
|
||||
|
||||
# The hash of emote names to ids.
|
||||
EMOTES = {}
|
||||
|
||||
# The maximum amount of lines of text that can be displayed on a dialogue.
|
||||
MAXIMUM_LINE_COUNT = 4
|
||||
|
||||
# The maximum amount of options that can be displayed on a dialogue.
|
||||
MAXIMUM_OPTION_COUNT = 5
|
||||
|
||||
# The maximum width of a line, in characters.
|
||||
MAXIMUM_LINE_WIDTH = 55
|
||||
|
||||
# The possible types of a dialogue.
|
||||
DIALOGUE_TYPES = [ :message_with_item, :message_with_model, :npc_speech, :options, :player_speech, :text ]
|
||||
|
||||
# A type of dialogue.
|
||||
class Dialogue
|
||||
attr_reader :emote, :name, :media, :options, :text, :title, :type
|
||||
|
||||
# Initializes the Dialogue.
|
||||
def initialize(name)
|
||||
@name = name.to_s
|
||||
@text = []
|
||||
@options = []
|
||||
end
|
||||
|
||||
# Closes the dialogue interface when the player clicks the 'Click here to continue...' text.
|
||||
def close
|
||||
continue(:close => true)
|
||||
end
|
||||
|
||||
# Defines the event that occurs when a player clicks the 'Click here to continue...' text.
|
||||
def continue(type=nil, &block)
|
||||
raise 'Cannot add a continue event on a dialogue with options.' unless @options.size.zero?
|
||||
raise 'Must declare either a type or a block for a continue event.' if (type.nil? && block.nil?)
|
||||
|
||||
@options << (block.nil? ? get_next_dialogue(type) : block)
|
||||
end
|
||||
|
||||
# Sets the emote performed by the dialogue head.
|
||||
def emote(emote=nil)
|
||||
raise 'Can only perform an emote on :player_speech or :npc_speech dialogues.' unless [ :npc_speech, :player_speech ].include?(@type)
|
||||
@emote = EMOTES[emote] if emote.kind_of?(Symbol)
|
||||
@emote
|
||||
end
|
||||
|
||||
# Gets the media of this dialogue.
|
||||
def media()
|
||||
case @type
|
||||
when :message_with_item then @item
|
||||
when :npc_speech then @npc
|
||||
when :message_with_model then @model
|
||||
else raise "Cannot get media for #{@type}."
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the id of the item displayed.
|
||||
def item(item=nil, scale=nil)
|
||||
unless item.nil?
|
||||
raise 'Can only display an item on :message_with_item dialogues.' unless @type == :message_with_item
|
||||
@item = item
|
||||
@item_scale = scale
|
||||
end
|
||||
|
||||
@item
|
||||
end
|
||||
|
||||
# Sets the id of the model displayed.
|
||||
def model(model=nil)
|
||||
unless model.nil?
|
||||
raise 'Can only display a model on :message_with_model dialogues.' unless @type == :message_with_model
|
||||
@model = model
|
||||
end
|
||||
|
||||
@model
|
||||
end
|
||||
|
||||
# Sets the id of the npc displayed.
|
||||
def npc(npc=nil)
|
||||
raise 'Can only display an npc on :npc_speech dialogues.' unless @type == :npc_speech
|
||||
@npc = lookup_npc(npc) unless npc.nil?
|
||||
@npc
|
||||
end
|
||||
|
||||
# Defines an option, displaying the specified message.
|
||||
def option(message, type)
|
||||
raise 'Can only display options on an :options dialogue.' unless @type == :options
|
||||
raise "Cannot display more than #{MAXIMUM_OPTION_COUNT} options on a dialogue." unless @options.size < MAXIMUM_OPTION_COUNT
|
||||
|
||||
@options[text.size] = get_next_dialogue(type)
|
||||
@text << message
|
||||
end
|
||||
|
||||
# Gets the array of options.
|
||||
def options
|
||||
@options.dup
|
||||
end
|
||||
|
||||
# Appends a message to the text list.
|
||||
def text(*message)
|
||||
unless message.nil?
|
||||
@text.concat(message)
|
||||
end
|
||||
|
||||
@text
|
||||
end
|
||||
|
||||
# Sets the title of the dialogue.
|
||||
def title(title=nil)
|
||||
@title = title unless title.nil?
|
||||
@title
|
||||
end
|
||||
|
||||
# Sets the type of dialogue.
|
||||
def type(type=nil)
|
||||
unless type.nil?
|
||||
verify_dialogue_type(type)
|
||||
@type = type
|
||||
end
|
||||
|
||||
@type
|
||||
end
|
||||
|
||||
# Wraps text in this Dialogue, inserting extra Dialogues in the chain if necessary.
|
||||
def wrap
|
||||
lines = []
|
||||
next if @type == :options
|
||||
|
||||
text = @text[0]
|
||||
segments = []# text.chars.each_slice(MAXIMUM_LINE_WIDTH).map(&:join) # Split text into array of strings with length <= 60.
|
||||
previous = 0; index = MAXIMUM_LINE_WIDTH
|
||||
|
||||
while index < text.length
|
||||
index -= 1 until text[index] == ' '
|
||||
segments << text[previous..index]
|
||||
previous = index
|
||||
index += MAXIMUM_LINE_WIDTH
|
||||
end
|
||||
segments << text[previous..text.length]
|
||||
|
||||
if (segments.size <= MAXIMUM_LINE_COUNT)
|
||||
lines.concat(segments)
|
||||
@text = @text.drop(1)
|
||||
insert_copy(@text) if @text.size > 0
|
||||
else
|
||||
remaining = MAXIMUM_LINE_COUNT - segments.size
|
||||
lines.concat(segments.first(remaining))
|
||||
insert_copy(segments.drop(remaining).join().concat(@text.drop(1)))
|
||||
end
|
||||
|
||||
@text = lines
|
||||
end
|
||||
|
||||
|
||||
# Copies the value of every variable from the specified Dialogue, optionally updating the text array.
|
||||
def copy_from(dialogue, text=nil)
|
||||
@emote = dialogue.emote
|
||||
@item = dialogue.item
|
||||
@model = dialogue.model
|
||||
@npc = dialogue.npc
|
||||
@options = dialogue.options
|
||||
@text = if text.nil? then dialogue.text.dup else text.dup end
|
||||
@type = dialogue.type
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Inserts a copy of this Dialogue into the chain, but with different text.
|
||||
def insert_copy(text)
|
||||
name = @name
|
||||
index = name.index('-auto-inserted-')
|
||||
|
||||
id = if index.nil? then 0 else name[name.rindex('-')..-1].to_i + 1 end
|
||||
index ||= -1
|
||||
name = "#{name[0..index]}-auto-inserted-#{id}"
|
||||
|
||||
dialogue = Dialogue.new(name)
|
||||
dialogue.copy_from(self, text.dup)
|
||||
dialogue.wrap()
|
||||
|
||||
DIALOGUES[name] = dialogue
|
||||
@options[0] = ->(player) { send_dialogue(player, dialogue) }
|
||||
end
|
||||
|
||||
# Decodes the next dialogue interface from the hash, returning a proc.
|
||||
def get_next_dialogue(hash)
|
||||
hash.keys.each do |key|
|
||||
case key
|
||||
when :close
|
||||
return ->(player) { player.send(CloseInterfaceMessage.new) }
|
||||
when :dialogue
|
||||
return ->(player) { send_dialogue(player, lookup_dialogue(hash[key])) }
|
||||
else raise "Unrecognised dialogue continue type #{key}."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# The existing Player class.
|
||||
class Player
|
||||
|
||||
# Opens the dialogue with the specified name.
|
||||
def open_dialogue(name)
|
||||
dialogue = lookup_dialogue(name)
|
||||
send_dialogue(self, dialogue)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
# Gets a Dialogue using the name it was registered with.
|
||||
def lookup_dialogue(name)
|
||||
dialogue = DIALOGUES[name]
|
||||
raise "No dialogue named #{name.to_s}." if dialogue.nil?
|
||||
|
||||
dialogue
|
||||
end
|
||||
|
||||
# Sends the specified dialogue.
|
||||
def send_dialogue(player, dialogue)
|
||||
type = dialogue.type
|
||||
|
||||
case type
|
||||
when :message_with_item then send_item_dialogue(player, dialogue)
|
||||
when :message_with_model then send_model_dialogue(player, dialogue)
|
||||
when :npc_speech then send_npc_dialogue(player, dialogue)
|
||||
when :options then send_options_dialogue(player, dialogue)
|
||||
when :player_speech then send_player_dialogue(player, dialogue)
|
||||
when :text then send_text_dialogue(player, dialogue)
|
||||
else raise "Unrecognised dialogue type #{type}."
|
||||
end
|
||||
end
|
||||
|
||||
# The dialogue interface ids for dialogues that only display text, ordered by line count.
|
||||
TEXT_DIALOGUE_IDS = [ 356, 359, 363, 368, 374 ]
|
||||
|
||||
# The dialogue interface ids for dialogues that display the head of the player, ordered by line count.
|
||||
PLAYER_DIALOGUE_IDS = [ 968, 973, 979, 986 ]
|
||||
|
||||
# The dialogue interface ids for dialogues that display the head of an npc, ordered by line count.
|
||||
NPC_DIALOGUE_IDS = [ 4882, 4887, 4893, 4900 ]
|
||||
|
||||
# The dialogue interface ids for option dialogues, ordered by (option_count - 1)
|
||||
OPTIONS_DIALOGUE_IDS = [ 2459, 2469, 2480, 2492 ]
|
||||
|
||||
# Sends a dialogue displaying only text.
|
||||
def send_text_dialogue(player, dialogue)
|
||||
title = dialogue.title
|
||||
send_generic_dialogue(player, dialogue, title, TEXT_DIALOGUE_IDS)
|
||||
end
|
||||
|
||||
# Sends a dialogue displaying the player's head.
|
||||
def send_player_dialogue(player, dialogue)
|
||||
send_generic_dialogue(player, dialogue, PLAYERS_DIALOGUE_IDS, ->(id) { SetWidgetPlayerModelMessage.new(id + 1) })
|
||||
end
|
||||
|
||||
# Sends a dialogue displaying the head of an npc.
|
||||
def send_npc_dialogue(player, dialogue)
|
||||
npc = dialogue.npc
|
||||
name = NpcDefinition.lookup(npc).name.to_s
|
||||
name = "" if (name.nil? || name == "null")
|
||||
|
||||
send_generic_dialogue(player, dialogue, name, NPC_DIALOGUE_IDS, ->(id) { SetWidgetNpcModelMessage.new(id + 1, npc)})
|
||||
end
|
||||
|
||||
|
||||
# Sends a dialogue displaying an event.
|
||||
def send_generic_dialogue(player, dialogue, title, ids, event=nil)
|
||||
text = dialogue.text
|
||||
dialogue_id = ids[text.size - 1]
|
||||
player.send(event.call(dialogue_id)) unless event.nil?
|
||||
|
||||
set_text(player, dialogue_title_id(dialogue_id), title)
|
||||
|
||||
text.each_index { |index| set_text(player, dialogue_text_id(dialogue_id, index), text[index]) }
|
||||
player.interface_set.open_dialogue(ContinueDialogueAdapter.new(player, dialogue.options[0]), dialogue_id) # TODO listener!!!
|
||||
end
|
||||
|
||||
|
||||
# Sends an options dialogue interface.
|
||||
def send_options_dialogue(player, dialogue)
|
||||
options = dialogue.options
|
||||
size = options.size
|
||||
raise 'Illegal options count: must be between 2 and 5, inclusive.' unless (2..5).include?(size)
|
||||
|
||||
text = dialogue.text
|
||||
dialogue_id = OPTIONS_DIALOGUE_IDS[size - 1]
|
||||
|
||||
question = dialogue.title
|
||||
set_text(player, dialogue_question_id(dialogue_id), question)
|
||||
|
||||
text.each_index { |index| set_text(player, dialogue_option_id(dialogue_id, index), text[index]) }
|
||||
player.interface_set.open_dialogue(OptionDialogueAdapter.new(player, options), dialogue_id) # TODO listener!!!
|
||||
end
|
||||
|
||||
|
||||
# A DialogueAdapter for dialogues with a 'Click here to continue...' message.
|
||||
class ContinueDialogueAdapter < DialogueAdapter
|
||||
|
||||
# Creates the ContinueDialogueAdadpter.
|
||||
def initialize(player, continue)
|
||||
super()
|
||||
@player = player
|
||||
@continue = continue
|
||||
end
|
||||
|
||||
# Executes the 'continue' lambda when the player clicks the 'Click here to continue...' message.
|
||||
def continued()
|
||||
@continue.call(@player)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# A DialogueAdapter for dialogues with a set of options that can be selected.
|
||||
class OptionDialogueAdapter < DialogueAdapter
|
||||
|
||||
# Creates the OptionDialogueAdadpter.
|
||||
def initialize(player, options)
|
||||
super()
|
||||
@player = player
|
||||
@options = options.dup
|
||||
end
|
||||
|
||||
# Executes an option.
|
||||
def button_clicked(button)
|
||||
option = OPTIONS_DIALOGUE_IDS.find_index(button)
|
||||
options[option].call(@player)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Gets the widget id of the question, for an options dialogue interface.
|
||||
def dialogue_question_id(id)
|
||||
id + 1
|
||||
end
|
||||
|
||||
# Gets the widget id of a dialogue option.
|
||||
def dialogue_option_id(id, option)
|
||||
id + 1 + option
|
||||
end
|
||||
|
||||
# Gets the widget id of a dialogue text line.
|
||||
def dialogue_text_id(id, line)
|
||||
id + 3 + line
|
||||
end
|
||||
|
||||
# Gets the widget id of a dialogue title.
|
||||
def dialogue_title_id(id)
|
||||
id + 2
|
||||
end
|
||||
|
||||
# Sets the text of a widget.
|
||||
def set_text(player, id, message)
|
||||
player.send(SetWidgetTextMessage.new(id, message))
|
||||
end
|
||||
|
||||
# Verifies that the dialogue type exists.
|
||||
def verify_dialogue_type(type)
|
||||
raise "Unrecognised dialogue type #{type}, expected one of #{DIALOGUE_TYPES}." unless DIALOGUE_TYPES.include?(type)
|
||||
end
|
||||
|
||||
# The spacing of each character glyph, for the font used for dialogue. TODO decode the font from the cache.
|
||||
GLYPH_SPACING = [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 7, 14, 9, 12, 12, 4, 5,
|
||||
5, 10, 8, 4, 8, 4, 7, 9, 7, 9, 8, 8, 8, 9, 7, 9, 9, 4, 5, 7,
|
||||
9, 7, 9, 14, 9, 8, 8, 8, 7, 7, 9, 8, 6, 8, 8, 7, 10, 9, 9, 8,
|
||||
9, 8, 8, 6, 9, 8, 10, 8, 8, 8, 6, 7, 6, 9, 10, 5, 8, 8, 7, 8,
|
||||
8, 7, 8, 8, 4, 7, 7, 4, 10, 8, 8, 8, 8, 6, 8, 6, 8, 8, 9, 8,
|
||||
8, 8, 6, 4, 6, 12, 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 8, 11, 8, 8, 4, 8, 7, 12, 6, 7, 9, 5, 12, 5, 6, 10, 6, 6, 6,
|
||||
8, 8, 4, 5, 5, 6, 7, 11, 11, 11, 9, 9, 9, 9, 9, 9, 9, 13, 8, 8,
|
||||
8, 8, 8, 4, 4, 5, 4, 8, 9, 9, 9, 9, 9, 9, 8, 10, 9, 9, 9, 9,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 13, 6, 8, 8, 8, 8, 4, 4, 5, 4, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 ]
|
||||
|
||||
def get_width(char)
|
||||
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0"?>
|
||||
<plugin>
|
||||
<id>dialogue</id>
|
||||
<version>0.1</version>
|
||||
<name>Dialogue</name>
|
||||
<description>Adds dialogue support.</description>
|
||||
<authors>
|
||||
<author>Major</author>
|
||||
</authors>
|
||||
<scripts>
|
||||
<script>dialogue.rb</script>
|
||||
</scripts>
|
||||
<dependencies>
|
||||
<dependency>util</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
@@ -24,7 +24,7 @@ def lookup_entity(type, name)
|
||||
return cached unless cached.nil?
|
||||
|
||||
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?
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ public final class Server {
|
||||
serviceManager.startAll();
|
||||
|
||||
int releaseNo = context.getRelease().getReleaseNumber();
|
||||
IndexedFileSystem fs = new IndexedFileSystem(Paths.get("data/fs/", Integer.toString(releaseNo)), true);
|
||||
IndexedFileSystem fs = new IndexedFileSystem(Paths.get("data/fs", Integer.toString(releaseNo)), true);
|
||||
World.getWorld().init(releaseNo, fs, manager);
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ public final class IndexedFileSystem implements Closeable {
|
||||
int nextType = header[7] & 0xFF;
|
||||
|
||||
if (i != curChunk) {
|
||||
throw new IOException("Chunk id mismatch.");
|
||||
Preconditions.checkArgument(i == curChunk, "Chunk id mismatch.");
|
||||
}
|
||||
|
||||
int chunkSize = size - read;
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package org.apollo.game.message.impl;
|
||||
|
||||
/**
|
||||
* The third {@link NpcActionMessage}.
|
||||
*
|
||||
* The fifth {@link NpcActionMessage}.
|
||||
*
|
||||
* @author Major
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class FifthNpcActionMessage extends NpcActionMessage {
|
||||
|
||||
/**
|
||||
* Creates a new third npc action message.
|
||||
* Creates the FifthNpcActionMessage.
|
||||
*
|
||||
* @param index The index of the npc.
|
||||
* @param index The index of the Npc.
|
||||
*/
|
||||
public FifthNpcActionMessage(int index) {
|
||||
super(5, index);
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package org.apollo.game.message.impl;
|
||||
|
||||
/**
|
||||
* The third {@link NpcActionMessage}.
|
||||
*
|
||||
* The fourth {@link NpcActionMessage}.
|
||||
*
|
||||
* @author Major
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class FourthNpcActionMessage extends NpcActionMessage {
|
||||
|
||||
/**
|
||||
* Creates a new third npc action message.
|
||||
*
|
||||
* @param index The index of the npc.
|
||||
* Creates the FourthNpcActionMessage.
|
||||
*
|
||||
* @param index The index of the Npc.
|
||||
*/
|
||||
public FourthNpcActionMessage(int index) {
|
||||
super(4, index);
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
package org.apollo.game.message.impl;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apollo.game.message.Message;
|
||||
import org.apollo.game.model.Position;
|
||||
|
||||
/**
|
||||
* A {@link Message} that displays a hint icon over an Npc, tile, or player.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public final class HintIconMessage extends Message {
|
||||
|
||||
// TODO identify the other types and use an enum.
|
||||
|
||||
/**
|
||||
* The hint icon type for Npcs.
|
||||
*/
|
||||
public static final int NPC_TYPE = 1;
|
||||
|
||||
/**
|
||||
* The hint icon type for Players.
|
||||
*/
|
||||
public static final int PLAYER_TYPE = 10;
|
||||
|
||||
/**
|
||||
* Creates a HintIconMessage for the Npc with the specified index.
|
||||
*
|
||||
* @param index The index of the Npc.
|
||||
* @return The HintIconMessage.
|
||||
*/
|
||||
public static HintIconMessage forNpc(int index) {
|
||||
return new HintIconMessage(NPC_TYPE, Optional.of(index), Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HintIconMessage for the Player with the specified index.
|
||||
*
|
||||
* @param index The index of the Player.
|
||||
* @return The HintIconMessage.
|
||||
*/
|
||||
public static HintIconMessage forPlayer(int index) {
|
||||
return new HintIconMessage(PLAYER_TYPE, Optional.of(index), Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* The index of the entity, if applicable.
|
||||
*/
|
||||
private final Optional<Integer> index;
|
||||
|
||||
/**
|
||||
* The Position of the tile, if applicable.
|
||||
*/
|
||||
private final Optional<Position> position;
|
||||
|
||||
/**
|
||||
* The type of entity this HintIconMessage is directed at.
|
||||
*/
|
||||
private final int type;
|
||||
|
||||
/**
|
||||
* Creates the HintIconMessage.
|
||||
*
|
||||
* @param type The type of entity this HintIconMessage is directed at.
|
||||
* @param index The index of the entity, if applicable.
|
||||
* @param position The Position of the tile, if applicable.
|
||||
*/
|
||||
private HintIconMessage(int type, Optional<Integer> index, Optional<Position> position) {
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the entity, if applicable.
|
||||
*
|
||||
* @return The index.
|
||||
*/
|
||||
public Optional<Integer> getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Position} of the tile, if applicable.
|
||||
*
|
||||
* @return The Position.
|
||||
*/
|
||||
public Optional<Position> getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type this HintIconMessage is directed at.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,63 +4,65 @@ import org.apollo.game.message.Message;
|
||||
import org.apollo.game.model.entity.Entity;
|
||||
|
||||
/**
|
||||
* A {@link Message} sent by the client representing when a player uses any type of magic spell on a mob.
|
||||
* A {@link Message} sent by the client when a Player uses a magic spell on a Mob.
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public abstract class MagicOnMobMessage extends Message {
|
||||
|
||||
/**
|
||||
* The type of the mob
|
||||
*/
|
||||
private final Entity.EntityType type;
|
||||
/**
|
||||
* The index of the mob
|
||||
*/
|
||||
private final int index;
|
||||
/**
|
||||
* The spell if used
|
||||
*/
|
||||
private final int spellId;
|
||||
/**
|
||||
* The type of the Mob.
|
||||
*/
|
||||
private final Entity.EntityType type;
|
||||
|
||||
/**
|
||||
* Creates a magic on mob message
|
||||
*
|
||||
* @param type The mob type
|
||||
* @param index The mob index
|
||||
* @param spellId The spell id
|
||||
*/
|
||||
public MagicOnMobMessage(Entity.EntityType type, int index, int spellId) {
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
this.spellId = spellId;
|
||||
}
|
||||
/**
|
||||
* The index of the Mob.
|
||||
*/
|
||||
private final int index;
|
||||
|
||||
/**
|
||||
* Gets the type of the mob the spell is being used on
|
||||
*
|
||||
* @return The mob type
|
||||
*/
|
||||
public Entity.EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* The spell if used.
|
||||
*/
|
||||
private final int spellId;
|
||||
|
||||
/**
|
||||
* Gets the index of the mob the spell is being used on
|
||||
*
|
||||
* @return The mob index
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
/**
|
||||
* Creates the MagicOnMobMessage.
|
||||
*
|
||||
* @param type The Mob type.
|
||||
* @param index The Mob index.
|
||||
* @param spellId The spell id.
|
||||
*/
|
||||
public MagicOnMobMessage(Entity.EntityType type, int index, int spellId) {
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
this.spellId = spellId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the spell id that is being used
|
||||
*
|
||||
* @return The spell id
|
||||
*/
|
||||
public int getSpellId() {
|
||||
return spellId;
|
||||
}
|
||||
/**
|
||||
* Gets the type of the Mob the spell is being used on.
|
||||
*
|
||||
* @return The Mob type.
|
||||
*/
|
||||
public Entity.EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the Mob the spell is being used on.
|
||||
*
|
||||
* @return The Mob index.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the spell id that is being used.
|
||||
*
|
||||
* @return The spell id.
|
||||
*/
|
||||
public int getSpellId() {
|
||||
return spellId;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +1,22 @@
|
||||
package org.apollo.game.message.impl;
|
||||
|
||||
import org.apollo.game.model.entity.Entity;
|
||||
import org.apollo.game.model.entity.Npc;
|
||||
|
||||
/**
|
||||
* The magic on npc {@link org.apollo.game.message.impl.MagicOnNpcMessage}
|
||||
* The magic on npc {@link MagicOnNpcMessage}
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class MagicOnNpcMessage extends MagicOnMobMessage {
|
||||
|
||||
/**
|
||||
* Creates the magic on npc message
|
||||
*
|
||||
* @param index The npc index
|
||||
* @param spellId The spell id used
|
||||
*/
|
||||
public MagicOnNpcMessage(int index, int spellId) {
|
||||
super(Entity.EntityType.NPC, index, spellId);
|
||||
}
|
||||
/**
|
||||
* Creates the MagicOnMobMessage.
|
||||
*
|
||||
* @param index The Npc index.
|
||||
* @param spellId The spell id used.
|
||||
*/
|
||||
public MagicOnNpcMessage(int index, int spellId) {
|
||||
super(Entity.EntityType.NPC, index, spellId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ package org.apollo.game.message.impl;
|
||||
import org.apollo.game.model.entity.Entity;
|
||||
|
||||
/**
|
||||
* The magic on player {@link org.apollo.game.message.impl.MagicOnMobMessage
|
||||
* The Player {@link MagicOnMobMessage}.
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class MagicOnPlayerMessage extends MagicOnMobMessage {
|
||||
|
||||
/**
|
||||
* Creates the magic on player message
|
||||
*
|
||||
* @param index The player index
|
||||
* @param spellId The spell id used
|
||||
*/
|
||||
public MagicOnPlayerMessage(int index, int spellId) {
|
||||
super(Entity.EntityType.PLAYER, index, spellId);
|
||||
}
|
||||
/**
|
||||
* Creates the MagicOnPlayerMessage.
|
||||
*
|
||||
* @param index The index of the player.
|
||||
* @param spellId The spell id used.
|
||||
*/
|
||||
public MagicOnPlayerMessage(int index, int spellId) {
|
||||
super(Entity.EntityType.PLAYER, index, spellId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,79 +4,82 @@ import org.apollo.game.message.Message;
|
||||
|
||||
/**
|
||||
* A {@link Message} sent by the client to indicate when the mouse button/s have been clicked. This can be used in
|
||||
* combination with {@link org.apollo.game.message.impl.FocusUpdateMessage} to work out if the player is clicking
|
||||
* whilst the client is closed
|
||||
* combination with {@link FocusUpdateMessage} to work out if the player is clicking whilst the client is closed.
|
||||
*
|
||||
* @author Stuart
|
||||
* @author Major
|
||||
*/
|
||||
public final class MouseClickedMessage extends Message {
|
||||
|
||||
/**
|
||||
* Time in milliseconds since the last click
|
||||
*/
|
||||
private final long lastClickedDelay;
|
||||
/**
|
||||
* Right mouse button flag
|
||||
*/
|
||||
private final boolean rightMouseButton;
|
||||
/**
|
||||
* The y position of the cursor
|
||||
*/
|
||||
private final int x;
|
||||
/**
|
||||
* The x position of the cursor
|
||||
*/
|
||||
private final int y;
|
||||
/**
|
||||
* The time, in milliseconds, since the last click.
|
||||
*/
|
||||
private final long clickDelay;
|
||||
|
||||
/**
|
||||
* Creates a new mouse clicked message
|
||||
*
|
||||
* @param lastClickedDelay The delay since the last click
|
||||
* @param rightMouseButton Whether or not the right mouse button was used
|
||||
* @param x The x cursor position when clicked
|
||||
* @param y The y cursor position when clicked
|
||||
*/
|
||||
public MouseClickedMessage(long lastClickedDelay, boolean rightMouseButton, int x, int y) {
|
||||
this.lastClickedDelay = lastClickedDelay;
|
||||
this.rightMouseButton = rightMouseButton;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
/**
|
||||
* Indicates whether or not the mouse button pressed was the right mouse button.
|
||||
*/
|
||||
private final boolean right;
|
||||
|
||||
/**
|
||||
* Gets the time in milliseconds since the last click
|
||||
*
|
||||
* @return The time in milliseconds since the last click
|
||||
*/
|
||||
public long getLastClickedDelay() {
|
||||
return lastClickedDelay;
|
||||
}
|
||||
/**
|
||||
* The y position of the cursor.
|
||||
*/
|
||||
private final int x;
|
||||
|
||||
/**
|
||||
* Gets whether the right mouse button was used or not
|
||||
*
|
||||
* @return If the mouse right button was used to click
|
||||
*/
|
||||
public boolean usingRightMouseButton() {
|
||||
return rightMouseButton;
|
||||
}
|
||||
/**
|
||||
* The x position of the cursor.
|
||||
*/
|
||||
private final int y;
|
||||
|
||||
/**
|
||||
* Gets the x position of the cursor
|
||||
*
|
||||
* @return The x position of the cursor when clicked
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
/**
|
||||
* Creates the MouseClickedMessage.
|
||||
*
|
||||
* @param clickDelay The delay, in milliseconds, since the last click.
|
||||
* @param right Whether or not the mouse button pressed was the right mouse button.
|
||||
* @param x The x cursor position when clicked.
|
||||
* @param y The y cursor position when clicked.
|
||||
*/
|
||||
public MouseClickedMessage(long clickDelay, boolean right, int x, int y) {
|
||||
this.clickDelay = clickDelay;
|
||||
this.right = right;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the y position of the cursor
|
||||
*
|
||||
* @return The y position of the cursor when clicked
|
||||
*/
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
/**
|
||||
* Gets the delay, in milliseconds, since the last click.
|
||||
*
|
||||
* @return The time delay.
|
||||
*/
|
||||
public long getClickDelay() {
|
||||
return clickDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the x position of the cursor.
|
||||
*
|
||||
* @return The x position of the cursor when clicked.
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the y position of the cursor.
|
||||
*
|
||||
* @return The y position of the cursor when clicked.
|
||||
*/
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the right mouse button was used.
|
||||
*
|
||||
* @return {@code true} if the right mouse button was used to click, {@code false} if not.
|
||||
*/
|
||||
public boolean wasRightMouseButton() {
|
||||
return right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.apollo.game.model.entity.Entity;
|
||||
import org.apollo.game.model.entity.Entity.EntityType;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
@@ -23,16 +22,16 @@ import com.google.common.collect.ImmutableSet;
|
||||
*/
|
||||
public final class Sector {
|
||||
|
||||
/**
|
||||
* The default size of newly-created sets, to reduce memory usage.
|
||||
*/
|
||||
private static final int DEFAULT_SET_SIZE = 2;
|
||||
|
||||
/**
|
||||
* The width and length of a sector, in tiles.
|
||||
*/
|
||||
public static final int SECTOR_SIZE = 8;
|
||||
|
||||
/**
|
||||
* The default size of newly-created sets, to reduce memory usage.
|
||||
*/
|
||||
private static final int DEFAULT_SET_SIZE = 2;
|
||||
|
||||
/**
|
||||
* The sector coordinates of this sector.
|
||||
*/
|
||||
@@ -72,6 +71,7 @@ public final class Sector {
|
||||
* register it to this sector.
|
||||
*
|
||||
* @param entity The entity.
|
||||
* @throws IllegalArgumentException If the entity does not belong in this sector.
|
||||
*/
|
||||
public void addEntity(Entity entity) {
|
||||
Position position = entity.getPosition();
|
||||
@@ -82,17 +82,6 @@ public final class Sector {
|
||||
notifyListeners(entity, SectorOperation.ADD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified {@link Position} is included in this sector.
|
||||
*
|
||||
* @param position The position.
|
||||
* @throws IllegalArgumentException If the specified position is not included in this sector.
|
||||
*/
|
||||
private void checkPosition(Position position) {
|
||||
Preconditions.checkArgument(coordinates.equals(SectorCoordinates.fromPosition(position)),
|
||||
"Position is not included in this sector.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this sector contains the specified entity.
|
||||
* <p>
|
||||
@@ -118,24 +107,24 @@ public final class Sector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a shallow copy of the {@link List} of {@link Entity} objects at the specified {@link Position}. The returned
|
||||
* type will be {@link ImmutableList}.
|
||||
* Gets a shallow copy of the {@link Set} of {@link Entity} objects at the specified {@link Position}. The returned
|
||||
* type will be immutable.
|
||||
*
|
||||
* @param position The position containing the entities.
|
||||
* @return The list.
|
||||
*/
|
||||
public List<Entity> getEntities(Position position) {
|
||||
return ImmutableList.copyOf(entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE)));
|
||||
public Set<Entity> getEntities(Position position) {
|
||||
return ImmutableSet.copyOf(entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a shallow copy of the {@link List} of {@link Entity}s with the specified {@link EntityType}. The returned
|
||||
* list will be an {@link ImmutableList}. Type will be inferred from the call, so ensure that the entity type and
|
||||
* the reference correspond, or this method will fail at runtime.
|
||||
* Gets a shallow copy of the {@link Set} of {@link Entity}s with the specified {@link EntityType}. The returned
|
||||
* type will be immutable. Type will be inferred from the call, so ensure that the entity type and the reference
|
||||
* correspond, or this method will fail at runtime.
|
||||
*
|
||||
* @param position The {@link Position} containing the entities.
|
||||
* @param type The {@link EntityType}.
|
||||
* @return The list of entities.
|
||||
* @return The set of entities.
|
||||
*/
|
||||
public <T extends Entity> Set<T> getEntities(Position position, EntityType type) {
|
||||
Set<Entity> local = entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE));
|
||||
@@ -145,6 +134,34 @@ public final class Sector {
|
||||
return ImmutableSet.copyOf(filtered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the {@link Entity} that was in the specified {@code old} {@link Position}, to the current position of the
|
||||
* entity.
|
||||
* <p>
|
||||
* Both the {@code old} and current positions of the entity must belong to this sector.
|
||||
*
|
||||
* @param old The old position of the entity.
|
||||
* @param entity The entity to move.
|
||||
* @throws IllegalArgumentException If either of the positions do not belong to this sector.
|
||||
*/
|
||||
public void moveEntity(Position old, Entity entity) {
|
||||
Position position = entity.getPosition();
|
||||
checkPosition(old);
|
||||
checkPosition(position);
|
||||
|
||||
Set<Entity> local = entities.get(old);
|
||||
|
||||
if (local == null || !local.remove(entity)) {
|
||||
throw new IllegalArgumentException("Entity belongs in this sector but does not exist.");
|
||||
}
|
||||
|
||||
local = entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE));
|
||||
|
||||
local.add(entity);
|
||||
notifyListeners(entity, SectorOperation.MOVE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the {@link SectorListener}s registered to this sector that an update has occurred.
|
||||
*
|
||||
@@ -174,4 +191,15 @@ public final class Sector {
|
||||
notifyListeners(entity, SectorOperation.REMOVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified {@link Position} is included in this sector.
|
||||
*
|
||||
* @param position The position.
|
||||
* @throws IllegalArgumentException If the specified position is not included in this sector.
|
||||
*/
|
||||
private void checkPosition(Position position) {
|
||||
Preconditions.checkArgument(coordinates.equals(SectorCoordinates.fromPosition(position)),
|
||||
"Position is not included in this sector.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,11 @@ public enum SectorOperation {
|
||||
*/
|
||||
ADD,
|
||||
|
||||
/**
|
||||
* The move operation, when an entity has moved positions, but is still in the same sector.
|
||||
*/
|
||||
MOVE,
|
||||
|
||||
/**
|
||||
* The remove operation, when an entity has been removed from a sector.
|
||||
*/
|
||||
|
||||
@@ -419,15 +419,20 @@ public abstract class Mob extends Entity {
|
||||
* @param position The position.
|
||||
*/
|
||||
public final void setPosition(Position position) {
|
||||
Position old = this.position;
|
||||
SectorRepository repository = World.getWorld().getSectorRepository();
|
||||
Sector current = repository.fromPosition(this.position);
|
||||
Sector current = repository.fromPosition(old);
|
||||
|
||||
Sector next = position.inside(current) ? current : repository.fromPosition(position);
|
||||
if (position.inside(current)) {
|
||||
this.position = position;
|
||||
current.moveEntity(old, this);
|
||||
} else {
|
||||
Sector next = repository.fromPosition(position);
|
||||
current.removeEntity(this);
|
||||
this.position = position; // addEntity relies on the position being updated, so do that first.
|
||||
|
||||
current.removeEntity(this);
|
||||
this.position = position; // addEntity relies on the position being updated, so do that first.
|
||||
|
||||
next.addEntity(this);
|
||||
next.addEntity(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,19 +13,19 @@ import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* An {@link Npc} is a {@link Mob} that is not being controlled by a player.
|
||||
* A {@link Mob} that is not controlled by a player.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public final class Npc extends Mob {
|
||||
|
||||
/**
|
||||
* The positions representing the bounds (i.e. walking limits) of this npc.
|
||||
* The positions representing the bounds (i.e. walking limits) of this Npc.
|
||||
*/
|
||||
private Position[] boundary;
|
||||
|
||||
/**
|
||||
* Creates a new npc with the specified id and {@link Position}.
|
||||
* Creates a new Npc with the specified id and {@link Position}.
|
||||
*
|
||||
* @param id The id.
|
||||
* @param position The position.
|
||||
@@ -35,7 +35,7 @@ public final class Npc extends Mob {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new npc with the specified {@link NpcDefinition} and {@link Position}.
|
||||
* Creates a new Npc with the specified {@link NpcDefinition} and {@link Position}.
|
||||
*
|
||||
* @param position The position.
|
||||
* @param definition The definition.
|
||||
@@ -57,7 +57,7 @@ public final class Npc extends Mob {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the boundary of this npc.
|
||||
* Gets the boundary of this Npc.
|
||||
*
|
||||
* @return The boundary.
|
||||
*/
|
||||
@@ -71,7 +71,7 @@ public final class Npc extends Mob {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this npc.
|
||||
* Gets the id of this Npc.
|
||||
*
|
||||
* @return The id.
|
||||
*/
|
||||
@@ -87,16 +87,16 @@ public final class Npc extends Mob {
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not this npc is bound to a specific set of coordinates.
|
||||
* Indicates whether or not this Npc is bound to a specific set of coordinates.
|
||||
*
|
||||
* @return {@code true} if the npc is bound, otherwise {@code false}.
|
||||
* @return {@code true} if the Npc is bound, otherwise {@code false}.
|
||||
*/
|
||||
public boolean isBound() {
|
||||
return boundary == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the boundary of this npc.
|
||||
* Sets the boundary of this Npc.
|
||||
*
|
||||
* @param boundary The boundary.
|
||||
*/
|
||||
@@ -111,7 +111,7 @@ public final class Npc extends Mob {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms this npc into the npc with the specified id.
|
||||
* Transforms this Npc into the Npc with the specified id.
|
||||
*
|
||||
* @param id The id.
|
||||
*/
|
||||
@@ -123,10 +123,10 @@ public final class Npc extends Mob {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises this npc.
|
||||
* Initialises this Npc.
|
||||
*/
|
||||
private void init() {
|
||||
// This has to be here instead of in Mob#init because of ordering issues - the player cannot be added to the
|
||||
// This has to be here instead of in Mob#init because of ordering issues - the Npc cannot be added to the
|
||||
// sector until their credentials have been set, which is only done after the super constructors are called.
|
||||
Sector sector = World.getWorld().getSectorRepository().get(position.getSectorCoordinates());
|
||||
sector.addEntity(this);
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.apollo.game.model.inter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apollo.game.message.impl.CloseInterfaceMessage;
|
||||
import org.apollo.game.message.impl.EnterAmountMessage;
|
||||
@@ -34,12 +35,12 @@ public final class InterfaceSet {
|
||||
/**
|
||||
* The current enter amount listener.
|
||||
*/
|
||||
private EnterAmountListener amountListener;
|
||||
private Optional<EnterAmountListener> amountListener = Optional.empty();
|
||||
|
||||
/**
|
||||
* The current chat box dialogue listener.
|
||||
*/
|
||||
private DialogueListener dialogueListener;
|
||||
private Optional<DialogueListener> dialogueListener = Optional.empty();
|
||||
|
||||
/**
|
||||
* A map of open interfaces.
|
||||
@@ -49,12 +50,12 @@ public final class InterfaceSet {
|
||||
/**
|
||||
* The current listener.
|
||||
*/
|
||||
private InterfaceListener listener;
|
||||
private Optional<InterfaceListener> listener = Optional.empty();
|
||||
|
||||
/**
|
||||
* The player whose interfaces are being managed.
|
||||
*/
|
||||
private final Player player; // TODO: maybe switch to a listener system like the inventory?
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Creates an interface set.
|
||||
@@ -72,8 +73,8 @@ public final class InterfaceSet {
|
||||
* @return {@code true} if the message handler chain should be broken.
|
||||
*/
|
||||
public boolean buttonClicked(int button) {
|
||||
if (dialogueListener != null) {
|
||||
return dialogueListener.buttonClicked(button);
|
||||
if (dialogueListener.isPresent()) {
|
||||
return dialogueListener.get().buttonClicked(button);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -86,21 +87,6 @@ public final class InterfaceSet {
|
||||
player.send(new CloseInterfaceMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal method for closing the interface, notifying the listener if appropriate, but not sending any
|
||||
* messages.
|
||||
*/
|
||||
private void closeAndNotify() {
|
||||
amountListener = null;
|
||||
dialogueListener = null;
|
||||
|
||||
interfaces.clear();
|
||||
if (listener != null) {
|
||||
listener.interfaceClosed();
|
||||
listener = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this interface sets contains the specified interface.
|
||||
*
|
||||
@@ -125,8 +111,8 @@ public final class InterfaceSet {
|
||||
* Called when the player has clicked the "Click here to continue" button on a dialogue.
|
||||
*/
|
||||
public void continueRequested() {
|
||||
if (dialogueListener != null) {
|
||||
dialogueListener.continued();
|
||||
if (dialogueListener.isPresent()) {
|
||||
dialogueListener.get().continued();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,9 +122,9 @@ public final class InterfaceSet {
|
||||
* @param amount The amount.
|
||||
*/
|
||||
public void enteredAmount(int amount) {
|
||||
if (amountListener != null) {
|
||||
amountListener.amountEntered(amount);
|
||||
amountListener = null;
|
||||
if (amountListener.isPresent()) {
|
||||
amountListener.get().amountEntered(amount);
|
||||
amountListener = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,8 +144,8 @@ public final class InterfaceSet {
|
||||
public void openDialogue(DialogueListener listener, int dialogueId) {
|
||||
closeAndNotify();
|
||||
|
||||
this.dialogueListener = listener;
|
||||
this.listener = listener;
|
||||
this.dialogueListener = Optional.ofNullable(listener);
|
||||
this.listener = Optional.ofNullable(listener);
|
||||
|
||||
interfaces.put(InterfaceType.DIALOGUE, dialogueId);
|
||||
player.send(new OpenDialogueInterfaceMessage(dialogueId));
|
||||
@@ -180,7 +166,7 @@ public final class InterfaceSet {
|
||||
* @param listener The enter amount listener.
|
||||
*/
|
||||
public void openEnterAmountDialogue(EnterAmountListener listener) {
|
||||
amountListener = listener;
|
||||
amountListener = Optional.of(listener);
|
||||
player.send(new EnterAmountMessage());
|
||||
}
|
||||
|
||||
@@ -201,7 +187,7 @@ public final class InterfaceSet {
|
||||
*/
|
||||
public void openWindow(InterfaceListener listener, int windowId) {
|
||||
closeAndNotify();
|
||||
this.listener = listener;
|
||||
this.listener = Optional.ofNullable(listener);
|
||||
|
||||
interfaces.put(InterfaceType.WINDOW, windowId);
|
||||
player.send(new OpenInterfaceMessage(windowId));
|
||||
@@ -226,7 +212,7 @@ public final class InterfaceSet {
|
||||
*/
|
||||
public void openWindowWithSidebar(InterfaceListener listener, int windowId, int sidebarId) {
|
||||
closeAndNotify();
|
||||
this.listener = listener;
|
||||
this.listener = Optional.ofNullable(listener);
|
||||
|
||||
interfaces.put(InterfaceType.WINDOW, windowId);
|
||||
interfaces.put(InterfaceType.SIDEBAR, sidebarId);
|
||||
@@ -243,4 +229,19 @@ public final class InterfaceSet {
|
||||
return interfaces.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal method for closing the interface, notifying the listener if appropriate, but not sending any
|
||||
* messages.
|
||||
*/
|
||||
private void closeAndNotify() {
|
||||
amountListener = Optional.empty();
|
||||
dialogueListener = Optional.empty();
|
||||
|
||||
interfaces.clear();
|
||||
if (listener.isPresent()) {
|
||||
listener.get().interfaceClosed();
|
||||
listener = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -122,19 +122,17 @@ public final class Inventory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to add as much of the specified {@code item} to this inventory
|
||||
* as possible. If any of the item remains, an {@link Item item with the
|
||||
* remainder} will be returned (in the case of stack-able items, any
|
||||
* quantity that remains in the stack is returned). If nothing remains, the
|
||||
* method will return {@link Optional#empty an empty Optional}.
|
||||
* Attempts to add as much of the specified {@code item} to this inventory as possible. If any of the item remains,
|
||||
* an {@link Item item with the remainder} will be returned (in the case of stack-able items, any quantity that
|
||||
* remains in the stack is returned). If nothing remains, the method will return {@link Optional#empty an empty
|
||||
* Optional}.
|
||||
*
|
||||
* <p>
|
||||
* If anything remains at all, the listener will be notified which could be
|
||||
* used for notifying a player that their inventory is full, for example.
|
||||
* If anything remains at all, the listener will be notified which could be used for notifying a player that their
|
||||
* inventory is full, for example.
|
||||
*
|
||||
* @param item The item to add to this inventory.
|
||||
* @return The item that may remain, if nothing remains,
|
||||
* {@link Optional#empty an empty Optional} is returned.
|
||||
* @return The item that may remain, if nothing remains, {@link Optional#empty an empty Optional} is returned.
|
||||
*/
|
||||
public Optional<Item> add(Item item) {
|
||||
int id = item.getId();
|
||||
@@ -463,10 +461,10 @@ public final class Inventory {
|
||||
if (amount >= item.getAmount()) {
|
||||
set(slot, null);
|
||||
return item.getAmount();
|
||||
} else {
|
||||
set(slot, new Item(item.getId(), item.getAmount() - amount));
|
||||
return amount;
|
||||
}
|
||||
|
||||
set(slot, new Item(item.getId(), item.getAmount() - amount));
|
||||
return amount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -69,13 +69,13 @@ public final class PlayerSynchronizationTask extends SynchronizationTask {
|
||||
List<SynchronizationSegment> segments = new ArrayList<>();
|
||||
|
||||
for (Iterator<Player> it = localPlayers.iterator(); it.hasNext();) {
|
||||
Player p = it.next();
|
||||
if (!p.isActive() || p.isTeleporting()
|
||||
|| p.getPosition().getLongestDelta(player.getPosition()) > player.getViewingDistance()) {
|
||||
Player other = it.next();
|
||||
if (!other.isActive() || other.isTeleporting()
|
||||
|| other.getPosition().getLongestDelta(player.getPosition()) > player.getViewingDistance()) {
|
||||
it.remove();
|
||||
segments.add(new RemoveMobSegment());
|
||||
} else {
|
||||
segments.add(new MovementSegment(p.getBlockSet(), p.getDirections()));
|
||||
segments.add(new MovementSegment(other.getBlockSet(), other.getDirections()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public final class PlayerSynchronizationTask extends SynchronizationTask {
|
||||
|
||||
MobRepository<Player> repository = World.getWorld().getPlayerRepository();
|
||||
for (Iterator<Player> it = repository.iterator(); it.hasNext();) {
|
||||
Player p = it.next();
|
||||
Player other = it.next();
|
||||
if (localPlayers.size() >= 255) {
|
||||
player.flagExcessivePlayers();
|
||||
break;
|
||||
@@ -91,19 +91,19 @@ public final class PlayerSynchronizationTask extends SynchronizationTask {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p != player && p.getPosition().isWithinDistance(player.getPosition(), player.getViewingDistance())
|
||||
&& !localPlayers.contains(p)) {
|
||||
localPlayers.add(p);
|
||||
if (other != player && other.getPosition().isWithinDistance(player.getPosition(), player.getViewingDistance())
|
||||
&& !localPlayers.contains(other)) {
|
||||
localPlayers.add(other);
|
||||
added++;
|
||||
|
||||
blockSet = p.getBlockSet();
|
||||
blockSet = other.getBlockSet();
|
||||
if (!blockSet.contains(AppearanceBlock.class)) {
|
||||
// TODO check if client has cached appearance
|
||||
blockSet = blockSet.clone();
|
||||
blockSet.add(SynchronizationBlock.createAppearanceBlock(p));
|
||||
blockSet.add(SynchronizationBlock.createAppearanceBlock(other));
|
||||
}
|
||||
|
||||
segments.add(new AddPlayerSegment(blockSet, p.getIndex(), p.getPosition()));
|
||||
segments.add(new AddPlayerSegment(blockSet, other.getIndex(), other.getPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,16 +8,17 @@ import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.FifthNpcActionMessage}.
|
||||
* A {@link MessageDecoder} for the {@link FifthNpcActionMessage}.
|
||||
*
|
||||
* @author Stuart
|
||||
* @author Major
|
||||
*/
|
||||
public final class FifthNpcActionMessageDecoder extends MessageDecoder<FifthNpcActionMessage> {
|
||||
|
||||
@Override
|
||||
public FifthNpcActionMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int index = (int) reader.getSigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
return new FifthNpcActionMessage(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,16 +7,17 @@ import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.FourthNpcActionMessage}.
|
||||
* A {@link MessageDecoder} for the {@link FourthNpcActionMessage}.
|
||||
*
|
||||
* @author Stuart
|
||||
* @author Major
|
||||
*/
|
||||
public final class FourthNpcActionMessageDecoder extends MessageDecoder<FourthNpcActionMessage> {
|
||||
|
||||
@Override
|
||||
public FourthNpcActionMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int index = (int) reader.getSigned(DataType.SHORT);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT);
|
||||
return new FourthNpcActionMessage(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.apollo.net.release.r317;
|
||||
|
||||
import org.apollo.game.message.impl.HintIconMessage;
|
||||
import org.apollo.net.codec.game.DataType;
|
||||
import org.apollo.net.codec.game.GamePacket;
|
||||
import org.apollo.net.codec.game.GamePacketBuilder;
|
||||
import org.apollo.net.release.MessageEncoder;
|
||||
|
||||
/**
|
||||
* A {@link MessageEncoder} for the {@link HintIconMessage}.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public final class HintIconMessageEncoder extends MessageEncoder<HintIconMessage> {
|
||||
|
||||
@Override
|
||||
public GamePacket encode(HintIconMessage message) {
|
||||
GamePacketBuilder builder = new GamePacketBuilder(254);
|
||||
int type = message.getType();
|
||||
builder.put(DataType.BYTE, type);
|
||||
|
||||
switch (type) {
|
||||
case HintIconMessage.NPC_TYPE:
|
||||
case HintIconMessage.PLAYER_TYPE:
|
||||
builder.put(DataType.SHORT, message.getIndex().get());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported hint icon type " + type + ".");
|
||||
}
|
||||
|
||||
return builder.toGamePacket();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +1,28 @@
|
||||
package org.apollo.net.release.r317;
|
||||
|
||||
import org.apollo.game.message.impl.MagicOnNpcMessage;
|
||||
import org.apollo.net.codec.game.*;
|
||||
import org.apollo.net.codec.game.DataOrder;
|
||||
import org.apollo.net.codec.game.DataTransformation;
|
||||
import org.apollo.net.codec.game.DataType;
|
||||
import org.apollo.net.codec.game.GamePacket;
|
||||
import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.MagicOnNpcMessage}
|
||||
* A {@link MessageDecoder} for the {@link MagicOnNpcMessage}
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class MagicOnNpcMessageDecoder extends MessageDecoder<MagicOnNpcMessage> {
|
||||
|
||||
@Override
|
||||
public MagicOnNpcMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
@Override
|
||||
public MagicOnNpcMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
|
||||
int index = (int) reader.getSigned(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD);
|
||||
int spellId = (int) reader.getSigned(DataType.SHORT, DataTransformation.ADD);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD);
|
||||
int spell = (int) reader.getUnsigned(DataType.SHORT, DataTransformation.ADD);
|
||||
|
||||
return new MagicOnNpcMessage(index, spellId);
|
||||
}
|
||||
return new MagicOnNpcMessage(index, spell);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +1,28 @@
|
||||
package org.apollo.net.release.r317;
|
||||
|
||||
import org.apollo.game.message.impl.MagicOnPlayerMessage;
|
||||
import org.apollo.net.codec.game.*;
|
||||
import org.apollo.net.codec.game.DataOrder;
|
||||
import org.apollo.net.codec.game.DataTransformation;
|
||||
import org.apollo.net.codec.game.DataType;
|
||||
import org.apollo.net.codec.game.GamePacket;
|
||||
import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.MagicOnPlayerMessage}
|
||||
* A {@link MessageDecoder} for the {@link MagicOnPlayerMessage}
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class MagicOnPlayerMessageDecoder extends MessageDecoder<MagicOnPlayerMessage> {
|
||||
|
||||
@Override
|
||||
public MagicOnPlayerMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
@Override
|
||||
public MagicOnPlayerMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
|
||||
int index = (int) reader.getSigned(DataType.SHORT, DataTransformation.ADD);
|
||||
int spellId = (int) reader.getSigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT, DataTransformation.ADD);
|
||||
int spell = (int) reader.getUnsigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
|
||||
return new MagicOnPlayerMessage(index, spellId);
|
||||
}
|
||||
return new MagicOnPlayerMessage(index, spell);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,26 +7,25 @@ import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.MouseClickedMessage}
|
||||
* A {@link MessageDecoder} for the {@link MouseClickedMessage}
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class MouseClickedMessageDecoder extends MessageDecoder<MouseClickedMessage> {
|
||||
|
||||
@Override
|
||||
public MouseClickedMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int value = (int)reader.getUnsigned(DataType.INT);
|
||||
@Override
|
||||
public MouseClickedMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int value = (int) reader.getUnsigned(DataType.INT);
|
||||
|
||||
long delay = (value >> 20) * 50;
|
||||
long delay = (value >> 20) * 50;
|
||||
boolean right = ((value >> 19) & 0x1) == 1;
|
||||
|
||||
boolean rightMouseButton = ((value >> 19) & 0x1) == 1;
|
||||
int cords = (value & 0x3FFFF);
|
||||
int x = cords % 765;
|
||||
int y = cords / 765;
|
||||
|
||||
int cords = (value & 0x3FFFF);
|
||||
int x = cords % 765;
|
||||
int y = cords / 765;
|
||||
|
||||
return new MouseClickedMessage(delay, rightMouseButton, x, y);
|
||||
}
|
||||
return new MouseClickedMessage(delay, right, x, y);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.apollo.game.message.impl.DisplayTabInterfaceMessage;
|
||||
import org.apollo.game.message.impl.EnterAmountMessage;
|
||||
import org.apollo.game.message.impl.ForwardPrivateChatMessage;
|
||||
import org.apollo.game.message.impl.FriendServerStatusMessage;
|
||||
import org.apollo.game.message.impl.HintIconMessage;
|
||||
import org.apollo.game.message.impl.IdAssignmentMessage;
|
||||
import org.apollo.game.message.impl.IgnoreListMessage;
|
||||
import org.apollo.game.message.impl.LogoutMessage;
|
||||
@@ -126,11 +127,11 @@ public final class Release317 extends Release {
|
||||
|
||||
register(53, new ItemOnItemMessageDecoder());
|
||||
register(237, new MagicOnItemMessageDecoder());
|
||||
register(249, new MagicOnPlayerMessageDecoder());
|
||||
register(249, new MagicOnPlayerMessageDecoder());
|
||||
|
||||
register(3, new FocusUpdateMessageDecoder());
|
||||
register(45, new FlaggedMouseEventMessageDecoder());
|
||||
register(241, new MouseClickedMessageDecoder());
|
||||
register(241, new MouseClickedMessageDecoder());
|
||||
register(86, new ArrowKeyMessageDecoder());
|
||||
register(95, new PrivacyOptionMessageDecoder());
|
||||
|
||||
@@ -145,11 +146,11 @@ public final class Release317 extends Release {
|
||||
|
||||
register(155, new FirstNpcActionMessageDecoder());
|
||||
register(72, new SecondNpcActionMessageDecoder());
|
||||
register(17, new ThirdNpcActionMessageDecoder());
|
||||
register(17, new ThirdNpcActionMessageDecoder());
|
||||
register(21, new FourthNpcActionMessageDecoder());
|
||||
register(18, new FifthNpcActionMessageDecoder());
|
||||
register(18, new FifthNpcActionMessageDecoder());
|
||||
|
||||
register(236, new TakeTileItemMessageDecoder());
|
||||
register(236, new TakeTileItemMessageDecoder());
|
||||
register(192, new ItemOnObjectMessageDecoder());
|
||||
|
||||
register(128, new FirstPlayerActionMessageDecoder());
|
||||
@@ -205,6 +206,6 @@ public final class Release317 extends Release {
|
||||
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
|
||||
register(IgnoreListMessage.class, new IgnoreListMessageEncoder());
|
||||
register(SendFriendMessage.class, new SendFriendMessageEncoder());
|
||||
register(HintIconMessage.class, new HintIconMessageEncoder());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.FifthNpcActionMessage}.
|
||||
* A {@link MessageDecoder} for the {@link FifthNpcActionMessage}.
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
@@ -17,7 +17,7 @@ public final class FifthNpcActionMessageDecoder extends MessageDecoder<FifthNpcA
|
||||
@Override
|
||||
public FifthNpcActionMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int index = (int) reader.getSigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
return new FifthNpcActionMessage(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.FourthNpcActionMessage}.
|
||||
* A {@link MessageDecoder} for the {@link FourthNpcActionMessage}.
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
@@ -16,7 +16,7 @@ public final class FourthNpcActionMessageDecoder extends MessageDecoder<FourthNp
|
||||
@Override
|
||||
public FourthNpcActionMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int index = (int) reader.getSigned(DataType.SHORT);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT);
|
||||
return new FourthNpcActionMessage(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.apollo.net.release.r377;
|
||||
|
||||
import org.apollo.game.message.impl.HintIconMessage;
|
||||
import org.apollo.net.codec.game.DataType;
|
||||
import org.apollo.net.codec.game.GamePacket;
|
||||
import org.apollo.net.codec.game.GamePacketBuilder;
|
||||
import org.apollo.net.release.MessageEncoder;
|
||||
|
||||
/**
|
||||
* A {@link MessageEncoder} for the {@link HintIconMessage}.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public final class HintIconMessageEncoder extends MessageEncoder<HintIconMessage> {
|
||||
|
||||
@Override
|
||||
public GamePacket encode(HintIconMessage message) {
|
||||
GamePacketBuilder builder = new GamePacketBuilder(199);
|
||||
int type = message.getType();
|
||||
builder.put(DataType.BYTE, type);
|
||||
|
||||
switch (type) {
|
||||
case HintIconMessage.NPC_TYPE:
|
||||
case HintIconMessage.PLAYER_TYPE:
|
||||
builder.put(DataType.SHORT, message.getIndex().get());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported hint icon type " + type + ".");
|
||||
}
|
||||
|
||||
return builder.toGamePacket();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
package org.apollo.net.release.r377;
|
||||
|
||||
import org.apollo.game.message.impl.MagicOnNpcMessage;
|
||||
import org.apollo.net.codec.game.*;
|
||||
import org.apollo.net.codec.game.DataOrder;
|
||||
import org.apollo.net.codec.game.DataTransformation;
|
||||
import org.apollo.net.codec.game.DataType;
|
||||
import org.apollo.net.codec.game.GamePacket;
|
||||
import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.MagicOnNpcMessage}
|
||||
* A {@link MessageDecoder} for the {@link MagicOnNpcMessage}
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
@@ -15,10 +19,10 @@ public final class MagicOnNpcMessageDecoder extends MessageDecoder<MagicOnNpcMes
|
||||
public MagicOnNpcMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
|
||||
int index = (int) reader.getSigned(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD);
|
||||
int spellId = (int) reader.getSigned(DataType.SHORT, DataTransformation.ADD);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD);
|
||||
int spell = (int) reader.getUnsigned(DataType.SHORT, DataTransformation.ADD);
|
||||
|
||||
return new MagicOnNpcMessage(index, spellId);
|
||||
return new MagicOnNpcMessage(index, spell);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +1,28 @@
|
||||
package org.apollo.net.release.r377;
|
||||
|
||||
import org.apollo.game.message.impl.MagicOnPlayerMessage;
|
||||
import org.apollo.net.codec.game.*;
|
||||
import org.apollo.net.codec.game.DataOrder;
|
||||
import org.apollo.net.codec.game.DataTransformation;
|
||||
import org.apollo.net.codec.game.DataType;
|
||||
import org.apollo.net.codec.game.GamePacket;
|
||||
import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.MagicOnPlayerMessage}
|
||||
* A {@link MessageDecoder} for the {@link MagicOnPlayerMessage}
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class MagicOnPlayerMessageDecoder extends MessageDecoder<MagicOnPlayerMessage> {
|
||||
|
||||
@Override
|
||||
public MagicOnPlayerMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
@Override
|
||||
public MagicOnPlayerMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
|
||||
int index = (int) reader.getSigned(DataType.SHORT, DataTransformation.ADD);
|
||||
int spellId = (int) reader.getSigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
int index = (int) reader.getUnsigned(DataType.SHORT, DataTransformation.ADD);
|
||||
int spell = (int) reader.getUnsigned(DataType.SHORT, DataOrder.LITTLE);
|
||||
|
||||
return new MagicOnPlayerMessage(index, spellId);
|
||||
}
|
||||
return new MagicOnPlayerMessage(index, spell);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,26 +7,25 @@ import org.apollo.net.codec.game.GamePacketReader;
|
||||
import org.apollo.net.release.MessageDecoder;
|
||||
|
||||
/**
|
||||
* A {@link org.apollo.net.release.MessageDecoder} for the {@link org.apollo.game.message.impl.MouseClickedMessage}
|
||||
* A {@link MessageDecoder} for the {@link MouseClickedMessage}
|
||||
*
|
||||
* @author Stuart
|
||||
*/
|
||||
public final class MouseClickedMessageDecoder extends MessageDecoder<MouseClickedMessage> {
|
||||
|
||||
@Override
|
||||
public MouseClickedMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int value = (int)reader.getUnsigned(DataType.INT);
|
||||
@Override
|
||||
public MouseClickedMessage decode(GamePacket packet) {
|
||||
GamePacketReader reader = new GamePacketReader(packet);
|
||||
int value = (int) reader.getUnsigned(DataType.INT);
|
||||
|
||||
long delay = (value >> 20) * 50;
|
||||
long delay = (value >> 20) * 50;
|
||||
boolean right = ((value >> 19) & 0x1) == 1;
|
||||
|
||||
boolean rightMouseButton = ((value >> 19) & 0x1) == 1;
|
||||
int cords = (value & 0x3FFFF);
|
||||
int x = cords % 765;
|
||||
int y = cords / 765;
|
||||
|
||||
int cords = (value & 0x3FFFF);
|
||||
int x = cords % 765;
|
||||
int y = cords / 765;
|
||||
|
||||
return new MouseClickedMessage(delay, rightMouseButton, x, y);
|
||||
}
|
||||
return new MouseClickedMessage(delay, right, x, y);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.apollo.game.message.impl.DisplayTabInterfaceMessage;
|
||||
import org.apollo.game.message.impl.EnterAmountMessage;
|
||||
import org.apollo.game.message.impl.ForwardPrivateChatMessage;
|
||||
import org.apollo.game.message.impl.FriendServerStatusMessage;
|
||||
import org.apollo.game.message.impl.HintIconMessage;
|
||||
import org.apollo.game.message.impl.IdAssignmentMessage;
|
||||
import org.apollo.game.message.impl.IgnoreListMessage;
|
||||
import org.apollo.game.message.impl.LogoutMessage;
|
||||
@@ -19,8 +20,8 @@ import org.apollo.game.message.impl.OpenInterfaceSidebarMessage;
|
||||
import org.apollo.game.message.impl.PlayerSynchronizationMessage;
|
||||
import org.apollo.game.message.impl.PositionMessage;
|
||||
import org.apollo.game.message.impl.PrivacyOptionMessage;
|
||||
import org.apollo.game.message.impl.SectorChangeMessage;
|
||||
import org.apollo.game.message.impl.RemoveTileItemMessage;
|
||||
import org.apollo.game.message.impl.SectorChangeMessage;
|
||||
import org.apollo.game.message.impl.SendFriendMessage;
|
||||
import org.apollo.game.message.impl.SendObjectMessage;
|
||||
import org.apollo.game.message.impl.ServerChatMessage;
|
||||
@@ -40,6 +41,7 @@ import org.apollo.game.message.impl.UpdateTileItemMessage;
|
||||
import org.apollo.game.message.impl.UpdateWeightMessage;
|
||||
import org.apollo.net.meta.PacketMetaDataGroup;
|
||||
import org.apollo.net.release.Release;
|
||||
import org.apollo.net.release.r317.HintIconMessageEncoder;
|
||||
|
||||
/**
|
||||
* A {@link Release} implementation for the 377 protocol.
|
||||
@@ -130,7 +132,7 @@ public final class Release377 extends Release {
|
||||
register(104, new MagicOnNpcMessageDecoder());
|
||||
|
||||
register(187, new FocusUpdateMessageDecoder());
|
||||
register(19, new MouseClickedMessageDecoder());
|
||||
register(19, new MouseClickedMessageDecoder());
|
||||
register(171, new FlaggedMouseEventMessageDecoder());
|
||||
register(140, new ArrowKeyMessageDecoder());
|
||||
register(176, new PrivacyOptionMessageDecoder());
|
||||
@@ -201,6 +203,7 @@ public final class Release377 extends Release {
|
||||
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
|
||||
register(IgnoreListMessage.class, new IgnoreListMessageEncoder());
|
||||
register(SendFriendMessage.class, new SendFriendMessageEncoder());
|
||||
register(HintIconMessage.class, new HintIconMessageEncoder());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user