1746 lines
57 KiB
Lua
1746 lines
57 KiB
Lua
|
---@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;
|