local SimpleSkillTask = require("Script.SimpleSkill.Task.SimpleSkillTask") local SimpleSkillTask_Ray = LuaClass("SimpleSkillTask_Ray", SimpleSkillTask) SimpleSkillTask_Ray.AdditionDamageRateTable = {0.1, 0.2, 0.3, 0.4} --伤害加成百分比 SimpleSkillTask_Ray.CurDamageRate = 0.0 SimpleSkillTask_Ray.BindWeapon = nil function SimpleSkillTask_Ray:ctor(OwnerSkill) SimpleSkillTask_Ray.super.ctor(self, OwnerSkill) end function SimpleSkillTask_Ray:InitTaskFromData(TaskData, CasterPawn) SimpleSkillTask.InitTaskFromData(self, TaskData, CasterPawn) self.TaskName = "Ray" end function SimpleSkillTask_Ray:UpdateSkillLevel(NewSkillLevel) SimpleSkillTask.UpdateSkillLevel(self, NewSkillLevel) self.CurDamageRate = self.AdditionDamageRateTable[self.SkillLevel] end function SimpleSkillTask_Ray:ActivateTask() SimpleSkillTask.ActivateTask(self) local CasterPawnWeapon = self.CasterPawn:GetWeaponComponent() if CasterPawnWeapon ~= nil and UE.IsValid(CasterPawnWeapon) then self.BindWeapon = CasterPawnWeapon self.BindWeapon.OnFireDelegate:Add(self.OnCasterPawnFire, self) else self.CasterPawn.OnWeaponSpawnedDelegate:Add(self.OnWeaponSpawned, self) end end function SimpleSkillTask_Ray:DeactivateTask() self.CasterPawn.OnWeaponSpawnedDelegate:Remove(self.OnWeaponSpawned, self) if self.BindWeapon ~= nil and UE.IsValid(self.BindWeapon) then self.BindWeapon.OnFireDelegate:Remove(self.OnCasterPawnFire, self) self.BindWeapon = nil end end function SimpleSkillTask_Ray:OnWeaponSpawned(Pawn) if Pawn ~= self.CasterPawn then return end local CasterPawnWeapon = self.CasterPawn:GetWeaponComponent() if CasterPawnWeapon ~= nil and UE.IsValid(CasterPawnWeapon) then self.BindWeapon = CasterPawnWeapon self.BindWeapon.OnFireDelegate:Add(self.OnCasterPawnFire, self) end end function SimpleSkillTask_Ray:OnCasterPawnFire(Weapon) if self.BindWeapon ~= Weapon then return end local Length, Width, Height = 1000, 50, 200 local BoxExtent = {X = Length/2, Y = Width/2, Z = Height/2} local ObjectTypes = {} local ActorClassFilter = UE.LoadClass(BPClassPath.MonsterBase) local ActorsToIgnore = {} local RotList = self:GetTargetRotationList() for _, Rotation in pairs(RotList) do local Forward = KismetMathLibrary.Conv_RotatorToVector(Rotation) local BoxLoc = VectorHelper.Add(self.CasterPawn:K2_GetActorLocation(), VectorHelper.MulNumber(KismetMathLibrary.Normal(Forward), Length / 2)) local RetVal, OutMonsters = KismetSystemLibrary.BoxOverlapActors(self.CasterPawn, BoxLoc, Rotation, BoxExtent, ObjectTypes, ActorClassFilter, ActorsToIgnore) if RetVal then self:ApplyRayDamage(OutMonsters) end if GlobalConfigs.OpenDebug then UnrealNetwork.CallUnrealRPC_Multicast(self.CasterPawn , "DrawDebugBox" , VectorHelper.ToLuaTable(BoxLoc), BoxExtent, {1,0,0,1}, Rotation) end end self:EnableSkillEffect(self.CasterPawn, nil, EEffectSpawnLocationType.Middle) end function SimpleSkillTask_Ray:EnableSkillEffect(Pawn, ActorList, SpawnLocationType, BoneName) local Duration = 0 local InstanceId = GameDataManager.GetEffectInstanceId() local EffectId = 1000 + self.SkillLevel local OwnerSkillComp = self.CasterPawn.SkillSystemComponent if OwnerSkillComp then local AllRaySkillInst = {} for Slot, SimpleSkill in pairs(OwnerSkillComp.SlotToSkillList) do if SimpleSkill.SkillName == ESkillName.Ray then table.insert(AllRaySkillInst, SimpleSkill) end end local RaySkillInstNum = table.getCount(AllRaySkillInst) if not table.isEmpty(AllRaySkillInst) and RaySkillInstNum > 1 then local RaySkillIndex = 0 table.sort(AllRaySkillInst, function(a, b) return a.SkillLevel > b.SkillLevel end) for Index, RaySkillInst in pairs(AllRaySkillInst) do if RaySkillInst.SkillLevel == self.SkillLevel then RaySkillIndex = Index break end end if RaySkillIndex ~= 0 then local OffsetMulti = RaySkillInstNum == 3 and 2 or 1.5 local Offset = 35 local OriginLocation = self.CasterPawn:K2_GetActorLocation() local EffectRotation = VectorHelper.RotToLuaTable(self.CasterPawn:K2_GetActorRotation()) local EffectLocation = {X = OriginLocation.X, Y = OriginLocation.Y, Z = OriginLocation.Z + Offset * (RaySkillIndex - OffsetMulti)} UnrealNetwork.CallUnrealRPC_Multicast(self.CasterPawn, "Client_MulticastRPC_PlayEffectAtLocation", InstanceId, EffectId, self.CasterPawn, EffectLocation, EffectRotation, 0) return end end end UnrealNetwork.CallUnrealRPC_Multicast(self.CasterPawn, "Client_MulticastRPC_PlayEffect", InstanceId, EffectId, Pawn, ActorList, Duration, SpawnLocationType, BoneName) end function SimpleSkillTask_Ray:ApplyRayDamage(InMonsters) local DamageAmount = 100 + self.CurDamageRate * UGCGameSystem.GetPlayerStateByPlayerKey(self.CasterPawn.PlayerKey).Attributes[AttributeType.Base].Base_Attack local EventInstigator = UGCGameSystem.GetPlayerControllerByPlayerKey(self.CasterPawn.PlayerKey) for _, Monster in pairs(InMonsters) do if Monster ~= nil and UE.IsValid(Monster) and self:CheckValidMonsterType(Monster) then UGCGameSystem.ApplyDamage(Monster, DamageAmount, EventInstigator, self.CasterPawn, EDamageType.ShootDamage) end end end function SimpleSkillTask_Ray:GetTargetRotationList() local CasterRotation = self.CasterPawn:K2_GetActorRotation() local BoxRotation1 = {Yaw = CasterRotation.Yaw, Pitch = CasterRotation.Pitch, Roll = CasterRotation.Roll} local BoxRotation2 = {Yaw = CasterRotation.Yaw + 30, Pitch = CasterRotation.Pitch, Roll = CasterRotation.Roll} local BoxRotation3 = {Yaw = CasterRotation.Yaw - 30, Pitch = CasterRotation.Pitch, Roll = CasterRotation.Roll} return {BoxRotation1, BoxRotation2, BoxRotation3} end function SimpleSkillTask_Ray:CheckValidMonsterType(Monster) local MonsterType = Monster:GetMonsterType() local IsAttackMonster = MonsterType == EMonsterType.Common or MonsterType == EMonsterType.Boss if self.CasterPawn.IsInArena then return IsAttackMonster else return not IsAttackMonster end end return SimpleSkillTask_Ray;