Files
BusyRabbit/Content/Lua/Gas/Ability/Role/Fox/FoxUltimate.lua
2025-10-19 03:33:01 +08:00

196 lines
6.5 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local GameplayStatics = import("GameplayStatics")
local AbilitySystemBlueprintLibrary = import("AbilitySystemBlueprintLibrary")
local BusyGameplayLibrary = import("BusyGameplayLibrary")
--- @class FoxUltimate
--- @field RecastWindow number
local FoxUltimate = {}
function FoxUltimate:ctor()
self.ultimate_phase = 1 -- 大招阶段
self.active_recast_handle = nil
self.active_accelerate_handle = nil
self.overlap_delegate_handle = nil
self.tag_add_or_remove_delegate = nil
end
function FoxUltimate:K2_ActivateAbilityFromEvent(EventData)
print("FoxUltimate:K2_ActivateAbilityFromEvent", self.ultimate_phase)
if not self:K2_CommitAbilityCost(false) then
return self:K2_EndAbility()
end
local owner = self:GetOwningActorFromActorInfo()
self.movement = owner.MovementComponent
self.animation = owner.SpineAnimationComponent
self.asc = AbilitySystemBlueprintLibrary.GetAbilitySystemComponent(owner)
self.recast_tag = BusyGameplayLibrary.RequestGameplayTag("Ability.Flags.Recast")
self.owner = owner
local asc = self.asc
if self.tag_add_or_remove_delegate == nil then
self.tag_add_or_remove_delegate = slua.createDelegate(function(tag, is_add)
if is_add == 0 and not self.bIsActive then
self.ultimate_phase = 1
self:K2_CommitAbilityCooldown(false, false)
end
end)
owner:BindGameplayTagAddOrRemove(self.recast_tag, self.tag_add_or_remove_delegate)
end
if self.ultimate_phase == 1 or asc:HasMatchingGameplayTag(self.recast_tag) then
self:TriggerUltimate(asc)
else
self:K2_EndAbility()
end
end
function FoxUltimate:TriggerUltimate(asc)
if self.ultimate_phase == 1 then
-- 第一次释放大招添加一个可以再次释放的Tag
local _, recast_effect = self:GetAbilityEffectSpecHandle("Recast", asc, 1, nil)
self.active_recast_handle = asc:BP_ApplyGameplayEffectSpecToSelf(recast_effect)
elseif self.ultimate_phase == 2 then
-- 第二次激活移除可重复释放的tag
self.asc:RemoveActiveGameplayEffect(self.active_recast_handle, -1)
elseif self.ultimate_phase == 3 then
self.asc:RemoveActiveGameplayEffect(self.active_recast_handle, -1)
end
-- 播放动画,并监听动画完成的事件
self:PlayAnimation()
end
function FoxUltimate:GetAnimationName(direction)
local animation_name_prefix
if direction.X >= 0 then
animation_name_prefix = "Ultimate/Right/"
else
animation_name_prefix = "Ultimate/Left/"
end
if self.ultimate_phase == 1 then
return animation_name_prefix .. "UltimateStage1"
elseif self.ultimate_phase == 2 then
return animation_name_prefix .. "UltimateStage2"
elseif self.ultimate_phase == 3 then
return animation_name_prefix .. "UltimateStage3"
end
return nil
end
function FoxUltimate:K2_OnEndAbility(bWasCancelled)
print("FoxUltimate:K2_OnEndAbility")
end
function FoxUltimate:GetSprintSpeedFactor()
if self.ultimate_phase == 1 then
return 2.5
elseif self.ultimate_phase == 2 then
return 2.8
elseif self.ultimate_phase == 3 then
return 3.0
end
end
function FoxUltimate:PlayAnimation()
local animation = self.animation
local PC = GameplayStatics.GetPlayerController(self, 0)
local result, ability_direction = PC:GetCursorDirection(nil) -- 获取技能的朝向
if not result then
print("FoxUltimate:TriggerPrimaryPhase can't find direction")
return
end
local anim_name = self:GetAnimationName(ability_direction) -- 获取技能动画名称
if not anim_name then
print("FoxUltimate:TriggerPrimaryPhase can't get animation", self.ultimate_phase)
return
end
local anim_entry = animation:SetAnimation(0, anim_name, false)
anim_entry.AnimationComplete:Add(function(entry) self:OnAnimationComplete(entry) end)
anim_entry.AnimationEvent:Add(function(entry, event) self:OnAnimationEvent(entry, event) end)
local anim_total_time = anim_entry:GetAnimationEnd() -- 获取技能动画时长
-- 附加加速buff
self:MakeAccelerate(self:GetSprintSpeedFactor(), anim_total_time)
self.movement:ActivateSprint(ability_direction, anim_total_time)
end
function FoxUltimate:MakeAccelerate(speed_factor, total_time)
local _, accelerate_effect = self:GetAbilityEffectSpecHandle("Accelerate", self.asc, 1, nil)
AbilitySystemBlueprintLibrary.AssignTagSetByCallerMagnitude(
accelerate_effect,
BusyGameplayLibrary.RequestGameplayTag("Effect.Factor"),
speed_factor
)
AbilitySystemBlueprintLibrary.AssignTagSetByCallerMagnitude(
accelerate_effect,
BusyGameplayLibrary.RequestGameplayTag("Effect.Duration"),
total_time
)
return self.asc:BP_ApplyGameplayEffectSpecToSelf(accelerate_effect)
end
function FoxUltimate:OnAnimationComplete(entry)
local new_phase = self.ultimate_phase + 1
if new_phase > 3 then
self.ultimate_phase = 1
else
self.ultimate_phase = new_phase
end
print("FoxUltimate:OnAnimationComplete", self.ultimate_phase)
if not self.asc:HasMatchingGameplayTag(self.recast_tag) then
self.ultimate_phase = 1
self:K2_CommitAbilityCooldown(false, false)
end
entry.AnimationComplete:Clear()
entry.AnimationEvent:Clear()
self:K2_EndAbility()
end
function FoxUltimate:OnAnimationEvent(entry, event)
if event.Name == "OnSpeedChange" then
self.active_accelerate_handle = self:MakeAccelerate(8.0, 0.5)
elseif event.Name == "OnSpeedReset" then
self.asc:RemoveActiveGameplayEffect(self.active_accelerate_handle, -1)
elseif event.Name == "OnDamageBegin" then
local collision = self.owner["TailCollision"]
collision:SetCollisionEnabled(1)
self.overlap_delegate_handle = collision.OnComponentBeginOverlap:Add(function()
if not self.asc:HasMatchingGameplayTag(self.recast_tag) then
local _, recast_effect = self:GetAbilityEffectSpecHandle("Recast", self.asc, 1, nil)
self.active_recast_handle = self.asc:BP_ApplyGameplayEffectSpecToSelf(recast_effect)
end
end)
elseif event.Name == "OnDamageEnd" then
self.owner["TailCollision"]:SetCollisionEnabled(0)
if self.overlap_delegate_handle ~= nil then
self.owner["TailCollision"].OnComponentBeginOverlap:Remove(self.overlap_delegate_handle)
self.overlap_delegate_handle = nil
end
end
end
return Class(nil, nil, FoxUltimate)