mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-07 16:49:12 +00:00
Add npc synchronization and spawning plugin.
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<plugin>
|
||||||
|
<id>cmd-npc</id>
|
||||||
|
<version>1</version>
|
||||||
|
<name>Npc Commands</name>
|
||||||
|
<description>Adds npc-related commands.</description>
|
||||||
|
<authors>
|
||||||
|
<author>Major</author>
|
||||||
|
</authors>
|
||||||
|
<scripts>
|
||||||
|
<script>spawn.rb</script>
|
||||||
|
</scripts>
|
||||||
|
<dependencies />
|
||||||
|
</plugin>
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
require 'java'
|
||||||
|
|
||||||
|
java_import 'org.apollo.game.model.def.NpcDefinition'
|
||||||
|
java_import 'org.apollo.game.model.Npc'
|
||||||
|
java_import 'org.apollo.game.model.World'
|
||||||
|
java_import 'org.apollo.game.model.Position'
|
||||||
|
|
||||||
|
blacklist = []
|
||||||
|
|
||||||
|
on :command, :spawn, RIGHTS_ADMIN do |player, command|
|
||||||
|
args = command.arguments
|
||||||
|
id = args[0].to_i
|
||||||
|
unless [1, 3].include? args.length and id > -1
|
||||||
|
player.send_message("Invalid syntax - ::spawn [npc id] [x] [y]")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if blacklist.include? id
|
||||||
|
player.send_message("Sorry, that npc is blacklisted!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
definition = NpcDefinition.lookup(id)
|
||||||
|
position = args.length == 1 ? player.position : Position.new(args[1].to_i, args[2].to_i, player.position.height)
|
||||||
|
|
||||||
|
World.world.register(Npc.new(definition, position))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
on :command, :mass, RIGHTS_ADMIN do |player, command|
|
||||||
|
args = command.arguments
|
||||||
|
unless args.length == 2
|
||||||
|
player.send_message("Invalid syntax - ::spawn [npc id] [range (1-5)]")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
id = args[0].to_i
|
||||||
|
range = args[1].to_i
|
||||||
|
|
||||||
|
unless (id > -1 and (1..5).include? range)
|
||||||
|
return player.send_message("Invalid syntax - ::spawn [npc id] [range (1-5)]")
|
||||||
|
end
|
||||||
|
|
||||||
|
if blacklist.include? id
|
||||||
|
player.send_message("Sorry, that npc is blacklisted!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
center_position = player.position
|
||||||
|
|
||||||
|
minX = center_position.x - range
|
||||||
|
minY = center_position.y - range
|
||||||
|
maxX = center_position.x + range
|
||||||
|
maxY = center_position.y + range
|
||||||
|
|
||||||
|
for x in minX..maxX do
|
||||||
|
for y in minY..maxY do
|
||||||
|
World.world.register(Npc.new(NpcDefinition.lookup(id), Position.new(x, y, center_position.height)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
player.send_message("Mass spawning npcs with id #{id}.")
|
||||||
|
end
|
||||||
|
|
||||||
|
on :command, :clearnpcs, RIGHTS_ADMIN do |player, command|
|
||||||
|
iterator = World.world.npc_repository.iterator
|
||||||
|
while iterator.has_next
|
||||||
|
World.world.unregister(iterator.next)
|
||||||
|
end
|
||||||
|
player.send_message("All npcs removed.")
|
||||||
|
end
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package org.apollo.game.event.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apollo.game.event.Event;
|
||||||
|
import org.apollo.game.model.Npc;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event which is sent to synchronize npcs with players.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public class NpcSynchronizationEvent extends Event {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The npc's position.
|
||||||
|
*/
|
||||||
|
private final Position position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of segments.
|
||||||
|
*/
|
||||||
|
private final List<SynchronizationSegment> segments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of local npcs.
|
||||||
|
*/
|
||||||
|
private final int localNpcs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link NpcSynchronizationEvent}.
|
||||||
|
*
|
||||||
|
* @param position The position of the {@link Npc}.
|
||||||
|
* @param segments The list of segments.
|
||||||
|
* @param localNpcs The amount of local npcs.
|
||||||
|
*/
|
||||||
|
public NpcSynchronizationEvent(Position position, List<SynchronizationSegment> segments, int localNpcs) {
|
||||||
|
this.position = position;
|
||||||
|
this.segments = segments;
|
||||||
|
this.localNpcs = localNpcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of local npcs.
|
||||||
|
*
|
||||||
|
* @return The number of local npcs.
|
||||||
|
*/
|
||||||
|
public int getLocalNpcCount() {
|
||||||
|
return localNpcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the npc's position.
|
||||||
|
*
|
||||||
|
* @return The npc's position.
|
||||||
|
*/
|
||||||
|
public Position getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the synchronization segments.
|
||||||
|
*
|
||||||
|
* @return The segments.
|
||||||
|
*/
|
||||||
|
public List<SynchronizationSegment> getSegments() {
|
||||||
|
return segments;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,11 +19,72 @@ import org.apollo.util.CharacterRepository;
|
|||||||
*/
|
*/
|
||||||
public abstract class Character {
|
public abstract class Character {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character's current action.
|
||||||
|
*/
|
||||||
|
private Action<?> action; // TODO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character's bank.
|
||||||
|
*/
|
||||||
|
private final Inventory bank = new Inventory(InventoryConstants.BANK_CAPACITY, StackMode.STACK_ALWAYS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of {@link SynchronizationBlock}s.
|
||||||
|
*/
|
||||||
|
private SynchronizationBlockSet blockSet = new SynchronizationBlockSet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character's {@link NpcDefinition). This is only used by an instance of the {@link Player} class if they are
|
||||||
|
* appearing as an npc in-game.
|
||||||
|
*/
|
||||||
|
private NpcDefinition definition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character's equipment.
|
||||||
|
*/
|
||||||
|
private final Inventory equipment = new Inventory(InventoryConstants.EQUIPMENT_CAPACITY, StackMode.STACK_ALWAYS);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first direction.
|
||||||
|
*/
|
||||||
|
private Direction firstDirection = Direction.NONE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index of this character in the {@link CharacterRepository} it belongs to.
|
* The index of this character in the {@link CharacterRepository} it belongs to.
|
||||||
*/
|
*/
|
||||||
private int index = -1;
|
private int index = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character's inventory.
|
||||||
|
*/
|
||||||
|
private final Inventory inventory = new Inventory(InventoryConstants.INVENTORY_CAPACITY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of local npcs.
|
||||||
|
*/
|
||||||
|
private final List<Npc> localNpcs = new ArrayList<Npc>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of local players.
|
||||||
|
*/
|
||||||
|
private final List<Player> localPlayers = new ArrayList<Player>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current position of this character.
|
||||||
|
*/
|
||||||
|
private Position position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The second direction.
|
||||||
|
*/
|
||||||
|
private Direction secondDirection = Direction.NONE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The character's skill set.
|
||||||
|
*/
|
||||||
|
private final SkillSet skillSet = new SkillSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Teleportation flag.
|
* Teleportation flag.
|
||||||
*/
|
*/
|
||||||
@@ -34,62 +95,6 @@ public abstract class Character {
|
|||||||
*/
|
*/
|
||||||
private final WalkingQueue walkingQueue = new WalkingQueue(this);
|
private final WalkingQueue walkingQueue = new WalkingQueue(this);
|
||||||
|
|
||||||
/**
|
|
||||||
* The first direction.
|
|
||||||
*/
|
|
||||||
private Direction firstDirection = Direction.NONE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The second direction.
|
|
||||||
*/
|
|
||||||
private Direction secondDirection = Direction.NONE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current position of this character.
|
|
||||||
*/
|
|
||||||
private Position position;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of local players.
|
|
||||||
*/
|
|
||||||
private final List<Player> localPlayers = new ArrayList<Player>(); // TODO make a specialized collection?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A set of {@link SynchronizationBlock}s.
|
|
||||||
*/
|
|
||||||
private SynchronizationBlockSet blockSet = new SynchronizationBlockSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The character's current action.
|
|
||||||
*/
|
|
||||||
private Action<?> action; // TODO
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The character's inventory.
|
|
||||||
*/
|
|
||||||
private final Inventory inventory = new Inventory(InventoryConstants.INVENTORY_CAPACITY);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The character's equipment.
|
|
||||||
*/
|
|
||||||
private final Inventory equipment = new Inventory(InventoryConstants.EQUIPMENT_CAPACITY, StackMode.STACK_ALWAYS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The character's bank.
|
|
||||||
*/
|
|
||||||
private final Inventory bank = new Inventory(InventoryConstants.BANK_CAPACITY, StackMode.STACK_ALWAYS);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The character's skill set.
|
|
||||||
*/
|
|
||||||
private final SkillSet skillSet = new SkillSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The character's {@link NpcDefinition). This is only used by an instance of the {@link Player} class if they are
|
|
||||||
* appearing as an npc in-game.
|
|
||||||
*/
|
|
||||||
private NpcDefinition definition;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new character with the specified initial position.
|
* Creates a new character with the specified initial position.
|
||||||
*
|
*
|
||||||
@@ -100,31 +105,6 @@ public abstract class Character {
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialises this character.
|
|
||||||
*/
|
|
||||||
private void init() {
|
|
||||||
World.getWorld().schedule(new SkillNormalizationTask(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the character's inventory.
|
|
||||||
*
|
|
||||||
* @return The character's inventory.
|
|
||||||
*/
|
|
||||||
public Inventory getInventory() {
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the character's equipment.
|
|
||||||
*
|
|
||||||
* @return The character's equipment.
|
|
||||||
*/
|
|
||||||
public Inventory getEquipment() {
|
|
||||||
return equipment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the character's bank.
|
* Gets the character's bank.
|
||||||
*
|
*
|
||||||
@@ -135,68 +115,12 @@ public abstract class Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the local player list.
|
* Gets the {@link SynchronizationBlockSet}.
|
||||||
*
|
*
|
||||||
* @return The local player list.
|
* @return The block set.
|
||||||
*/
|
*/
|
||||||
public List<Player> getLocalPlayerList() {
|
public SynchronizationBlockSet getBlockSet() {
|
||||||
return localPlayers;
|
return blockSet;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this player is currently teleporting.
|
|
||||||
*
|
|
||||||
* @return {@code true} if so, {@code false} if not.
|
|
||||||
*/
|
|
||||||
public boolean isTeleporting() {
|
|
||||||
return teleporting;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the teleporting flag.
|
|
||||||
*
|
|
||||||
* @param teleporting {@code true} if the player is teleporting, {@code false} if not.
|
|
||||||
*/
|
|
||||||
public void setTeleporting(boolean teleporting) {
|
|
||||||
this.teleporting = teleporting;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the walking queue.
|
|
||||||
*
|
|
||||||
* @return The walking queue.
|
|
||||||
*/
|
|
||||||
public WalkingQueue getWalkingQueue() {
|
|
||||||
return walkingQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the next directions for this character.
|
|
||||||
*
|
|
||||||
* @param first The first direction.
|
|
||||||
* @param second The second direction.
|
|
||||||
*/
|
|
||||||
public void setDirections(Direction first, Direction second) {
|
|
||||||
this.firstDirection = first;
|
|
||||||
this.secondDirection = second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the first direction.
|
|
||||||
*
|
|
||||||
* @return The first direction.
|
|
||||||
*/
|
|
||||||
public Direction getFirstDirection() {
|
|
||||||
return firstDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the second direction.
|
|
||||||
*
|
|
||||||
* @return The second direction.
|
|
||||||
*/
|
|
||||||
public Direction getSecondDirection() {
|
|
||||||
return secondDirection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -217,30 +141,21 @@ public abstract class Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the position of this character.
|
* Gets the character's equipment.
|
||||||
*
|
*
|
||||||
* @return The position of this character.
|
* @return The character's equipment.
|
||||||
*/
|
*/
|
||||||
public Position getPosition() {
|
public Inventory getEquipment() {
|
||||||
return position;
|
return equipment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the position of this character.
|
* Gets the first direction.
|
||||||
*
|
*
|
||||||
* @param position The position of this character.
|
* @return The first direction.
|
||||||
*/
|
*/
|
||||||
public void setPosition(Position position) {
|
public Direction getFirstDirection() {
|
||||||
this.position = position;
|
return firstDirection;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this character is active.
|
|
||||||
*
|
|
||||||
* @return {@code true} if so, {@code false} if not.
|
|
||||||
*/
|
|
||||||
public boolean isActive() {
|
|
||||||
return index != -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -255,23 +170,118 @@ public abstract class Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the index of this character.
|
* Gets the character's inventory.
|
||||||
*
|
*
|
||||||
* @param index The index of this character.
|
* @return The character's inventory.
|
||||||
*/
|
*/
|
||||||
public void setIndex(int index) {
|
public Inventory getInventory() {
|
||||||
synchronized (this) {
|
return inventory;
|
||||||
this.index = index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link SynchronizationBlockSet}.
|
* Gets the local npc list.
|
||||||
*
|
*
|
||||||
* @return The block set.
|
* @return The local npc list.
|
||||||
*/
|
*/
|
||||||
public SynchronizationBlockSet getBlockSet() {
|
public List<Npc> getLocalNpcList() {
|
||||||
return blockSet;
|
return localNpcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the local player list.
|
||||||
|
*
|
||||||
|
* @return The local player list.
|
||||||
|
*/
|
||||||
|
public List<Player> getLocalPlayerList() {
|
||||||
|
return localPlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this character's {@link NpcDefinition}.
|
||||||
|
*
|
||||||
|
* @param definition The definition.
|
||||||
|
*/
|
||||||
|
public NpcDefinition getNpcDefinition() {
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position of this character.
|
||||||
|
*
|
||||||
|
* @return The position of this character.
|
||||||
|
*/
|
||||||
|
public Position getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the second direction.
|
||||||
|
*
|
||||||
|
* @return The second direction.
|
||||||
|
*/
|
||||||
|
public Direction getSecondDirection() {
|
||||||
|
return secondDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the character's skill set.
|
||||||
|
*
|
||||||
|
* @return The character's skill set.
|
||||||
|
*/
|
||||||
|
public SkillSet getSkillSet() {
|
||||||
|
return skillSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the walking queue.
|
||||||
|
*
|
||||||
|
* @return The walking queue.
|
||||||
|
*/
|
||||||
|
public WalkingQueue getWalkingQueue() {
|
||||||
|
return walkingQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises this character.
|
||||||
|
*/
|
||||||
|
private void init() {
|
||||||
|
World.getWorld().schedule(new SkillNormalizationTask(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this character is active.
|
||||||
|
*
|
||||||
|
* @return {@code true} if so, {@code false} if not.
|
||||||
|
*/
|
||||||
|
public boolean isActive() {
|
||||||
|
return index != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this player is currently teleporting.
|
||||||
|
*
|
||||||
|
* @return {@code true} if so, {@code false} if not.
|
||||||
|
*/
|
||||||
|
public boolean isTeleporting() {
|
||||||
|
return teleporting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays the specified animation.
|
||||||
|
*
|
||||||
|
* @param animation The animation.
|
||||||
|
*/
|
||||||
|
public void playAnimation(Animation animation) {
|
||||||
|
blockSet.add(SynchronizationBlock.createAnimationBlock(animation));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays the specified graphic.
|
||||||
|
*
|
||||||
|
* @param graphic The graphic.
|
||||||
|
*/
|
||||||
|
public void playGraphic(Graphic graphic) {
|
||||||
|
blockSet.add(SynchronizationBlock.createGraphicBlock(graphic));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -293,56 +303,52 @@ public abstract class Character {
|
|||||||
public abstract void send(Event event);
|
public abstract void send(Event event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Teleports this character to the specified position, setting the appropriate flags and clearing the walking queue.
|
* Sets this character's {@link NpcDefinition}.
|
||||||
*
|
*
|
||||||
* @param position The position.
|
* @param definition The definition.
|
||||||
*/
|
*/
|
||||||
public void teleport(Position position) {
|
public void setDefinition(NpcDefinition definition) {
|
||||||
this.teleporting = true;
|
this.definition = definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the next directions for this character.
|
||||||
|
*
|
||||||
|
* @param first The first direction.
|
||||||
|
* @param second The second direction.
|
||||||
|
*/
|
||||||
|
public void setDirections(Direction first, Direction second) {
|
||||||
|
this.firstDirection = first;
|
||||||
|
this.secondDirection = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the index of this character.
|
||||||
|
*
|
||||||
|
* @param index The index of this character.
|
||||||
|
*/
|
||||||
|
public void setIndex(int index) {
|
||||||
|
synchronized (this) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of this character.
|
||||||
|
*
|
||||||
|
* @param position The position of this character.
|
||||||
|
*/
|
||||||
|
public void setPosition(Position position) {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.walkingQueue.clear();
|
|
||||||
this.stopAction(); // TODO do it on any movement is a must.. walking queue perhaps?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays the specified animation.
|
* Sets the teleporting flag.
|
||||||
*
|
*
|
||||||
* @param animation The animation.
|
* @param teleporting {@code true} if the player is teleporting, {@code false} if not.
|
||||||
*/
|
*/
|
||||||
public void playAnimation(Animation animation) {
|
public void setTeleporting(boolean teleporting) {
|
||||||
blockSet.add(SynchronizationBlock.createAnimationBlock(animation));
|
this.teleporting = teleporting;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops the current animation.
|
|
||||||
*/
|
|
||||||
public void stopAnimation() {
|
|
||||||
playAnimation(Animation.STOP_ANIMATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plays the specified graphic.
|
|
||||||
*
|
|
||||||
* @param graphic The graphic.
|
|
||||||
*/
|
|
||||||
public void playGraphic(Graphic graphic) {
|
|
||||||
blockSet.add(SynchronizationBlock.createGraphicBlock(graphic));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops the current graphic.
|
|
||||||
*/
|
|
||||||
public void stopGraphic() {
|
|
||||||
playGraphic(Graphic.STOP_GRAPHIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the character's skill set.
|
|
||||||
*
|
|
||||||
* @return The character's skill set.
|
|
||||||
*/
|
|
||||||
public SkillSet getSkillSet() {
|
|
||||||
return skillSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -373,6 +379,32 @@ public abstract class Character {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the current animation.
|
||||||
|
*/
|
||||||
|
public void stopAnimation() {
|
||||||
|
playAnimation(Animation.STOP_ANIMATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the current graphic.
|
||||||
|
*/
|
||||||
|
public void stopGraphic() {
|
||||||
|
playGraphic(Graphic.STOP_GRAPHIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teleports this character to the specified position, setting the appropriate flags and clearing the walking queue.
|
||||||
|
*
|
||||||
|
* @param position The position.
|
||||||
|
*/
|
||||||
|
public void teleport(Position position) {
|
||||||
|
this.teleporting = true;
|
||||||
|
this.position = position;
|
||||||
|
this.walkingQueue.clear();
|
||||||
|
this.stopAction(); // TODO do it on any movement is a must.. walking queue perhaps?
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns the character to face the specified position.
|
* Turns the character to face the specified position.
|
||||||
*
|
*
|
||||||
@@ -391,22 +423,4 @@ public abstract class Character {
|
|||||||
blockSet.add(SynchronizationBlock.createInteractingCharacterBlock(index));
|
blockSet.add(SynchronizationBlock.createInteractingCharacterBlock(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets this character's {@link NpcDefinition}.
|
|
||||||
*
|
|
||||||
* @param definition The definition.
|
|
||||||
*/
|
|
||||||
public NpcDefinition getNpcDefinition() {
|
|
||||||
return definition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets this character's {@link NpcDefinition}.
|
|
||||||
*
|
|
||||||
* @param definition The definition.
|
|
||||||
*/
|
|
||||||
public void setDefinition(NpcDefinition definition) {
|
|
||||||
this.definition = definition;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -35,9 +35,9 @@ public final class Player extends Character {
|
|||||||
public enum PrivilegeLevel {
|
public enum PrivilegeLevel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A standard (rights 0) account.
|
* An administrator (rights 2) account.
|
||||||
*/
|
*/
|
||||||
STANDARD(0),
|
ADMINISTRATOR(2),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A player moderator (rights 1) account.
|
* A player moderator (rights 1) account.
|
||||||
@@ -45,9 +45,9 @@ public final class Player extends Character {
|
|||||||
MODERATOR(1),
|
MODERATOR(1),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An administrator (rights 2) account.
|
* A standard (rights 0) account.
|
||||||
*/
|
*/
|
||||||
ADMINISTRATOR(2);
|
STANDARD(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the privilege level for the specified numerical level.
|
* Gets the privilege level for the specified numerical level.
|
||||||
@@ -90,45 +90,7 @@ public final class Player extends Character {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A temporary queue of events sent during the login process.
|
|
||||||
*/
|
|
||||||
private final Queue<Event> queuedEvents = new ArrayDeque<Event>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The player's credentials.
|
|
||||||
*/
|
|
||||||
private PlayerCredentials credentials;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The privilege level.
|
|
||||||
*/
|
|
||||||
private PrivilegeLevel privilegeLevel = PrivilegeLevel.STANDARD;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The membership flag.
|
|
||||||
*/
|
|
||||||
private boolean members = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag indicating if the player has designed their character.
|
|
||||||
*/
|
|
||||||
private boolean designedCharacter = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link GameSession} currently attached to this {@link Player}.
|
|
||||||
*/
|
|
||||||
private GameSession session;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The centre of the last region the client has loaded.
|
|
||||||
*/
|
|
||||||
private Position lastKnownRegion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag indicating if the region changed in the last cycle.
|
|
||||||
*/
|
|
||||||
private boolean regionChanged = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The player's appearance.
|
* The player's appearance.
|
||||||
@@ -136,9 +98,19 @@ public final class Player extends Character {
|
|||||||
private Appearance appearance = Appearance.DEFAULT_APPEARANCE;
|
private Appearance appearance = Appearance.DEFAULT_APPEARANCE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current maximum viewing distance of this player.
|
* The player's credentials.
|
||||||
*/
|
*/
|
||||||
private int viewingDistance = 1;
|
private PlayerCredentials credentials;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag indicating if the player has designed their character.
|
||||||
|
*/
|
||||||
|
private boolean designedCharacter = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag which indicates there are npcs that couldn't be added.
|
||||||
|
*/
|
||||||
|
private boolean excessiveNpcs = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flag which indicates there are players that couldn't be added.
|
* A flag which indicates there are players that couldn't be added.
|
||||||
@@ -150,15 +122,50 @@ public final class Player extends Character {
|
|||||||
*/
|
*/
|
||||||
private int headIcon = -1;
|
private int headIcon = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This player's interface set.
|
||||||
|
*/
|
||||||
|
private final InterfaceSet interfaceSet = new InterfaceSet(this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The centre of the last region the client has loaded.
|
||||||
|
*/
|
||||||
|
private Position lastKnownRegion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The membership flag.
|
||||||
|
*/
|
||||||
|
private boolean members = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This player's prayer icon.
|
* This player's prayer icon.
|
||||||
*/
|
*/
|
||||||
private int prayerIcon = -1;
|
private int prayerIcon = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This player's interface set.
|
* The privilege level.
|
||||||
*/
|
*/
|
||||||
private final InterfaceSet interfaceSet = new InterfaceSet(this);
|
private PrivilegeLevel privilegeLevel = PrivilegeLevel.STANDARD;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A temporary queue of events sent during the login process.
|
||||||
|
*/
|
||||||
|
private final Queue<Event> queuedEvents = new ArrayDeque<Event>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag indicating if the region changed in the last cycle.
|
||||||
|
*/
|
||||||
|
private boolean regionChanged = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link GameSession} currently attached to this {@link Player}.
|
||||||
|
*/
|
||||||
|
private GameSession session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current maximum viewing distance of this player.
|
||||||
|
*/
|
||||||
|
private int viewingDistance = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flag indicating if the player is withdrawing items as notes.
|
* A flag indicating if the player is withdrawing items as notes.
|
||||||
@@ -178,21 +185,19 @@ public final class Player extends Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets this player's interface set.
|
* Decrements this player's viewing distance if it is greater than 1.
|
||||||
*
|
|
||||||
* @return The interface set for this player.
|
|
||||||
*/
|
*/
|
||||||
public InterfaceSet getInterfaceSet() {
|
public void decrementViewingDistance() {
|
||||||
return interfaceSet;
|
if (viewingDistance > 1) { // TODO should it be 0?
|
||||||
|
viewingDistance--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if there are excessive players.
|
* Sets the excessive npcs flag.
|
||||||
*
|
|
||||||
* @return {@code true} if so, {@code false} if not.
|
|
||||||
*/
|
*/
|
||||||
public boolean isExcessivePlayersSet() {
|
public void flagExcessiveNpcs() {
|
||||||
return excessivePlayers;
|
this.excessiveNpcs = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -203,53 +208,48 @@ public final class Player extends Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the excessive players flag.
|
* Gets the player's appearance.
|
||||||
*/
|
|
||||||
public void resetExcessivePlayers() {
|
|
||||||
excessivePlayers = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets this player's viewing distance.
|
|
||||||
*/
|
|
||||||
public void resetViewingDistance() {
|
|
||||||
viewingDistance = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets this player's viewing distance.
|
|
||||||
*
|
*
|
||||||
* @return The viewing distance.
|
* @return The appearance.
|
||||||
*/
|
*/
|
||||||
public int getViewingDistance() {
|
public Appearance getAppearance() {
|
||||||
return viewingDistance;
|
return appearance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments this player's viewing distance if it is less than the maximum viewing distance.
|
* Gets the player's credentials.
|
||||||
*/
|
|
||||||
public void incrementViewingDistance() {
|
|
||||||
if (viewingDistance < Position.MAX_DISTANCE) {
|
|
||||||
viewingDistance++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decrements this player's viewing distance if it is greater than 1.
|
|
||||||
*/
|
|
||||||
public void decrementViewingDistance() {
|
|
||||||
if (viewingDistance > 1) { // TODO should it be 0?
|
|
||||||
viewingDistance--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this player has ever known a region.
|
|
||||||
*
|
*
|
||||||
* @return {@code true} if so, {@code false} if not.
|
* @return The player's credentials.
|
||||||
*/
|
*/
|
||||||
public boolean hasLastKnownRegion() {
|
public PlayerCredentials getCredentials() {
|
||||||
return lastKnownRegion != null;
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player's name, encoded as a long.
|
||||||
|
*
|
||||||
|
* @return The encoded player name.
|
||||||
|
*/
|
||||||
|
public long getEncodedName() {
|
||||||
|
return credentials.getEncodedUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player's head icon.
|
||||||
|
*
|
||||||
|
* @return The head icon.
|
||||||
|
*/
|
||||||
|
public int getHeadIcon() {
|
||||||
|
return headIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this player's interface set.
|
||||||
|
*
|
||||||
|
* @return The interface set for this player.
|
||||||
|
*/
|
||||||
|
public InterfaceSet getInterfaceSet() {
|
||||||
|
return interfaceSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -262,12 +262,21 @@ public final class Player extends Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the last known region.
|
* Gets the player's name.
|
||||||
*
|
*
|
||||||
* @param lastKnownRegion The last known region.
|
* @return The player's name.
|
||||||
*/
|
*/
|
||||||
public void setLastKnownRegion(Position lastKnownRegion) {
|
public String getName() {
|
||||||
this.lastKnownRegion = lastKnownRegion;
|
return credentials.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player's prayer icon.
|
||||||
|
*
|
||||||
|
* @return The prayer icon.
|
||||||
|
*/
|
||||||
|
public int getPrayerIcon() {
|
||||||
|
return prayerIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -280,67 +289,56 @@ public final class Player extends Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the privilege level.
|
* Gets the game session.
|
||||||
*
|
*
|
||||||
* @param privilegeLevel The privilege level.
|
* @return The game session.
|
||||||
*/
|
*/
|
||||||
public void setPrivilegeLevel(PrivilegeLevel privilegeLevel) {
|
public GameSession getSession() {
|
||||||
this.privilegeLevel = privilegeLevel;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if this player account has membership.
|
* Gets this player's viewing distance.
|
||||||
|
*
|
||||||
|
* @return The viewing distance.
|
||||||
|
*/
|
||||||
|
public int getViewingDistance() {
|
||||||
|
return viewingDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the player has designed their character.
|
||||||
|
*
|
||||||
|
* @return A flag indicating if the player has designed their character.
|
||||||
|
*/
|
||||||
|
public boolean hasDesignedCharacter() {
|
||||||
|
return designedCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this player has ever known a region.
|
||||||
*
|
*
|
||||||
* @return {@code true} if so, {@code false} if not.
|
* @return {@code true} if so, {@code false} if not.
|
||||||
*/
|
*/
|
||||||
public boolean isMembers() {
|
public boolean hasLastKnownRegion() {
|
||||||
return members;
|
return lastKnownRegion != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the membership status of this player.
|
* Checks if the region has changed.
|
||||||
*
|
*
|
||||||
* @param members The new membership flag.
|
* @return {@code true} if so, {@code false} if not.
|
||||||
*/
|
*/
|
||||||
public void setMembers(boolean members) {
|
public boolean hasRegionChanged() {
|
||||||
this.members = members;
|
return regionChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the player's {@link GameSession}.
|
* Increments this player's viewing distance if it is less than the maximum viewing distance.
|
||||||
*
|
|
||||||
* @param session The player's {@link GameSession}.
|
|
||||||
* @param reconnecting The reconnecting flag.
|
|
||||||
*/
|
*/
|
||||||
public void setSession(GameSession session, boolean reconnecting) {
|
public void incrementViewingDistance() {
|
||||||
this.session = session;
|
if (viewingDistance < Position.MAX_DISTANCE) {
|
||||||
if (!reconnecting) {
|
viewingDistance++;
|
||||||
sendInitialEvents();
|
|
||||||
}
|
|
||||||
getBlockSet().add(SynchronizationBlock.createAppearanceBlock(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's credentials.
|
|
||||||
*
|
|
||||||
* @return The player's credentials.
|
|
||||||
*/
|
|
||||||
public PlayerCredentials getCredentials() {
|
|
||||||
return credentials;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(Event event) {
|
|
||||||
if (isActive()) {
|
|
||||||
if (!queuedEvents.isEmpty()) {
|
|
||||||
for (Event queuedEvent : queuedEvents) {
|
|
||||||
session.dispatchEvent(queuedEvent);
|
|
||||||
}
|
|
||||||
queuedEvents.clear();
|
|
||||||
}
|
|
||||||
session.dispatchEvent(event);
|
|
||||||
} else {
|
|
||||||
queuedEvents.add(event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,23 +350,6 @@ public final class Player extends Character {
|
|||||||
initSkills();
|
initSkills();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialises the player's skills.
|
|
||||||
*/
|
|
||||||
private void initSkills() {
|
|
||||||
SkillSet skills = getSkillSet();
|
|
||||||
|
|
||||||
// synchronization listener
|
|
||||||
SkillListener syncListener = new SynchronizationSkillListener(this);
|
|
||||||
|
|
||||||
// level up listener
|
|
||||||
SkillListener levelUpListener = new LevelUpSkillListener(this);
|
|
||||||
|
|
||||||
// add the listeners
|
|
||||||
skills.addListener(syncListener);
|
|
||||||
skills.addListener(levelUpListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the player's inventories.
|
* Initialises the player's inventories.
|
||||||
*/
|
*/
|
||||||
@@ -406,6 +387,95 @@ public final class Player extends Character {
|
|||||||
equipment.addListener(fullEquipmentListener);
|
equipment.addListener(fullEquipmentListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises the player's skills.
|
||||||
|
*/
|
||||||
|
private void initSkills() {
|
||||||
|
SkillSet skills = getSkillSet();
|
||||||
|
|
||||||
|
// synchronization listener
|
||||||
|
SkillListener syncListener = new SynchronizationSkillListener(this);
|
||||||
|
|
||||||
|
// level up listener
|
||||||
|
SkillListener levelUpListener = new LevelUpSkillListener(this);
|
||||||
|
|
||||||
|
// add the listeners
|
||||||
|
skills.addListener(syncListener);
|
||||||
|
skills.addListener(levelUpListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there are excessive npcs.
|
||||||
|
*
|
||||||
|
* @return {@code true} if so, {@code false} if not.
|
||||||
|
*/
|
||||||
|
public boolean isExcessiveNpcsSet() {
|
||||||
|
return excessiveNpcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there are excessive players.
|
||||||
|
*
|
||||||
|
* @return {@code true} if so, {@code false} if not.
|
||||||
|
*/
|
||||||
|
public boolean isExcessivePlayersSet() {
|
||||||
|
return excessivePlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this player account has membership.
|
||||||
|
*
|
||||||
|
* @return {@code true} if so, {@code false} if not.
|
||||||
|
*/
|
||||||
|
public boolean isMembers() {
|
||||||
|
return members;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the withdrawing notes flag.
|
||||||
|
*
|
||||||
|
* @return The flag.
|
||||||
|
*/
|
||||||
|
public boolean isWithdrawingNotes() {
|
||||||
|
return withdrawingNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the player out, if possible.
|
||||||
|
*/
|
||||||
|
public void logout() {
|
||||||
|
send(new LogoutEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the excessive players flag.
|
||||||
|
*/
|
||||||
|
public void resetExcessivePlayers() {
|
||||||
|
excessivePlayers = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets this player's viewing distance.
|
||||||
|
*/
|
||||||
|
public void resetViewingDistance() {
|
||||||
|
viewingDistance = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(Event event) {
|
||||||
|
if (isActive()) {
|
||||||
|
if (!queuedEvents.isEmpty()) {
|
||||||
|
for (Event queuedEvent : queuedEvents) {
|
||||||
|
session.dispatchEvent(queuedEvent);
|
||||||
|
}
|
||||||
|
queuedEvents.clear();
|
||||||
|
}
|
||||||
|
session.dispatchEvent(event);
|
||||||
|
} else {
|
||||||
|
queuedEvents.add(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the initial events.
|
* Sends the initial events.
|
||||||
*/
|
*/
|
||||||
@@ -438,37 +508,13 @@ public final class Player extends Character {
|
|||||||
getSkillSet().forceRefresh();
|
getSkillSet().forceRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return Player.class.getName() + " [username=" + credentials.getUsername() + ", privilegeLevel="
|
|
||||||
+ privilegeLevel + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the region changed flag.
|
* Sends a message to the character.
|
||||||
*
|
*
|
||||||
* @param regionChanged A flag indicating if the region has changed.
|
* @param message The message.
|
||||||
*/
|
*/
|
||||||
public void setRegionChanged(boolean regionChanged) {
|
public void sendMessage(String message) {
|
||||||
this.regionChanged = regionChanged;
|
send(new ServerMessageEvent(message));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the region has changed.
|
|
||||||
*
|
|
||||||
* @return {@code true} if so, {@code false} if not.
|
|
||||||
*/
|
|
||||||
public boolean hasRegionChanged() {
|
|
||||||
return regionChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's appearance.
|
|
||||||
*
|
|
||||||
* @return The appearance.
|
|
||||||
*/
|
|
||||||
public Appearance getAppearance() {
|
|
||||||
return appearance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -481,40 +527,6 @@ public final class Player extends Character {
|
|||||||
this.getBlockSet().add(SynchronizationBlock.createAppearanceBlock(this));
|
this.getBlockSet().add(SynchronizationBlock.createAppearanceBlock(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's name.
|
|
||||||
*
|
|
||||||
* @return The player's name.
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return credentials.getUsername();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's name, encoded as a long.
|
|
||||||
*
|
|
||||||
* @return The encoded player name.
|
|
||||||
*/
|
|
||||||
public long getEncodedName() {
|
|
||||||
return credentials.getEncodedUsername();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs the player out, if possible.
|
|
||||||
*/
|
|
||||||
public void logout() {
|
|
||||||
send(new LogoutEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the game session.
|
|
||||||
*
|
|
||||||
* @return The game session.
|
|
||||||
*/
|
|
||||||
public GameSession getSession() {
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the character design flag.
|
* Sets the character design flag.
|
||||||
*
|
*
|
||||||
@@ -525,21 +537,71 @@ public final class Player extends Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the player has designed their character.
|
* Sets the player's head icon.
|
||||||
*
|
*
|
||||||
* @return A flag indicating if the player has designed their character.
|
* @param headIcon The head icon.
|
||||||
*/
|
*/
|
||||||
public boolean hasDesignedCharacter() {
|
public void setHeadIcon(int headIcon) {
|
||||||
return designedCharacter;
|
this.headIcon = headIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the withdrawing notes flag.
|
* Sets the last known region.
|
||||||
*
|
*
|
||||||
* @return The flag.
|
* @param lastKnownRegion The last known region.
|
||||||
*/
|
*/
|
||||||
public boolean isWithdrawingNotes() {
|
public void setLastKnownRegion(Position lastKnownRegion) {
|
||||||
return withdrawingNotes;
|
this.lastKnownRegion = lastKnownRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the membership status of this player.
|
||||||
|
*
|
||||||
|
* @param members The new membership flag.
|
||||||
|
*/
|
||||||
|
public void setMembers(boolean members) {
|
||||||
|
this.members = members;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the player's prayer icon.
|
||||||
|
*
|
||||||
|
* @param prayerIcon The prayer icon.
|
||||||
|
*/
|
||||||
|
public void setPrayerIcon(int prayerIcon) {
|
||||||
|
this.prayerIcon = prayerIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the privilege level.
|
||||||
|
*
|
||||||
|
* @param privilegeLevel The privilege level.
|
||||||
|
*/
|
||||||
|
public void setPrivilegeLevel(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 {@link GameSession}.
|
||||||
|
*
|
||||||
|
* @param session The player's {@link GameSession}.
|
||||||
|
* @param reconnecting The reconnecting flag.
|
||||||
|
*/
|
||||||
|
public void setSession(GameSession session, boolean reconnecting) {
|
||||||
|
this.session = session;
|
||||||
|
if (!reconnecting) {
|
||||||
|
sendInitialEvents();
|
||||||
|
}
|
||||||
|
getBlockSet().add(SynchronizationBlock.createAppearanceBlock(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -557,49 +619,10 @@ public final class Player extends Character {
|
|||||||
interfaceSet.close(); // TODO: should this be done if size == 0?
|
interfaceSet.close(); // TODO: should this be done if size == 0?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Gets the player's prayer icon.
|
public String toString() {
|
||||||
*
|
return Player.class.getName() + " [username=" + credentials.getUsername() + ", privilegeLevel="
|
||||||
* @return The prayer icon.
|
+ privilegeLevel + "]";
|
||||||
*/
|
|
||||||
public int getPrayerIcon() {
|
|
||||||
return prayerIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the player's head icon.
|
|
||||||
*
|
|
||||||
* @return The head icon.
|
|
||||||
*/
|
|
||||||
public int getHeadIcon() {
|
|
||||||
return headIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a message to the character.
|
|
||||||
*
|
|
||||||
* @param message The message.
|
|
||||||
*/
|
|
||||||
public void sendMessage(String message) {
|
|
||||||
send(new ServerMessageEvent(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the player's head icon.
|
|
||||||
*
|
|
||||||
* @param headIcon The head icon.
|
|
||||||
*/
|
|
||||||
public void setHeadIcon(int headIcon) {
|
|
||||||
this.headIcon = headIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the player's prayer icon.
|
|
||||||
*
|
|
||||||
* @param prayerIcon The prayer icon.
|
|
||||||
*/
|
|
||||||
public void setPrayerIcon(int prayerIcon) {
|
|
||||||
this.prayerIcon = prayerIcon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -33,16 +33,6 @@ import org.apollo.util.plugin.PluginManager;
|
|||||||
*/
|
*/
|
||||||
public final class World {
|
public final class World {
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger for this class.
|
|
||||||
*/
|
|
||||||
private static final Logger logger = Logger.getLogger(World.class.getName());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The world.
|
|
||||||
*/
|
|
||||||
private static final World world = new World();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the different status codes for registering a player.
|
* Represents the different status codes for registering a player.
|
||||||
*
|
*
|
||||||
@@ -50,11 +40,6 @@ public final class World {
|
|||||||
*/
|
*/
|
||||||
public enum RegistrationStatus {
|
public enum RegistrationStatus {
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates the world is full.
|
|
||||||
*/
|
|
||||||
WORLD_FULL,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the player is already online.
|
* Indicates that the player is already online.
|
||||||
*/
|
*/
|
||||||
@@ -63,9 +48,24 @@ public final class World {
|
|||||||
/**
|
/**
|
||||||
* Indicates that the player was registered successfully.
|
* Indicates that the player was registered successfully.
|
||||||
*/
|
*/
|
||||||
OK;
|
OK,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the world is full.
|
||||||
|
*/
|
||||||
|
WORLD_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logger for this class.
|
||||||
|
*/
|
||||||
|
private static final Logger logger = Logger.getLogger(World.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The world.
|
||||||
|
*/
|
||||||
|
private static final World world = new World();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the world.
|
* Gets the world.
|
||||||
*
|
*
|
||||||
@@ -75,20 +75,16 @@ public final class World {
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The scheduler.
|
|
||||||
*/
|
|
||||||
// TODO: better place than here?
|
|
||||||
private final Scheduler scheduler = new Scheduler();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The command dispatcher.
|
* The command dispatcher.
|
||||||
*/
|
*/
|
||||||
// TODO: better place than here?
|
// TODO: better place than here?
|
||||||
private final CommandDispatcher dispatcher = new CommandDispatcher();
|
private final CommandDispatcher dispatcher = new CommandDispatcher();
|
||||||
|
|
||||||
// TODO: better place than here!!
|
/**
|
||||||
private PluginManager pluginManager;
|
* The {@link CharacterRepository} of {@link Npc}s.
|
||||||
|
*/
|
||||||
|
private final CharacterRepository<Npc> npcRepository = new CharacterRepository<Npc>(WorldConstants.MAXIMUM_NPCS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link CharacterRepository} of {@link Player}s.
|
* The {@link CharacterRepository} of {@link Player}s.
|
||||||
@@ -96,6 +92,15 @@ public final class World {
|
|||||||
private final CharacterRepository<Player> playerRepository = new CharacterRepository<Player>(
|
private final CharacterRepository<Player> playerRepository = new CharacterRepository<Player>(
|
||||||
WorldConstants.MAXIMUM_PLAYERS);
|
WorldConstants.MAXIMUM_PLAYERS);
|
||||||
|
|
||||||
|
// TODO: better place than here!!
|
||||||
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scheduler.
|
||||||
|
*/
|
||||||
|
// TODO: better place than here?
|
||||||
|
private final Scheduler scheduler = new Scheduler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the world.
|
* Creates the world.
|
||||||
*/
|
*/
|
||||||
@@ -103,6 +108,47 @@ public final class World {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the command dispatcher. TODO should this be here?
|
||||||
|
*
|
||||||
|
* @return The command dispatcher.
|
||||||
|
*/
|
||||||
|
public CommandDispatcher getCommandDispatcher() {
|
||||||
|
return dispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the npc repository.
|
||||||
|
*
|
||||||
|
* @return The npc repository.
|
||||||
|
*/
|
||||||
|
public CharacterRepository<Npc> getNpcRepository() {
|
||||||
|
return npcRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the character repository. NOTE: {@link CharacterRepository#add(Character)} and
|
||||||
|
* {@link CharacterRepository#remove(Character)} should not be called directly! These mutation methods are not
|
||||||
|
* guaranteed to work in future releases!
|
||||||
|
* <p>
|
||||||
|
* Instead, use the {@link World#register(Player)} and {@link World#unregister(Player)} methods which do the same
|
||||||
|
* thing and will continue to work as normal in future releases.
|
||||||
|
*
|
||||||
|
* @return The character repository.
|
||||||
|
*/
|
||||||
|
public CharacterRepository<Player> getPlayerRepository() {
|
||||||
|
return playerRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the plugin manager. TODO should this be here?
|
||||||
|
*
|
||||||
|
* @return The plugin manager.
|
||||||
|
*/
|
||||||
|
public PluginManager getPluginManager() {
|
||||||
|
return pluginManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises the world by loading definitions from the specified file system.
|
* Initialises the world by loading definitions from the specified file system.
|
||||||
*
|
*
|
||||||
@@ -147,17 +193,42 @@ public final class World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the character repository. NOTE: {@link CharacterRepository#add(Character)} and
|
* Checks if the specified player is online.
|
||||||
* {@link CharacterRepository#remove(Character)} should not be called directly! These mutation methods are not
|
|
||||||
* guaranteed to work in future releases!
|
|
||||||
* <p>
|
|
||||||
* Instead, use the {@link World#register(Player)} and {@link World#unregister(Player)} methods which do the same
|
|
||||||
* thing and will continue to work as normal in future releases.
|
|
||||||
*
|
*
|
||||||
* @return The character repository.
|
* @param name The player's name.
|
||||||
|
* @return {@code true} if so, {@code false} if not.
|
||||||
*/
|
*/
|
||||||
public CharacterRepository<Player> getPlayerRepository() {
|
public boolean isPlayerOnline(String name) {
|
||||||
return playerRepository;
|
// TODO: use a hash set or map in the future?
|
||||||
|
for (Player player : playerRepository) {
|
||||||
|
if (player.getName().equalsIgnoreCase(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the {@link Scheduler#pulse()} method.
|
||||||
|
*/
|
||||||
|
public void pulse() {
|
||||||
|
scheduler.pulse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the specified npc.
|
||||||
|
*
|
||||||
|
* @param npc The npc.
|
||||||
|
* @return {@code true} if the npc registered successfully, otherwise {@code false}.
|
||||||
|
*/
|
||||||
|
public boolean register(final Npc npc) {
|
||||||
|
boolean success = npcRepository.add(npc);
|
||||||
|
if (success) {
|
||||||
|
logger.info("Registered npc: " + npc + " [online=" + npcRepository.size() + "]");
|
||||||
|
} else {
|
||||||
|
logger.warning("Failed to register npc, repository capacity reached: [online=" + npcRepository.size() + "]");
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,19 +254,25 @@ public final class World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the specified player is online.
|
* Schedules a new task.
|
||||||
*
|
*
|
||||||
* @param name The player's name.
|
* @param task The {@link ScheduledTask}.
|
||||||
* @return {@code true} if so, {@code false} if not.
|
|
||||||
*/
|
*/
|
||||||
public boolean isPlayerOnline(String name) {
|
public void schedule(ScheduledTask task) {
|
||||||
// TODO: use a hash set or map in the future?
|
scheduler.schedule(task);
|
||||||
for (Player player : playerRepository) {
|
|
||||||
if (player.getName().equalsIgnoreCase(name)) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters the specified {@link Npc}.
|
||||||
|
*
|
||||||
|
* @param npc The npc.
|
||||||
|
*/
|
||||||
|
public void unregister(Npc npc) {
|
||||||
|
if (npcRepository.remove(npc)) {
|
||||||
|
logger.info("Unregistered npc: " + npc + " [online=" + npcRepository.size() + "]");
|
||||||
|
} else {
|
||||||
|
logger.warning("Could not find npc " + npc + " to unregister!");
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,38 +288,4 @@ public final class World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedules a new task.
|
|
||||||
*
|
|
||||||
* @param task The {@link ScheduledTask}.
|
|
||||||
*/
|
|
||||||
public void schedule(ScheduledTask task) {
|
|
||||||
scheduler.schedule(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the {@link Scheduler#pulse()} method.
|
|
||||||
*/
|
|
||||||
public void pulse() {
|
|
||||||
scheduler.pulse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the command dispatcher. TODO should this be here?
|
|
||||||
*
|
|
||||||
* @return The command dispatcher.
|
|
||||||
*/
|
|
||||||
public CommandDispatcher getCommandDispatcher() {
|
|
||||||
return dispatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the plugin manager. TODO should this be here?
|
|
||||||
*
|
|
||||||
* @return The plugin manager.
|
|
||||||
*/
|
|
||||||
public PluginManager getPluginManager() {
|
|
||||||
return pluginManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ package org.apollo.game.model;
|
|||||||
*/
|
*/
|
||||||
public final class WorldConstants {
|
public final class WorldConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of npcs.
|
||||||
|
*/
|
||||||
|
public static final int MAXIMUM_NPCS = 2000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of players.
|
* The maximum number of players.
|
||||||
*/
|
*/
|
||||||
@@ -16,7 +21,6 @@ public final class WorldConstants {
|
|||||||
* Default private constructor to prevent instantiation by other classes.
|
* Default private constructor to prevent instantiation by other classes.
|
||||||
*/
|
*/
|
||||||
private WorldConstants() {
|
private WorldConstants() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,11 +6,15 @@ 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.model.Player;
|
import org.apollo.game.model.Npc;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.model.Player;
|
||||||
|
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.PhasedSynchronizationTask;
|
import org.apollo.game.sync.task.PhasedSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.PlayerSynchronizationTask;
|
import org.apollo.game.sync.task.PlayerSynchronizationTask;
|
||||||
|
import org.apollo.game.sync.task.PostNpcSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.PostPlayerSynchronizationTask;
|
import org.apollo.game.sync.task.PostPlayerSynchronizationTask;
|
||||||
|
import org.apollo.game.sync.task.PreNpcSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.PrePlayerSynchronizationTask;
|
import org.apollo.game.sync.task.PrePlayerSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.SynchronizationTask;
|
import org.apollo.game.sync.task.SynchronizationTask;
|
||||||
import org.apollo.util.CharacterRepository;
|
import org.apollo.util.CharacterRepository;
|
||||||
@@ -24,6 +28,7 @@ import org.apollo.util.NamedThreadFactory;
|
|||||||
* will work.
|
* will work.
|
||||||
*
|
*
|
||||||
* @author Graham
|
* @author Graham
|
||||||
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
||||||
|
|
||||||
@@ -50,7 +55,9 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
|||||||
@Override
|
@Override
|
||||||
public void synchronize() {
|
public void synchronize() {
|
||||||
CharacterRepository<Player> players = World.getWorld().getPlayerRepository();
|
CharacterRepository<Player> players = World.getWorld().getPlayerRepository();
|
||||||
|
CharacterRepository<Npc> npcs = World.getWorld().getNpcRepository();
|
||||||
int playerCount = players.size();
|
int playerCount = players.size();
|
||||||
|
int npcCount = npcs.size();
|
||||||
|
|
||||||
phaser.bulkRegister(playerCount);
|
phaser.bulkRegister(playerCount);
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
@@ -59,6 +66,13 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
|||||||
}
|
}
|
||||||
phaser.arriveAndAwaitAdvance();
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
|
||||||
|
phaser.bulkRegister(npcCount);
|
||||||
|
for (Npc npc : npcs) {
|
||||||
|
SynchronizationTask task = new PreNpcSynchronizationTask(npc);
|
||||||
|
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
||||||
|
}
|
||||||
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
|
||||||
phaser.bulkRegister(playerCount);
|
phaser.bulkRegister(playerCount);
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
SynchronizationTask task = new PlayerSynchronizationTask(player);
|
SynchronizationTask task = new PlayerSynchronizationTask(player);
|
||||||
@@ -66,12 +80,26 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
|||||||
}
|
}
|
||||||
phaser.arriveAndAwaitAdvance();
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
|
||||||
|
phaser.bulkRegister(playerCount);
|
||||||
|
for (Player player : players) {
|
||||||
|
SynchronizationTask task = new NpcSynchronizationTask(player);
|
||||||
|
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
||||||
|
}
|
||||||
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
|
||||||
phaser.bulkRegister(playerCount);
|
phaser.bulkRegister(playerCount);
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
SynchronizationTask task = new PostPlayerSynchronizationTask(player);
|
SynchronizationTask task = new PostPlayerSynchronizationTask(player);
|
||||||
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
||||||
}
|
}
|
||||||
phaser.arriveAndAwaitAdvance();
|
phaser.arriveAndAwaitAdvance();
|
||||||
|
|
||||||
|
phaser.bulkRegister(npcCount);
|
||||||
|
for (Npc npc : npcs) {
|
||||||
|
SynchronizationTask task = new PostNpcSynchronizationTask(npc);
|
||||||
|
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
||||||
|
}
|
||||||
|
phaser.arriveAndAwaitAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
package org.apollo.game.sync;
|
package org.apollo.game.sync;
|
||||||
|
|
||||||
import org.apollo.game.GameService;
|
import org.apollo.game.GameService;
|
||||||
import org.apollo.game.model.Player;
|
import org.apollo.game.model.Npc;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.model.Player;
|
||||||
|
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.PlayerSynchronizationTask;
|
import org.apollo.game.sync.task.PlayerSynchronizationTask;
|
||||||
|
import org.apollo.game.sync.task.PostNpcSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.PostPlayerSynchronizationTask;
|
import org.apollo.game.sync.task.PostPlayerSynchronizationTask;
|
||||||
|
import org.apollo.game.sync.task.PreNpcSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.PrePlayerSynchronizationTask;
|
import org.apollo.game.sync.task.PrePlayerSynchronizationTask;
|
||||||
import org.apollo.game.sync.task.SynchronizationTask;
|
import org.apollo.game.sync.task.SynchronizationTask;
|
||||||
import org.apollo.util.CharacterRepository;
|
import org.apollo.util.CharacterRepository;
|
||||||
@@ -16,27 +20,41 @@ import org.apollo.util.CharacterRepository;
|
|||||||
* cores/processors, however, both classes will work.
|
* cores/processors, however, both classes will work.
|
||||||
*
|
*
|
||||||
* @author Graham
|
* @author Graham
|
||||||
|
* @author Major
|
||||||
*/
|
*/
|
||||||
public final class SequentialClientSynchronizer extends ClientSynchronizer {
|
public final class SequentialClientSynchronizer extends ClientSynchronizer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void synchronize() {
|
public void synchronize() {
|
||||||
CharacterRepository<Player> players = World.getWorld().getPlayerRepository();
|
CharacterRepository<Player> players = World.getWorld().getPlayerRepository();
|
||||||
|
CharacterRepository<Npc> npcs = World.getWorld().getNpcRepository();
|
||||||
|
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
SynchronizationTask task = new PrePlayerSynchronizationTask(player);
|
SynchronizationTask task = new PrePlayerSynchronizationTask(player);
|
||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Npc npc : npcs) {
|
||||||
|
SynchronizationTask task = new PreNpcSynchronizationTask(npc);
|
||||||
|
task.run();
|
||||||
|
}
|
||||||
|
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
SynchronizationTask task = new PlayerSynchronizationTask(player);
|
SynchronizationTask task = new PlayerSynchronizationTask(player);
|
||||||
task.run();
|
task.run();
|
||||||
|
task = new NpcSynchronizationTask(player);
|
||||||
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
SynchronizationTask task = new PostPlayerSynchronizationTask(player);
|
SynchronizationTask task = new PostPlayerSynchronizationTask(player);
|
||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Npc npc : npcs) {
|
||||||
|
SynchronizationTask task = new PostNpcSynchronizationTask(npc);
|
||||||
|
task.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package org.apollo.game.sync.block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The transform {@link SynchronizationBlock}. This is an npc-only block that updates the npc's definition in the
|
||||||
|
* client, and thus its animations, size, etc.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class TransformBlock extends SynchronizationBlock {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The new id.
|
||||||
|
*/
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new transform block.
|
||||||
|
*
|
||||||
|
* @param id The id.
|
||||||
|
*/
|
||||||
|
public TransformBlock(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the id.
|
||||||
|
*
|
||||||
|
* @return The id.
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package org.apollo.game.sync.seg;
|
||||||
|
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link SynchronizationSegment} that adds an npc.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class AddNpcSegment extends SynchronizationSegment {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index.
|
||||||
|
*/
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position.
|
||||||
|
*/
|
||||||
|
private final Position position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the npc.
|
||||||
|
*/
|
||||||
|
private final int npcId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the add npc segment.
|
||||||
|
*
|
||||||
|
* @param blockSet The block set.
|
||||||
|
* @param index The characters's index.
|
||||||
|
* @param position The position.
|
||||||
|
* @param npcId The id of the npc.
|
||||||
|
*/
|
||||||
|
public AddNpcSegment(SynchronizationBlockSet blockSet, int index, Position position, int npcId) {
|
||||||
|
super(blockSet);
|
||||||
|
this.index = index;
|
||||||
|
this.position = position;
|
||||||
|
this.npcId = npcId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the character's index.
|
||||||
|
*
|
||||||
|
* @return The index.
|
||||||
|
*/
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the npc id.
|
||||||
|
*
|
||||||
|
* @return The npcId
|
||||||
|
*/
|
||||||
|
public int getNpcId() {
|
||||||
|
return npcId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position.
|
||||||
|
*
|
||||||
|
* @return The position.
|
||||||
|
*/
|
||||||
|
public Position getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SegmentType getType() {
|
||||||
|
return SegmentType.ADD_CHARACTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-2
@@ -8,7 +8,7 @@ import org.apollo.game.sync.block.SynchronizationBlockSet;
|
|||||||
*
|
*
|
||||||
* @author Graham
|
* @author Graham
|
||||||
*/
|
*/
|
||||||
public final class AddCharacterSegment extends SynchronizationSegment {
|
public final class AddPlayerSegment extends SynchronizationSegment {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index.
|
* The index.
|
||||||
@@ -27,7 +27,7 @@ public final class AddCharacterSegment extends SynchronizationSegment {
|
|||||||
* @param index The characters's index.
|
* @param index The characters's index.
|
||||||
* @param position The position.
|
* @param position The position.
|
||||||
*/
|
*/
|
||||||
public AddCharacterSegment(SynchronizationBlockSet blockSet, int index, Position position) {
|
public AddPlayerSegment(SynchronizationBlockSet blockSet, int index, Position position) {
|
||||||
super(blockSet);
|
super(blockSet);
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package org.apollo.game.sync.task;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apollo.game.event.impl.NpcSynchronizationEvent;
|
||||||
|
import org.apollo.game.model.Npc;
|
||||||
|
import org.apollo.game.model.Player;
|
||||||
|
import org.apollo.game.model.World;
|
||||||
|
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||||
|
import org.apollo.game.sync.seg.AddNpcSegment;
|
||||||
|
import org.apollo.game.sync.seg.MovementSegment;
|
||||||
|
import org.apollo.game.sync.seg.RemoveCharacterSegment;
|
||||||
|
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||||
|
import org.apollo.util.CharacterRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link SynchronizationTask} which synchronizes npcs with the specified {@link Player}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class NpcSynchronizationTask extends SynchronizationTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of npcs to load per cycle. This prevents the update packet from becoming too large (the client
|
||||||
|
* uses a 5000 byte buffer) and also stops old spec PCs from crashing when they login or teleport.
|
||||||
|
*/
|
||||||
|
private static final int NEW_NPCS_PER_CYCLE = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The player.
|
||||||
|
*/
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the {@link NpcSynchronizationTask} for the specified player.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
*/
|
||||||
|
public NpcSynchronizationTask(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SynchronizationBlockSet blockSet = player.getBlockSet();
|
||||||
|
List<Npc> localNpcs = player.getLocalNpcList();
|
||||||
|
int oldLocalNpcs = localNpcs.size();
|
||||||
|
List<SynchronizationSegment> segments = new ArrayList<SynchronizationSegment>();
|
||||||
|
|
||||||
|
for (Iterator<Npc> it = localNpcs.iterator(); it.hasNext();) {
|
||||||
|
Npc npc = it.next();
|
||||||
|
if (!npc.isActive() || npc.isTeleporting()
|
||||||
|
|| npc.getPosition().getLongestDelta(player.getPosition()) > player.getViewingDistance()) {
|
||||||
|
it.remove();
|
||||||
|
segments.add(new RemoveCharacterSegment());
|
||||||
|
} else {
|
||||||
|
segments.add(new MovementSegment(npc.getBlockSet(), npc.getDirections()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int added = 0;
|
||||||
|
|
||||||
|
CharacterRepository<Npc> repository = World.getWorld().getNpcRepository();
|
||||||
|
for (Npc npc : repository) {
|
||||||
|
if (localNpcs.size() >= 255) {
|
||||||
|
player.flagExcessiveNpcs();
|
||||||
|
break;
|
||||||
|
} else if (added >= NEW_NPCS_PER_CYCLE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (npc.getPosition().isWithinDistance(player.getPosition(), player.getViewingDistance())
|
||||||
|
&& !localNpcs.contains(npc)) {
|
||||||
|
localNpcs.add(npc);
|
||||||
|
added++;
|
||||||
|
blockSet = npc.getBlockSet();
|
||||||
|
segments.add(new AddNpcSegment(blockSet, npc.getIndex(), npc.getPosition(), npc.getNpcDefinition()
|
||||||
|
.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
NpcSynchronizationEvent event = new NpcSynchronizationEvent(player.getPosition(), segments, oldLocalNpcs);
|
||||||
|
player.send(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ import org.apollo.game.sync.block.AppearanceBlock;
|
|||||||
import org.apollo.game.sync.block.ChatBlock;
|
import org.apollo.game.sync.block.ChatBlock;
|
||||||
import org.apollo.game.sync.block.SynchronizationBlock;
|
import org.apollo.game.sync.block.SynchronizationBlock;
|
||||||
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||||
import org.apollo.game.sync.seg.AddCharacterSegment;
|
import org.apollo.game.sync.seg.AddPlayerSegment;
|
||||||
import org.apollo.game.sync.seg.RemoveCharacterSegment;
|
import org.apollo.game.sync.seg.RemoveCharacterSegment;
|
||||||
import org.apollo.game.sync.seg.MovementSegment;
|
import org.apollo.game.sync.seg.MovementSegment;
|
||||||
import org.apollo.game.sync.seg.SynchronizationSegment;
|
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||||
@@ -104,7 +104,7 @@ public final class PlayerSynchronizationTask extends SynchronizationTask {
|
|||||||
blockSet.add(SynchronizationBlock.createAppearanceBlock(p));
|
blockSet.add(SynchronizationBlock.createAppearanceBlock(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
segments.add(new AddCharacterSegment(blockSet, p.getIndex(), p.getPosition()));
|
segments.add(new AddPlayerSegment(blockSet, p.getIndex(), p.getPosition()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.apollo.game.sync.task;
|
||||||
|
|
||||||
|
import org.apollo.game.model.Npc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link SynchronizationTask} which does post-synchronization work for the specified {@link Npc}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class PostNpcSynchronizationTask extends SynchronizationTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The npc.
|
||||||
|
*/
|
||||||
|
private final Npc npc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the {@link PostNpcSynchronizationTask} for the specified player.
|
||||||
|
*
|
||||||
|
* @param npc The npc.
|
||||||
|
*/
|
||||||
|
public PostNpcSynchronizationTask(Npc npc) {
|
||||||
|
this.npc = npc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
npc.setTeleporting(false);
|
||||||
|
npc.resetBlockSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package org.apollo.game.sync.task;
|
||||||
|
|
||||||
|
import org.apollo.game.model.Npc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link SynchronizationTask} which does pre-synchronization work for the specified npc.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public final class PreNpcSynchronizationTask extends SynchronizationTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The npc.
|
||||||
|
*/
|
||||||
|
private final Npc npc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the {@link PreNpcSynchronizationTask} for the specified npc.
|
||||||
|
*
|
||||||
|
* @param npc The npc.
|
||||||
|
*/
|
||||||
|
public PreNpcSynchronizationTask(Npc npc) {
|
||||||
|
this.npc = npc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
npc.getWalkingQueue().pulse();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
package org.apollo.net.release.r317;
|
||||||
|
|
||||||
|
import org.apollo.game.event.impl.NpcSynchronizationEvent;
|
||||||
|
import org.apollo.game.model.Animation;
|
||||||
|
import org.apollo.game.model.Direction;
|
||||||
|
import org.apollo.game.model.Graphic;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.sync.block.AnimationBlock;
|
||||||
|
import org.apollo.game.sync.block.ForceChatBlock;
|
||||||
|
import org.apollo.game.sync.block.GraphicBlock;
|
||||||
|
import org.apollo.game.sync.block.HitUpdateBlock;
|
||||||
|
import org.apollo.game.sync.block.InteractingCharacterBlock;
|
||||||
|
import org.apollo.game.sync.block.SecondHitUpdateBlock;
|
||||||
|
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||||
|
import org.apollo.game.sync.block.TransformBlock;
|
||||||
|
import org.apollo.game.sync.block.TurnToPositionBlock;
|
||||||
|
import org.apollo.game.sync.seg.AddNpcSegment;
|
||||||
|
import org.apollo.game.sync.seg.MovementSegment;
|
||||||
|
import org.apollo.game.sync.seg.SegmentType;
|
||||||
|
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||||
|
import org.apollo.net.codec.game.DataOrder;
|
||||||
|
import org.apollo.net.codec.game.DataTransformation;
|
||||||
|
import org.apollo.net.codec.game.DataType;
|
||||||
|
import org.apollo.net.codec.game.GamePacket;
|
||||||
|
import org.apollo.net.codec.game.GamePacketBuilder;
|
||||||
|
import org.apollo.net.meta.PacketType;
|
||||||
|
import org.apollo.net.release.EventEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link EventEncoder} for the {@link NpcSynchronizationEvent}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public class NpcSynchronizationEventEncoder extends EventEncoder<NpcSynchronizationEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(NpcSynchronizationEvent event) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(65, PacketType.VARIABLE_SHORT);
|
||||||
|
builder.switchToBitAccess();
|
||||||
|
|
||||||
|
GamePacketBuilder blockBuilder = new GamePacketBuilder();
|
||||||
|
|
||||||
|
builder.putBits(8, event.getLocalNpcCount());
|
||||||
|
|
||||||
|
for (SynchronizationSegment segment : event.getSegments()) {
|
||||||
|
SegmentType type = segment.getType();
|
||||||
|
if (type == SegmentType.REMOVE_CHARACTER) {
|
||||||
|
putRemoveCharacterUpdate(builder);
|
||||||
|
} else if (type == SegmentType.ADD_CHARACTER) {
|
||||||
|
putAddNpcUpdate((AddNpcSegment) segment, event, builder);
|
||||||
|
putBlocks(segment, blockBuilder);
|
||||||
|
} else {
|
||||||
|
putMovementUpdate(segment, event, builder);
|
||||||
|
putBlocks(segment, blockBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockBuilder.getLength() > 0) {
|
||||||
|
builder.putBits(14, 16383);
|
||||||
|
builder.switchToByteAccess();
|
||||||
|
builder.putRawBuilder(blockBuilder);
|
||||||
|
} else {
|
||||||
|
builder.switchToByteAccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an add character update.
|
||||||
|
*
|
||||||
|
* @param seg The segment.
|
||||||
|
* @param event The event.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putAddNpcUpdate(AddNpcSegment seg, NpcSynchronizationEvent event, GamePacketBuilder builder) {
|
||||||
|
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||||
|
Position npc = event.getPosition();
|
||||||
|
Position other = seg.getPosition();
|
||||||
|
builder.putBits(14, seg.getIndex());
|
||||||
|
builder.putBits(5, other.getY() - npc.getY());
|
||||||
|
builder.putBits(5, other.getX() - npc.getX());
|
||||||
|
builder.putBits(1, 0); // discard walking queue
|
||||||
|
builder.putBits(12, seg.getNpcId());
|
||||||
|
builder.putBits(1, updateRequired ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an animation block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param blockBuilder The builder.
|
||||||
|
*/
|
||||||
|
private void putAnimationBlock(AnimationBlock block, GamePacketBuilder blockBuilder) {
|
||||||
|
Animation animation = block.getAnimation();
|
||||||
|
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, animation.getId());
|
||||||
|
blockBuilder.put(DataType.BYTE, animation.getDelay());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts the blocks for the specified segment.
|
||||||
|
*
|
||||||
|
* @param segment The segment.
|
||||||
|
* @param blockBuilder The block builder.
|
||||||
|
*/
|
||||||
|
private void putBlocks(SynchronizationSegment segment, GamePacketBuilder blockBuilder) {
|
||||||
|
SynchronizationBlockSet blockSet = segment.getBlockSet();
|
||||||
|
if (blockSet.size() > 0) {
|
||||||
|
int mask = 0;
|
||||||
|
|
||||||
|
if (blockSet.contains(AnimationBlock.class)) {
|
||||||
|
mask |= 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||||
|
mask |= 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(GraphicBlock.class)) {
|
||||||
|
mask |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||||
|
mask |= 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(ForceChatBlock.class)) {
|
||||||
|
mask |= 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||||
|
mask |= 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(TransformBlock.class)) {
|
||||||
|
mask |= 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||||
|
mask |= 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockBuilder.put(DataType.BYTE, mask);
|
||||||
|
|
||||||
|
if (blockSet.contains(AnimationBlock.class)) {
|
||||||
|
putAnimationBlock(blockSet.get(AnimationBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||||
|
putHitUpdateBlock(blockSet.get(HitUpdateBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(GraphicBlock.class)) {
|
||||||
|
putGraphicBlock(blockSet.get(GraphicBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||||
|
putInteractingCharacterBlock(blockSet.get(InteractingCharacterBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(ForceChatBlock.class)) {
|
||||||
|
putForceChatBlock(blockSet.get(ForceChatBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||||
|
putSecondHitUpdateBlock(blockSet.get(SecondHitUpdateBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(TransformBlock.class)) {
|
||||||
|
putTransformBlock(blockSet.get(TransformBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||||
|
putTurnToPositionBlock(blockSet.get(TurnToPositionBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a force chat block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putForceChatBlock(ForceChatBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.putString(block.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a graphic block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param blockBuilder The builder.
|
||||||
|
*/
|
||||||
|
private void putGraphicBlock(GraphicBlock block, GamePacketBuilder blockBuilder) {
|
||||||
|
Graphic graphic = block.getGraphic();
|
||||||
|
blockBuilder.put(DataType.SHORT, graphic.getId());
|
||||||
|
blockBuilder.put(DataType.INT, graphic.getDelay());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a hit update block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putHitUpdateBlock(HitUpdateBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.ADD, block.getDamage());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, block.getType());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.ADD, block.getCurrentHealth());
|
||||||
|
builder.put(DataType.BYTE, block.getMaximumHealth());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an interacting character block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putInteractingCharacterBlock(InteractingCharacterBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.SHORT, block.getInteractingCharacterIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a movement update for the specified segment.
|
||||||
|
*
|
||||||
|
* @param segment The segment.
|
||||||
|
* @param event The event.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putMovementUpdate(SynchronizationSegment segment, NpcSynchronizationEvent event,
|
||||||
|
GamePacketBuilder builder) {
|
||||||
|
boolean updateRequired = segment.getBlockSet().size() > 0;
|
||||||
|
if (segment.getType() == SegmentType.RUN) {
|
||||||
|
Direction[] directions = ((MovementSegment) segment).getDirections();
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 2);
|
||||||
|
builder.putBits(3, directions[0].toInteger());
|
||||||
|
builder.putBits(3, directions[1].toInteger());
|
||||||
|
builder.putBits(1, updateRequired ? 1 : 0);
|
||||||
|
} else if (segment.getType() == SegmentType.WALK) {
|
||||||
|
Direction[] directions = ((MovementSegment) segment).getDirections();
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 1);
|
||||||
|
builder.putBits(3, directions[0].toInteger());
|
||||||
|
builder.putBits(1, updateRequired ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
if (updateRequired) {
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 0);
|
||||||
|
} else {
|
||||||
|
builder.putBits(1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a remove character update.
|
||||||
|
*
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putRemoveCharacterUpdate(GamePacketBuilder builder) {
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a second hit update block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putSecondHitUpdateBlock(SecondHitUpdateBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, block.getDamage());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getType());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getCurrentHealth());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, block.getMaximumHealth());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a transform block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putTransformBlock(TransformBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, block.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a turn to position block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param blockBuilder The builder.
|
||||||
|
*/
|
||||||
|
private void putTurnToPositionBlock(TurnToPositionBlock block, GamePacketBuilder blockBuilder) {
|
||||||
|
Position pos = block.getPosition();
|
||||||
|
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, pos.getX() * 2 + 1);
|
||||||
|
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, pos.getY() * 2 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ import org.apollo.game.sync.block.InteractingCharacterBlock;
|
|||||||
import org.apollo.game.sync.block.SecondHitUpdateBlock;
|
import org.apollo.game.sync.block.SecondHitUpdateBlock;
|
||||||
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||||
import org.apollo.game.sync.block.TurnToPositionBlock;
|
import org.apollo.game.sync.block.TurnToPositionBlock;
|
||||||
import org.apollo.game.sync.seg.AddCharacterSegment;
|
import org.apollo.game.sync.seg.AddPlayerSegment;
|
||||||
import org.apollo.game.sync.seg.MovementSegment;
|
import org.apollo.game.sync.seg.MovementSegment;
|
||||||
import org.apollo.game.sync.seg.SegmentType;
|
import org.apollo.game.sync.seg.SegmentType;
|
||||||
import org.apollo.game.sync.seg.SynchronizationSegment;
|
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||||
@@ -60,7 +60,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
|||||||
if (type == SegmentType.REMOVE_CHARACTER) {
|
if (type == SegmentType.REMOVE_CHARACTER) {
|
||||||
putRemoveCharacterUpdate(builder);
|
putRemoveCharacterUpdate(builder);
|
||||||
} else if (type == SegmentType.ADD_CHARACTER) {
|
} else if (type == SegmentType.ADD_CHARACTER) {
|
||||||
putAddCharacterUpdate((AddCharacterSegment) segment, event, builder);
|
putAddCharacterUpdate((AddPlayerSegment) segment, event, builder);
|
||||||
putBlocks(segment, blockBuilder);
|
putBlocks(segment, blockBuilder);
|
||||||
} else {
|
} else {
|
||||||
putMovementUpdate(segment, event, builder);
|
putMovementUpdate(segment, event, builder);
|
||||||
@@ -86,7 +86,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
|||||||
* @param event The event.
|
* @param event The event.
|
||||||
* @param builder The builder.
|
* @param builder The builder.
|
||||||
*/
|
*/
|
||||||
private void putAddCharacterUpdate(AddCharacterSegment seg, PlayerSynchronizationEvent event,
|
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event,
|
||||||
GamePacketBuilder builder) {
|
GamePacketBuilder builder) {
|
||||||
boolean updateRequired = seg.getBlockSet().size() > 0;
|
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||||
Position player = event.getPosition();
|
Position player = event.getPosition();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.apollo.game.event.impl.CloseInterfaceEvent;
|
|||||||
import org.apollo.game.event.impl.EnterAmountEvent;
|
import org.apollo.game.event.impl.EnterAmountEvent;
|
||||||
import org.apollo.game.event.impl.IdAssignmentEvent;
|
import org.apollo.game.event.impl.IdAssignmentEvent;
|
||||||
import org.apollo.game.event.impl.LogoutEvent;
|
import org.apollo.game.event.impl.LogoutEvent;
|
||||||
|
import org.apollo.game.event.impl.NpcSynchronizationEvent;
|
||||||
import org.apollo.game.event.impl.OpenInterfaceEvent;
|
import org.apollo.game.event.impl.OpenInterfaceEvent;
|
||||||
import org.apollo.game.event.impl.OpenInterfaceSidebarEvent;
|
import org.apollo.game.event.impl.OpenInterfaceSidebarEvent;
|
||||||
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
||||||
@@ -105,6 +106,7 @@ public final class Release317 extends Release {
|
|||||||
register(OpenInterfaceSidebarEvent.class, new OpenInterfaceSidebarEventEncoder());
|
register(OpenInterfaceSidebarEvent.class, new OpenInterfaceSidebarEventEncoder());
|
||||||
register(EnterAmountEvent.class, new EnterAmountEventEncoder());
|
register(EnterAmountEvent.class, new EnterAmountEventEncoder());
|
||||||
register(SetInterfaceTextEvent.class, new SetInterfaceTextEventEncoder());
|
register(SetInterfaceTextEvent.class, new SetInterfaceTextEventEncoder());
|
||||||
|
register(NpcSynchronizationEvent.class, new NpcSynchronizationEventEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
package org.apollo.net.release.r377;
|
||||||
|
|
||||||
|
import org.apollo.game.event.impl.NpcSynchronizationEvent;
|
||||||
|
import org.apollo.game.model.Animation;
|
||||||
|
import org.apollo.game.model.Direction;
|
||||||
|
import org.apollo.game.model.Graphic;
|
||||||
|
import org.apollo.game.model.Position;
|
||||||
|
import org.apollo.game.sync.block.AnimationBlock;
|
||||||
|
import org.apollo.game.sync.block.ForceChatBlock;
|
||||||
|
import org.apollo.game.sync.block.GraphicBlock;
|
||||||
|
import org.apollo.game.sync.block.HitUpdateBlock;
|
||||||
|
import org.apollo.game.sync.block.InteractingCharacterBlock;
|
||||||
|
import org.apollo.game.sync.block.SecondHitUpdateBlock;
|
||||||
|
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||||
|
import org.apollo.game.sync.block.TransformBlock;
|
||||||
|
import org.apollo.game.sync.block.TurnToPositionBlock;
|
||||||
|
import org.apollo.game.sync.seg.AddNpcSegment;
|
||||||
|
import org.apollo.game.sync.seg.MovementSegment;
|
||||||
|
import org.apollo.game.sync.seg.SegmentType;
|
||||||
|
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||||
|
import org.apollo.net.codec.game.DataOrder;
|
||||||
|
import org.apollo.net.codec.game.DataTransformation;
|
||||||
|
import org.apollo.net.codec.game.DataType;
|
||||||
|
import org.apollo.net.codec.game.GamePacket;
|
||||||
|
import org.apollo.net.codec.game.GamePacketBuilder;
|
||||||
|
import org.apollo.net.meta.PacketType;
|
||||||
|
import org.apollo.net.release.EventEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link EventEncoder} for the {@link NpcSynchronizationEvent}.
|
||||||
|
*
|
||||||
|
* @author Major
|
||||||
|
*/
|
||||||
|
public class NpcSynchronizationEventEncoder extends EventEncoder<NpcSynchronizationEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GamePacket encode(NpcSynchronizationEvent event) {
|
||||||
|
GamePacketBuilder builder = new GamePacketBuilder(71, PacketType.VARIABLE_SHORT);
|
||||||
|
builder.switchToBitAccess();
|
||||||
|
|
||||||
|
GamePacketBuilder blockBuilder = new GamePacketBuilder();
|
||||||
|
|
||||||
|
builder.putBits(8, event.getLocalNpcCount());
|
||||||
|
|
||||||
|
for (SynchronizationSegment segment : event.getSegments()) {
|
||||||
|
SegmentType type = segment.getType();
|
||||||
|
if (type == SegmentType.REMOVE_CHARACTER) {
|
||||||
|
putRemoveCharacterUpdate(builder);
|
||||||
|
} else if (type == SegmentType.ADD_CHARACTER) {
|
||||||
|
putAddNpcUpdate((AddNpcSegment) segment, event, builder);
|
||||||
|
putBlocks(segment, blockBuilder);
|
||||||
|
} else {
|
||||||
|
putMovementUpdate(segment, event, builder);
|
||||||
|
putBlocks(segment, blockBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockBuilder.getLength() > 0) {
|
||||||
|
builder.putBits(14, 16383);
|
||||||
|
builder.switchToByteAccess();
|
||||||
|
builder.putRawBuilder(blockBuilder);
|
||||||
|
} else {
|
||||||
|
builder.switchToByteAccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toGamePacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an add character update.
|
||||||
|
*
|
||||||
|
* @param seg The segment.
|
||||||
|
* @param event The event.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putAddNpcUpdate(AddNpcSegment seg, NpcSynchronizationEvent event, GamePacketBuilder builder) {
|
||||||
|
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||||
|
Position npc = event.getPosition();
|
||||||
|
Position other = seg.getPosition();
|
||||||
|
builder.putBits(14, seg.getIndex());
|
||||||
|
builder.putBits(1, updateRequired ? 1 : 0);
|
||||||
|
builder.putBits(5, other.getY() - npc.getY()); // these might be
|
||||||
|
builder.putBits(5, other.getX() - npc.getX()); // the wrong way around
|
||||||
|
builder.putBits(1, 0); // discard walking queue
|
||||||
|
builder.putBits(13, seg.getNpcId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an animation block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param blockBuilder The builder.
|
||||||
|
*/
|
||||||
|
private void putAnimationBlock(AnimationBlock block, GamePacketBuilder blockBuilder) {
|
||||||
|
Animation animation = block.getAnimation();
|
||||||
|
blockBuilder.put(DataType.SHORT, animation.getId());
|
||||||
|
blockBuilder.put(DataType.BYTE, DataTransformation.SUBTRACT, animation.getDelay());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts the blocks for the specified segment.
|
||||||
|
*
|
||||||
|
* @param segment The segment.
|
||||||
|
* @param blockBuilder The block builder.
|
||||||
|
*/
|
||||||
|
private void putBlocks(SynchronizationSegment segment, GamePacketBuilder blockBuilder) {
|
||||||
|
SynchronizationBlockSet blockSet = segment.getBlockSet();
|
||||||
|
if (blockSet.size() > 0) {
|
||||||
|
int mask = 0;
|
||||||
|
|
||||||
|
if (blockSet.contains(TransformBlock.class)) {
|
||||||
|
mask |= 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||||
|
mask |= 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||||
|
mask |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(GraphicBlock.class)) {
|
||||||
|
mask |= 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(ForceChatBlock.class)) {
|
||||||
|
mask |= 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||||
|
mask |= 0x8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(AnimationBlock.class)) {
|
||||||
|
mask |= 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||||
|
mask |= 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockBuilder.put(DataType.BYTE, mask);
|
||||||
|
|
||||||
|
if (blockSet.contains(TransformBlock.class)) {
|
||||||
|
putTransformBlock(blockSet.get(TransformBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||||
|
putInteractingCharacterBlock(blockSet.get(InteractingCharacterBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||||
|
putHitUpdateBlock(blockSet.get(HitUpdateBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(GraphicBlock.class)) {
|
||||||
|
putGraphicBlock(blockSet.get(GraphicBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(ForceChatBlock.class)) {
|
||||||
|
putForceChatBlock(blockSet.get(ForceChatBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||||
|
putTurnToPositionBlock(blockSet.get(TurnToPositionBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(AnimationBlock.class)) {
|
||||||
|
putAnimationBlock(blockSet.get(AnimationBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||||
|
putSecondHitUpdateBlock(blockSet.get(SecondHitUpdateBlock.class), blockBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a force chat block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putForceChatBlock(ForceChatBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.putString(block.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a graphic block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param blockBuilder The builder.
|
||||||
|
*/
|
||||||
|
private void putGraphicBlock(GraphicBlock block, GamePacketBuilder blockBuilder) {
|
||||||
|
Graphic graphic = block.getGraphic();
|
||||||
|
blockBuilder.put(DataType.SHORT, graphic.getId());
|
||||||
|
blockBuilder.put(DataType.INT, DataOrder.MIDDLE, graphic.getDelay());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a hit update block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putHitUpdateBlock(HitUpdateBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.ADD, block.getDamage());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.ADD, block.getType());
|
||||||
|
builder.put(DataType.BYTE, block.getCurrentHealth());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getMaximumHealth());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an interacting character block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putInteractingCharacterBlock(InteractingCharacterBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.SHORT, DataOrder.LITTLE, block.getInteractingCharacterIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a movement update for the specified segment.
|
||||||
|
*
|
||||||
|
* @param seg The segment.
|
||||||
|
* @param event The event.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putMovementUpdate(SynchronizationSegment seg, NpcSynchronizationEvent event, GamePacketBuilder builder) {
|
||||||
|
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||||
|
if (seg.getType() == SegmentType.RUN) {
|
||||||
|
Direction[] directions = ((MovementSegment) seg).getDirections();
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 2);
|
||||||
|
builder.putBits(3, directions[0].toInteger());
|
||||||
|
builder.putBits(3, directions[1].toInteger());
|
||||||
|
builder.putBits(1, updateRequired ? 1 : 0);
|
||||||
|
} else if (seg.getType() == SegmentType.WALK) {
|
||||||
|
Direction[] directions = ((MovementSegment) seg).getDirections();
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 1);
|
||||||
|
builder.putBits(3, directions[0].toInteger());
|
||||||
|
builder.putBits(1, updateRequired ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
if (updateRequired) {
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 0);
|
||||||
|
} else {
|
||||||
|
builder.putBits(1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a remove character update.
|
||||||
|
*
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putRemoveCharacterUpdate(GamePacketBuilder builder) {
|
||||||
|
builder.putBits(1, 1);
|
||||||
|
builder.putBits(2, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a second hit update block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putSecondHitUpdateBlock(SecondHitUpdateBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getDamage());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getType());
|
||||||
|
builder.put(DataType.BYTE, block.getCurrentHealth());
|
||||||
|
builder.put(DataType.BYTE, DataTransformation.NEGATE, block.getMaximumHealth());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a transform block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param builder The builder.
|
||||||
|
*/
|
||||||
|
private void putTransformBlock(TransformBlock block, GamePacketBuilder builder) {
|
||||||
|
builder.put(DataType.SHORT, DataTransformation.ADD, block.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts a turn to position block into the specified builder.
|
||||||
|
*
|
||||||
|
* @param block The block.
|
||||||
|
* @param blockBuilder The builder.
|
||||||
|
*/
|
||||||
|
private void putTurnToPositionBlock(TurnToPositionBlock block, GamePacketBuilder blockBuilder) {
|
||||||
|
Position pos = block.getPosition();
|
||||||
|
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, pos.getX() * 2 + 1);
|
||||||
|
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, pos.getY() * 2 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ import org.apollo.game.sync.block.InteractingCharacterBlock;
|
|||||||
import org.apollo.game.sync.block.SecondHitUpdateBlock;
|
import org.apollo.game.sync.block.SecondHitUpdateBlock;
|
||||||
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||||
import org.apollo.game.sync.block.TurnToPositionBlock;
|
import org.apollo.game.sync.block.TurnToPositionBlock;
|
||||||
import org.apollo.game.sync.seg.AddCharacterSegment;
|
import org.apollo.game.sync.seg.AddPlayerSegment;
|
||||||
import org.apollo.game.sync.seg.MovementSegment;
|
import org.apollo.game.sync.seg.MovementSegment;
|
||||||
import org.apollo.game.sync.seg.SegmentType;
|
import org.apollo.game.sync.seg.SegmentType;
|
||||||
import org.apollo.game.sync.seg.SynchronizationSegment;
|
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||||
@@ -60,7 +60,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
|||||||
if (type == SegmentType.REMOVE_CHARACTER) {
|
if (type == SegmentType.REMOVE_CHARACTER) {
|
||||||
putRemoveCharacterUpdate(builder);
|
putRemoveCharacterUpdate(builder);
|
||||||
} else if (type == SegmentType.ADD_CHARACTER) {
|
} else if (type == SegmentType.ADD_CHARACTER) {
|
||||||
putAddCharacterUpdate((AddCharacterSegment) segment, event, builder);
|
putAddCharacterUpdate((AddPlayerSegment) segment, event, builder);
|
||||||
putBlocks(segment, blockBuilder);
|
putBlocks(segment, blockBuilder);
|
||||||
} else {
|
} else {
|
||||||
putMovementUpdate(segment, event, builder);
|
putMovementUpdate(segment, event, builder);
|
||||||
@@ -86,7 +86,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
|||||||
* @param event The event.
|
* @param event The event.
|
||||||
* @param builder The builder.
|
* @param builder The builder.
|
||||||
*/
|
*/
|
||||||
private void putAddCharacterUpdate(AddCharacterSegment seg, PlayerSynchronizationEvent event,
|
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event,
|
||||||
GamePacketBuilder builder) {
|
GamePacketBuilder builder) {
|
||||||
boolean updateRequired = seg.getBlockSet().size() > 0;
|
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||||
Position player = event.getPosition();
|
Position player = event.getPosition();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.apollo.game.event.impl.CloseInterfaceEvent;
|
|||||||
import org.apollo.game.event.impl.EnterAmountEvent;
|
import org.apollo.game.event.impl.EnterAmountEvent;
|
||||||
import org.apollo.game.event.impl.IdAssignmentEvent;
|
import org.apollo.game.event.impl.IdAssignmentEvent;
|
||||||
import org.apollo.game.event.impl.LogoutEvent;
|
import org.apollo.game.event.impl.LogoutEvent;
|
||||||
|
import org.apollo.game.event.impl.NpcSynchronizationEvent;
|
||||||
import org.apollo.game.event.impl.OpenInterfaceEvent;
|
import org.apollo.game.event.impl.OpenInterfaceEvent;
|
||||||
import org.apollo.game.event.impl.OpenInterfaceSidebarEvent;
|
import org.apollo.game.event.impl.OpenInterfaceSidebarEvent;
|
||||||
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
||||||
@@ -105,6 +106,7 @@ public final class Release377 extends Release {
|
|||||||
register(OpenInterfaceSidebarEvent.class, new OpenInterfaceSidebarEventEncoder());
|
register(OpenInterfaceSidebarEvent.class, new OpenInterfaceSidebarEventEncoder());
|
||||||
register(EnterAmountEvent.class, new EnterAmountEventEncoder());
|
register(EnterAmountEvent.class, new EnterAmountEventEncoder());
|
||||||
register(SetInterfaceTextEvent.class, new SetInterfaceTextEventEncoder());
|
register(SetInterfaceTextEvent.class, new SetInterfaceTextEventEncoder());
|
||||||
|
register(NpcSynchronizationEvent.class, new NpcSynchronizationEventEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user