UGCProjects/GZJ/Script/Blueprint/Weapon/BP_WeaponPawnBase.lua

831 lines
27 KiB
Lua
Raw Normal View History

2025-01-08 22:46:12 +08:00
---@class BP_WeaponPawnBase_C:APawn
---@field Sphere USphereComponent
---@field DefaultRoot USceneComponent
---@field StaticMesh1 UStaticMeshComponent
---@field StaticMesh4 UStaticMeshComponent
---@field StaticMesh3 UStaticMeshComponent
---@field StaticMesh2 UStaticMeshComponent
---@field MuzzleParticle UParticleSystem
--Edit Below--
local BP_WeaponPawnBase = {
Activated = false,
HasBegunPlay = false,
InRangeMonsters = {}, -- 检测区域中的 Monster
TargetMonster = nil, -- 目标 Monster
MarkPendingInitialized = false,
Weapons = {}, --所有的武器 数组类型
CurrentWeaponId = 0, -- 这个是 武器表中的 Id
OwnerCharacter = nil,
OwningPlayerState = nil, -- 拥有的PlayerState
OwningPlayerController = nil, -- 拥有的 PlayerController
DefaultShootCountPerSecond = 1, -- 默认每秒射击次数
TimeTemp = 0, -- 射击的定时器
DefaultSphereRadius = 1200, -- 默认球体半径
TempSphereRadius = 0,
IsPlayerInArena = false; -- 玩家是否在场内,因为玩家默认不在场内
-- Client
IsAttackNearestMonster = true; -- 是否攻击离得最近的怪物
};
BP_WeaponPawnBase.OnFireDelegate = Delegate.New()
--设置同步的属性
function BP_WeaponPawnBase:GetReplicatedProperties()
return
"Activated",
"OwnerCharacter",
"TargetMonster",
"CurrentWeaponId"
end
function BP_WeaponPawnBase:ReceiveBeginPlay()
BP_WeaponPawnBase.SuperClass.ReceiveBeginPlay(self)
self.MainMesh = self.StaticMesh1
self.PartStaticMeshes = { self.StaticMesh2, self.StaticMesh3, self.StaticMesh4 }
self.MonsterBaseClass = UE.LoadClass(BPClassPath.MonsterBase)
self.InRangeMonsters = {}
self.HasBegunPlay = true
if self:HasAuthority() then
self:LoadPlayerState()
self:LoadPlayerController()
--self:SetFireTimer()
self.OnFireDelegate:Add(BP_WeaponPawnBase.MulticastPlayMuzzleEffectAndSound, self)
else
self.Sphere.OnComponentBeginOverlap:Add(BP_WeaponPawnBase.Sphere_OnComponentBeginOverlap, self)
self.Sphere.OnComponentEndOverlap:Add(BP_WeaponPawnBase.Sphere_OnComponentEndOverlap, self)
EventSystem:AddListener(EventType.AsyncLoadWeaponMeshesCompleted, BP_WeaponPawnBase.OnPreLoadAccessable, self)
EventSystem:AddListener(EventType.AttackRangeChanged, BP_WeaponPawnBase.SetSphereSizeRadius, self)
self:OnCreateWeapons()
end
end
function BP_WeaponPawnBase:ReceiveEndPlay()
self.HasBegunPlay = false
self.MainMesh = nil
self.PartStaticMeshes = nil
self.MonsterBaseClass = nil
self.InRangeMonsters = nil
if self:HasAuthority() then
self:ClearFireTimer()
self.OnFireDelegate:Remove(BP_WeaponPawnBase.MulticastPlayMuzzleEffectAndSound, self)
else
self.Sphere.OnComponentBeginOverlap:Remove(BP_WeaponPawnBase.Sphere_OnComponentBeginOverlap, self)
self.Sphere.OnComponentEndOverlap:Remove(BP_WeaponPawnBase.Sphere_OnComponentEndOverlap, self)
EventSystem:RemoveListener(EventType.AsyncLoadWeaponMeshesCompleted, BP_WeaponPawnBase.OnPreLoadAccessable, self)
EventSystem:RemoveListener(EventType.AttackRangeChanged, BP_WeaponPawnBase.SetSphereSizeRadius, self)
end
BP_WeaponPawnBase.SuperClass.ReceiveEndPlay(self)
end
function BP_WeaponPawnBase:ReceiveTick(DeltaTime)
BP_WeaponPawnBase.SuperClass.ReceiveTick(self, DeltaTime)
if not self.HasBegunPlay then
return
end
if self:HasAuthority() then
-- 获取次数
if self.OwnerCharacter == nil or not UE.IsValid(self.OwnerCharacter) then
return
end
if self.OwnerCharacter:IsSelfAlive() then
self:TickFire(DeltaTime)
end
else
if self.MarkPendingInitialized then
self:ChangeWeaponId(self.CurrentWeaponId)
end
-- 每帧获取对应位置和旋转
if UE.IsValid(self.OwnerCharacter) then
self:UpdateTargetMonster()
if UE.IsValid(self.TargetMonster) then
local SocketPos = VectorHelper.Add(self.OwnerCharacter:K2_GetActorLocation(), { X = 0, Y = 0, Z = 110 })
local MonsterPos = VectorHelper.Add(self.TargetMonster:K2_GetActorLocation(), { X = 0, Y = 0, Z = 80 })
self.StaticMesh1:K2_SetWorldRotation(KismetMathLibrary.FindLookAtRotation(SocketPos, MonsterPos), false)
else
self.StaticMesh1:K2_SetWorldRotation(self.OwnerCharacter:K2_GetActorRotation(), false)
end
end
self.TimeTemp = self.TimeTemp + DeltaTime
if self.TimeTemp > 1 then
-- print(string.format('[BP_WeaponPawnBase:ReceiveTick] 开始打印怪物名称'))
if #self.InRangeMonsters > 0 then
for i, v in pairs(self.InRangeMonsters) do
-- print(string.format('[BP_WeaponPawnBase:ReceiveTick] MonsterName = %s', KismetSystemLibrary.GetObjectName(v)))
end
end
-- print(string.format('[BP_WeaponPawnBase:ReceiveTick] 结束打印, Target Monster Name = %s', KismetSystemLibrary.GetObjectName(self.TargetMonster)))
self.TimeTemp = self.TimeTemp - 1
end
end
end
function BP_WeaponPawnBase:OnCreateWeapons()
if not self.OwnerCharacter then
return
end
-- 先关闭
local ObjectTypes = {}
local ActorClassFilter = UE.LoadClass(BPClassPath.MonsterBase)
local ActorsToIgnore = { }
local SphereLoc = self.OwnerCharacter:K2_GetActorLocation()
local Radius = self.Sphere.SphereRadius
local OutArrs = {}
local RetVal, OutActors = KismetSystemLibrary.SphereOverlapActors(self.OwnerCharacter, SphereLoc, Radius, ObjectTypes, ActorClassFilter, ActorsToIgnore, OutArrs)
--STExtraGameplayStatics.ClientDrawDebugSphere(SphereLoc, Radius, 6, {R = 1, G = 0, B = 0, A = 1}, 10, 1)
--print(string.format('[BP_WeaponPawnBase:OnCreateWeapons] OutArrs Len = %d', #OutArrs))
if RetVal then
--print(string.format('[BP_WeaponPawnBase:OnCreateWeapons] 进来了是进来了,有多少值呢:%d, Radius = %d', table.getCount(OutActors), Radius))
if table.getCount(OutActors) > 0 then
for i = 1, #OutActors do
table.insert(self.InRangeMonsters, OutActors[i])
end
self:UpdateTargetMonster()
end
else
print(string.format('[BP_WeaponPawnBase:OnCreateWeapons] 没有用呀~~'))
end
-- 先关闭
--self.TempSphereRadius = self.Sphere.SphereRadius
--self.Sphere:SetActive(false, true)
----self.Sphere:SetSphereRadius(5)
--EventSystem.SetTimer(self, function()
-- --self.Sphere:SetSphereRadius(self.TempSphereRadius, true)
-- self.Sphere:SetActive(true, true)
--end, 0.2)
end
function BP_WeaponPawnBase:PlayerInArena(IsInArena)
-- print(string.format('[BP_WeaponPawnBase:PlayerInArena] '.. tostring(IsInArena)))
self.IsPlayerInArena = IsInArena
end
function BP_WeaponPawnBase:TickFire(DeltaTime)
local ShootTime = self:GetShootTime()
self.TimeTemp = self.TimeTemp + DeltaTime
if self.TimeTemp > ShootTime then
-- print(string.format("[BP_WeaponPawnBase:TickFire] 隔 %f 秒进行第二次射击", ShootTime))
self.TimeTemp = self.TimeTemp - ShootTime
self:Fire()
end
end
function BP_WeaponPawnBase:LoadPlayerController()
if self.OwnerCharacter ~= nil then
self.OwningPlayerController = self.OwnerCharacter:GetPlayerControllerSafety()
end
end
function BP_WeaponPawnBase:LoadPlayerState()
if self.OwningPlayerState == nil then
if self.OwnerCharacter ~= nil then
self.OwningPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.OwnerCharacter.PlayerKey)
end
end
end
function BP_WeaponPawnBase:Fire()
print(string.format("[BP_WeaponPawnBase:Fire] 开始开火"))
if not self.Activated then
return
end
if UE.IsValid(self.TargetMonster) == false then
return
end
if UE.IsValid(self.OwnerCharacter) == false then
return
end
if not self.TargetMonster:IsAlive() then
return
end
self:LoadPlayerState()
if self.OwningPlayerController == nil then
self:LoadPlayerController()
end
if self.OwningPlayerController == nil then
print(string.format("[BP_WeaponPawnBase:Fire] 玩家控制器设置出错,请检查"))
return
end
-- 造成的伤害
local Damage = self.OwningPlayerState:MakeDamage(self.TargetMonster)
self.OnFireDelegate(self, Damage)
local RealDamage = UGCGameSystem.ApplyDamage(self.TargetMonster, Damage, self.OwningPlayerController, self.OwnerCharacter, EDamageType.ShootDamage)
-- 在这进行判断
if self.TargetMonster then
GameDataManager.GetMonsterTypeByID(self.TargetMonster.ID)
end
--调用PlayerState 射击生命值 和 射击威力值
self.OwningPlayerState:OnShot()
UE.Log("[BP_WeaponPawnBase:Fire] RealDamage = %f, Player Key = %d", RealDamage, self.OwnerCharacter.PlayerKey)
end
function BP_WeaponPawnBase:MulticastPlayMuzzleEffectAndSound()
local SoundConfigId = Tables.WeaponSoundConfig[self.CurrentWeaponId]
if SoundConfigId then
UnrealNetwork.CallUnrealRPC_Multicast_Unreliable(self, "Client_MulticastRPC_PlayMuzzleEffectAndSound", SoundConfigId)
end
end
-- Client
function BP_WeaponPawnBase:ChangeWeaponId(ID)
if not self.HasBegunPlay then
UE.LogError("[BP_WeaponPawnBase:ChangeWeaponId] Has not BegunPlay, Mark Pending Initialized")
self.MarkPendingInitialized = true
return
end
self.MarkPendingInitialized = false
if ID <= 0 then
self.MainMesh:SetHiddenInGame(true, false)
for _, StaticMeshComp in pairs(self.PartStaticMeshes) do
StaticMeshComp:SetHiddenInGame(true, false)
end
return
end
local RowData = GameDataManager.GetWeaponConstructDataByID(ID)
local MeshInfo = GameDataManager.GetWeaponMeshInfo(ID)
if RowData == nil or MeshInfo == nil then
self.MainMesh:SetHiddenInGame(true, false)
for _, PartMesh in pairs(self.PartStaticMeshes) do
PartMesh:SetHiddenInGame(true, false)
end
UE.Log("[BP_WeaponPawnBase:ChangeWeaponId] RowData or MeshInfo is nil")
return
end
local MainStaticMesh = MeshInfo.MainMesh
local PartStaticMeshes = MeshInfo.PartMeshes
if MainStaticMesh then
self.MainMesh:SetStaticMesh(MainStaticMesh)
end
for i, PartMesh in pairs(self.PartStaticMeshes) do
local PartStaticMesh = PartStaticMeshes[i]
if PartStaticMesh then
local SocketName = PartStaticMesh.SocketName
local Mesh = PartStaticMesh.PartMesh
PartMesh:SetHiddenInGame(false, false)
PartMesh:SetStaticMesh(Mesh)
PartMesh:K2_AttachTo(self.MainMesh, SocketName, EAttachLocation.SnapToTarget, false)
else
PartMesh:SetHiddenInGame(true, false)
end
end
local Trans = MeshInfo.RelativeTransform
self.MainMesh:K2_SetRelativeTransform(Trans, false, nil, false)
end
function BP_WeaponPawnBase:OnRep_Activated()
---TODO
end
function BP_WeaponPawnBase:OnRep_OwnerCharacter()
-- UE.Log("[BP_WeaponPawnBase:OnRep_OwnerCharacter]")
if self.OwnerCharacter then
-- 武器绑定到人物头上
self:K2_AttachToComponent(self.OwnerCharacter.WeaponActorSocket, "", EAttachmentRule.SnapToTarget, EAttachmentRule.KeepRelative, EAttachmentRule.SnapToTarget, true)
end
end
---Server
function BP_WeaponPawnBase:SetWeaponID(ID)
print(string.format("[BP_WeaponPawnBase:SetWeaponID] 设置 Weapon Id = %d", ID))
self.CurrentWeaponId = ID
self.Activated = ID > 0
end
---S
function BP_WeaponPawnBase:SetOwnerCharacter(InCharacter)
if InCharacter == nil then
return
end
self.OwnerCharacter = InCharacter
self:SetOwner(InCharacter)
end
function BP_WeaponPawnBase:SetFireTimer()
if self.OwningPlayerState == nil then
self.OwningPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
end
KismetSystemLibrary.K2_ClearTimerHandle(self, self.TimerHandle)
if self.FireTimerDelegate then
ObjectExtend.DestroyDelegate(self.FireTimerDelegate)
end
self.FireTimerDelegate = ObjectExtend.CreateDelegate(self,
function()
if self.Activated and UE.IsValid(self.TargetMonster) and UE.IsValid(self.OwnerCharacter) and self.TargetMonster:IsAlive() then
local PC = self.OwnerCharacter:GetPlayerControllerSafety()
if PC then
-- 造成的伤害
local Damage = self.OwningPlayerState:MakeDamage(self.TargetMonster)
local RealDamage = UGCGameSystem.ApplyDamage(self.TargetMonster, Damage, PC, self.OwnerCharacter, EDamageType.ShootDamage)
-- 在这进行判断
if self.TargetMonster then
GameDataManager.GetMonsterTypeByID(self.TargetMonster.ID)
end
UE.Log("[BP_WeaponPawnBase:FireTimerDelegate] RealDamage = %f", RealDamage)
end
end
end)
-- 获取一下默认属性
self:RefreshShootSpeed()
end
function BP_WeaponPawnBase:RefreshShootSpeed()
local bIsActive = KismetSystemLibrary.K2_IsTimerActiveDelegate(self.TimerHandle)
if bIsActive then
KismetSystemLibrary.K2_ClearTimerDelegate(self.TimerHandle)
end
if self.OwningPlayerState == nil then
self.OwningPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.PlayerKey)
end
local ShootRate = self.OwningPlayerState:ShootTimeEverSecond()
--这个 0.5 是一个基础射击数值
local TimeDelta = 0.5 / ShootRate
self.TimerHandle = KismetSystemLibrary.K2_SetTimerDelegateForLua(self.FireTimerDelegate, self, TimeDelta, true)
end
-- server 获取射击间隔(s)
function BP_WeaponPawnBase:GetShootTime()
if self.OwningPlayerState == nil or self.OwnerCharacter == nil then
-- 默认情况下攻速
return 1 / 1.30
end
local ShootRate = self.OwningPlayerState:ShootTimeEverSecond()
--print(string.format("[BP_WeaponPawnBase:GetShootTime] Shoot Rate = %f", ShootRate))
return 1 / ShootRate
end
function BP_WeaponPawnBase:ClearFireTimer()
KismetSystemLibrary.K2_ClearTimerHandle(self, self.TimerHandle)
ObjectExtend.DestroyDelegate(self.FireTimerDelegate)
end
function BP_WeaponPawnBase:GetWeaponTypeByWeaponId(InWeaponId)
return GameDataManager.GetWeaponType(InWeaponId)
end
---C
function BP_WeaponPawnBase:OnPreLoadAccessable()
self:OnRep_OwnerCharacter()
end
function BP_WeaponPawnBase:Sphere_OnComponentBeginOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult)
if UE.IsValid(OtherActor) and UE.IsA(OtherActor, self.MonsterBaseClass) then
self:UpdateMonsterInRange(OtherActor, true)
end
end
function BP_WeaponPawnBase:Sphere_OnComponentEndOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex)
if UE.IsValid(OtherActor) and UE.IsA(OtherActor, self.MonsterBaseClass) then
self:UpdateMonsterInRange(OtherActor, false)
end
end
function BP_WeaponPawnBase:UpdateMonsterInRange(InMonster, IsAdd)
if not self.OwnerCharacter then
return
end
if IsAdd and InMonster:IsAlive() then
InMonster.OnDeath:Add(self.OnOverlappedMonsterDeath, self)
table.insert(self.InRangeMonsters, InMonster)
else
InMonster.OnDeath:Remove(self.OnOverlappedMonsterDeath, self)
table.removeValue(self.InRangeMonsters, InMonster)
end
self:UpdateTargetMonster()
end
function BP_WeaponPawnBase:UpdateTargetMonster()
if (not UE.IsValid(self.OwnerCharacter)) or (not self.Sphere) then
return
end
local MinDist = self.Sphere:GetScaledSphereRadius()
local PawnLocation = self.OwnerCharacter:K2_GetActorLocation()
local CurTarget = nil
local Func = function(InMinDist, InMonster, InPawnLoc, InCurr)
if UE.IsValid(InMonster) and InMonster:IsAlive() then
local MonsterLocation = InMonster:K2_GetActorLocation()
local Dist = VectorHelper.GetDistance(InPawnLoc, MonsterLocation)
if Dist < InMinDist then
InMinDist = Dist
InCurr = InMonster
end
end
return InCurr, InMinDist
end
-- 选择最近的怪物
if self.IsAttackNearestMonster then
for _, Monster in pairs(self.InRangeMonsters) do
if UE.IsValid(Monster) then
local IsInArenaMonster = Monster:GetMonsterType() == EMonsterType.Boss or Monster:GetMonsterType() == EMonsterType.Common
if self.IsPlayerInArena then
if IsInArenaMonster then
CurTarget, MinDist = Func(MinDist, Monster, PawnLocation, CurTarget)
end
else
CurTarget, MinDist = Func(MinDist, Monster, PawnLocation, CurTarget)
end
end
end
else
-- 按照权重进行设置,找到 BOSS
local NiuBiGuai = {}
for _, Monster in pairs(self.InRangeMonsters) do
if UE.IsValid(Monster) and Monster:IsAlive() then
local MonsterType = Tables.MonsterBaseConfig[Monster.ID].Type
if MonsterType == EMonsterType.Default or MonsterType == EMonsterType.Common or MonsterType == EMonsterType.HangupRoom then
else
table.insert(NiuBiGuai, Monster)
end
end
end
if table.getCount(NiuBiGuai) > 0 then
for _, Monster in pairs(NiuBiGuai) do
CurTarget, MinDist = Func(MinDist, Monster, PawnLocation, CurTarget)
end
end
if CurTarget == nil then
for _, Monster in pairs(self.InRangeMonsters) do
CurTarget, MinDist = Func(MinDist, Monster, PawnLocation, CurTarget)
end
end
end
if CurTarget ~= self.TargetMonster then
self.TargetMonster = CurTarget
-- print(string.format('[BP_WeaponPawnBase:UpdateTargetMonster] 设置Target Monster = %s', KismetSystemLibrary.GetObjectName(CurTarget)))
UnrealNetwork.CallUnrealRPC(self, self, "ServerRPC_SetTargetMonster", CurTarget)
end
end
function BP_WeaponPawnBase:ServerRPC_SetTargetMonster(InMonster)
-- print(string.format('[BP_WeaponPawnBase:ServerRPC_SetTargetMonster] 服务端设置 TargetMonster%s', KismetSystemLibrary.GetObjectName(InMonster)))
if UE.IsValid(InMonster) and InMonster:IsAlive() then
self.TargetMonster = InMonster
else
self.TargetMonster = nil
end
end
function BP_WeaponPawnBase:GetAvailableServerRPCs()
return
-- "Client_MulticastRPC_PlayMuzzleEffectAndSound"
"ServerRPC_SetTargetMonster"
end
function BP_WeaponPawnBase:OnOverlappedMonsterDeath(DeadMonster, KillerController, DamageCauser, KillingHitInfo, KillingHitImpulseDir, KillingHitDamageTypeID, DamageTypeClass, IsHeadShotDamage)
if DeadMonster and UE.IsA(DeadMonster, self.MonsterBaseClass) then
self:UpdateMonsterInRange(DeadMonster, false)
end
end
function BP_WeaponPawnBase:GetPlayerState()
if UGCGameSystem.IsServer() then
local PlayerKey = self.OwnerCharacter.PlayerKey
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
return PlayerState
else
local PlayerState = GameDataManager.GetLocalPlayerState()
return PlayerState
end
end
function BP_WeaponPawnBase:FindWeaponById(InWeaponId)
-- 找到 PS
return self:GetPlayerState():FindWeaponById(InWeaponId)
end
function BP_WeaponPawnBase:GetWeaponByFittingItemId(InFittingItemId)
local WeaponType = GetItemWeaponTypeByItemId(InFittingItemId)
for i = 1, #self.Weapons do
local Weapon = self.Weapons[i]
if Weapon.Type == WeaponType then
return Weapon
end
end
return nil
end
-- 查找配件的武器是否存在
function BP_WeaponPawnBase:FindWeaponExist(InFittingItemId)
local WeaponType = GetItemWeaponTypeByItemId(InFittingItemId)
return self:FindWeaponByWeaponType(WeaponType)
end
function BP_WeaponPawnBase:FindWeaponByWeaponType(InWeaponType)
for i = 1, #self.Weapons do
if self.Weapons[i].Type == InWeaponType then
return self.Weapons[i]
end
end
return nil
end
--Server 获取当前武器的属性,这是一个表:{ { Type = "", Value = 0 },{ Type = "", Value = 0 } }
function BP_WeaponPawnBase:GetOutProps()
-- 需要获取手枪属性
local OutTable = {}
local TheTable = DropItemMap.WeaponTable[EWeaponClassType.WT_Pistol].Props
OutTable = TableHelper.DeepCopyTable(TheTable)
if self.CurrentWeaponId == 0 then
-- 说明当前是手枪,不进行处理
return self:MergeOutTable(OutTable)
end
print(string.format("[BP_WeaponPawnBase:GetOutProps] 当前武器 Id = %d", self.CurrentWeaponId))
-- NativeProps
local Weapon = self:FindWeaponById(self.CurrentWeaponId)
local SpecialItems = {}
--print(string.format("[BP_WeaponPawnBase:GetOutProps] 开始打印武器高级属性,数量为:%d", table.getCount(Weapon.NativeProps.Plus)))
-- 高级属性
for i = 1, table.getCount(Weapon.NativeProps.Plus) do
local Val = Weapon.NativeProps.Plus[i]
--print(string.format("[BP_WeaponPawnBase:GetOutProps] MainType: %s,类型是:%s", tostring(Val.MainType), type(Val.MainType)))
local Name = Tables.WeaponPropertyConfig[Val.MainType].PropName
local ItemData = {
Type = Name,
Value = Val.Value
}
--print(string.format("[BP_WeaponPawnBase:GetOutProps] 武器高级属性Name:%s, Value: %s", Name, tostring(Val.Value)))
table.insert(OutTable, ItemData)
end
-- 添加 Properties
local Properties = Weapon.Properties
--print(string.format("[BP_WeaponPawnBase:GetOutProps] 开始打印武器属性,数量:%d", table.getCount(Properties)))
for i = 1, #Properties do
local Prop = Properties[i]
local ItemData = {
Type = Tables.WeaponPropertyConfig[Prop.MainType].PropName,
Value = Prop.Value
}
--print(string.format("[BP_WeaponPawnBase:GetOutProps] 武器属性Name: %s, Value: %s", ItemData.Type, tostring(Prop.Value)))
table.insert(OutTable, ItemData)
end
-- 处理武器自带属性
local FittingLevel = Weapon.FittingLevel
if FittingLevel > 0 then
local Val = DropItemMap.WeaponTable[Weapon.Type].PlusProps[FittingLevel]
local ItemData = {
Type = Val.Type,
Value = Val.Value
}
table.insert(OutTable, ItemData)
end
-- FittingItems
local FittingList = Weapon.Fittings
for i = 1, #FittingList do
local FittingItemId = FittingList[i]
local FittingProps = DropItemMap.FittingItemMap[FittingItemId].Props
for j = 1, #FittingProps do
if FittingProps[j].Unit ~= 'Special' then
local ItemData = {
Type = FittingProps[j].Type,
Value = FittingProps[j].Value
}
table.insert(OutTable, ItemData)
else
local ItemData = {
ItemId = FittingItemId,
}
table.insert(SpecialItems, ItemData)
end
end
end
-- OutTable 是不包含特殊词条属性的SpecialItems 里面是词条属性
return self:MergeOutTable(OutTable), SpecialItems
end
-- Server 设置当前的武器,当点击页面上的武器的时候执行这个
function BP_WeaponPawnBase:SetCurrentWeapon(InId)
-- 重复点击无效
if InId == self.CurrentWeaponId then
print(string.format("[BP_WeaponPawnBase:SetCurrentWeapon] 当前选择的Id与原先的Id相同"))
return
end
if self:FindWeaponById(InId) == nil then
print(string.format("[BP_WeaponPawnBase:SetCurrentWeapon] 无法找到对应Id"))
return
end
self.CurrentWeaponId = InId
-- 通知进行改变
print(string.format("[BP_WeaponPawnBase:SetCurrentWeapon] WeaponId = %d", self.CurrentWeaponId))
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.OwnerCharacter.PlayerKey)
PlayerState:OnWeaponAttributeChanged(self.CurrentWeaponId)
end
-- 每操作一下就执行该方法进行检测 FittingLevel然后刷新全部属性
function BP_WeaponPawnBase:GetWeaponFittingLevel(InWeaponId)
if not self:FindWeaponExist(InWeaponId) then
print(string.format('[BP_WeaponPawnBase:GetWeaponFittingLevel] 找不到对应武器,请检查'))
return -1
end
print(string.format('[BP_WeaponPawnBase:GetWeaponFittingLevel] 找到了对应武器,数量是: %d', InWeaponId))
return self:FindWeaponById(InWeaponId).FittingLevel
end
function BP_WeaponPawnBase:OnRep_CurrentWeaponId()
if self.OwnerCharacter == nil or UE.IsValid(self.OwnerCharacter) == false then
return
end
EventSystem:SendEvent(EventType.ClientUpdateWeapon, self.CurrentWeaponId, self.OwnerCharacter.PlayerKey)
if self.CurrentWeaponId > 0 then
self:ChangeWeaponId(self.CurrentWeaponId)
end
end
function BP_WeaponPawnBase:GetWeaponFittingsById(InItemId)
print(string.format("[BP_WeaponPawnBase:GetWeaponFittingsById] 开始输入Ids"))
if self:FindWeaponById(InItemId) == nil then
for i, v in pairs(self.Weapons) do
print(i)
end
end
print(string.format("[BP_WeaponPawnBase:GetWeaponFittingsById] 结束输入Ids"))
return self:FindWeaponById(InItemId).Fittings
end
function BP_WeaponPawnBase:GetWeaponCount()
return #self:GetWeapons()
end
function BP_WeaponPawnBase:FindWeaponIndexById(InWeaponId)
local PSWeapons = self:GetWeapons()
for i = 1, #PSWeapons do
if PSWeapons[i].WeaponId == InWeaponId then
return i
end
end
return -1
end
function BP_WeaponPawnBase:GetWeapons()
return self:GetPlayerState().OwnerWeapons
end
function BP_WeaponPawnBase:FindWeaponIdByIndex(InIndex)
if InIndex <= 0 or InIndex > self:GetWeaponCount() then
return
end
return self:GetWeapons()[InIndex].WeaponId
end
function BP_WeaponPawnBase:GetCurrentWeaponIndex()
return self:FindWeaponIndexById(self.CurrentWeaponId)
end
-- SC
function BP_WeaponPawnBase:SetSphereSizeRadius(InAddNum)
self.Sphere:SetSphereRadius(self.DefaultSphereRadius + InAddNum, true)
end
--获取武器基础属性
function BP_WeaponPawnBase:GetWeaponBaseAttribute()
local OutTable = {}
local TheTable = DropItemMap.WeaponTable[EWeaponClassType.WT_Pistol].Props
OutTable = TableHelper.DeepCopyTable(TheTable)
if self.CurrentWeaponId == 0 then
-- 说明当前是手枪,不进行处理
return self:MergeOutTable(OutTable)
end
local Weapon = self:FindWeaponById(self.CurrentWeaponId)
--武器基础属性
local FittingLevel = Weapon.FittingLevel
if FittingLevel > 0 then
local Val = DropItemMap.WeaponTable[Weapon.Type].PlusProps[FittingLevel]
local ItemData = {
Type = Val.Type,
Value = Val.Value
}
table.insert(OutTable, ItemData)
end
-- FittingItems
local FittingList = Weapon.Fittings
for i = 1, #FittingList do
local FittingItemId = FittingList[i]
local FittingProps = DropItemMap.FittingItemMap[FittingItemId].Props
for j = 1, #FittingProps do
if FittingProps[j].Unit ~= 'Special' then
local ItemData = {
Type = FittingProps[j].Type,
Value = FittingProps[j].Value
}
table.insert(OutTable, ItemData)
end
end
end
return self:MergeOutTable(OutTable)
end
--获取武器高级属性
function BP_WeaponPawnBase:GetWeaponSeniorAttribute()
local OutTable = {}
if self.CurrentWeaponId == 0 then
return {}
end
local Weapon = self:FindWeaponById(self.CurrentWeaponId)
local Properties = Weapon.Properties
for i = 1, #Properties do
local Prop = Properties[i]
local ItemData = {
Type = Tables.WeaponPropertyConfig[Prop.MainType].PropName,
Value = Prop.Value
}
table.insert(OutTable, ItemData)
end
for i = 1, table.getCount(Weapon.NativeProps.Plus) do
local Val = Weapon.NativeProps.Plus[i]
local Name = Tables.WeaponPropertyConfig[Val.MainType].PropName
local ItemData = {
Type = Name,
Value = Val.Value
}
table.insert(OutTable, ItemData)
end
return self:MergeOutTable(OutTable)
end
-- 叠加属性
function BP_WeaponPawnBase:MergeOutTable(InOutTable)
local Items = {}
for i = 1, table.getCount(InOutTable) do
local Name = InOutTable[i].Type
local Value = InOutTable[i].Value
if Items[Name] == nil then
Items[Name] = Value
else
Items[Name] = Items[Name] + Value
end
end
local OutTable = {}
for i, v in pairs(Items) do
if string.len(i) < 10 then
local ItemData = {
Type = i,
Value = v
}
table.insert(OutTable, ItemData)
end
end
return OutTable
end
function BP_WeaponPawnBase:Client_MulticastRPC_PlayMuzzleEffectAndSound(SoundConfigId)
if self.OwnerCharacter then
SoundManager.PlaySoundAtLocation(SoundConfigId, self.OwnerCharacter:K2_GetActorLocation(), self.OwnerCharacter:K2_GetActorRotation())
end
if self.MuzzleParticle and self.MainMesh then
GameplayStatics.SpawnEmitterAttached(self.MuzzleParticle, self.MainMesh, "MuzzleEffect", VectorHelper.VectorZero(), VectorHelper.RotZero(), VectorHelper.Scale(0.5), EAttachLocation.SnapToTarget, true)
end
end
return BP_WeaponPawnBase;