mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 08:39:11 +00:00
Move next_attack logic to CombatState
* Moves the decision of what attack is used next to CombatState and defers selecting the attack until the player is actually ready to hit their target for damage. * Adds a distance check so combat is only initiated within the correct range. If the player isn't close enough to their target, they will run towards it and check every tick if they're close enough to make an attack.
This commit is contained in:
@@ -50,7 +50,19 @@ class CombatAction < Action
|
||||
end
|
||||
|
||||
def update_idle
|
||||
if @combat_state.queued_attacks.empty? and @combat_state.supports_weapon
|
||||
next_attack = @combat_state.next_attack true
|
||||
current_distance = mob.position.get_distance @combat_state.target.position
|
||||
|
||||
if current_distance > next_attack.range
|
||||
@combat_state.state = :chasing
|
||||
|
||||
mob.follow @combat_state.target, next_attack.range
|
||||
set_delay 0
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if @combat_state.supports_weapon
|
||||
weapon = EquipmentUtil.equipped_weapon mob
|
||||
weapon_class = weapon.weapon_class
|
||||
combat_style = weapon_class.style_at mob.combat_style
|
||||
@@ -62,16 +74,7 @@ class CombatAction < Action
|
||||
mob.attacking = true
|
||||
end
|
||||
|
||||
if mob.using_special and weapon.special_attack?
|
||||
@combat_state.next_attack = weapon.special_attack
|
||||
else
|
||||
@combat_state.next_attack = weapon_class.attack(combat_style)
|
||||
end
|
||||
|
||||
@combat_state.state = :attacking
|
||||
elsif @combat_state.queued_attacks.size > 0
|
||||
@combat_state.next_attack = @combat_state.queued_attacks.pop
|
||||
@combat_state.state = :attacking
|
||||
else
|
||||
stop
|
||||
@combat_state.reset
|
||||
@@ -79,20 +82,35 @@ class CombatAction < Action
|
||||
end
|
||||
|
||||
def update_attacking
|
||||
raise RuntimeError.new('no attack when in :attacking state') if @combat_state.next_attack.nil?
|
||||
|
||||
begin
|
||||
@combat_state.next_attack.do(mob, @combat_state.target)
|
||||
next_attack = @combat_state.next_attack
|
||||
next_attack.requirements.each do |requirement|
|
||||
requirement.validate! mob
|
||||
end
|
||||
|
||||
@combat_state.state = :idle
|
||||
set_delay 0
|
||||
next_attack.requirements.each do |requirement|
|
||||
requirement.apply mob
|
||||
end
|
||||
|
||||
next_attack.do(mob, @combat_state.target)
|
||||
rescue AttackRequirementException => e
|
||||
mob.send_message e.message
|
||||
ensure
|
||||
@combat_state.state = :idle
|
||||
set_delay 0
|
||||
end
|
||||
end
|
||||
|
||||
def update_chasing
|
||||
next_attack = @combat_state.next_attack true
|
||||
current_distance = mob.position.get_distance @combat_state.target.position
|
||||
|
||||
if current_distance <= next_attack.range
|
||||
@combat_state.state = :attacking
|
||||
|
||||
mob.following = -1
|
||||
set_delay 0
|
||||
end
|
||||
end
|
||||
|
||||
def stop
|
||||
|
||||
@@ -11,7 +11,7 @@ end
|
||||
private
|
||||
|
||||
class CombatState
|
||||
attr_accessor :state, :next_attack
|
||||
attr_accessor :state
|
||||
attr_reader :queued_attacks, :supports_weapon
|
||||
|
||||
def initialize(mob, supports_weapon = true)
|
||||
@@ -41,6 +41,23 @@ class CombatState
|
||||
def queue_attack(attack)
|
||||
@queued_attacks.push(attack)
|
||||
end
|
||||
|
||||
def next_attack(peek = false)
|
||||
if @queued_attacks.size > 0
|
||||
peek ? @queued_attacks.first : @queued_attacks.pop
|
||||
else
|
||||
weapon = EquipmentUtil.equipped_weapon @mob
|
||||
|
||||
if @mob.using_special and weapon.special_attack?
|
||||
weapon.special_attack
|
||||
else
|
||||
weapon_class = weapon.weapon_class
|
||||
combat_style = weapon_class.style_at @mob.combat_style
|
||||
|
||||
weapon_class.attack combat_style
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MOB_COMBAT_STATE_CACHE = {
|
||||
|
||||
Reference in New Issue
Block a user