mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-07 16:49:12 +00:00
Add half-done grouped region frame stuff so Ryley can take a look. This is in master because I'm an idiot.
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
java_import 'org.apollo.game.model.Direction'
|
require 'set'
|
||||||
|
|
||||||
|
# Contains door-related constants.
|
||||||
module DoorConstants
|
module DoorConstants
|
||||||
|
|
||||||
# TODO: GameObjectOrientation enumeration in Apollo's core?
|
# TODO: GameObjectOrientation enumeration in Apollo's core?
|
||||||
module Orientation
|
module Orientation
|
||||||
WEST = 0
|
WEST = 0
|
||||||
@@ -9,17 +11,18 @@ module DoorConstants
|
|||||||
SOUTH = 3
|
SOUTH = 3
|
||||||
end
|
end
|
||||||
|
|
||||||
# The object size of a door.
|
# The size of a door object.
|
||||||
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_SIDE_HINGE_DOOR_IDS = [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_SIDE_HINGE_DOOR_IDS = [1519, 1530, 4465, 4467, 3014, 3017, 3018, 3019]
|
RIGHT_HINGE_DOORS = Set.new [ 1519, 1530, 4465, 4467, 3014, 3017, 3018, 3019 ]
|
||||||
|
|
||||||
# A map 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,
|
||||||
@@ -27,6 +30,7 @@ module DoorConstants
|
|||||||
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,
|
||||||
@@ -35,4 +39,5 @@ module DoorConstants
|
|||||||
Orientation::EAST => Orientation::SOUTH
|
Orientation::EAST => Orientation::SOUTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -4,28 +4,30 @@ java_import 'org.apollo.game.action.DistancedAction'
|
|||||||
class OpenDoorAction < DistancedAction
|
class OpenDoorAction < DistancedAction
|
||||||
include DoorConstants
|
include DoorConstants
|
||||||
|
|
||||||
attr_reader :door_object
|
attr_reader :door
|
||||||
|
|
||||||
def initialize(mob, door_object)
|
def initialize(mob, door)
|
||||||
super(0, true, mob, door_object.position, DOOR_SIZE)
|
super(0, true, mob, door.position, DOOR_SIZE)
|
||||||
@door_object = door_object
|
@door = door
|
||||||
end
|
end
|
||||||
|
|
||||||
def executeAction
|
def executeAction
|
||||||
mob.turn_to @door_object.position
|
mob.turn_to(@door.position)
|
||||||
DoorUtil::toggle(@door_object, mob)
|
DoorUtil::toggle(@door, mob)
|
||||||
stop
|
stop
|
||||||
end
|
end
|
||||||
|
|
||||||
def equals(other)
|
def equals(other)
|
||||||
return (get_class == other.get_class && @door_object == other.door_object)
|
return (get_class == other.get_class && @door_object == other.door_object)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Message handler for opening and closing doors.
|
# Message handler for opening and closing doors.
|
||||||
on :message, :first_object_action do |ctx, player, message|
|
on :message, :first_object_action do |ctx, player, message|
|
||||||
if DoorUtil::is_door?(message.id)
|
if DoorUtil::is_door?(message.id)
|
||||||
door_object = DoorUtil::get_door_object(message.position, message.id)
|
puts "Player: #{player.position}, door: #{message.position}"
|
||||||
player.start_action(OpenDoorAction.new(player, door_object)) unless door_object.nil?
|
door = DoorUtil::get_door_object(message.position, message.id)
|
||||||
|
player.start_action(OpenDoorAction.new(player, door)) unless door.nil?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
java_import 'org.apollo.game.model.entity.GameObject'
|
require 'java'
|
||||||
java_import 'org.apollo.game.model.entity.Entity'
|
|
||||||
java_import 'org.apollo.game.model.Position'
|
|
||||||
java_import 'org.apollo.game.message.impl.PositionMessage'
|
|
||||||
java_import 'org.apollo.game.message.impl.RemoveObjectMessage'
|
|
||||||
java_import 'org.apollo.game.message.impl.SendObjectMessage'
|
|
||||||
|
|
||||||
|
java_import 'org.apollo.game.model.Position'
|
||||||
|
java_import 'org.apollo.game.model.area.Region'
|
||||||
|
java_import 'org.apollo.game.model.entity.Entity'
|
||||||
|
java_import 'org.apollo.game.model.entity.obj.DynamicGameObject'
|
||||||
|
|
||||||
|
# Contains door-related utility methods.
|
||||||
module DoorUtil
|
module DoorUtil
|
||||||
include DoorConstants
|
include DoorConstants
|
||||||
|
|
||||||
# A hash containing currently toggled door objects mapped to the original door objects.
|
# A hash containing currently toggled door objects mapped to the original door objects.
|
||||||
TOGGLED_DOOR_REPOSITORY = {}
|
TOGGLED_DOORS = {}
|
||||||
|
|
||||||
# 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
|
orientation = door.orientation
|
||||||
|
|
||||||
case orientation
|
case orientation
|
||||||
when Orientation::WEST
|
when Orientation::WEST
|
||||||
return Position.new(position.x - 1, position.y, position.height)
|
return Position.new(position.x - 1, position.y, position.height)
|
||||||
@@ -25,6 +27,7 @@ module DoorUtil
|
|||||||
when Orientation::SOUTH
|
when Orientation::SOUTH
|
||||||
return Position.new(position.x, position.y - 1, position.height)
|
return Position.new(position.x, position.y - 1, position.height)
|
||||||
end
|
end
|
||||||
|
|
||||||
raise 'Invalid orientation for door!'
|
raise 'Invalid orientation for door!'
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -32,68 +35,49 @@ module DoorUtil
|
|||||||
def self.translate_door_orientation(door)
|
def self.translate_door_orientation(door)
|
||||||
object_id = door.id
|
object_id = door.id
|
||||||
orientation = door.orientation
|
orientation = door.orientation
|
||||||
if RIGHT_SIDE_HINGE_DOOR_IDS.include?(object_id)
|
|
||||||
|
if RIGHT_HINGE_DOORS.include?(object_id)
|
||||||
return ORIENTATIONS[:right_side_hinge][orientation]
|
return ORIENTATIONS[:right_side_hinge][orientation]
|
||||||
elsif LEFT_SIDE_HINGE_DOOR_IDS.include?(object_id)
|
elsif LEFT_HINGE_DOORS.include?(object_id)
|
||||||
return ORIENTATIONS[:left_side_hinge][orientation]
|
return ORIENTATIONS[:left_side_hinge][orientation]
|
||||||
end
|
end
|
||||||
raise 'Given object was not registered as a door!'
|
|
||||||
end
|
|
||||||
|
|
||||||
# Replaces a door object for a given player.
|
raise 'Given object was not registered as a door.'
|
||||||
# TODO: This is temporary.
|
|
||||||
def self.replace_door(player, original, new)
|
|
||||||
player.send PositionMessage.new(player.last_known_region, original.position)
|
|
||||||
player.send RemoveObjectMessage.new(original)
|
|
||||||
player.send PositionMessage.new(player.last_known_region, new.position)
|
|
||||||
player.send SendObjectMessage.new(new)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Toggles the given door.
|
# Toggles the given door.
|
||||||
def self.toggle(door, player)
|
def self.toggle(door, player)
|
||||||
# First, we remove the door we're toggling (or un-toggling) from the game world.
|
|
||||||
position = door.position
|
position = door.position
|
||||||
region = $world.region_repository.from_position(position)
|
region = $world.region_repository.from_position(position)
|
||||||
region.remove_entity door
|
region.remove_entity(door)
|
||||||
|
|
||||||
# Have we toggled this door already?
|
if TOGGLED_DOORS.include?(door)
|
||||||
if TOGGLED_DOOR_REPOSITORY.include?(door)
|
original_door = TOGGLED_DOORS.delete(door)
|
||||||
# If we have, we get our original door. This also deletes the entry from our repository.
|
|
||||||
original_door = TOGGLED_DOOR_REPOSITORY.delete(door)
|
|
||||||
|
|
||||||
# Now we add our new door to the game world.
|
|
||||||
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)
|
||||||
|
|
||||||
# TODO: This and the 'player' parameter are temporary. We still need to synchronize objects for local players.
|
|
||||||
replace_door player, door, original_door
|
|
||||||
else
|
else
|
||||||
# If not, we get the translated orientation and position for this door, and create a new game object.
|
|
||||||
toggled_position = translate_door_position(door)
|
toggled_position = translate_door_position(door)
|
||||||
toggled_orientation = translate_door_orientation(door)
|
toggled_orientation = translate_door_orientation(door)
|
||||||
toggled_door = GameObject.new(door.id, toggled_position, door.type, toggled_orientation)
|
toggled_door = DynamicGameObject.createPublic(door.id, toggled_position, door.type, toggled_orientation)
|
||||||
|
|
||||||
# Now we add our new door to the game world.
|
|
||||||
toggled_region = $world.region_repository.from_position(toggled_position)
|
toggled_region = $world.region_repository.from_position(toggled_position)
|
||||||
toggled_region.add_entity toggled_door
|
toggled_region.add_entity(toggled_door)
|
||||||
|
|
||||||
# Insert our toggled door in the repository.
|
TOGGLED_DOORS[toggled_door] = door
|
||||||
TOGGLED_DOOR_REPOSITORY[toggled_door] = door
|
|
||||||
|
|
||||||
# TODO: This and the 'player' parameter are temporary. We still need to synchronize objects for local players.
|
|
||||||
replace_door player, door, toggled_door
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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::GAME_OBJECT)
|
game_objects = $world.region_repository.from_position(position).get_entities(position, EntityType::DYNAMIC_OBJECT, EntityType::STATIC_OBJECT)
|
||||||
game_objects.each { |game_object| return game_object if game_object.id == object_id }
|
game_objects.each { |game_object| return game_object if game_object.id == object_id }
|
||||||
return nil
|
return 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.is_door?(object_id)
|
||||||
RIGHT_SIDE_HINGE_DOOR_IDS.include?(object_id) || LEFT_SIDE_HINGE_DOOR_IDS.include?(object_id)
|
RIGHT_HINGE_DOORS.include?(object_id) || LEFT_HINGE_DOORS.include?(object_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -14,9 +14,10 @@ import org.apollo.game.model.Position;
|
|||||||
import org.apollo.game.model.area.Region;
|
import org.apollo.game.model.area.Region;
|
||||||
import org.apollo.game.model.area.RegionRepository;
|
import org.apollo.game.model.area.RegionRepository;
|
||||||
import org.apollo.game.model.area.collision.CollisionMatrix;
|
import org.apollo.game.model.area.collision.CollisionMatrix;
|
||||||
import org.apollo.game.model.area.obj.ObjectType;
|
|
||||||
import org.apollo.game.model.def.ObjectDefinition;
|
import org.apollo.game.model.def.ObjectDefinition;
|
||||||
import org.apollo.game.model.entity.GameObject;
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
|
import org.apollo.game.model.entity.obj.ObjectType;
|
||||||
|
import org.apollo.game.model.entity.obj.StaticGameObject;
|
||||||
import org.apollo.util.BufferUtil;
|
import org.apollo.util.BufferUtil;
|
||||||
import org.apollo.util.CompressionUtil;
|
import org.apollo.util.CompressionUtil;
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ public final class GameObjectDecoder {
|
|||||||
if (block) {
|
if (block) {
|
||||||
for (int dx = 0; dx < definition.getWidth(); dx++) {
|
for (int dx = 0; dx < definition.getWidth(); dx++) {
|
||||||
for (int dy = 0; dy < definition.getLength(); dy++) {
|
for (int dy = 0; dy < definition.getLength(); dy++) {
|
||||||
int localX = (x % Region.REGION_SIZE) + dx, localY = (y % Region.REGION_SIZE) + dy;
|
int localX = (x % Region.SIZE) + dx, localY = (y % Region.SIZE) + dy;
|
||||||
|
|
||||||
if (localX > 7 || localY > 7) {
|
if (localX > 7 || localY > 7) {
|
||||||
int nextLocalX = localX > 7 ? x + localX - 7 : x + localX;
|
int nextLocalX = localX > 7 ? x + localX - 7 : x + localX;
|
||||||
@@ -140,8 +141,7 @@ public final class GameObjectDecoder {
|
|||||||
Position nextPosition = new Position(nextLocalX, nextLocalY);
|
Position nextPosition = new Position(nextLocalX, nextLocalY);
|
||||||
Region next = regions.fromPosition(nextPosition);
|
Region next = regions.fromPosition(nextPosition);
|
||||||
|
|
||||||
int nextX = (nextPosition.getX() % Region.REGION_SIZE) + dx, nextY = (nextPosition.getY() % Region.REGION_SIZE)
|
int nextX = (nextPosition.getX() % Region.SIZE) + dx, nextY = (nextPosition.getY() % Region.SIZE) + dy;
|
||||||
+ dy;
|
|
||||||
if (nextX > 7)
|
if (nextX > 7)
|
||||||
nextX -= 7;
|
nextX -= 7;
|
||||||
if (nextY > 7)
|
if (nextY > 7)
|
||||||
@@ -181,7 +181,7 @@ public final class GameObjectDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (block) {
|
if (block) {
|
||||||
int localX = (x % Region.REGION_SIZE), localY = (y % Region.REGION_SIZE);
|
int localX = (x % Region.SIZE), localY = (y % Region.SIZE);
|
||||||
current.block(localX, localY);
|
current.block(localX, localY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ public final class GameObjectDecoder {
|
|||||||
int orientation = attributes & 0x3;
|
int orientation = attributes & 0x3;
|
||||||
Position position = new Position(x + localX, y + localY, height);
|
Position position = new Position(x + localX, y + localY, height);
|
||||||
|
|
||||||
GameObject object = new GameObject(id, position, type, orientation);
|
GameObject object = new StaticGameObject(id, position, type, orientation);
|
||||||
objects.add(object);
|
objects.add(object);
|
||||||
|
|
||||||
block(object, position);
|
block(object, position);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public final class MapFileDecoder {
|
|||||||
/**
|
/**
|
||||||
* The width (and length) of a map file, in tiles.
|
* The width (and length) of a map file, in tiles.
|
||||||
*/
|
*/
|
||||||
public static final int MAP_FILE_WIDTH = Region.REGION_SIZE * Region.REGION_SIZE;
|
public static final int MAP_FILE_WIDTH = Region.SIZE * Region.SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The file id of the versions archive.
|
* The file id of the versions archive.
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.apollo.Service;
|
|||||||
import org.apollo.game.message.handler.MessageHandlerChainGroup;
|
import org.apollo.game.message.handler.MessageHandlerChainGroup;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
import org.apollo.game.model.World.RegistrationStatus;
|
import org.apollo.game.model.World.RegistrationStatus;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
import org.apollo.game.model.entity.Player;
|
import org.apollo.game.model.entity.Player;
|
||||||
import org.apollo.game.sync.ClientSynchronizer;
|
import org.apollo.game.sync.ClientSynchronizer;
|
||||||
import org.apollo.io.MessageHandlerChainParser;
|
import org.apollo.io.MessageHandlerChainParser;
|
||||||
@@ -49,7 +50,8 @@ public final class GameService extends Service {
|
|||||||
/**
|
/**
|
||||||
* The scheduled executor service.
|
* The scheduled executor service.
|
||||||
*/
|
*/
|
||||||
private final ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("GameService"));
|
private final ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory(
|
||||||
|
"GameService"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ClientSynchronizer}.
|
* The {@link ClientSynchronizer}.
|
||||||
@@ -154,10 +156,15 @@ public final class GameService extends Service {
|
|||||||
* @return A {@link RegistrationStatus}.
|
* @return A {@link RegistrationStatus}.
|
||||||
*/
|
*/
|
||||||
public RegistrationStatus registerPlayer(Player player, GameSession session) {
|
public RegistrationStatus registerPlayer(Player player, GameSession session) {
|
||||||
|
World world = World.getWorld();
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
RegistrationStatus status = World.getWorld().register(player);
|
RegistrationStatus status = world.register(player);
|
||||||
if (status == RegistrationStatus.OK) {
|
if (status == RegistrationStatus.OK) {
|
||||||
player.setSession(session);
|
player.setSession(session);
|
||||||
|
|
||||||
|
Region region = world.getRegionRepository().get(player.getPosition().getRegionCoordinates());
|
||||||
|
region.addEntity(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -169,7 +176,8 @@ public final class GameService extends Service {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
scheduledExecutor.scheduleAtFixedRate(new GamePulseHandler(this), GameConstants.PULSE_DELAY, GameConstants.PULSE_DELAY, TimeUnit.MILLISECONDS);
|
scheduledExecutor.scheduleAtFixedRate(new GamePulseHandler(this), GameConstants.PULSE_DELAY, GameConstants.PULSE_DELAY,
|
||||||
|
TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import org.apollo.game.model.area.Region;
|
|||||||
import org.apollo.game.model.area.RegionRepository;
|
import org.apollo.game.model.area.RegionRepository;
|
||||||
import org.apollo.game.model.def.ObjectDefinition;
|
import org.apollo.game.model.def.ObjectDefinition;
|
||||||
import org.apollo.game.model.entity.Entity.EntityType;
|
import org.apollo.game.model.entity.Entity.EntityType;
|
||||||
import org.apollo.game.model.entity.GameObject;
|
|
||||||
import org.apollo.game.model.entity.Player;
|
import org.apollo.game.model.entity.Player;
|
||||||
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A verification {@link MessageHandler} for the {@link ObjectActionMessage}.
|
* A verification {@link MessageHandler} for the {@link ObjectActionMessage}.
|
||||||
@@ -35,9 +35,10 @@ public final class ObjectActionVerificationHandler extends MessageHandler<Object
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Position position = message.getPosition();
|
Position position = message.getPosition();
|
||||||
Region region = repository.fromPosition(position);
|
Region region = repository.fromPosition(position);
|
||||||
Set<GameObject> objects = region.getEntities(position, EntityType.GAME_OBJECT);
|
Set<GameObject> objects = region.getEntities(position, EntityType.STATIC_OBJECT, EntityType.DYNAMIC_OBJECT);
|
||||||
|
|
||||||
if (!player.getPosition().isWithinDistance(position, 15) || !containsObject(id, objects)) {
|
if (!player.getPosition().isWithinDistance(position, 15) || !containsObject(id, objects)) {
|
||||||
ctx.breakHandlerChain();
|
ctx.breakHandlerChain();
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ public final class WalkMessageHandler extends MessageHandler<WalkMessage> {
|
|||||||
WalkingQueue queue = player.getWalkingQueue();
|
WalkingQueue queue = player.getWalkingQueue();
|
||||||
|
|
||||||
Position[] steps = message.getSteps();
|
Position[] steps = message.getSteps();
|
||||||
for (int i = 0; i < steps.length; i++) {
|
for (int index = 0; index < steps.length; index++) {
|
||||||
Position step = steps[i];
|
Position step = steps[index];
|
||||||
if (i == 0) {
|
if (index == 0) {
|
||||||
if (!queue.addFirstStep(step)) {
|
if (!queue.addFirstStep(step)) {
|
||||||
return; // ignore packet
|
return; // ignore packet
|
||||||
}
|
}
|
||||||
@@ -31,16 +31,15 @@ public final class WalkMessageHandler extends MessageHandler<WalkMessage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
queue.setRunningQueue(message.isRunning() || player.isRunning());
|
queue.setRunningQueue(message.isRunning() || player.isRunning());
|
||||||
|
player.getInterfaceSet().close();
|
||||||
|
|
||||||
if (queue.size() > 0) {
|
if (queue.size() > 0) {
|
||||||
player.stopAction();
|
player.stopAction();
|
||||||
}
|
}
|
||||||
player.getInterfaceSet().close();
|
|
||||||
|
|
||||||
if (player.getInteractingMob() != null) {
|
if (player.getInteractingMob() != null) {
|
||||||
player.resetInteractingMob();
|
player.resetInteractingMob();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package org.apollo.game.message.impl;
|
||||||
|
|
||||||
|
import org.apollo.game.message.Message;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Message} sent to the client to remove all spawned objects and items from a Region.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class ClearRegionMessage extends Message {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Position of the Player.
|
||||||
|
*/
|
||||||
|
private final Position player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Position in the Region being cleared.
|
||||||
|
*/
|
||||||
|
private final Position region;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the ClearRegionMessage.
|
||||||
|
*
|
||||||
|
* @param player The {@link Position} of the Player this {@link Message} is being sent to.
|
||||||
|
* @param region The {@link RegionCoordinates} of the Region being cleared.
|
||||||
|
*/
|
||||||
|
public ClearRegionMessage(Position player, RegionCoordinates region) {
|
||||||
|
this.player = player;
|
||||||
|
this.region = new Position(region.getAbsoluteX(), region.getAbsoluteY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Position} of the Player this {@link Message} is being sent to..
|
||||||
|
*
|
||||||
|
* @return The Position.
|
||||||
|
*/
|
||||||
|
public Position getPlayerPosition() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Position} of the Region being cleared.
|
||||||
|
*
|
||||||
|
* @return The Position.
|
||||||
|
*/
|
||||||
|
public Position getRegionPosition() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package org.apollo.game.message.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apollo.game.message.Message;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Message} sent to the client that contains multiple
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class GroupedRegionUpdateMessage extends Message {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Position of the Player.
|
||||||
|
*/
|
||||||
|
private final Position player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Position of the Region being updated.
|
||||||
|
*/
|
||||||
|
private final Position region;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The List of RegionUpdateMessages to be sent.
|
||||||
|
*/
|
||||||
|
private final List<RegionUpdateMessage> messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the GroupedRegionUpdateMessage.
|
||||||
|
*
|
||||||
|
* @param player The {@link Position} of the Player.
|
||||||
|
* @param coordinates The {@link RegionCoordinates} of the Region being updated.
|
||||||
|
* @param messages The {@link List} of {@link RegionUpdateMessage}s.
|
||||||
|
*/
|
||||||
|
public GroupedRegionUpdateMessage(Position player, RegionCoordinates coordinates, List<RegionUpdateMessage> messages) {
|
||||||
|
this.player = player;
|
||||||
|
this.region = new Position(coordinates.getAbsoluteX(), coordinates.getAbsoluteY());
|
||||||
|
this.messages = messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Position} of the Player.
|
||||||
|
*
|
||||||
|
* @return The Position.
|
||||||
|
*/
|
||||||
|
public Position getPlayerPosition() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link List} of {@link RegionUpdateMessage}s.
|
||||||
|
*
|
||||||
|
* @return The Collection.
|
||||||
|
*/
|
||||||
|
public List<RegionUpdateMessage> getMessages() {
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Position} of the Region these updates affect.
|
||||||
|
*
|
||||||
|
* @return The Position.
|
||||||
|
*/
|
||||||
|
public Position getRegionPosition() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package org.apollo.game.message.impl;
|
|
||||||
|
|
||||||
import org.apollo.game.message.Message;
|
|
||||||
import org.apollo.game.model.Position;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link Message} sent to the client to focus on a specific {@link Position} (on which an action should be
|
|
||||||
* performed).
|
|
||||||
*
|
|
||||||
* @author Chris Fletcher
|
|
||||||
*/
|
|
||||||
public final class PositionMessage extends Message {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The base position.
|
|
||||||
*/
|
|
||||||
private final Position base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The target position.
|
|
||||||
*/
|
|
||||||
private final Position position;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new position message.
|
|
||||||
*
|
|
||||||
* @param base The base from which the position is being focused on.
|
|
||||||
* @param position The position to focus on.
|
|
||||||
*/
|
|
||||||
public PositionMessage(Position base, Position position) {
|
|
||||||
this.base = base;
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the base position.
|
|
||||||
*
|
|
||||||
* @return The position.
|
|
||||||
*/
|
|
||||||
public Position getBase() {
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the position to focus on.
|
|
||||||
*
|
|
||||||
* @return The target position.
|
|
||||||
*/
|
|
||||||
public Position getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package org.apollo.game.message.impl;
|
||||||
|
|
||||||
|
import org.apollo.game.message.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Message} that can be grouped with other Messages as part of a {@link GroupedRegionUpdateMessage}.
|
||||||
|
* <p>
|
||||||
|
* This is a utility class for Messages that can be grouped, as is not encoded directly.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public abstract class RegionUpdateMessage extends Message implements Comparable<RegionUpdateMessage> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The integer value indicating this RegionUpdateMessage is a high-priority message.
|
||||||
|
*/
|
||||||
|
protected static final int HIGH_PRIORITY = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The integer value indicating this RegionUpdateMessage is a low-priority message.
|
||||||
|
*/
|
||||||
|
protected static final int LOW_PRIORITY = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int compareTo(RegionUpdateMessage other) {
|
||||||
|
return Integer.compare(priority(), other.priority());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract boolean equals(Object obj);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract int hashCode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the priority of this RegionUpdateMessage, to use when sorting.
|
||||||
|
*
|
||||||
|
* @return The priority. Should be either 1 (low) or 0 (high).
|
||||||
|
*/
|
||||||
|
public abstract int priority();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package org.apollo.game.message.impl;
|
package org.apollo.game.message.impl;
|
||||||
|
|
||||||
import org.apollo.game.message.Message;
|
import org.apollo.game.message.Message;
|
||||||
import org.apollo.game.model.entity.GameObject;
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Message} sent to the client to remove an object from a tile.
|
* A {@link Message} sent to the client to remove an object from a tile.
|
||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class RemoveObjectMessage extends Message {
|
public final class RemoveObjectMessage extends RegionUpdateMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The orientation of the object.
|
* The orientation of the object.
|
||||||
@@ -29,16 +29,7 @@ public final class RemoveObjectMessage extends Message {
|
|||||||
* Creates the RemoveObjectMessage.
|
* Creates the RemoveObjectMessage.
|
||||||
*
|
*
|
||||||
* @param object The {@link GameObject} to send.
|
* @param object The {@link GameObject} to send.
|
||||||
*/
|
* @param positionOffset The offset of the GameObject's Position from the Region's top-left position.
|
||||||
public RemoveObjectMessage(GameObject object) {
|
|
||||||
this(object, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the RemoveObjectMessage.
|
|
||||||
*
|
|
||||||
* @param object The {@link GameObject} to send.
|
|
||||||
* @param positionOffset The offset of the object's position from the region's central position.
|
|
||||||
*/
|
*/
|
||||||
public RemoveObjectMessage(GameObject object, int positionOffset) {
|
public RemoveObjectMessage(GameObject object, int positionOffset) {
|
||||||
this.positionOffset = positionOffset;
|
this.positionOffset = positionOffset;
|
||||||
@@ -46,6 +37,16 @@ public final class RemoveObjectMessage extends Message {
|
|||||||
this.orientation = object.getOrientation();
|
this.orientation = object.getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof RemoveObjectMessage) {
|
||||||
|
RemoveObjectMessage other = (RemoveObjectMessage) obj;
|
||||||
|
return type == other.type && orientation == other.orientation && positionOffset == other.positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the orientation of the object.
|
* Gets the orientation of the object.
|
||||||
*
|
*
|
||||||
@@ -73,4 +74,16 @@ public final class RemoveObjectMessage extends Message {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = prime * positionOffset + orientation;
|
||||||
|
return prime * result + type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return HIGH_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
package org.apollo.game.message.impl;
|
package org.apollo.game.message.impl;
|
||||||
|
|
||||||
import org.apollo.game.message.Message;
|
import org.apollo.game.message.Message;
|
||||||
|
import org.apollo.game.model.Item;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Message} sent to the client to remove an item from a tile.
|
* A {@link Message} sent to the client to remove an item from a tile.
|
||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class RemoveTileItemMessage extends Message {
|
public final class RemoveTileItemMessage extends RegionUpdateMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item.
|
* The id of the Item to remove.
|
||||||
*/
|
*/
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
@@ -20,18 +21,9 @@ public final class RemoveTileItemMessage extends Message {
|
|||||||
private final int positionOffset;
|
private final int positionOffset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a remove tile item message.
|
* Creates the RemoveTileItemMessage.
|
||||||
*
|
*
|
||||||
* @param id The id of the item to remove.
|
* @param id The id of the {@link Item} to remove.
|
||||||
*/
|
|
||||||
public RemoveTileItemMessage(int id) {
|
|
||||||
this(id, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a remove tile item message.
|
|
||||||
*
|
|
||||||
* @param id The id of the item to remove.
|
|
||||||
* @param positionOffset The offset from the 'base' position.
|
* @param positionOffset The offset from the 'base' position.
|
||||||
*/
|
*/
|
||||||
public RemoveTileItemMessage(int id, int positionOffset) {
|
public RemoveTileItemMessage(int id, int positionOffset) {
|
||||||
@@ -39,6 +31,26 @@ public final class RemoveTileItemMessage extends Message {
|
|||||||
this.positionOffset = positionOffset;
|
this.positionOffset = positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the RemoveTileItemMessage.
|
||||||
|
*
|
||||||
|
* @param item The {@link Item} to remove.
|
||||||
|
* @param positionOffset The offset from the 'base' position.
|
||||||
|
*/
|
||||||
|
public RemoveTileItemMessage(Item item, int positionOffset) {
|
||||||
|
this(item.getId(), positionOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof RemoveTileItemMessage) {
|
||||||
|
RemoveTileItemMessage other = (RemoveTileItemMessage) obj;
|
||||||
|
return id == other.id && positionOffset == other.positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the id of the item to remove.
|
* Gets the id of the item to remove.
|
||||||
*
|
*
|
||||||
@@ -57,4 +69,15 @@ public final class RemoveTileItemMessage extends Message {
|
|||||||
return positionOffset;
|
return positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
return prime * id + positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return HIGH_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package org.apollo.game.message.impl;
|
package org.apollo.game.message.impl;
|
||||||
|
|
||||||
import org.apollo.game.message.Message;
|
import org.apollo.game.message.Message;
|
||||||
import org.apollo.game.model.entity.GameObject;
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Message} sent to the client to spawn an object.
|
* A {@link Message} sent to the client to spawn an object.
|
||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class SendObjectMessage extends Message {
|
public final class SendObjectMessage extends RegionUpdateMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the object.
|
* The id of the object.
|
||||||
@@ -30,15 +30,6 @@ public final class SendObjectMessage extends Message {
|
|||||||
*/
|
*/
|
||||||
private final int type;
|
private final int type;
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the SendObjectMessage.
|
|
||||||
*
|
|
||||||
* @param object The {@link GameObject} to send.
|
|
||||||
*/
|
|
||||||
public SendObjectMessage(GameObject object) {
|
|
||||||
this(object, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the SendObjectMessage.
|
* Creates the SendObjectMessage.
|
||||||
*
|
*
|
||||||
@@ -52,6 +43,20 @@ public final class SendObjectMessage extends Message {
|
|||||||
this.orientation = object.getOrientation();
|
this.orientation = object.getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof SendObjectMessage) {
|
||||||
|
SendObjectMessage other = (SendObjectMessage) obj;
|
||||||
|
if (id != other.id || type != other.type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return positionOffset == other.positionOffset && type == other.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the id of the object.
|
* Gets the id of the object.
|
||||||
*
|
*
|
||||||
@@ -88,4 +93,17 @@ public final class SendObjectMessage extends Message {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = prime * id + orientation;
|
||||||
|
result = prime * result + type;
|
||||||
|
return prime * result + positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return LOW_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+37
-25
@@ -8,7 +8,12 @@ import org.apollo.game.model.Item;
|
|||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class AddGlobalTileItemMessage extends Message {
|
public final class SendPublicTileItemMessage extends RegionUpdateMessage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the player who dropped the item.
|
||||||
|
*/
|
||||||
|
private final int index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item to add to the tile.
|
* The item to add to the tile.
|
||||||
@@ -21,40 +26,26 @@ public final class AddGlobalTileItemMessage extends Message {
|
|||||||
private final int positionOffset;
|
private final int positionOffset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index of the player who dropped the item.
|
* Creates the SendPublicTileItemMessage.
|
||||||
*/
|
|
||||||
private final int index;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the add global tile item message.
|
|
||||||
*
|
|
||||||
* @param item The item to add to the tile.
|
|
||||||
* @param index The index of the player who dropped the item.
|
|
||||||
*/
|
|
||||||
public AddGlobalTileItemMessage(Item item, int index) {
|
|
||||||
this(item, index, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the add global tile item message.
|
|
||||||
*
|
*
|
||||||
* @param item The item to add to the tile.
|
* @param item The item to add to the tile.
|
||||||
* @param index The index of the player who dropped the item.
|
* @param index The index of the player who dropped the item.
|
||||||
* @param positionOffset The offset from the 'base' position.
|
* @param positionOffset The offset from the 'base' position.
|
||||||
*/
|
*/
|
||||||
public AddGlobalTileItemMessage(Item item, int index, int positionOffset) {
|
public SendPublicTileItemMessage(Item item, int index, int positionOffset) {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.positionOffset = positionOffset;
|
this.positionOffset = positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Gets the id of the item.
|
public boolean equals(Object obj) {
|
||||||
*
|
if (obj instanceof SendPublicTileItemMessage) {
|
||||||
* @return The id.
|
SendPublicTileItemMessage other = (SendPublicTileItemMessage) obj;
|
||||||
*/
|
return item.equals(other.item) && index == other.index && positionOffset == other.positionOffset;
|
||||||
public int getId() {
|
}
|
||||||
return item.getId();
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +57,15 @@ public final class AddGlobalTileItemMessage extends Message {
|
|||||||
return item.getAmount();
|
return item.getAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the id of the item.
|
||||||
|
*
|
||||||
|
* @return The id.
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return item.getId();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the index of the player who dropped the item.
|
* Gets the index of the player who dropped the item.
|
||||||
*
|
*
|
||||||
@@ -84,4 +84,16 @@ public final class AddGlobalTileItemMessage extends Message {
|
|||||||
return positionOffset;
|
return positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = item.hashCode() * prime + index;
|
||||||
|
return result * prime + positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return LOW_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+24
-12
@@ -8,7 +8,7 @@ import org.apollo.game.model.Item;
|
|||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class AddTileItemMessage extends Message {
|
public final class SendTileItemMessage extends RegionUpdateMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item to add to the tile.
|
* The item to add to the tile.
|
||||||
@@ -21,21 +21,12 @@ public final class AddTileItemMessage extends Message {
|
|||||||
private final int positionOffset;
|
private final int positionOffset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an add tile item message.
|
* Creates the SendTileItemMessage.
|
||||||
*
|
|
||||||
* @param item The item to add to the tile.
|
|
||||||
*/
|
|
||||||
public AddTileItemMessage(Item item) {
|
|
||||||
this(item, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an add tile item message.
|
|
||||||
*
|
*
|
||||||
* @param item The item to add to the tile.
|
* @param item The item to add to the tile.
|
||||||
* @param positionOffset The offset from the 'base' position.
|
* @param positionOffset The offset from the 'base' position.
|
||||||
*/
|
*/
|
||||||
public AddTileItemMessage(Item item, int positionOffset) {
|
public SendTileItemMessage(Item item, int positionOffset) {
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.positionOffset = positionOffset;
|
this.positionOffset = positionOffset;
|
||||||
}
|
}
|
||||||
@@ -67,4 +58,25 @@ public final class AddTileItemMessage extends Message {
|
|||||||
return positionOffset;
|
return positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof SendTileItemMessage) {
|
||||||
|
SendTileItemMessage other = (SendTileItemMessage) obj;
|
||||||
|
return item.equals(other.item) && positionOffset == other.positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
return item.hashCode() * prime + positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return LOW_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package org.apollo.game.message.impl;
|
||||||
|
|
||||||
|
import org.apollo.game.message.Message;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Message} sent to the client to set the coordinates of the Region currently being updated.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class SetUpdatedRegionMessage extends Message {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Position of the Player.
|
||||||
|
*/
|
||||||
|
private final Position player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Position in the Region being cleared.
|
||||||
|
*/
|
||||||
|
private final Position region;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the SetUpdatedRegionMessage.
|
||||||
|
*
|
||||||
|
* @param player The {@link Position} of the Player this {@link Message} is being sent to.
|
||||||
|
* @param region The {@link RegionCoordinates} of the Region being set.
|
||||||
|
*/
|
||||||
|
public SetUpdatedRegionMessage(Position player, RegionCoordinates region) {
|
||||||
|
this.player = player;
|
||||||
|
this.region = new Position(region.getAbsoluteX(), region.getAbsoluteY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Position} of the Player this {@link Message} is being sent to..
|
||||||
|
*
|
||||||
|
* @return The Position.
|
||||||
|
*/
|
||||||
|
public Position getPlayerPosition() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Position} of the Region being cleared.
|
||||||
|
*
|
||||||
|
* @return The Position.
|
||||||
|
*/
|
||||||
|
public Position getRegionPosition() {
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import org.apollo.game.model.Item;
|
|||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class UpdateTileItemMessage extends Message {
|
public final class UpdateTileItemMessage extends RegionUpdateMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Item}.
|
* The {@link Item}.
|
||||||
@@ -48,6 +48,16 @@ public final class UpdateTileItemMessage extends Message {
|
|||||||
this.positionOffset = positionOffset;
|
this.positionOffset = positionOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof UpdateTileItemMessage) {
|
||||||
|
UpdateTileItemMessage other = (UpdateTileItemMessage) obj;
|
||||||
|
return item.equals(other.item) && previousAmount == other.previousAmount && positionOffset == other.positionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the amount of the item.
|
* Gets the amount of the item.
|
||||||
*
|
*
|
||||||
@@ -84,4 +94,16 @@ public final class UpdateTileItemMessage extends Message {
|
|||||||
return previousAmount;
|
return previousAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = item.hashCode() * prime + positionOffset;
|
||||||
|
return result * prime + previousAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int priority() {
|
||||||
|
return LOW_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -50,6 +50,16 @@ public final class Item {
|
|||||||
this.definition = ItemDefinition.lookup(id);
|
this.definition = ItemDefinition.lookup(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof Item) {
|
||||||
|
Item other = (Item) obj;
|
||||||
|
return id == other.id && amount == other.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the amount.
|
* Gets the amount.
|
||||||
*
|
*
|
||||||
@@ -77,6 +87,12 @@ public final class Item {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
return amount * prime + id;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this).add("id", id).add("amount", amount).toString();
|
return MoreObjects.toStringHelper(this).add("id", id).add("amount", amount).toString();
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ import org.apollo.game.model.def.ItemDefinition;
|
|||||||
import org.apollo.game.model.def.NpcDefinition;
|
import org.apollo.game.model.def.NpcDefinition;
|
||||||
import org.apollo.game.model.def.ObjectDefinition;
|
import org.apollo.game.model.def.ObjectDefinition;
|
||||||
import org.apollo.game.model.entity.Entity;
|
import org.apollo.game.model.entity.Entity;
|
||||||
import org.apollo.game.model.entity.GameObject;
|
import org.apollo.game.model.entity.Entity.EntityType;
|
||||||
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
import org.apollo.game.model.entity.Npc;
|
import org.apollo.game.model.entity.Npc;
|
||||||
import org.apollo.game.model.entity.Player;
|
import org.apollo.game.model.entity.Player;
|
||||||
import org.apollo.game.model.event.Event;
|
import org.apollo.game.model.event.Event;
|
||||||
@@ -36,6 +37,8 @@ import org.apollo.util.MobRepository;
|
|||||||
import org.apollo.util.NameUtil;
|
import org.apollo.util.NameUtil;
|
||||||
import org.apollo.util.plugin.PluginManager;
|
import org.apollo.util.plugin.PluginManager;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The world class is a singleton which contains objects like the {@link MobRepository} for players and NPCs. It should
|
* The world class is a singleton which contains objects like the {@link MobRepository} for players and NPCs. It should
|
||||||
* only contain things relevant to the in-game world and not classes which deal with I/O and such (these may be better
|
* only contain things relevant to the in-game world and not classes which deal with I/O and such (these may be better
|
||||||
@@ -123,6 +126,11 @@ public final class World {
|
|||||||
*/
|
*/
|
||||||
private PluginManager pluginManager;
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This world's {@link RegionRepository}.
|
||||||
|
*/
|
||||||
|
private final RegionRepository regions = RegionRepository.immutable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The release number (i.e. version) of this world.
|
* The release number (i.e. version) of this world.
|
||||||
*/
|
*/
|
||||||
@@ -133,11 +141,6 @@ public final class World {
|
|||||||
*/
|
*/
|
||||||
private final Scheduler scheduler = new Scheduler();
|
private final Scheduler scheduler = new Scheduler();
|
||||||
|
|
||||||
/**
|
|
||||||
* This world's {@link RegionRepository}.
|
|
||||||
*/
|
|
||||||
private final RegionRepository regions = RegionRepository.immutable();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the world.
|
* Creates the world.
|
||||||
*/
|
*/
|
||||||
@@ -192,15 +195,6 @@ public final class World {
|
|||||||
return pluginManager;
|
return pluginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the release number of this world.
|
|
||||||
*
|
|
||||||
* @return The release number.
|
|
||||||
*/
|
|
||||||
public int getReleaseNumber() {
|
|
||||||
return releaseNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets this world's {@link RegionRepository}.
|
* Gets this world's {@link RegionRepository}.
|
||||||
*
|
*
|
||||||
@@ -210,6 +204,15 @@ public final class World {
|
|||||||
return regions;
|
return regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the release number of this world.
|
||||||
|
*
|
||||||
|
* @return The release number.
|
||||||
|
*/
|
||||||
|
public int getReleaseNumber() {
|
||||||
|
return releaseNumber;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the world by loading definitions from the specified file system.
|
* Initialises the world by loading definitions from the specified file system.
|
||||||
*
|
*
|
||||||
@@ -288,7 +291,7 @@ public final class World {
|
|||||||
* @param npc The npc.
|
* @param npc The npc.
|
||||||
* @return {@code true} if the npc registered successfully, otherwise {@code false}.
|
* @return {@code true} if the npc registered successfully, otherwise {@code false}.
|
||||||
*/
|
*/
|
||||||
public boolean register(final Npc npc) {
|
public boolean register(Npc npc) {
|
||||||
boolean success = npcRepository.add(npc);
|
boolean success = npcRepository.add(npc);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -310,7 +313,7 @@ public final class World {
|
|||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @return A {@link RegistrationStatus}.
|
* @return A {@link RegistrationStatus}.
|
||||||
*/
|
*/
|
||||||
public RegistrationStatus register(final Player player) {
|
public RegistrationStatus register(Player player) {
|
||||||
String username = player.getUsername();
|
String username = player.getUsername();
|
||||||
if (isPlayerOnline(username)) {
|
if (isPlayerOnline(username)) {
|
||||||
return RegistrationStatus.ALREADY_ONLINE;
|
return RegistrationStatus.ALREADY_ONLINE;
|
||||||
@@ -319,8 +322,6 @@ public final class World {
|
|||||||
boolean success = playerRepository.add(player);
|
boolean success = playerRepository.add(player);
|
||||||
if (success) {
|
if (success) {
|
||||||
players.put(NameUtil.encodeBase37(username), player);
|
players.put(NameUtil.encodeBase37(username), player);
|
||||||
Region region = regions.fromPosition(player.getPosition());
|
|
||||||
region.addEntity(player);
|
|
||||||
|
|
||||||
logger.info("Registered player: " + player + " [count=" + playerRepository.size() + "]");
|
logger.info("Registered player: " + player + " [count=" + playerRepository.size() + "]");
|
||||||
return RegistrationStatus.OK;
|
return RegistrationStatus.OK;
|
||||||
@@ -340,6 +341,20 @@ public final class World {
|
|||||||
return scheduler.schedule(task);
|
return scheduler.schedule(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns the specified {@link Entity}, which must not be a {@link Player} or an {@link Npc}, which have their own
|
||||||
|
* register methods.
|
||||||
|
*
|
||||||
|
* @param entity The Entity.
|
||||||
|
*/
|
||||||
|
public void spawn(Entity entity) {
|
||||||
|
EntityType type = entity.getEntityType();
|
||||||
|
Preconditions.checkArgument(type != EntityType.PLAYER && type != EntityType.NPC, "Cannot spawn a Mob.");
|
||||||
|
|
||||||
|
Region region = regions.fromPosition(entity.getPosition());
|
||||||
|
region.addEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submits the specified {@link Event}, passing it to the listeners..
|
* Submits the specified {@link Event}, passing it to the listeners..
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.apollo.game.model.area;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of update that an Entity in a {@link Region} may have.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public enum EntityUpdateType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The add type, when an Entity has been added to a {@link Region}.
|
||||||
|
*/
|
||||||
|
ADD,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The remove type, when an Entity has been removed from a {@link Region}.
|
||||||
|
*/
|
||||||
|
REMOVE;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.apollo.game.model.area;
|
package org.apollo.game.model.area;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -8,14 +10,18 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
import org.apollo.game.model.Direction;
|
import org.apollo.game.model.Direction;
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
import org.apollo.game.model.area.collision.CollisionMatrix;
|
import org.apollo.game.model.area.collision.CollisionMatrix;
|
||||||
|
import org.apollo.game.model.area.update.UpdateOperation;
|
||||||
import org.apollo.game.model.entity.Entity;
|
import org.apollo.game.model.entity.Entity;
|
||||||
import org.apollo.game.model.entity.Entity.EntityType;
|
import org.apollo.game.model.entity.Entity.EntityType;
|
||||||
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,10 +31,30 @@ import com.google.common.collect.ImmutableSet;
|
|||||||
*/
|
*/
|
||||||
public final class Region {
|
public final class Region {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RegionListener} for {@link UpdateOperation}s.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
private static final class UpdateRegionListener implements RegionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Region region, Entity entity, EntityUpdateType update) {
|
||||||
|
EntityType type = entity.getEntityType();
|
||||||
|
if (type != EntityType.PLAYER && type != EntityType.NPC
|
||||||
|
&& (type != EntityType.STATIC_OBJECT || update == EntityUpdateType.REMOVE)) {
|
||||||
|
region.record(entity, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width and length of a Region, in tiles.
|
* The width and length of a Region, in tiles.
|
||||||
*/
|
*/
|
||||||
public static final int REGION_SIZE = 8;
|
public static final int SIZE = 8;
|
||||||
|
|
||||||
|
static final long start = System.currentTimeMillis();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default size of newly-created sets, to reduce memory usage.
|
* The default size of newly-created sets, to reduce memory usage.
|
||||||
@@ -53,7 +79,17 @@ public final class Region {
|
|||||||
/**
|
/**
|
||||||
* The CollisionMatrix.
|
* The CollisionMatrix.
|
||||||
*/
|
*/
|
||||||
private final CollisionMatrix[] matrices = CollisionMatrix.createMatrices(Position.HEIGHT_LEVELS, REGION_SIZE, REGION_SIZE);
|
private final CollisionMatrix[] matrices = CollisionMatrix.createMatrices(Position.HEIGHT_LEVELS, SIZE, SIZE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Set containing RegionUpdateMessages which can be sent to add every non-Mob Entity in this Region.
|
||||||
|
*/
|
||||||
|
private final List<List<RegionUpdateMessage>> snapshots = new ArrayList<>(Position.HEIGHT_LEVELS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Set containing UpdateOperations.
|
||||||
|
*/
|
||||||
|
private final List<List<RegionUpdateMessage>> updates = new ArrayList<>(Position.HEIGHT_LEVELS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Region.
|
* Creates a new Region.
|
||||||
@@ -72,6 +108,12 @@ public final class Region {
|
|||||||
*/
|
*/
|
||||||
public Region(RegionCoordinates coordinates) {
|
public Region(RegionCoordinates coordinates) {
|
||||||
this.coordinates = coordinates;
|
this.coordinates = coordinates;
|
||||||
|
listeners.add(new UpdateRegionListener());
|
||||||
|
|
||||||
|
for (int height = 0; height < Position.HEIGHT_LEVELS; height++) {
|
||||||
|
snapshots.add(new ArrayList<>());
|
||||||
|
updates.add(new ArrayList<>(DEFAULT_SET_SIZE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,7 +130,11 @@ public final class Region {
|
|||||||
Set<Entity> local = entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE));
|
Set<Entity> local = entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE));
|
||||||
local.add(entity);
|
local.add(entity);
|
||||||
|
|
||||||
notifyListeners(entity, RegionOperation.ADD);
|
if ((System.currentTimeMillis() - start) / 1000 > 10 && (entity instanceof GameObject)) {
|
||||||
|
System.out.println("Adding entity " + entity + " to " + entity.getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners(entity, EntityUpdateType.ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,22 +174,24 @@ public final class Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a shallow copy of the {@link Set} of {@link Entity}s with the specified {@link EntityType}. The returned
|
* Gets a shallow copy of the {@link Set} of {@link Entity}s with the specified {@link EntityType}(s). The returned
|
||||||
* type will be immutable. Type will be inferred from the call, so ensure that the Entity type and the reference
|
* 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.
|
* correspond, or this method will fail at runtime.
|
||||||
*
|
*
|
||||||
* @param position The {@link Position} containing the entities.
|
* @param position The {@link Position} containing the entities.
|
||||||
* @param type The {@link EntityType}.
|
* @param types The {@link EntityType}s.
|
||||||
* @return The set of entities.
|
* @return The set of entities.
|
||||||
*/
|
*/
|
||||||
public <T extends Entity> Set<T> getEntities(Position position, EntityType type) {
|
public <T extends Entity> Set<T> getEntities(Position position, EntityType... types) {
|
||||||
Set<Entity> local = entities.get(position);
|
Set<Entity> local = entities.get(position);
|
||||||
if (local == null) {
|
if (local == null) {
|
||||||
return ImmutableSet.of();
|
return ImmutableSet.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<EntityType> set = new HashSet<>(Arrays.asList(types));
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<T> filtered = (Set<T>) local.stream().filter(Entity -> Entity.getEntityType() == type).collect(Collectors.toSet());
|
Set<T> filtered = (Set<T>) local.stream().filter(entity -> set.contains(entity.getEntityType()))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
return ImmutableSet.copyOf(filtered);
|
return ImmutableSet.copyOf(filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,40 +207,41 @@ public final class Region {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the {@link Entity} that was in the specified {@code old} {@link Position}, to the current position of the
|
* Gets a {@link Set} containing {@link RegionUpdateMessage}s that add every {@link Entity} in this Region.
|
||||||
* Entity.
|
|
||||||
* <p>
|
|
||||||
* Both the {@code old} and current positions of the Entity must belong to this Region.
|
|
||||||
*
|
*
|
||||||
* @param old The old position of the Entity.
|
* @param height The height level to get the Set of RegionUpdateMessages for.
|
||||||
* @param entity The Entity to move.
|
* @return The Set of RegionUpdateMessages.
|
||||||
* @throws IllegalArgumentException If either of the positions do not belong to this Region.
|
|
||||||
*/
|
*/
|
||||||
public void moveEntity(Position old, Entity entity) {
|
public List<RegionUpdateMessage> getSnapshot(int height) {
|
||||||
Position position = entity.getPosition();
|
List<RegionUpdateMessage> copy = new ArrayList<>(snapshots.get(height));
|
||||||
checkPosition(old);
|
Collections.sort(copy);
|
||||||
checkPosition(position);
|
return ImmutableList.copyOf(copy);
|
||||||
|
|
||||||
Set<Entity> local = entities.get(old);
|
|
||||||
|
|
||||||
if (local == null || !local.remove(entity)) {
|
|
||||||
throw new IllegalArgumentException("Entity belongs in this Region (" + this + ") but does not exist.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local = entities.computeIfAbsent(position, key -> new HashSet<>(DEFAULT_SET_SIZE));
|
/**
|
||||||
|
* Gets the updates that have occurred in the last tick in this Region, as a {@link Set} of
|
||||||
|
* {@link RegionUpdateMessage}s.
|
||||||
|
*
|
||||||
|
* @param height The height level to get the Set of RegionUpdateMessages for.
|
||||||
|
* @return The Set of RegionUpdateMessages.
|
||||||
|
*/
|
||||||
|
public List<RegionUpdateMessage> getUpdates(int height) {
|
||||||
|
List<RegionUpdateMessage> original = this.updates.get(height);
|
||||||
|
List<RegionUpdateMessage> updates = new ArrayList<>(original);
|
||||||
|
original.clear();
|
||||||
|
|
||||||
local.add(entity);
|
Collections.sort(updates);
|
||||||
notifyListeners(entity, RegionOperation.MOVE);
|
return ImmutableList.copyOf(updates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the {@link RegionListener}s registered to this Region that an update has occurred.
|
* Notifies the {@link RegionListener}s registered to this Region that an update has occurred.
|
||||||
*
|
*
|
||||||
* @param entity The {@link Entity} that was updated.
|
* @param entity The {@link Entity} that was updated.
|
||||||
* @param operation The {@link RegionOperation} that occurred.
|
* @param type The {@link EntityUpdateType} that occurred.
|
||||||
*/
|
*/
|
||||||
public void notifyListeners(Entity entity, RegionOperation operation) {
|
public void notifyListeners(Entity entity, EntityUpdateType type) {
|
||||||
listeners.forEach(listener -> listener.execute(this, entity, operation));
|
listeners.forEach(listener -> listener.execute(this, entity, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,7 +260,12 @@ public final class Region {
|
|||||||
throw new IllegalArgumentException("Entity belongs in this Region (" + this + ") but does not exist.");
|
throw new IllegalArgumentException("Entity belongs in this Region (" + this + ") but does not exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyListeners(entity, RegionOperation.REMOVE);
|
notifyListeners(entity, EntityUpdateType.REMOVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MoreObjects.toStringHelper(this).add("coordinates", coordinates).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,12 +281,7 @@ public final class Region {
|
|||||||
CollisionMatrix matrix = matrices[position.getHeight()];
|
CollisionMatrix matrix = matrices[position.getHeight()];
|
||||||
int x = position.getX(), y = position.getY();
|
int x = position.getX(), y = position.getY();
|
||||||
|
|
||||||
return !matrix.untraversable(x % REGION_SIZE, y % REGION_SIZE, entity, direction);
|
return !matrix.untraversable(x % SIZE, y % SIZE, entity, direction);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return MoreObjects.toStringHelper(this).add("coordinates", coordinates).toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -246,4 +295,19 @@ public final class Region {
|
|||||||
"Position is not included in this Region.");
|
"Position is not included in this Region.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records the specified {@link Entity} as being updated this pulse.
|
||||||
|
*
|
||||||
|
* @param entity The Entity.
|
||||||
|
* @param type The {@link EntityUpdateType}.
|
||||||
|
* @throws UnsupportedOperationException If the specified Entity cannot be operated on in this manner.
|
||||||
|
*/
|
||||||
|
private void record(Entity entity, EntityUpdateType type) {
|
||||||
|
RegionUpdateMessage message = entity.toUpdateOperation(this, type).toMessage();
|
||||||
|
int height = entity.getPosition().getHeight();
|
||||||
|
|
||||||
|
updates.get(height).add(message);
|
||||||
|
snapshots.get(height).add(message);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -14,10 +14,10 @@ import com.google.common.base.MoreObjects;
|
|||||||
public final class RegionCoordinates {
|
public final class RegionCoordinates {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a pair of region coordinates from a {@link Position}.
|
* Gets the RegionCoordinates for the specified {@link Position}.
|
||||||
*
|
*
|
||||||
* @param position The position.
|
* @param position The Position.
|
||||||
* @return The region coordinates.
|
* @return The RegionCoordinates.
|
||||||
*/
|
*/
|
||||||
public static RegionCoordinates fromPosition(Position position) {
|
public static RegionCoordinates fromPosition(Position position) {
|
||||||
return new RegionCoordinates(position.getTopLeftRegionX(), position.getTopLeftRegionY());
|
return new RegionCoordinates(position.getTopLeftRegionX(), position.getTopLeftRegionY());
|
||||||
@@ -54,6 +54,24 @@ public final class RegionCoordinates {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the absolute x coordinate of this Region (which can be compared directly against {@link Position#getX()}.
|
||||||
|
*
|
||||||
|
* @return The absolute x coordinate.
|
||||||
|
*/
|
||||||
|
public int getAbsoluteX() {
|
||||||
|
return Region.SIZE * (x + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the absolute y coordinate of this Region (which can be compared directly against {@link Position#getY()}.
|
||||||
|
*
|
||||||
|
* @return The absolute y coordinate.
|
||||||
|
*/
|
||||||
|
public int getAbsoluteY() {
|
||||||
|
return Region.SIZE * (y + 6);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the x coordinate (equivalent to the {@link Position#getTopLeftRegionX()} of a position within this region).
|
* Gets the x coordinate (equivalent to the {@link Position#getTopLeftRegionX()} of a position within this region).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ public interface RegionListener {
|
|||||||
*
|
*
|
||||||
* @param region The {@link Region} that was updated.
|
* @param region The {@link Region} that was updated.
|
||||||
* @param entity The affected {@link Entity}.
|
* @param entity The affected {@link Entity}.
|
||||||
* @param operation The type of {@link RegionOperation}.
|
* @param type The type of {@link EntityUpdateType}.
|
||||||
*/
|
*/
|
||||||
public abstract void execute(Region region, Entity entity, RegionOperation operation);
|
public abstract void execute(Region region, Entity entity, EntityUpdateType type);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package org.apollo.game.model.area;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An operation that can be performed by a region, used by {@link RegionListener}s to differentiate between operations.
|
|
||||||
*
|
|
||||||
* @author Major
|
|
||||||
*/
|
|
||||||
public enum RegionOperation {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The add operation, when an entity has been added to a region.
|
|
||||||
*/
|
|
||||||
ADD,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The move operation, when an entity has moved positions, but is still in the same region.
|
|
||||||
*/
|
|
||||||
MOVE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The remove operation, when an entity has been removed from a region.
|
|
||||||
*/
|
|
||||||
REMOVE;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -76,7 +76,13 @@ public final class CollisionMatrix {
|
|||||||
* @return {@code true} if all of the CollisionFlags are set, otherwise {@code false}.
|
* @return {@code true} if all of the CollisionFlags are set, otherwise {@code false}.
|
||||||
*/
|
*/
|
||||||
public boolean all(int x, int y, CollisionFlag... flags) {
|
public boolean all(int x, int y, CollisionFlag... flags) {
|
||||||
return Arrays.stream(flags).allMatch(flag -> (get(x, y) & flag.asByte()) != 0);
|
for (CollisionFlag flag : flags) {
|
||||||
|
if (!flagged(x, y, flag)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +95,13 @@ public final class CollisionMatrix {
|
|||||||
* @return {@code true} if any of the CollisionFlags are set, otherwise {@code false}.
|
* @return {@code true} if any of the CollisionFlags are set, otherwise {@code false}.
|
||||||
*/
|
*/
|
||||||
public boolean any(int x, int y, CollisionFlag... flags) {
|
public boolean any(int x, int y, CollisionFlag... flags) {
|
||||||
return Arrays.stream(flags).anyMatch(flag -> (get(x, y) & flag.asByte()) != 0);
|
for (CollisionFlag flag : flags) {
|
||||||
|
if (flagged(x, y, flag)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,6 +159,17 @@ public final class CollisionMatrix {
|
|||||||
set(x, y, ALL_ALLOWED);
|
set(x, y, ALL_ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the appropriate index for the specified coordinate pair to the specified value.
|
||||||
|
*
|
||||||
|
* @param x The x coordinate.
|
||||||
|
* @param y The y coordinate.
|
||||||
|
* @param value The value.
|
||||||
|
*/
|
||||||
|
private void set(int x, int y, byte value) {
|
||||||
|
matrix[indexOf(x, y)] = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets (i.e. sets to {@code true}) the value of the specified {@link CollisionFlag} for the specified coordinate
|
* Sets (i.e. sets to {@code true}) the value of the specified {@link CollisionFlag} for the specified coordinate
|
||||||
* pair.
|
* pair.
|
||||||
@@ -161,7 +184,8 @@ public final class CollisionMatrix {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this).add("width", width).add("length", length).add("matrix", Arrays.toString(matrix)).toString();
|
return MoreObjects.toStringHelper(this).add("width", width).add("length", length).add("matrix", Arrays.toString(matrix))
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,15 +239,4 @@ public final class CollisionMatrix {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the appropriate index for the specified coordinate pair to the specified value.
|
|
||||||
*
|
|
||||||
* @param x The x coordinate.
|
|
||||||
* @param y The y coordinate.
|
|
||||||
* @param value The value.
|
|
||||||
*/
|
|
||||||
public void set(int x, int y, byte value) {
|
|
||||||
matrix[indexOf(x, y)] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.apollo.game.model.area.update;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
|
import org.apollo.game.message.impl.RemoveTileItemMessage;
|
||||||
|
import org.apollo.game.message.impl.SendPublicTileItemMessage;
|
||||||
|
import org.apollo.game.model.area.EntityUpdateType;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
|
import org.apollo.game.model.entity.GroundItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link UpdateOperation} for {@link GroundItem}s.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class ItemUpdateOperation extends UpdateOperation<GroundItem> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the ItemUpdateOperation.
|
||||||
|
*
|
||||||
|
* @param region The {@link Region} the type occurred in. Must not be {@code null}.
|
||||||
|
* @param type The {@link EntityUpdateType}. Must not be {@code null}.
|
||||||
|
* @param item The modified {@link GroundItem}. Must not be {@code null}.
|
||||||
|
*/
|
||||||
|
public ItemUpdateOperation(Region region, EntityUpdateType type, GroundItem item) {
|
||||||
|
super(region, type, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RegionUpdateMessage add(int offset) {
|
||||||
|
return new SendPublicTileItemMessage(entity.getItem(), offset, entity.getOwnerIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RegionUpdateMessage remove(int offset) {
|
||||||
|
return new RemoveTileItemMessage(entity.getItem(), offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.apollo.game.model.area.update;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
|
import org.apollo.game.message.impl.RemoveObjectMessage;
|
||||||
|
import org.apollo.game.message.impl.SendObjectMessage;
|
||||||
|
import org.apollo.game.model.area.EntityUpdateType;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link UpdateOperation} for addition or removal of {@link GameObject}s.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class ObjectUpdateOperation extends UpdateOperation<GameObject> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the ObjectUpdateOperation.
|
||||||
|
*
|
||||||
|
* @param region The {@link Region} in which the ObjectUpdateOperation occurred. Must not be {@code null}.
|
||||||
|
* @param type The {@link EntityUpdateType}. Must not be {@code null}.
|
||||||
|
* @param object The {@linkGameObject}. Must not be {@code null}.
|
||||||
|
*/
|
||||||
|
public ObjectUpdateOperation(Region region, EntityUpdateType type, GameObject object) {
|
||||||
|
super(region, type, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RegionUpdateMessage add(int offset) {
|
||||||
|
return new SendObjectMessage(entity, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RegionUpdateMessage remove(int offset) {
|
||||||
|
return new RemoveObjectMessage(entity, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package org.apollo.game.model.area.update;
|
||||||
|
|
||||||
|
import org.apollo.game.message.Message;
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.area.EntityUpdateType;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
|
import org.apollo.game.model.entity.Entity;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An type that is contained in the snapshot of a {@link Region}, which consists of an {@link Entity} being added,
|
||||||
|
* removed, or moved.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
* @param <E> The type of {@link Entity} in this type.
|
||||||
|
*/
|
||||||
|
public abstract class UpdateOperation<E extends Entity> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Entity involved in this UpdateOperation.
|
||||||
|
*/
|
||||||
|
protected final E entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Region in which this type occurred.
|
||||||
|
*/
|
||||||
|
protected final Region region;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of update.
|
||||||
|
*/
|
||||||
|
protected final EntityUpdateType type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the UpdateOperation.
|
||||||
|
*
|
||||||
|
* @param region The region in which the UpdateOperation occurred. Must not be {@code null}.
|
||||||
|
* @param type The type of {@link EntityUpdateType}. Must not be {@code null}.
|
||||||
|
* @param entity The {@link Entity} being added or removed. Must not be {@code null}.
|
||||||
|
*/
|
||||||
|
public UpdateOperation(Region region, EntityUpdateType type, E entity) {
|
||||||
|
this.region = region;
|
||||||
|
this.type = type;
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this UpdateOperation as a {@link Message}.
|
||||||
|
*
|
||||||
|
* @return The Message.
|
||||||
|
*/
|
||||||
|
public final RegionUpdateMessage toMessage() {
|
||||||
|
int offset = getPositionOffset(entity.getPosition());
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case ADD:
|
||||||
|
return add(offset);
|
||||||
|
case REMOVE:
|
||||||
|
return remove(offset);
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unsupported EntityUpdateType " + type + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link RegionUpdateMessage} that adds the {@link Entity} in this UpdateOperation.
|
||||||
|
*
|
||||||
|
* @param offset The offset of the {@link Position} of the Entity from the Position of the {@link Region}.
|
||||||
|
* @return The RegionUpdateMessage.
|
||||||
|
*/
|
||||||
|
protected abstract RegionUpdateMessage add(int offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link RegionUpdateMessage} that removes the {@link Entity} in this UpdateOperation.
|
||||||
|
*
|
||||||
|
* @param offset The offset of the {@link Position} of the Entity from the Position of the {@link Region}.
|
||||||
|
* @return The RegionUpdateMessage.
|
||||||
|
*/
|
||||||
|
protected abstract RegionUpdateMessage remove(int offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position offset for the specified {@link Position}.
|
||||||
|
*
|
||||||
|
* @param position The Position.
|
||||||
|
* @return The position offset.
|
||||||
|
*/
|
||||||
|
private final int getPositionOffset(Position position) {
|
||||||
|
RegionCoordinates coordinates = region.getCoordinates();
|
||||||
|
int dx = position.getX() - coordinates.getAbsoluteX();
|
||||||
|
int dy = position.getY() - coordinates.getAbsoluteY();
|
||||||
|
|
||||||
|
Preconditions.checkArgument(dx >= 0 && dx < Region.SIZE, position + " not in expected Region of " + region + ".");
|
||||||
|
Preconditions.checkArgument(dy >= 0 && dy < Region.SIZE, position + " not in expected Region of " + region + ".");
|
||||||
|
|
||||||
|
return (dx << 4) | dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Contains snapshot-related classes.
|
||||||
|
*/
|
||||||
|
package org.apollo.game.model.area.update;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.apollo.game.model.def;
|
package org.apollo.game.model.def;
|
||||||
|
|
||||||
import org.apollo.game.model.entity.GameObject;
|
import org.apollo.game.model.entity.obj.GameObject;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package org.apollo.game.model.entity;
|
package org.apollo.game.model.entity;
|
||||||
|
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.area.EntityUpdateType;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
|
import org.apollo.game.model.area.update.UpdateOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an in-game entity, such as a mob, object, projectile, etc.
|
* Represents an in-game entity, such as a mob, object, projectile, etc.
|
||||||
@@ -11,28 +14,31 @@ public abstract class Entity {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a type of {@link Entity}.
|
* Represents a type of {@link Entity}.
|
||||||
*
|
|
||||||
* @author Major
|
|
||||||
*/
|
*/
|
||||||
public enum EntityType {
|
public enum EntityType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An item that has been dropped on the ground.
|
* An Item that is positioned on the ground.
|
||||||
*/
|
*/
|
||||||
DROPPED_ITEM,
|
GROUND_ITEM,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object appearing in the game world.
|
* A GameObject that is loaded statically (i.e. from the game resources) at start-up.
|
||||||
*/
|
*/
|
||||||
GAME_OBJECT,
|
STATIC_OBJECT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An npc.
|
* A GameObject that is loaded dynamically, usually for specific Players.
|
||||||
|
*/
|
||||||
|
DYNAMIC_OBJECT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Npc.
|
||||||
*/
|
*/
|
||||||
NPC,
|
NPC,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A player.
|
* A Player.
|
||||||
*/
|
*/
|
||||||
PLAYER,
|
PLAYER,
|
||||||
|
|
||||||
@@ -41,6 +47,15 @@ public abstract class Entity {
|
|||||||
*/
|
*/
|
||||||
PROJECTILE;
|
PROJECTILE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this EntityType is for a Mob.
|
||||||
|
*
|
||||||
|
* @return {@code true} if this EntityType is for a Mob, otherwise {@code false}.
|
||||||
|
*/
|
||||||
|
public boolean isMob() {
|
||||||
|
return this == PLAYER || this == NPC;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +72,9 @@ public abstract class Entity {
|
|||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract boolean equals(Object obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link EntityType} of this entity.
|
* Gets the {@link EntityType} of this entity.
|
||||||
*
|
*
|
||||||
@@ -73,10 +91,16 @@ public abstract class Entity {
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract boolean equals(Object obj);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract int hashCode();
|
public abstract int hashCode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this Entity, as an {@link UpdateOperation} of a {@link Region}.
|
||||||
|
*
|
||||||
|
* @param region The Region.
|
||||||
|
* @param type The EntityUpdateType.
|
||||||
|
* @return The UpdateOperation.
|
||||||
|
*/
|
||||||
|
public abstract UpdateOperation<?> toUpdateOperation(Region region, EntityUpdateType type);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package org.apollo.game.model.entity;
|
||||||
|
|
||||||
|
import org.apollo.game.model.Item;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
|
import org.apollo.game.model.area.EntityUpdateType;
|
||||||
|
import org.apollo.game.model.area.update.ItemUpdateOperation;
|
||||||
|
import org.apollo.game.model.area.update.UpdateOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link Item} displayed on the ground.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class GroundItem extends Entity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new GroundItem.
|
||||||
|
*
|
||||||
|
* @param position The {@link Position} of the Item.
|
||||||
|
* @param item The Item displayed on the ground.
|
||||||
|
* @return The GroundItem.
|
||||||
|
*/
|
||||||
|
public static GroundItem create(Position position, Item item) {
|
||||||
|
return new GroundItem(position, item, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new dropped GroundItem.
|
||||||
|
*
|
||||||
|
* @param position The {@link Position} of the Item.
|
||||||
|
* @param item The Item displayed on the ground.
|
||||||
|
* @param owner The the {@link Player} who dropped this GroundItem.
|
||||||
|
* @return The GroundItem.
|
||||||
|
*/
|
||||||
|
public static GroundItem dropped(Position position, Item item, Player owner) {
|
||||||
|
return new GroundItem(position, item, owner.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the Player who dropped this GroundItem.
|
||||||
|
*/
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Item displayed on the ground.
|
||||||
|
*/
|
||||||
|
private final Item item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the GroundItem.
|
||||||
|
*
|
||||||
|
* @param position The {@link Position} of the Item.
|
||||||
|
* @param item The Item displayed on the ground.
|
||||||
|
* @param index The index of the {@link Player} who dropped this GroundItem.
|
||||||
|
*/
|
||||||
|
private GroundItem(Position position, Item item, int index) {
|
||||||
|
super(position);
|
||||||
|
this.item = item;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof GroundItem) {
|
||||||
|
GroundItem other = (GroundItem) obj;
|
||||||
|
return position.equals(other.position);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType getEntityType() {
|
||||||
|
return EntityType.GROUND_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Item} displayed on the ground.
|
||||||
|
*
|
||||||
|
* @return The Item.
|
||||||
|
*/
|
||||||
|
public Item getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of the {@link Player} who dropped this GroundItem, or {@code -1} if this GroundItem was not
|
||||||
|
* dropped by a Player.
|
||||||
|
*
|
||||||
|
* @return The index.
|
||||||
|
*/
|
||||||
|
public int getOwnerIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return position.hashCode() * 31 + item.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UpdateOperation<GroundItem> toUpdateOperation(Region region, EntityUpdateType operation) {
|
||||||
|
return new ItemUpdateOperation(region, operation, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,8 +11,10 @@ import org.apollo.game.model.Direction;
|
|||||||
import org.apollo.game.model.Graphic;
|
import org.apollo.game.model.Graphic;
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.model.area.EntityUpdateType;
|
||||||
import org.apollo.game.model.area.Region;
|
import org.apollo.game.model.area.Region;
|
||||||
import org.apollo.game.model.area.RegionRepository;
|
import org.apollo.game.model.area.RegionRepository;
|
||||||
|
import org.apollo.game.model.area.update.UpdateOperation;
|
||||||
import org.apollo.game.model.def.NpcDefinition;
|
import org.apollo.game.model.def.NpcDefinition;
|
||||||
import org.apollo.game.model.entity.attr.Attribute;
|
import org.apollo.game.model.entity.attr.Attribute;
|
||||||
import org.apollo.game.model.entity.attr.AttributeMap;
|
import org.apollo.game.model.entity.attr.AttributeMap;
|
||||||
@@ -194,8 +196,8 @@ public abstract class Mob extends Entity {
|
|||||||
*/
|
*/
|
||||||
public final Direction[] getDirections() {
|
public final Direction[] getDirections() {
|
||||||
if (firstDirection != Direction.NONE) {
|
if (firstDirection != Direction.NONE) {
|
||||||
return secondDirection == Direction.NONE ? new Direction[] { firstDirection } : new Direction[] {
|
return secondDirection == Direction.NONE ? new Direction[] { firstDirection } : new Direction[] { firstDirection,
|
||||||
firstDirection, secondDirection };
|
secondDirection };
|
||||||
}
|
}
|
||||||
|
|
||||||
return Direction.EMPTY_DIRECTION_ARRAY;
|
return Direction.EMPTY_DIRECTION_ARRAY;
|
||||||
@@ -248,6 +250,15 @@ public abstract class Mob extends Entity {
|
|||||||
return interactingMob;
|
return interactingMob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this mobs interacting index.
|
||||||
|
*
|
||||||
|
* @return The interaction index of this mob.
|
||||||
|
*/
|
||||||
|
public int getInteractionIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets this mob's inventory.
|
* Gets this mob's inventory.
|
||||||
*
|
*
|
||||||
@@ -404,15 +415,6 @@ public abstract class Mob extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns this mobs interacting index.
|
|
||||||
*
|
|
||||||
* @return The interaction index of this mob.
|
|
||||||
*/
|
|
||||||
public int getInteractionIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates this mob's interacting mob.
|
* Updates this mob's interacting mob.
|
||||||
*
|
*
|
||||||
@@ -425,22 +427,19 @@ public abstract class Mob extends Entity {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link Position} of this mob.
|
* Sets the {@link Position} of this mob.
|
||||||
|
* <p>
|
||||||
|
* This method may be intercepted using a {@link MobPositionUpdateEvent}, which can be terminated like any other.
|
||||||
|
* Plugins that intercept this Event <strong>must</strong> be cautious, because movement will not be possible (even
|
||||||
|
* through mechanisms such as teleporting) if the Event is terminated.
|
||||||
*
|
*
|
||||||
* @param position The position.
|
* @param position The Position.
|
||||||
*/
|
*/
|
||||||
public final void setPosition(Position position) {
|
public final void setPosition(Position position) {
|
||||||
World.getWorld().submit(new MobPositionUpdateEvent(this, position));
|
if (World.getWorld().submit(new MobPositionUpdateEvent(this, position))) {
|
||||||
// Intentionally ignore the Event result - accidentally terminating this method would break the entire server.
|
|
||||||
|
|
||||||
Position old = this.position;
|
Position old = this.position;
|
||||||
RegionRepository repository = World.getWorld().getRegionRepository();
|
RegionRepository repository = World.getWorld().getRegionRepository();
|
||||||
Region current = repository.fromPosition(old);
|
Region current = repository.fromPosition(old), next = repository.fromPosition(position);
|
||||||
|
|
||||||
if (position.inside(current)) {
|
|
||||||
this.position = position;
|
|
||||||
current.moveEntity(old, this);
|
|
||||||
} else {
|
|
||||||
Region next = repository.fromPosition(position);
|
|
||||||
current.removeEntity(this);
|
current.removeEntity(this);
|
||||||
this.position = position; // addEntity relies on the position being updated, so do that first.
|
this.position = position; // addEntity relies on the position being updated, so do that first.
|
||||||
|
|
||||||
@@ -523,6 +522,11 @@ public abstract class Mob extends Entity {
|
|||||||
stopAction();
|
stopAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final UpdateOperation<Entity> toUpdateOperation(Region region, EntityUpdateType operation) {
|
||||||
|
throw new UnsupportedOperationException("Mobs cannot be recorded as a Region update.");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns this mob to face the specified {@link Position}.
|
* Turns this mob to face the specified {@link Position}.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package org.apollo.game.model.entity;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
import org.apollo.game.model.World;
|
|
||||||
import org.apollo.game.model.area.Region;
|
|
||||||
import org.apollo.game.model.def.NpcDefinition;
|
import org.apollo.game.model.def.NpcDefinition;
|
||||||
import org.apollo.game.sync.block.SynchronizationBlock;
|
import org.apollo.game.sync.block.SynchronizationBlock;
|
||||||
|
|
||||||
@@ -44,7 +42,6 @@ public final class Npc extends Mob {
|
|||||||
super(position, definition);
|
super(position, definition);
|
||||||
|
|
||||||
this.boundaries = Optional.ofNullable(boundaries);
|
this.boundaries = Optional.ofNullable(boundaries);
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -122,14 +119,4 @@ public final class Npc extends Mob {
|
|||||||
blockSet.add(SynchronizationBlock.createTransformBlock(id));
|
blockSet.add(SynchronizationBlock.createTransformBlock(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialises this Npc.
|
|
||||||
*/
|
|
||||||
private void init() {
|
|
||||||
// This has to be here instead of in Mob#init because of ordering issues - the Npc cannot be added to the
|
|
||||||
// region until their credentials have been set, which is only done after the super constructors are called.
|
|
||||||
Region region = World.getWorld().getRegionRepository().get(position.getRegionCoordinates());
|
|
||||||
region.addEntity(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,6 @@ import org.apollo.game.message.impl.UpdateRunEnergyMessage;
|
|||||||
import org.apollo.game.model.Appearance;
|
import org.apollo.game.model.Appearance;
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
import org.apollo.game.model.area.Region;
|
|
||||||
import org.apollo.game.model.entity.attr.Attribute;
|
import org.apollo.game.model.entity.attr.Attribute;
|
||||||
import org.apollo.game.model.entity.attr.AttributeDefinition;
|
import org.apollo.game.model.entity.attr.AttributeDefinition;
|
||||||
import org.apollo.game.model.entity.attr.AttributeMap;
|
import org.apollo.game.model.entity.attr.AttributeMap;
|
||||||
@@ -155,6 +154,11 @@ public final class Player extends Mob {
|
|||||||
*/
|
*/
|
||||||
private final transient Deque<Message> queuedMessages = new ArrayDeque<>();
|
private final transient Deque<Message> queuedMessages = new ArrayDeque<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag indicating if the region changed in the last cycle.
|
||||||
|
*/
|
||||||
|
private transient boolean regionChanged = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flag indicating if this player is running.
|
* A flag indicating if this player is running.
|
||||||
*/
|
*/
|
||||||
@@ -165,11 +169,6 @@ public final class Player extends Mob {
|
|||||||
*/
|
*/
|
||||||
private ScreenBrightness screenBrightness = ScreenBrightness.NORMAL;
|
private ScreenBrightness screenBrightness = ScreenBrightness.NORMAL;
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag indicating if the region changed in the last cycle.
|
|
||||||
*/
|
|
||||||
private transient boolean regionChanged = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link GameSession} currently attached to this {@link Player}.
|
* The {@link GameSession} currently attached to this {@link Player}.
|
||||||
*/
|
*/
|
||||||
@@ -407,6 +406,15 @@ public final class Player extends Mob {
|
|||||||
return lastKnownRegion;
|
return lastKnownRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link MembershipStatus} of this Player.
|
||||||
|
*
|
||||||
|
* @return The MembershipStatus.
|
||||||
|
*/
|
||||||
|
public MembershipStatus getMembershipStatus() {
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the player's prayer icon.
|
* Gets the player's prayer icon.
|
||||||
*
|
*
|
||||||
@@ -558,15 +566,6 @@ public final class Player extends Mob {
|
|||||||
return members == MembershipStatus.PAID;
|
return members == MembershipStatus.PAID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link MembershipStatus} of this Player.
|
|
||||||
*
|
|
||||||
* @return The MembershipStatus.
|
|
||||||
*/
|
|
||||||
public MembershipStatus getMembershipStatus() {
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this player is running.
|
* Checks if this player is running.
|
||||||
*
|
*
|
||||||
@@ -846,6 +845,15 @@ public final class Player extends Mob {
|
|||||||
this.privilegeLevel = privilegeLevel;
|
this.privilegeLevel = privilegeLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the region changed flag.
|
||||||
|
*
|
||||||
|
* @param regionChanged A flag indicating if the region has changed.
|
||||||
|
*/
|
||||||
|
public void setRegionChanged(boolean regionChanged) {
|
||||||
|
this.regionChanged = regionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the player's run energy.
|
* Sets the player's run energy.
|
||||||
*
|
*
|
||||||
@@ -865,15 +873,6 @@ public final class Player extends Mob {
|
|||||||
this.screenBrightness = brightness;
|
this.screenBrightness = brightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the region changed flag.
|
|
||||||
*
|
|
||||||
* @param regionChanged A flag indicating if the region has changed.
|
|
||||||
*/
|
|
||||||
public void setRegionChanged(boolean regionChanged) {
|
|
||||||
this.regionChanged = regionChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the player's {@link GameSession}.
|
* Sets the player's {@link GameSession}.
|
||||||
*
|
*
|
||||||
@@ -943,7 +942,8 @@ public final class Player extends Mob {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this).add("username", getUsername()).add("privilege", privilegeLevel).add("client version", getClientVersion()).toString();
|
return MoreObjects.toStringHelper(this).add("username", getUsername()).add("privilege", privilegeLevel)
|
||||||
|
.add("client version", getClientVersion()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -952,11 +952,6 @@ public final class Player extends Mob {
|
|||||||
private void init() {
|
private void init() {
|
||||||
initInventories();
|
initInventories();
|
||||||
initSkills();
|
initSkills();
|
||||||
|
|
||||||
// This has to be here instead of in Mob#init because of ordering issues - the player cannot be added to the
|
|
||||||
// region until their credentials have been set, which is only done after the super constructors are called.
|
|
||||||
Region region = World.getWorld().getRegionRepository().get(position.getRegionCoordinates());
|
|
||||||
region.addEntity(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -967,7 +962,8 @@ public final class Player extends Mob {
|
|||||||
InventoryListener fullBankListener = new FullInventoryListener(this, FullInventoryListener.FULL_BANK_MESSAGE);
|
InventoryListener fullBankListener = new FullInventoryListener(this, FullInventoryListener.FULL_BANK_MESSAGE);
|
||||||
InventoryListener appearanceListener = new AppearanceInventoryListener(this);
|
InventoryListener appearanceListener = new AppearanceInventoryListener(this);
|
||||||
|
|
||||||
InventoryListener syncInventoryListener = new SynchronizationInventoryListener(this, SynchronizationInventoryListener.INVENTORY_ID);
|
InventoryListener syncInventoryListener = new SynchronizationInventoryListener(this,
|
||||||
|
SynchronizationInventoryListener.INVENTORY_ID);
|
||||||
InventoryListener syncBankListener = new SynchronizationInventoryListener(this, BankConstants.BANK_INVENTORY_ID);
|
InventoryListener syncBankListener = new SynchronizationInventoryListener(this, BankConstants.BANK_INVENTORY_ID);
|
||||||
InventoryListener syncEquipmentListener = new SynchronizationInventoryListener(this,
|
InventoryListener syncEquipmentListener = new SynchronizationInventoryListener(this,
|
||||||
SynchronizationInventoryListener.EQUIPMENT_ID);
|
SynchronizationInventoryListener.EQUIPMENT_ID);
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package org.apollo.game.model.entity.obj;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.entity.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link GameObject} that is loaded dynamically, usually for specific Players.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class DynamicGameObject extends GameObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link WeakReference} for {@link Player}s.
|
||||||
|
*/
|
||||||
|
private static final class WeakPlayerReference extends WeakReference<Player> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the WeakPlayerReference.
|
||||||
|
*
|
||||||
|
* @param player The Player wrapped in this {@link WeakReference}.
|
||||||
|
*/
|
||||||
|
public WeakPlayerReference(Player player) {
|
||||||
|
super(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof WeakPlayerReference) {
|
||||||
|
WeakPlayerReference other = (WeakPlayerReference) obj;
|
||||||
|
|
||||||
|
Player player = get();
|
||||||
|
return player != null && player.equals(other.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
Player player = get();
|
||||||
|
return (player == null) ? 0 : player.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a DynamicGameObject that is visible only to {@link Player}s specified later.
|
||||||
|
*
|
||||||
|
* @param id The id of the DynamicGameObject
|
||||||
|
* @param position The {@link Position} of the DynamicGameObject.
|
||||||
|
* @param type The type of the DynamicGameObject.
|
||||||
|
* @param orientation The orientation of the DynamicGameObject.
|
||||||
|
* @return The DynamicGameObject.
|
||||||
|
*/
|
||||||
|
public static DynamicGameObject createLocal(int id, Position position, int type, int orientation) {
|
||||||
|
return new DynamicGameObject(id, position, type, orientation, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a DynamicGameObject that is always visible.
|
||||||
|
*
|
||||||
|
* @param id The id of the DynamicGameObject
|
||||||
|
* @param position The {@link Position} of the DynamicGameObject.
|
||||||
|
* @param type The type of the DynamicGameObject.
|
||||||
|
* @param orientation The orientation of the DynamicGameObject.
|
||||||
|
* @return The DynamicGameObject.
|
||||||
|
*/
|
||||||
|
public static DynamicGameObject createPublic(int id, Position position, int type, int orientation) {
|
||||||
|
return new DynamicGameObject(id, position, type, orientation, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The flag indicating whether or not this DynamicGameObject is visible to every player.
|
||||||
|
*/
|
||||||
|
private final boolean alwaysVisible;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Set of Players that can view this DynamicGameObject.
|
||||||
|
*/
|
||||||
|
private final Set<WeakPlayerReference> players = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the DynamicGameObject.
|
||||||
|
*
|
||||||
|
* @param id The id of the DynamicGameObject
|
||||||
|
* @param position The {@link Position} of the DynamicGameObject.
|
||||||
|
* @param type The type of the DynamicGameObject.
|
||||||
|
* @param orientation The orientation of the DynamicGameObject.
|
||||||
|
* @param alwaysVisible The flag indicates whether or not this DynamicGameObject is visible to every player.
|
||||||
|
*/
|
||||||
|
private DynamicGameObject(int id, Position position, int type, int orientation, boolean alwaysVisible) {
|
||||||
|
super(id, position, type, orientation);
|
||||||
|
this.alwaysVisible = alwaysVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds this DynamicGameObject to the view of the specified {@link Player}.
|
||||||
|
*
|
||||||
|
* @param player The Player.
|
||||||
|
* @return {@code true} if this GameObject was not already visible to the specified Player.
|
||||||
|
*/
|
||||||
|
public boolean addTo(Player player) {
|
||||||
|
WeakPlayerReference reference = new WeakPlayerReference(player);
|
||||||
|
return players.add(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType getEntityType() {
|
||||||
|
return EntityType.DYNAMIC_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes this DynamicGameObject from the view of the specified {@link Player}.
|
||||||
|
*
|
||||||
|
* @param player The Player.
|
||||||
|
* @return {@code true} if this GameObject was visible to the specified Player.
|
||||||
|
*/
|
||||||
|
public boolean removeFrom(Player player) {
|
||||||
|
WeakPlayerReference reference = new WeakPlayerReference(player);
|
||||||
|
return players.remove(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean viewableBy(Player player) {
|
||||||
|
return alwaysVisible || players.contains(new WeakPlayerReference(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+28
-14
@@ -1,7 +1,12 @@
|
|||||||
package org.apollo.game.model.entity;
|
package org.apollo.game.model.entity.obj;
|
||||||
|
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.area.EntityUpdateType;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
|
import org.apollo.game.model.area.update.ObjectUpdateOperation;
|
||||||
import org.apollo.game.model.def.ObjectDefinition;
|
import org.apollo.game.model.def.ObjectDefinition;
|
||||||
|
import org.apollo.game.model.entity.Entity;
|
||||||
|
import org.apollo.game.model.entity.Player;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
|
|
||||||
@@ -11,7 +16,7 @@ import com.google.common.base.MoreObjects;
|
|||||||
* @author Chris Fletcher
|
* @author Chris Fletcher
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class GameObject extends Entity {
|
public abstract class GameObject extends Entity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The packed value that stores this object's id, type, and orientation.
|
* The packed value that stores this object's id, type, and orientation.
|
||||||
@@ -19,12 +24,12 @@ public final class GameObject extends Entity {
|
|||||||
private final int packed;
|
private final int packed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the game object.
|
* Creates the GameObject.
|
||||||
*
|
*
|
||||||
* @param id The object's id.
|
* @param id The id of the GameObject
|
||||||
* @param position The position.
|
* @param position The {@link Position} of the GameObject.
|
||||||
* @param type The type code of the object.
|
* @param type The type of the GameObject.
|
||||||
* @param orientation The orientation of the object.
|
* @param orientation The orientation of the GameObject.
|
||||||
*/
|
*/
|
||||||
public GameObject(int id, Position position, int type, int orientation) {
|
public GameObject(int id, Position position, int type, int orientation) {
|
||||||
super(position);
|
super(position);
|
||||||
@@ -50,18 +55,13 @@ public final class GameObject extends Entity {
|
|||||||
return ObjectDefinition.lookup(getId());
|
return ObjectDefinition.lookup(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityType getEntityType() {
|
|
||||||
return EntityType.GAME_OBJECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets this object's id.
|
* Gets this object's id.
|
||||||
*
|
*
|
||||||
* @return The id.
|
* @return The id.
|
||||||
*/
|
*/
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return packed >> 8;
|
return packed >>> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +89,21 @@ public final class GameObject extends Entity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this).add("id", getId()).add("type", getType()).add("orientation", getOrientation()).toString();
|
return MoreObjects.toStringHelper(this).add("id", getId()).add("type", getType()).add("orientation", getOrientation())
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectUpdateOperation toUpdateOperation(Region region, EntityUpdateType operation) {
|
||||||
|
return new ObjectUpdateOperation(region, operation, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this GameObject can be seen by the specified {@link Player}.
|
||||||
|
*
|
||||||
|
* @param player The Player.
|
||||||
|
* @return {@code true} if the Player can see this GameObject, {@code false} if not.
|
||||||
|
*/
|
||||||
|
public abstract boolean viewableBy(Player player);
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
package org.apollo.game.model.area.obj;
|
package org.apollo.game.model.entity.obj;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ public enum ObjectGroup {
|
|||||||
WALL_DECORATION(1),
|
WALL_DECORATION(1),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interactable object group, for objects that can be clicked and interacted with.
|
* The interactable object group, for objects that can be clicked and interacted with. TODO rename
|
||||||
*/
|
*/
|
||||||
INTERACTABLE_OBJECT(2),
|
INTERACTABLE_OBJECT(2),
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.apollo.game.model.area.obj;
|
package org.apollo.game.model.entity.obj;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of an object, which affects specified behaviour (such as whether it displaces existing objects). TODO
|
* The type of an object, which affects specified behaviour (such as whether it displaces existing objects). TODO
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.apollo.game.model.entity.obj;
|
||||||
|
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
|
import org.apollo.game.model.area.RegionRepository;
|
||||||
|
import org.apollo.game.model.entity.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link GameObject} that is a static part of the game world (i.e. is stored in the game resources).
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class StaticGameObject extends GameObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the StaticGameObject.
|
||||||
|
*
|
||||||
|
* @param id The id of the StaticGameObject
|
||||||
|
* @param position The {@link Position} of the StaticGameObject.
|
||||||
|
* @param type The type code of the StaticGameObject.
|
||||||
|
* @param orientation The orientation of the StaticGameObject.
|
||||||
|
*/
|
||||||
|
public StaticGameObject(int id, Position position, int type, int orientation) {
|
||||||
|
super(id, position, type, orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityType getEntityType() {
|
||||||
|
return EntityType.STATIC_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean viewableBy(Player player) {
|
||||||
|
RegionRepository repository = World.getWorld().getRegionRepository();
|
||||||
|
RegionCoordinates coordinates = position.getRegionCoordinates();
|
||||||
|
|
||||||
|
return repository.get(coordinates).contains(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* Contains object-related classes.
|
* Contains object-related classes.
|
||||||
*/
|
*/
|
||||||
package org.apollo.game.model.area.obj;
|
package org.apollo.game.model.entity.obj;
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
package org.apollo.game.sync;
|
package org.apollo.game.sync;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Phaser;
|
import java.util.concurrent.Phaser;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
|
||||||
import org.apollo.game.GameService;
|
import org.apollo.game.GameService;
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
import org.apollo.game.model.entity.Npc;
|
import org.apollo.game.model.entity.Npc;
|
||||||
import org.apollo.game.model.entity.Player;
|
import org.apollo.game.model.entity.Player;
|
||||||
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
||||||
@@ -59,9 +64,12 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
|||||||
int playerCount = players.size();
|
int playerCount = players.size();
|
||||||
int npcCount = npcs.size();
|
int npcCount = npcs.size();
|
||||||
|
|
||||||
|
Map<RegionCoordinates, List<RegionUpdateMessage>> updates = new HashMap<>();
|
||||||
|
Map<RegionCoordinates, List<RegionUpdateMessage>> snapshots = new HashMap<>();
|
||||||
|
|
||||||
phaser.bulkRegister(playerCount);
|
phaser.bulkRegister(playerCount);
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
SynchronizationTask task = new PrePlayerSynchronizationTask(player);
|
SynchronizationTask task = new PrePlayerSynchronizationTask(player, updates, snapshots);
|
||||||
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
||||||
}
|
}
|
||||||
phaser.arriveAndAwaitAdvance();
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
package org.apollo.game.sync;
|
package org.apollo.game.sync;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apollo.game.GameService;
|
import org.apollo.game.GameService;
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
import org.apollo.game.model.entity.Npc;
|
import org.apollo.game.model.entity.Npc;
|
||||||
import org.apollo.game.model.entity.Player;
|
import org.apollo.game.model.entity.Player;
|
||||||
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
||||||
@@ -29,8 +35,11 @@ public final class SequentialClientSynchronizer extends ClientSynchronizer {
|
|||||||
MobRepository<Player> players = World.getWorld().getPlayerRepository();
|
MobRepository<Player> players = World.getWorld().getPlayerRepository();
|
||||||
MobRepository<Npc> npcs = World.getWorld().getNpcRepository();
|
MobRepository<Npc> npcs = World.getWorld().getNpcRepository();
|
||||||
|
|
||||||
|
Map<RegionCoordinates, List<RegionUpdateMessage>> updates = new HashMap<>();
|
||||||
|
Map<RegionCoordinates, List<RegionUpdateMessage>> snapshots = new HashMap<>();
|
||||||
|
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
SynchronizationTask task = new PrePlayerSynchronizationTask(player);
|
SynchronizationTask task = new PrePlayerSynchronizationTask(player, updates, snapshots);
|
||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,207 @@
|
|||||||
package org.apollo.game.sync.task;
|
package org.apollo.game.sync.task;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.ClearRegionMessage;
|
||||||
|
import org.apollo.game.message.impl.GroupedRegionUpdateMessage;
|
||||||
import org.apollo.game.message.impl.RegionChangeMessage;
|
import org.apollo.game.message.impl.RegionChangeMessage;
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.model.area.Region;
|
||||||
|
import org.apollo.game.model.area.RegionCoordinates;
|
||||||
|
import org.apollo.game.model.area.RegionRepository;
|
||||||
import org.apollo.game.model.entity.Player;
|
import org.apollo.game.model.entity.Player;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link SynchronizationTask} which does pre-synchronization work for the specified {@link Player}.
|
* A {@link SynchronizationTask} which does pre-synchronization work for the specified {@link Player}.
|
||||||
*
|
*
|
||||||
* @author Graham
|
* @author Graham
|
||||||
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class PrePlayerSynchronizationTask extends SynchronizationTask {
|
public final class PrePlayerSynchronizationTask extends SynchronizationTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The update mode used when sending a {@link GroupedRegionUpdateMessage}.
|
||||||
|
*/
|
||||||
|
private enum RegionUpdateMode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The difference update mode, which only sends updates for changes that have occurred in the last pulse.
|
||||||
|
*/
|
||||||
|
DIFFERENCE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full update mode, which sends everything in the Region.
|
||||||
|
*/
|
||||||
|
FULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of Regions that are in view of a player, in one direction.
|
||||||
|
*/
|
||||||
|
private static final int REGION_COUNT = (int) Math.ceil(Position.MAX_DISTANCE / Region.SIZE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The width of the viewport of every Player, in tiles.
|
||||||
|
*/
|
||||||
|
private static final int VIEWPORT_WIDTH = Region.SIZE * 13;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The player.
|
* The player.
|
||||||
*/
|
*/
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the {@link PrePlayerSynchronizationTask} for the specified player.
|
* The Map of RegionCoordinates to Sets of RegionUpdateMessages, which contain all of the Entity information for a
|
||||||
*
|
* Region.
|
||||||
* @param player The player.
|
|
||||||
*/
|
*/
|
||||||
public PrePlayerSynchronizationTask(Player player) {
|
private final Map<RegionCoordinates, List<RegionUpdateMessage>> snapshots;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Map of RegionCoordinates to Sets of RegionUpdateMessages, which contain the updates for a Region a Player can
|
||||||
|
* already view.
|
||||||
|
*/
|
||||||
|
private final Map<RegionCoordinates, List<RegionUpdateMessage>> updates;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the {@link PrePlayerSynchronizationTask} for the specified {@link Player}.
|
||||||
|
*
|
||||||
|
* @param player The Player.
|
||||||
|
* @param updates The {@link Map} containing {@link Region} updates.
|
||||||
|
* @param snapshots The Map containing Region snapshots.
|
||||||
|
*/
|
||||||
|
public PrePlayerSynchronizationTask(Player player, Map<RegionCoordinates, List<RegionUpdateMessage>> updates,
|
||||||
|
Map<RegionCoordinates, List<RegionUpdateMessage>> snapshots) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
this.updates = updates;
|
||||||
|
this.snapshots = snapshots;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Position old = player.getPosition();
|
||||||
|
player.getWalkingQueue().pulse();
|
||||||
|
|
||||||
|
RegionUpdateMode mode = RegionUpdateMode.DIFFERENCE;
|
||||||
|
|
||||||
|
if (player.isTeleporting()) {
|
||||||
|
player.resetViewingDistance();
|
||||||
|
mode = RegionUpdateMode.FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasKnownRegion = player.hasLastKnownRegion();
|
||||||
|
if (!hasKnownRegion) {
|
||||||
|
mode = RegionUpdateMode.FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasKnownRegion || isRegionUpdateRequired()) {
|
||||||
|
player.setRegionChanged(true);
|
||||||
|
|
||||||
|
Position position = player.getPosition();
|
||||||
|
player.setLastKnownRegion(position);
|
||||||
|
player.send(new RegionChangeMessage(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<RegionCoordinates> newRegions = getNewRegions(old, player.getPosition());
|
||||||
|
sendRegionUpdates(mode, newRegions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link Set} of {@link RegionCoordinates} of {@link Region}s that the {@link Player} in this task has
|
||||||
|
* only just became able to view.
|
||||||
|
*
|
||||||
|
* @param old The old {@link Position} of the Player.
|
||||||
|
* @param next The new Position of the Player.
|
||||||
|
* @return The Set of RegionCoordinates. Will not be {@code null}, but may be empty.
|
||||||
|
*/
|
||||||
|
private Set<RegionCoordinates> getNewRegions(Position old, Position next) {
|
||||||
|
RegionCoordinates oldRegion = old.getRegionCoordinates();
|
||||||
|
RegionCoordinates nextRegion = next.getRegionCoordinates();
|
||||||
|
|
||||||
|
if (oldRegion.equals(nextRegion)) {
|
||||||
|
return ImmutableSet.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<RegionCoordinates> coordinates = new HashSet<>(9);
|
||||||
|
int oldX = oldRegion.getX(), oldY = oldRegion.getY();
|
||||||
|
|
||||||
|
int dx = nextRegion.getX() - oldX;
|
||||||
|
int dy = nextRegion.getY() - oldY;
|
||||||
|
|
||||||
|
if (dx != 0) {
|
||||||
|
int x = oldX + dx;
|
||||||
|
int maxY = oldY + REGION_COUNT;
|
||||||
|
|
||||||
|
for (int y = oldY - REGION_COUNT; y <= maxY; y++) {
|
||||||
|
coordinates.add(new RegionCoordinates(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dy != 0) {
|
||||||
|
int y = oldY + dy;
|
||||||
|
int maxX = oldX + REGION_COUNT;
|
||||||
|
|
||||||
|
for (int x = oldX - REGION_COUNT; x <= maxX; x++) {
|
||||||
|
coordinates.add(new RegionCoordinates(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link List} of {@link GroupedRegionUpdateMessage}s.
|
||||||
|
*
|
||||||
|
* @param mode The {@link RegionUpdateMode} used when creating the Messages.
|
||||||
|
* @param newRegions The {@link Set} of {@link RegionCoordinates} that should be sent as a full update.
|
||||||
|
*/
|
||||||
|
private void sendRegionUpdates(RegionUpdateMode mode, Set<RegionCoordinates> newRegions) {
|
||||||
|
Position position = player.getPosition();
|
||||||
|
RegionCoordinates base = position.getRegionCoordinates();
|
||||||
|
int baseX = base.getX(), baseY = base.getY();
|
||||||
|
|
||||||
|
RegionRepository repository = World.getWorld().getRegionRepository();
|
||||||
|
List<GroupedRegionUpdateMessage> messages = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int x = baseX - REGION_COUNT; x <= baseX + REGION_COUNT; x++) {
|
||||||
|
for (int y = baseY - REGION_COUNT; y <= baseY + REGION_COUNT; y++) {
|
||||||
|
RegionCoordinates coordinates = new RegionCoordinates(x, y);
|
||||||
|
|
||||||
|
RegionUpdateMode local = mode;
|
||||||
|
if (mode == RegionUpdateMode.DIFFERENCE && newRegions.contains(coordinates)) {
|
||||||
|
local = RegionUpdateMode.FULL;
|
||||||
|
|
||||||
|
player.send(new ClearRegionMessage(position, coordinates));
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<GroupedRegionUpdateMessage> message = toUpdateMessage(local, position, coordinates, repository);
|
||||||
|
if (message.isPresent()) {
|
||||||
|
messages.add(message.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messages.size() > 0) {
|
||||||
|
System.out.println("Sending in mode " + mode + ", new regions=" + newRegions);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
messages.forEach(player::send);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a region update is required.
|
* Checks if a region update is required.
|
||||||
*
|
*
|
||||||
* @return {@code true} if so, {@code false} otherwise.
|
* @return {@code true} if a Region update is required, {@code false} if not.
|
||||||
*/
|
*/
|
||||||
private boolean isRegionUpdateRequired() {
|
private boolean isRegionUpdateRequired() {
|
||||||
Position current = player.getPosition();
|
Position current = player.getPosition();
|
||||||
@@ -37,24 +210,59 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask {
|
|||||||
int deltaX = current.getLocalX(last);
|
int deltaX = current.getLocalX(last);
|
||||||
int deltaY = current.getLocalY(last);
|
int deltaY = current.getLocalY(last);
|
||||||
|
|
||||||
return deltaX < 16 || deltaX >= 88 || deltaY < 16 || deltaY >= 88;
|
return deltaX <= Position.MAX_DISTANCE || deltaX >= (VIEWPORT_WIDTH - Position.MAX_DISTANCE - 1)
|
||||||
|
|| deltaY <= Position.MAX_DISTANCE || deltaY >= (VIEWPORT_WIDTH - Position.MAX_DISTANCE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void run() {
|
* Creates a {@link GroupedRegionUpdateMessage} using the specified {@link RegionUpdateMode}, returning
|
||||||
player.getWalkingQueue().pulse();
|
* {@link Optional#empty()} if no update message is required.
|
||||||
|
*
|
||||||
|
* @param mode The RegionUpdateMode for the Message.
|
||||||
|
* @param position The {@link Position} of the Player.
|
||||||
|
* @param coordinates The {@link RegionCoordinates} of the {@link Region}.
|
||||||
|
* @param repository The {@link RegionRepository} containing the Regions.
|
||||||
|
* @return The Optional containing the GroupedRegionUpdateMessage.
|
||||||
|
*/
|
||||||
|
private Optional<GroupedRegionUpdateMessage> toUpdateMessage(RegionUpdateMode mode, Position position,
|
||||||
|
RegionCoordinates coordinates, RegionRepository repository) {
|
||||||
|
List<RegionUpdateMessage> messages;
|
||||||
|
|
||||||
if (player.isTeleporting()) {
|
/*
|
||||||
player.resetViewingDistance();
|
* Here we used Map#computeIfAbsent because the value may have been inserted into the Map by another thread
|
||||||
|
* after our Map#get call. This is done in two separate parts (rather than acquiring the lock every time, and
|
||||||
|
* just calling Map#computeIfAbsent immediately) for performance - once the List<RegionUpdateMessage> has been
|
||||||
|
* placed into the Map once, it will never be changed, and is therefore a read-only operation after this. The
|
||||||
|
* alternative, acquiring the lock for every access, would be very slow.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case DIFFERENCE:
|
||||||
|
messages = updates.get(coordinates);
|
||||||
|
if (messages == null) {
|
||||||
|
synchronized (updates) {
|
||||||
|
messages = updates.computeIfAbsent(coordinates,
|
||||||
|
coords -> repository.get(coords).getUpdates(position.getHeight()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!player.hasLastKnownRegion() || isRegionUpdateRequired()) {
|
break;
|
||||||
player.setRegionChanged(true);
|
case FULL:
|
||||||
|
messages = snapshots.get(coordinates);
|
||||||
Position position = player.getPosition();
|
if (messages == null) {
|
||||||
player.setLastKnownRegion(position);
|
synchronized (snapshots) {
|
||||||
player.send(new RegionChangeMessage(position));
|
messages = snapshots.computeIfAbsent(coordinates,
|
||||||
|
coords -> repository.get(coords).getSnapshot(position.getHeight()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unrecognised RegionUpdateMode " + mode + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages.isEmpty() ? Optional.empty() : Optional
|
||||||
|
.of(new GroupedRegionUpdateMessage(position, coordinates, messages));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.apollo.net.release.r317;
|
package org.apollo.net.release.r317;
|
||||||
|
|
||||||
import org.apollo.game.message.impl.AddGlobalTileItemMessage;
|
import org.apollo.game.message.impl.SendPublicTileItemMessage;
|
||||||
import org.apollo.net.codec.game.DataTransformation;
|
import org.apollo.net.codec.game.DataTransformation;
|
||||||
import org.apollo.net.codec.game.DataType;
|
import org.apollo.net.codec.game.DataType;
|
||||||
import org.apollo.net.codec.game.GamePacket;
|
import org.apollo.net.codec.game.GamePacket;
|
||||||
@@ -8,14 +8,14 @@ import org.apollo.net.codec.game.GamePacketBuilder;
|
|||||||
import org.apollo.net.release.MessageEncoder;
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link MessageEncoder} for the {@link AddGlobalTileItemMessage}.
|
* A {@link MessageEncoder} for the {@link SendPublicTileItemMessage}.
|
||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class AddGlobalTileItemMessageEncoder extends MessageEncoder<AddGlobalTileItemMessage> {
|
public final class AddGlobalTileItemMessageEncoder extends MessageEncoder<SendPublicTileItemMessage> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GamePacket encode(AddGlobalTileItemMessage message) {
|
public GamePacket encode(SendPublicTileItemMessage message) {
|
||||||
GamePacketBuilder builder = new GamePacketBuilder(215);
|
GamePacketBuilder builder = new GamePacketBuilder(215);
|
||||||
builder.put(DataType.SHORT, DataTransformation.ADD, message.getId());
|
builder.put(DataType.SHORT, DataTransformation.ADD, message.getId());
|
||||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, message.getPositionOffset());
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, message.getPositionOffset());
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.apollo.net.release.r317;
|
package org.apollo.net.release.r317;
|
||||||
|
|
||||||
import org.apollo.game.message.impl.AddTileItemMessage;
|
import org.apollo.game.message.impl.SendTileItemMessage;
|
||||||
import org.apollo.net.codec.game.DataOrder;
|
import org.apollo.net.codec.game.DataOrder;
|
||||||
import org.apollo.net.codec.game.DataTransformation;
|
import org.apollo.net.codec.game.DataTransformation;
|
||||||
import org.apollo.net.codec.game.DataType;
|
import org.apollo.net.codec.game.DataType;
|
||||||
@@ -9,14 +9,14 @@ import org.apollo.net.codec.game.GamePacketBuilder;
|
|||||||
import org.apollo.net.release.MessageEncoder;
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link MessageEncoder} for the {@link AddTileItemMessage}.
|
* A {@link MessageEncoder} for the {@link SendTileItemMessage}.
|
||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class AddTileItemMessageEncoder extends MessageEncoder<AddTileItemMessage> {
|
public final class AddTileItemMessageEncoder extends MessageEncoder<SendTileItemMessage> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GamePacket encode(AddTileItemMessage message) {
|
public GamePacket encode(SendTileItemMessage message) {
|
||||||
GamePacketBuilder builder = new GamePacketBuilder(44);
|
GamePacketBuilder builder = new GamePacketBuilder(44);
|
||||||
builder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, message.getId());
|
builder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, message.getId());
|
||||||
builder.put(DataType.SHORT, message.getAmount());
|
builder.put(DataType.SHORT, message.getAmount());
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.apollo.net.release.r317;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.ClearRegionMessage;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
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.GamePacketBuilder;
|
||||||
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MessageEncoder} for the {@link ClearRegionMessage}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class ClearRegionMessageEncoder extends MessageEncoder<ClearRegionMessage> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(ClearRegionMessage message) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(64);
|
||||||
|
Position player = message.getPlayerPosition(), region = message.getRegionPosition();
|
||||||
|
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, region.getLocalX(player));
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, region.getLocalY(player));
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.apollo.net.release.r317;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.GroupedRegionUpdateMessage;
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
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.GamePacketBuilder;
|
||||||
|
import org.apollo.net.meta.PacketType;
|
||||||
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
import org.apollo.net.release.Release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MessageEncoder} for the {@link GroupedRegionUpdateMessage}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class GroupedRegionUpdateMessageEncoder extends MessageEncoder<GroupedRegionUpdateMessage> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Release containing the MessageEncoders for the RegionUpdateMessages.
|
||||||
|
*/
|
||||||
|
private final Release release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the GroupedRegionUpdateMessageEncoder.
|
||||||
|
*
|
||||||
|
* @param release The {@link Release} containing the {@link MessageEncoder}s for the {@link RegionUpdateMessage}s.
|
||||||
|
*/
|
||||||
|
public GroupedRegionUpdateMessageEncoder(Release release) {
|
||||||
|
this.release = release;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(GroupedRegionUpdateMessage message) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(60, PacketType.VARIABLE_SHORT);
|
||||||
|
Position player = message.getPlayerPosition(), region = message.getRegionPosition();
|
||||||
|
|
||||||
|
builder.put(DataType.BYTE, player.getLocalY(region));
|
||||||
|
System.out.println("Grum: local x: " + player.getLocalX(region) + ", local y: " + player.getLocalY(region));
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, player.getLocalX(region));
|
||||||
|
|
||||||
|
for (RegionUpdateMessage update : message.getMessages()) {
|
||||||
|
System.out.println("==== Sending " + update + " as part of grum");
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
MessageEncoder<RegionUpdateMessage> encoder = (MessageEncoder<RegionUpdateMessage>) release.getMessageEncoder(update
|
||||||
|
.getClass());
|
||||||
|
|
||||||
|
GamePacket packet = encoder.encode(update);
|
||||||
|
builder.put(DataType.BYTE, packet.getOpcode());
|
||||||
|
builder.putBytes(packet.getPayload());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package org.apollo.net.release.r317;
|
|
||||||
|
|
||||||
import org.apollo.game.message.impl.PositionMessage;
|
|
||||||
import org.apollo.game.model.Position;
|
|
||||||
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.GamePacketBuilder;
|
|
||||||
import org.apollo.net.release.MessageEncoder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link MessageEncoder} for the {@link PositionMessage}.
|
|
||||||
*
|
|
||||||
* @author Chris Fletcher
|
|
||||||
*/
|
|
||||||
final class PositionMessageEncoder extends MessageEncoder<PositionMessage> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GamePacket encode(PositionMessage message) {
|
|
||||||
GamePacketBuilder builder = new GamePacketBuilder(85);
|
|
||||||
Position base = message.getBase(), pos = message.getPosition();
|
|
||||||
|
|
||||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, pos.getLocalY(base));
|
|
||||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, pos.getLocalX(base));
|
|
||||||
|
|
||||||
return builder.toGamePacket();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.apollo.net.release.r317;
|
package org.apollo.net.release.r317;
|
||||||
|
|
||||||
import org.apollo.game.message.impl.AddGlobalTileItemMessage;
|
import org.apollo.game.message.impl.ClearRegionMessage;
|
||||||
import org.apollo.game.message.impl.AddTileItemMessage;
|
|
||||||
import org.apollo.game.message.impl.CloseInterfaceMessage;
|
import org.apollo.game.message.impl.CloseInterfaceMessage;
|
||||||
import org.apollo.game.message.impl.ConfigMessage;
|
import org.apollo.game.message.impl.ConfigMessage;
|
||||||
import org.apollo.game.message.impl.DisplayCrossbonesMessage;
|
import org.apollo.game.message.impl.DisplayCrossbonesMessage;
|
||||||
@@ -10,6 +9,7 @@ import org.apollo.game.message.impl.EnterAmountMessage;
|
|||||||
import org.apollo.game.message.impl.FlashTabInterfaceMessage;
|
import org.apollo.game.message.impl.FlashTabInterfaceMessage;
|
||||||
import org.apollo.game.message.impl.ForwardPrivateChatMessage;
|
import org.apollo.game.message.impl.ForwardPrivateChatMessage;
|
||||||
import org.apollo.game.message.impl.FriendServerStatusMessage;
|
import org.apollo.game.message.impl.FriendServerStatusMessage;
|
||||||
|
import org.apollo.game.message.impl.GroupedRegionUpdateMessage;
|
||||||
import org.apollo.game.message.impl.HintIconMessage;
|
import org.apollo.game.message.impl.HintIconMessage;
|
||||||
import org.apollo.game.message.impl.IdAssignmentMessage;
|
import org.apollo.game.message.impl.IdAssignmentMessage;
|
||||||
import org.apollo.game.message.impl.IgnoreListMessage;
|
import org.apollo.game.message.impl.IgnoreListMessage;
|
||||||
@@ -22,15 +22,17 @@ import org.apollo.game.message.impl.OpenInterfaceSidebarMessage;
|
|||||||
import org.apollo.game.message.impl.OpenOverlayMessage;
|
import org.apollo.game.message.impl.OpenOverlayMessage;
|
||||||
import org.apollo.game.message.impl.OpenSidebarMessage;
|
import org.apollo.game.message.impl.OpenSidebarMessage;
|
||||||
import org.apollo.game.message.impl.PlayerSynchronizationMessage;
|
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.PrivacyOptionMessage;
|
||||||
|
import org.apollo.game.message.impl.RegionChangeMessage;
|
||||||
import org.apollo.game.message.impl.RemoveObjectMessage;
|
import org.apollo.game.message.impl.RemoveObjectMessage;
|
||||||
import org.apollo.game.message.impl.RemoveTileItemMessage;
|
import org.apollo.game.message.impl.RemoveTileItemMessage;
|
||||||
import org.apollo.game.message.impl.RegionChangeMessage;
|
|
||||||
import org.apollo.game.message.impl.SendFriendMessage;
|
import org.apollo.game.message.impl.SendFriendMessage;
|
||||||
import org.apollo.game.message.impl.SendObjectMessage;
|
import org.apollo.game.message.impl.SendObjectMessage;
|
||||||
|
import org.apollo.game.message.impl.SendPublicTileItemMessage;
|
||||||
|
import org.apollo.game.message.impl.SendTileItemMessage;
|
||||||
import org.apollo.game.message.impl.ServerChatMessage;
|
import org.apollo.game.message.impl.ServerChatMessage;
|
||||||
import org.apollo.game.message.impl.SetPlayerActionMessage;
|
import org.apollo.game.message.impl.SetPlayerActionMessage;
|
||||||
|
import org.apollo.game.message.impl.SetUpdatedRegionMessage;
|
||||||
import org.apollo.game.message.impl.SetWidgetItemModelMessage;
|
import org.apollo.game.message.impl.SetWidgetItemModelMessage;
|
||||||
import org.apollo.game.message.impl.SetWidgetModelAnimationMessage;
|
import org.apollo.game.message.impl.SetWidgetModelAnimationMessage;
|
||||||
import org.apollo.game.message.impl.SetWidgetNpcModelMessage;
|
import org.apollo.game.message.impl.SetWidgetNpcModelMessage;
|
||||||
@@ -194,7 +196,7 @@ public final class Release317 extends Release {
|
|||||||
register(SetWidgetModelAnimationMessage.class, new SetWidgetModelAnimationMessageEncoder());
|
register(SetWidgetModelAnimationMessage.class, new SetWidgetModelAnimationMessageEncoder());
|
||||||
register(ConfigMessage.class, new ConfigMessageEncoder());
|
register(ConfigMessage.class, new ConfigMessageEncoder());
|
||||||
register(DisplayTabInterfaceMessage.class, new DisplayTabInterfaceMessageEncoder());
|
register(DisplayTabInterfaceMessage.class, new DisplayTabInterfaceMessageEncoder());
|
||||||
register(PositionMessage.class, new PositionMessageEncoder());
|
register(SetUpdatedRegionMessage.class, new SetUpdatedRegionMessageEncoder());
|
||||||
register(UpdateRunEnergyMessage.class, new UpdateRunEnergyMessageEncoder());
|
register(UpdateRunEnergyMessage.class, new UpdateRunEnergyMessageEncoder());
|
||||||
register(PrivacyOptionMessage.class, new PrivacyOptionMessageEncoder());
|
register(PrivacyOptionMessage.class, new PrivacyOptionMessageEncoder());
|
||||||
register(OpenDialogueInterfaceMessage.class, new OpenDialogueInterfaceMessageEncoder());
|
register(OpenDialogueInterfaceMessage.class, new OpenDialogueInterfaceMessageEncoder());
|
||||||
@@ -202,13 +204,16 @@ public final class Release317 extends Release {
|
|||||||
register(SetPlayerActionMessage.class, new SetPlayerActionMessageEncoder());
|
register(SetPlayerActionMessage.class, new SetPlayerActionMessageEncoder());
|
||||||
register(DisplayCrossbonesMessage.class, new DisplayCrossbonesMessageEncoder());
|
register(DisplayCrossbonesMessage.class, new DisplayCrossbonesMessageEncoder());
|
||||||
|
|
||||||
register(AddGlobalTileItemMessage.class, new AddGlobalTileItemMessageEncoder());
|
register(SendPublicTileItemMessage.class, new AddGlobalTileItemMessageEncoder());
|
||||||
register(AddTileItemMessage.class, new AddTileItemMessageEncoder());
|
register(SendTileItemMessage.class, new AddTileItemMessageEncoder());
|
||||||
register(UpdateTileItemMessage.class, new UpdateTileItemMessageEncoder());
|
register(UpdateTileItemMessage.class, new UpdateTileItemMessageEncoder());
|
||||||
register(RemoveTileItemMessage.class, new RemoveTileItemMessageEncoder());
|
register(RemoveTileItemMessage.class, new RemoveTileItemMessageEncoder());
|
||||||
register(SendObjectMessage.class, new SendObjectMessageEncoder());
|
register(SendObjectMessage.class, new SendObjectMessageEncoder());
|
||||||
register(RemoveObjectMessage.class, new RemoveObjectMessageEncoder());
|
register(RemoveObjectMessage.class, new RemoveObjectMessageEncoder());
|
||||||
|
|
||||||
|
register(GroupedRegionUpdateMessage.class, new GroupedRegionUpdateMessageEncoder(this));
|
||||||
|
register(ClearRegionMessage.class, new ClearRegionMessageEncoder());
|
||||||
|
|
||||||
register(ForwardPrivateChatMessage.class, new ForwardPrivateChatMessageEncoder());
|
register(ForwardPrivateChatMessage.class, new ForwardPrivateChatMessageEncoder());
|
||||||
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
|
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
|
||||||
register(IgnoreListMessage.class, new IgnoreListMessageEncoder());
|
register(IgnoreListMessage.class, new IgnoreListMessageEncoder());
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ public final class RemoveObjectMessageEncoder extends MessageEncoder<RemoveObjec
|
|||||||
GamePacketBuilder builder = new GamePacketBuilder(101);
|
GamePacketBuilder builder = new GamePacketBuilder(101);
|
||||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, message.getType() << 2 | message.getOrientation());
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, message.getType() << 2 | message.getOrientation());
|
||||||
builder.put(DataType.BYTE, message.getPositionOffset());
|
builder.put(DataType.BYTE, message.getPositionOffset());
|
||||||
|
|
||||||
|
System.out.println("Sending rm obj: type=" + message.getType() + ", orient=" + message.getOrientation() + ",posoff="
|
||||||
|
+ Integer.toBinaryString(message.getPositionOffset()));
|
||||||
return builder.toGamePacket();
|
return builder.toGamePacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.apollo.net.release.r317;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.SetUpdatedRegionMessage;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
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.GamePacketBuilder;
|
||||||
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MessageEncoder} for the {@link SetUpdatedRegionMessage}.
|
||||||
|
*
|
||||||
|
* @author Chris Fletcher
|
||||||
|
*/
|
||||||
|
final class SetUpdatedRegionMessageEncoder extends MessageEncoder<SetUpdatedRegionMessage> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(SetUpdatedRegionMessage message) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(85);
|
||||||
|
Position player = message.getPlayerPosition(), region = message.getRegionPosition();
|
||||||
|
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, region.getLocalY(player));
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, region.getLocalX(player));
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.apollo.net.release.r377;
|
package org.apollo.net.release.r377;
|
||||||
|
|
||||||
import org.apollo.game.message.impl.AddGlobalTileItemMessage;
|
import org.apollo.game.message.impl.SendPublicTileItemMessage;
|
||||||
import org.apollo.net.codec.game.DataOrder;
|
import org.apollo.net.codec.game.DataOrder;
|
||||||
import org.apollo.net.codec.game.DataTransformation;
|
import org.apollo.net.codec.game.DataTransformation;
|
||||||
import org.apollo.net.codec.game.DataType;
|
import org.apollo.net.codec.game.DataType;
|
||||||
@@ -9,14 +9,14 @@ import org.apollo.net.codec.game.GamePacketBuilder;
|
|||||||
import org.apollo.net.release.MessageEncoder;
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link MessageEncoder} for the {@link AddGlobalTileItemMessage}.
|
* A {@link MessageEncoder} for the {@link SendPublicTileItemMessage}.
|
||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class AddGlobalTileItemMessageEncoder extends MessageEncoder<AddGlobalTileItemMessage> {
|
public final class AddGlobalTileItemMessageEncoder extends MessageEncoder<SendPublicTileItemMessage> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GamePacket encode(AddGlobalTileItemMessage message) {
|
public GamePacket encode(SendPublicTileItemMessage message) {
|
||||||
GamePacketBuilder builder = new GamePacketBuilder(106);
|
GamePacketBuilder builder = new GamePacketBuilder(106);
|
||||||
builder.put(DataType.BYTE, DataTransformation.ADD, message.getPositionOffset());
|
builder.put(DataType.BYTE, DataTransformation.ADD, message.getPositionOffset());
|
||||||
builder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, message.getAmount());
|
builder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, message.getAmount());
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.apollo.net.release.r377;
|
package org.apollo.net.release.r377;
|
||||||
|
|
||||||
import org.apollo.game.message.impl.AddTileItemMessage;
|
import org.apollo.game.message.impl.SendTileItemMessage;
|
||||||
import org.apollo.net.codec.game.DataTransformation;
|
import org.apollo.net.codec.game.DataTransformation;
|
||||||
import org.apollo.net.codec.game.DataType;
|
import org.apollo.net.codec.game.DataType;
|
||||||
import org.apollo.net.codec.game.GamePacket;
|
import org.apollo.net.codec.game.GamePacket;
|
||||||
@@ -8,14 +8,14 @@ import org.apollo.net.codec.game.GamePacketBuilder;
|
|||||||
import org.apollo.net.release.MessageEncoder;
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link MessageEncoder} for the {@link AddTileItemMessage}.
|
* A {@link MessageEncoder} for the {@link SendTileItemMessage}.
|
||||||
*
|
*
|
||||||
* @author Major
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class AddTileItemMessageEncoder extends MessageEncoder<AddTileItemMessage> {
|
public final class AddTileItemMessageEncoder extends MessageEncoder<SendTileItemMessage> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GamePacket encode(AddTileItemMessage message) {
|
public GamePacket encode(SendTileItemMessage message) {
|
||||||
GamePacketBuilder builder = new GamePacketBuilder(107);
|
GamePacketBuilder builder = new GamePacketBuilder(107);
|
||||||
builder.put(DataType.SHORT, message.getId());
|
builder.put(DataType.SHORT, message.getId());
|
||||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, message.getPositionOffset());
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, message.getPositionOffset());
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.apollo.net.release.r377;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.ClearRegionMessage;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
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.GamePacketBuilder;
|
||||||
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MessageEncoder} for the {@link ClearRegionMessage}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class ClearRegionMessageEncoder extends MessageEncoder<ClearRegionMessage> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(ClearRegionMessage message) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(40);
|
||||||
|
Position player = message.getPlayerPosition(), region = message.getRegionPosition();
|
||||||
|
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, region.getLocalY(player));
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, region.getLocalX(player));
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package org.apollo.net.release.r377;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.GroupedRegionUpdateMessage;
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
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.GamePacketBuilder;
|
||||||
|
import org.apollo.net.meta.PacketType;
|
||||||
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MessageEncoder} for the {@link GroupedRegionUpdateMessage}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class GroupedRegionUpdateMessageEncoder extends MessageEncoder<GroupedRegionUpdateMessage> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Map of RegionUpdateMessages to MessageEncoders.
|
||||||
|
*/
|
||||||
|
private final Map<Class<? extends RegionUpdateMessage>, MessageEncoder<? extends RegionUpdateMessage>> encoders;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the GroupedRegionUpdateMessageEncoder.
|
||||||
|
*
|
||||||
|
* @param encoders The Map of RegionUpdateMessages to MessageEncoders.
|
||||||
|
*/
|
||||||
|
public GroupedRegionUpdateMessageEncoder(
|
||||||
|
Map<Class<? extends RegionUpdateMessage>, MessageEncoder<? extends RegionUpdateMessage>> encoders) {
|
||||||
|
this.encoders = ImmutableMap.copyOf(encoders);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(GroupedRegionUpdateMessage message) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(183, PacketType.VARIABLE_SHORT);
|
||||||
|
Position base = message.getPlayerPosition(), region = message.getRegionPosition();
|
||||||
|
|
||||||
|
builder.put(DataType.BYTE, region.getLocalX(base));
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.ADD, region.getLocalY(base));
|
||||||
|
|
||||||
|
for (RegionUpdateMessage update : message.getMessages()) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
MessageEncoder<RegionUpdateMessage> encoder = (MessageEncoder<RegionUpdateMessage>) encoders.get(update);
|
||||||
|
|
||||||
|
Preconditions.checkState(encoder != null, update.getClass()
|
||||||
|
+ " does not have a registered encoder in GroupedRegionUpdateMessageEncoder.");
|
||||||
|
|
||||||
|
GamePacket packet = encoder.encode(update);
|
||||||
|
builder.put(DataType.BYTE, packet.getOpcode());
|
||||||
|
builder.putBytes(packet.getPayload());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.apollo.net.release.r377;
|
|
||||||
|
|
||||||
import org.apollo.game.message.impl.PositionMessage;
|
|
||||||
import org.apollo.game.model.Position;
|
|
||||||
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.GamePacketBuilder;
|
|
||||||
import org.apollo.net.release.MessageEncoder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link MessageEncoder} for the {@link PositionMessage}.
|
|
||||||
*
|
|
||||||
* @author Chris Fletcher
|
|
||||||
* @author Major
|
|
||||||
*/
|
|
||||||
public final class PositionMessageEncoder extends MessageEncoder<PositionMessage> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GamePacket encode(PositionMessage message) {
|
|
||||||
GamePacketBuilder builder = new GamePacketBuilder(75);
|
|
||||||
Position base = message.getBase(), pos = message.getPosition();
|
|
||||||
|
|
||||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, pos.getLocalX(base));
|
|
||||||
builder.put(DataType.BYTE, DataTransformation.ADD, pos.getLocalY(base));
|
|
||||||
|
|
||||||
return builder.toGamePacket();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package org.apollo.net.release.r377;
|
package org.apollo.net.release.r377;
|
||||||
|
|
||||||
import org.apollo.game.message.impl.AddGlobalTileItemMessage;
|
import java.util.HashMap;
|
||||||
import org.apollo.game.message.impl.AddTileItemMessage;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.ClearRegionMessage;
|
||||||
import org.apollo.game.message.impl.CloseInterfaceMessage;
|
import org.apollo.game.message.impl.CloseInterfaceMessage;
|
||||||
import org.apollo.game.message.impl.ConfigMessage;
|
import org.apollo.game.message.impl.ConfigMessage;
|
||||||
import org.apollo.game.message.impl.DisplayCrossbonesMessage;
|
import org.apollo.game.message.impl.DisplayCrossbonesMessage;
|
||||||
@@ -10,6 +12,7 @@ import org.apollo.game.message.impl.EnterAmountMessage;
|
|||||||
import org.apollo.game.message.impl.FlashTabInterfaceMessage;
|
import org.apollo.game.message.impl.FlashTabInterfaceMessage;
|
||||||
import org.apollo.game.message.impl.ForwardPrivateChatMessage;
|
import org.apollo.game.message.impl.ForwardPrivateChatMessage;
|
||||||
import org.apollo.game.message.impl.FriendServerStatusMessage;
|
import org.apollo.game.message.impl.FriendServerStatusMessage;
|
||||||
|
import org.apollo.game.message.impl.GroupedRegionUpdateMessage;
|
||||||
import org.apollo.game.message.impl.HintIconMessage;
|
import org.apollo.game.message.impl.HintIconMessage;
|
||||||
import org.apollo.game.message.impl.IdAssignmentMessage;
|
import org.apollo.game.message.impl.IdAssignmentMessage;
|
||||||
import org.apollo.game.message.impl.IgnoreListMessage;
|
import org.apollo.game.message.impl.IgnoreListMessage;
|
||||||
@@ -22,15 +25,18 @@ import org.apollo.game.message.impl.OpenInterfaceSidebarMessage;
|
|||||||
import org.apollo.game.message.impl.OpenOverlayMessage;
|
import org.apollo.game.message.impl.OpenOverlayMessage;
|
||||||
import org.apollo.game.message.impl.OpenSidebarMessage;
|
import org.apollo.game.message.impl.OpenSidebarMessage;
|
||||||
import org.apollo.game.message.impl.PlayerSynchronizationMessage;
|
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.PrivacyOptionMessage;
|
||||||
|
import org.apollo.game.message.impl.RegionChangeMessage;
|
||||||
|
import org.apollo.game.message.impl.RegionUpdateMessage;
|
||||||
import org.apollo.game.message.impl.RemoveObjectMessage;
|
import org.apollo.game.message.impl.RemoveObjectMessage;
|
||||||
import org.apollo.game.message.impl.RemoveTileItemMessage;
|
import org.apollo.game.message.impl.RemoveTileItemMessage;
|
||||||
import org.apollo.game.message.impl.RegionChangeMessage;
|
|
||||||
import org.apollo.game.message.impl.SendFriendMessage;
|
import org.apollo.game.message.impl.SendFriendMessage;
|
||||||
import org.apollo.game.message.impl.SendObjectMessage;
|
import org.apollo.game.message.impl.SendObjectMessage;
|
||||||
|
import org.apollo.game.message.impl.SendPublicTileItemMessage;
|
||||||
|
import org.apollo.game.message.impl.SendTileItemMessage;
|
||||||
import org.apollo.game.message.impl.ServerChatMessage;
|
import org.apollo.game.message.impl.ServerChatMessage;
|
||||||
import org.apollo.game.message.impl.SetPlayerActionMessage;
|
import org.apollo.game.message.impl.SetPlayerActionMessage;
|
||||||
|
import org.apollo.game.message.impl.SetUpdatedRegionMessage;
|
||||||
import org.apollo.game.message.impl.SetWidgetItemModelMessage;
|
import org.apollo.game.message.impl.SetWidgetItemModelMessage;
|
||||||
import org.apollo.game.message.impl.SetWidgetModelAnimationMessage;
|
import org.apollo.game.message.impl.SetWidgetModelAnimationMessage;
|
||||||
import org.apollo.game.message.impl.SetWidgetNpcModelMessage;
|
import org.apollo.game.message.impl.SetWidgetNpcModelMessage;
|
||||||
@@ -45,6 +51,7 @@ import org.apollo.game.message.impl.UpdateSlottedItemsMessage;
|
|||||||
import org.apollo.game.message.impl.UpdateTileItemMessage;
|
import org.apollo.game.message.impl.UpdateTileItemMessage;
|
||||||
import org.apollo.game.message.impl.UpdateWeightMessage;
|
import org.apollo.game.message.impl.UpdateWeightMessage;
|
||||||
import org.apollo.net.meta.PacketMetaDataGroup;
|
import org.apollo.net.meta.PacketMetaDataGroup;
|
||||||
|
import org.apollo.net.release.MessageEncoder;
|
||||||
import org.apollo.net.release.Release;
|
import org.apollo.net.release.Release;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -190,7 +197,7 @@ public final class Release377 extends Release {
|
|||||||
register(SetWidgetModelAnimationMessage.class, new SetWidgetModelAnimationMessageEncoder());
|
register(SetWidgetModelAnimationMessage.class, new SetWidgetModelAnimationMessageEncoder());
|
||||||
register(ConfigMessage.class, new ConfigMessageEncoder());
|
register(ConfigMessage.class, new ConfigMessageEncoder());
|
||||||
register(DisplayTabInterfaceMessage.class, new DisplayTabInterfaceMessageEncoder());
|
register(DisplayTabInterfaceMessage.class, new DisplayTabInterfaceMessageEncoder());
|
||||||
register(PositionMessage.class, new PositionMessageEncoder());
|
register(SetUpdatedRegionMessage.class, new SetUpdatedRegionMessageEncoder());
|
||||||
register(UpdateRunEnergyMessage.class, new UpdateRunEnergyMessageEncoder());
|
register(UpdateRunEnergyMessage.class, new UpdateRunEnergyMessageEncoder());
|
||||||
register(PrivacyOptionMessage.class, new PrivacyOptionMessageEncoder());
|
register(PrivacyOptionMessage.class, new PrivacyOptionMessageEncoder());
|
||||||
register(OpenDialogueInterfaceMessage.class, new OpenDialogueInterfaceMessageEncoder());
|
register(OpenDialogueInterfaceMessage.class, new OpenDialogueInterfaceMessageEncoder());
|
||||||
@@ -198,13 +205,35 @@ public final class Release377 extends Release {
|
|||||||
register(SetPlayerActionMessage.class, new SetPlayerActionMessageEncoder());
|
register(SetPlayerActionMessage.class, new SetPlayerActionMessageEncoder());
|
||||||
register(DisplayCrossbonesMessage.class, new DisplayCrossbonesMessageEncoder());
|
register(DisplayCrossbonesMessage.class, new DisplayCrossbonesMessageEncoder());
|
||||||
|
|
||||||
register(AddGlobalTileItemMessage.class, new AddGlobalTileItemMessageEncoder());
|
register(SendPublicTileItemMessage.class, new AddGlobalTileItemMessageEncoder());
|
||||||
register(AddTileItemMessage.class, new AddTileItemMessageEncoder());
|
register(SendTileItemMessage.class, new AddTileItemMessageEncoder());
|
||||||
register(UpdateTileItemMessage.class, new UpdateTileItemMessageEncoder());
|
register(UpdateTileItemMessage.class, new UpdateTileItemMessageEncoder());
|
||||||
register(RemoveTileItemMessage.class, new RemoveTileItemMessageEncoder());
|
register(RemoveTileItemMessage.class, new RemoveTileItemMessageEncoder());
|
||||||
register(SendObjectMessage.class, new SendObjectMessageEncoder());
|
register(SendObjectMessage.class, new SendObjectMessageEncoder());
|
||||||
register(RemoveObjectMessage.class, new RemoveObjectMessageEncoder());
|
register(RemoveObjectMessage.class, new RemoveObjectMessageEncoder());
|
||||||
|
|
||||||
|
Map<Class<? extends RegionUpdateMessage>, MessageEncoder<? extends RegionUpdateMessage>> regionUpdates = new HashMap<>();
|
||||||
|
|
||||||
|
regionUpdates.put(SendPublicTileItemMessage.class, new AddGlobalTileItemMessageEncoder());
|
||||||
|
regionUpdates.put(SendTileItemMessage.class, new AddTileItemMessageEncoder());
|
||||||
|
regionUpdates.put(UpdateTileItemMessage.class, new UpdateTileItemMessageEncoder());
|
||||||
|
regionUpdates.put(RemoveTileItemMessage.class, new RemoveTileItemMessageEncoder());
|
||||||
|
regionUpdates.put(SendObjectMessage.class, new SendObjectMessageEncoder());
|
||||||
|
regionUpdates.put(RemoveObjectMessage.class, new RemoveObjectMessageEncoder());
|
||||||
|
|
||||||
|
for (Map.Entry<Class<? extends RegionUpdateMessage>, MessageEncoder<? extends RegionUpdateMessage>> entry : regionUpdates
|
||||||
|
.entrySet()) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<RegionUpdateMessage> clazz = (Class<RegionUpdateMessage>) entry.getKey();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
MessageEncoder<RegionUpdateMessage> encoder = (MessageEncoder<RegionUpdateMessage>) entry.getValue();
|
||||||
|
|
||||||
|
register(clazz, encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
register(GroupedRegionUpdateMessage.class, new GroupedRegionUpdateMessageEncoder(regionUpdates));
|
||||||
|
register(ClearRegionMessage.class, new ClearRegionMessageEncoder());
|
||||||
|
|
||||||
register(ForwardPrivateChatMessage.class, new ForwardPrivateChatMessageEncoder());
|
register(ForwardPrivateChatMessage.class, new ForwardPrivateChatMessageEncoder());
|
||||||
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
|
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
|
||||||
register(IgnoreListMessage.class, new IgnoreListMessageEncoder());
|
register(IgnoreListMessage.class, new IgnoreListMessageEncoder());
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.apollo.net.release.r377;
|
||||||
|
|
||||||
|
import org.apollo.game.message.impl.SetUpdatedRegionMessage;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
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.GamePacketBuilder;
|
||||||
|
import org.apollo.net.release.MessageEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link MessageEncoder} for the {@link SetUpdatedRegionMessage}.
|
||||||
|
*
|
||||||
|
* @author Chris Fletcher
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class SetUpdatedRegionMessageEncoder extends MessageEncoder<SetUpdatedRegionMessage> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(SetUpdatedRegionMessage message) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(75);
|
||||||
|
Position base = message.getPlayerPosition(), position = message.getRegionPosition();
|
||||||
|
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, position.getLocalX(base));
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.ADD, position.getLocalY(base));
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package org.apollo.util;
|
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
|
||||||
import org.apollo.util.xml.XmlNode;
|
|
||||||
import org.apollo.util.xml.XmlParser;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author Stuart
|
|
||||||
*/
|
|
||||||
public final class DatabaseUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final ComboPooledDataSource pool = new ComboPooledDataSource();
|
|
||||||
|
|
||||||
static {
|
|
||||||
try(InputStream is = new FileInputStream("data/database.xml")) {
|
|
||||||
XmlNode config = new XmlParser().parse(is);
|
|
||||||
if(!config.getName().equals("database")) {
|
|
||||||
throw new IOException("Root node is not 'database'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
XmlNode url = config.getChild("url"), username = config.getChild("username"), password = config.getChild("password");
|
|
||||||
if(url == null || username == null || password == null) {
|
|
||||||
throw new IOException("Root node must contain these three children - 'url', 'username', 'password'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
pool.setJdbcUrl(url.getValue());
|
|
||||||
pool.setUser(username.getValue());
|
|
||||||
pool.setPassword(password.getValue());
|
|
||||||
|
|
||||||
// optional params
|
|
||||||
XmlNode initialPoolSize = config.getChild("initial_pool_size"), acquireIncrement = config.getChild("acquire_increment"),
|
|
||||||
maxPoolSize = config.getChild("max_pool_size"), minPoolSize = config.getChild("min_pool_size");
|
|
||||||
|
|
||||||
if(initialPoolSize != null) {
|
|
||||||
pool.setInitialPoolSize(Integer.parseInt(initialPoolSize.getValue()));
|
|
||||||
}
|
|
||||||
if(acquireIncrement != null) {
|
|
||||||
pool.setAcquireIncrement(Integer.parseInt(acquireIncrement.getValue()));
|
|
||||||
}
|
|
||||||
if(maxPoolSize != null) {
|
|
||||||
pool.setMaxPoolSize(Integer.parseInt(maxPoolSize.getValue()));
|
|
||||||
}
|
|
||||||
if(minPoolSize != null) {
|
|
||||||
pool.setMinPoolSize(Integer.parseInt(minPoolSize.getValue()));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ExceptionInInitializerError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @throws SQLException
|
|
||||||
*/
|
|
||||||
public static Connection getConnection() throws SQLException {
|
|
||||||
return pool.getConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user