---@class UGCPlayerPawn_C:BP_UGCPlayerPawn_C --Edit Below-- ---@type UGCPlayerPawn_C local UGCPlayerPawn = { -- Attr ------------------------- -- 伤害缩放 Attr_DamageScale = 1; -- 防御缩放 Attr_DefenseScale = 1; -- 闪避概率 Attr_Dodge = 0; -- -- Attr End --------------------- }; -- Replicated ------------------------------------------------------------------------------------------------------- function UGCPlayerPawn:GetReplicatedProperties() return end -- Replicated End --------------------------------------------------------------------------------------------------- -- Attr ------------------------------------------------------------------------------------------------------------- function UGCPlayerPawn:SetDamageScale(InDamageScale) self.Attr_DamageScale = InDamageScale end function UGCPlayerPawn:GetDamageScale() return self.Attr_DamageScale end function UGCPlayerPawn:SetDefenseScale(InDefenseScale) -- 防御值不能小于0 if InDefenseScale <= 0 then return false end self.Attr_DefenseScale = InDefenseScale return true end function UGCPlayerPawn:GetDefenseScale() return self.Attr_DefenseScale end function UGCPlayerPawn:SetDodge(InDodge) self.Attr_Dodge = InDodge return true end function UGCPlayerPawn:GetDodge() return self.Attr_DefenseScale end -- Attr End --------------------------------------------------------------------------------------------------------- -- 关闭盒子掉落 --function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater) -- return true --end function UGCPlayerPawn:ReceiveBeginPlay() self.SuperClass.ReceiveBeginPlay(self); --- 设置翻墙功能 self.bVaultIsOpen = true --- 设置滑铲功能 self.IsOpenShovelAbility = false UGCEventSystem.SendEvent(EventEnum.PlayerBeginPlay, self) if self:HasAuthority() then self:AddEvent() if UE.IsValid(self:GetController()) then self:ReceivePossessed(self:GetController()) UGCLogSystem.Log("[UGCPlayerPawn_ReceiveBeginPlay] Controller Is Valid") end else end end --- 客户端必定执行的BeginPlay function UGCPlayerPawn:ClientMustBeExeBeginPlay() if self.DoOnceMustBeExeBeginPlay then return end self.DoOnceMustBeExeBeginPlay = true self.ClientUpdatedPlayerKey = false end function UGCPlayerPawn:ReceivePossessed(NewController) self.SuperClass.ReceivePossessed(self, NewController); UGCLogSystem.Log("[UGCPlayerPawn_ReceivePossessed] PlayerKey:%s", tostring(NewController.PlayerKey)) UGCEventSystem.SendEvent(EventEnum.PlayerPossessed, NewController.PlayerKey) UGCGameSystem.GameState:SetPlayerIsAlive(NewController.PlayerKey, self) if UGCSystemLibrary.GetIsPreparationState() then UGCSystemLibrary.SetPlayerPawnMovable(self, false) end ---- 设置上条命保存的Buff --self.OwnedIncrease = NewController:GetOwnedIncrease() --for IncreaseType, Level in pairs(self.OwnedIncrease) do -- BuffSystemAPI.PlayerAddBuff(self, GodOfWarConfig.BuffList[IncreaseType][Level]) --end ---- 初始化上条命的进度 --self:AddToGodSchedule(NewController:GetToGodSchedule()) ---- 初始化上条命可选择的增益 --self:SetNowCanSelectIncrease(NewController:GetNowCanSelectIncrease()) ---- 初始化上条命可选择的增益数 --self:SetCanObtainIncreaseCount(NewController:GetCanObtainIncreaseCount()) -- ---- 增加一个增益 --self:AddCanObtainIncreaseCount() end function UGCPlayerPawn:ReceiveTick(DeltaTime) self.SuperClass.ReceiveTick(self, DeltaTime); if not UGCGameSystem.IsServer() then self:ClientMustBeExeBeginPlay() self:UpdatePlayerKey() --local HeadPos = self.Mesh:GetSocketLocation("head") --UGCLogSystem.Log("[UGCPlayerPawn_ReceiveTick]HeadPos:%s, ActorPos:%s", VectorHelper.ToString(HeadPos), VectorHelper.ToString(self:K2_GetActorLocation())) end end function UGCPlayerPawn:ReceiveEndPlay() self:RemoveEvent() self.SuperClass.ReceiveEndPlay(self); end function UGCPlayerPawn:AddEvent() if self:HasAuthority() then -- 这个回调无法拿到倒地死亡的玩家 -- self.DeadNotifyDelegate:Add(self.PlayerDead, self) self.DamageNotifyDelegate:Add(self.PlayerInjury, self) self.OnDeath:Add(self.OnDeathCallBack, self) else end end function UGCPlayerPawn:RemoveEvent() if self:HasAuthority() then -- self.DeadNotifyDelegate:Remove(self.PlayerDead, self) self.DamageNotifyDelegate:Remove(self.PlayerInjury, self) self.OnDeath:Remove(self.OnDeathCallBack, self) if self.CheckBornItemsHandle then UGCEventSystem.StopTimer(self.CheckBornItemsHandle) self.CheckBornItemsHandle = nil end if self.CheckWeaponAndPartsHandle then UGCEventSystem.StopTimer(self.CheckWeaponAndPartsHandle) self.CheckWeaponAndPartsHandle = nil end else end end function UGCPlayerPawn:CheckWeaponAndParts() UGCGameSystem.GameState:CheckWeaponAndParts(self.PlayerKey) end function UGCPlayerPawn:CheckBornItems() UGCLogSystem.Log("[UGCPlayerPawn_CheckBornItems] PlayerKey:%s", tostring(self.PlayerKey)) UGCLogSystem.LogTree("[UGCPlayerPawn_CheckBornItems]", self.DefaultBackPack) for i = #self.DefaultBackPack, 1, -1 do local ItemID = self.DefaultBackPack[i].ItemID local Count = self.DefaultBackPack[i].Count local InstCount = UGCBackPackSystem.GetItemCount(self, ItemID) if InstCount >= Count then UGCLogSystem.Log("[UGCPlayerPawn_CheckBornItems] i:%s", tostring(i)) table.remove(self.DefaultBackPack, i) UGCLogSystem.LogTree("[UGCPlayerPawn_CheckBornItems]", self.DefaultBackPack) else UGCBackPackSystem.AddItem(self, ItemID, Count - InstCount) end end if #self.DefaultBackPack == 0 then UGCEventSystem.StopTimer(self.CheckBornItemsHandle) self.CheckBornItemsHandle = nil UGCLogSystem.Log("[UGCPlayerPawn_CheckBornItems] Succeed PlayerKey:%s", tostring(self.PlayerKey)); end end -------------------------------------------------- Delegate -------------------------------------------------- ---@param DamageInfo FDamageInfoCollection ---@return VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue uint, uint, int, EDamageType, bool, float, float function UGCPlayerPawn:GetDamageInfoCollectionInfo(DamageInfo) local CauserController = DamageInfo.Instigator local WeaponID = -1 local CauserKey = CauserController and CauserController.PlayerKey or -1 local VictimKey = self.PlayerKey local CauserItemID = DamageInfo.CauserItemID --- 近战投掷、投掷手雷 if CauserItemID then WeaponID = CauserItemID end UGCLogSystem.Log("[UGCPlayerPawn_GetDamageInfoCollectionInfo] WeaponID:%d", WeaponID) local Distance = 0. if CauserController and CauserController.Pawn then Distance = VectorHelper.GetDistance(self:K2_GetActorLocation(), CauserController.Pawn:K2_GetActorLocation()) end local IsHeadShotDamage = (DamageInfo.Hit.BoneName == "head") return VictimKey, CauserKey, WeaponID, DamageInfo.DamageType, IsHeadShotDamage, Distance, DamageInfo.Damage end ---@param DamageInfo FDamageInfoCollection function UGCPlayerPawn:PlayerDead(DamageInfo) UGCLogSystem.LogTree("[UGCPlayerPawn_PlayerDead] DamageInfo:", UE.ToTable(DamageInfo)) local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo) --UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue) --UGCEventSystem.SendEvent(EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue) UGCGameSystem.GameState:SetPlayerIsAlive(VictimKey, nil) end ---@param DamageInfo FDamageInfoCollection ---@param ReturnValue float function UGCPlayerPawn:PlayerInjury(DamageInfo) local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo) UGCEventSystem.SendEvent(EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue) UGCSendRPCSystem.RPCEvent(CauserKey, EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue) end function UGCPlayerPawn:OnDeathCallBack(DeadCharacter,Killer,DamageCauser,KillingHitInfo,KillingHitImpulseDir,KillingHitDamageTypeID,DamageTypeClass,IsHeadShotDamage) local CauserKey = Killer and Killer.PlayerKey local WeaponID = -1 local DamageType = EDamageType.UGCCustomDamageType + 1 UGCLogSystem.Log("[UGCPlayerPawn_TestOnDeath] PlayerKey:%s, CauserKey:%s", tostring(self.PlayerKey), tostring(CauserKey)) UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerDeathInfo, self.PlayerKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, 0, 0) UGCEventSystem.SendEvent(EventEnum.PlayerDeathInfo, self.PlayerKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, 0, 0) UGCGameSystem.GameState:SetPlayerIsAlive(self.PlayerKey, nil) end ------------------------------------------------ Delegate End ------------------------------------------------ ------------------------------------------------ ModifyDamage ------------------------------------------------ ---@field UGC_TakeDamageOverrideEvent:fun(Damage:float,DamageType:EDamageType,EventInstigator:AController,DamageCauser:AActor,Hit:FHitResult):float function UGCPlayerPawn:UGC_TakeDamageOverrideEvent(Damage, DamageType, EventInstigator, DamageCauser, Hit) -- 判断游戏状态伤害 if GlobalConfigs.GameSetting.JustPlayingEnableDamage and UGCGameSystem.GameState:GetGameStateType() ~= CustomEnum.EGameState.Playing then return 0 end -- 判断准备阶段伤害开启 if not GlobalConfigs.GameSetting.ReadyStateEnableDamage and UGCGameSystem.GameState:IsReadyState() then return 0 end -- 拷贝临时伤害值 local DamageAmount = Damage -- 输出修改前的伤害数值 UGCLogSystem.Log("[UGCPlayerPawn_UGC_TakeDamageOverrideEvent] InDamageAmount:%s, DamageType:%s", tostring(DamageAmount), tostring(DamageType)) -- 玩家参数信息对伤害数值的修改 DamageAmount = self:ModifyDamageByPlayerParameters(DamageAmount, EventInstigator) -- 伤害类型对伤害数值的修改 DamageAmount = self:ModifyDamageByDamageType(DamageAmount, DamageType) -- 绑定的委托的伤害修改 DamageAmount = self:ModifyDamageByAttachDamageFunc(DamageAmount, DamageType, EventInstigator, DamageCauser, Hit) UGCLogSystem.Log("[UGCPlayerPawn_UGC_TakeDamageOverrideEvent] ModifyDamageAmount:%s", tostring(DamageAmount)) return DamageAmount end --- 玩家信息对伤害数值的修改 function UGCPlayerPawn:ModifyDamageByPlayerParameters(DamageAmount, CauserPC) if UE.IsValid(CauserPC) then local CauserPlayerKey = CauserPC.PlayerKey if CauserPlayerKey then -- 获取敌方队伍ID local CauserTeamID = UGCPlayerStateSystem.GetTeamID(CauserPlayerKey) -- 获取己方队伍ID local SelfTeamID = UGCPlayerStateSystem.GetTeamID(self.PlayerKey) -- 获取施加者的玩家Pawn local CauserPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(CauserPlayerKey) if CauserPlayerKey == self.PlayerKey and GlobalConfigs.GameSetting.bEnableSelfHarm then --- 对自己的伤害 DamageAmount = GlobalConfigs.GameSetting.SelfHarmInjuryRatio * DamageAmount else --- 他人对自己的伤害 -- 判断友伤 if CauserTeamID == SelfTeamID then -- 友伤数值修改 DamageAmount = GlobalConfigs.GameSetting.FriendlyInjuryRatio * DamageAmount end end -- 获取攻击者伤害缩放 local DamageScale = CauserPawn and CauserPawn:GetDamageScale() or 1 -- 施加者攻击力对伤害的修改 DamageAmount = DamageAmount / self:GetDefenseScale() * DamageScale end -- 防御力对伤害的修改 DamageAmount = DamageAmount / self:GetDefenseScale() end return DamageAmount end --- 伤害类型对伤害数值的修改 function UGCPlayerPawn:ModifyDamageByDamageType(DamageAmount, DamageType) -- 掉落伤害 if DamageType == EDamageType.FallingDamage then DamageAmount = GlobalConfigs.GameSetting.bEnableDropDamage and DamageAmount or 0. end -- 设置近战伤害缩放 if DamageType == EDamageType.MeleeDamage then DamageAmount = DamageAmount * GlobalConfigs.GameSetting.MeleeDamageScale end -- 判断忽略的伤害 if table.hasValue(GlobalConfigs.GameSetting.IgnoreDamageType, DamageType) then DamageAmount = 0. end return DamageAmount end -- 伤害修改列表 UGCPlayerPawn.DamageModifyFunctions = {} --- 绑定是伤害修改函数对伤害的修改 function UGCPlayerPawn:ModifyDamageByAttachDamageFunc(DamageAmount, DamageType, EventInstigator, DamageCauser, Hit) for i, v in pairs(self.DamageModifyFunctions) do if v.Obj then DamageAmount = v.Func(v.Obj, self, DamageAmount, DamageType, EventInstigator, DamageCauser, Hit) else DamageAmount = v.Func(self, DamageAmount, DamageType, EventInstigator, DamageCauser, Hit) end UGCLogSystem.Log("[UGCPlayerPawn_ModifyDamageByAttachDamageFunc] ChangeDamage:%s", tostring(DamageAmount)) end return DamageAmount end --- 添加伤害修改函数 ---@param ModifyFunc function 修改伤害的静态函数 fun(Pawn, Damage, DamageType, EventInstigator, DamageCauser, Hit):float ---@param Layer 修改的层级 层级越高越往后对伤害进行修改 function UGCPlayerPawn:AddDamageModifyFunc(ModifyFunc, Obj, Layer) -- 设置层级默认值 if Layer == nil then Layer = 1 end -- 插入修改函数 local IsInsert = false for i, v in pairs(self.DamageModifyFunctions) do if v.Layer > Layer then table.insert(self.DamageModifyFunctions, i, {Func = ModifyFunc, Obj = Obj, Layer = Layer}) IsInsert = true break end end if not IsInsert then table.insert(self.DamageModifyFunctions, #self.DamageModifyFunctions + 1, {Func = ModifyFunc, Obj = Obj, Layer = Layer}) end UGCLogSystem.LogTree("[UGCPlayerPawn_AddDamageModifyFunc]", self.DamageModifyFunctions) end --- 移除伤害修改函数 function UGCPlayerPawn:RemoveDamageModifyFunc(ModifyFunc, Obj) for i, v in pairs(self.DamageModifyFunctions) do if v.Func == ModifyFunc and v.Obj == Obj then table.remove(self.DamageModifyFunctions, i) UGCLogSystem.LogTree("[UGCPlayerPawn_RemoveDamageModifyFunc]", self.DamageModifyFunctions) break end end end ---------------------------------------------- ModifyDamage End ---------------------------------------------- -- UGC Event ------------------------------------------------------------------------------------------------------- -- 这些事件都是官方的回调或者可重写的事件 ---@field UGC_PlayerDeadEvent:fun(Killer:AController,DamageType:EDamageType) ---@field UGC_PlayerPickUpEvent:fun() ---@field UGC_LeavePawnStateEvent:fun(PawnState:EPawnState) ---@field UGC_EnterPawnStateEvent:fun(PawnState:EPawnState) ---@field UGC_CloseScopeEvent:fun() ---@field UGC_OpenScopeEvent:fun() ---@field UGC_ReloadEndEvent:fun() ---@field UGC_ReloadStartEvent:fun() ---@field UGC_WeaponSwitchEvent:fun() ---@field UGC_WeaponStopFireEvent:fun() ---@field UGC_WeaponStartFireEvent:fun(isAuto:ESTEWeaponShootType) ---@field UGC_EquipWeaponEvent:fun(Slot:ESurviveWeaponPropSlot) ---@field UGC_ChangeCurrentUsingWeaponEvent:fun(UsingWeaponSlot:ESurviveWeaponPropSlot,LastSlot:ESurviveWeaponPropSlot) --- 子弹命中 ---@field UGC_WeaponBulletHitEvent:fun(ShootWeapon:ASTExtraShootWeapon,Bullet:ASTExtraShootWeaponBulletBase,HitInfo:FHitResult) function UGCPlayerPawn:UGC_WeaponBulletHitEvent(ShootWeapon, Bullet, HitInfo) UGCEventSystem.SendEvent(EventEnum.BulletHitCallBack, self, ShootWeapon, Bullet, HitInfo) end ---@field UGC_WeaponShootBulletEvent:fun(ShootWeapon:ASTExtraShootWeapon,Bullet:ASTExtraShootWeaponBulletBase) -- UGC Event End ----------------------------------------------------------------------------------------------------- --- 处理飘字 function UGCPlayerPawn:UGC_GetDamageNumberConfigIndex(Damage, IsHeadShot, InstigatorController, DamageCauser, DamageType) UGCLogSystem.Log("[UGCPlayerPawn_UGC_GetDamageNumberConfigIndex]") if GlobalConfigs.GameSetting.ShowDamageNumber and InstigatorController == UGCSystemLibrary.GetLocalPlayerController() then return 0 else return -1 end end --- 播放粒子 function UGCPlayerPawn:PlayParticle(InParticleType) ParticleConfig.AddParticleAttachPlayer(self, InParticleType) end ----------------------------------------------------------------------------------------------------------------------- --- 客户端玩家Key更新 function UGCPlayerPawn:UpdatePlayerKey() if self.ClientUpdatedPlayerKey == false then if self.PlayerKey and self.PlayerKey > 0 then self.ClientUpdatedPlayerKey = true self:Stroke() end end end --- Client --- 描边 function UGCPlayerPawn:Stroke() if GlobalConfigs.GameSetting.EnableStroke then UGCLogSystem.Log("[UGCPlayerPawn_Stroke]PlayerKey:%s", tostring(self.PlayerKey)) UGCEventSystem.SetTimer(self, function() if UGCGameSystem.GameState:GetPlayerTeamIDByPlayerKey(self.PlayerKey) ~= UGCGameSystem.GameState:GetPlayerTeamIDByPlayerKey(UGCSystemLibrary.GetLocalPlayerKey()) then if GlobalConfigs.IsHaiDao then self.Mesh:SetDrawIdeaOutline(true) for EAvatarSlotTypeNum = 0, EAvatarSlotType.EAvatarSlotType_Max -1 do UGCLogSystem.Log("[UGCPlayerPawn_Stroke]" .. EAvatarSlotTypeNum) local MeshComponent = self.CharacterAvatarComp_BP:GetMeshCompBySlot(EAvatarSlotTypeNum) if MeshComponent ~= nil then UGCLogSystem.Log("[UGCPlayerPawn_Stroke] Succeed" .. EAvatarSlotTypeNum) MeshComponent:SetDrawIdeaOutline(true) end end else -- UGCGameSystem.GameState:RegisterPostProcessMgr(self) STExtraBlueprintFunctionLibrary.EnablePlayerAvatarOutline(self, true) UGCLogSystem.Log("[UGCPlayerPawn_Stroke] EnablePlayerAvatarOutline") end end end, 2) end end --function UGCPlayerPawn:GetAvailableServerRPCs() -- return --end return UGCPlayerPawn;