mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 08:39:11 +00:00
Fully implement player synchronization.
This commit is contained in:
@@ -5,8 +5,8 @@ import java.util.List;
|
||||
|
||||
import org.apollo.game.action.Action;
|
||||
import org.apollo.game.event.Event;
|
||||
import org.apollo.game.event.impl.ServerMessageEvent;
|
||||
import org.apollo.game.model.Inventory.StackMode;
|
||||
import org.apollo.game.model.def.NpcDefinition;
|
||||
import org.apollo.game.scheduling.impl.SkillNormalizationTask;
|
||||
import org.apollo.game.sync.block.SynchronizationBlock;
|
||||
import org.apollo.game.sync.block.SynchronizationBlockSet;
|
||||
@@ -84,6 +84,12 @@ public abstract class Character {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@@ -377,12 +383,30 @@ public abstract class Character {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the character.
|
||||
* Updates the character's interacting character.
|
||||
*
|
||||
* @param message The message.
|
||||
* @param index The index of the interacting character.
|
||||
*/
|
||||
public void sendMessage(String message) {
|
||||
send(new ServerMessageEvent(message));
|
||||
public void updateInteractingCharacter(int 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public class Npc extends Character {
|
||||
*
|
||||
* @return The definition.
|
||||
*/
|
||||
public NpcDefinition getDefinition() {
|
||||
public NpcDefinition getNpcDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Queue;
|
||||
import org.apollo.game.event.Event;
|
||||
import org.apollo.game.event.impl.IdAssignmentEvent;
|
||||
import org.apollo.game.event.impl.LogoutEvent;
|
||||
import org.apollo.game.event.impl.ServerMessageEvent;
|
||||
import org.apollo.game.event.impl.SwitchTabInterfaceEvent;
|
||||
import org.apollo.game.model.inter.bank.BankConstants;
|
||||
import org.apollo.game.model.inv.AppearanceInventoryListener;
|
||||
@@ -144,6 +145,16 @@ public final class Player extends Character {
|
||||
*/
|
||||
private boolean excessivePlayers = false;
|
||||
|
||||
/**
|
||||
* This player's head icon.
|
||||
*/
|
||||
private int headIcon = -1;
|
||||
|
||||
/**
|
||||
* This player's prayer icon.
|
||||
*/
|
||||
private int prayerIcon = -1;
|
||||
|
||||
/**
|
||||
* This player's interface set.
|
||||
*/
|
||||
@@ -546,4 +557,49 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.apollo.game.sync.block;
|
||||
|
||||
import org.apollo.game.model.Appearance;
|
||||
import org.apollo.game.model.Inventory;
|
||||
import org.apollo.game.model.Appearance;
|
||||
|
||||
/**
|
||||
* The appearance {@link SynchronizationBlock}.
|
||||
@@ -10,8 +10,6 @@ import org.apollo.game.model.Inventory;
|
||||
*/
|
||||
public final class AppearanceBlock extends SynchronizationBlock {
|
||||
|
||||
// TODO head icons support
|
||||
|
||||
/**
|
||||
* The player's name.
|
||||
*/
|
||||
@@ -37,6 +35,21 @@ public final class AppearanceBlock extends SynchronizationBlock {
|
||||
*/
|
||||
private final Inventory equipment;
|
||||
|
||||
/**
|
||||
* The player's prayer icon.
|
||||
*/
|
||||
private final int prayerIcon;
|
||||
|
||||
/**
|
||||
* The player's head icon.
|
||||
*/
|
||||
private final int headIcon;
|
||||
|
||||
/**
|
||||
* The npc id this player is appearing as, if any.
|
||||
*/
|
||||
private final int npcId;
|
||||
|
||||
/**
|
||||
* Creates the appearance block.
|
||||
*
|
||||
@@ -46,21 +59,25 @@ public final class AppearanceBlock extends SynchronizationBlock {
|
||||
* @param skill The player's skill, or 0 if showing the combat level.
|
||||
* @param equipment The player's equipment.
|
||||
*/
|
||||
AppearanceBlock(long name, Appearance appearance, int combat, int skill, Inventory equipment) {
|
||||
AppearanceBlock(long name, Appearance appearance, int combat, int skill, Inventory equipment, int prayerIcon,
|
||||
int headIcon, int npcId) {
|
||||
this.name = name;
|
||||
this.appearance = appearance;
|
||||
this.combat = combat;
|
||||
this.skill = skill;
|
||||
this.equipment = equipment.clone();
|
||||
this.prayerIcon = prayerIcon;
|
||||
this.headIcon = headIcon;
|
||||
this.npcId = npcId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's name.
|
||||
* If the player is appearing as an npc or not.
|
||||
*
|
||||
* @return The player's name.
|
||||
* @return {@code true} if the player is appearing as an npc, otherwise {@code false}.
|
||||
*/
|
||||
public long getName() {
|
||||
return name;
|
||||
public boolean appearingAsNpc() {
|
||||
return npcId != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,15 +98,6 @@ public final class AppearanceBlock extends SynchronizationBlock {
|
||||
return combat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's skill level.
|
||||
*
|
||||
* @return The player's skill level.
|
||||
*/
|
||||
public int getSkillLevel() {
|
||||
return skill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's equipment.
|
||||
*
|
||||
@@ -99,4 +107,49 @@ public final class AppearanceBlock extends SynchronizationBlock {
|
||||
return equipment;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Gets the player's head icon.
|
||||
*
|
||||
* @return The head icon.
|
||||
*/
|
||||
public int getHeadIcon() {
|
||||
return headIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's name.
|
||||
*
|
||||
* @return The player's name.
|
||||
*/
|
||||
public long getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the npc id the player is appearing as, if any.
|
||||
*
|
||||
* @return The npc id.
|
||||
*/
|
||||
public int getNpcId() {
|
||||
return npcId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's prayer icon.
|
||||
*
|
||||
* @return The prayer icon.
|
||||
*/
|
||||
public int getPrayerIcon() {
|
||||
return prayerIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's skill level.
|
||||
*
|
||||
* @return The player's skill level.
|
||||
*/
|
||||
public int getSkillLevel() {
|
||||
return skill;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,12 +29,12 @@ public final class ChatBlock extends SynchronizationBlock {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the privilege level of the player who said the message.
|
||||
* Gets the compressed message.
|
||||
*
|
||||
* @return The privilege level.
|
||||
* @return The compressed message.
|
||||
*/
|
||||
public PrivilegeLevel getPrivilegeLevel() {
|
||||
return privilegeLevel;
|
||||
public byte[] getCompressedMessage() {
|
||||
return chatEvent.getCompressedMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,6 +46,15 @@ public final class ChatBlock extends SynchronizationBlock {
|
||||
return chatEvent.getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the privilege level of the player who said the message.
|
||||
*
|
||||
* @return The privilege level.
|
||||
*/
|
||||
public PrivilegeLevel getPrivilegeLevel() {
|
||||
return privilegeLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text color.
|
||||
*
|
||||
@@ -64,13 +73,4 @@ public final class ChatBlock extends SynchronizationBlock {
|
||||
return chatEvent.getTextEffects();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the compressed message.
|
||||
*
|
||||
* @return The compressed message.
|
||||
*/
|
||||
public byte[] getCompressedMessage() {
|
||||
return chatEvent.getCompressedMessage();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.apollo.game.sync.block;
|
||||
|
||||
/**
|
||||
* The Force Chat {@link SynchronizationBlock}. This is a block that can be implemented in both player and npc
|
||||
* synchronization tasks, and will cause the character to shout the specified text. It is not possible to add colour or
|
||||
* effect (e.g. wave or scroll) to this block.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public class ForceChatBlock extends SynchronizationBlock {
|
||||
|
||||
/**
|
||||
* The chat text.
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
/**
|
||||
* Creates a new force chat [@link SynchronizationBlock}.
|
||||
*
|
||||
* @param message The message the character will say.
|
||||
*/
|
||||
public ForceChatBlock(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message being sent by this block.
|
||||
*
|
||||
* @return The message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package org.apollo.game.sync.block;
|
||||
|
||||
import org.apollo.game.model.Direction;
|
||||
import org.apollo.game.model.Position;
|
||||
|
||||
/**
|
||||
* The Force Movement {@link SynchronizationBlock}.
|
||||
*
|
||||
* @note This block is used to force a player to walk to a set location. The player can then perform an action (e.g. an
|
||||
* animation), as used in the Agility skill, hence this block earning the name 'Asynchronous Animation/Walking',
|
||||
* although the action is not restricted to animations.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public class ForceMovementBlock extends SynchronizationBlock {
|
||||
|
||||
/**
|
||||
* The initial {@link Position} of the player.
|
||||
*/
|
||||
private final Position initialPosition;
|
||||
|
||||
/**
|
||||
* The {@link Position} the player is being moved to.
|
||||
*/
|
||||
private final Position finalPosition;
|
||||
|
||||
/**
|
||||
* The length of time (in game ticks) the player's movement along the X axis will last.
|
||||
*/
|
||||
private final int travelDurationX;
|
||||
|
||||
/**
|
||||
* The length of time (in game ticks) the player's movement along the Y axis will last.
|
||||
*/
|
||||
private final int travelDurationY;
|
||||
|
||||
/**
|
||||
* The direction the player is moving.
|
||||
*/
|
||||
private final Direction direction;
|
||||
|
||||
/**
|
||||
* Creates a new Force Movement block.
|
||||
*
|
||||
* @param initialPosition The initial {@link Position} of the player.
|
||||
* @param finalPosition The final {@link Position} of the player
|
||||
* @param travelDurationX The length of time (in game ticks) the player's movement along the X axis will last.
|
||||
* @param travelDurationY The length of time (in game ticks) the player's movement along the Y axis will last.
|
||||
* @param direction The direction the player should move.
|
||||
*/
|
||||
public ForceMovementBlock(Position initialPosition, Position finalPosition, int travelDurationX,
|
||||
int travelDurationY, Direction direction) {
|
||||
this.initialPosition = initialPosition;
|
||||
this.finalPosition = finalPosition;
|
||||
this.travelDurationX = travelDurationX;
|
||||
this.travelDurationY = travelDurationY;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the direction the player should move.
|
||||
*
|
||||
* @return The direction.
|
||||
*/
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the final position. This shouldn't be used to get the initial X and Y coordinates, see {@link #getFinalX()}
|
||||
* and {@link #getFinalY()}.
|
||||
*
|
||||
* @return The final {@link Position}.
|
||||
*/
|
||||
public Position getFinalPosition() {
|
||||
return finalPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the X coordinate of the final {@link Position}.
|
||||
*
|
||||
* @return The X coordinate.
|
||||
*/
|
||||
public int getFinalX() {
|
||||
return finalPosition.getX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Y coordinate of the final {@link Position}.
|
||||
*
|
||||
* @return The Y coordinate.
|
||||
*/
|
||||
public int getFinalY() {
|
||||
return finalPosition.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the initial position. This shouldn't be used to get the initial X and Y coordinates, see
|
||||
* {@link #getInitialX()} and {@link #getInitialY()}.
|
||||
*
|
||||
* @return The initial {@link Position}.
|
||||
*/
|
||||
public Position getInitialPosition() {
|
||||
return initialPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the X coordinate of the initial {@link Position}.
|
||||
*
|
||||
* @return The X coordinate.
|
||||
*/
|
||||
public int getInitialX() {
|
||||
return initialPosition.getX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Y coordinate of the initial {@link Position}.
|
||||
*
|
||||
* @return The Y coordinate.
|
||||
*/
|
||||
public int getInitialY() {
|
||||
return initialPosition.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of time (in game ticks) the player's movement along the Y axis will last.
|
||||
*
|
||||
* @return The time period.
|
||||
*/
|
||||
public int getTravelDurationX() {
|
||||
return travelDurationX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of time (in game ticks) the player's movement along the Y axis will last.
|
||||
*
|
||||
* @return The time period.
|
||||
*/
|
||||
public int getTravelDurationY() {
|
||||
return travelDurationY;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.apollo.game.sync.block;
|
||||
|
||||
/**
|
||||
* The Hit Update {@link SynchronizationBlock}. This is a simple implementation designed so that you can integrate it
|
||||
* easily with your combat system. Both npcs and players can implement this block.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public class HitUpdateBlock extends SynchronizationBlock {
|
||||
|
||||
/**
|
||||
* The amount of damage the hit will do.
|
||||
*/
|
||||
private final int damage;
|
||||
|
||||
/**
|
||||
* The type of hit (e.g. normal, poison).
|
||||
*/
|
||||
private final int type;
|
||||
|
||||
/**
|
||||
* The {@link org.apollo.game.model.Character}'s current health.
|
||||
*/
|
||||
private final int currentHealth;
|
||||
|
||||
/**
|
||||
* The {@link org.apollo.game.model.Character}'s maximum health.
|
||||
*/
|
||||
private final int maximumHealth;
|
||||
|
||||
/**
|
||||
* Creates a new Hit Update block.
|
||||
*
|
||||
* @param hitDamage The damage dealt by the hit.
|
||||
* @param hitType The type of hit.
|
||||
* @param currentHealth The current health of the {@link org.apollo.game.model.Character}.
|
||||
* @param maximumHealth The maximum health of the {@link org.apollo.game.model.Character}.
|
||||
*/
|
||||
public HitUpdateBlock(int hitDamage, int hitType, int currentHealth, int maximumHealth) {
|
||||
damage = hitDamage;
|
||||
type = hitType;
|
||||
this.currentHealth = currentHealth;
|
||||
this.maximumHealth = maximumHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current health of the {@link org.apollo.game.model.Character}.
|
||||
*
|
||||
* @return The current health;
|
||||
*/
|
||||
public int getCurrentHealth() {
|
||||
return currentHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the damage done by the hit.
|
||||
*
|
||||
* @return The damage.
|
||||
*/
|
||||
public int getDamage() {
|
||||
return damage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum health of the {@link org.apollo.game.model.Character}.
|
||||
*
|
||||
* @return The maximum health.
|
||||
*/
|
||||
public int getMaximumHealth() {
|
||||
return maximumHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hit type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.apollo.game.sync.block;
|
||||
|
||||
/**
|
||||
* The InteractingCharacterBlock {@link SynchronizationBlock}.
|
||||
*
|
||||
* @note As all Apollo events should be immutable to avoid concurency issues, this uses the index of the character
|
||||
* rather than the actual character. This should not be changed.
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public class InteractingCharacterBlock extends SynchronizationBlock {
|
||||
|
||||
/**
|
||||
* The index of the character.
|
||||
*/
|
||||
private final int characterIndex;
|
||||
|
||||
/**
|
||||
* Creates the interacting character block.
|
||||
*
|
||||
* @param characterIndex The index of the current interacting character.
|
||||
*/
|
||||
public InteractingCharacterBlock(int characterIndex) {
|
||||
this.characterIndex = characterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interacting character's current index.
|
||||
*
|
||||
* @return The index of the character.
|
||||
*/
|
||||
public int getInteractingCharacterIndex() {
|
||||
return characterIndex;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.apollo.game.sync.block;
|
||||
|
||||
/**
|
||||
* The Second Hit Update {@link SynchronizationBlock}. This is believed to be used for when multiple attacks happen at
|
||||
* once (for example, the dragon-dagger special attack). This block can be implemented by both players and npcs.
|
||||
*
|
||||
*
|
||||
* @author Major
|
||||
*/
|
||||
public class SecondHitUpdateBlock extends SynchronizationBlock {
|
||||
|
||||
/**
|
||||
* The amount of damage the hit will do.
|
||||
*/
|
||||
private final int damage;
|
||||
|
||||
/**
|
||||
* The type of hit (e.g. normal, poison).
|
||||
*/
|
||||
private final int type;
|
||||
|
||||
/**
|
||||
* The character's current health.
|
||||
*/
|
||||
private final int currentHealth;
|
||||
|
||||
/**
|
||||
* The character's maximum health.
|
||||
*/
|
||||
private final int maximumHealth;
|
||||
|
||||
/**
|
||||
* Creates a new Second Hit Update block.
|
||||
*
|
||||
* @param hitDamage The damage dealt by the hit.
|
||||
* @param hitType The type of hit.
|
||||
* @param currentHealth The current health of the character.
|
||||
* @param maximumHealth The maximum health of the character.
|
||||
*/
|
||||
public SecondHitUpdateBlock(int hitDamage, int hitType, int currentHealth, int maximumHealth) {
|
||||
damage = hitDamage;
|
||||
type = hitType;
|
||||
this.currentHealth = currentHealth;
|
||||
this.maximumHealth = maximumHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current health of the character.
|
||||
*
|
||||
* @return The current health;
|
||||
*/
|
||||
public int getCurrentHealth() {
|
||||
return currentHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the damage done by the hit.
|
||||
*
|
||||
* @return The damage.
|
||||
*/
|
||||
public int getDamage() {
|
||||
return damage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum health of the character.
|
||||
*
|
||||
* @return The maximum health.
|
||||
*/
|
||||
public int getMaximumHealth() {
|
||||
return maximumHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hit type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,9 +2,10 @@ package org.apollo.game.sync.block;
|
||||
|
||||
import org.apollo.game.event.impl.ChatEvent;
|
||||
import org.apollo.game.model.Animation;
|
||||
import org.apollo.game.model.Direction;
|
||||
import org.apollo.game.model.Graphic;
|
||||
import org.apollo.game.model.Player;
|
||||
import org.apollo.game.model.Position;
|
||||
import org.apollo.game.model.Player;
|
||||
import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||
|
||||
/**
|
||||
@@ -16,6 +17,16 @@ import org.apollo.game.sync.seg.SynchronizationSegment;
|
||||
*/
|
||||
public abstract class SynchronizationBlock {
|
||||
|
||||
/**
|
||||
* Creates an animation block with the specified animation.
|
||||
*
|
||||
* @param animation The animation.
|
||||
* @return The animation block.
|
||||
*/
|
||||
public static SynchronizationBlock createAnimationBlock(Animation animation) {
|
||||
return new AnimationBlock(animation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an appearance block for the specified player.
|
||||
*
|
||||
@@ -24,7 +35,8 @@ public abstract class SynchronizationBlock {
|
||||
*/
|
||||
public static SynchronizationBlock createAppearanceBlock(Player player) {
|
||||
return new AppearanceBlock(player.getEncodedName(), player.getAppearance(), player.getSkillSet()
|
||||
.getCombatLevel(), 0, player.getEquipment());
|
||||
.getCombatLevel(), 0, player.getEquipment(), player.getPrayerIcon(), player.getHeadIcon(),
|
||||
player.getNpcDefinition() == null ? -1 : player.getNpcDefinition().getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,13 +51,28 @@ public abstract class SynchronizationBlock {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animation block with the specified animation.
|
||||
* Creates a new force chat block with the specified message.
|
||||
*
|
||||
* @param animation The animation.
|
||||
* @return The animation block.
|
||||
* @param message The message.
|
||||
* @return The force chat block.
|
||||
*/
|
||||
public static SynchronizationBlock createAnimationBlock(Animation animation) {
|
||||
return new AnimationBlock(animation);
|
||||
public static SynchronizationBlock createForceChatBlock(String message) {
|
||||
return new ForceChatBlock(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new force movement block with the specified parameters.
|
||||
*
|
||||
* @param initialPosition The initial position of the player.
|
||||
* @param finalPosition The final position of the player.
|
||||
* @param travelDurationX The duration motion along the X axis will occur.
|
||||
* @param travelDurationY The duration motion along the Y axis will occur.
|
||||
* @param direction The direction the player will face.
|
||||
* @return The force movement block.
|
||||
*/
|
||||
public static SynchronizationBlock createForceMovementBlock(Position initialPosition, Position finalPosition,
|
||||
int travelDurationX, int travelDurationY, Direction direction) {
|
||||
return new ForceMovementBlock(initialPosition, finalPosition, travelDurationX, travelDurationY, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,6 +85,16 @@ public abstract class SynchronizationBlock {
|
||||
return new GraphicBlock(graphic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an interacting character block with the specified character index.
|
||||
*
|
||||
* @param index The index of the interacting character.
|
||||
* @return The interacting character block.
|
||||
*/
|
||||
public static SynchronizationBlock createInteractingCharacterBlock(int index) {
|
||||
return new InteractingCharacterBlock(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a turn to position block with the specified position.
|
||||
*
|
||||
@@ -68,4 +105,4 @@ public abstract class SynchronizationBlock {
|
||||
return new TurnToPositionBlock(position);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,15 @@ public final class SynchronizationBlockSet implements Cloneable {
|
||||
*/
|
||||
public void add(SynchronizationBlock block) {
|
||||
Class<? extends SynchronizationBlock> clazz = block.getClass();
|
||||
blocks.put(clazz, block); // this will overwrite old updates. best thing to do?
|
||||
blocks.put(clazz, block); // this will overwrite old updates. best thing
|
||||
// to do?
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the set.
|
||||
*/
|
||||
public void clear() {
|
||||
blocks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -32,22 +40,6 @@ public final class SynchronizationBlockSet implements Cloneable {
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the set.
|
||||
*/
|
||||
public void clear() {
|
||||
blocks.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the set.
|
||||
*
|
||||
* @return The size of the set.
|
||||
*/
|
||||
public int size() {
|
||||
return blocks.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this set contains the specified block.
|
||||
*
|
||||
@@ -58,15 +50,6 @@ public final class SynchronizationBlockSet implements Cloneable {
|
||||
return blocks.containsKey(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a block.
|
||||
*
|
||||
* @param clazz The block's class.
|
||||
*/
|
||||
public void remove(Class<? extends SynchronizationBlock> clazz) {
|
||||
blocks.remove(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a block.
|
||||
*
|
||||
@@ -79,4 +62,22 @@ public final class SynchronizationBlockSet implements Cloneable {
|
||||
return (T) blocks.get(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a block.
|
||||
*
|
||||
* @param clazz The block's class.
|
||||
*/
|
||||
public void remove(Class<? extends SynchronizationBlock> clazz) {
|
||||
blocks.remove(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the set.
|
||||
*
|
||||
* @return The size of the set.
|
||||
*/
|
||||
public int size() {
|
||||
return blocks.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,19 +2,24 @@ package org.apollo.net.release.r317;
|
||||
|
||||
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
||||
import org.apollo.game.model.Animation;
|
||||
import org.apollo.game.model.Appearance;
|
||||
import org.apollo.game.model.Direction;
|
||||
import org.apollo.game.model.EquipmentConstants;
|
||||
import org.apollo.game.model.Gender;
|
||||
import org.apollo.game.model.Graphic;
|
||||
import org.apollo.game.model.Inventory;
|
||||
import org.apollo.game.model.Item;
|
||||
import org.apollo.game.model.Position;
|
||||
import org.apollo.game.model.def.EquipmentDefinition;
|
||||
import org.apollo.game.model.Appearance;
|
||||
import org.apollo.game.model.EquipmentConstants;
|
||||
import org.apollo.game.sync.block.AnimationBlock;
|
||||
import org.apollo.game.sync.block.AppearanceBlock;
|
||||
import org.apollo.game.sync.block.ChatBlock;
|
||||
import org.apollo.game.sync.block.ForceChatBlock;
|
||||
import org.apollo.game.sync.block.ForceMovementBlock;
|
||||
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.TurnToPositionBlock;
|
||||
import org.apollo.game.sync.seg.AddCharacterSegment;
|
||||
@@ -34,6 +39,7 @@ import org.apollo.net.release.EventEncoder;
|
||||
* An {@link EventEncoder} for the {@link PlayerSynchronizationEvent}.
|
||||
*
|
||||
* @author Graham
|
||||
* @author Major
|
||||
*/
|
||||
public final class PlayerSynchronizationEventEncoder extends EventEncoder<PlayerSynchronizationEvent> {
|
||||
|
||||
@@ -73,16 +79,6 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
return builder.toGamePacket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a remove character update.
|
||||
*
|
||||
* @param builder The builder.
|
||||
*/
|
||||
private void putRemoveCharacterUpdate(GamePacketBuilder builder) {
|
||||
builder.putBits(1, 1);
|
||||
builder.putBits(2, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an add character update.
|
||||
*
|
||||
@@ -103,45 +99,130 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a movement update for the specified segment.
|
||||
* Puts an Animation block into the specified builder.
|
||||
*
|
||||
* @param seg The segment.
|
||||
* @param event The event.
|
||||
* @param builder The builder.
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putMovementUpdate(SynchronizationSegment seg, PlayerSynchronizationEvent event,
|
||||
GamePacketBuilder builder) {
|
||||
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||
if (seg.getType() == SegmentType.TELEPORT) {
|
||||
Position pos = ((TeleportSegment) seg).getDestination();
|
||||
builder.putBits(1, 1);
|
||||
builder.putBits(2, 3);
|
||||
builder.putBits(2, pos.getHeight());
|
||||
builder.putBits(1, event.hasRegionChanged() ? 0 : 1);
|
||||
builder.putBits(1, updateRequired ? 1 : 0);
|
||||
builder.putBits(7, pos.getLocalY(event.getLastKnownRegion()));
|
||||
builder.putBits(7, pos.getLocalX(event.getLastKnownRegion()));
|
||||
} else 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);
|
||||
private void putAnimationBlock(AnimationBlock block, GamePacketBuilder blockBuilder) {
|
||||
Animation animation = block.getAnimation();
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, animation.getId());
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.NEGATE, animation.getDelay());
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an appearance block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putAppearanceBlock(AppearanceBlock block, GamePacketBuilder blockBuilder) {
|
||||
Appearance appearance = block.getAppearance();
|
||||
GamePacketBuilder playerProperties = new GamePacketBuilder();
|
||||
|
||||
playerProperties.put(DataType.BYTE, appearance.getGender().toInteger());
|
||||
playerProperties.put(DataType.BYTE, block.getPrayerIcon() < 0 ? 0 : block.getPrayerIcon());
|
||||
|
||||
if (block.appearingAsNpc()) {
|
||||
playerProperties.put(DataType.BYTE, 255);
|
||||
playerProperties.put(DataType.BYTE, 255);
|
||||
playerProperties.put(DataType.SHORT, block.getNpcId());
|
||||
} else {
|
||||
if (updateRequired) {
|
||||
builder.putBits(1, 1);
|
||||
builder.putBits(2, 0);
|
||||
Inventory equipment = block.getEquipment();
|
||||
int[] style = appearance.getStyle();
|
||||
Item item, chest, helm;
|
||||
|
||||
for (int slot = 0; slot < 4; slot++) {
|
||||
if ((item = equipment.get(slot)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((chest = equipment.get(EquipmentConstants.CHEST)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + chest.getId());
|
||||
} else {
|
||||
builder.putBits(1, 0);
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[2]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.SHIELD)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
|
||||
if (chest != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(chest.getId());
|
||||
if (def != null && !def.isFullBody()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.LEGS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[5]);
|
||||
}
|
||||
|
||||
if ((helm = equipment.get(EquipmentConstants.HAT)) != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(helm.getId());
|
||||
if (def != null && !def.isFullHat() && !def.isFullMask()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.HANDS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[4]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.FEET)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[6]);
|
||||
}
|
||||
|
||||
EquipmentDefinition def = null;
|
||||
if (helm != null) {
|
||||
def = EquipmentDefinition.forId(helm.getId());
|
||||
}
|
||||
if (def != null && (def.isFullHat() || def.isFullMask()) || appearance.getGender() == Gender.FEMALE) {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[1]);
|
||||
}
|
||||
}
|
||||
|
||||
int[] colors = appearance.getColors();
|
||||
for (int color : colors) {
|
||||
playerProperties.put(DataType.BYTE, color);
|
||||
}
|
||||
|
||||
playerProperties.put(DataType.SHORT, 0x328); // stand
|
||||
playerProperties.put(DataType.SHORT, 0x337); // stand turn
|
||||
playerProperties.put(DataType.SHORT, 0x333); // walk
|
||||
playerProperties.put(DataType.SHORT, 0x334); // turn 180
|
||||
playerProperties.put(DataType.SHORT, 0x335); // turn 90 cw
|
||||
playerProperties.put(DataType.SHORT, 0x336); // turn 90 ccw
|
||||
playerProperties.put(DataType.SHORT, 0x338); // run
|
||||
|
||||
playerProperties.put(DataType.LONG, block.getName());
|
||||
playerProperties.put(DataType.BYTE, block.getCombatLevel());
|
||||
playerProperties.put(DataType.SHORT, block.getSkillLevel());
|
||||
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.NEGATE, playerProperties.getLength());
|
||||
|
||||
blockBuilder.putRawBuilder(playerProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,25 +236,36 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
if (blockSet.size() > 0) {
|
||||
int mask = 0;
|
||||
|
||||
if (blockSet.contains(ForceMovementBlock.class)) {
|
||||
mask |= 0x400;
|
||||
}
|
||||
if (blockSet.contains(GraphicBlock.class)) {
|
||||
mask |= 0x100;
|
||||
}
|
||||
|
||||
if (blockSet.contains(AnimationBlock.class)) {
|
||||
mask |= 0x8;
|
||||
}
|
||||
|
||||
if (blockSet.contains(ForceChatBlock.class)) {
|
||||
mask |= 0x4;
|
||||
}
|
||||
if (blockSet.contains(ChatBlock.class)) {
|
||||
mask |= 0x80;
|
||||
}
|
||||
|
||||
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||
mask |= 0x1;
|
||||
}
|
||||
if (blockSet.contains(AppearanceBlock.class)) {
|
||||
mask |= 0x10;
|
||||
}
|
||||
|
||||
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||
mask |= 0x2;
|
||||
}
|
||||
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||
mask |= 0x20;
|
||||
}
|
||||
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||
mask |= 0x200;
|
||||
}
|
||||
|
||||
if (mask >= 0x100) {
|
||||
mask |= 0x40;
|
||||
@@ -182,30 +274,181 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
blockBuilder.put(DataType.BYTE, mask);
|
||||
}
|
||||
|
||||
if (blockSet.contains(ForceMovementBlock.class)) {
|
||||
putForceMovementBlock(blockSet.get(ForceMovementBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(GraphicBlock.class)) {
|
||||
putGraphicBlock(blockSet.get(GraphicBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(AnimationBlock.class)) {
|
||||
putAnimationBlock(blockSet.get(AnimationBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(ForceChatBlock.class)) {
|
||||
putForceChatBlock(blockSet.get(ForceChatBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(ChatBlock.class)) {
|
||||
putChatBlock(blockSet.get(ChatBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||
putInteractingCharacterBlock(blockSet.get(InteractingCharacterBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(AppearanceBlock.class)) {
|
||||
putAppearanceBlock(blockSet.get(AppearanceBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||
putTurnToPositionBlock(blockSet.get(TurnToPositionBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||
putHitUpdateBlock(blockSet.get(HitUpdateBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||
putSecondHitUpdateBlock(blockSet.get(SecondHitUpdateBlock.class), blockBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a turn to position block into the specified builder.
|
||||
* Puts a Chat block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putChatBlock(ChatBlock block, GamePacketBuilder blockBuilder) {
|
||||
byte[] bytes = block.getCompressedMessage();
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, block.getTextColor() << 8 | block.getTextEffects());
|
||||
blockBuilder.put(DataType.BYTE, block.getPrivilegeLevel().toInteger());
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.NEGATE, bytes.length);
|
||||
blockBuilder.putBytesReverse(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Force Movement block in the specified builder.
|
||||
*
|
||||
* @param forceMovementBlock The block.
|
||||
* @param builder The builder.
|
||||
*/
|
||||
private void putForceMovementBlock(ForceMovementBlock block, GamePacketBuilder builder) {
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getInitialX());
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getInitialY());
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getFinalX());
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getFinalY());
|
||||
builder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, block.getTravelDurationX());
|
||||
builder.put(DataType.SHORT, DataTransformation.ADD, block.getTravelDurationY());
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getDirection().toInteger());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, DataOrder.LITTLE, graphic.getId());
|
||||
blockBuilder.put(DataType.INT, graphic.getHeight() << 16 | graphic.getDelay() & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, block.getDamage());
|
||||
builder.put(DataType.BYTE, DataTransformation.ADD, block.getType());
|
||||
builder.put(DataType.BYTE, block.getCurrentHealth());
|
||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, 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, PlayerSynchronizationEvent event,
|
||||
GamePacketBuilder builder) {
|
||||
boolean updateRequired = seg.getBlockSet().size() > 0;
|
||||
if (seg.getType() == SegmentType.TELEPORT) { // teleported
|
||||
Position pos = ((TeleportSegment) seg).getDestination();
|
||||
builder.putBits(1, 1);
|
||||
builder.putBits(2, 3);
|
||||
builder.putBits(2, pos.getHeight());
|
||||
builder.putBits(1, event.hasRegionChanged() ? 0 : 1);
|
||||
builder.putBits(1, updateRequired ? 1 : 0);
|
||||
builder.putBits(7, pos.getLocalY(event.getLastKnownRegion()));
|
||||
builder.putBits(7, pos.getLocalX(event.getLastKnownRegion()));
|
||||
} else if (seg.getType() == SegmentType.RUN) { // running movement
|
||||
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) { // walking movement
|
||||
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) { // no movement
|
||||
builder.putBits(1, 1);
|
||||
builder.putBits(2, 0);
|
||||
} else {
|
||||
builder.putBits(1, 0); // no sync required
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, 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 Turn To Position block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
@@ -216,153 +459,4 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, pos.getY() * 2 + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, DataOrder.LITTLE, graphic.getId());
|
||||
blockBuilder.put(DataType.INT, (graphic.getHeight() << 16) | (graphic.getDelay() & 0xFFFF));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, DataTransformation.NEGATE, animation.getDelay());
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a chat block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putChatBlock(ChatBlock block, GamePacketBuilder blockBuilder) {
|
||||
byte[] bytes = block.getCompressedMessage();
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, (block.getTextColor() << 8) | block.getTextEffects());
|
||||
blockBuilder.put(DataType.BYTE, block.getPrivilegeLevel().toInteger());
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.NEGATE, bytes.length);
|
||||
blockBuilder.putBytesReverse(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an appearance block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putAppearanceBlock(AppearanceBlock block, GamePacketBuilder blockBuilder) {
|
||||
Appearance appearance = block.getAppearance();
|
||||
GamePacketBuilder playerProperties = new GamePacketBuilder();
|
||||
|
||||
playerProperties.put(DataType.BYTE, appearance.getGender().toInteger()); // gender
|
||||
playerProperties.put(DataType.BYTE, 0); // skull icon
|
||||
|
||||
Inventory equipment = block.getEquipment();
|
||||
int[] style = appearance.getStyle();
|
||||
Item item, chest, helm;
|
||||
|
||||
for (int slot = 0; slot < 4; slot++) {
|
||||
if ((item = equipment.get(slot)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((chest = equipment.get(EquipmentConstants.CHEST)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + chest.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[2]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.SHIELD)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
|
||||
if (chest != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(chest.getId());
|
||||
if (def != null && !def.isFullBody()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.LEGS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[5]);
|
||||
}
|
||||
|
||||
if ((helm = equipment.get(EquipmentConstants.HAT)) != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(helm.getId());
|
||||
if (def != null && !def.isFullHat() && !def.isFullMask()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.HANDS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[4]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.FEET)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[6]);
|
||||
}
|
||||
|
||||
EquipmentDefinition def = null;
|
||||
if (helm != null) {
|
||||
def = EquipmentDefinition.forId(helm.getId());
|
||||
}
|
||||
if ((def != null && (def.isFullHat() || def.isFullMask())) || appearance.getGender() == Gender.FEMALE) {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[1]);
|
||||
}
|
||||
|
||||
int[] colors = appearance.getColors();
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
playerProperties.put(DataType.BYTE, colors[i]);
|
||||
}
|
||||
|
||||
playerProperties.put(DataType.SHORT, 0x328); // stand
|
||||
playerProperties.put(DataType.SHORT, 0x337); // stand turn
|
||||
playerProperties.put(DataType.SHORT, 0x333); // walk
|
||||
playerProperties.put(DataType.SHORT, 0x334); // turn 180
|
||||
playerProperties.put(DataType.SHORT, 0x335); // turn 90 cw
|
||||
playerProperties.put(DataType.SHORT, 0x336); // turn 90 ccw
|
||||
playerProperties.put(DataType.SHORT, 0x338); // run
|
||||
|
||||
playerProperties.put(DataType.LONG, block.getName());
|
||||
playerProperties.put(DataType.BYTE, block.getCombatLevel()); // combat
|
||||
// level
|
||||
playerProperties.put(DataType.SHORT, block.getSkillLevel()); // total
|
||||
// skill
|
||||
// level
|
||||
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.NEGATE, playerProperties.getLength());
|
||||
blockBuilder.putRawBuilder(playerProperties);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,19 +2,24 @@ package org.apollo.net.release.r377;
|
||||
|
||||
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
|
||||
import org.apollo.game.model.Animation;
|
||||
import org.apollo.game.model.Appearance;
|
||||
import org.apollo.game.model.Direction;
|
||||
import org.apollo.game.model.EquipmentConstants;
|
||||
import org.apollo.game.model.Gender;
|
||||
import org.apollo.game.model.Graphic;
|
||||
import org.apollo.game.model.Inventory;
|
||||
import org.apollo.game.model.Item;
|
||||
import org.apollo.game.model.Position;
|
||||
import org.apollo.game.model.def.EquipmentDefinition;
|
||||
import org.apollo.game.model.Appearance;
|
||||
import org.apollo.game.model.EquipmentConstants;
|
||||
import org.apollo.game.sync.block.AnimationBlock;
|
||||
import org.apollo.game.sync.block.AppearanceBlock;
|
||||
import org.apollo.game.sync.block.ChatBlock;
|
||||
import org.apollo.game.sync.block.ForceChatBlock;
|
||||
import org.apollo.game.sync.block.ForceMovementBlock;
|
||||
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.TurnToPositionBlock;
|
||||
import org.apollo.game.sync.seg.AddCharacterSegment;
|
||||
@@ -34,6 +39,7 @@ import org.apollo.net.release.EventEncoder;
|
||||
* An {@link EventEncoder} for the {@link PlayerSynchronizationEvent}.
|
||||
*
|
||||
* @author Graham
|
||||
* @author Major
|
||||
*/
|
||||
public final class PlayerSynchronizationEventEncoder extends EventEncoder<PlayerSynchronizationEvent> {
|
||||
|
||||
@@ -73,16 +79,6 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
return builder.toGamePacket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a remove character update.
|
||||
*
|
||||
* @param builder The builder.
|
||||
*/
|
||||
private void putRemoveCharacterUpdate(GamePacketBuilder builder) {
|
||||
builder.putBits(1, 1);
|
||||
builder.putBits(2, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an add character update.
|
||||
*
|
||||
@@ -102,6 +98,292 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
builder.putBits(5, other.getY() - player.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.ADD, animation.getDelay());
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an Appearance block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putAppearanceBlock(AppearanceBlock block, GamePacketBuilder blockBuilder) {
|
||||
Appearance appearance = block.getAppearance();
|
||||
GamePacketBuilder playerProperties = new GamePacketBuilder();
|
||||
|
||||
playerProperties.put(DataType.BYTE, appearance.getGender().toInteger());
|
||||
playerProperties.put(DataType.BYTE, -1); // skull icon
|
||||
playerProperties.put(DataType.BYTE, -1); // prayer icon
|
||||
|
||||
if (block.appearingAsNpc()) {
|
||||
playerProperties.put(DataType.BYTE, 255);
|
||||
playerProperties.put(DataType.BYTE, 255);
|
||||
playerProperties.put(DataType.SHORT, block.getNpcId());
|
||||
} else {
|
||||
Inventory equipment = block.getEquipment();
|
||||
int[] style = appearance.getStyle();
|
||||
Item item, chest, helm;
|
||||
|
||||
for (int slot = 0; slot < 4; slot++) {
|
||||
if ((item = equipment.get(slot)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((chest = equipment.get(EquipmentConstants.CHEST)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + chest.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[2]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.SHIELD)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
|
||||
if (chest != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(chest.getId());
|
||||
if (def != null && !def.isFullBody()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.LEGS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[5]);
|
||||
}
|
||||
|
||||
if ((helm = equipment.get(EquipmentConstants.HAT)) != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(helm.getId());
|
||||
if (def != null && !def.isFullHat() && !def.isFullMask()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.HANDS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[4]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.FEET)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[6]);
|
||||
}
|
||||
|
||||
EquipmentDefinition def = null;
|
||||
if (helm != null) {
|
||||
def = EquipmentDefinition.forId(helm.getId());
|
||||
}
|
||||
if (def != null && (def.isFullHat() || def.isFullMask()) || appearance.getGender() == Gender.FEMALE) {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[1]);
|
||||
}
|
||||
}
|
||||
|
||||
int[] colors = appearance.getColors();
|
||||
for (int color : colors) {
|
||||
playerProperties.put(DataType.BYTE, color);
|
||||
}
|
||||
|
||||
playerProperties.put(DataType.SHORT, 0x328); // stand
|
||||
playerProperties.put(DataType.SHORT, 0x337); // stand turn
|
||||
playerProperties.put(DataType.SHORT, 0x333); // walk
|
||||
playerProperties.put(DataType.SHORT, 0x334); // turn 180
|
||||
playerProperties.put(DataType.SHORT, 0x335); // turn 90 cw
|
||||
playerProperties.put(DataType.SHORT, 0x336); // turn 90 ccw
|
||||
playerProperties.put(DataType.SHORT, 0x338); // run
|
||||
|
||||
playerProperties.put(DataType.LONG, block.getName());
|
||||
playerProperties.put(DataType.BYTE, block.getCombatLevel());
|
||||
playerProperties.put(DataType.SHORT, block.getSkillLevel());
|
||||
|
||||
blockBuilder.put(DataType.BYTE, playerProperties.getLength());
|
||||
blockBuilder.putRawBuilderReverse(playerProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 |= 0x8;
|
||||
}
|
||||
if (blockSet.contains(ForceChatBlock.class)) {
|
||||
mask |= 0x10;
|
||||
}
|
||||
if (blockSet.contains(ForceMovementBlock.class)) {
|
||||
mask |= 0x100;
|
||||
}
|
||||
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||
mask |= 0x1;
|
||||
}
|
||||
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||
mask |= 0x2;
|
||||
}
|
||||
if (blockSet.contains(GraphicBlock.class)) {
|
||||
mask |= 0x200;
|
||||
}
|
||||
if (blockSet.contains(AppearanceBlock.class)) {
|
||||
mask |= 0x4;
|
||||
}
|
||||
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||
mask |= 0x400;
|
||||
}
|
||||
if (blockSet.contains(ChatBlock.class)) {
|
||||
mask |= 0x40;
|
||||
}
|
||||
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||
mask |= 0x80;
|
||||
}
|
||||
|
||||
if (mask >= 0x100) {
|
||||
mask |= 0x20;
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, mask);
|
||||
} else {
|
||||
blockBuilder.put(DataType.BYTE, mask);
|
||||
}
|
||||
|
||||
if (blockSet.contains(AnimationBlock.class)) {
|
||||
putAnimationBlock(blockSet.get(AnimationBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(ForceChatBlock.class)) {
|
||||
putForceChatBlock(blockSet.get(ForceChatBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(ForceMovementBlock.class)) {
|
||||
putForceMovementBlock(blockSet.get(ForceMovementBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(InteractingCharacterBlock.class)) {
|
||||
putInteractingCharacterBlock(blockSet.get(InteractingCharacterBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||
putTurnToPositionBlock(blockSet.get(TurnToPositionBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(GraphicBlock.class)) {
|
||||
putGraphicBlock(blockSet.get(GraphicBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(AppearanceBlock.class)) {
|
||||
putAppearanceBlock(blockSet.get(AppearanceBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(SecondHitUpdateBlock.class)) {
|
||||
putSecondHitUpdateBlock(blockSet.get(SecondHitUpdateBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(ChatBlock.class)) {
|
||||
putChatBlock(blockSet.get(ChatBlock.class), blockBuilder);
|
||||
}
|
||||
if (blockSet.contains(HitUpdateBlock.class)) {
|
||||
putHitUpdateBlock(blockSet.get(HitUpdateBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a chat block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putChatBlock(ChatBlock block, GamePacketBuilder blockBuilder) {
|
||||
byte[] bytes = block.getCompressedMessage();
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, block.getTextEffects() << 8 | block.getTextColor());
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.NEGATE, block.getPrivilegeLevel().toInteger());
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.ADD, bytes.length);
|
||||
blockBuilder.putBytes(DataTransformation.ADD, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 force movement block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param builder The builder.
|
||||
*/
|
||||
private void putForceMovementBlock(ForceMovementBlock block, GamePacketBuilder builder) {
|
||||
builder.put(DataType.BYTE, DataTransformation.ADD, block.getInitialX());
|
||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, block.getInitialY());
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getFinalX());
|
||||
builder.put(DataType.BYTE, block.getFinalY());
|
||||
builder.put(DataType.SHORT, block.getTravelDurationX());
|
||||
builder.put(DataType.SHORT, DataTransformation.ADD, block.getTravelDurationY());
|
||||
builder.put(DataType.BYTE, block.getDirection().toInteger());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, DataTransformation.ADD, graphic.getId());
|
||||
blockBuilder.put(DataType.INT, DataOrder.MIDDLE, graphic.getHeight() << 16 & 0xFFFF0000 | graphic.getDelay()
|
||||
& 0x0000FFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.SUBTRACT, block.getDamage());
|
||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, block.getType());
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, 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, DataTransformation.ADD, block.getInteractingCharacterIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a movement update for the specified segment.
|
||||
*
|
||||
@@ -145,63 +427,26 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the blocks for the specified segment.
|
||||
* Puts a remove character update.
|
||||
*
|
||||
* @param segment The segment.
|
||||
* @param blockBuilder The block builder.
|
||||
* @param builder The builder.
|
||||
*/
|
||||
private void putBlocks(SynchronizationSegment segment, GamePacketBuilder blockBuilder) {
|
||||
SynchronizationBlockSet blockSet = segment.getBlockSet();
|
||||
if (blockSet.size() > 0) {
|
||||
int mask = 0;
|
||||
private void putRemoveCharacterUpdate(GamePacketBuilder builder) {
|
||||
builder.putBits(1, 1);
|
||||
builder.putBits(2, 3);
|
||||
}
|
||||
|
||||
if (blockSet.contains(AnimationBlock.class)) {
|
||||
mask |= 0x8;
|
||||
}
|
||||
|
||||
if (blockSet.contains(ChatBlock.class)) {
|
||||
mask |= 0x40;
|
||||
}
|
||||
|
||||
if (blockSet.contains(GraphicBlock.class)) {
|
||||
mask |= 0x200;
|
||||
}
|
||||
|
||||
if (blockSet.contains(AppearanceBlock.class)) {
|
||||
mask |= 0x4;
|
||||
}
|
||||
|
||||
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||
mask |= 0x2;
|
||||
}
|
||||
|
||||
if (mask >= 0x100) {
|
||||
mask |= 0x20;
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, mask);
|
||||
} else {
|
||||
blockBuilder.put(DataType.BYTE, mask);
|
||||
}
|
||||
|
||||
if (blockSet.contains(AnimationBlock.class)) {
|
||||
putAnimationBlock(blockSet.get(AnimationBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(ChatBlock.class)) {
|
||||
putChatBlock(blockSet.get(ChatBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(GraphicBlock.class)) {
|
||||
putGraphicBlock(blockSet.get(GraphicBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(AppearanceBlock.class)) {
|
||||
putAppearanceBlock(blockSet.get(AppearanceBlock.class), blockBuilder);
|
||||
}
|
||||
|
||||
if (blockSet.contains(TurnToPositionBlock.class)) {
|
||||
putTurnToPositionBlock(blockSet.get(TurnToPositionBlock.class), blockBuilder);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Puts a secondary 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.ADD, block.getDamage());
|
||||
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, block.getType());
|
||||
builder.put(DataType.BYTE, DataTransformation.NEGATE, block.getCurrentHealth());
|
||||
builder.put(DataType.BYTE, block.getMaximumHealth());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,152 +461,4 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
|
||||
blockBuilder.put(DataType.SHORT, pos.getY() * 2 + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, DataTransformation.ADD, graphic.getId());
|
||||
blockBuilder.put(DataType.INT, DataOrder.MIDDLE,
|
||||
((graphic.getHeight() << 16) & 0xFFFF0000) | (graphic.getDelay() & 0x0000FFFF));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.ADD, animation.getDelay());
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a chat block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putChatBlock(ChatBlock block, GamePacketBuilder blockBuilder) {
|
||||
byte[] bytes = block.getCompressedMessage();
|
||||
blockBuilder.put(DataType.SHORT, DataOrder.LITTLE, (block.getTextEffects() << 8) | block.getTextColor());
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.NEGATE, block.getPrivilegeLevel().toInteger());
|
||||
blockBuilder.put(DataType.BYTE, DataTransformation.ADD, bytes.length);
|
||||
blockBuilder.putBytes(DataTransformation.ADD, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts an appearance block into the specified builder.
|
||||
*
|
||||
* @param block The block.
|
||||
* @param blockBuilder The builder.
|
||||
*/
|
||||
private void putAppearanceBlock(AppearanceBlock block, GamePacketBuilder blockBuilder) {
|
||||
Appearance appearance = block.getAppearance();
|
||||
GamePacketBuilder playerProperties = new GamePacketBuilder();
|
||||
|
||||
playerProperties.put(DataType.BYTE, appearance.getGender().toInteger()); // gender
|
||||
playerProperties.put(DataType.BYTE, -1); // skull icon
|
||||
playerProperties.put(DataType.BYTE, -1); // prayer icon
|
||||
|
||||
Inventory equipment = block.getEquipment();
|
||||
int[] style = appearance.getStyle();
|
||||
Item item, chest, helm;
|
||||
|
||||
for (int slot = 0; slot < 4; slot++) {
|
||||
if ((item = equipment.get(slot)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((chest = equipment.get(EquipmentConstants.CHEST)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + chest.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[2]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.SHIELD)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
|
||||
if (chest != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(chest.getId());
|
||||
if (def != null && !def.isFullBody()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[3]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.LEGS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[5]);
|
||||
}
|
||||
|
||||
if ((helm = equipment.get(EquipmentConstants.HAT)) != null) {
|
||||
EquipmentDefinition def = EquipmentDefinition.forId(helm.getId());
|
||||
if (def != null && !def.isFullHat() && !def.isFullMask()) {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
} else {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
}
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[0]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.HANDS)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[4]);
|
||||
}
|
||||
|
||||
if ((item = equipment.get(EquipmentConstants.FEET)) != null) {
|
||||
playerProperties.put(DataType.SHORT, 0x200 + item.getId());
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[6]);
|
||||
}
|
||||
|
||||
EquipmentDefinition def = null;
|
||||
if (helm != null) {
|
||||
def = EquipmentDefinition.forId(helm.getId());
|
||||
}
|
||||
if ((def != null && (def.isFullHat() || def.isFullMask())) || appearance.getGender() == Gender.FEMALE) {
|
||||
playerProperties.put(DataType.BYTE, 0);
|
||||
} else {
|
||||
playerProperties.put(DataType.SHORT, 0x100 + style[1]);
|
||||
}
|
||||
|
||||
int[] colors = appearance.getColors();
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
playerProperties.put(DataType.BYTE, colors[i]);
|
||||
}
|
||||
|
||||
playerProperties.put(DataType.SHORT, 0x328); // stand
|
||||
playerProperties.put(DataType.SHORT, 0x337); // stand turn
|
||||
playerProperties.put(DataType.SHORT, 0x333); // walk
|
||||
playerProperties.put(DataType.SHORT, 0x334); // turn 180
|
||||
playerProperties.put(DataType.SHORT, 0x335); // turn 90 cw
|
||||
playerProperties.put(DataType.SHORT, 0x336); // turn 90 ccw
|
||||
playerProperties.put(DataType.SHORT, 0x338); // run
|
||||
|
||||
playerProperties.put(DataType.LONG, block.getName());
|
||||
playerProperties.put(DataType.BYTE, block.getCombatLevel()); // combat level
|
||||
playerProperties.put(DataType.SHORT, block.getSkillLevel()); // total skill level
|
||||
|
||||
blockBuilder.put(DataType.BYTE, playerProperties.getLength());
|
||||
blockBuilder.putRawBuilderReverse(playerProperties);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user