mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-05 16:49:04 +00:00
Add door plugin. Note that this will need to be revisited when local object synchronization is complete.
This commit is contained in:
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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>
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user