Redo attributes system, add support for saving and loading, move settings classes around.

This commit is contained in:
Major-
2014-07-19 04:15:06 +01:00
parent 9d465e4885
commit 13ca51809c
42 changed files with 762 additions and 103 deletions
+68
View File
@@ -0,0 +1,68 @@
require 'java'
java_import 'org.apollo.game.event.impl.DisplayCrossbonesEvent'
java_import 'org.apollo.game.model.entity.Player'
AREA_ACTIONS = {}
# An action that is called when a player enters or exits an area.
class AreaAction
# Sets the block to be called when the player enters the area.
def on_entry(&block)
@on_enter = block
end
# Sets the block to be called while the player is in the area.
def while_in(&block)
@while_in = block
end
# Sets the block to be called when the player exits the area.
def on_exit(&block)
@on_exit = block
end
# Called when the player has entered an area this action is registered to.
def entered(player)
@on_enter.call(player) unless @on_enter == nil
end
# Called while the player is in area this action is registered to.
def inside(player)
@while_in.call(player) unless @while_in == nil
end
# Called when the player has exited an area this action is registered to.
def exited(player)
@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 a pvp area action.
area_action :pvp do
on_entry { |player| player.set_attribute("pvp", :boolean, true ) }
on_exit { |player| player.set_attribute("pvp", :boolean, false) }
end
# Defines a multi-combat area action.
area_action :wilderness do
on_entry do |player|
player.send(DisplayCrossbonesEvent.new(true))
player.set_attribute("wilderness", :boolean, true)
end
on_exit do |player|
player.send(DisplayCrossbonesEvent.new(false))
player.set_attribute("wilderness", :boolean, false)
end
end
+44
View File
@@ -0,0 +1,44 @@
require 'java'
java_import 'org.apollo.game.model.entity.Player'
# A map of coordinates (as an array) to areas.
AREAS = []
# An area of the game world.
class Area
def initialize(name, coordinates, actions)
@name = name
@coordinates = coordinates
@actions = actions
end
# Called when the player has entered the area.
def entered(player)
actions.each { |action| action.entered(player) }
end
# Called whilst the player is inside the area.
def inside(player)
acttions.each { |action| action.inside(player) }
end
# Called when the player has exited the area.
def 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_key?(:name) && hash.has_key?(:coordinates) && hash.has_key?(:actions)
name = hash[:name]; coordinates = hash[:coordinates]; actions = hash[:actions]
AREAS << Area.new(name, coordinates, actions.is_a?(Symbol) ? [actions] : actions)
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.
area :name => :wilderness, :coordinates => [ 2944, 3520, 3391, 3967, 0 ], :actions => [ :pvp, :multicombat, :wilderness ]
area :name => :duel_arena, :coordinates => [ 3327, 3200, 3392, 3286, 0 ], :actions => :pvp
+1 -1
View File
@@ -20,7 +20,7 @@ java_import 'org.apollo.game.login.LoginListener'
java_import 'org.apollo.game.login.LogoutListener'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.entity.Player'
java_import 'org.apollo.game.model.settings.PrivilegeLevel'
java_import 'org.apollo.game.model.setting.PrivilegeLevel'
java_import 'org.apollo.game.scheduling.ScheduledTask'
# Alias the privilege levels.
+1 -1
View File
@@ -1,6 +1,6 @@
require 'java'
java_import 'org.apollo.game.model.settings.PrivacyState'
java_import 'org.apollo.game.model.setting.PrivacyState'
java_import 'org.apollo.game.event.impl.SendFriendEvent'
on :event, :privacy_option do |ctx, player, event|
-1
View File
@@ -2,7 +2,6 @@ require 'java'
java_import 'org.apollo.game.event.impl.ForwardPrivateMessageEvent'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.settings.PrivacyState'
on :command, :filter do |player, command|
player.send_message('Your message filter is now ' + (player.toggle_message_filter ? 'enabled.' : 'disabled.'))
+16
View File
@@ -0,0 +1,16 @@
# Intercepts the first npc action event.
on :event, :npc_action do |ctx, player, event|
if (event.option == 1)
# TODO check if player is not in pvp area
end
end
def dialogue(name, &block)
end
dialogue :banker_introduction do
#
end
+55 -41
View File
@@ -1,64 +1,78 @@
require 'java'
java_import 'org.apollo.game.model.entity.Entity'
# Maps attribute names (i.e. symbols) to attribute definitions.
ATTRIBUTE_DEFINITIONS = {}
java_import 'org.apollo.game.model.entity.attr.Attribute'
java_import 'org.apollo.game.model.entity.attr.AttributeDefinition'
java_import 'org.apollo.game.model.entity.attr.AttributeMap'
java_import 'org.apollo.game.model.entity.attr.AttributeType'
java_import 'org.apollo.game.model.entity.attr.BooleanAttribute'
java_import 'org.apollo.game.model.entity.attr.NumericalAttribute'
java_import 'org.apollo.game.model.entity.attr.StringAttribute'
class Entity
# Overridies method_missing
# Overrides method_missing
def method_missing(symbol, *args)
name = symbol.to_s.strip
if name[-1] == "="
raise "Error - expected argument count of 1, received #{args.length}" unless args.length == 1
raise "Expected argument count of 1, received #{args.length}" unless args.length == 1
name = name[0...-1].strip # Drop the equals and preceeding whitespace
attributes[name] = args[0].is_a?(Symbol) ? args[0].to_s : args[0]
elsif ATTRIBUTE_DEFINITIONS[name] == nil
puts name
name = name[0...-1].strip # Drop the equals
set_attribute(name, to_attribute(args[0]))
elsif AttributeMap::get_definition(name) == nil
super(symbol, *args)
else
if attributes[name] == nil then return ATTRIBUTE_DEFINITIONS[name].default end
return ATTRIBUTE_DEFINITIONS[name].type == :symbol ? attributes[name].to_sym : attributes[name]
attribute = get_attribute(name); definition = AttributeMap::get_definition(name)
value = attribute == nil ? definition.default : attribute.value
return definition.type == AttributeType::SYMBOL ? value.to_sym : value
end
end
def to_s
return value.to_s
end
end
# An attribute belonging to an entity.
class AttributeDefinition
attr_reader :default, :type, :persistence
def initialize(default, persistence=:transient)
@default = default
@type = get_type
@persistence = persistence
end
def to_s
return "[AttributeDefinition - default=#{default}, type=#{type}, persistence=#{persistence}]."
end
private # Gets the type of an attribute from its default value.
def get_type
case @default
when Fixnum, Integer then type = :number
when String then type = :string
when Symbol then type = :symbol
when TrueClass, FalseClass then type = :boolean
else raise "Error - #{value} has an unrecognised attribute type of #{value.class}."
# Gets the appropriate attribute for the specified value.
private
def to_attribute(value)
case value
when String, Symbol then return StringAttribute.new(value.to_s, value.is_a?(Symbol))
when Integer, Float then return NumericalAttribute.new(value)
when TrueClass, FalseClass then return BooleanAttribute.new(value)
else raise "Undefined attribute type #{value.class}."
end
end
end
# Declares an attribute which can then be assigned.
# Declares an attribute and adds its definition.
def declare_attribute(name, default, persistence=:transient)
ATTRIBUTE_DEFINITIONS[name.to_s] = AttributeDefinition.new(default, persistence)
AttributeMap::add_definition(name.to_s, AttributeDefinition.new(default, get_persistence(persistence), get_type(default)))
end
# Gets the attribute type of the specified value.
private
def get_type(value)
case value
when String then return AttributeType::STRING
when Symbol then return AttributeType::SYMBOL
when Integer then return AttributeType::LONG
when Float then return AttributeType::DOUBLE
when TrueClass, FalseClass then return AttributeType::BOOLEAN
else raise "Undefined attribute type #{value.class}."
end
end
# Gets the Persistence type of the specified value.
def get_persistence(persistence)
raise "Undefined persistence type #{persistence}." unless persistence == :serialized || persistence == :transient
return persistence == :serialized ? AttributeDefinition::Persistence::SERIALIZED : AttributeDefinition::Persistence::TRANSIENT
end
declare_attribute :test, 42, :serialized
on :command, :test do |player, command|
player.send_message(player.test.to_s)
player.test = 6.5
player.send_message(player.test.to_s)
end
@@ -0,0 +1,44 @@
require 'java'
java_import 'org.apollo.game.model.Position'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.area.Sector'
java_import 'org.apollo.game.model.area.SectorCoordinates'
java_import 'org.apollo.game.model.area.SectorRepository'
java_import 'org.apollo.game.model.def.ItemDefinition'
# :transient :recurrent
def spawn_npc(hash)
raise 'A name (or id), x coordinate, and y coordinate must be specified to spawn an item' unless (hash.has_key?(:name) || hash.has_key?(:id)) && hash.has_key?(:x) && hash.has_key?(:y)
z = hash.delete(:z)
position = Position.new(hash.delete(:x), hash.delete(:y), z == nil ? 0 : z)
end
def get_item(hash)
id = hash.delete(:id)
if id == nil
name = hash.delete(:name).to_s.gsub('_', ' ')
if name.include?(' ')
id = name[name.rindex(' ') + 1, name.length - 1].to_i
end
id = locate_entity('item', name, 1).first if id == nil || id == 0
end
raise "The item called #{name} could not be identified." if id == nil
amount = hash.delete(:amount)
return Item.new(id, amount)
end
class GroundItem
def initialise(id, amount, x, y, z)
@item = Item.new(id, amount)
@position = Position.new(x, y, z)
end
end
+9
View File
@@ -0,0 +1,9 @@
spawn_npc :name => :gem_trader, :x => 3287, :y => 3210, :face => :south
spawn_npc :name => :al_karid_warrior_18, :x => 3288, :y => 3169
spawn_npc :name => :al_karid_warrior_18, :x => 3295, :y => 3170
spawn_npc :name => :al_karid_warrior_18, :x => 3297, :y => 3175
spawn_npc :name => :al_karid_warrior_18, :x => 3300, :y => 3171
spawn_npc :name => :al_karid_warrior_18, :x => 3301, :y => 3168
spawn_npc :name => :al_karid_warrior_18, :x => 3301, :y => 3164
spawn_npc :name => :al_karid_warrior_18, :x => 3295, :y => 3162
+2 -2
View File
@@ -3,8 +3,8 @@ require 'java'
java_import 'org.apollo.game.event.impl.FriendServerStatusEvent'
java_import 'org.apollo.game.event.impl.SendFriendEvent'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.settings.ServerStatus'
java_import 'org.apollo.game.model.settings.PrivacyState'
java_import 'org.apollo.game.model.setting.ServerStatus'
java_import 'org.apollo.game.model.setting.PrivacyState'
java_import 'org.apollo.game.model.entity.Player'
+1 -1
View File
@@ -2,7 +2,7 @@ require 'java'
java_import 'org.apollo.game.event.impl.ForwardPrivateMessageEvent'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.settings.PrivacyState'
java_import 'org.apollo.game.model.setting.PrivacyState'
on :event, :private_message do |ctx, player, event|
friend = World.world.get_player(event.username)
@@ -0,0 +1,54 @@
require 'java'
java_import 'org.apollo.game.action.Action'
java_import 'org.apollo.game.model.entity.Skill'
FIRE_OBJECT_ID = 2732
LOGS = {}
LIGHTERS = {}
class Log
attr_reader :id, :level, :experience
def initialize(id, level, experience)
@id = id
@level = level
@experience = experience
end
end
# An action where a player lights a log.
class LogLightingAction < Action
def initialize(player, log, animation)
super(1, true, player)
@log = log
@time = 1
end
def execute
if time == 0
player.play_animation(animation)
# TODO drop logs, spawn obj
else
time -= 1
end
end
end
# Appends a log to the hash.
def append_log(hash)
raise "Hash must contain an id, level, and experience value." unless hash.has_key?(:id) && hash.has_key?(:level) && hash.has_key?(:experience)
id = hash[:id]; level = hash[:level]; experience = hash[:experience]
LOGS[id] = Log.new(level, experience)
end
# Appends a lighter to the hash.
def append_lighter(id, animation_id)
LIGHTERS[id] = animation_id
end