Merge branch 'master' of git@bitbucket.org:Major-/apollo.git.

This commit is contained in:
Ryley Kimmel
2015-03-03 17:45:28 -05:00
14 changed files with 334 additions and 9 deletions
+38
View File
@@ -0,0 +1,38 @@
java_import 'org.apollo.game.model.Direction'
module DoorConstants
# TODO: GameObjectOrientation enumeration in Apollo's core?
module Orientation
WEST = 0
NORTH = 1
EAST = 2
SOUTH = 3
end
# The object size of a door.
DOOR_SIZE = 1
# Door object ids that have a hinge on the left side.
LEFT_SIDE_HINGE_DOOR_IDS = [1516, 1536, 1533]
# Door object ids that have a hinge on the right side.
RIGHT_SIDE_HINGE_DOOR_IDS = [1519, 1530, 4465, 4467, 3014, 3017, 3018, 3019]
# A map of orientations that a door will translate to when opened.
ORIENTATIONS = {
# Orientations for doors that have a hinge on the left side.
:left_side_hinge => {
Orientation::NORTH => Orientation::WEST,
Orientation::SOUTH => Orientation::EAST,
Orientation::WEST => Orientation::SOUTH,
Orientation::EAST => Orientation::NORTH
},
# Orientations for doors that have a hinge on the right side.
:right_side_hinge => {
Orientation::NORTH => Orientation::EAST,
Orientation::SOUTH => Orientation::WEST,
Orientation::WEST => Orientation::NORTH,
Orientation::EAST => Orientation::SOUTH
}
}
end
+31
View File
@@ -0,0 +1,31 @@
java_import 'org.apollo.game.action.DistancedAction'
# A distanced action which opens a door.
class OpenDoorAction < DistancedAction
include DoorConstants
attr_reader :door_object
def initialize(mob, door_object)
super(0, true, mob, door_object.position, DOOR_SIZE)
@door_object = door_object
end
def executeAction
mob.turn_to @door_object.position
DoorUtil::toggle(@door_object, mob)
stop
end
def equals(other)
return (get_class == other.get_class && @position == other.position)
end
end
# Message handler for opening and closing doors.
on :message, :first_object_action do |ctx, player, message|
if DoorUtil::is_door?(message.id)
door_object = DoorUtil::get_door_object(message.position, message.id)
player.start_action(OpenDoorAction.new(player, door_object)) unless door_object.nil?
end
end
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<plugin>
<id>door</id>
<version>1</version>
<name>Doors</name>
<description>Adds support for doors throughout the game.</description>
<authors>
<author>Shiver</author>
</authors>
<scripts>
<script>constants.rb</script>
<script>util.rb</script>
<script>door.rb</script>
</scripts>
<dependencies/>
</plugin>
+99
View File
@@ -0,0 +1,99 @@
java_import 'org.apollo.game.model.entity.GameObject'
java_import 'org.apollo.game.model.entity.Entity'
java_import 'org.apollo.game.model.Position'
java_import 'org.apollo.game.message.impl.PositionMessage'
java_import 'org.apollo.game.message.impl.RemoveObjectMessage'
java_import 'org.apollo.game.message.impl.SendObjectMessage'
module DoorUtil
include DoorConstants
# A hash containing currently toggled door objects mapped to the original door objects.
TOGGLED_DOOR_REPOSITORY = {}
# Translates a door's position in the direction of its orientation.
def self.translate_door_position(door)
position = door.position
orientation = door.orientation
case orientation
when Orientation::WEST
return Position.new(position.x - 1, position.y, position.height)
when Orientation::EAST
return Position.new(position.x + 1, position.y, position.height)
when Orientation::NORTH
return Position.new(position.x, position.y + 1, position.height)
when Orientation::SOUTH
return Position.new(position.x, position.y - 1, position.height)
end
raise 'Invalid orientation for door!'
end
# Translates the orientation of a door to a toggled position.
def self.translate_door_orientation(door)
object_id = door.id
orientation = door.orientation
if RIGHT_SIDE_HINGE_DOOR_IDS.include?(object_id)
return ORIENTATIONS[:right_side_hinge][orientation]
elsif LEFT_SIDE_HINGE_DOOR_IDS.include?(object_id)
return ORIENTATIONS[:left_side_hinge][orientation]
end
raise 'Given object was not registered as a door!'
end
# Replaces a door object for a given player.
# TODO: This is temporary.
def self.replace_door(player, original, new)
player.send PositionMessage.new(player.last_known_sector, original.position)
player.send RemoveObjectMessage.new(original)
player.send PositionMessage.new(player.last_known_sector, new.position)
player.send SendObjectMessage.new(new)
end
# Toggles the given door.
def self.toggle(door, player)
# First, we remove the door we're toggling (or un-toggling) from the game world.
position = door.position
sector = $world.sector_repository.from_position(position)
sector.remove_entity door
# Have we toggled this door already?
if TOGGLED_DOOR_REPOSITORY.include?(door)
# If we have, we get our original door. This also deletes the entry from our repository.
original_door = TOGGLED_DOOR_REPOSITORY.delete(door)
# Now we add our new door to the game world.
original_sector = $world.sector_repository.from_position(original_door.position)
original_sector.add_entity original_door
# TODO: This and the 'player' parameter are temporary. We still need to synchronize objects for local players.
replace_door player, door, original_door
else
# If not, we get the translated orientation and position for this door, and create a new game object.
toggled_position = translate_door_position(door)
toggled_orientation = translate_door_orientation(door)
toggled_door = GameObject.new(door.id, toggled_position, door.type, toggled_orientation)
# Now we add our new door to the game world.
toggled_sector = $world.sector_repository.from_position(toggled_position)
toggled_sector.add_entity toggled_door
# Insert our toggled door in the repository.
TOGGLED_DOOR_REPOSITORY[toggled_door] = door
# TODO: This and the 'player' parameter are temporary. We still need to synchronize objects for local players.
replace_door player, door, toggled_door
end
end
# Gets the door object at the given position, if it exists.
def self.get_door_object(position, object_id)
game_objects = $world.sector_repository.from_position(position).get_entities(position, EntityType::GAME_OBJECT)
game_objects.each { |game_object| return game_object if game_object.get_id == object_id }
return nil
end
# Checks if the given game object id is a door.
def self.is_door?(object_id)
RIGHT_SIDE_HINGE_DOOR_IDS.include?(object_id) || LEFT_SIDE_HINGE_DOOR_IDS.include?(object_id)
end
end
@@ -0,0 +1,76 @@
package org.apollo.game.message.impl;
import org.apollo.game.message.Message;
import org.apollo.game.model.entity.GameObject;
/**
* A {@link Message} sent to the client to remove an object from a tile.
*
* @author Major
*/
public final class RemoveObjectMessage extends Message {
/**
* The orientation of the object.
*/
private final int orientation;
/**
* The position of the object.
*/
private final int positionOffset;
/**
* The type of the object.
*/
private final int type;
/**
* Creates the RemoveObjectMessage.
*
* @param object The {@link GameObject} to send.
*/
public RemoveObjectMessage(GameObject object) {
this(object, 0);
}
/**
* Creates the RemoveObjectMessage.
*
* @param object The {@link GameObject} to send.
* @param positionOffset The offset of the object's position from the sector's central position.
*/
public RemoveObjectMessage(GameObject object, int positionOffset) {
this.positionOffset = positionOffset;
this.type = object.getType();
this.orientation = object.getOrientation();
}
/**
* Gets the orientation of the object.
*
* @return The orientation.
*/
public int getOrientation() {
return orientation;
}
/**
* Gets the position offset of the object.
*
* @return The position offset.
*/
public int getPositionOffset() {
return positionOffset;
}
/**
* Gets the orientation of the object.
*
* @return The type.
*/
public int getType() {
return type;
}
}
@@ -31,15 +31,25 @@ public final class SendObjectMessage extends Message {
private final int type;
/**
* Creates the send object message.
* Creates the SendObjectMessage.
*
* @param object The {@link GameObject} to send.
*/
public SendObjectMessage(GameObject object) {
this(object, 0);
}
/**
* Creates the SendObjectMessage.
*
* @param object The {@link GameObject} to send.
* @param positionOffset The offset of the object's position from the sector's central position.
*/
public SendObjectMessage(GameObject object, int positionOffset) {
this.id = object.getId();
this.positionOffset = 0;
this.positionOffset = positionOffset;
this.type = object.getType();
this.orientation = object.getRotation();
this.orientation = object.getOrientation();
}
/**
@@ -28,7 +28,7 @@ public final class GameObject extends Entity {
*/
public GameObject(int id, Position position, int type, int orientation) {
super(position);
this.packed = id << 8 | type << 2 | orientation;
this.packed = id << 8 | (type & 0x3F) << 2 | orientation & 0x3;
}
@Override
@@ -69,7 +69,7 @@ public final class GameObject extends Entity {
*
* @return The orientation.
*/
public int getRotation() {
public int getOrientation() {
return packed & 0x3;
}
@@ -89,7 +89,8 @@ public final class GameObject extends Entity {
@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("id", getId()).add("type", getType()).add("rotation", getRotation()).toString();
return MoreObjects.toStringHelper(this).add("id", getId()).add("type", getType()).add("orientation", getOrientation())
.toString();
}
}
@@ -24,6 +24,7 @@ import org.apollo.game.message.impl.OpenSidebarMessage;
import org.apollo.game.message.impl.PlayerSynchronizationMessage;
import org.apollo.game.message.impl.PositionMessage;
import org.apollo.game.message.impl.PrivacyOptionMessage;
import org.apollo.game.message.impl.RemoveObjectMessage;
import org.apollo.game.message.impl.RemoveTileItemMessage;
import org.apollo.game.message.impl.SectorChangeMessage;
import org.apollo.game.message.impl.SendFriendMessage;
@@ -206,6 +207,7 @@ public final class Release317 extends Release {
register(UpdateTileItemMessage.class, new UpdateTileItemMessageEncoder());
register(RemoveTileItemMessage.class, new RemoveTileItemMessageEncoder());
register(SendObjectMessage.class, new SendObjectMessageEncoder());
register(RemoveObjectMessage.class, new RemoveObjectMessageEncoder());
register(ForwardPrivateChatMessage.class, new ForwardPrivateChatMessageEncoder());
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
@@ -0,0 +1,25 @@
package org.apollo.net.release.r317;
import org.apollo.game.message.impl.RemoveObjectMessage;
import org.apollo.net.codec.game.DataTransformation;
import org.apollo.net.codec.game.DataType;
import org.apollo.net.codec.game.GamePacket;
import org.apollo.net.codec.game.GamePacketBuilder;
import org.apollo.net.release.MessageEncoder;
/**
* A {@link MessageEncoder} for the {@link RemoveObjectMessage}.
*
* @author Major
*/
public final class RemoveObjectMessageEncoder extends MessageEncoder<RemoveObjectMessage> {
@Override
public GamePacket encode(RemoveObjectMessage message) {
GamePacketBuilder builder = new GamePacketBuilder(101);
builder.put(DataType.BYTE, DataTransformation.NEGATE, message.getType() << 2 | message.getOrientation());
builder.put(DataType.BYTE, message.getPositionOffset());
return builder.toGamePacket();
}
}
@@ -20,7 +20,7 @@ public final class SendObjectMessageEncoder extends MessageEncoder<SendObjectMes
GamePacketBuilder builder = new GamePacketBuilder(151);
builder.put(DataType.BYTE, DataTransformation.ADD, message.getPositionOffset());
builder.put(DataType.SHORT, DataOrder.LITTLE, message.getId());
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, message.getType() << 2 + message.getOrientation());
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, message.getType() << 2 | message.getOrientation());
return builder.toGamePacket();
}
@@ -24,6 +24,7 @@ import org.apollo.game.message.impl.OpenSidebarMessage;
import org.apollo.game.message.impl.PlayerSynchronizationMessage;
import org.apollo.game.message.impl.PositionMessage;
import org.apollo.game.message.impl.PrivacyOptionMessage;
import org.apollo.game.message.impl.RemoveObjectMessage;
import org.apollo.game.message.impl.RemoveTileItemMessage;
import org.apollo.game.message.impl.SectorChangeMessage;
import org.apollo.game.message.impl.SendFriendMessage;
@@ -202,6 +203,7 @@ public final class Release377 extends Release {
register(UpdateTileItemMessage.class, new UpdateTileItemMessageEncoder());
register(RemoveTileItemMessage.class, new RemoveTileItemMessageEncoder());
register(SendObjectMessage.class, new SendObjectMessageEncoder());
register(RemoveObjectMessage.class, new RemoveObjectMessageEncoder());
register(ForwardPrivateChatMessage.class, new ForwardPrivateChatMessageEncoder());
register(FriendServerStatusMessage.class, new FriendServerStatusMessageEncoder());
@@ -0,0 +1,25 @@
package org.apollo.net.release.r377;
import org.apollo.game.message.impl.RemoveObjectMessage;
import org.apollo.net.codec.game.DataTransformation;
import org.apollo.net.codec.game.DataType;
import org.apollo.net.codec.game.GamePacket;
import org.apollo.net.codec.game.GamePacketBuilder;
import org.apollo.net.release.MessageEncoder;
/**
* A {@link MessageEncoder} for the {@link RemoveObjectMessage}.
*
* @author Major
*/
public final class RemoveObjectMessageEncoder extends MessageEncoder<RemoveObjectMessage> {
@Override
public GamePacket encode(RemoveObjectMessage message) {
GamePacketBuilder builder = new GamePacketBuilder(88);
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, message.getPositionOffset());
builder.put(DataType.BYTE, DataTransformation.SUBTRACT, message.getType() << 2 | message.getOrientation());
return builder.toGamePacket();
}
}
@@ -18,7 +18,7 @@ public final class SendObjectMessageEncoder extends MessageEncoder<SendObjectMes
@Override
public GamePacket encode(SendObjectMessage message) {
GamePacketBuilder builder = new GamePacketBuilder(152);
builder.put(DataType.BYTE, DataTransformation.NEGATE, message.getType() << 2 + message.getOrientation());
builder.put(DataType.BYTE, DataTransformation.NEGATE, message.getType() << 2 | message.getOrientation());
builder.put(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD, message.getId());
builder.put(DataType.BYTE, DataTransformation.ADD, message.getPositionOffset());
return builder.toGamePacket();
@@ -46,4 +46,4 @@ public final class WalkMessageDecoder extends MessageDecoder<WalkMessage> {
return new WalkMessage(positions, run);
}
}
}