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

1746 lines
57 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_PlayerController_C:BP_UGCPlayerController_C
--Edit Below--
UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom')
UGCGameSystem.UGCRequire('Script.Common.ue_struct_custom')
UGCGameSystem.UGCRequire('Script.Global.Global')
local BP_PlayerController = {
IsRunOnServer = false,
IsDead = false,
IsDeadInArena = false,
HasSelectedBaseAttribute = false,
HasSelectedGameDifficulty = false,
HasSelectedDefaultWeapon = false,
CameraManager = nil,
BackpackComp = nil, --背包组件
---@type table<ESkillSlot, table<ESkillName, SkillLevel>>
ActiveSkillNameList = {}, --技能映射表
ResourceGrade = 1, -- 资源等级
SealInfo = {
-- 次数
Times = 1,
-- 击杀数该数据会依次增加然后在50的时候如果没有点击封印就一直是50当点击封印的时候该数值重置死了之后也不会改变
KillCount = 0,
-- 怪物是否存活,如果不存活说明没有挑战成功,需要继续挑战,即显示挑战按钮
IsMonsterAlive = false,
},
-- 背包数据
ItemMap = {
[0] = {}, --枪口
[1] = {}, --握把
[2] = {}, --弹夹
[3] = {}, --枪托
[4] = {}, --准镜
[5] = {}, --技能书
[6] = {}, --重铸石
[7] = {}, --置换石
},
ItemActorClass = nil,
AutoPickIntervalTime = {
Current = 0,
LimitTime = 1,
};
IsAutoRightNowPick = false;
------------- 拾取操作 -------------
-- 场景中的物品
AllItemActors = {
[ETeleportType.InHangupRoom] = {},
[ETeleportType.InArena] = {},
};
-- 拾取距离
PickupDistance = 1000;
--自动拾取距离
AutoPickupDistance = 200;
-- 初始化的界面
InitialWidget = nil;
};
function BP_PlayerController:GetReplicatedProperties()
return
"ActiveSkillNameList",
"ResourceGrade",
"ItemMap"
end
function BP_PlayerController:GetAvailableServerRPCs()
return
"ServerRPC_SelectGameDifficulty",
--"ServerRPC_SelectBaseAttribute",
--"ServerRPC_SelectDefaultWeapon",
--"ServerRPC_AddWeapon",
"ServerRPC_AddItemsByThisID",
"ServerRPC_DiscardItems",
-- "ClientRPC_ShowGeneralNoticeTips",
-- "ClientRPC_ShowNoticeTips",
-- "Client_MulticastRPC_PlayWeaponFireEffect",
-- "ClientRPC_BuyTechSucceed",
"ServerRPC_BuyTech",
"ServerRPC_ChallengeSucceed",
-- 背包
"ServerRPC_GenerateItem",
"ServerRPC_SellItem",
"ServerRPC_ResetItem",
"ServerRPC_GenerateAllItem",
"ServerRPC_OnBreach",
-- "ClientRPC_ShowPickUpItems",
--"ClientRPC_UpdateBackpackItemMap",
--武器
"ServerRPC_AddFittingItem",
"ServerRPC_ChangeCurrentWeaponId",
"ServerRPC_ResetWeapon", -- 重铸
--释放技能
"ServerRPC_GiveSkill",
"ServerRPC_OnCastSkill",
-- "ClientRPC_SetupSkillButton",
-- "ClientRPC_SetSkillCD",
--突破
"ServerRPC_StartSpawnBreachMonster",
-- "ClientRPC_SetBreachButtonVisible",
-- 封印
"ServerRPC_StartSpawnSealMonster",
"ServerRPC_ApplyRewards",
-- "ClientRPC_SetSealRewards",
-- "ClientRPC_SetSealButtonVisible",
-- 传承
"ServerRPC_Inherit",
-- "ClientRPC_UpdateInherit",
-- 资源等级
"ServerRPC_SetResourceGrade",
-- 背包
--"ClientRPC_ReplicatePawn",
--新手引导
-- "ClientRPC_TriggerGuide",
-- "ClientRPC_RemoveGuide",
"ServerRPC_RecordForceGuideInfo",
-- 生成练功房掉落物
"ServerRPC_AddExerciseItems",
-- "ClientRPC_SpawnExerciseDropItem",
-- "ClientRPC_ShowInitialPanel",
-- "Client_UpdateArchiveData",
"ServerRPC_CloseInitialNotice",
-- GM命令
"ServerRPC_GM_AddItems",
"ServerRPC_GM_AddCoinPoint",
"ServerRPC_GM_AddTechPoint",
"ServerRPC_GM_ChangeTimeScale"
;
end
function BP_PlayerController:ReceiveBeginPlay()
BP_PlayerController.SuperClass.ReceiveBeginPlay(self)
self.IsRunOnServer = UGCGameSystem.IsServer()
-- 不要自动切换相机
self.bNeedResetCameraOnPossess = false
self.ItemActorClass = UE.LoadClass(BPClassPath.PickupItemClass)
if self.IsRunOnServer then
self.OnCharacterDeadDelegate:Add(self.ServerOnCharacterDead, self)
self.PlayerControllerRespawnedDelegate:Add(self.ServerOnRespawn, self)
else
self.PlayerControllerRespawnedDelegate:Add(self.ClientOnRespawn, self)
self.OnCharacterDeadDelegate:Add(self.ClientOnCharacterDead, self)
GameDataManager:SetLocalPlayerController(self)
local CommandManager = require('Script.Manager.CommandQueneManager')
CommandManager:AddInitCommand(self, self.Client_Init)
end
end
function BP_PlayerController:ReceiveEndPlay()
if self.IsRunOnServer then
self.PlayerControllerRespawnedDelegate:Remove(self.ServerOnRespawn, self)
self.OnCharacterDeadDelegate:Remove(self.ServerOnCharacterDead, self)
else
self.OnCharacterDeadDelegate:Remove(self.ClientOnCharacterDead, self)
self.PlayerControllerRespawnedDelegate:Remove(self.ClientOnRespawn, self)
end
BP_PlayerController.SuperClass.ReceiveEndPlay(self)
end
--function BP_PlayerController:Possess(InPawn)
-- -- 同步一下 Pawn
-- self.SuperClass:Possess(InPawn)
-- --UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_ReplicatePawn", InPawn)
--end
function BP_PlayerController:ReceiveTick(DeltaTime)
if not self.IsRunOnServer then
if self.bHasInitClient == nil and self.PlayerKey ~= 0 and self.IsDead == false then
local CommandManager = require('Script.Manager.CommandQueneManager')
CommandManager.bPlayerCtrlReady = true
self.bHasInitClient = true
UE.Log("[BP_PlayerController] *** UGCPlayerController Tick Init Ready PlayerKey:%s", self.PlayerKey)
end
end
if self:HasAuthority() == false then
-- 自动拾取
self.AutoPickIntervalTime.Current = self.AutoPickIntervalTime.Current + DeltaTime
if self.AutoPickIntervalTime.Current > self.AutoPickIntervalTime.LimitTime then
self.AutoPickIntervalTime.Current = self.AutoPickIntervalTime.Current - self.AutoPickIntervalTime.LimitTime
self:RequestPickupNearbyItems(false)
end
end
end
function BP_PlayerController:Client_Init()
UE.Log("[BP_PlayerController] Client_Init PlayerKey=%d", self.PlayerKey);
GameDataManager:SetLocalPlayerController(self)
GameDataManager:SetLocalPlayerState(self.PlayerState)
-- 不要自动切换相机
self.bAutoManageActiveCameraTarget = false
-- 初始化摄像机
self:SetupCamera(0.2)
-- 初始化UI
local UIManager = require('Script.Manager.UIManager')
UIManager:Init()
require('Script.Manager.NewPlayerGuideManager')
NewPlayerGuideManager:Init()
local GameStage = UGCGameSystem.GameState.GameStage
if GameStage > EGameStage.WaitForPlayer then
if self.InitialWidget then
self.InitialWidget:SetVisibility(ESlateVisibility.Collapsed)
end
end
if GameStage == EGameStage.GameReady then
if UGCGameSystem.GameState.GameReadyStage >= 0 and UGCGameSystem.GameState.GameReadyStageRemainTime > 0 then
for _, Config in pairs(Tables.GameReadyStageConfig) do
if Config.Stage == UGCGameSystem.GameState.GameReadyStage then
UIManager:ShowPanel(Config.TriggerUI)
break
end
end
end
end
self.CheckForceGuidePanelHandle = EventSystem.SetTimerLoop(self, function()
local GameState = UGCGameSystem.GameState
if GameState and GameState.GameDifficulty > 0 then
local PS = GameDataManager.GetLocalPlayerState()
if PS then
if PS:GetNeedTriggerForceGuide() then
if PS.ForceGuideInfo ~= nil and PS.ForceGuideInfo.CurStepIndex > 0 then
local ForceGuidePanel = UIManager:GetPanel(EUIType.ForceGuide)
if ForceGuidePanel and UE.IsValid(ForceGuidePanel) then
ForceGuidePanel:InitByRecordedInfo(PS.ForceGuideInfo)
end
end
end
EventSystem.StopTimer(self.CheckForceGuidePanelHandle)
end
end
end, 0.5)
end
function BP_PlayerController:ServerOnRespawn(InPlayerController)
if InPlayerController == self then
UE.Log("[BP_PlayerController:ServerOnRespawn] PlayerKey=%d", self.PlayerKey)
local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey)
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
if PlayerPawn and UE.IsValid(PlayerPawn) and UE.IsValid(PlayerState) then
UGCPawnSystem.SetIsInvincible(PlayerPawn, true)
EventSystem.SetTimer(self, function()
local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(self.PlayerKey)
PlayerPawn:OnPlayerRespawned(PlayerState, self)
UGCPawnSystem.SetIsInvincible(PlayerPawn, false)
end, 1.0)
end
end
end
function BP_PlayerController:ClientOnRespawn(InPlayerController)
if InPlayerController == self then
UE.Log("[BP_PlayerController:ClientOnRespawn] PlayerKey=%d", self.PlayerKey)
GameDataManager:SetLocalPlayerController(self)
self.IsDead = false
end
end
function BP_PlayerController:ServerOnCharacterDead(InCharacter)
if InCharacter.PlayerKey == self.PlayerKey then
UE.Log("[BP_PlayerController:ServerOnCharacterDead] PlayerKey=%d", self.PlayerKey)
end
end
function BP_PlayerController:ClientOnCharacterDead(InCharacter)
if InCharacter.PlayerKey == self.PlayerKey then
UE.Log("[BP_PlayerController:ClientOnCharacterDead] PlayerKey=%d", self.PlayerKey)
self.bHasInitClient = nil
self.IsDead = true
CommandQueneManager.bHasInit = false
CommandQueneManager.bPlayerCtrlReady = false
CommandQueneManager:RemoveInitCommand(InCharacter)
----记录强引导的当前步数
local PS = GameDataManager.GetLocalPlayerState()
if PS and PS:GetNeedTriggerForceGuide() then
local ForceGuidePanel = UIManager:GetPanel(EUIType.ForceGuide)
if ForceGuidePanel and UE.IsValid(ForceGuidePanel) and ForceGuidePanel.CurStepIndex > 0 then
UnrealNetwork.CallUnrealRPC(self, self, "ServerRPC_RecordForceGuideInfo", self.PlayerKey,
ForceGuidePanel.CurStepIndex, ForceGuidePanel.CurValidStepIndex, ForceGuidePanel.bIsInStepProgress, ForceGuidePanel.StepPendingList)
end
end
UIManager:DestroyAllPanel(true)
UIManager:ShowNotice(ECustomNoticeType.RespawnNotice, 5)
NewPlayerGuideManager:RemoveAllGuide()
end
end
function BP_PlayerController:SetupCamera(DelayTime)
local CameraManagerClass = require('Script.Manager.CameraManager')
self.CameraManager = CameraManagerClass.New(self)
EventSystem.SetTimer(self,
function()
self:GetCameraManager():SetupOverlookCamera()
end, DelayTime)
end
function BP_PlayerController:GetCameraManager()
return self.CameraManager
end
function BP_PlayerController:OnRep_ResourceGrade()
if EventSystem and GameDataManager.GetLocalPlayerController() == self then
EventSystem:SendEvent(EventType.OnResourceGradeChanged, self.ResourceGrade)
end
end
function BP_PlayerController:ServerRPC_RecordForceGuideInfo(PlayerKey, CurStepIndex, ValidStepIndex, bIsInStepProgress, StepPendingList)
if not self:HasAuthority() then return end
local PS = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
if PS then
PS.ForceGuideInfo = {
CurStepIndex = CurStepIndex,
ValidStepIndex = ValidStepIndex,
bIsInStepProgress = bIsInStepProgress,
StepPendingList = StepPendingList,
}
UnrealNetwork.RepLazyProperty(PS, "ForceGuideInfo")
end
end
function BP_PlayerController:ServerRPC_SelectGameDifficulty(Index)
if self.HasSelectedGameDifficulty then return end
if self:HasAuthority() then
UE.Log("[BP_PlayerController:ServerRPC_SelectGameDifficulty] Index = " .. tostring(Index))
if UGCGameSystem.GameState.PlayerDifficultySelection[Index] == nil then
UGCGameSystem.GameState.PlayerDifficultySelection[Index] = 1
else
UGCGameSystem.GameState.PlayerDifficultySelection[Index] = UGCGameSystem.GameState.PlayerDifficultySelection[Index] + 1
end
self.HasSelectedGameDifficulty = true
end
end
function BP_PlayerController:ServerRPC_SelectBaseAttribute(Index)
if self.HasSelectedBaseAttribute then return end
if self:HasAuthority() then
local AttributeInfo = {
PlayerKey = UGCPawnAttrSystem.GetPlayerKeyInt64(self:GetPlayerCharacterSafety()),
AttributeIndex = Index,
}
table.insert(UGCGameSystem.GameState.PlayerAttributeSelection, AttributeInfo)
self.HasSelectedBaseAttribute = true
end
end
function BP_PlayerController:ServerRPC_SelectDefaultWeapon(ID)
if self.HasSelectedDefaultWeapon then
UE.LogError("[BP_PlayerController:ServerRPC_SelectDefaultWeapon] HasSelected")
return
end
if self:HasAuthority() then
UE.Log("[BP_PlayerController:ServerRPC_SelectDefaultWeapon] ID = " .. tostring(ID))
self:ServerRPC_AddWeapon(ID, self.PlayerKey)
self.HasSelectedDefaultWeapon = true
end
end
-- 添加武器唯一入口
function BP_PlayerController:ServerRPC_AddWeapon(ID, InPlayerKey)
if self:HasAuthority() then
if InPlayerKey ~= self.PlayerKey then
return
end
print(string.format('[BP_PlayerController:ServerRPC_AddWeapon] 添加武器'))
if InPlayerKey ~= nil then
UE.Log("[BP_PlayerController:ServerRPC_AddWeapon] 开始添加武器, Id = %d, PlayerKey = %d", ID, InPlayerKey)
end
local ControlledCharacter = self:GetPlayerCharacterSafety()
if not UE.IsValid(ControlledCharacter) then
return
end
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
local ControlledWeapon = ControlledCharacter.WeaponActor
--新添加的武器 Id 将会被显示
if UE.IsValid(ControlledWeapon) then
ControlledWeapon:SetWeaponID(ID)
PlayerState:AddWeapon(ID)
else
-- 这说明武器里面啥都没有
AsyncLoadTools:LoadObject(BPClassPath.WeaponBaseActor,
function(WeaponClass)
if UE.IsValid(self) and UE.IsValid(WeaponClass) and UE.IsValid(PlayerState) then
ControlledWeapon = UGCGameSystem.SpawnActor(self, WeaponClass, ControlledCharacter:K2_GetActorLocation(), ControlledCharacter:K2_GetActorRotation(), VectorHelper.ScaleOne(), nil)
ControlledCharacter.WeaponActor = ControlledWeapon
ControlledCharacter.OnWeaponSpawnedDelegate(ControlledCharacter)
ControlledWeapon:SetWeaponID(ID)
ControlledWeapon:SetOwnerCharacter(ControlledCharacter)
PlayerState:AddWeapon(ID)
end
end)
end
end
end
--改变当前武器
function BP_PlayerController:ServerRPC_ChangeCurrentWeaponId(InWeaponId)
UE.Log("[BP_PlayerController:ServerRPC_ChangeCurrentWeaponId] 开始执行改变当前武器操作")
local ControlledCharacter = self:GetPlayerCharacterSafety()
local WC = ControlledCharacter:GetWeaponComponent()
if WC ~= nil then
if WC:FindWeaponById(InWeaponId) ~= nil then
WC:SetCurrentWeapon(InWeaponId)
else
UE.Log("[BP_PlayerController:ServerRPC_ChangeCurrentWeaponId] 找不到该武器,请检查一下")
end
end
end
function BP_PlayerController:ServerRPC_ResetWeapon(InWeaponId)
UE.Log("[BP_PlayerController:ServerRPC_ResetWeapon] Weapon Id = %d", InWeaponId)
-- 移除石头
local ItemData = {
ItemID = 31000,
ItemCount = -1
}
local bSuccess = self:UpdateBackpackItem(ItemData)
if not bSuccess then
UE.Log("[BP_PlayerController:ServerRPC_ResetWeapon] 移除重铸石失败,请检查一下")
return
end
-- 移除成功了,开始重铸玩家武器属性
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
bSuccess = PlayerState:ResetWeapon(InWeaponId)
if not bSuccess then
local Item = {
ItemID = 31000,
ItemCount = 1
}
bSuccess = self:UpdateBackpackItem(Item)
if not bSuccess then
UE.Log("[BP_PlayerController:ServerRPC_ResetWeapon] 添加重铸石失败,请检查原因")
end
end
end
function BP_PlayerController:ServerRPC_GenerateItem(InItemList)
-- 先生成一个
self:GenerateItem(InItemList)
end
-- 添加物品的时候
function BP_PlayerController:ServerRPC_AddItemsByThisID(InThisIDList)
if self:HasAuthority() then
local GameState = UGCGameSystem.GameState
if not UE.IsValid(GameState) then
UE.Log("[ServerRPC_AddItemsByThisID] invalid gamestate")
return
end
local ThisIDList = InThisIDList
local HadItemIds = {}
for i, v in pairs(GameState.GlobalDropItemActorList) do
table.insert(HadItemIds, i)
end
log_tree('Common GlobalDropItemActorList = ', HadItemIds)
log_tree('Common ThisIDList = ', ThisIDList)
local Func = function(InGameState, InThisIdList)
local PendingActorThisIDs = {}
local AddItemIds = {}
local LogStr = "[ServerRPC_AddItemsByThisID] Add: "
for _, InThisID in pairs(InThisIdList) do
local ItemActor = InGameState.GlobalDropItemActorList[InThisID]
if UE.IsValid(ItemActor) and ItemActor.bIsPicking == false then
local ItemID = ItemActor:GetItemID()
local ItemCount = ItemActor:GetItemCount()
ItemActor:SetIsPicking(true)
-- 检查是否添加进去了
local AddCount = self:UpdateItemMap(ItemID, ItemCount)
-- 当添加数量或者移除数量跟原先的一样的时候才会销毁
if AddCount == ItemActor:GetItemCount() then
LogStr = LogStr .. string.format("{ItemID = %d, Count = %d},", ItemID, AddCount)
table.insert(PendingActorThisIDs, InThisID)
table.insert(AddItemIds, ItemID)
end
end
end
UE.Log(LogStr)
return PendingActorThisIDs, AddItemIds
end
local PendingActorThisIDs, AddItemIds = Func(GameState, ThisIDList)
UE.Log("[ServerRPC_AddItemsByThisID] PendingActorThisIDs Length = %d", #PendingActorThisIDs)
for _, ThisID in pairs(PendingActorThisIDs) do
local ThisActor = GameState.GlobalDropItemActorList[ThisID]
if UE.IsValid(ThisActor) and ThisActor.bIsPicking then
ThisActor:K2_DestroyActor()
else
print(string.format('[BP_PlayerController:ServerRPC_AddItemsByThisID] 无法找到 This ID = %d', ThisID))
end
GameState.GlobalDropItemActorList[ThisID] = nil
end
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_ShowPickUpItems", AddItemIds)
end
end
-- 往武器上添加配件
function BP_PlayerController:ServerRPC_AddFittingItem(InWeaponId, InFittingItemId)
UE.Log("[BP_PlayerController:ServerRPC_AddFittingItem] 添加配件")
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
PlayerState:AddWeaponFittingItem(InWeaponId, InFittingItemId)
end
function BP_PlayerController:ServerRPC_RemoveFittingItem(InFittingItemId)
UE.Log("[BP_PlayerController:ServerRPC_RemoveFittingItem] 开始执行")
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
PlayerState:RemoveWeaponFittingItem(InFittingItemId)
end
-- Server 该生成仅生成在玩家周围
function BP_PlayerController:CreateItem(InPlayer, InItemData, IsFromDiscard)
print(string.format('[BP_PlayerController:CreateItem] 执行'))
if InPlayer == nil then
InPlayer = self:GetPlayerCharacterSafety()
end
-- TODO
local PlayerVec = VectorHelper.ToLuaTable(InPlayer:K2_GetActorLocation())
--local DropPos = VectorHelper.Sub(PlayerVec, { X = 0, Y = 0, Z = 0 })
local DropPos = PlayerVec
log_tree("PlayerVec = ", PlayerVec)
UE.Log("DiscardItemId: %d, DiscardCount = %d", InItemData.ItemID, InItemData.ItemCount)
if self.Pawn.IsInArena then
print(string.format('[BP_PlayerController:CreateItem] 在场景中丢弃'))
EventSystem:SendEvent(EventType.SpawnDropItemByID, InItemData.ItemID, InItemData.ItemCount, DropPos, InPlayer:K2_GetActorRotation(), self.PlayerKey, IsFromDiscard)
else
-- 练功房通知生成一个
print(string.format('[BP_PlayerController:CreateItem] 在练功房丢弃'))
local ItemData = {
ItemID = InItemData.ItemID,
Count = InItemData.ItemCount
}
self:RequestExerciseDropItem(self.PlayerKey, DropPos, VectorHelper.RotZero(), ItemData, false, IsFromDiscard)
end
end
-- 丢弃物品
function BP_PlayerController:ServerRPC_DiscardItems(InDiscardItems)
if self:HasAuthority() then
print(string.format('[BP_PlayerController:ServerRPC_DiscardItems] 执行'))
local GameState = UGCGameSystem.GameState
if not UE.IsValid(GameState) then
UE.Log("[ServerRPC_DiscardItems] invalid gamestate")
return
end
local LogStr = "[ServerRPC_DiscardItems] Discard: "
local DiscardItemIDs = {}
for ItemID, Count in pairs(InDiscardItems) do
-- 看一下此时的type
local DiscardCount = self:UpdateItemMap(ItemID, Count)
-- 检查一下 Discard
UE.Log('[BP_PlayerController:ServerRPC_DiscardItems] Discard Count = %d', DiscardCount)
if DiscardCount == Count then
LogStr = LogStr .. string.format("{ItemID = %d, Count = %d},", ItemID, Count)
if DiscardCount < 0 then
DiscardCount = -DiscardCount
end
DiscardItemIDs[ItemID] = DiscardCount
else
print(string.format('[BP_PlayerController:ServerRPC_DiscardItems] 丢弃物品数量不对,本应该丢弃:%d实际上丢弃%d', Count, DiscardCount))
end
end
UE.Log(LogStr)
for DiscardItemID, DiscardCount in pairs(DiscardItemIDs) do
local ItemData = {
ItemID = DiscardItemID,
ItemCount = DiscardCount
}
self:CreateItem(self.Pawn, ItemData, true)
end
LogStr = "[ServerRPC_DiscardItems] Result ItemMap = "
local CurItemMap = self:GetItemMap()
for ItemType, ItemList in pairs(CurItemMap) do
for i, v in pairs(ItemList) do
LogStr = LogStr .. string.format("{ItemType = %d, ItemID = %d, Count = %d},", ItemType, i, v)
end
end
UE.Log(LogStr)
end
end
--function BP_PlayerController:ClientRPC_UpdateBackpackItemMap(InItemMap)
-- if self:HasAuthority() then return end
--
-- --此处需要知道死亡之后自己是谁,每次获取即可
-- self:ClientUpdateItemMap(InItemMap)
--end
function BP_PlayerController:ClientRPC_UpdateWeaponById(InWeaponType)
end
-- Server, 直接输入{ItemID, ±ItemCount},返回添加或者移除的是否是这些东西
function BP_PlayerController:UpdateBackpackItem(InData)
local GameState = UGCGameSystem.GameState
if not UE.IsValid(GameState) then
return
end
local DiscardCount = self:UpdateItemMap(InData.ItemID, InData.ItemCount)
local bSuccess = DiscardCount == InData.ItemCount
return bSuccess
end
-- Server
function BP_PlayerController:UpdateMoney(InDelta)
local ControlledCharacter = self:GetPlayerCharacterSafety()
if not UE.IsValid(ControlledCharacter) then
return false
end
local PlayerKey = UGCPawnAttrSystem.GetPlayerKeyInt64(ControlledCharacter)
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
return PlayerState:UpdateCoinPoint(InDelta)
end
function BP_PlayerController:ServerRPC_SellItem(InData)
if InData.ItemCount > 0 then
InData.ItemCount = -InData.ItemCount
end
local bSuccess = self:UpdateBackpackItem(InData)
--售卖东西
if bSuccess then
local Money = math.abs(Tables.QualityInfo[GetItemQualityLevel(InData.ItemID)][2] * InData.ItemCount)
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
bSuccess = PlayerState ~= nil and UE.IsValid(PlayerState) and PlayerState:AddCoinPointDirectly(Money)
if bSuccess then
UE.Log("[BP_PlayerController:ServerRPC_SellItem] 售卖 Item: Id = %d 成功", InData.ItemID)
end
else
UE.Log("[BP_PlayerController:ServerRPC_SellItem] 售卖 Item: Id = %d 失败", InData.ItemID)
end
end
--执行置换
function BP_PlayerController:ServerRPC_ResetItem(InData)
--这是要移除的,说明开始转换了
UE.Log('[BP_PlayerController:ServerRPC_ResetItem] 开始 Rest Item')
--if GetItemQualityLevel(InData.ItemID) >= EQualityType.Super then
-- -- 再做一次限制
-- return
--end
--开始移除
local TheCount = InData.ItemCount
InData.ItemCount = - TheCount
local bSuccess = self:UpdateBackpackItem(InData)
if bSuccess then
-- 开始添加物品,如果添加不下了,就生成一个
if GetItemGrantTypeById(InData.ItemID) == EDropItemSet.SkillBooks then
local SkillId = GetSkillIdByItemId(InData.ItemID)
local Skills = {}
for i = 9, 32 do
if SkillId == i then
else
table.insert(Skills, i)
end
end
local Skill = Skills[math.random(1, table.getCount(Skills))]
Skill = 20000 + Skill * 100 + InData.ItemID % 100
local ItemData = {
ItemID = Skill,
ItemCount = TheCount
}
bSuccess = self:UpdateBackpackItem(ItemData)
else
local TempArr1 = { 1, 2, 3, 4, 5 }
local TempArr2 = { 1, 2, 3, 4, 5, 6 }
local CurrentItemType = GetItemTypeByItemId(InData.ItemID) + 1
local CurrentWeaponType = GetItemWeaponTypeByItemId(InData.ItemID)
local RandomNum = math.random(1, 4)
table.remove(TempArr1, CurrentItemType)
InData.ItemID = InData.ItemID - CurrentItemType * 1000 + TempArr1[RandomNum] * 1000
table.remove(TempArr2, CurrentWeaponType)
RandomNum = math.random(1, 5)
InData.ItemID = InData.ItemID - CurrentWeaponType * 100 + TempArr2[RandomNum] * 100
InData.ItemCount = TheCount
bSuccess = self:UpdateBackpackItem(InData)
end
if bSuccess then
local ItemData = {
ItemID = 32000,
ItemCount = - TheCount
}
self:UpdateBackpackItem(ItemData)
end
end
end
function BP_PlayerController:ClientRPC_ShowGeneralNoticeTips(InText, ShowAlert, ShowTime)
if self:HasAuthority() then return end
UIManager:ShowGeneralNotice(InText, ShowAlert, ShowTime)
end
function BP_PlayerController:ClientRPC_ShowNoticeTips(InNoticeType, ...)
if self:HasAuthority() then return end
UIManager:ShowNotice(InNoticeType, ...)
end
function BP_PlayerController:Client_MulticastRPC_PlayWeaponFireEffect()
if self:HasAuthority() then return end
local ControlledCharacter = self:GetPlayerCharacterSafety()
if UE.IsValid(ControlledCharacter) then
local ControlledWeapon = ControlledCharacter.WeaponActor
if ControlledWeapon then
ControlledWeapon:PlayFireEffect()
end
end
end
--- 购买科技
function BP_PlayerController:ServerRPC_BuyTech(TechID)
if self:HasAuthority() then
local TargetPlayerState = self:GetCurPlayerState()
if TargetPlayerState.TechBuyNum[TechID] ~= nil then
if Tables.Tech[TechID].bLimit and Tables.Tech[TechID].LimitNum <= TargetPlayerState.TechBuyNum[TechID] then
UE.Log("BP_PlayerController_Fun_" .. "ServerRPC_BuyTech_" .. "BugFailure")
return
end
local NeedKillPoint = Tables.Tech[TechID].KillingPoints(TargetPlayerState.TechBuyNum[TechID] + 1)
local Temp = 0
for i, v in pairs(TargetPlayerState.Attributes) do
Temp = Temp + v.KillPoint_Cost
end
NeedKillPoint = NeedKillPoint * (1 + Temp)
if TargetPlayerState.KillPoint.Current >= NeedKillPoint then
TargetPlayerState.KillPoint.Current = TargetPlayerState.KillPoint.Current - NeedKillPoint
TargetPlayerState.TechBuyNum[TechID] = TargetPlayerState.TechBuyNum[TechID] + 1
Tables.Tech[TechID].ChangeTechParam(self)
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_BuyTechSucceed", TechID, TargetPlayerState.TechBuyNum[TechID])
else
NoticeTipsTools.ServerGeneralNoticeTips(self.PlayerKey, "科技点不足", true)
end
end
end
end
function BP_PlayerController:ClientRPC_BuyTechSucceed(TechID, BuyNum)
EventSystem:SendEvent(EventType.PlayerBuyTechSucceed, TechID, BuyNum)
end
function BP_PlayerController:ServerRPC_ChallengeSucceed(ChallengeInfoKey, PlayerKey, ChallengeMonsterType, MonsterLevel, bSkipCheckCD)
--TODO:检测是否该挑战在CD中
if Tables.ChallengeInfo[ChallengeInfoKey] == nil then
UE.Log("[BP_PlayerController:ServerRPC_ChallengeSucceed] [Error] invalid ChallengeInfoKey")
return
end
local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
local NowTime = UGCGameSystem.GameState.GameDuration
if not bSkipCheckCD then
local LastChallengeTime = TargetPlayerState.ChallengeMonsterTime[ChallengeInfoKey].LastChallengeTime
local CoolingTime = TargetPlayerState.ChallengeMonsterTime[ChallengeInfoKey].CoolingTime
if NowTime - LastChallengeTime < CoolingTime then return end
end
TargetPlayerState.ChallengeMonsterTime[ChallengeInfoKey].LastChallengeTime = NowTime
local TargetSpawner = UGCGameSystem.GameState:GetSpawnerByPlayerKey(PlayerKey)
if UE.IsValid(TargetSpawner) then
TargetSpawner:StartSpawnChallengeMonster(ChallengeMonsterType, MonsterLevel)
NoticeTipsTools.ServerGeneralNoticeTips(PlayerKey, "挑战怪已生成在练功房,请尽快击败获取奖励!", true, 4.0)
end
end
--------------------------------------------- 技能相关逻辑 ----------------------------------------------------
function BP_PlayerController:ServerRPC_GiveSkill(SkillName, SkillSlot, SkillLevel)
UE.Log("[BP_PlayerController:ServerRPC_GiveSkill] [%s] [%s] GiveSkill:%d, Slot:%s, Level:%s", self.PlayerKey, self.PlayerName, SkillName, tostring(SkillSlot), tostring(SkillLevel))
--- OldSkillId == -1: 失败出错
--- OldSkillId == 0: 当前是空插槽
--- OldSkillId > 0: 当前是空插槽
local OldSkillId = self:GiveSkill(SkillName, SkillSlot, SkillLevel)
if SkillLevel == nil then
return
end
if OldSkillId == -1 then
print(string.format('[BP_PlayerController:ServerRPC_GiveSkill] 添加错误'))
elseif OldSkillId == 0 then
-- 说明是空白插槽
if SkillLevel == nil then
return
end
local InSkillId = 20000 + SkillName * 100 + SkillLevel * 10
local AddItemCount = self:UpdateItemMap(InSkillId, -1)
if AddItemCount == -1 then
print(string.format('[BP_PlayerController:ServerRPC_GiveSkill] 添加好啦'))
else
print(string.format('[BP_PlayerController:ServerRPC_GiveSkill] 添加失败'))
end
else
-- 说明是替换技能
-- 塞回背包
local InSkillId = 20000 + SkillName * 100 + SkillLevel * 10
local AddItemCount = self:UpdateItemMap(InSkillId, -1)
if AddItemCount == -1 then
AddItemCount = self:UpdateItemMap(OldSkillId, 1)
if AddItemCount == 1 then
print(string.format('[BP_PlayerController:ServerRPC_GiveSkill] 成功啦~'))
else
-- 检查背包是否满了
if self:IsBackpackFull(EItemType.SkillBook) then
-- 丢到地面上
self:CreateItem(nil, { ItemID = OldSkillId, ItemCount = 1 })
else
print(string.format('[BP_PlayerController:ServerRPC_GiveSkill] 存在问题,请检查一下'))
end
print(string.format('[BP_PlayerController:ServerRPC_GiveSkill] 存在问题,请检查一下'))
end
else
-- 检查背包是否满了
if self:IsBackpackFull(EItemType.SkillBook) then
-- 丢到地面上
self:CreateItem(nil, { ItemID = OldSkillId, ItemCount = 1 })
else
print(string.format('[BP_PlayerController:ServerRPC_GiveSkill] 存在问题,请检查一下'))
end
end
end
end
function BP_PlayerController:ClientRPC_SetupSkillButton(SkillName, SkillSlot, SkillLevel)
EventSystem:SendEvent(EventType.OnSetupSkillButton, SkillName, SkillSlot, SkillLevel)
end
function BP_PlayerController:GiveSkillList(SkillNameList)
if (not (self.Pawn and UE.IsValid(self.Pawn))) then
UE.LogError("[BP_PlayerController:GiveSkillList] self.Pawn == nil")
return
end
if SkillNameList == nil then
return
end
self.Pawn:GiveSkillWithSkillNameList(SkillNameList)
end
function BP_PlayerController:GiveSkill(SkillName, SkillSlot, SkillLevel)
if (not (self.Pawn and UE.IsValid(self.Pawn))) then
UE.LogError("[BP_PlayerController:GiveSkill] self.Pawn == nil")
return -1
end
if SkillName == nil or SkillName == ESkillName.Default then
UE.LogError("[BP_PlayerController:GiveSkill] invalid SkillName")
return -1
end
for i, v in pairs(self.ActiveSkillNameList) do
print(string.format('[BP_PlayerController:GiveSkill] Slot: %d, SkillName: %d, SkillLevel: %d', i, v.SkillName, v.SkillLevel))
end
for Slot, SkillInfo in pairs(self.ActiveSkillNameList) do
if SkillInfo.SkillName == SkillName and SkillInfo.SkillLevel == SkillLevel then
UE.LogError("[BP_PlayerController:GiveSkill] Has Same Skill")
return -1
end
end
return self.Pawn:GiveSkill(SkillName, SkillSlot, SkillLevel)
end
---@param SkillSlot ESkillSlot
function BP_PlayerController:ClientOnCastSkill(SkillSlot)
UE.Log("[Skill] [%s] [%s] ClientOnCastSkill:%s", self.PlayerKey, self.PlayerName, SkillSlot)
UnrealNetwork.CallUnrealRPC(self, self, "ServerRPC_OnCastSkill", SkillSlot)
end
function BP_PlayerController:ServerRPC_OnCastSkill(SkillSlot)
UE.Log("[Skill] [%s] [%s] ServerRPC_OnCastSkill:%s", self.PlayerKey, self.PlayerName, SkillSlot)
local Pawn = self:GetPlayerCharacterSafety()
if UE.IsValid(Pawn) then
Pawn:TryActiveSkillBySlot(SkillSlot)
end
end
function BP_PlayerController:ClientRPC_SetSkillCD(Slot, CDDuration)
-- 更改CD状态
UE.Log("[Skill] ClientRPC_SetSkillCD Slot:%s Duration:%f", Slot, CDDuration)
EventSystem:SendEvent(EventType.PlayerSkillCDTriggered, Slot, CDDuration)
end
-- 获取空的机能插槽
function BP_PlayerController:GetEmptySlots()
local Slots = { ESkillSlot.Slot1, ESkillSlot.Slot2, ESkillSlot.Slot3, }
local NeedRemoveSlots = {}
if table.getCount(self.ActiveSkillNameList) > 0 then
for i, v in pairs(self.ActiveSkillNameList) do
for j = 1, #Slots do
if i == Slots[j] then
table.insert(NeedRemoveSlots, j)
end
end
end
end
if #NeedRemoveSlots > 0 then
--for i = 1, #NeedRemoveSlots do
-- print(string.format('[BP_PlayerController:GetEmptySlots] 移除的index = %d', NeedRemoveSlots[i]))
--end
for i = 1, #NeedRemoveSlots do
table.remove(Slots, NeedRemoveSlots[#NeedRemoveSlots - i + 1])
end
end
return Slots
end
-- 获取主动技能
function BP_PlayerController:GetInitiativeSkillSlots()
local Slots = {}
for i, v in pairs(self.ActiveSkillNameList) do
for j = 1, 3 do
if i == j then
table.insert(Slots, i)
end
end
end
return Slots
end
function BP_PlayerController:GetNearEmptySlot()
local EmptySlots = self:GetEmptySlots()
if #EmptySlots == 0 then
return 0
end
return EmptySlots[1]
end
function BP_PlayerController:IsFullInitiativeSkills()
return self:GetEmptySlots() == 0
end
--------------------------------------------- 新手引导相关 ---------------------------------------------
function BP_PlayerController:ClientRPC_TriggerGuide(ConfigID)
if NewPlayerGuideManager then
NewPlayerGuideManager:TriggerGuide(ConfigID)
end
end
function BP_PlayerController:ClientRPC_RemoveGuide(ConfigID)
if NewPlayerGuideManager then
NewPlayerGuideManager:RemoveGuide(ConfigID)
end
end
--------------------------------------------- 突破相关逻辑 ----------------------------------------------------
function BP_PlayerController:ClientRPC_SetBreachButtonVisible(IsShow)
EventSystem:SendEvent(EventType.ToggleBreachButton, IsShow)
end
function BP_PlayerController:ClientRPC_SetSealButtonVisible(IsShow)
EventSystem:SendEvent(EventType.ShowSealButton, IsShow)
end
function BP_PlayerController:ServerRPC_StartSpawnBreachMonster(RewardWeaponID, InLevel)
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
if UE.IsValid(PlayerState) == false or PlayerState:GetCanSpawnBreachMonster() == false then
return
end
local TargetSpawner = UGCGameSystem.GameState:GetSpawnerByPlayerKey(self.PlayerKey)
if UE.IsValid(TargetSpawner) == false then
return
end
TargetSpawner:StartSpawnBreachMonster(RewardWeaponID, InLevel)
end
--------------------------------------------- 封印 ---------------------------------------------
-- 增加封印击杀数
function BP_PlayerController:AddSealKillCount()
-- 阉割版
--if self.SealInfo.KillCount + 1 >= SealTables.MultiCount then
-- -- 执行显示封印按钮,如果当前有封引怪或者显示按钮,那么就不进行操作
-- if not self.SealInfo.IsMonsterAlive then
-- UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_SetSealButtonVisible", true)
-- end
--else
-- self.SealInfo.KillCount = self.SealInfo.KillCount + 1
--end
end
function BP_PlayerController:ServerRPC_StartSpawnSealMonster()
local TargetSpawner = UGCGameSystem.GameState:GetSpawnerByPlayerKey(self.PlayerKey)
if UE.IsValid(TargetSpawner) == false then
return
end
TargetSpawner:StartSpawnSeal(self)
NoticeTipsTools.ServerGeneralNoticeTips(self.PlayerKey, "封印怪已生成在练功房,请尽快击败获取奖励!", true, 4.0)
end
function BP_PlayerController:ClientRPC_SetSealRewards(InRewardsItems)
-- 显示奖励界面
UIManager.AllPanel[EUIType.SealRewards]:SetRewards(InRewardsItems)
UIManager:ShowPanel(EUIType.SealRewards)
end
function BP_PlayerController:ServerRPC_ApplyRewards(InData)
print(string.format('[BP_PlayerController:ServerRPC_ApplyRewards] Type = %s', InData.Type))
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
local Type = InData.Type
if Type == '配件' or Type == '技能书' then
for _ = 1, InData.Value do
local ItemData
if Type == '配件' then
ItemData = GenerateWeaponPartData()
else
ItemData = GenerateSkillBookData()
end
local ItemInfo = {
ItemID = ItemData.ItemID,
ItemCount = ItemData.Count
}
self:CreateItem(nil, ItemInfo)
end
elseif Type == '金币' then
PlayerState:UpdateCoinPoint(InData.Value)
elseif Type == '科技点' then
PlayerState:AddKillPoint(InData.Value)
else
PlayerState:AddAttribute(Type, InData.Value, true)
end
end
--------------------------------------------- 传承 ---------------------------------------------
function BP_PlayerController:ServerRPC_Inherit(IsBreak, SelectText, InCurrId)
print(string.format('[BP_PlayerController:ServerRPC_Inherit] 继承怪'))
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
local OldNum = PlayerState.InheritItems[SelectText]
local OldInfo = InheritTable.Items[OldNum]
if InCurrId ~= OldNum then
print(string.format('[BP_PlayerController:ServerRPC_Inherit] Current Id = %d', InCurrId))
print(string.format('[BP_PlayerController:ServerRPC_Inherit] Old Num = %d', OldNum))
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_UpdateInherit", self.PlayerKey, 4)
return
end
local NextId = InheritTable.GetNextId(OldNum)
local NewInfo = InheritTable.Items[NextId]
if IsBreak then
-- 出个怪
local TargetSpawner = UGCGameSystem.GameState:GetSpawnerByPlayerKey(self.PlayerKey)
if UE.IsValid(TargetSpawner) == false then
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_UpdateInherit", self.PlayerKey, 2)
return
end
TargetSpawner:StartSpawnInherit(self, SelectText, OldNum)
NoticeTipsTools.ServerGeneralNoticeTips(self.PlayerKey, "进阶怪已生成在练功房,请尽快击败获取奖励!", true, 4.0)
else
if PlayerState.CoinPoint.Current < OldInfo.Cost then
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_UpdateInherit", self.PlayerKey, 3)
return
else
local IsSuccess = PlayerState:UpdateCoinPoint( - OldInfo.Cost)
if IsSuccess then
PlayerState.InheritItems[SelectText] = NextId
--获得奖励
for i = 1, #NewInfo.Benefit do
PlayerState:AddAttribute(OldInfo.Benefit[i].Type, OldInfo.Benefit[i].Value, true)
end
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_UpdateInherit", self.PlayerKey, 1)
else
print(string.format('[BP_PlayerController:ServerRPC_Inherit] 没有添加成功'))
end
end
end
end
-- IsSuccess: 0:击杀怪物1:扣除金币成功2:击杀失败;3:扣除失败;4:执行失败
function BP_PlayerController:ClientRPC_UpdateInherit(InPlayerKey, IsSuccess)
if InPlayerKey ~= self.PlayerKey then
return
end
UIManager.AllPanel[EUIType.Inherit]:UpdateInherit(IsSuccess)
end
function BP_PlayerController:ServerRPC_SetResourceGrade(ResourceGrade)
if type(ResourceGrade) ~= 'number' or ResourceGrade < 1 or ResourceGrade > 4 then
return
end
local GameState = UGCGameSystem.GameState
if GameState == nil or UE.IsValid(GameState) == false then
return
end
local Spawner = GameState:GetSpawnerByPlayerKey(self.PlayerKey)
if Spawner == nil or UE.IsValid(Spawner) == false then
return
end
self.ResourceGrade = ResourceGrade
Spawner:UpdateHangupRoomMonsterLevel(ResourceGrade)
end
-- 一键合成
function BP_PlayerController:ServerRPC_GenerateAllItem(InType)
local ItemMap = self:GetItemMapByItemType(InType)
if ItemMap == nil then
print(string.format('[BP_PlayerController:ServerRPC_GenerateAllItem] 当前背包中没有 %d', InType))
return
end
-- 首先,将背包中的物品放到各个数组中
local AllItems = {}
-- 全部拆分开
for i, v in pairs(ItemMap) do
local Quality = GetItemQualityLevel(i)
if AllItems[Quality] == nil then
AllItems[Quality] = {}
end
AllItems[Quality][i] = v
end
local SingleItems = {}
-- 先根据AllItems[Quality] 进行判断
local TheType = EQualityType.Senior
while TheType >= 0 do
if AllItems[TheType] ~= nil then
for i, v in pairs(AllItems[TheType]) do
local NextStack = v // 3
if NextStack > 0 then
for d = 1, NextStack do
local ItemData = {i,i,i}
self:GenerateItem(ItemData)
end
end
-- 检查一下剩余的
local LastCount = v - NextStack * 3
if LastCount > 0 then
if SingleItems[TheType] == nil then
SingleItems[TheType] = {}
end
for c = 1, LastCount do
table.insert(SingleItems[TheType], i)
end
end
end
if SingleItems[TheType] ~= nil then
-- 计算数量
local Count = table.getCount(SingleItems[TheType])
local NextTypeCount = Count // 3
if NextTypeCount >= 1 then
for i = 1, NextTypeCount do
local ItemData = {
SingleItems[TheType][3 * (i - 1) + 1],
SingleItems[TheType][3 * (i - 1) + 2],
SingleItems[TheType][3 * (i - 1) + 3],
}
self:GenerateItem(ItemData)
end
end
end
end
TheType = TheType - 1
end
end
function BP_PlayerController:GenerateItem(InItemList)
-- InData 中包含的是几个要合成的 Id
for i = 1, #InItemList do
local InData = InItemList[i]
local RemoveCount = self:UpdateItemMap(InData, -1)
UE.Log('移除的数量:%d移除的 Id = %d', RemoveCount, InData)
end
-- 判断是不是技能书
local CreateId = self:GetCreateId(InItemList)
CreateId = CreateId + 10 -- 抬升一个等级
-- 判断当前技能是否是超级
if GetItemQualityLevel(CreateId) == EQualityType.Super then
self.PlayerState.ArchiveData.TotalSuperSkill = self.PlayerState.ArchiveData.TotalSuperSkill + 1
end
UE.Log('要添加的物品的 Id%d', CreateId)
local AddItemCount = self:UpdateItemMap(CreateId, 1)
if AddItemCount == 0 then
local ItemData = {
ItemID = CreateId,
ItemCount = 1
}
self:CreateItem(nil, ItemData)
return
end
end
function BP_PlayerController:GetCreateId(InItemList)
--local ItemId = InItemList[1]
--local Level = GetItemQualityLevel(ItemId) + 1
--
----生成ID
--local WeaponType = math.random(1, 6)
--
---- 判断是不是技能书
--local CreateId = 0
--if GetItemGrantTypeById(ItemId) == EDropItemSet.SkillBooks then
-- local Val = math.random(9, 32)
-- CreateId = 20000 + Val * 100 + (Level + 1) * 10
--else
-- CreateId = ItemId // 1000 * 1000 + WeaponType * 100 + (Level + 1) * 10
--end
--
--if ItemId == InItemList[2] and ItemId == InItemList[3] then
-- CreateId = ItemId + 10 -- 抬升一个等级
--end
return InItemList[math.random(1,3)]
end
-- 显示所有拾取的东西
function BP_PlayerController:ClientRPC_ShowPickUpItems(InAddItems)
local ItemsMap = {}
for i = 1, table.getCount(InAddItems) do
local ItemId = InAddItems[i]
if ItemsMap[ItemId] == nil then
ItemsMap[ItemId] = 1
else
ItemsMap[ItemId] = ItemsMap[ItemId] + 1
end
end
-- 找到对应物品
for i, v in pairs(ItemsMap) do
local FittingItem = DropItemMap.FittingItemMap[i]
local Item = nil
if FittingItem ~= nil then
Item = FittingItem["Quality"] .. FittingItem["WeaponType"] .. FittingItem["FittingType"]
else
FittingItem = DropItemMap.SkillItemMap[i]
if FittingItem == nil then
print(string.format('[BP_PlayerController:ClientRPC_ShowPickUpItems] 当前没有该元素:%s', tostring(i)))
return
end
Item = FittingItem["Quality"] .. FittingItem["SkillName"]
end
local Params = {
Text = Item,
Color = Tables.ItemRarityColor[GetItemQualityLevel(i)].LinearColor, -- 16进制颜色
Num = v,
}
NoticeTipsTools.ClientNoticeTips(ECustomNoticeType.RollingNotice, Params, ERollingNoticeType.Gain)
end
end
------------------------------------ 背包相关逻辑 ------------------------------------
function BP_PlayerController:OnRep_ItemMap()
-- 刷新一下背包界面
--log_tree("ItemMap - ", self.ItemMap)
EventSystem:SendEvent(EventType.UpdateItemList, false)
end
function BP_PlayerController:GetItemTypeCountByType(InType)
return table.getCount(self.ItemMap[InType])
end
--- Server 添加/减少物品数量
---@param InItemID number @目标物品ID
---@param InCount number @更改的数量(若为负数则视为丢弃)
---@return number @实际添加/减少的数量,当 数据 == -1000 的时候没有拾取或者丢弃
---减少的时候数量不会超过该物品的总数,因此不需要判断具体减少数据会不会超过总数
function BP_PlayerController:UpdateItemMap(InItemID, InCount)
local RetVal = 0
--石头 和 技能书
if InItemID > 20000 then
--获取对应信息即可
local InType = nil
if InItemID // 1000 == 31 then
InType = EItemType.ScouringStone
elseif InItemID // 1000 == 32 then
InType = EItemType.SubstituteStone
elseif InItemID // 10000 == 2 then
InType = EItemType.SkillBook
end
RetVal = InCount
print(string.format('当前玩家身上物品表的数量为:%d', self:GetItemTypeCountByType(InType)))
local val = self.ItemMap[InType][InItemID]
if self:GetItemTypeCountByType(InType) >= 24 then
-- 判断当前是否有该物品如果有就执行操作没有就返回0
if val == nil then
return 0
end
end
if val == nil then
if InCount <= 0 then
RetVal = 0
else
self.ItemMap[InType][InItemID] = InCount
end
else
--表示由原先值并且打算移除
if val + InCount == 0 then
table.removeKey(self.ItemMap[InType], InItemID)
else
self.ItemMap[InType][InItemID] = val + InCount
end
RetVal = InCount
end
return RetVal
end
-- 普通武器配件
local Type = GetItemTypeByItemId(InItemID)
if self:GetItemTypeCountByType(Type) >= 24 then
if InCount <= 0 then
return 0
end
end
local CurCount = self.ItemMap[Type][InItemID]
if InCount > 0 then
if CurCount == nil then
self.ItemMap[Type][InItemID] = InCount
else
-- 此处判断是否会超出数量
self.ItemMap[Type][InItemID] = CurCount + InCount
end
RetVal = InCount
elseif InCount < 0 then
if CurCount == nil then
return 0
end
print(string.format('开始移除'))
if math.abs(InCount) == CurCount then
table.removeKey(self.ItemMap[Type], InItemID)
else
self.ItemMap[Type][InItemID] = CurCount + InCount
end
RetVal = InCount
else
RetVal = 0
end
return RetVal
end
-- 添加背包物品
function BP_PlayerController:AddBagItem(InItemData)
local HadAddCount = self:UpdateItemMap(InItemData.ItemID, InItemData.ItemCount) --该数据只有 == 数量和 0 这两个值
if HadAddCount == InItemData.ItemCount then
return
end
-- 生成出来
if InItemData.ItemCount < 0 then
return
end
self:CreateItem(nil, InItemData)
end
function BP_PlayerController:GenerateItemList(InItemList)
print(string.format("[BP_PlayerController:GenerateItemList] 当前要删除的数量为:%d", #InItemList))
local ItemList = {}
for i = 1, #InItemList do
table.insert(ItemList, InItemList[i])
end
UnrealNetwork.CallUnrealRPC(self, self, "ServerRPC_GenerateItem", ItemList)
end
function BP_PlayerController:GetItemMap()
return self.ItemMap
end
function BP_PlayerController:GetItemMapByItemType(InType)
return self.ItemMap[InType]
end
function BP_PlayerController:FindItemCount( InType, InItemID )
if InItemID ~= nil then
print('[BP_PlayerController:FindItemCount] ItemId = NIl')
else
print(string.format('[BP_PlayerController:FindItemCount] ItemId = %d, ItemMap Count = %d', InItemID, #self.ItemMap))
end
local Count = self.ItemMap[InType][InItemID]
if Count == nil then
return 0
end
return Count
end
-- 拾取操作
function BP_PlayerController:RequestPickupNearbyItems(IsPickAll)
-- 首先判断玩家在哪部分
if self.Pawn.IsInArena then
local Dis
if IsPickAll then
Dis = self.PickupDistance
else
Dis = self.AutoPickupDistance
end
if not table.isEmpty(self.AllItemActors[ETeleportType.InArena]) then
local AddItemThisIDs = {}
for i, v in pairs(self.AllItemActors[ETeleportType.InArena]) do
if UE.IsValid(v) and v.bIsPicking == false then
local bCanPick = true
if IsPickAll == false then
bCanPick = v:IsAutoPickupDisabled(self.PlayerKey) == false
end
local DisLen = VectorHelper.Length(VectorHelper.Sub(self.Pawn:K2_GetActorLocation(), v:K2_GetActorLocation()))
if Dis >= DisLen and bCanPick then
v:SetIsPicking(true)
table.insert(AddItemThisIDs, v:GetThisID())
end
end
end
-- 告知服务器进行拾取这些
UnrealNetwork.CallUnrealRPC(self, self, "ServerRPC_AddItemsByThisID", AddItemThisIDs)
end
else
if not table.isEmpty(self.AllItemActors[ETeleportType.InHangupRoom]) then
-- 拾取这里面的所有物品
-- i: 序号v: 具体物体
local AddItems = {}
for i, v in pairs(self.AllItemActors[ETeleportType.InHangupRoom]) do
if UE.IsValid(v) and v.bIsPicking == false then
-- 通知服务器进行添加
local bCanPick = false
if not IsPickAll then
local DisLen = VectorHelper.Length(VectorHelper.Sub(self.Pawn:K2_GetActorLocation(), v:K2_GetActorLocation()))
bCanPick = v:IsAutoPickupDisabled(self.PlayerKey) == false and DisLen <= self.AutoPickupDistance
end
bCanPick = self:CanAddItemById(v:GetItemID()) and (IsPickAll or bCanPick)
if bCanPick then
v:SetIsPicking(true)
local ItemData = {
ItemID = v:GetItemID(),
ItemCount = v:GetItemCount()
}
v:K2_DestroyActor()
table.insert(AddItems, ItemData)
end
end
end
if not table.isEmpty(AddItems) then
UnrealNetwork.CallUnrealRPC(self, self, "ServerRPC_AddExerciseItems", AddItems)
end
end
end
end
function BP_PlayerController:ClientUpdateItemMap(ItemMap)
self.ItemMap = TableHelper.DeepCopyTable(ItemMap)
end
function BP_PlayerController:IsBackpackFull(InItemType)
return table.getCount(self.ItemMap[InItemType]) == 24
end
function BP_PlayerController:FindQualityItemCount(InQuality, InGrantType)
local Count = 0
if InGrantType == EDropItemSet.WeaponParts then
for i, v in pairs(self.ItemMap) do
if i < EItemType.SkillBook then
for c, d in pairs(v) do
if GetItemQualityLevel(c) == InQuality then
Count = Count + d
end
end
end
end
elseif InGrantType == EDropItemSet.SkillBooks then
for i, v in pairs(self.ItemMap[EItemType.SkillBook]) do
if GetItemQualityLevel(i) == InQuality then
Count = Count + v
end
end
end
return Count
end
-- S / C: 是否可以添加新的物品
function BP_PlayerController:CanAddItemById(InItemId)
-- 如果没满的话
local InType = GetItemTypeByItemId(InItemId)
if self:IsBackpackFull(GetItemTypeByItemId(InItemId)) then
-- 遍历查找是否有该东西
local Count = self:FindItemCount(InType, InItemId)
return Count > 0
end
return true
end
function BP_PlayerController:RequestExerciseDropItem(InPlayerKey, InLoc, InRot, InData, IsMonsterDrop, IsFromDiscard)
print(string.format('[BP_PlayerController:RequestExerciseDropItem] '.. tostring(InPlayerKey)))
InLoc = VectorHelper.ToLuaTable(InLoc)
InRot = VectorHelper.RotToLuaTable(InRot)
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_SpawnExerciseDropItem", InPlayerKey, InLoc, InRot, InData, IsMonsterDrop, IsFromDiscard)
end
-- 客户端生成
function BP_PlayerController:ClientRPC_SpawnExerciseDropItem(InPlayerKey, InLoc, InRot, InData, IsMonsterDrop, IsFromDiscard)
if self.PlayerKey ~= InPlayerKey then
return;
end
print(string.format('[BP_PlayerController:ClientRPC_SpawnExerciseDropItem] 执行'))
local Location = self.Pawn:K2_GetActorLocation()
local ForwardLocation = VectorHelper.ToLuaTable(self.Pawn:GetActorForwardVector())
local Scalar = 1.5
ForwardLocation = { X = ForwardLocation.X * Scalar, Y = ForwardLocation.Y * Scalar, Z = ForwardLocation.Z - 0 }
log_tree('ForwardLocation = ', ForwardLocation)
Location = VectorHelper.Add(Location, ForwardLocation)
--Location = VectorHelper.Add(Location, VectorHelper.MulScalar(ForwardLocation, 1.5))
Location = VectorHelper.ToLuaTable(Location)
local Scale = VectorHelper.ScaleOne()
--此处生成了一个具体的 Item
local DropItemActor = nil
if IsMonsterDrop then
DropItemActor = UGCGameSystem.SpawnActor(
self,
self.ItemActorClass,
InLoc, -- 阉割版
InRot,
Scale,
UGCGameSystem.GameState
)
else
DropItemActor = UGCGameSystem.SpawnActor(
self,
self.ItemActorClass,
Location, -- 阉割版
InRot,
Scale,
UGCGameSystem.GameState
)
end
--DropItemActor:SetPickItemData(string.format("%d;%d", InData.ItemID, InData.Count))
-- 设置数据进去
DropItemActor:SetItemData(InData)
-- 设置自动销毁时间
DropItemActor:SetLifeSpan(60 * 30)
if IsFromDiscard then
DropItemActor:SetAutoPickupDisabled(InPlayerKey)
end
table.insert(self.AllItemActors[ETeleportType.InHangupRoom], DropItemActor)
end
function BP_PlayerController:ServerRPC_AddExerciseItems(InItemList)
local AddItems = {}
print(string.format('[BP_PlayerController:ServerRPC_AddExerciseItems] 执行!'.. tostring(self.PlayerKey)))
log_tree('InItemList = ', InItemList)
log_tree('UGCGameSystem.GameState.DropItemList = ', UGCGameSystem.GameState.DropItemList)
local AddItemIds = {}
for i = 1, #InItemList do
-- 检查保存在 GameState 中的数组
-- c: ItemId, v:ItemCount
local SavedCount = UGCGameSystem.GameState.DropItemList[self.PlayerKey][InItemList[i].ItemID]
if SavedCount ~= nil then
if SavedCount < InItemList[i].ItemCount then
print(string.format('[BP_PlayerController:ServerRPC_AddExerciseItems] 该元素:%d 作弊了', InItemList[i].ItemID))
else
local ItemData = {
ItemID = InItemList[i].ItemID,
ItemCount = InItemList[i].ItemCount,
}
table.insert(AddItems, ItemData)
table.insert(AddItemIds, InItemList[i].ItemID)
local AddCount = self:UpdateItemMap(InItemList[i].ItemID, InItemList[i].ItemCount)
if SavedCount == AddCount then
table.removeKey(UGCGameSystem.GameState.DropItemList[self.PlayerKey], InItemList[i].ItemID)
else
UGCGameSystem.GameState.DropItemList[self.PlayerKey][InItemList[i].ItemID] = SavedCount - InItemList[i].ItemCount
end
end
else
print(string.format('[BP_PlayerController:ServerRPC_AddExerciseItems] 该元素:%d 作弊了', InItemList[i].ItemID))
end
end
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_ShowPickUpItems", AddItemIds)
end
function BP_PlayerController:ServerRPC_GM_AddItems(InItemDataList)
local AddItemIds = {}
for _, ItemData in pairs(InItemDataList) do
if self:UpdateItemMap(ItemData.ItemID, ItemData.ItemCount) > 0 then
table.insert(AddItemIds, ItemData.ItemID)
end
end
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_ShowPickUpItems", AddItemIds)
end
function BP_PlayerController:ServerRPC_GM_AddCoinPoint(InDelta)
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
if UE.IsValid(PlayerState) then
PlayerState:AddCoinPointDirectly(InDelta)
end
end
function BP_PlayerController:ServerRPC_GM_AddTechPoint(InDelta)
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
if UE.IsValid(PlayerState) then
PlayerState:AddTechPointDirectly(InDelta)
end
end
function BP_PlayerController:ServerRPC_GM_ChangeTimeScale(Scale)
EventSystem:SendEvent(EventType.GM_TimeScale, Scale)
end
function BP_PlayerController:ServerRPC_OnBreach(InPlayerKey)
print(string.format('[BP_PlayerController:ServerRPC_OnBreach] 执行生成一个怪'))
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(InPlayerKey)
local Level = PlayerState.Level
if Level % 10 ~= 0 then
return
end
local LevelVal = Level / 10
-- 获取 BossId
local BossList = UGCGameSystem.GameState.BossList
if LevelVal > #BossList then
LevelVal = #BossList
end
local BossId = BossList[LevelVal]
print(string.format('[BP_PlayerController:ServerRPC_OnBreach] BossId = %d', BossId))
-- 找到要添加的枪
local NeedAddWeaponType = Tables.MonsterBaseConfig[BossId].WeaponType
if NeedAddWeaponType == nil then
print(string.format('[BP_PlayerController:ServerRPC_OnBreach] 找不到当前武器类型:%d', NeedAddWeaponType))
return
end
for i, v in pairs(Tables.DefaultWeaponId) do
if v == NeedAddWeaponType then
-- 要添加 i
self:ServerRPC_StartSpawnBreachMonster(i, Level)
break
end
end
end
function BP_PlayerController:ClientRPC_ShowInitialPanel(IsShow)
print(string.format('[BP_PlayerController:ClientRPC_ShowInitialPanel] 执行'))
if IsShow then
self.InitialWidget = UserWidget.NewWidgetObjectBP(self, UE.LoadClass(UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/Notice/WBP_InitialNotice_V2.WBP_InitialNotice_V2_C')))
self.InitialWidget:AddToViewport()
self.InitialWidget:SetVisibility(ESlateVisibility.Visible)
else
if self.InitialWidget then
self.InitialWidget:SetVisibility(ESlateVisibility.Collapsed)
end
end
end
function BP_PlayerController:ClientRPC_ShowPanel(UIType, ...)
UIManager:ShowPanel(UIType, ...)
end
function BP_PlayerController:ServerRPC_CloseInitialNotice(IsShow)
UGCGameSystem.GameState:SetInitialOver(IsShow)
end
function BP_PlayerController:Client_UpdateArchiveData(InArchiveData)
log_tree("[BP_PlayerController:Client_UpdateArchiveData] InArchiveData = ", InArchiveData);
self.PlayerState:SetGameEndArchiveData(InArchiveData);
end
return BP_PlayerController;