196 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
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) |