UGCProjects/GZJ/Script/Blueprint/Player/BP_PlayerState.lua
2025-01-08 22:46:12 +08:00

2093 lines
71 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---@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] -- 这里面只存IdCount == 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;