mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Build a framework for a maintainable combat plugin
* Uses a hierarchy of WeaponClasses -> Weapons for performing attacks, with WeaponClass having a set of styles and associated Attacks for those styles. Weapons and their classes are built with an easy to use and clean DSL. * Adds a BonusContainer mixin, so that Equipment, Weapons, and WeaponClasses can all have their own set of bonuses which apply to the player. * Allows attacks to be queued to the Mobs CombatState instance from external code, allowing e.g., NPCs or auto-cast to queue attacks to be executed.
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
java_import 'org.apollo.cache.def.ItemDefinition'
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Graphic'
|
||||
|
||||
class BaseAttack
|
||||
attr_reader :requirements, :range
|
||||
|
||||
def initialize(animation, graphic = nil, range = 1, requirements = [])
|
||||
@animation = animation
|
||||
@graphic = graphic
|
||||
@range = range
|
||||
@requirements = requirements
|
||||
end
|
||||
|
||||
def do(source, target)
|
||||
source.play_animation(Animation.new(@animation))
|
||||
|
||||
unless @graphic.nil?
|
||||
if @graphic.is_a?(Hash)
|
||||
source.play_graphic(Graphic.new(@graphic[:id], @graphic[:delay] || 0, @graphic[:height] | 0))
|
||||
else
|
||||
source.play_graphic(Graphic.new(@graphic))
|
||||
end
|
||||
end
|
||||
|
||||
apply(source, target)
|
||||
end
|
||||
|
||||
def apply(source, target)
|
||||
raise "BaseAttack#apply unimplemented"
|
||||
end
|
||||
|
||||
def damage!(source, target, amount, delay = 0)
|
||||
schedule delay do |task|
|
||||
task.stop && return if source.dead or target.dead
|
||||
|
||||
target_combat_state = get_combat_state target
|
||||
target_hitpoints = target.skill_set.get_skill(Skill::HITPOINTS).get_current_level
|
||||
amount = target_hitpoints if target_hitpoints < amount
|
||||
|
||||
type = amount > 0 ? 1 : 0
|
||||
target.play_animation(Animation.new(424)) unless target_combat_state.state == :attacking
|
||||
target.damage(amount, type, false)
|
||||
|
||||
task.stop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ProcAttack < BaseAttack
|
||||
def initialize(block, animation:, graphic:, range: 1, requirements: [])
|
||||
super(animation, graphic, range, requirements)
|
||||
|
||||
@block = block
|
||||
end
|
||||
|
||||
def apply(source, target)
|
||||
self.instance_exec(source, target, &@block)
|
||||
end
|
||||
end
|
||||
|
||||
class RangedAttack < BaseAttack
|
||||
def initialize(animation:, graphic:, requirements: [])
|
||||
|
||||
end
|
||||
|
||||
def calculate_delay(source, target)
|
||||
|
||||
end
|
||||
|
||||
def apply(source, target)
|
||||
|
||||
end
|
||||
|
||||
def projectile!(source, target, projectile_id)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
class Attack < BaseAttack
|
||||
def initialize(animation:, graphic: nil, range: 1, requirements: [])
|
||||
super(animation, graphic, range, requirements)
|
||||
end
|
||||
|
||||
def apply(source, target)
|
||||
damage! source, target, CombatUtil::calculate_hit(source, target)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user