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) |