mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Listen for the PositionUpdateEvent so area listeners now function.
This commit is contained in:
@@ -3,8 +3,20 @@ require 'java'
|
||||
java_import 'org.apollo.game.message.impl.DisplayCrossbonesMessage'
|
||||
java_import 'org.apollo.game.model.entity.Player'
|
||||
|
||||
|
||||
|
||||
# Registers an area action.
|
||||
def area_action(name, &block)
|
||||
AREA_ACTIONS[name] = action = AreaAction.new
|
||||
action.instance_eval(&block)
|
||||
end
|
||||
|
||||
|
||||
AREA_ACTIONS = {}
|
||||
|
||||
|
||||
private
|
||||
|
||||
# An action that is called when a player enters or exits an area.
|
||||
class AreaAction
|
||||
|
||||
@@ -38,31 +50,4 @@ class AreaAction
|
||||
@on_exit.call(player) unless @on_exit.nil?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Registers an area action.
|
||||
def area_action(name, &block)
|
||||
AREA_ACTIONS[name] = action = AreaAction.new
|
||||
action.instance_eval(&block)
|
||||
end
|
||||
|
||||
# Defines the pvp area action.
|
||||
area_action :pvp do
|
||||
on_entry { |player| player.in_pvp = true }
|
||||
on_exit { |player| player.in_pvp = false }
|
||||
end
|
||||
|
||||
# Defines the wilderness area action.
|
||||
area_action :wilderness do
|
||||
|
||||
on_entry do |player|
|
||||
player.send(DisplayCrossbonesMessage.new(true))
|
||||
player.in_wilderness = true
|
||||
end
|
||||
|
||||
on_exit do |player|
|
||||
player.send(DisplayCrossbonesMessage.new(false))
|
||||
player.in_wilderness = false
|
||||
end
|
||||
|
||||
end
|
||||
+70
-16
@@ -1,11 +1,26 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Position'
|
||||
java_import 'org.apollo.game.model.entity.Entity$EntityType'
|
||||
java_import 'org.apollo.game.model.entity.Player'
|
||||
|
||||
# Todo make 0 the default height
|
||||
|
||||
|
||||
# Creates a new area and registers it with the supplied coordinates.
|
||||
def area(hash)
|
||||
raise 'Hash must contain a name, coordinates, and actions pair.' unless hash.has_keys?(:name, :coordinates, :actions)
|
||||
name = hash[:name]; coordinates = hash[:coordinates]; actions = hash[:actions]
|
||||
|
||||
actions = [ actions ] if actions.is_a?(Symbol)
|
||||
actions.map! { |action| AREA_ACTIONS[action]}
|
||||
@areas << Area.new(name, coordinates, actions)
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
# A map of coordinates (as an array) to areas.
|
||||
AREAS = []
|
||||
@areas = []
|
||||
|
||||
# An area of the game world.
|
||||
class Area
|
||||
@@ -16,31 +31,70 @@ class Area
|
||||
@actions = actions
|
||||
end
|
||||
|
||||
# Called when the player has entered the area.
|
||||
def entered(player)
|
||||
actions.each { |action| action.entered(player) }
|
||||
def min_x() # TODO better data structure and methods than this
|
||||
@coordinates[0]
|
||||
end
|
||||
|
||||
# Called whilst the player is inside the area.
|
||||
def min_y()
|
||||
@coordinates[1]
|
||||
end
|
||||
|
||||
def max_x()
|
||||
@coordinates[2]
|
||||
end
|
||||
|
||||
def max_y()
|
||||
@coordinates[3]
|
||||
end
|
||||
|
||||
def height()
|
||||
@coordinates[4]
|
||||
end
|
||||
|
||||
# Called when the player has entered the area.
|
||||
def entered(player)
|
||||
@actions.each { |action| action.entered(player) }
|
||||
end
|
||||
|
||||
# Called when the player has moved, but is still inside the area (and was in the area before).
|
||||
def inside(player)
|
||||
acttions.each { |action| action.inside(player) }
|
||||
@actions.each { |action| action.inside(player) }
|
||||
end
|
||||
|
||||
# Called when the player has exited the area.
|
||||
def exited(player)
|
||||
actions.each { |action| action.exited(player) }
|
||||
@actions.each { |action| action.exited(player) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Creates a new area and registers it with the supplied coordinates.
|
||||
def area(hash)
|
||||
raise 'Hash must contain a name, coordinates, and actions pair.' unless hash.has_keys?(:name, :coordinates, :actions)
|
||||
name = hash[:name]; coordinates = hash[:coordinates]; actions = hash[:actions]
|
||||
# Listen for the MobPositionUpdateEvent and update the area listeners if appropriate.
|
||||
on :mob_position_update do |event|
|
||||
mob = event.mob
|
||||
next unless mob.entity_type == EntityType::PLAYER
|
||||
|
||||
AREAS << Area.new(name, coordinates, actions.is_a?(Symbol) ? [actions] : actions)
|
||||
old = mob.position
|
||||
@areas.each do |area|
|
||||
was_inside = old.inside(area)
|
||||
next_inside = event.next.inside(area)
|
||||
|
||||
if was_inside
|
||||
if next_inside then area.inside(mob) else area.exited(mob) end
|
||||
else
|
||||
area.entered(mob) if next_inside
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Coordinates refer to the bottom-left position (min_x, min_y) and the top-right position (max_x, max_y), followed by the height (optional).
|
||||
area :name => :wilderness, :coordinates => [ 2944, 3520, 3392, 6400, 0 ], :actions => [ :pvp, :multicombat, :wilderness ]
|
||||
area :name => :duel_arena, :coordinates => [ 3327, 3200, 3392, 3286 ], :actions => :pvp
|
||||
# The existing Position class.
|
||||
class Position
|
||||
|
||||
# Returns whether or not this Position is inside the specified Area.
|
||||
def inside(area)
|
||||
return false if (x < area.min_x() || x > area.max_x() || y < area.min_y() || y > area.max_y())
|
||||
z = area.height()
|
||||
|
||||
return true if (z.nil? || z == height)
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user