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

831 lines
27 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

---@class BP_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;