local SoldierManager = {}; local Dir = "Script.Blueprint.Soldier." ---@type table SoldierManager.Soldiers = {}; SoldierManager.BaseValues = {}; SoldierManager.Owner = nil; function SoldierManager:Init(InOwner) self.Owner = InOwner; end ---@param InList table function SoldierManager:ClientAddSoldier(InOld, InList) for PlayerKey, SoldierType in pairs(InList) do if self.Soldiers[PlayerKey] == nil then self:AddSoldier(PlayerKey, SoldierType); elseif SoldierType ~= self.Soldiers[PlayerKey] then self:ChangeSoldier(PlayerKey, SoldierType); end end end --- 给一个玩家添加兵种 function SoldierManager:AddSoldier(InPlayerKey, InSoldierType) -- 检查是否可以添加 if IsServer then assert(InPlayerKey ~= nil and InSoldierType ~= nil) end self.Soldiers[InPlayerKey] = InSoldierType; local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(InPlayerKey); table.func(PC, "OnAddSoldier", InSoldierType); local PS = UGCGameSystem.GetPlayerStateByPlayerKey(InPlayerKey); table.func(PS, "OnAddSoldier", InSoldierType); UGCLogSystem.Log("[SoldierManager:AddSoldier] 添加成功") end --- 设置所有人对应的兵种 function SoldierManager:SetAllPlayerSoldiers() if IsClient then return ; end for PlayerKey, SoldierType in pairs(self.Soldiers) do local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey); if UE.IsValidPawn(Pawn) then self:SetPlayerSoldier(Pawn, SoldierType); end end end ---@param Pawn UGCPlayerPawn_C ---@param SoldierType ESoldierType function SoldierManager:SetPlayerSoldier(Pawn, SoldierType) -- 清空玩家身上所有东西 ItemTool.ClearAllItems(Pawn); UGCLogSystem.Log("[SoldierManager:SetPlayerSoldier] SoldierType = %s", tostring(SoldierType)); -- 清空技能 UGCEventSystem.SendEvent(EventTypes.AddAutoHealing, Pawn.PlayerKey, UGCPawnAttrSystem.GetTeamID(Pawn), false); if SoldierCommonInfo.Bag and BagItems[SoldierCommonInfo.Bag] then -- 添加一个 Pawn:AddItem(BagItems[SoldierCommonInfo.Bag], 1); end -- 添加炸弹 local BombDiff = SoldierConfig[SoldierType].Weapons.Bomb; -- 此时玩家必须存在 for i, v in pairs(SoldierCommonInfo.Bombs) do local Count = v; if BombDiff ~= nil then Count = Count + (BombDiff[i] or 0); end if Count > 0 then if EBombType[i] and BombItems[EBombType[i]] then Pawn:AddItem(BombItems[EBombType[i]], Count); end end end -- 添加药品 local MedicationsDiff = SoldierConfig[SoldierType].Medications for i, v in pairs(SoldierCommonInfo.Medications) do local Count = v; if MedicationsDiff then Count = Count + (MedicationsDiff[i] or 0); end if Count > 0 then if ESupplyType[i] and SupplyItems[ESupplyType[i]] then local ItemId = SupplyItems[ESupplyType[i]]; Pawn:AddItem(ItemId, Count); end end end local OthersDiff = SoldierConfig[SoldierType].Weapons.Others if OthersDiff then Pawn:AddInitItems(OthersDiff); end -- 添加护甲 local Armors = SoldierConfig[SoldierType].Armors UGCLogSystem.LogTree(string.format("[SoldierManager:SetPlayerSoldier] Armors ="), Armors) Pawn:AddItem(ArmorItems[Armors[1]], 1); Pawn:AddItem(HelmetItems[Armors[2]], 1); -- 添加属性 local Benefit = SoldierConfig[SoldierType].Benefit if Benefit then for i, v in pairs(Benefit) do local Val = ESoldierAddType[i] local Count = 0; if Val == ESoldierAddType.MaxHealth then Pawn:SetMaxHealth(v); elseif Val == ESoldierAddType.Damage then Pawn:SetDamageScale(v); elseif Val == ESoldierAddType.Speed then UGCPawnAttrSystem.SetSpeedScale(Pawn, v * Pawn.BaseSpeedScale); elseif Val == ESoldierAddType.Poison then Pawn:SetPoisonScale(v); elseif Val == ESoldierAddType.Defence then Pawn:SetArmor(v); elseif Val == ESoldierAddType.Jump then UGCPawnAttrSystem.SetJumpZVelocity(Pawn, v * Pawn.BaseJumpZVelocity); end end end -- 添加技能 local Buff = SoldierConfig[SoldierType].Buff; if Buff and Buff.Name then local BuffName = FindBuffByName(Buff.Name); UGCLogSystem.Log("[SoldierManager:SetPlayerSoldier] BuffName = %s, ", tostring(Buff.Name)); if not BuffManager:Has(Pawn.PlayerKey, BuffName) then BuffManager:Add(Pawn.PlayerKey, BuffName); end end end --- 设置玩家的属性 ---@param InPawn UGCPlayerPawn_C function SoldierManager:SetPawnAttr(InPawn) if IsClient then return ; end -- 检查是否存在 local Soldier = self.Soldiers[InPawn.PlayerKey]; if Soldier == nil then return ; end local HealthMax = table.func(Soldier, "GetHealthMax"); if HealthMax then -- 先获取当前的血量 local CurrHealthMax = UGCPawnAttrSystem.GetHealthMax(InPawn); if self.BaseValues["HealthMax"] == nil then self.BaseValues.HealthMax = CurrHealthMax; end local Health = UGCPawnAttrSystem.GetHealth(InPawn); local Percent = Health / HealthMax; local NextHealth = HealthMax * Percent; UGCPawnAttrSystem.SetHealthMax(InPawn, HealthMax); UGCPawnAttrSystem.SetHealth(InPawn, NextHealth); end local SpeedScale = table.func(Soldier, "GetSpeed"); if SpeedScale then local CurrSpeedScale = UGCPawnAttrSystem.GetSpeedScale(InPawn); if self.BaseValues["SpeedScale"] == nil then self.BaseValues["SpeedScale"] = CurrSpeedScale; end UGCPawnAttrSystem.SetSpeedScale(InPawn, SpeedScale); end local JumpScale = table.func(Soldier, "GetJump"); if JumpScale then -- 获取一个 Base local BaseJump = UGCPawnAttrSystem.GetJumpZVelocity(InPawn); if self.BaseValues["JumpScale"] == nil then self.BaseValues["JumpScale"] = BaseJump; end UGCPawnAttrSystem.SetJumpZVelocity(InPawn, self.BaseValues["JumpScale"] * JumpScale); end local DamageScale = table.func(Soldier, "GetDamage"); if DamageScale then InPawn:SetDamageScale(DamageScale); end local PoisonScale = table.func(Soldier, "GetPoison"); if PoisonScale then InPawn:SetPoisonScale(PoisonScale); end UGCLogSystem.Log("[SoldierManager:SetPawnAttr] %s 设置完毕", UGCPawnAttrSystem.GetPlayerName(InPawn)); end function SoldierManager:ChangeSoldier(InPlayerKey, InSoldierType) -- 直接改变即可 self.Soldiers[InPlayerKey] = InSoldierType; local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey); -- 该玩家需要复活重生一次才行 BuffManager:RemoveAll(InPlayerKey); end function SoldierManager:SendRPC(InFuncName, ...) if IsServer then UnrealNetwork.CallUnrealRPC_Multicast(self.Owner, "SendSoldierRPC", InFuncName, ...); end end function SoldierManager:OnPlayerDead(DeadPlayerKey, KillerPlayerKey) BuffManager:RemoveAll(DeadPlayerKey); end return SoldierManager;