2025-10-18 04:37:34 +08:00
|
|
|
|
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
|
2025-10-18 17:30:58 +08:00
|
|
|
|
|
2025-10-19 03:33:01 +08:00
|
|
|
|
self.overlap_delegate_handle = nil
|
2025-10-18 17:30:58 +08:00
|
|
|
|
self.tag_add_or_remove_delegate = nil
|
2025-10-18 04:37:34 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function FoxUltimate:K2_ActivateAbilityFromEvent(EventData)
|
|
|
|
|
|
print("FoxUltimate:K2_ActivateAbilityFromEvent", self.ultimate_phase)
|
|
|
|
|
|
|
2025-10-18 17:30:58 +08:00
|
|
|
|
if not self:K2_CommitAbilityCost(false) then
|
|
|
|
|
|
return self:K2_EndAbility()
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2025-10-18 04:37:34 +08:00
|
|
|
|
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")
|
2025-10-19 03:33:01 +08:00
|
|
|
|
self.owner = owner
|
|
|
|
|
|
|
2025-10-18 04:37:34 +08:00
|
|
|
|
|
|
|
|
|
|
local asc = self.asc
|
|
|
|
|
|
|
2025-10-18 17:30:58 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
2025-10-18 04:37:34 +08:00
|
|
|
|
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)
|
2025-10-18 17:30:58 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
2025-10-18 04:37:34 +08:00
|
|
|
|
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)
|
2025-10-19 03:33:01 +08:00
|
|
|
|
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
|
2025-10-18 04:37:34 +08:00
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Class(nil, nil, FoxUltimate)
|