---@class BP_PlayerState_C:BP_UGCPlayerState_C --Edit Below-- UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom') UGCGameSystem.UGCRequire('Script.Common.ue_struct_custom') UGCGameSystem.UGCRequire('Script.Global.Global') local BP_PlayerState = { -- [AttributeType] = { AttributeName: Value , ...}, ... Attributes = {}, -- 玩家属性表,存放所有属性 CombatPoint = 0, -- 战力 CoinPoint = { Total = 0, Current = 0, }, -- 金币 KillPoint = { Total = 0, Current = 0, }, -- 杀敌点 KillCount = { Total = 0, Boss = 0, }, -- 杀敌数,用于计算增加量和表示玩家击杀怪物 Level = 1, -- 等级 CurExp = 0, -- 获取的总经验 NextAddExp = 0, -- 由于被打断,之后需要添加的值 BreachInfo = { NeedBreach = false, --是否需要突破 InBreachProgress = false, --是否正在突破中 }, BreachSuccessTime = 0, --突破成功次数 --local ItemData = { -- WeaponId = InWeaponId, -- Type = WeaponType, -- NativeProps = { -- Common = 0, -- Plus = { }, -- }, -- Properties = { }, -- Fittings = { }, -- FittingLevel = 0, -- } OwnerWeapons = {}, TotalWeaponCount = 0, --当前拥有的Weapon数量 TechBuyNum = {}, -- 玩家科技表 BackupEnergyData = {}, --玩家能量信息备份 -- 需要同步的射击距离 AttackRange = 0, -- 同步的射击距离 ChallengeMonsterTime = {}, LastSpecialItems = {}, -- 保存着上一次的词条属性 --- 存放特殊词条物品,如果存在,那么就是有该属性;不存在,就取消 --- [id] = { --- Times = 0, --- LastTime = ServerTime, --- } SpecialItemTimerHandles = { ['击败'] = { }, ['每秒'] = { }, ['射击'] = { }, ['射击%'] = { }, ['周期'] = { }, ['固定'] = { }, }, --保存着对应Id的Timer --- 存放着继承的等级 InheritItems = { ['盔'] = 110, ['甲'] = 210, }, -- 特殊物品数据存放地方,没有特定结构,数据结构 { [ID] = {}, } SpecialThings = {}, --- 每局游戏通关之类保存的数据 --- { --- GameTimes = 0, --游玩局数 --- GameClearanceTimes = 0, --游戏通关数 --- TotalCoinPoint = 0, --获取总金币数 --- TotalKillPoint = 0, --获取总杀敌点数 --- TotalBossKilledTimes = 0,--击杀 Boss 次数 --- TotalSuperSkill = 0, --获取总超级技能数 --- TotalSuperFitting = 0, --获取超级配件数 --- TotalUnpackTimes = 0, --总开箱次数 --- Score = 0, --积分 --- --- PlayedGames = { --通关过的游戏 --- Difficulty = Times --- }, --- BossDropItems = { --- ["春"] = { --- Type: Count --- }, --- }, --- GameDropItems = { --- Difficulty = { Type: Count }, --- }, --- EasterEggs = { --彩蛋类 --- }, --- } ArchiveData = nil, -- 存一份缓存 SavedArchiveData = nil; GameEndSavedArchiveData = {}; -- 新的一局游戏初始数据,该数据是 { Type = Value, ... } NewGameInitialData = {}, EasterEggsData = { }, -- 一些其他属性 AppendAttribute = {}, --当前强制引导信息 ForceGuideInfo = { CurStepIndex = -2, ValidStepIndex = -2, bIsInStepProgress = false, StepPendingList = {}, }, }; function BP_PlayerState:GetReplicatedProperties() return "Attributes", "CoinPoint", "KillPoint", "OwnerWeapons", "TechBuyNum", "AttackRange", "TotalWeaponCount", "ChallengeMonsterTime", "InheritItems", "ArchiveData", {"BreachInfo", "Lazy"}, {"ForceGuideInfo", "Lazy"}, {"SavedArchiveData", "Lazy"} end function BP_PlayerState:ReceiveBeginPlay() BP_PlayerState.SuperClass.ReceiveBeginPlay(self) if self:HasAuthority() == true then self:BindServerEvent() self:InitWeaponAttribute() self:InitChallengeMonsterTime(-10000.0) for key, _ in pairs(Tables.Tech) do self.TechBuyNum[key] = 0 end EventSystem.SetTimer(self, function() --self:TestAddStone() end, 20) else local CommandManager = require('Script.Manager.CommandQueneManager') CommandManager.bPlayerStateReady = true CommandManager:AddInitCommand(self, self.Client_Init) UE.Log("[BP_PlayerState] *** BP_PlayerPawn Tick Init Ready PlayerKey:%s", self.PlayerKey) end end function BP_PlayerState:ReceiveEndPlay() if self:HasAuthority() then self:UnbindServerEvent() else CommandQueneManager:RemoveInitCommand(self) end BP_PlayerState.SuperClass:ReceiveEndPlay() end function BP_PlayerState:Client_Init() if self:GetOwner() == STExtraGameplayStatics.GetFirstPlayerController(self) then GameDataManager:SetLocalPlayerState(self) end self:OnRep_Attributes() self:OnRep_CoinPoint() self:OnRep_KillPoint() self:OnRep_OwnerWeapons() self:OnRep_TotalWeaponCount() self:OnRep_AttackRange() end function BP_PlayerState:BindServerEvent() end function BP_PlayerState:UnbindServerEvent() end function BP_PlayerState:InitArchiveData() local ItemData = { GameTimes = 0, --游玩局数 GameClearanceTimes = 0, --游戏通关数 TotalCoinPoint = 0, --获取总金币数 TotalKillPoint = 0, --获取总杀敌点数 TotalBossKilledTimes = 0, --击杀 Boss 次数 TotalSuperSkill = 0, --获取总超级技能数 TotalSuperFitting = 0, --获取超级配件数 TotalUnpackTimes = 0, --总开箱次数 Score = 0, --总开箱次数 PlayedGames = { --游玩过的游戏 }, BossDropItems = { }, GameDropItems = { }, EasterEggs = { --彩蛋类 }, } -- 初始化 for i = 1, 13 do --if i ~= 9 then ItemData.EasterEggs[i] = { Active = false, -- 是否激活 } --end end return ItemData end -- 加载重生数据 function BP_PlayerState:LoadNewGameInitialData() print(string.format('[BP_PlayerState:LoadNewGameInitialData] 加载到 NewGameInitialData 中')) local Data = self.ArchiveData local OutTable = {} if Data == nil then -- 说明还未加载,请检查原因 print(string.format('[BP_PlayerState:LoadNewGameInitialData] Error 按理说此处应该加载了,但是并没有显示出来')) self.NewGameInitialData = {} return end -- 通关检查 if self.ArchiveData.GameClearanceTimes > 0 then -- i:难度(int); v:次数(int) for i, v in pairs(self.ArchiveData.PlayedGames) do -- 从表中进行加载,k: 可以获得奖励的次数; u: 具体奖励 for k,u in pairs(ArchiveTable.GameClearanceRewards[i]) do if k <= v then ArchiveTable.Funcs[ArchiveTable.ArchiveType.GameClearance](i, k, OutTable) end end end else -- 表示第一次游玩 print(string.format('[BP_PlayerState:LoadNewGameInitialData] 第一次游玩')) end local Func = function(InTable, InOutTable) for i, v in pairs(InTable) do InOutTable[i] = v end end -- 积分 ArchiveTable.Funcs[ArchiveTable.ArchiveType.Credit](self.ArchiveData.Score, OutTable) --Func(OutTable, self.NewGameInitialData) -- 依次判断以下内容 --- 通关 ArchiveTable.Funcs[ArchiveTable.ArchiveType.Achievement].Func("通关", self.ArchiveData.GameClearanceTimes, OutTable) --- 击杀首领 ArchiveTable.Funcs[ArchiveTable.ArchiveType.Achievement].Func("击败", self.ArchiveData.TotalBossKilledTimes, OutTable) --- 获得金币,单位是w ArchiveTable.Funcs[ArchiveTable.ArchiveType.Achievement].Func("金币", self.ArchiveData.TotalCoinPoint / 10000, OutTable) --- 获得杀敌点 ArchiveTable.Funcs[ArchiveTable.ArchiveType.Achievement].Func("科技点", self.ArchiveData.TotalKillPoint, OutTable) --- 获得超级技能 ArchiveTable.Funcs[ArchiveTable.ArchiveType.Achievement].Func("技能", self.ArchiveData.TotalSuperSkill, OutTable) --- 获得超级配件 ArchiveTable.Funcs[ArchiveTable.ArchiveType.Achievement].Func("配件", self.ArchiveData.TotalSuperFitting, OutTable) --- 开箱次数 ArchiveTable.Funcs[ArchiveTable.ArchiveType.Achievement].Func("开箱", self.ArchiveData.TotalUnpackTimes, OutTable) Func(OutTable, self.NewGameInitialData) -- Boss 掉落物 ArchiveTable.Funcs[ArchiveTable.ArchiveType.DropBossItems](self.ArchiveData.BossDropItems, OutTable) Func(OutTable, self.NewGameInitialData) -- 游戏掉落物 ArchiveTable.Funcs[ArchiveTable.ArchiveType.DropGameItems](self.ArchiveData.GameDropItems, OutTable) Func(OutTable, self.NewGameInitialData) log_tree("[BP_PlayerState:LoadNewGameInitialData] Begin self.NewGameInitialData = ", self.NewGameInitialData); -- 彩蛋类 for EasterIndex, Table in pairs(ArchiveTable.EasterEggs) do if self.ArchiveData.EasterEggs[EasterIndex] == nil then self.ArchiveData.EasterEggs[EasterIndex] = { Active = false; } else if self.ArchiveData.EasterEggs[EasterIndex].Active then local Type = Table.Reward.Type; if Type ~= nil then if self.NewGameInitialData[Type] == nil then self.NewGameInitialData[Type] = Table.Reward.Value else self.NewGameInitialData[Type] = self.NewGameInitialData[Type] + Table.Reward.Value end --print(string.format("[BP_PlayerState:LoadNewGameInitialData] Type = " .. tostring(Type))) end end end end --for EasterIndex, Table in pairs(self.ArchiveData.EasterEggs) do -- if Table and Table.Active then -- -- 添加进去 -- local Item = ArchiveTable.EasterEggs[EasterIndex] -- if Item ~= nil then -- local Type = Item.Reward.Type -- if Type ~= nil then -- if self.NewGameInitialData[Type] == nil then -- self.NewGameInitialData[Type] = ArchiveTable.EasterEggs[EasterIndex].Reward.Value -- else -- self.NewGameInitialData[Type] = self.NewGameInitialData[Type] + ArchiveTable.EasterEggs[EasterIndex].Reward.Value -- end -- --print(string.format("[BP_PlayerState:LoadNewGameInitialData] Type = " .. tostring(Type))) -- end -- end -- end --end log_tree("[BP_PlayerState:LoadNewGameInitialData] End self.NewGameInitialData = ", self.NewGameInitialData); -- 应用到 Attributes[Base] 中 --self.NewGameInitialData = OutTable print(string.format('[BP_PlayerState:LoadNewGameInitialData] 应用到数据:')) log_tree("NewGameInitialData = ", self.NewGameInitialData) end function BP_PlayerState:GetGameTimes() local GameTimes = 0 local ArchiveData = self.ArchiveData if ArchiveData then local ArchivedGameTimes = ArchiveData.GameTimes GameTimes = ArchivedGameTimes ~= nil and ArchivedGameTimes or 0 end return GameTimes end function BP_PlayerState:GetNeedTriggerForceGuide() local SavedArchiveData = self.SavedArchiveData local PlayedGames = SavedArchiveData.PlayedGames local MaxDifficulty = 0 for Difficulty, Times in pairs(PlayedGames) do if Times ~= nil and Times > 0 then if Difficulty >= 5 then return false else if Difficulty > MaxDifficulty then MaxDifficulty = Difficulty end end end end -- return self:GetGameTimes() <= 100 local GameDifficulty = UGCGameSystem.GameState.GameDifficulty return false -- return GameDifficulty ~= nil and MaxDifficulty < 5 and GameDifficulty > 0 and GameDifficulty <= 2 end -- 初始化存档数据(从 NewGameInitialData 加载到 Attributes[Base] ) function BP_PlayerState:InitData() print(string.format('[BP_PlayerState:InitData] 开始往 Attributes 中写入数据')) for i, v in pairs(self.NewGameInitialData) do if self.Attributes[AttributeType.Base][i] ~= nil then self.Attributes[AttributeType.Base][i] = self.Attributes[AttributeType.Base][i] + v else local EnName = GlobalConfigs.AttributeNameTable[i] if EnName ~= nil then if self.Attributes[AttributeType.Base][EnName] == nil then self.Attributes[AttributeType.Base][EnName] = v else self.Attributes[AttributeType.Base][EnName] = self.Attributes[AttributeType.Base][EnName] + v end else self.AppendAttribute[i] = v print(string.format('[BP_PlayerState:InitData] 无法找到名为 %s 的属性,请检查', i)) end end end print(string.format('[BP_PlayerState:InitData] 玩家:%d', self.UID)) log_tree("Attributes = ", self.Attributes) -- 下面是检查其他不在 GlobalConfigs 中的一些属性,然后依次实现即可,比如 中级配件 这种 self:HandleOtherAttribute() end function BP_PlayerState:HandleOtherAttribute() log_tree("[BP_PlayerState:HandleOtherAttribute] self.AppendAttribute = ", self.AppendAttribute); for i, v in pairs(self.AppendAttribute) do if i == '初始金币' then self.CoinPoint.Current = self.CoinPoint.Current + v self.CoinPoint.Total = self.CoinPoint.Total + v; elseif i == '初始科技点' then self.KillPoint.Current = self.KillPoint.Current + v; self.KillPoint.Total = self.KillPoint.Total + v; -- @Test 简化 --elseif i == '初级配件' then -- self:GiveArchiveInitItem(EDropItemSet.WeaponParts, EQualityType.Primary) --elseif i == '中级配件' then -- self:GiveArchiveInitItem(EDropItemSet.WeaponParts, EQualityType.Middle) --elseif i == '高级配件' then -- self:GiveArchiveInitItem(EDropItemSet.WeaponParts, EQualityType.Senior) elseif i == '初级技能' then if type(v) == 'number' then for c = 1, v do self:GiveArchiveInitItem(EDropItemSet.SkillBooks, EQualityType.Primary, 1) end else self:GiveArchiveInitItem(EDropItemSet.SkillBooks, EQualityType.Primary, 1) end elseif i == '中级技能' then if type(v) == 'number' then for c = 1, v do self:GiveArchiveInitItem(EDropItemSet.SkillBooks, EQualityType.Middle, 1) end else self:GiveArchiveInitItem(EDropItemSet.SkillBooks, EQualityType.Middle, 1) end elseif i == '高级技能' then if type(v) == 'number' then for c = 1, v do self:GiveArchiveInitItem(EDropItemSet.SkillBooks, EQualityType.Senior, 1) end else self:GiveArchiveInitItem(EDropItemSet.SkillBooks, EQualityType.Senior, 1) end --elseif i == "高级抽奖金币消耗%" then elseif i == "初始经验" then -- 添加初始经验 self:AddExp(v) else print(string.format("[BP_PlayerState:HandleOtherAttribute] 此时选项是 %s, 值是 %s", tostring(i), tostring(v))); end end end function BP_PlayerState:GiveArchiveInitItem(InType, InQuality, InCount) local ItemId = 0 if InType == EDropItemSet.WeaponParts then local RanNum1 = math.random(1, 5) -- 配件种类 local RandNum2 = math.random(1, 6) -- 武器 ItemId = 10000 + RanNum1 * 1000 + RandNum2 * 100 + (InQuality + 1) * 10 elseif InType == EDropItemSet.SkillBooks then local RanNum = math.random(9, 32) ItemId = 20000 + RanNum * 100 + (InQuality + 1) * 10 end -- 加到背包 local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey) PlayerController:UpdateItemMap(ItemId, InCount) end function BP_PlayerState:TestAddStone() local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey) PlayerController:UpdateItemMap(31000, 100) PlayerController:UpdateItemMap(32000, 100) end -- 重置除了基础属性其他属性 function BP_PlayerState:InitWeaponAttribute() if self.Attributes[AttributeType.Weapon] ~= nil then for i, v in pairs(self.Attributes[AttributeType.Weapon]) do self.Attributes[AttributeType.Weapon][i] = 0 self.Attributes[AttributeType.WeaponSpecial][i] = 0 end end end function BP_PlayerState:InitChallengeMonsterTime(InTime) for k, TargetMonsterInfo in pairs(Tables.ChallengeInfo) do self.ChallengeMonsterTime[k] = {LastChallengeTime = InTime, CoolingTime = TargetMonsterInfo.CoolingTime} end end -- Server function BP_PlayerState:OnWeaponAttributeChanged(InWeaponId) -- 在这里判断是不是当前 Weapon,如果不是可以直接不更新 UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 开始更新玩家属性表") local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) local WC = PlayerPawn:GetWeaponComponent() if WC == nil then UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 检查一下 WC") return end local CurrWeaponId = WC.CurrentWeaponId local Data = GameDataManager.GetWeaponConstructDataByID(CurrWeaponId) if Data == nil then UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] Data is nil") return end --要更新的不是当前武器,所以忽略 if InWeaponId ~= CurrWeaponId then return end -- 清空属性表 self:InitWeaponAttribute() local OutTable, SpecialItems = --[[WC:GetOutProps()]] {}, {} -- 是否要刷新射速 local bShootRefresh = false for i = 1, #OutTable do local SingleVal = OutTable[i] if SingleVal == nil then UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 里面的值为空,请检查") else local Index = GlobalConfigs.AttributeNameTable[SingleVal.Type] if not bShootRefresh then if SingleVal.Type ~= nil then bShootRefresh = string.find(SingleVal.Type, '射速') ~= -1 else UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 此时属性是 nil") end end -- 这些是基础属性 if Index ~= nil then -- 添加到武器属性上 self.Attributes[AttributeType.Weapon][Index] = SingleVal.Value + self.Attributes[AttributeType.Weapon][Index] print(string.format("[BP_PlayerState:OnWeaponAttributeChanged] Value = %s", tostring(self.Attributes[AttributeType.Weapon][Index]))) else -- 检查是否是 Special if SingleVal.Unit == 'Special' then print(string.format('[BP_PlayerState:OnWeaponAttributeChanged] 当前是特殊词条')) self.Attributes[AttributeType.WeaponSpecial][SingleVal.Type] = SingleVal.Value else end if SingleVal.Type ~= nil then if math.type(SingleVal.Value) == 'integer' then UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 未设置:Key: %s, Value = %d", SingleVal.Type, SingleVal.Value) elseif math.type(SingleVal.Value) == 'float' then UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 未设置:Key: %s, Value = %f", SingleVal.Type, SingleVal.Value) else UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 值为空,请检查一下") end else UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] Find Index == nil") end end end end local Val = 0 for _, v in pairs(self.Attributes) do Val = Val + v.Base_AttackRange end UE.Log("[BP_PlayerState:OnWeaponAttributeChanged] 此时额外攻击距离是 %s", tostring(Val)) self.AttackRange = Val > 0 and Val or 0 if bShootRefresh then EventSystem:SendEvent(EventType.RefreshShoot) end if table.getCount(SpecialItems) > 0 then self:DealWithSpecialItems(SpecialItems) else print(string.format("[BP_PlayerState:OnWeaponAttributeChanged] 当前没有特殊的配件")) end self:PostChangedProps(); self:ApplyAttributes(); end function BP_PlayerState:PostChangedProps() -- 每1%的暴击伤害%加成会提高3%的射击伤害% if self:IsCurrentWeaponHasItem(14540) then local TotalAttack = 0 for _, v in pairs(self.Attributes) do TotalAttack = v.Bonus_CriticalAttack + TotalAttack end self.Attributes[AttributeType.WeaponSpecial].Bonus_CriticalAttack = TotalAttack * 3 else self.Attributes[AttributeType.WeaponSpecial].Bonus_CriticalAttack = 0 end if self:IsCurrentWeaponHasItem(15640) then local TotalAttack = 0 for _, v in pairs(self.Attributes) do TotalAttack = v.Bonus_FireAttack + TotalAttack end self.Attributes[AttributeType.WeaponSpecial].Adv_CriticalAttack = TotalAttack * 3 else self.Attributes[AttributeType.WeaponSpecial].Adv_CriticalAttack = 0 end end function BP_PlayerState:DealWithSpecialItems(InItems) print(string.format("[BP_PlayerState:DealWithSpecialItems] 处理特殊物品")) -- 此时里面是有数据的 -- 首先跟之前的进行比较,观察是否有移除或者添加的 Item,找出交集,然后分别对比前后 local SameItems = {} local NeedRemoveItems = {} local NeedAddItems = {} local NewItems = {} local OldItems = {} for i = 1, table.getCount(InItems) do NewItems[InItems[i].ItemId] = 1 print(string.format("[BP_PlayerState:DealWithSpecialItems] Item Id = %d", InItems[i].ItemId)) end for i = 1, table.getCount(self.LastSpecialItems) do OldItems[self.LastSpecialItems[i]] = 1 end for i, v in pairs(NewItems) do if OldItems[i] == 1 then -- 说明这是公共的 SameItems[i] = 1 else -- 说明是需要添加的 NeedAddItems[i] = 1 end end for i, v in pairs(OldItems) do if OldItems[i] == nil then -- 说明是需要移除的 NeedRemoveItems[i] = 1 end end self.LastSpecialItems = InItems if table.getCount(SameItems) then for i, v in pairs(SameItems) do print(string.format("[BP_PlayerState:DealWithSpecialItems] 相同的物品:%d", i)) end end if table.getCount(NeedAddItems) > 0 then for i, v in pairs(NeedAddItems) do print(string.format("[BP_PlayerState:DealWithSpecialItems] 需要添加的物品:%d", i)) end end if table.getCount(NeedRemoveItems) > 0 then for i, v in pairs(NeedRemoveItems) do print(string.format("[BP_PlayerState:DealWithSpecialItems] 需要移除的物品:%d", i)) end end if table.getCount(NeedAddItems) > 0 then self:AddSpecialItems(NeedAddItems) end if table.getCount(NeedRemoveItems) > 0 then self:RemoveSpecialItems(NeedRemoveItems) end end -- {id = 1} function BP_PlayerState:AddSpecialItems(InItems) local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) print(string.format("[BP_PlayerState:AddSpecialItems] 添加特殊物品")) for i, v in pairs(InItems) do print(string.format("[BP_PlayerState:AddSpecialItems] 特殊物品:%d", i)) local Cond = DropItemMap.SpecialFittingProperties[i][1].Condition self.SpecialItemTimerHandles[Cond][i] = { Times = 0, LastTime = 0, } if Cond == '击败' then elseif Cond == '每秒' then elseif Cond == '射击' then --self:Special_RemoveKillCount(i) elseif Cond == '射击%' then elseif Cond == '周期' then elseif Cond == '固定' then end end end -- {id = 1} function BP_PlayerState:RemoveSpecialItems(InItems) for i, v in pairs(InItems) do local Cond = DropItemMap.SpecialFittingProperties[i][1].Condition self.SpecialItemTimerHandles[Cond][i] = { Times = 0, LastTime = 0, } if Cond == '击败' then self:Special_RemoveKillCount(i) elseif Cond == '每秒' then self:Special_RemoveKillCount(i) elseif Cond == '射击' then self:Special_RemoveKillCount(i) elseif Cond == '射击%' then elseif Cond == '周期' then elseif Cond == '固定' then end end end --测试打印所有属性 function BP_PlayerState:PrintAllAttributes() UE.Log("[BP_PlayerState:PrintAllAttributes] 开始打印 Attributes") --玩家的普通属性 for _, v in pairs(self.Attributes) do print(string.format('[BP_PlayerState:PrintAllAttributes] Id = %d', _)) for j, k in pairs(v) do if math.type(k) == 'integer' then UE.Log('%s = %d', j, k) elseif math.type(k) == 'float' then UE.Log('%s = %f', j, k) end end end UE.Log("[BP_PlayerState:PrintAllAttributes] 结束打印 Attributes") end -- 应用玩家最大生命值和最大能量值属性 function BP_PlayerState:ApplyAttributes() print(string.format('[BP_PlayerState:ApplyAttributes] 执行方法')) local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) --self:PrintAllAttributes() local TheHP = 0 local TheEnergy = 0 for _, v in pairs(self.Attributes) do TheHP = TheHP + v.Base_MaxHP TheEnergy = TheEnergy + v.Base_MaxEnergy end UE.Log("[BP_PlayerState:ApplyAttributes] PlayerKey = %d, MaxHealth = %f, MaxEnergy = %f", self.PlayerKey, TheHP, TheEnergy) PlayerPawn:SetMaxHealth(TheHP) PlayerPawn:SetMaxEnergy(TheEnergy) end -- 武器属性不用管 function BP_PlayerState:GrowthAttributes() local GrowthHp = 0 -- 直接读取所有的 GrowthHp for _, v in pairs(self.Attributes) do GrowthHp = v.Growth_MaxHP * (1 + v.Bonus_MaxHP) + GrowthHp end if GrowthHp > 0 then self.Attributes[AttributeType.Base].Base_MaxHP = self.Attributes[AttributeType.Base].Base_MaxHP + GrowthHp local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) local Temp = 0 for _, v in pairs(self.Attributes) do Temp = Temp + v.Base_MaxHP end PlayerPawn:SetMaxHealth(Temp) end for _, v in pairs(self.Attributes) do v.Base_Attack = v.Base_Attack + v.Growth_Attack * (1 + v.Bonus_Attack) end end -- 武器属性不用管 function BP_PlayerState:GrowthKillPoint() local Temp = 0 for _, v in pairs(self.Attributes) do Temp = Temp + v.Growth_KillPoint * (1 + v.Eco_KillPoint) end self.KillPoint.Current = self.KillPoint.Current + Temp self.KillPoint.Total = self.KillPoint.Total + Temp ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](self, 6) end -- 战斗力公式(没啥用,就仅显示) function BP_PlayerState:RefreshCombatPoint() local CombatPoint = 0 for _, v in pairs(self.Attributes) do CombatPoint = CombatPoint + v.Base_MaxHP / 250 + v.Base_Attack / 50 + v.Base_Defence / 4 + v.Adv_DefencePenetration * 3 + v.Adv_CriticalAttackRate * 20000 + v.Adv_CriticalAttack * 150 + v.Adv_FireAttack * 225 + v.Adv_DefencePenetrationPercent * 50000 + v.Adv_AdditionalAttack * 30000 + v.Adv_FinalAttack * 30000 + v.Growth_MaxHP * 500 + v.Growth_Attack * 2500 + v.Base_AttackSpeed * 2000 + v.Bonus_Attack * 5000 + v.Bonus_MaxHP * 10000 + v.Bonus_Defence * 5000 + v.Bonus_DamageReduction * 200000 + v.Eco_CoinPoint * 2000 + v.Eco_KillPoint * 2000 + v.Eco_Exp * 3000 + v.Eco_DropRate * 2000 + v.Bonus_CriticalAttack * 100000 + v.Bonus_FireAttack * 150000 + v.Growth_Kill_MaxHP * 1000 + v.Growth_Kill_Attack * 5000 end self.CombatPoint = math.ceil(CombatPoint) EventSystem:SendEvent(EventType.ServerOnCombatPointChanged, self.PlayerKey, self.CombatPoint) end -- 玩家造成伤害公式,InVal是反弹伤害 function BP_PlayerState:MakeDamage(InEnemy, InVal) --这个是敌人受到伤害加成 local EnemyAppendDamage = self:GetAdditionDamage() local Damage = 0 for _, v in pairs(self.Attributes) do Damage = Damage + (v.Base_Attack * (1 + v.Bonus_Attack)) * (1 + v.Adv_FireAttack * (1 + v.Bonus_FireAttack) + v.Adv_AdditionalAttack) * (1 + EnemyAppendDamage) * (1 + v.Adv_FinalAttack) end -- 每射击5次,下次射击必定暴击 if self:IsCurrentWeaponHasItem(11140) then local TheId = 11140 local AttackTimes = DropItemMap.SpecialFittingProperties[TheId][1].Times if self.SpecialThings[TheId] == nil then self.SpecialThings[TheId] = {} end if self.SpecialThings[TheId].Times ~= nil then if self.SpecialThings[TheId].Times < AttackTimes then self.SpecialThings[TheId].Times = self.SpecialThings[TheId].Times + 1 self.SpecialThings[TheId].CertainCriticalAttack = true else self.SpecialThings[TheId].Times = self.SpecialThings[TheId].Times - AttackTimes self.SpecialThings[TheId].CertainCriticalAttack = false -- 让下次射击暴击 end else self.SpecialThings[TheId].Times = 1 self.SpecialThings[TheId].CertainCriticalAttack = false end end --每次射击有25%概率造成2次伤害 local Val = 1 if self:IsCurrentWeaponHasItem(11440) and math.RandomValue(25) then Val = 2 end -- 射击有5%概率使敌人防御值降低30%,持续5秒 local TheId1 = 14240 if self:IsCurrentWeaponHasItem(TheId1) then local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self) if self.SpecialThings[TheId1] == nil then self.SpecialThings[TheId1] = {} self.SpecialThings[TheId1].ServerTime = ServerTime self.SpecialThings[TheId1].LimitServerTime = ServerTime else local LimitServerTime = self.SpecialThings[TheId1].ServerTime if self.SpecialThings[TheId1].ServerTime > LimitServerTime then if math.RandomValue(0.01 * DropItemMap.SpecialFittingProperties[TheId1][1].Probability) then InEnemy:SetDefenseScale(DropItemMap.SpecialFittingProperties[TheId1][1].Benefit.Value) self.SpecialThings[TheId1].LimitServerTime = DropItemMap.SpecialFittingProperties[TheId1][1].CoolDown + ServerTime end else self.SpecialThings[TheId1].ServerTime = ServerTime end end end if self:OnCriticalAttack() then local Multiply = 0 for _, v in pairs(self.Attributes) do Multiply = Multiply + (1 + v.Adv_CriticalAttack) * (1 + v.Bonus_CriticalAttack) end Damage = Damage * Multiply end if InVal == nil then InVal = 0 end return Damage * Val + InVal end -- private 计算是否暴击 function BP_PlayerState:OnCriticalAttack() local TheId = 11140 local ShouldCriticalAttack = self.SpecialThings[TheId] ~= nil and self.SpecialThings[TheId].CertainCriticalAttack or false local CriticalAttackPercent = 0 for _, v in pairs(self.Attributes) do CriticalAttackPercent = CriticalAttackPercent + v.Adv_CriticalAttackRate end local RandomVal = math.random() return RandomVal <= CriticalAttackPercent or ShouldCriticalAttack end -- 玩家防御穿透 function BP_PlayerState:DefencePenetrate() local Temp = 0 for _, v in pairs(self.Attributes) do Temp = Temp + v.Adv_DefencePenetration end return Temp end -- 玩家产生的伤害加成 function BP_PlayerState:GetAdditionDamage() return 0 end -- 减伤公式 function BP_PlayerState:InjuryReduction(InEnemy) -- local EnemyDefence = InEnemy:GetDefense() local EnemyDefencePercent = InEnemy.DamageReductionPercentage -- 伤害减免 local Temp = 0 for i, v in pairs(self.Attributes) do Temp = Temp + (v.Base_Defence * (1 + v.Bonus_Defence) - 0) * (1 - EnemyDefencePercent) end return Temp end -- 玩家收到的伤害 function BP_PlayerState:GetDamage(InEnemy, InNum) local EnemyDamage = self:InjuryReduction(InEnemy) local Temp = 0 for _, v in pairs(self.Attributes) do Temp = Temp + v.Bonus_DamageReduction end local Res = InNum * (1 - (EnemyDamage / (EnemyDamage + 1000))) * (1 - Temp) return Res end --反弹伤害 function BP_PlayerState:GetReverseDamage(InEnemy) local Ir = self:InjuryReduction(InEnemy) return self:MakeDamage(InEnemy) * (1 - Ir) end -- 根据数值进行 Reverse Damage function BP_PlayerState:GetReverseDamage(InEnemy, InNum) local Ir = self:InjuryReduction(InEnemy) local Damage = 0 local DamagePercent = 0 -- 计算反弹伤害 for i, v in pairs(self.Attributes) do Damage = v.Base_ReboundDamage + Damage DamagePercent = v.Base_ReboundDamagePercent + DamagePercent end return self:MakeDamage(InEnemy, Damage + InNum * DamagePercent) * (1 - Ir) end -- 处理护盾,返回具体受到的伤害 function BP_PlayerState:DealShield(InDamage) if self.Attributes[AttributeType.Base].Base_Shield > InDamage then self.Attributes[AttributeType.Base].Base_Shield = self.Attributes[AttributeType.Base].Base_Shield - InDamage return 0 else local Ret = InDamage - self.Attributes[AttributeType.Base].Base_Shield self.Attributes[AttributeType.Base].Base_Shield = 0 return Ret end end --吸血 function BP_PlayerState:SuckBlood(InDamage) local VampVal = 0 for _, v in pairs(self.Attributes) do VampVal = VampVal + v.Base_Vamp end return InDamage * (1 - 1 / (1 + VampVal)) end -- 闪避 function BP_PlayerState:Dodge() local Rate = 0 for _, v in pairs(self.Attributes) do Rate = Rate + v.Base_EvadeRate end return 1 - 1 / (1 + Rate) end -- 韧性 function BP_PlayerState:Tenacity() local Rate = 0 for _, v in pairs(self.Attributes) do Rate = Rate + v.Base_Toughness end return 1 - Rate end -- 每秒射速 function BP_PlayerState:ShootTimeEverSecond() local AttackSpeed, Rate = 0, 0 for _, v in pairs(self.Attributes) do Rate = Rate + v.Base_AttackIntervalReduction AttackSpeed = AttackSpeed + v.Base_AttackSpeed end return AttackSpeed / Rate end -- 每秒生命值 function BP_PlayerState:RecoverPlayerPawn() local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) local RecoverHp, RecoverHpPercent, bre, brep = 0, 0, 0, 0 for _, v in pairs(self.Attributes) do RecoverHp = RecoverHp + v.Base_RecoverHP RecoverHpPercent = RecoverHpPercent + v.Base_RecoverHPPercent bre = bre + v.Base_RecoverEnergy brep = brep + v.Base_RecoverEnergyPercent end UE.Log("[BP_PlayerState:RecoverPlayerPawn] PlayerKey: %d, Recover HP = %s, Recover HP Percent = %s", self.PlayerKey, tostring(RecoverHp), tostring(RecoverHpPercent)) if UE.IsValid(PlayerPawn) then self:RecoverPlayerCurHP(PlayerPawn, RecoverHp, RecoverHpPercent) self:RecoverPlayerCurEnergy(PlayerPawn, bre, brep) end end -- 每秒刷新的数据 function BP_PlayerState:AttributeAdditionPerSecond() --每秒杀敌点 local val, Shield = 0, 0 for _, v in pairs(self.Attributes) do val = val + v.Growth_KillPoint Shield = Shield + v.Growth_Shield end if val > 0 then self.KillPoint.Current = math.ceil(self.KillPoint.Current + val) self.KillPoint.Total = (self.KillPoint.Total + val) end self:Special_AddPerSecondProp(12440, 0) self:Special_AddPerSecondProp(12540, 0) -- 查看是否需要护盾,该值是 % if Shield > 0 then self:PropShield('Shield', Shield) end -- 每隔10秒,进入嗜血状态,该状态下吸血%达到100%,持续2秒 if self:IsCurrentWeaponHasItem(11340) then local TheId = 11340 if self.SpecialThings[TheId] == nil then self.SpecialThings[TheId] = {} self.SpecialThings[TheId].CurrentTime = 1 else self.SpecialThings[TheId].CurrentTime = self.SpecialThings[TheId].CurrentTime + 1 if self.SpecialThings[TheId].CurrentTime >= 10 then -- 此时启动即可 self.Attributes[AttributeType.WeaponSpecial].Base_Vamp = 1 EventSystem.SetTimer(self, function() self.Attributes[AttributeType.WeaponSpecial].Base_Vamp = 0 end, 2) end end end end -- 此处 Id 是护盾的意思 function BP_PlayerState:PropShield(InId, InValue) if self.SpecialThings[InId] == nil then self.SpecialThings[InId] = 0 end if self.SpecialThings[InId] < 10 then self.SpecialThings[InId] = self.SpecialThings[InId] + 1 else local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) local MaxHP = UGCPawnAttrSystem.GetHealthMax(Pawn) local AppendHealth = InValue * MaxHP self.Attributes[AttributeType.Base].Base_Shield = self.Attributes[AttributeType.Base].Base_Shield + AppendHealth end end -- 这是添加每秒的东西 function BP_PlayerState:Special_AddPerSecondProp(InId, InTime) if self:IsCurrentWeaponHasItem(InId) then if self.SpecialThings[InId] == nil then self.SpecialThings[InId] = 0 end if self.SpecialThings[InId] < InTime then self.SpecialThings[InId] = self.SpecialThings[InId] + 1 else local Val = DropItemMap.SpecialFittingProperties[InId][1].Benefit self:AddAttribute(Val.Type, Val.Value, true) self.SpecialThings[InId] = 0 end end end function BP_PlayerState:GetDroppingRate() local DropRate = 0 for i, v in pairs(self.Attributes) do DropRate = DropRate + v.Eco_DropRate end return DropRate end function BP_PlayerState:RecoverPlayerCurHP(Pawn, Value, Percent) Pawn:RecoverCurHP(Value, Percent) end function BP_PlayerState:RecoverPlayerCurEnergy(Pawn, Value, Percent) Pawn:RecoverCurEnergy(Value, Percent) end --server 增加或者减少金币 function BP_PlayerState:UpdateCoinPoint(InDelta) if self.CoinPoint.Current + InDelta < 0 then return false else if InDelta > 0 then self:AddCoinPoint(InDelta) else self.CoinPoint.Current = self.CoinPoint.Current + InDelta end return true end end ---生效范围:S,向上取整 function BP_PlayerState:AddCoinPointDirectly(InDelta) if InDelta <= 0 then return false end self.CoinPoint.Current = self.CoinPoint.Current + InDelta self.CoinPoint.Current = math.ceil(self.CoinPoint.Current) self.CoinPoint.Total = self.CoinPoint.Total + InDelta ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](self, 1) return true end ---生效范围:S,向上取整 function BP_PlayerState:AddTechPointDirectly(InDelta) local Delta = InDelta self.KillPoint.Current = self.KillPoint.Current + Delta self.KillPoint.Total = self.KillPoint.Total + Delta self.KillPoint.Current = math.ceil(self.KillPoint.Current) end ---生效范围:S,向上取整 function BP_PlayerState:AddCoinPoint(InDelta) local Temp = 0 for i, v in pairs(self.Attributes) do Temp = Temp + v.Eco_CoinPoint end local Delta = InDelta * (1 + Temp) self.CoinPoint.Current = self.CoinPoint.Current + Delta self.CoinPoint.Current = math.ceil(self.CoinPoint.Current) self.CoinPoint.Total = self.CoinPoint.Total + Delta -- 检查一下 ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](self, 1) end ---生效范围:S,向上取整 function BP_PlayerState:AddKillPoint(InDelta) local Temp = 0 for i, v in pairs(self.Attributes) do Temp = Temp + v.Eco_KillPoint end local Delta = InDelta * (1 + Temp) self.KillPoint.Current = self.KillPoint.Current + Delta self.KillPoint.Total = self.KillPoint.Total + Delta self.KillPoint.Current = math.ceil(self.KillPoint.Current) end -- 添加杀敌数(这个是真实数据) function BP_PlayerState:AddKillCount() self.KillCount.Total = self.KillCount.Total + 1 local Temp = 0 for i, v in pairs(self.Attributes) do Temp = Temp + v.Growth_Kill_Attack end self.Attributes[AttributeType.Base].Base_Attack = self.Attributes[AttributeType.Base].Base_Attack + Temp -- 执行 4 个 --local val = '击败' --for i, v in pairs(self.SpecialItemTimerHandles[val]) do -- print(string.format("[BP_PlayerState:AddKillCount] ItemID = %d", i)) -- self:Special_AddKillCount(val, i) --end end --添加特殊词条 支持杀敌,这是那种有最大射击数的 function BP_PlayerState:Special_AddKillCount(InCond, InId) --说明开启了 print(string.format("[BP_PlayerState:Special_AddKillCount] 执行到了")) if self.SpecialItemTimerHandles[InCond] == nil then return end local Prop = self.SpecialItemTimerHandles[InCond][InId] local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self) -- 是否可以操作 local CanDoOperation = false -- 说明当前还没开始 if Prop.Times == 0 then -- 记录开始的时间 self.SpecialItemTimerHandles[InCond][InId].Times = 1 CanDoOperation = true else local LastTime = self.SpecialItemTimerHandles[InCond][InId].LastTime local ContinueTime = DropItemMap.SpecialFittingProperties[InId][1].ContinueTime if ContinueTime == nil or ContinueTime == -1 then if Prop.Times <= DropItemMap.SpecialFittingProperties[InId][1].Times then CanDoOperation = true self.SpecialItemTimerHandles[InCond][InId].Times = Prop.Times + 1 end else if ServerTime - LastTime > ContinueTime then --重置 self.SpecialItemTimerHandles[InCond][InId].Times = 0 self:Special_AddKillCount(InId) else if Prop.Times <= DropItemMap.SpecialFittingProperties[InId][1].Times then CanDoOperation = true self.SpecialItemTimerHandles[InCond][InId].Times = Prop.Times + 1 end end end end self.SpecialItemTimerHandles[InCond][InId].LastTime = ServerTime if CanDoOperation then local ChineseType = DropItemMap.SpecialFittingProperties[InId][1].Benefit.Type -- 往这里面添加数据 print(string.format("[BP_PlayerState:Special_AddKillCount] Current Type = %s", ChineseType)) self.Attributes[AttributeType.WeaponSpecial][GlobalConfigs.AttributeNameTable[ChineseType]] = DropItemMap.SpecialFittingProperties[InId][1].Benefit.Value * self.SpecialItemTimerHandles[InCond][InId].Times end end --移除特殊词条 function BP_PlayerState:Special_RemoveKillCount(InId) local ChineseType = DropItemMap.SpecialFittingProperties[InId][1].Benefit.Type self.Attributes[AttributeType.WeaponSpecial][GlobalConfigs.AttributeNameTable[ChineseType]] = 0 table.remove(self.SpecialItemTimerHandles, InId) end -- Server function BP_PlayerState:SetLevelDirectly(NewLevel) self.Level = NewLevel ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](self, 7) EventSystem:SendEvent(EventType.ServerOnLevelAndExpChanged, self.PlayerKey, self.Level, self.CurExp, self:GetNeedExpByLevel(self.Level)) end -- Server function BP_PlayerState:AddExp(InDelta) -- 判断当前 Exp,改变当前传入的值 if InDelta < 0 then return end -- 限制一下最高等级 if self.Level >= 60 then return end -- 需要检查一下该值的变化 if self.BreachInfo.NeedBreach then return end -- 数值 local Temp = 0 for _, v in pairs(self.Attributes) do Temp = Temp + v.Eco_Exp end -- 当前产生的 Exp local Val = self.CurExp + InDelta * (1 + Temp) Val = Val + self.NextAddExp; if Val <= 0 then return end local NeedExp = self:GetNeedExpByLevel(self.Level) while Val >= NeedExp do self.Level = self.Level + 1 Val = Val - NeedExp if self.Level % 10 == 0 then self.BreachInfo.NeedBreach = true self.BreachInfo.InBreachProgress = false UnrealNetwork.RepLazyProperty(self, "BreachInfo") -- 此时设置 加入之后需要添加的量 self.NextAddExp = Val Val = 0 end if self.Level % 8 == 0 then local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey) UnrealNetwork.CallUnrealRPC(PC, PC, "ClientRPC_TriggerGuide", 15) end if self.Level == 3 then local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey) UnrealNetwork.CallUnrealRPC(PC, PC, "ClientRPC_TriggerGuide", 31) end NeedExp = self:GetNeedExpByLevel(self.Level) local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) self:RecoverPlayerCurHP(PlayerPawn, 0, 1.0) self:RecoverPlayerCurEnergy(PlayerPawn, 0, 1.0) UnrealNetwork.CallUnrealRPC_Multicast(PlayerPawn, "Client_MulticastRPC_PlayEffect", GameDataManager.GetEffectInstanceId(), 35, PlayerPawn, nil, 0, EEffectSpawnLocationType.Attach) end ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](self, 7) self.CurExp = Val EventSystem:SendEvent(EventType.ServerOnLevelAndExpChanged, self.PlayerKey, self.Level, self.CurExp, self:GetNeedExpByLevel(self.Level)) end -- S, 杀敌后根据杀敌威力值增加威力值 function BP_PlayerState:GrowthKillAttack() local Temp = 0 for i, v in pairs(self.Attributes) do Temp = Temp + v.Growth_Kill_Attack end self.Attributes[AttributeType.Base].Base_Attack = self.Attributes[AttributeType.Base].Base_Attack + Temp end --- Server 重铸武器的属性 ---@return bool 是否重铸成功 function BP_PlayerState:ResetWeapon(InWeaponId) -- 移除武器的所有属性,然后再给武器添加对应这么多的属性 local FindIndex = 0 for i = 1, table.getCount(self.OwnerWeapons) do if self.OwnerWeapons[i].WeaponId == InWeaponId then FindIndex = i break end end if FindIndex == 0 then UE.Log("[BP_PlayerState:ResetWeapon] 找不到对应武器:%d", InWeaponId) return false end --先看一下有多少条 local PlusPropCount = #self.OwnerWeapons[FindIndex].NativeProps.Plus self.OwnerWeapons[FindIndex].NativeProps.Plus = {} local bSuccess = self:AddNewEntry(InWeaponId, PlusPropCount) local PlayerCharacter = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) if PlayerCharacter ~= nil and PlayerCharacter.WeaponActor ~= nil then if PlayerCharacter.WeaponActor.CurrentWeaponId == InWeaponId then self:OnWeaponAttributeChanged(InWeaponId) end end return bSuccess end function BP_PlayerState:OnRep_Attributes() if GameDataManager and GameDataManager.GetLocalPlayerState() == self then EventSystem:SendEvent(EventType.OnPlayerAttributeChanged, self.Attributes) if self.Attributes[AttributeType.Base] and self.Attributes[AttributeType.Base].Base_Attack then EventSystem:SendEvent(EventType.OnPlayerBaseAttackValueChanged, self.PlayerKey, self.Attributes[AttributeType.Base].Base_Attack) end end end function BP_PlayerState:OnRep_CoinPoint() if GameDataManager and GameDataManager.GetLocalPlayerState() == self then if EventSystem and EventType then EventSystem:SendEvent(EventType.PlayerCoinPointChanged, self.CoinPoint.Current) end end end function BP_PlayerState:OnRep_KillPoint() if GameDataManager and GameDataManager.GetLocalPlayerState() == self then EventSystem:SendEvent(EventType.PlayerKillPointChanged, self.KillPoint.Current) end end function BP_PlayerState:OnRep_OwnerWeapons() -- 通知更新 武器 if EventSystem ~= nil and EventType ~= nil then EventSystem:SendEvent(EventType.UpdateAllWeapon, self.OwnerWeapons, self.PlayerKey) end log_tree_dev("PlayerKey = "..tostring(self.PlayerKey) .. " ,OwnerWeapons = ", self.OwnerWeapons) end --这个是更新所有背包中的武器 function BP_PlayerState:OnRep_TotalWeaponCount(InOldCount) if GameDataManager.GetLocalPlayerState() == nil then return end if self.TotalWeaponCount == InOldCount then return end if self.PlayerKey ~= GameDataManager.GetLocalPlayerState().PlayerKey then return end --进行通知 EventSystem:SendEvent(EventType.RefreshWeapons, self.TotalWeaponCount) end function BP_PlayerState:OnRep_InheritItems() if EventSystem ~= nil and EventType ~= nil then EventSystem:SendEvent(EventType.PlayerInheritItemsChanged, self.InheritItems) end end function BP_PlayerState:OnRep_BreachInfo() UE.Log("[BP_PlayerState:OnRep_BreachInfo] NeedBreach=%s, InBreachProgress=%s", tostring(self.BreachInfo.NeedBreach), tostring(self.BreachInfo.InBreachProgress)) EventSystem:SendEvent(EventType.ToggleBreachButton, self:GetNeedShowBreachButton(), self.PlayerKey) end -- 获取是否能生成突破怪 function BP_PlayerState:GetCanSpawnBreachMonster() return self.BreachInfo.NeedBreach == true and self.BreachInfo.InBreachProgress == false end -- 获取是否需要显示突破按钮 function BP_PlayerState:GetNeedShowBreachButton() return self.BreachInfo.NeedBreach == true and self.BreachInfo.InBreachProgress == false end -- Server 应用等级改变 function BP_PlayerState:OnChangedLevel() -- 依次添加 local IsZero = self.Level % 10 == 0 local BreachLevel = 0 if IsZero then BreachLevel = self.Level / 10 end self.Attributes[AttributeType.Base].Base_MaxHP = self.Attributes[AttributeType.Base].Base_MaxHP + LevelRewards.EachLevel.Health self.Attributes[AttributeType.Base].Base_Attack = self.Attributes[AttributeType.Base].Base_Attack + LevelRewards.EachLevel.Attack self.Attributes[AttributeType.Base].Base_Defence = self.Attributes[AttributeType.Base].Base_Defence + LevelRewards.EachLevel.Defence if BreachLevel <= 0 then return end -- Apply Attributes -- TODO 阉割版 --self.Attributes[AttributeType.Base].Base_MaxHP = self.Attributes[AttributeType.Base].Base_MaxHP + Tables.BreachRewards[BreachLevel].Health --self.Attributes[AttributeType.Base].Base_Attack = self.Attributes[AttributeType.Base].Base_Attack + Tables.BreachRewards[BreachLevel].Attack --self.Attributes[AttributeType.Base].Eco_CoinPoint = self.Attributes[AttributeType.Base].Eco_CoinPoint + Tables.BreachRewards[BreachLevel].Bonus_Gold --self.Attributes[AttributeType.Base].Base_AttackSpeed = self.Attributes[AttributeType.Base].Base_AttackSpeed + Tables.BreachRewards[BreachLevel].Attack_Speed --self.Attributes[AttributeType.Base].Adv_FireAttack = self.Attributes[AttributeType.Base].Adv_FireAttack + Tables.BreachRewards[BreachLevel].Attack_Damage -- -- 应用提升等级奖励 local Func = function(InLevel, InVal) if InLevel <= 1 then return 0 end return LevelRewards.Rewards[InLevel - 1][InVal] end self.Attributes[AttributeType.Base].Base_MaxHP = self.Attributes[AttributeType.Base].Base_MaxHP + LevelRewards.Rewards[BreachLevel].Health - Func(BreachLevel, 'Health') self.Attributes[AttributeType.Base].Base_Attack = self.Attributes[AttributeType.Base].Base_Attack + LevelRewards.Rewards[BreachLevel].Attack - Func(BreachLevel, 'Attack') self.Attributes[AttributeType.Base].Base_AttackSpeed = self.Attributes[AttributeType.Base].Base_AttackSpeed + LevelRewards.Rewards[BreachLevel].AttackSpeed - Func(BreachLevel, 'AttackSpeed') self.Attributes[AttributeType.Base].Growth_Kill_Attack = self.Attributes[AttributeType.Base].Growth_Kill_Attack + 1 self:ApplyAttributes() end -- function BP_PlayerState:GetNeedExpByLevel(InLevel) return math.ceil((100 + 113.103448 * (InLevel - 1)) / (InLevel <= 10 and 2 or 1)) end -- function BP_PlayerState:OnRep_AttackRange() -- 通知更新 if EventSystem ~= nil and EventType ~= nil then EventSystem:SendEvent(EventType.AttackRangeChanged, self.AttackRange) end end --创建一个新的武器并添加到列表中 function BP_PlayerState:AddWeapon(InId) UE.Log("[BP_PlayerState:AddWeapon] 开始添加武器,Id = %d", InId) if not self:HasAuthority() then return end -- 判断是否有对应武器 if self:FindWeaponExist(InId) then UE.Log("[BP_PlayerState:AddWeapon] 能找到对应武器 Id: %d", InId) -- 提示添加词条 self:AddNewEntry(InId, 2) else UE.Log("[BP_PlayerState:AddWeapon] 找不到对应武器,需要重新添加") self:AddNewWeaponInternal(InId) end --找到对应的, local PlayerCharacter = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) if PlayerCharacter ~= nil and PlayerCharacter.WeaponActor ~= nil then PlayerCharacter.WeaponActor:SetCurrentWeapon(InId) end -- 阉割版 --ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](self, 9) -- 服务端 UE.Log("[BP_PlayerState:AddWeapon] 当前的Id = %d", InId) self:OnWeaponAttributeChanged(InId) end -- 移除武器但是不移除配件 function BP_PlayerState:RemoveWeapon(InWeaponId) if self:FindWeaponById(InWeaponId) == nil then UE.Log("[BP_PlayerState:RemoveWeapon] 没有当前武器:%d,请检查", InWeaponId) return end -- 将武器身上的所有配件都移掉,再删除武器 local bSuccess = self:RemoveAllWeaponFittings(InWeaponId) if bSuccess then -- 从背包中删除武器 local Index = self:GetWeaponIndex(InWeaponId) table.remove(self.OwnerWeapons, Index) else UE.Log("[BP_PlayerState:RemoveWeapon] 移除配件失败,请检查原因") end end --这里面保存着小手枪 function BP_PlayerState:AddNewWeaponInternal(InWeaponId) -- 判断类型 local WeaponType = GameDataManager.GetWeaponType(InWeaponId) if WeaponType == nil then UE.Log("[BP_PlayerState:AddNewWeaponInternal] WeaponData is nil") return end local ItemData = { WeaponId = InWeaponId, Type = WeaponType, -- 这个是固有属性 NativeProps = { -- 这个是武器默认属性 Common = 0, -- 开始拥有的高级属性 Plus = { }, }, --这条是后面添加的词条属性 Properties = { }, --配件,存放的是Id 的数组 Fittings = { }, --- 武器的配件等级: --- 一旦有一个格子没有配件,那就 == 0 --- 有[五个初级,五个中级)的时候就是初级 == 1 --- 有[五个中级,五个高级)的时候就是中级 == 2 --- 有[五个高级,五个超级)的时候就是高级 == 3 --- 有[五个超级]的时候就是超级 == 4 FittingLevel = 0, } local MainIndex, Val if WeaponType == EWeaponClassType.WT_Pistol then else MainIndex, Val = RandomWeaponProperty(self) local Pro = {MainType = MainIndex, Value = Val } table.insert(ItemData.NativeProps.Plus, Pro) end self:RemovePistol() table.insert(self.OwnerWeapons, ItemData) -- 更新背包中武器数量 if self.OwnerWeapons[1].Type ~= EWeaponClassType.WT_Pistol then self.TotalWeaponCount = table.getCount(self.OwnerWeapons) end end --移除小手枪 function BP_PlayerState:RemovePistol() local RemoveIndex = 0 for i = 1, #self.OwnerWeapons do if self.OwnerWeapons[i].Type == EWeaponClassType.WT_Pistol then RemoveIndex = i break end end -- 当不是小手枪的时候,那就移除 if RemoveIndex ~= 0 then UE.Log("[BP_PlayerState:RemovePistol] 移除了小手枪") table.remove(self.OwnerWeapons, RemoveIndex) end end function BP_PlayerState:FindWeaponExist(InWeaponId) for i = 1, #self.OwnerWeapons do local Weapon = self.OwnerWeapons[i] if Weapon.WeaponId == InWeaponId then return true end end return false end function BP_PlayerState:FindWeaponById(InWeaponId) for i = 1, #self.OwnerWeapons do if self.OwnerWeapons[i].WeaponId == InWeaponId then return self.OwnerWeapons[i] end end return nil end function BP_PlayerState:GetWeaponIndex(InWeaponId) for i = 1, #self.OwnerWeapons do if self.OwnerWeapons[i].WeaponId == InWeaponId then return i end end return -1 end function BP_PlayerState:AddNewEntry(InWeaponId, InCount) -- 如果是已经添加过了的,那就添加词条,如果是小手枪,那就不添加,返回 local WeaponType = GameDataManager.GetWeaponType(InWeaponId) if WeaponType == nil or WeaponType == EWeaponClassType.WT_Pistol then UE.Log("[BP_PlayerState:AddNewEntry] Data is nil") return false end UE.Log("[BP_PlayerState:AddNewEntry] 开始给 %d 添加 %d 条词条", InWeaponId, InCount) for _ = 1, InCount do local MainIndex, Val = RandomWeaponProperty(self) --在 Properties 中添加 local ItemData = { MainType = MainIndex, Value = Val } --输出一下添加的属性 UE.Log("[BP_PlayerState:AddNewEntry] 添加的属性为:%s, 值为:%s", Tables.WeaponPropertyConfig[ItemData.MainType].PropName, tostring(Val)) table.insert(self:FindWeaponById(InWeaponId).NativeProps.Plus, ItemData) end return true end -- 添加到对应武器上配件 function BP_PlayerState:AddWeaponFittingItem(InWeaponId, InItemId) UE.Log("[BP_PlayerState:AddWeaponFittingItem] 开始添加新的配件 %d", InItemId) if GetItemGrantTypeById(InItemId) ~= EDropItemSet.WeaponParts then return false end local WeaponInfo = GameDataManager.GetWeaponConstructDataByID(InWeaponId) if WeaponInfo == nil then UE.Log("[BP_PlayerState:AddWeaponFittingItem] WeaponData is nil") return false end local WeaponType = WeaponInfo.WeaponType UE.Log("[BP_PlayerState:AddWeaponFittingItem] 找到武器后开始添加") --查看是否有其他的 if self:FindTargetFittingItemExist(InWeaponId, InItemId) then --这个是必须成功的 UE.Log("[BP_PlayerState:AddWeaponFittingItem] 开始移除原先的配件") self:RemoveFittingItemByItemType(InWeaponId, GetItemTypeByItemId(InItemId)) end self:AddFittingItemInternal(InWeaponId, InItemId) -- 添加完成之后需要检查一些当前数量够不够,对于五个初级,五个中级 self:CheckFittingLevel(InWeaponId) print(string.format("[BP_PlayerState:AddWeaponFittingItem] Weapon Type = %d", WeaponType)) self:OnWeaponAttributeChanged(InWeaponId) end --找到 Target 武器类型 function BP_PlayerState:FindTargetFittingItemExist(InWeaponId, InFittingItemId) UE.Log("[BP_PlayerState:FindTargetFittingItemExist] 开始寻找对应类型的配件") local WeaponInfo = self:FindWeaponById(InWeaponId) if WeaponInfo == nil then return false end local ItemType = GetItemTypeByItemId(InFittingItemId) --查找对应配件 for i = 1, #WeaponInfo.Fittings do local FittingItem = WeaponInfo.Fittings[i] if ItemType == GetItemTypeByItemId(FittingItem) then --说明有,进行移除操作 return true end end return false end function BP_PlayerState:RemoveAllWeaponFittings(InWeaponId) local Weapon = self:FindWeaponById(InWeaponId) if Weapon == nil then UE.Log("[BP_PlayerState:RemoveAllWeaponFittings] 没有当前武器: %d,请检查一下", InWeaponId) return false end local Count = table.getCount(Weapon.Fittings) for i = 1, Count do local FittingId = Weapon.Fittings[i] self:RemoveFittingItemByItemType(InWeaponId, GetItemTypeByItemId(FittingId)) end return true end -- 通过武器配件类型移除武器配件 function BP_PlayerState:RemoveFittingItemByItemType(InWeaponId, InItemType) UE.Log("[BP_PlayerState:RemoveFittingItemByItemType] 开始通过物品Type: %d 在 %d 武器中进行移除", InItemType, InWeaponId) local RemovePos = 0 local RemoveItemId = 0 for i = 1, #self:FindWeaponById(InWeaponId).Fittings do local FittingItem = self:FindWeaponById(InWeaponId).Fittings[i] -- 这里面只存Id,Count == 1 --这说明找到了 if GetItemTypeByItemId(FittingItem) == InItemType then UE.Log("[BP_PlayerState:RemoveFittingItemByItemType] 找到对应选项") RemovePos = i RemoveItemId = FittingItem end end if RemovePos == 0 then UE.Log("[BP_PlayerState:RemoveFittingItemByItemType] 没有找到要移除的配件") end --添加到背包中 local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey) local RemoveCount = PlayerController:UpdateItemMap(RemoveItemId, 1) if RemoveCount == 1 then -- 说明添加成功 UE.Log('[BP_PlayerState:RemoveFittingItemByItemType] 添加成功,开始移除') table.remove(self:FindWeaponById(InWeaponId).Fittings, RemovePos) else UE.Log('[BP_PlayerState:RemoveFittingItemByItemType] 无法添加成功,请检查原因') end end function BP_PlayerState:GetWeaponByFittingItemId(InFittingItemId) local WeaponType = GetItemWeaponTypeByItemId(InFittingItemId) for i = 1, #self.OwnerWeapons do local Weapon = self.OwnerWeapons[i] if Weapon.Type == WeaponType then return Weapon end end return nil end -- 所有武器上是否有对应Item function BP_PlayerState:IsItemInWeapon(InFittingItemId) for i = 1, #self.OwnerWeapons do for j = 1, #self.OwnerWeapons[i].Fittings do if InFittingItemId == self.OwnerWeapons[i].Fittings[j] then return true end end end return false end -- 查找当前武器上是否有对应配件 function BP_PlayerState:IsItemInWeapon(InWeaponId, InFittingItemId) local Weapon = nil for i = 1, #self.OwnerWeapons do if self.OwnerWeapons[i].WeaponId == InWeaponId then Weapon = self.OwnerWeapons[i] break end end if Weapon ~= nil then for i = 1, #Weapon.Fittings do if Weapon.Fittings[i] == InFittingItemId then return true end end end return false end -- 当前武器上是否有对应配件 function BP_PlayerState:IsCurrentWeaponHasItem(InFittingItemId) local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey) if PlayerPawn.WeaponActor ~= nil and UE.IsValid(PlayerPawn.WeaponActor) then return self:IsItemInWeapon(PlayerPawn.WeaponActor.CurrentWeaponId, InFittingItemId) end return false end --实施具体的添加武器配件操作 function BP_PlayerState:AddFittingItemInternal(InWeaponId, InFittingItemId) UE.Log("[BP_WeaponPawnBase:AddFittingItemInternal] 添加配件") local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey) local RemoveCount = PlayerController:UpdateItemMap(InFittingItemId, -1) if RemoveCount == -1 then local Weapon = self:FindWeaponById(InWeaponId) UE.Log("[BP_WeaponPawnBase:AddFittingItemInternal] Weapon Id = %d", InWeaponId) if Weapon == nil then UE.Log("[BP_WeaponPawnBase:AddFittingItemInternal] 找不到 Weapon") end table.insert(Weapon.Fittings, InFittingItemId) else UE.Log("[BP_WeaponPawnBase:AddFittingItemInternal] 无法从背包中移除,请检查原因") end end function BP_PlayerState:FindWeaponByWeaponType(InWeaponType) for i = 1, #self.OwnerWeapons do if self.OwnerWeapons[i].Type == InWeaponType then return self.OwnerWeapons[i] end end return nil end -- 从背包中移除 function BP_PlayerState:RemoveWeaponFittingItem(InFittingItemId) self:RemoveFittingItemByItemType(self:GetWeaponByFittingItemId(InFittingItemId).WeaponId, GetItemTypeByItemId(InFittingItemId)) self:OnWeaponAttributeChanged(self:GetWeaponByFittingItemId(InFittingItemId).WeaponId) end -- 检查并判断当前的level,然后跟之前的level进行比较,然后增加或者删除高级属性词条 function BP_PlayerState:CheckFittingLevel(InWeaponId) local FittingList = self:FindWeaponById(InWeaponId).Fittings local OldFittingLevel = self:FindWeaponById(InWeaponId).FittingLevel -- 找到 WeaponType local ThisWeaponType = GameDataManager.GetWeaponType(InWeaponId) if ThisWeaponType == nil then UE.Log("[BP_PlayerState:CheckFittingLevel] Data is nil") return end local NewFittingLevel --在这里刷新一下 if #FittingList ~= 5 then NewFittingLevel = 0 else local Lowest = 10 local bIsSelfWeaponFitting = true for i = 1, #FittingList do local Item = FittingList[i] -- 找到最低的 local Quality = GetItemQualityLevel(Item) local WeaponType = GetItemWeaponTypeByItemId(Item) if bIsSelfWeaponFitting and WeaponType ~= ThisWeaponType then bIsSelfWeaponFitting = false end if Quality < Lowest then Lowest = Quality end end if bIsSelfWeaponFitting then -- 说明之前都是对的,此时添加新的词条 NewFittingLevel = Lowest + 1 else NewFittingLevel = 0 end end self:FindWeaponById(InWeaponId).FittingLevel = NewFittingLevel -- 需要更新的就是 New - Old self:UpdateFittingLevel(InWeaponId, NewFittingLevel - OldFittingLevel, NewFittingLevel) end function BP_PlayerState:UpdateFittingLevel(InWeaponId, InCount, InNowLevel) UE.Log("[BP_PlayerState:UpdateFittingLevel] 要添加的武器 Id:%d, 数量:%d", InWeaponId, InCount) if InCount == 0 then UE.Log("[BP_PlayerState:UpdateFittingLevel] 添加物品并不能导致变化") return end local Props = self:FindWeaponById(InWeaponId).Properties if InCount < 0 then for _ = 1, -InCount do table.remove(self:FindWeaponById(InWeaponId).Properties, #Props) end else for _ = 1, InCount do local MainIndex, Val = RandomWeaponProperty(self) local ItemData = { MainType = MainIndex, Value = Val } table.insert(self:FindWeaponById(InWeaponId).Properties, ItemData) end end end function BP_PlayerState:GetWeaponCount() return #self.OwnerWeapons end -- SC function BP_PlayerState:GetWeapons() return self.OwnerWeapons end function BP_PlayerState:SetGameEndArchiveData(InData) self.GameEndSavedArchiveData = InData; end function BP_PlayerState:AddAttribute(InType, InValue, IsChinese) local Val = InType if IsChinese then Val = GlobalConfigs.AttributeNameTable[InType] end self.Attributes[AttributeType.Base][Val] = self.Attributes[AttributeType.Base][Val] + InValue self:ApplyAttributes() end function BP_PlayerState:AddWeaponAttribute(InType, InValue) end function BP_PlayerState:FindPistolExist() for i = 1, #self.OwnerWeapons do if self.OwnerWeapons[i].Type == EWeaponClassType.WT_Pistol then return true end end return false end function BP_PlayerState:GetWeaponFittingsById(InWeaponId) local Weapon = self:FindWeaponById(InWeaponId) if Weapon == nil then UE.Log("[BP_PlayerState:GetWeaponFittingsById] 无法找到 %d 的武器", InWeaponId) else return Weapon.Fittings end end --当开火的时候 function BP_PlayerState:OnShot() local Temp1, Temp2 = 0, 0 for i, v in pairs(self.Attributes) do Temp1 = Temp1 + v.Growth_Fire_MaxHP Temp2 = Temp2 + v.Growth_Fire_Attack end self.Attributes[AttributeType.Base].Base_MaxHP = self.Attributes[AttributeType.Base].Base_MaxHP + Temp1 self.Attributes[AttributeType.Base].Base_Attack = self.Attributes[AttributeType.Base].Base_Attack + Temp2 -- 造成伤害提升1点防御穿透,最高75点 if self:IsCurrentWeaponHasItem(13440) then -- 防御穿透 if self.Attributes[AttributeType.WeaponSpecial].Adv_DefencePenetration < 75 then self.Attributes[AttributeType.WeaponSpecial].Adv_DefencePenetration = self.Attributes[AttributeType.WeaponSpecial].Adv_DefencePenetration + 1 end else self.Attributes[AttributeType.WeaponSpecial].Adv_DefencePenetration = 0 end -- 射击有5%的概率获得5000金币,如成功获得金币则进入10秒冷却期 if self:IsCurrentWeaponHasItem(14440) then local TheId = 14440 local Rate = DropItemMap.SpecialFittingProperties[TheId][1].Probability / 100 local Cooldown = DropItemMap.SpecialFittingProperties[TheId][1].CoolDown local Func = DropItemMap.SpecialFittingProperties[TheId][1].Func self:RateBenefit(TheId, Rate, Cooldown, Func) end -- 射击有5%的概率获得150点杀敌点,如成功获得杀敌点则进入10秒冷却期 if self:IsCurrentWeaponHasItem(14140) then local TheId = 14140 local Rate = DropItemMap.SpecialFittingProperties[TheId][1].Probability / 100 local Cooldown = DropItemMap.SpecialFittingProperties[TheId][1].CoolDown local Func = DropItemMap.SpecialFittingProperties[TheId][1].Func self:RateBenefit(TheId, Rate, Cooldown, Func) end -- 每1%的暴击伤害%加成会提高3%的射击伤害% if self:IsCurrentWeaponHasItem(14540) then local Attack = 0 for i, v in pairs(self.Attributes) do Attack = Attack + v.Bonus_CriticalAttack end self.Attributes[AttributeType.WeaponSpecial].Adv_FireAttack = self.Attributes[AttributeType.WeaponSpecial].Adv_FireAttack + Attack * 3 else self.Attributes[AttributeType.WeaponSpecial].Adv_FireAttack = 0 end -- 射击会造成5%威力值的射击伤害% if self:IsCurrentWeaponHasItem(14340) then -- 获取威力值 local Attack = 0 for _, v in pairs(self.Attributes) do Attack = Attack + v.Base_Attack end self.Attributes[AttributeType.WeaponSpecial].Adv_FireAttack = Attack * 0.05 + self.Attributes[AttributeType.WeaponSpecial].Adv_FireAttack else self.Attributes[AttributeType.WeaponSpecial].Adv_FireAttack = 0 end -- 射击有10%的概率进入极速状态,该状态下射速提升100%,持续5s if self:IsCurrentWeaponHasItem(11240) then local TheId = 11240 local Rate = DropItemMap.SpecialFittingProperties[TheId][1].Probability / 100 local Cooldown = DropItemMap.SpecialFittingProperties[TheId][1].CoolDown self:QuickSpeedState(TheId, Rate, Cooldown) end end function BP_PlayerState:QuickSpeedState(InId, Percent, CoolDown) if self.SpecialThings[InId] == nil then self.SpecialThings[InId] = {} local CurrentRealTime = KismetSystemLibrary.GetGameTimeInSeconds(self) self.SpecialThings[InId].ServerTime = CurrentRealTime self.SpecialThings[InId].LimitServerTime = CurrentRealTime end if self.SpecialThings[InId].ServerTime < self.SpecialThings[InId].LimitServerTime then return end local RandomPercent = math.random() if RandomPercent < Percent then -- 说明成功了 self.Attributes[AttributeType.WeaponSpecial].Base_AttackSpeed = 1 EventSystem.SetTimer(self, function() self.Attributes[AttributeType.WeaponSpecial].Base_AttackSpeed = 0 end, CoolDown) end end function BP_PlayerState:RateBenefit(InId, Percent, CoolDown, InFunc) local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self) if self.SpecialThings[InId] == nil then self.SpecialThings[InId] = {} self.SpecialThings[InId].ServerTime = ServerTime self.SpecialThings[InId].LimitServerTime = ServerTime end if self.SpecialThings[InId].ServerTime < self.SpecialThings[InId].LimitServerTime then return end local RandomPercent = math.random() if RandomPercent < Percent then -- 说明成功了 InFunc(self) self.SpecialThings[InId].LimitServerTime = ServerTime + CoolDown end self.SpecialThings[InId].ServerTime = ServerTime end --获取练功房多加的怪物数量 function BP_PlayerState:GetMonsterSpawnAdditionCount() local Temp = 0 for i, v in pairs(self.Attributes) do Temp = Temp + v.Eco_HangupRoomMonsterNum end return Temp end -- 获得练功房刷怪效率 function BP_PlayerState:GetMonsterRefreshEfficiency() local Temp = 0 for i, v in pairs(self.Attributes) do Temp = Temp + v.Eco_HangupRoomRefreshRate end return Temp end -- 获取所有武器上的装备 function BP_PlayerState:GetAllEquipment() local OutData = {} for i, v in ipairs(self.OwnerWeapons) do for c, d in pairs(v.Fittings) do table.insert(OutData, d) end end return OutData end return BP_PlayerState;