mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +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 {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@@ -34,62 +95,6 @@ public abstract class Character {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -100,31 +105,6 @@ public abstract class Character {
|
||||
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.
|
||||
*
|
||||
@@ -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() {
|
||||
return localPlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
public SynchronizationBlockSet getBlockSet() {
|
||||
return blockSet;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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() {
|
||||
return position;
|
||||
public Inventory getEquipment() {
|
||||
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) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this character is active.
|
||||
*
|
||||
* @return {@code true} if so, {@code false} if not.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return index != -1;
|
||||
public Direction getFirstDirection() {
|
||||
return firstDirection;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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) {
|
||||
synchronized (this) {
|
||||
this.index = index;
|
||||
}
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link SynchronizationBlockSet}.
|
||||
* Gets the local npc list.
|
||||
*
|
||||
* @return The block set.
|
||||
* @return The local npc list.
|
||||
*/
|
||||
public SynchronizationBlockSet getBlockSet() {
|
||||
return blockSet;
|
||||
public List<Npc> getLocalNpcList() {
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
this.teleporting = true;
|
||||
public void setDefinition(NpcDefinition definition) {
|
||||
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.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) {
|
||||
blockSet.add(SynchronizationBlock.createAnimationBlock(animation));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
public void setTeleporting(boolean teleporting) {
|
||||
this.teleporting = teleporting;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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.
|
||||
*
|
||||
@@ -391,22 +423,4 @@ public abstract class Character {
|
||||
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 {
|
||||
|
||||
/**
|
||||
* A standard (rights 0) account.
|
||||
* An administrator (rights 2) account.
|
||||
*/
|
||||
STANDARD(0),
|
||||
ADMINISTRATOR(2),
|
||||
|
||||
/**
|
||||
* A player moderator (rights 1) account.
|
||||
@@ -45,9 +45,9 @@ public final class Player extends Character {
|
||||
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.
|
||||
@@ -89,46 +89,8 @@ 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.
|
||||
@@ -136,9 +98,19 @@ public final class Player extends Character {
|
||||
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.
|
||||
@@ -150,15 +122,50 @@ public final class Player extends Character {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
@@ -178,21 +185,19 @@ public final class Player extends Character {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this player's interface set.
|
||||
*
|
||||
* @return The interface set for this player.
|
||||
* Decrements this player's viewing distance if it is greater than 1.
|
||||
*/
|
||||
public InterfaceSet getInterfaceSet() {
|
||||
return interfaceSet;
|
||||
public void decrementViewingDistance() {
|
||||
if (viewingDistance > 1) { // TODO should it be 0?
|
||||
viewingDistance--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are excessive players.
|
||||
*
|
||||
* @return {@code true} if so, {@code false} if not.
|
||||
* Sets the excessive npcs flag.
|
||||
*/
|
||||
public boolean isExcessivePlayersSet() {
|
||||
return excessivePlayers;
|
||||
public void flagExcessiveNpcs() {
|
||||
this.excessiveNpcs = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,53 +208,48 @@ public final class Player extends Character {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the excessive players flag.
|
||||
*/
|
||||
public void resetExcessivePlayers() {
|
||||
excessivePlayers = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this player's viewing distance.
|
||||
*/
|
||||
public void resetViewingDistance() {
|
||||
viewingDistance = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this player's viewing distance.
|
||||
* Gets the player's appearance.
|
||||
*
|
||||
* @return The viewing distance.
|
||||
* @return The appearance.
|
||||
*/
|
||||
public int getViewingDistance() {
|
||||
return viewingDistance;
|
||||
public Appearance getAppearance() {
|
||||
return appearance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments this player's viewing distance if it is less than the maximum viewing distance.
|
||||
*/
|
||||
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.
|
||||
* Gets the player's credentials.
|
||||
*
|
||||
* @return {@code true} if so, {@code false} if not.
|
||||
* @return The player's credentials.
|
||||
*/
|
||||
public boolean hasLastKnownRegion() {
|
||||
return lastKnownRegion != null;
|
||||
public PlayerCredentials getCredentials() {
|
||||
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) {
|
||||
this.lastKnownRegion = lastKnownRegion;
|
||||
public String getName() {
|
||||
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) {
|
||||
this.privilegeLevel = privilegeLevel;
|
||||
public GameSession getSession() {
|
||||
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.
|
||||
*/
|
||||
public boolean isMembers() {
|
||||
return members;
|
||||
public boolean hasLastKnownRegion() {
|
||||
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) {
|
||||
this.members = members;
|
||||
public boolean hasRegionChanged() {
|
||||
return regionChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player's {@link GameSession}.
|
||||
*
|
||||
* @param session The player's {@link GameSession}.
|
||||
* @param reconnecting The reconnecting flag.
|
||||
* Increments this player's viewing distance if it is less than the maximum viewing distance.
|
||||
*/
|
||||
public void setSession(GameSession session, boolean reconnecting) {
|
||||
this.session = session;
|
||||
if (!reconnecting) {
|
||||
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);
|
||||
public void incrementViewingDistance() {
|
||||
if (viewingDistance < Position.MAX_DISTANCE) {
|
||||
viewingDistance++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,23 +350,6 @@ public final class Player extends Character {
|
||||
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.
|
||||
*/
|
||||
@@ -406,6 +387,95 @@ public final class Player extends Character {
|
||||
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.
|
||||
*/
|
||||
@@ -438,37 +508,13 @@ public final class Player extends Character {
|
||||
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) {
|
||||
this.regionChanged = regionChanged;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
public void sendMessage(String message) {
|
||||
send(new ServerMessageEvent(message));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,40 +527,6 @@ public final class Player extends Character {
|
||||
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.
|
||||
*
|
||||
@@ -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() {
|
||||
return designedCharacter;
|
||||
public void setHeadIcon(int headIcon) {
|
||||
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() {
|
||||
return withdrawingNotes;
|
||||
public void setLastKnownRegion(Position lastKnownRegion) {
|
||||
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?
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's prayer icon.
|
||||
*
|
||||
* @return The prayer icon.
|
||||
*/
|
||||
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;
|
||||
@Override
|
||||
public String toString() {
|
||||
return Player.class.getName() + " [username=" + credentials.getUsername() + ", privilegeLevel="
|
||||
+ privilegeLevel + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,16 +33,6 @@ import org.apollo.util.plugin.PluginManager;
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -50,11 +40,6 @@ public final class World {
|
||||
*/
|
||||
public enum RegistrationStatus {
|
||||
|
||||
/**
|
||||
* Indicates the world is full.
|
||||
*/
|
||||
WORLD_FULL,
|
||||
|
||||
/**
|
||||
* Indicates that the player is already online.
|
||||
*/
|
||||
@@ -63,9 +48,24 @@ public final class World {
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -75,20 +75,16 @@ public final class World {
|
||||
return world;
|
||||
}
|
||||
|
||||
/**
|
||||
* The scheduler.
|
||||
*/
|
||||
// TODO: better place than here?
|
||||
private final Scheduler scheduler = new Scheduler();
|
||||
|
||||
/**
|
||||
* The command dispatcher.
|
||||
*/
|
||||
// TODO: better place than here?
|
||||
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.
|
||||
@@ -96,6 +92,15 @@ public final class World {
|
||||
private final CharacterRepository<Player> playerRepository = new CharacterRepository<Player>(
|
||||
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.
|
||||
*/
|
||||
@@ -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.
|
||||
*
|
||||
@@ -147,17 +193,42 @@ public final class World {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Checks if the specified player is online.
|
||||
*
|
||||
* @return The character repository.
|
||||
* @param name The player's name.
|
||||
* @return {@code true} if so, {@code false} if not.
|
||||
*/
|
||||
public CharacterRepository<Player> getPlayerRepository() {
|
||||
return playerRepository;
|
||||
public boolean isPlayerOnline(String name) {
|
||||
// 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.
|
||||
* @return {@code true} if so, {@code false} if not.
|
||||
* @param task The {@link ScheduledTask}.
|
||||
*/
|
||||
public boolean isPlayerOnline(String name) {
|
||||
// TODO: use a hash set or map in the future?
|
||||
for (Player player : playerRepository) {
|
||||
if (player.getName().equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
public void schedule(ScheduledTask task) {
|
||||
scheduler.schedule(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* The maximum number of npcs.
|
||||
*/
|
||||
public static final int MAXIMUM_NPCS = 2000;
|
||||
|
||||
/**
|
||||
* The maximum number of players.
|
||||
*/
|
||||
@@ -16,7 +21,6 @@ public final class WorldConstants {
|
||||
* Default private constructor to prevent instantiation by other classes.
|
||||
*/
|
||||
private WorldConstants() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,15 @@ import java.util.concurrent.Phaser;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
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.Player;
|
||||
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
||||
import org.apollo.game.sync.task.PhasedSynchronizationTask;
|
||||
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.PreNpcSynchronizationTask;
|
||||
import org.apollo.game.sync.task.PrePlayerSynchronizationTask;
|
||||
import org.apollo.game.sync.task.SynchronizationTask;
|
||||
import org.apollo.util.CharacterRepository;
|
||||
@@ -24,6 +28,7 @@ import org.apollo.util.NamedThreadFactory;
|
||||
* will work.
|
||||
*
|
||||
* @author Graham
|
||||
* @author Major
|
||||
*/
|
||||
public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
||||
|
||||
@@ -50,7 +55,9 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
||||
@Override
|
||||
public void synchronize() {
|
||||
CharacterRepository<Player> players = World.getWorld().getPlayerRepository();
|
||||
CharacterRepository<Npc> npcs = World.getWorld().getNpcRepository();
|
||||
int playerCount = players.size();
|
||||
int npcCount = npcs.size();
|
||||
|
||||
phaser.bulkRegister(playerCount);
|
||||
for (Player player : players) {
|
||||
@@ -59,6 +66,13 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
||||
}
|
||||
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);
|
||||
for (Player player : players) {
|
||||
SynchronizationTask task = new PlayerSynchronizationTask(player);
|
||||
@@ -66,12 +80,26 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
|
||||
}
|
||||
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);
|
||||
for (Player player : players) {
|
||||
SynchronizationTask task = new PostPlayerSynchronizationTask(player);
|
||||
executor.submit(new PhasedSynchronizationTask(phaser, task));
|
||||
}
|
||||
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;
|
||||
|
||||
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.Player;
|
||||
import org.apollo.game.sync.task.NpcSynchronizationTask;
|
||||
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.PreNpcSynchronizationTask;
|
||||
import org.apollo.game.sync.task.PrePlayerSynchronizationTask;
|
||||
import org.apollo.game.sync.task.SynchronizationTask;
|
||||
import org.apollo.util.CharacterRepository;
|
||||
@@ -16,27 +20,41 @@ import org.apollo.util.CharacterRepository;
|
||||
* cores/processors, however, both classes will work.
|
||||
*
|
||||
* @author Graham
|
||||
* @author Major
|
||||
*/
|
||||
public final class SequentialClientSynchronizer extends ClientSynchronizer {
|
||||
|
||||
@Override
|
||||
public void synchronize() {
|
||||
CharacterRepository<Player> players = World.getWorld().getPlayerRepository();
|
||||
CharacterRepository<Npc> npcs = World.getWorld().getNpcRepository();
|
||||
|
||||
for (Player player : players) {
|
||||
SynchronizationTask task = new PrePlayerSynchronizationTask(player);
|
||||
task.run();
|
||||
}
|
||||
|
||||
for (Npc npc : npcs) {
|
||||
SynchronizationTask task = new PreNpcSynchronizationTask(npc);
|
||||
task.run();
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
SynchronizationTask task = new PlayerSynchronizationTask(player);
|
||||
task.run();
|
||||
task = new NpcSynchronizationTask(player);
|
||||
task.run();
|
||||
}
|
||||
|
||||
for (Player player : players) {
|
||||
SynchronizationTask task = new PostPlayerSynchronizationTask(player);
|
||||
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
|
||||
*/
|
||||
public final class AddCharacterSegment extends SynchronizationSegment {
|
||||
public final class AddPlayerSegment extends SynchronizationSegment {
|
||||
|
||||
/**
|
||||
* The index.
|
||||
@@ -27,7 +27,7 @@ public final class AddCharacterSegment extends SynchronizationSegment {
|
||||
* @param index The characters's index.
|
||||
* @param position The position.
|
||||
*/
|
||||
public AddCharacterSegment(SynchronizationBlockSet blockSet, int index, Position position) {
|
||||
public AddPlayerSegment(SynchronizationBlockSet blockSet, int index, Position position) {
|
||||
super(blockSet);
|
||||
this.index = index;
|
||||
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.SynchronizationBlock;
|
||||
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.MovementSegment;
|
||||
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||
@@ -104,7 +104,7 @@ public final class PlayerSynchronizationTask extends SynchronizationTask {
|
||||
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.SynchronizationBlockSet;
|
||||
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.SegmentType;
|
||||
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||
@@ -60,7 +60,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
if (type == SegmentType.REMOVE_CHARACTER) {
|
||||
putRemoveCharacterUpdate(builder);
|
||||
} else if (type == SegmentType.ADD_CHARACTER) {
|
||||
putAddCharacterUpdate((AddCharacterSegment) segment, event, builder);
|
||||
putAddCharacterUpdate((AddPlayerSegment) segment, event, builder);
|
||||
putBlocks(segment, blockBuilder);
|
||||
} else {
|
||||
putMovementUpdate(segment, event, builder);
|
||||
@@ -86,7 +86,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
* @param event The event.
|
||||
* @param builder The builder.
|
||||
*/
|
||||
private void putAddCharacterUpdate(AddCharacterSegment seg, PlayerSynchronizationEvent event,
|
||||
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event,
|
||||
GamePacketBuilder builder) {
|
||||
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||
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.IdAssignmentEvent;
|
||||
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.OpenInterfaceSidebarEvent;
|
||||
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
||||
@@ -105,6 +106,7 @@ public final class Release317 extends Release {
|
||||
register(OpenInterfaceSidebarEvent.class, new OpenInterfaceSidebarEventEncoder());
|
||||
register(EnterAmountEvent.class, new EnterAmountEventEncoder());
|
||||
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.SynchronizationBlockSet;
|
||||
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.SegmentType;
|
||||
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||
@@ -60,7 +60,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
if (type == SegmentType.REMOVE_CHARACTER) {
|
||||
putRemoveCharacterUpdate(builder);
|
||||
} else if (type == SegmentType.ADD_CHARACTER) {
|
||||
putAddCharacterUpdate((AddCharacterSegment) segment, event, builder);
|
||||
putAddCharacterUpdate((AddPlayerSegment) segment, event, builder);
|
||||
putBlocks(segment, blockBuilder);
|
||||
} else {
|
||||
putMovementUpdate(segment, event, builder);
|
||||
@@ -86,7 +86,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
* @param event The event.
|
||||
* @param builder The builder.
|
||||
*/
|
||||
private void putAddCharacterUpdate(AddCharacterSegment seg, PlayerSynchronizationEvent event,
|
||||
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event,
|
||||
GamePacketBuilder builder) {
|
||||
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||
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.IdAssignmentEvent;
|
||||
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.OpenInterfaceSidebarEvent;
|
||||
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
||||
@@ -105,6 +106,7 @@ public final class Release377 extends Release {
|
||||
register(OpenInterfaceSidebarEvent.class, new OpenInterfaceSidebarEventEncoder());
|
||||
register(EnterAmountEvent.class, new EnterAmountEventEncoder());
|
||||
register(SetInterfaceTextEvent.class, new SetInterfaceTextEventEncoder());
|
||||
register(NpcSynchronizationEvent.class, new NpcSynchronizationEventEncoder());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user