From 245eb9e55237897572b61f59ba09c93723847b38 Mon Sep 17 00:00:00 2001 From: ForrestMarkX Date: Thu, 9 Jan 2020 05:05:13 -0600 Subject: [PATCH] Updated to the latest KF version --- ServerExt/Classes/ExtAutoPurchaseHelper.uc | 2 +- ServerExt/Classes/ExtCharacterInfo.uc | 961 +++++++++++------- ServerExt/Classes/ExtHUD_PlayerStatus.uc | 9 +- ServerExt/Classes/ExtMenu_Gear.uc | 943 ++++++++--------- ServerExt/Classes/ExtMoviePlayer_HUD.uc | 4 +- ServerExt/Classes/ExtPlayerController.uc | 14 +- ServerExt/Classes/ExtPlayerReplicationInfo.uc | 31 +- ServerExt/Classes/ExtWidget_PartyInGame.uc | 8 +- ServerExt/Classes/Ext_PerkBase.uc | 2 +- ServerExt/Classes/KFExtendedHUD.uc | 470 +++++---- ServerExt/Classes/SRPerkManager.uc | 5 + ServerExtMut/Classes/ServerExtMut.uc | 3 +- 12 files changed, 1408 insertions(+), 1044 deletions(-) create mode 100644 ServerExt/Classes/SRPerkManager.uc diff --git a/ServerExt/Classes/ExtAutoPurchaseHelper.uc b/ServerExt/Classes/ExtAutoPurchaseHelper.uc index d3237b1..ca12aca 100644 --- a/ServerExt/Classes/ExtAutoPurchaseHelper.uc +++ b/ServerExt/Classes/ExtAutoPurchaseHelper.uc @@ -230,7 +230,7 @@ function int AddItemByPriority( out SItemInformation WeaponInfo ) return BestIndex; } -function bool CanCarry( const out STraderItem Item ) +function bool CanCarry(const out STraderItem Item, optional int OverrideLevelValue = INDEX_NONE) { local int Result; diff --git a/ServerExt/Classes/ExtCharacterInfo.uc b/ServerExt/Classes/ExtCharacterInfo.uc index 0445bb2..0727753 100644 --- a/ServerExt/Classes/ExtCharacterInfo.uc +++ b/ServerExt/Classes/ExtCharacterInfo.uc @@ -1,473 +1,682 @@ // Only a helper class to hold code. class ExtCharacterInfo extends Object - abstract; + abstract; // Hack fix for not being able to compile materials in run-time. static final function CloneMIC( MaterialInstanceConstant B ) { - local int i; - local MaterialInstanceConstant M; - local LinearColor C; - - M = MaterialInstanceConstant(B.Parent); - if( M==None ) - return; - B.SetParent(M.Parent); - - for( i=0; i 0 ) - { - // Assign a skin to the body mesh as a material override - CurrentBodyMeshIndex = (CurrentBodyMeshIndex < C.BodyVariants.length) ? CurrentBodyMeshIndex : 0; + //Always use default body on servers + if (KFP.WorldInfo.NetMode == NM_DedicatedServer) + { + CurrentBodyMeshIndex = 0; + CurrentBodySkinIndex = 0; + } - // Load the meshes - CharBodyMesh = SkeletalMesh(SafeLoadObject(C.BodyVariants[CurrentBodyMeshIndex].MeshName, class'SkeletalMesh')); + // Character Mesh + if( C.BodyVariants.length > 0 ) + { + // Assign a skin to the body mesh as a material override + CurrentBodyMeshIndex = (CurrentBodyMeshIndex < C.BodyVariants.length) ? CurrentBodyMeshIndex : 0; + + if (KFPRI.StartLoadCosmeticContent(C, ECOSMETICTYPE_Body, CurrentBodyMeshIndex)) + { + return; + } - // Assign the body mesh to the pawn - KFP.Mesh.SetSkeletalMesh(CharBodyMesh); + // Retrieve the name of the meshes to be used from the archetype + CharBodyMeshName = C.BodyVariants[CurrentBodyMeshIndex].MeshName; - if (KFP.WorldInfo.NetMode != NM_DedicatedServer) - { - SetBodySkinMaterial(C, C.BodyVariants[CurrentBodyMeshIndex], CurrentBodySkinIndex, KFP); - } - } - else - { - `warn("Character does not have a valid mesh"); - } + // Load the meshes + CharBodyMesh = SkeletalMesh(SafeLoadObject(CharBodyMeshName, class'SkeletalMesh')); + + // Assign the body mesh to the pawn + if ( CharBodyMesh != KFP.Mesh.SkeletalMesh ) + { + KFP.Mesh.SetSkeletalMesh(CharBodyMesh); + KFP.OnCharacterMeshChanged(); + } + + if (KFP.WorldInfo.NetMode != NM_DedicatedServer) + { + SetBodySkinMaterial(C, C.BodyVariants[CurrentBodyMeshIndex], CurrentBodySkinIndex, KFP); + } + } + else + { + `warn("Character does not have a valid mesh"); + } } static final function SetBodySkinMaterial( KFCharacterInfo_Human C, OutfitVariants CurrentVariant, byte NewSkinIndex, KFPawn KFP) { - local int i; + local int i; - if (KFP.WorldInfo.NetMode != NM_DedicatedServer) - { - if( CurrentVariant.SkinVariations.length > 0 ) - { - // Assign a skin to the body mesh as a material override - NewSkinIndex = (NewSkinIndex < CurrentVariant.SkinVariations.length) ? NewSkinIndex : 0; - KFP.Mesh.SetMaterial(C.BodyMaterialID, CurrentVariant.SkinVariations[NewSkinIndex].Skin); - } - else - { - // Use material specified in the mesh asset - for( i=0; i 0 ) + { + // Assign a skin to the body mesh as a material override + NewSkinIndex = (NewSkinIndex < CurrentVariant.SkinVariations.length) ? NewSkinIndex : 0; + KFP.Mesh.SetMaterial(C.BodyMaterialID, CurrentVariant.SkinVariations[NewSkinIndex].Skin); + } + else + { + // Use material specified in the mesh asset + for( i=0; i 0 ) - { - // Assign a skin to the body mesh as a material override - NewSkinIndex = (NewSkinIndex < CurrentVariant.SkinVariations.length) ? NewSkinIndex : 0; - KFP.ThirdPersonHeadMeshComponent.SetMaterial(C.HeadMaterialID, CurrentVariant.SkinVariations[NewSkinIndex].Skin); - } - else - { - // Use material specified in the mesh asset - for( i=0; i 0 ) + { + // Assign a skin to the body mesh as a material override + NewSkinIndex = (NewSkinIndex < CurrentVariant.SkinVariations.length) ? NewSkinIndex : 0; + KFP.ThirdPersonHeadMeshComponent.SetMaterial(C.HeadMaterialID, CurrentVariant.SkinVariations[NewSkinIndex].Skin); + } + else + { + // Use material specified in the mesh asset + for( i=0; i 0 ) - { - CurrentHeadMeshIndex = (CurrentHeadMeshIndex < C.HeadVariants.length) ? CurrentHeadMeshIndex : 0; + if ( C.HeadVariants.length > 0 ) + { + CurrentHeadMeshIndex = (CurrentHeadMeshIndex < C.HeadVariants.length) ? CurrentHeadMeshIndex : 0; + + if (KFPRI.StartLoadCosmeticContent(C, ECOSMETICTYPE_Head, CurrentHeadMeshIndex)) + { + return; + } - CharHeadMeshName = C.HeadVariants[CurrentHeadMeshIndex].MeshName; - CharHeadMesh = SkeletalMesh(DynamicLoadObject(CharHeadMeshName, class'SkeletalMesh')); + CharHeadMeshName = C.HeadVariants[CurrentHeadMeshIndex].MeshName; + CharHeadMesh = SkeletalMesh(DynamicLoadObject(CharHeadMeshName, class'SkeletalMesh')); - // Parent the third person head mesh to the body mesh - KFP.ThirdPersonHeadMeshComponent.SetSkeletalMesh(CharHeadMesh); - KFP.ThirdPersonHeadMeshComponent.SetScale(C.DefaultMeshScale); + // Parent the third person head mesh to the body mesh + KFP.ThirdPersonHeadMeshComponent.SetSkeletalMesh(CharHeadMesh); + KFP.ThirdPersonHeadMeshComponent.SetScale(C.DefaultMeshScale); - KFP.ThirdPersonHeadMeshComponent.SetParentAnimComponent(KFP.Mesh); - KFP.ThirdPersonHeadMeshComponent.SetShadowParent(KFP.Mesh); - KFP.ThirdPersonHeadMeshComponent.SetLODParent(KFP.Mesh); + KFP.ThirdPersonHeadMeshComponent.SetParentAnimComponent(KFP.Mesh); + KFP.ThirdPersonHeadMeshComponent.SetShadowParent(KFP.Mesh); + KFP.ThirdPersonHeadMeshComponent.SetLODParent(KFP.Mesh); - KFP.AttachComponent(KFP.ThirdPersonHeadMeshComponent); + KFP.AttachComponent(KFP.ThirdPersonHeadMeshComponent); - if (KFP.WorldInfo.NetMode != NM_DedicatedServer) - { - SetHeadSkinMaterial(C, C.HeadVariants[CurrentHeadMeshIndex], CurrentHeadSkinIndex, KFP); - } - } + if (KFP.WorldInfo.NetMode != NM_DedicatedServer) + { + SetHeadSkinMaterial(C, C.HeadVariants[CurrentHeadMeshIndex], CurrentHeadSkinIndex, KFP); + } + } } static final function SetAttachmentSkinMaterial( KFCharacterInfo_Human C, - int PawnAttachmentIndex, - const out AttachmentVariants CurrentVariant, - byte NewSkinIndex, - KFPawn KFP) + int PawnAttachmentIndex, + const out AttachmentVariants CurrentVariant, + byte NewSkinIndex, + KFPawn KFP, + optional bool bIsFirstPerson) { - local int i; - if (KFP.WorldInfo.NetMode != NM_DedicatedServer) - { - if( CurrentVariant.AttachmentItem.SkinVariations.length > 0 ) - { - // Assign a skin to the attachment mesh as a material override - if ( NewSkinIndex < CurrentVariant.AttachmentItem.SkinVariations.length ) - { - KFP.ThirdPersonAttachments[PawnAttachmentIndex].SetMaterial( - CurrentVariant.AttachmentItem.SkinMaterialID, - CurrentVariant.AttachmentItem.SkinVariations[NewSkinIndex].Skin); - } - else - { - `log("Out of bounds skin index for"@CurrentVariant.MeshName); - C.RemoveAttachmentMeshAndSkin(PawnAttachmentIndex, KFP); - } - } - else - { - // Use material specified in the mesh asset - for( i=0; i < KFP.ThirdPersonAttachments[PawnAttachmentIndex].GetNumElements(); i++ ) - { - KFP.ThirdPersonAttachments[PawnAttachmentIndex].SetMaterial(i, none); - } - } - } + local int i; + if (KFP.WorldInfo.NetMode != NM_DedicatedServer) + { + if( CurrentVariant.AttachmentItem.SkinVariations.length > 0 ) + { + // Assign a skin to the attachment mesh as a material override + if ( NewSkinIndex < CurrentVariant.AttachmentItem.SkinVariations.length ) + { + if (bIsFirstPerson) + { + if (KFP.FirstPersonAttachments[PawnAttachmentIndex] != none) + { + KFP.FirstPersonAttachments[PawnAttachmentIndex].SetMaterial( + CurrentVariant.AttachmentItem.SkinMaterialID, + CurrentVariant.AttachmentItem.SkinVariations[NewSkinIndex].Skin1p); + } + } + else + { + KFP.ThirdPersonAttachments[PawnAttachmentIndex].SetMaterial( + CurrentVariant.AttachmentItem.SkinMaterialID, + CurrentVariant.AttachmentItem.SkinVariations[NewSkinIndex].Skin); + } + } + else + { + `log("Out of bounds skin index for"@CurrentVariant.MeshName); + C.RemoveAttachmentMeshAndSkin(PawnAttachmentIndex, KFP); + } + } + else + { + if (bIsFirstPerson) + { + if (KFP.FirstPersonAttachments[PawnAttachmentIndex] != none) + { + for (i = 0; i < KFP.FirstPersonAttachments[PawnAttachmentIndex].GetNumElements(); i++) + { + KFP.FirstPersonAttachments[PawnAttachmentIndex].SetMaterial(i, none); + } + } + } + else + { + // Use material specified in the mesh asset + for( i=0; i < KFP.ThirdPersonAttachments[PawnAttachmentIndex].GetNumElements(); i++ ) + { + KFP.ThirdPersonAttachments[PawnAttachmentIndex].SetMaterial(i, none); + } + } + } + } } -/** Called on owning client to change a cosmetic attachment or on other clients via replication */ static final function SetAttachmentMeshAndSkin( KFCharacterInfo_Human C, - byte CurrentAttachmentMeshIndex, - byte CurrentAttachmentSkinIndex, - KFPawn KFP, - optional KFPlayerReplicationInfo KFPRI ) + int CurrentAttachmentMeshIndex, + int CurrentAttachmentSkinIndex, + KFPawn KFP, + KFPlayerReplicationInfo KFPRI, + optional bool bIsFirstPerson ) { - local string CharAttachmentMeshName; - local name CharAttachmentSocketName; - local bool bIsSkeletalAttachment; - local StaticMesh CharAttachmentStaticMesh; - local SkeletalMesh CharacterAttachmentSkelMesh; - local float MaxDrawDistance; - local StaticMeshComponent StaticAttachment; - local SkeletalMeshComponent SkeletalAttachment; - local SkeletalMeshSocket AttachmentSocket; - local vector AttachmentLocationRelativeToSocket, AttachmentScaleRelativeToSocket; - local rotator AttachmentRotationRelativeToSocket; - local int AttachmentSlotIndex; + local string CharAttachmentMeshName; + local name CharAttachmentSocketName; + local int AttachmentSlotIndex; + local SkeletalMeshComponent AttachmentMesh; - if (KFP.WorldInfo.NetMode == NM_DedicatedServer) - { - return; - } + if (KFP.WorldInfo.NetMode == NM_DedicatedServer) + { + return; + } - // Clear any previously attachments for the same slot - //DetachConflictingAttachments(CurrentAttachmentMeshIndex, KFP, KFPRI); - // Get a slot where this attachment could fit - AttachmentSlotIndex = C.GetAttachmentSlotIndex(CurrentAttachmentMeshIndex, KFP); + // Clear any previously attachments for the same slot + //DetachConflictingAttachments(CurrentAttachmentMeshIndex, KFP, KFPRI); + // Get a slot where this attachment could fit + AttachmentSlotIndex = GetAttachmentSlotIndex(C, CurrentAttachmentMeshIndex, KFP, KFPRI); + + if (AttachmentSlotIndex == INDEX_NONE) + { + return; + } - // Since cosmetic attachments are optional, do not choose index 0 if none is - // specified unlike the the head and body meshes - if ( C.CosmeticVariants.length > 0 && - CurrentAttachmentMeshIndex < C.CosmeticVariants.length ) - { - // Cache values from character info - CharAttachmentMeshName = C.GetMeshByIndex(CurrentAttachmentMeshIndex); - CharAttachmentSocketName = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.SocketName; - MaxDrawDistance = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.MaxDrawDistance; - AttachmentLocationRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeTranslation; - AttachmentRotationRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeRotation; - AttachmentScaleRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeScale; - bIsSkeletalAttachment = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.bIsSkeletalAttachment; + // Since cosmetic attachments are optional, do not choose index 0 if none is + // specified unlike the the head and body meshes + if ( C.CosmeticVariants.Length > 0 && + CurrentAttachmentMeshIndex < C.CosmeticVariants.Length ) + { + if (KFPRI.StartLoadCosmeticContent(C, ECOSMETICTYPE_Attachment, CurrentAttachmentMeshIndex)) + { + return; + } + + // Cache values from character info + CharAttachmentMeshName = bIsFirstPerson ? C.Get1pMeshByIndex(CurrentAttachmentMeshIndex) : C.GetMeshByIndex(CurrentAttachmentMeshIndex); + CharAttachmentSocketName = bIsFirstPerson ? C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.SocketName1p : C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.SocketName; + AttachmentMesh = bIsFirstPerson ? KFP.ArmsMesh : KFP.Mesh; - // If previously attached and we could have changed outfits (e.g. local player UI) then re-validate - // required skeletal mesh socket. Must be after body mesh DLO, but before AttachComponent. - if ( KFP.IsLocallyControlled() ) - { - if ( CharAttachmentSocketName != '' && KFP.Mesh.GetSocketByName(CharAttachmentSocketName) == None ) - { - C.RemoveAttachmentMeshAndSkin(AttachmentSlotIndex, KFP, KFPRI); - return; - } - } + // If previously attached and we could have changed outfits (e.g. local player UI) then re-validate + // required skeletal mesh socket. Must be after body mesh DLO, but before AttachComponent. + if ( KFP.IsLocallyControlled() ) + { + if ( CharAttachmentSocketName != '' && KFP.Mesh.GetSocketByName(CharAttachmentSocketName) == None ) + { + C.RemoveAttachmentMeshAndSkin(AttachmentSlotIndex, KFP, KFPRI); + return; + } + } - //`log("AttachmentLocationRelativeToSocket: x="$AttachmentLocationRelativeToSocket.x@"y="$AttachmentLocationRelativeToSocket.y@"z="$AttachmentLocationRelativeToSocket.z); - // If it is a skeletal attachment, parent anim it to the body mesh - if( bIsSkeletalAttachment ) - { - if( SkeletalMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]) != none ) - { - SkeletalAttachment = SkeletalMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]); - } - else - { - SkeletalAttachment = new(KFP) class'SkeletalMeshComponent'; - SkeletalAttachment.SetActorCollision(false, false); - KFP.ThirdPersonAttachments[AttachmentSlotIndex] = SkeletalAttachment; - } + // Set First Person Cosmetic if mesh exists for it. + if(CharAttachmentMeshName != "") + { + // Set Cosmetic Mesh + SetAttachmentMesh(C, CurrentAttachmentMeshIndex, AttachmentSlotIndex, CharAttachmentMeshName, CharAttachmentSocketName, AttachmentMesh, KFP, bIsFirstPerson); + } + else + { + // Make sure to clear out attachment if we're replacing with nothing. + if(bIsFirstPerson) + { + KFP.FirstPersonAttachments[AttachmentSlotIndex] = none; + KFP.FirstPersonAttachmentSocketNames[AttachmentSlotIndex] = ''; + } + } - // Load and assign skeletal mesh - CharacterAttachmentSkelMesh = SkeletalMesh(DynamicLoadObject(CharAttachmentMeshName, class'SkeletalMesh')); - SkeletalAttachment.SetSkeletalMesh(CharacterAttachmentSkelMesh); + // Set Cosmetic Skin + SetAttachmentSkinMaterial( + C, + AttachmentSlotIndex, + C.CosmeticVariants[CurrentAttachmentMeshIndex], + CurrentAttachmentSkinIndex, + KFP, + bIsFirstPerson); + } - // Parent animation and LOD transitions to body mesh - SkeletalAttachment.SetParentAnimComponent(KFP.Mesh); - SkeletalAttachment.SetLODParent(KFP.Mesh); - SkeletalAttachment.SetScale(C.DefaultMeshScale); - SkeletalAttachment.SetCullDistance(MaxDrawDistance); - SkeletalAttachment.SetShadowParent(KFP.Mesh); - SkeletalAttachment.SetLightingChannels(KFP.PawnLightingChannel); + // Treat `CLEARED_ATTACHMENT_INDEX as special value (for client detachment) + if( CurrentAttachmentMeshIndex == `CLEARED_ATTACHMENT_INDEX ) + { + C.RemoveAttachmentMeshAndSkin(AttachmentSlotIndex, KFP, KFPRI); + } +} - // Attach - KFP.AttachComponent(SkeletalAttachment); - } - // Otherwise (if static), attach to a socket on the body mesh - else - { - if( StaticMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]) != none ) - { - StaticAttachment = StaticMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]); - } - else - { - StaticAttachment = new(KFP) class'StaticMeshComponent'; - StaticAttachment.SetActorCollision(false, false); - KFP.ThirdPersonAttachments[AttachmentSlotIndex] = StaticAttachment; - } +static final function SetAttachmentMesh(KFCharacterInfo_Human C, int CurrentAttachmentMeshIndex, int AttachmentSlotIndex, string CharAttachmentMeshName, name CharAttachmentSocketName, SkeletalMeshComponent PawnMesh, KFPawn KFP, bool bIsFirstPerson = false) +{ + local StaticMeshComponent StaticAttachment; + local SkeletalMeshComponent SkeletalAttachment; + local bool bIsSkeletalAttachment; + local StaticMesh CharAttachmentStaticMesh; + local SkeletalMesh CharacterAttachmentSkelMesh; + local float MaxDrawDistance; + local SkeletalMeshSocket AttachmentSocket; + local vector AttachmentLocationRelativeToSocket, AttachmentScaleRelativeToSocket; + local rotator AttachmentRotationRelativeToSocket; - // Load and assign static mesh - CharAttachmentStaticMesh = StaticMesh(DynamicLoadObject(CharAttachmentMeshName, class'StaticMesh')); - StaticAttachment.SetStaticMesh(CharAttachmentStaticMesh); + MaxDrawDistance = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.MaxDrawDistance; + AttachmentLocationRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeTranslation; + AttachmentRotationRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeRotation; + AttachmentScaleRelativeToSocket = C.CosmeticVariants[CurrentAttachmentMeshIndex].RelativeScale; + bIsSkeletalAttachment = C.CosmeticVariants[CurrentAttachmentMeshIndex].AttachmentItem.bIsSkeletalAttachment; - // Set properties - StaticAttachment.SetScale(C.DefaultMeshScale); - StaticAttachment.SetCullDistance(MaxDrawDistance); - StaticAttachment.SetShadowParent(KFP.Mesh); - StaticAttachment.SetLightingChannels(KFP.PawnLightingChannel); + //`log("AttachmentLocationRelativeToSocket: x="$AttachmentLocationRelativeToSocket.x@"y="$AttachmentLocationRelativeToSocket.y@"z="$AttachmentLocationRelativeToSocket.z); + // If it is a skeletal attachment, parent anim it to the body mesh + if (bIsSkeletalAttachment) + { + if (bIsFirstPerson && (SkeletalMeshComponent(KFP.FirstPersonAttachments[AttachmentSlotIndex]) != none)) + { + SkeletalAttachment = SkeletalMeshComponent(KFP.FirstPersonAttachments[AttachmentSlotIndex]); + } + else if (!bIsFirstPerson && (SkeletalMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]) != none)) + { + SkeletalAttachment = SkeletalMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]); + } + else + { + SkeletalAttachment = new(KFP) class'KFSkeletalMeshComponent'; + if (bIsFirstPerson) + { + C.SetFirstPersonCosmeticAttachment(SkeletalAttachment); + } + SkeletalAttachment.SetActorCollision(false, false); - // For static meshes, attach to given socket - AttachmentSocket = KFP.mesh.GetSocketByName(CharAttachmentSocketName); - KFP.mesh.AttachComponent( - StaticAttachment, - AttachmentSocket.BoneName, - AttachmentSocket.RelativeLocation + AttachmentLocationRelativeToSocket, - AttachmentSocket.RelativeRotation + AttachmentRotationRelativeToSocket, - AttachmentSocket.RelativeScale * AttachmentScaleRelativeToSocket); - } + if(bIsFirstPerson) + { + KFP.FirstPersonAttachments[AttachmentSlotIndex] = SkeletalAttachment; + } + else + { + KFP.ThirdPersonAttachments[AttachmentSlotIndex] = SkeletalAttachment; + } + } - // Update the pawn's attachment metadata - KFP.ThirdPersonAttachmentBitMask = KFP.ThirdPersonAttachmentBitMask | (1 << AttachmentSlotIndex); - KFP.ThirdPersonAttachmentSocketNames[AttachmentSlotIndex] = CharAttachmentSocketName; + // Load and assign skeletal mesh + CharacterAttachmentSkelMesh = SkeletalMesh(DynamicLoadObject(CharAttachmentMeshName, class'SkeletalMesh')); + SkeletalAttachment.SetSkeletalMesh(CharacterAttachmentSkelMesh); - SetAttachmentSkinMaterial( - C, - AttachmentSlotIndex, - C.CosmeticVariants[CurrentAttachmentMeshIndex], - CurrentAttachmentSkinIndex, - KFP); - } + // Parent animation and LOD transitions to body mesh + SkeletalAttachment.SetParentAnimComponent(PawnMesh); + SkeletalAttachment.SetLODParent(PawnMesh); + SkeletalAttachment.SetScale(C.DefaultMeshScale); + SkeletalAttachment.SetCullDistance(MaxDrawDistance); + SkeletalAttachment.SetShadowParent(PawnMesh); + SkeletalAttachment.SetLightingChannels(KFP.PawnLightingChannel); - // Treat `CLEARED_ATTACHMENT_INDEX as special value (for client detachment) - if( CurrentAttachmentMeshIndex == `CLEARED_ATTACHMENT_INDEX ) - { - C.RemoveAttachmentMeshAndSkin(AttachmentSlotIndex, KFP, KFPRI); - } + KFP.AttachComponent(SkeletalAttachment); + } + // Otherwise (if static), attach to a socket on the body mesh + else + { + if (!bIsFirstPerson && (StaticMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]) != none)) + { + StaticAttachment = StaticMeshComponent(KFP.ThirdPersonAttachments[AttachmentSlotIndex]); + } + else if (bIsFirstPerson && (StaticMeshComponent(KFP.FirstPersonAttachments[AttachmentSlotIndex]) != none)) + { + StaticAttachment = StaticMeshComponent(KFP.FirstPersonAttachments[AttachmentSlotIndex]); + } + else + { + StaticAttachment = new(KFP) class'StaticMeshComponent'; + StaticAttachment.SetActorCollision(false, false); + + if(bIsFirstPerson) + { + KFP.FirstPersonAttachments[AttachmentSlotIndex] = StaticAttachment; + } + else + { + KFP.ThirdPersonAttachments[AttachmentSlotIndex] = StaticAttachment; + } + } + + // Load and assign static mesh + CharAttachmentStaticMesh = StaticMesh(DynamicLoadObject(CharAttachmentMeshName, class'StaticMesh')); + StaticAttachment.SetStaticMesh(CharAttachmentStaticMesh); + + // Set properties + StaticAttachment.SetScale(C.DefaultMeshScale); + StaticAttachment.SetCullDistance(MaxDrawDistance); + StaticAttachment.SetShadowParent(KFP.Mesh); + StaticAttachment.SetLightingChannels(KFP.PawnLightingChannel); + + // For static meshes, attach to given socket + AttachmentSocket = PawnMesh.GetSocketByName(CharAttachmentSocketName); + PawnMesh.AttachComponent( + StaticAttachment, + AttachmentSocket.BoneName, + AttachmentSocket.RelativeLocation + AttachmentLocationRelativeToSocket, + AttachmentSocket.RelativeRotation + AttachmentRotationRelativeToSocket, + AttachmentSocket.RelativeScale * AttachmentScaleRelativeToSocket); + } + + if(bIsFirstPerson) + { + KFP.FirstPersonAttachmentSocketNames[AttachmentSlotIndex] = CharAttachmentSocketName; + } + else + { + KFP.ThirdPersonAttachmentSocketNames[AttachmentSlotIndex] = CharAttachmentSocketName; + } } /** * Removes any attachments that exist in the same socket or have overriding cases * Network: Local Player */ -static final function DetachConflictingAttachments( KFCharacterInfo_Human C, byte NewAttachmentMeshIndex, KFPawn KFP, optional KFPlayerReplicationInfo KFPRI) +static final function DetachConflictingAttachments( KFCharacterInfo_Human C, int NewAttachmentMeshIndex, KFPawn KFP, optional KFPlayerReplicationInfo KFPRI) { - local name NewAttachmentSocketName; - local int i, CurrentAttachmentIdx; - local ExtPlayerReplicationInfo EPRI; + local name NewAttachmentSocketName; + local int i, CurrentAttachmentIdx; + local ExtPlayerReplicationInfo EPRI; - EPRI = ExtPlayerReplicationInfo(KFPRI); - if ( EPRI==none || !EPRI.UsesCustomChar() ) - return; + EPRI = ExtPlayerReplicationInfo(KFPRI); + if ( EPRI==none || !EPRI.UsesCustomChar() ) + return; - if ( C.CosmeticVariants.length > 0 && - NewAttachmentMeshIndex < C.CosmeticVariants.length ) - { - // The socket that this attachment requires - NewAttachmentSocketName = C.CosmeticVariants[NewAttachmentMeshIndex].SocketName; + if ( C.CosmeticVariants.length > 0 && + NewAttachmentMeshIndex < C.CosmeticVariants.length ) + { + // The socket that this attachment requires + NewAttachmentSocketName = C.CosmeticVariants[NewAttachmentMeshIndex].AttachmentItem.SocketName; - for( i=0; i < `MAX_COSMETIC_ATTACHMENTS; i++ ) - { - CurrentAttachmentIdx = EPRI.CustomCharacter.AttachmentMeshIndices[i]; - if ( CurrentAttachmentIdx == `CLEARED_ATTACHMENT_INDEX ) - continue; + for( i=0; i < `MAX_COSMETIC_ATTACHMENTS; i++ ) + { + CurrentAttachmentIdx = EPRI.CustomCharacter.AttachmentMeshIndices[i]; + if ( CurrentAttachmentIdx == `CLEARED_ATTACHMENT_INDEX ) + continue; - // Remove the object if it is taking up our desired slot - if( KFP.ThirdPersonAttachmentSocketNames[i] != '' && - KFP.ThirdPersonAttachmentSocketNames[i] == NewAttachmentSocketName ) - { - C.RemoveAttachmentMeshAndSkin(i, KFP, KFPRI); - continue; - } + // Remove the object if it is taking up our desired slot + if( KFP.ThirdPersonAttachmentSocketNames[i] != '' && + KFP.ThirdPersonAttachmentSocketNames[i] == NewAttachmentSocketName ) + { + C.RemoveAttachmentMeshAndSkin(i, KFP, KFPRI); + continue; + } - // Remove the object if it cannot exist at the same time as another equipped item - if( C.GetOverrideCase(CurrentAttachmentIdx, NewAttachmentMeshIndex) ) - { - C.RemoveAttachmentMeshAndSkin(i, KFP, KFPRI); - continue; - } + // Remove the object if it cannot exist at the same time as another equipped item + if( C.GetOverrideCase(CurrentAttachmentIdx, NewAttachmentMeshIndex) ) + { + C.RemoveAttachmentMeshAndSkin(i, KFP, KFPRI); + continue; + } - // Check inverse override - if( C.GetOverrideCase(NewAttachmentMeshIndex, CurrentAttachmentIdx) ) - { - C.RemoveAttachmentMeshAndSkin(i, KFP, KFPRI); - continue; - } - } - } + // Check inverse override + if( C.GetOverrideCase(NewAttachmentMeshIndex, CurrentAttachmentIdx) ) + { + C.RemoveAttachmentMeshAndSkin(i, KFP, KFPRI); + continue; + } + } + } } /** Assign an arm mesh and material to this pawn */ static final function SetFirstPersonArmsFromArch( KFCharacterInfo_Human C, KFPawn KFP, optional KFPlayerReplicationInfo KFPRI ) { - local MaterialInstanceConstant M; - local ExtPlayerReplicationInfo EPRI; - local bool bCustom; + local MaterialInstanceConstant M; + local ExtPlayerReplicationInfo EPRI; + local bool bCustom; + local int AttachmentIdx, CosmeticMeshIdx; - EPRI = ExtPlayerReplicationInfo(KFPRI); - if ( KFPRI == none ) - { + if ( KFPRI == none ) + { `Warn("Does not have a KFPRI" @ C); - return; - } - bCustom = (EPRI!=None ? EPRI.UsesCustomChar() : false); + return; + } + EPRI = ExtPlayerReplicationInfo(KFPRI); + bCustom = (EPRI!=None ? EPRI.UsesCustomChar() : false); - // First person arms mesh and skin are based on body mesh & skin. - // Index of 255 implies use index 0 (default). - C.SetArmsMeshAndSkin( - bCustom ? EPRI.CustomCharacter.BodyMeshIndex : KFPRI.RepCustomizationInfo.BodyMeshIndex, - bCustom ? EPRI.CustomCharacter.BodySkinIndex : KFPRI.RepCustomizationInfo.BodySkinIndex, - KFP); - - // Hack fix for a material bug on KF2 - if( bCustom && KFP.ArmsMesh.SkeletalMesh!=None && KFP.ArmsMesh.GetMaterial(0)!=None ) - { - M = KFP.ArmsMesh.CreateAndSetMaterialInstanceConstant(0); - CloneMIC(M); - } + // First person arms mesh and skin are based on body mesh & skin. + // Index of 255 implies use index 0 (default). + C.SetArmsMeshAndSkin( + bCustom ? EPRI.CustomCharacter.BodyMeshIndex : KFPRI.RepCustomizationInfo.BodyMeshIndex, + bCustom ? EPRI.CustomCharacter.BodySkinIndex : KFPRI.RepCustomizationInfo.BodySkinIndex, + KFP, + KFPRI); + + for (AttachmentIdx = 0; AttachmentIdx < `MAX_COSMETIC_ATTACHMENTS; AttachmentIdx++) + { + CosmeticMeshIdx = bCustom ? EPRI.CustomCharacter.AttachmentMeshIndices[AttachmentIdx] : KFPRI.RepCustomizationInfo.AttachmentMeshIndices[AttachmentIdx]; + if (CosmeticMeshIdx != `CLEARED_ATTACHMENT_INDEX && CosmeticMeshIdx != INDEX_NONE) + { + // Attach all saved attachments to the character + SetAttachmentMeshAndSkin( + C, + CosmeticMeshIdx, + bCustom ? EPRI.CustomCharacter.AttachmentSkinIndices[AttachmentIdx] : KFPRI.RepCustomizationInfo.AttachmentSkinIndices[AttachmentIdx], + KFP, KFPRI, true); + } + } + + // Hack fix for a material bug on KF2 + if( bCustom && KFP.ArmsMesh.SkeletalMesh!=None && KFP.ArmsMesh.GetMaterial(0)!=None ) + { + M = KFP.ArmsMesh.CreateAndSetMaterialInstanceConstant(0); + CloneMIC(M); + } } + +static function int GetAttachmentSlotIndex( + KFCharacterInfo_Human C, + int CurrentAttachmentMeshIndex, + KFPawn KFP, + KFPlayerReplicationInfo KFPRI) +{ + local int AttachmentIdx,CosmeticMeshIdx; + local ExtPlayerReplicationInfo EPRI; + local bool bCustom; + + if( KFPRI == None ) + { + `warn("GetAttachmentSlotIndex - NO KFPRI"); + return INDEX_NONE; + } + + EPRI = ExtPlayerReplicationInfo(KFPRI); + bCustom = (EPRI!=None ? EPRI.UsesCustomChar() : false); + + // Return the next available attachment index or the index that matches this mesh + for( AttachmentIdx = 0; AttachmentIdx < `MAX_COSMETIC_ATTACHMENTS; AttachmentIdx++ ) + { + CosmeticMeshIdx = bCustom ? EPRI.CustomCharacter.AttachmentMeshIndices[AttachmentIdx] : KFPRI.RepCustomizationInfo.AttachmentMeshIndices[AttachmentIdx]; + if( CosmeticMeshIdx == INDEX_NONE || CosmeticMeshIdx == CurrentAttachmentMeshIndex ) + { + return AttachmentIdx; + } + } + return INDEX_NONE; +} + +static function bool IsAttachmentAvailable(KFCharacterInfo_Human C, const out AttachmentVariants Attachment, Pawn PreviewPawn) +{ + if ( Attachment.AttachmentItem.SocketName != '' && PreviewPawn.Mesh.GetSocketByName(Attachment.AttachmentItem.SocketName) == None ) + { + return false; + } + + return true; +} \ No newline at end of file diff --git a/ServerExt/Classes/ExtHUD_PlayerStatus.uc b/ServerExt/Classes/ExtHUD_PlayerStatus.uc index f14c6fc..12fb9fa 100644 --- a/ServerExt/Classes/ExtHUD_PlayerStatus.uc +++ b/ServerExt/Classes/ExtHUD_PlayerStatus.uc @@ -14,6 +14,7 @@ function UpdatePerk() { local int CurrentPerkLevel,CurrentPerkEXP; local Ext_PerkBase CurrentPerk; + local GFxObject PerkIconObject; if( ExPC == none || ExPC.ActivePerkManager==None || ExPC.ActivePerkManager.CurrentPerk==None ) return; @@ -21,12 +22,16 @@ function UpdatePerk() CurrentPerk = ExPC.ActivePerkManager.CurrentPerk; CurrentPerkLevel = CurrentPerk.CurrentLevel; CurrentPerkEXP = CurrentPerk.CurrentEXP; - + // Update the perk class. if( ( ExLastPerkClass != CurrentPerk.Class ) || ( LastPerkLevel != CurrentPerkLevel ) ) { CurPerkPath = CurrentPerk.GetPerkIconPath(CurrentPerkLevel); - SetString("playerPerkIcon" , CurPerkPath); + + PerkIconObject = CreateObject("Object"); + PerkIconObject.SetString("perkIcon", CurPerkPath); + SetObject("playerPerkIcon", PerkIconObject); + SetInt("playerPerkXPPercent", CurrentPerk.GetProgressPercent() * 100.f ); if( LastPerkLevel != CurrentPerkLevel && ExLastPerkClass==CurrentPerk.Class ) { diff --git a/ServerExt/Classes/ExtMenu_Gear.uc b/ServerExt/Classes/ExtMenu_Gear.uc index 52254b0..c948271 100644 --- a/ServerExt/Classes/ExtMenu_Gear.uc +++ b/ServerExt/Classes/ExtMenu_Gear.uc @@ -14,631 +14,660 @@ var bool bWaitingCharList,bIsCustomChar; function InitializeMenu( KFGFxMoviePlayer_Manager InManager ) { - super(KFGFxObject_Menu).InitializeMenu(InManager); - LocalizeText(); - EmoteList = class'ExtEmoteList'.static.GetEmoteArray(); - InitCharacterMenu(); - TraderItems = KFGameReplicationInfo( GetPC().WorldInfo.GRI ).TraderItems; + super(KFGFxObject_Menu).InitializeMenu(InManager); + CheckForCustomizationPawn( GetPC() ); + LocalizeText(); + EmoteList = class'ExtEmoteList'.static.GetEmoteArray(); + InitCharacterMenu(); + TraderItems = KFGameReplicationInfo( GetPC().WorldInfo.GRI ).TraderItems; } function InitCharacterMenu() { - ExtPRI = ExtPlayerReplicationInfo(GetPC().PlayerReplicationInfo); - - if( ExtPRI!=None && ExtPRI.bClientInitChars ) - CharListRecieved(); - else if( ExtPRI==None ) - { - if( GetPC().PlayerReplicationInfo!=None ) // Faulty mod setup. - { - bWaitingCharList = true; - return; - } - GetPC().SetTimer(0.1,false,'InitCharacterMenu',Self); - } - else - { - ExtPRI.OnCharListDone = CharListRecieved; - bWaitingCharList = true; - } + ExtPRI = ExtPlayerReplicationInfo(GetPC().PlayerReplicationInfo); + + if( ExtPRI!=None && ExtPRI.bClientInitChars ) + CharListRecieved(); + else if( ExtPRI==None ) + { + if( GetPC().PlayerReplicationInfo!=None ) // Faulty mod setup. + { + bWaitingCharList = true; + return; + } + GetPC().SetTimer(0.1,false,'InitCharacterMenu',Self); + } + else + { + ExtPRI.OnCharListDone = CharListRecieved; + bWaitingCharList = true; + } } event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget) -{ - switch(WidgetName) - { - case 'perkSelectionContainer': - if ( PerkSelectionContainer == none ) - { - PerkSelectionContainer = KFGFxGearContainer_PerksSelection( Widget ); - PerkSelectionContainer.Initialize(self); - } - break; - } +{ + switch(WidgetName) + { + case 'perkSelectionContainer': + if ( PerkSelectionContainer == none ) + { + PerkSelectionContainer = KFGFxGearContainer_PerksSelection( Widget ); + PerkSelectionContainer.Initialize(self); + } + break; + } - return true; + return true; } function OnOpen() { - local PlayerController PC; + local PlayerController PC; - PC = GetPC(); - if( PC == none ) - return; - - // @hack: moved from KFGfxMoviePlayer_Manager because this causes a crash while - // bink (e.g. KFII-25456) are playing. Don't use HandleInputAxis with Bink! (for now) :) - GetGameViewportClient().HandleInputAxis = OnAxisModified; + PC = GetPC(); + if( PC == none ) + return; + + CheckForCustomizationPawn( PC ); + //GetGameViewportClient().HandleInputAxis = OnAxisModified; - if ( PC.PlayerReplicationInfo.bReadyToPlay && PC.WorldInfo.GRI.bMatchHasBegun ) - { - // Players cannot change characters if they are in a game - SetBool("characterButtonEnabled", false); - } + if ( PC.PlayerReplicationInfo.bReadyToPlay && PC.WorldInfo.GRI.bMatchHasBegun ) + { + // Players cannot change characters if they are in a game + SetBool("characterButtonEnabled", false); + } +} + +/** The customization pawn won't exist if this menu was opened mid-match */ +function CheckForCustomizationPawn( PlayerController PC ) +{ + local KFPlayerController KFPC; + + if( PC.Pawn == None || (!PC.Pawn.IsAliveAndWell() && KFPawn_Customization(PC.Pawn) == None) ) + { + KFPC = KFPlayerController( PC ); + if( KFPC != None ) + { + KFPC.SpawnMidGameCustomizationPawn(); + } + } } function LocalizeText() { - local GFxObject LocalizedObject; + local GFxObject LocalizedObject; - LocalizedObject = CreateObject("Object"); + LocalizedObject = CreateObject("Object"); - LocalizedObject.SetString("header", class'KFGFxMenu_Gear'.Default.GearHeaderString); - LocalizedObject.SetString("listButton", class'KFGFxMenu_Gear'.Default.BackString); - LocalizedObject.SetString("bioStringText", class'KFGFxMenu_Gear'.Default.BioString); - LocalizedObject.SetString("charactersString", class'KFGFxMenu_Gear'.Default.CharacterString); - LocalizedObject.SetString("headsString", class'KFGFxMenu_Gear'.Default.HeadString); - LocalizedObject.SetString("emoteString", Class'KFLocalMessage_VoiceComms'.default.VoiceCommsOptionStrings[8]); - LocalizedObject.SetString("bodiesString", class'KFGFxMenu_Gear'.Default.BodyString); - LocalizedObject.SetString("skinsString", class'KFGFxMenu_Gear'.Default.SkinsString); - LocalizedObject.SetString("attachmentsString", class'KFGFxMenu_Gear'.Default.AttachmentsString); + LocalizedObject.SetString("header", class'KFGFxMenu_Gear'.Default.GearHeaderString); + LocalizedObject.SetString("listButton", class'KFGFxMenu_Gear'.Default.BackString); + LocalizedObject.SetString("bioStringText", class'KFGFxMenu_Gear'.Default.BioString); + LocalizedObject.SetString("charactersString", class'KFGFxMenu_Gear'.Default.CharacterString); + LocalizedObject.SetString("headsString", class'KFGFxMenu_Gear'.Default.HeadString); + LocalizedObject.SetString("emoteString", Class'KFLocalMessage_VoiceComms'.default.VoiceCommsOptionStrings[8]); + LocalizedObject.SetString("bodiesString", class'KFGFxMenu_Gear'.Default.BodyString); + LocalizedObject.SetString("skinsString", class'KFGFxMenu_Gear'.Default.SkinsString); + LocalizedObject.SetString("attachmentsString", class'KFGFxMenu_Gear'.Default.AttachmentsString); - SetObject("localizeText", LocalizedObject); + SetObject("localizeText", LocalizedObject); } simulated function CharListRecieved() { - UpdateCharacterList(); - UpdateGear(); + UpdateCharacterList(); + UpdateGear(); } function UpdateEmoteList() { - local byte ItemIndex, i; - local GFxObject DataProvider, SlotObject; - local string TexturePath; + local int ItemIndex, i; + local GFxObject DataProvider, SlotObject; + local string TexturePath; - ItemIndex = 0; - DataProvider = CreateArray(); + ItemIndex = 0; + DataProvider = CreateArray(); - for (i = 0; i < EmoteList.length; i++) - { - if ( class'ExtEmoteList'.static.GetUnlockedEmote(EmoteList[i].Id, ExtPlayerController(GetPC())) != 'NONE') - { - SlotObject = CreateObject( "Object" ); - SlotObject.SetInt("ItemIndex", i); - SlotObject.SetString("label", Localize(EmoteList[i].ItemName, "EmoteName", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)); - TexturePath = "img://"$EmoteList[i].IconPath; - SlotObject.SetBool("enabled", true); - SlotObject.SetString("source", TexturePath); - DataProvider.SetElementObject(ItemIndex, SlotObject); - ItemIndex++; - } - else - { - //`log(MyKFPRI.EmoteList[i] @ "is not purchased."); - } - } - - SetObject("emoteArray", DataProvider); + for (i = 0; i < EmoteList.length; i++) + { + if ( class'ExtEmoteList'.static.GetUnlockedEmote(EmoteList[i].Id, ExtPlayerController(GetPC())) != 'NONE') + { + SlotObject = CreateObject( "Object" ); + SlotObject.SetInt("ItemIndex", i); + SlotObject.SetString("label", Localize(EmoteList[i].ItemName, "EmoteName", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)); + TexturePath = "img://"$EmoteList[i].IconPath; + SlotObject.SetBool("enabled", true); + SlotObject.SetString("source", TexturePath); + DataProvider.SetElementObject(ItemIndex, SlotObject); + ItemIndex++; + } + else + { + //`log(MyKFPRI.EmoteList[i] @ "is not purchased."); + } + } + + SetObject("emoteArray", DataProvider); } function UpdateCharacterList() { - local byte i, ItemIndex; - local GFxObject DataProvider, SlotObject; - local string TexturePath; + local int i, ItemIndex; + local GFxObject DataProvider, SlotObject; + local string TexturePath; - bWaitingCharList = false; - ItemIndex = 0; - DataProvider = CreateArray(); - for( i=0; i Outfits, string DataArrayString) { - local byte i, ItemIndex; - local GFxObject DataProvider, SlotObject; - local string TexturePath, OutfitName; - local OutfitVariants Outfit; - local SkinVariant FirstSkin; - - ItemIndex = 0; - DataProvider = CreateArray(); - for (i = 0; i < Outfits.length; i++) - { - Outfit = Outfits[i]; - - OutfitName = Localize(CharInfoPath, OutfitKey$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); - if( bIsCustomChar ) - OutfitName = GetMenuNameStr(Outfit.MeshName); - - if ( InStr(OutfitName, "?INT?") != -1 ) - continue; - - SlotObject = CreateObject( "Object" ); - SlotObject.SetInt("ItemIndex", i); - SlotObject.SetString("label", OutfitName); - SlotObject.SetBool("enabled", true); - FirstSkin = UpdateOutfitVariants( OutfitKey, SkinKey, Outfit.SkinVariations, i, SlotObject ); - if( string(FirstSkin.UITexture) == "Bad" ) - continue; - - TexturePath = "img://"$PathName(FirstSkin.UITexture); - SlotObject.SetString("source", TexturePath); + local int i, ItemIndex; + local GFxObject DataProvider, SlotObject; + local string TexturePath, OutfitName; + local OutfitVariants Outfit; + local SkinVariant FirstSkin; + + ItemIndex = 0; + DataProvider = CreateArray(); + for (i = 0; i < Outfits.Length; i++) + { + Outfit = Outfits[i]; + + OutfitName = Localize(CharInfoPath, OutfitKey$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); + if( bIsCustomChar ) + OutfitName = GetMenuNameStr(Outfit.MeshName); + + if ( InStr(OutfitName, "?INT?") != -1 ) + continue; + + SlotObject = CreateObject( "Object" ); + SlotObject.SetInt("ItemIndex", i); + SlotObject.SetString("label", OutfitName); + SlotObject.SetBool("enabled", true); + FirstSkin = UpdateOutfitVariants( OutfitKey, SkinKey, Outfit.SkinVariations, i, SlotObject ); + if( string(FirstSkin.UITexture) == "Bad" ) + continue; + + TexturePath = "img://"$PathName(FirstSkin.UITexture); + SlotObject.SetString("source", TexturePath); - DataProvider.SetElementObject(ItemIndex, SlotObject); - ItemIndex++; - } - - SetObject(DataArrayString, DataProvider); + DataProvider.SetElementObject(ItemIndex, SlotObject); + ItemIndex++; + } + + SetObject(DataArrayString, DataProvider); } function SkinVariant UpdateOutfitVariants(string OutfitKey, string KeyName, out array SkinVariations, int OutfitIndex, out GFxObject MeshObject) { - local byte i, ItemIndex; - local GFxObject DataProvider, SlotObject; - local SkinVariant Skin; - local SkinVariant FirstSkin; - local string SectionPath; - local string TexturePath; - local bool bFoundFirst; + local int i, ItemIndex; + local GFxObject DataProvider, SlotObject; + local SkinVariant Skin; + local SkinVariant FirstSkin; + local string SectionPath; + local string TexturePath; + local bool bFoundFirst; - ItemIndex = 0; - DataProvider = CreateArray(); - SectionPath = CharInfoPath$"."$OutfitKey$OutfitIndex; + ItemIndex = 0; + DataProvider = CreateArray(); + SectionPath = CharInfoPath$"."$OutfitKey$OutfitIndex; - for (i = 0; i < SkinVariations.length; i++) - { - Skin = SkinVariations[i]; - if(!bFoundFirst) - { - FirstSkin = Skin; - bFoundFirst = true; - } - SlotObject = CreateObject( "Object" ); - SlotObject.SetInt("ItemIndex", i); - SlotObject.SetString("label", Localize(SectionPath, KeyName$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)); - TexturePath = "img://"$PathName(Skin.UITexture); - SlotObject.SetBool("enabled", true); - SlotObject.SetString("source", TexturePath); + for (i = 0; i < SkinVariations.length; i++) + { + Skin = SkinVariations[i]; + if(!bFoundFirst) + { + FirstSkin = Skin; + bFoundFirst = true; + } + SlotObject = CreateObject( "Object" ); + SlotObject.SetInt("ItemIndex", i); + SlotObject.SetString("label", Localize(SectionPath, KeyName$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)); + TexturePath = "img://"$PathName(Skin.UITexture); + SlotObject.SetBool("enabled", true); + SlotObject.SetString("source", TexturePath); - DataProvider.SetElementObject(ItemIndex, SlotObject); - ItemIndex++; - } - MeshObject.SetObject("skinInfo", DataProvider); + DataProvider.SetElementObject(ItemIndex, SlotObject); + ItemIndex++; + } + MeshObject.SetObject("skinInfo", DataProvider); - return FirstSkin; + return FirstSkin; } function UpdateAttachmentsList(array Attachments) { - local byte i, ItemIndex; - local GFxObject DataProvider, SlotObject; - local string TexturePath; - local AttachmentVariants Variant; - local SkinVariant FirstSkin; - local string AttachmentName; - - ItemIndex = 0; - DataProvider = CreateArray(); + local int i, ItemIndex; + local GFxObject DataProvider, SlotObject; + local string TexturePath; + local AttachmentVariants Variant; + local Pawn MyPawn; + local SkinVariant FirstSkin; + local string AttachmentName; + + ItemIndex = 0; + DataProvider = CreateArray(); + MyPawn = GetPC().Pawn; - // Insert blank object - SlotObject = CreateObject( "Object" ); - SlotObject.SetString("label", class'KFGFxMenu_Gear'.Default.NoneString); - SlotObject.SetString("source", "img://"$class'KFGFxMenu_Gear'.Default.ClearImagePath); - SlotObject.SetBool("enabled", true); - DataProvider.SetElementObject(ItemIndex, SlotObject); - ItemIndex++; + // Insert blank object + SlotObject = CreateObject( "Object" ); + SlotObject.SetString("label", class'KFGFxMenu_Gear'.default.NoneString); + SlotObject.SetString("source", "img://"$class'KFGFxMenu_Gear'.default.ClearImagePath); + SlotObject.SetInt("ItemIndex", INDEX_NONE); + SlotObject.SetBool("enabled", true); + DataProvider.SetElementObject(ItemIndex, SlotObject); + ItemIndex++; - for (i = 0; i < Attachments.length; i++) - { - Variant = Attachments[i]; - - AttachmentName = Localize(string(Variant.AttachmentItem.Name), class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); - if( bIsCustomChar ) - AttachmentName = GetMenuNameStr(Variant.MeshName); - - if ( InStr(AttachmentName, "?INT?") != -1 ) - continue; - - SlotObject = CreateObject( "Object" ); - SlotObject.SetInt("ItemIndex", i); - FirstSkin = UpdateCosmeticVariants( class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentSkinKey, Variant.AttachmentItem, i, SlotObject ); - if( string(FirstSkin.UITexture) == "Bad" ) - continue; - - SlotObject.SetString("label", AttachmentName); - SlotObject.SetBool("enabled", true); - TexturePath = "img://"$PathName(FirstSkin.UITexture); - SlotObject.SetString("source", TexturePath); - - DataProvider.SetElementObject(ItemIndex, SlotObject); - ItemIndex++; - } - - SetObject("attachmentsArray", DataProvider); + for (i = 0; i < Attachments.Length; i++) + { + Variant = Attachments[i]; + if ( class'ExtCharacterInfo'.static.IsAttachmentAvailable(CurrentCharInfo, Variant, MyPawn) ) + { + SlotObject = CreateObject( "Object" ); + SlotObject.SetInt("ItemIndex", i); + FirstSkin = UpdateCosmeticVariants( class'KFGFxMenu_Gear'.default.AttachmentKey, class'KFGFxMenu_Gear'.default.AttachmentSkinKey, Variant.AttachmentItem, i, SlotObject ); + AttachmentName = bIsCustomChar ? GetMenuNameStr(Variant.MeshName) : Localize(string(Variant.AttachmentItem.Name), class'KFGFxMenu_Gear'.default.AttachmentKey, class'KFGFxMenu_Gear'.default.KFCharacterInfoString); + SlotObject.SetString("label", AttachmentName); + SlotObject.SetBool("enabled", true); + TexturePath = "img://"$PathName(FirstSkin.UITexture); + SlotObject.SetString("source", TexturePath); + + DataProvider.SetElementObject(ItemIndex, SlotObject); + ItemIndex++; + } + } + + SetObject("attachmentsArray", DataProvider); } function SkinVariant UpdateCosmeticVariants(string OutfitKey, string KeyName, KFCharacterAttachment Attachment, int OutfitIndex, out GFxObject MeshObject) { - local byte i, ItemIndex; - local GFxObject DataProvider, SlotObject; - local SkinVariant Skin; - local SkinVariant FirstSkin; - local string TexturePath; - local bool bFoundFirst; - local string SkinName; + local int i, ItemIndex; + local GFxObject DataProvider, SlotObject; + local SkinVariant Skin; + local SkinVariant FirstSkin; + local string TexturePath; + local bool bFoundFirst; + local string SkinName; - ItemIndex = 0; - DataProvider = CreateArray(); + ItemIndex = 0; + DataProvider = CreateArray(); - for (i = 0; i < Attachment.SkinVariations.length; i++) - { - Skin = Attachment.SkinVariations[i]; - if(!bFoundFirst) - { - FirstSkin = Skin; - bFoundFirst = true; - } - SlotObject = CreateObject( "Object" ); - SlotObject.SetInt("ItemIndex", i); - SkinName = Localize(string(Attachment.Name), KeyName$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); - SlotObject.SetString("label", SkinName); - TexturePath = "img://"$PathName(Skin.UITexture); - SlotObject.SetBool("enabled", true); - SlotObject.SetString("source", TexturePath); + for (i = 0; i < Attachment.SkinVariations.length; i++) + { + Skin = Attachment.SkinVariations[i]; + if(!bFoundFirst) + { + FirstSkin = Skin; + bFoundFirst = true; + } + SlotObject = CreateObject( "Object" ); + SlotObject.SetInt("ItemIndex", i); + SkinName = Localize(string(Attachment.Name), KeyName$i, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); + SlotObject.SetString("label", SkinName); + TexturePath = "img://"$PathName(Skin.UITexture); + SlotObject.SetBool("enabled", true); + SlotObject.SetString("source", TexturePath); - DataProvider.SetElementObject(ItemIndex, SlotObject); - ItemIndex++; - } - MeshObject.SetObject("skinInfo", DataProvider); + DataProvider.SetElementObject(ItemIndex, SlotObject); + ItemIndex++; + } + MeshObject.SetObject("skinInfo", DataProvider); - return FirstSkin; + return FirstSkin; } function SetCurrentCharacterButtons() { - local bool bCustom; - local GFxObject DataObject; + local bool bCustom; + local GFxObject DataObject; + local byte CharacterIndex, HeadMeshIndex, HeadSkinIndex, BodyMeshIndex, BodySkinIndex; - bCustom = ExtPRI.UsesCustomChar(); - DataObject = CreateObject("Object"); + bCustom = ExtPRI.UsesCustomChar(); + DataObject = CreateObject("Object"); + + CharacterIndex = ExtPRI.RepCustomizationInfo.CharacterIndex; + HeadMeshIndex = ExtPRI.RepCustomizationInfo.HeadMeshIndex; + HeadSkinIndex = ExtPRI.RepCustomizationInfo.HeadSkinIndex; + BodyMeshIndex = ExtPRI.RepCustomizationInfo.BodyMeshIndex; + BodySkinIndex = ExtPRI.RepCustomizationInfo.BodySkinIndex; + if( bCustom ) + { + CharacterIndex = ExtPRI.CustomCharacter.CharacterIndex; + HeadMeshIndex = ExtPRI.CustomCharacter.HeadMeshIndex; + HeadSkinIndex = ExtPRI.CustomCharacter.HeadSkinIndex; + BodyMeshIndex = ExtPRI.CustomCharacter.BodyMeshIndex; + BodySkinIndex = ExtPRI.CustomCharacter.BodySkinIndex; + } - DataObject.SetString( "selectedCharacter", (bIsCustomChar ? Repl(string(CurrentCharInfo.Name),"_"," ") : Localize(CharInfoPath, "CharacterName", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)) ); - DataObject.SetString( "characterBio", (bIsCustomChar ? Repl(CurrentCharInfo.ArmMeshPackageName,"|","\n") : Localize(CharInfoPath, "Description", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)) ); - DataObject.SetInt( "selectedCharacterIndex", bCustom ? ExtPRI.CustomCharacter.CharacterIndex : ExtPRI.RepCustomizationInfo.CharacterIndex ); + DataObject.SetString( "selectedCharacter", (bIsCustomChar ? Repl(string(CurrentCharInfo.Name),"_"," ") : Localize(CharInfoPath, "CharacterName", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)) ); + DataObject.SetString( "characterBio", (bIsCustomChar ? Repl(CurrentCharInfo.ArmMeshPackageName,"|","\n") : Localize(CharInfoPath, "Description", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)) ); + DataObject.SetInt( "selectedCharacterIndex", CharacterIndex ); - SetObject( "selectedCharacter", DataObject); + SetObject( "selectedCharacter", DataObject); - //set head - SetGearButtons(bCustom ? ExtPRI.CustomCharacter.HeadMeshIndex : ExtPRI.RepCustomizationInfo.HeadMeshIndex, bCustom ? ExtPRI.CustomCharacter.HeadSkinIndex : ExtPRI.RepCustomizationInfo.HeadSkinIndex, class'KFGFxMenu_Gear'.Default.HeadMeshKey, class'KFGFxMenu_Gear'.Default.HeadSkinKey, class'KFGFxMenu_Gear'.Default.HeadFunctionKey); - //set body - SetGearButtons(bCustom ? ExtPRI.CustomCharacter.BodyMeshIndex : ExtPRI.RepCustomizationInfo.BodyMeshIndex, bCustom ? ExtPRI.CustomCharacter.BodySkinIndex : ExtPRI.RepCustomizationInfo.BodySkinIndex, class'KFGFxMenu_Gear'.Default.BodyMeshKey, class'KFGFxMenu_Gear'.Default.BodySkinKey, class'KFGFxMenu_Gear'.Default.BodyFunctionKey); - //set attachments - SetAttachmentButtons(class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentFunctionKey); - - SetEmoteButton(); + //set head + SetGearButtons(HeadMeshIndex, HeadSkinIndex, class'KFGFxMenu_Gear'.Default.HeadMeshKey, class'KFGFxMenu_Gear'.Default.HeadSkinKey, class'KFGFxMenu_Gear'.Default.HeadFunctionKey); + //set body + SetGearButtons(BodyMeshIndex, BodySkinIndex, class'KFGFxMenu_Gear'.Default.BodyMeshKey, class'KFGFxMenu_Gear'.Default.BodySkinKey, class'KFGFxMenu_Gear'.Default.BodyFunctionKey); + //set attachments + SetAttachmentButtons(class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentFunctionKey); + + SetEmoteButton(); } function SetEmoteButton() { - local GFxObject DataObject; - local int EmoteIndex; + local GFxObject DataObject; + local int EmoteIndex; - EmoteIndex = class'ExtEmoteList'.static.GetEmoteIndex( class'ExtEmoteList'.static.GetEquippedEmoteId(ExtPlayerController(GetPC()))); + EmoteIndex = class'ExtEmoteList'.static.GetEmoteIndex( class'ExtEmoteList'.static.GetEquippedEmoteId(ExtPlayerController(GetPC()))); - DataObject = CreateObject("Object"); - if(EmoteIndex == 255) - { - DataObject.SetString( "selectedEmote", ""); - DataObject.SetInt( "selectedEmoteIndex", 0 ); - } - else - { - DataObject.SetString( "selectedEmote", Localize(EmoteList[EmoteIndex].ItemName, "EmoteName", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)); - DataObject.SetInt( "selectedEmoteIndex", 0 ); - } - + DataObject = CreateObject("Object"); + if(EmoteIndex == 255) + { + DataObject.SetString( "selectedEmote", ""); + DataObject.SetInt( "selectedEmoteIndex", 0 ); + } + else + { + DataObject.SetString( "selectedEmote", Localize(EmoteList[EmoteIndex].ItemName, "EmoteName", class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)); + DataObject.SetInt( "selectedEmoteIndex", 0 ); + } + - SetObject("selectedEmote", DataObject); + SetObject("selectedEmote", DataObject); } /** Update the labels for our gear buttons */ -function SetGearButtons(byte MeshIndex, byte SkinIndex, string MeshKey, string SkinKey, string sectionFunctionName) +function SetGearButtons(int MeshIndex, int SkinIndex, string MeshKey, string SkinKey, string sectionFunctionName) { - local string SectionPath; - local string CurrentMesh; - local string SkinName, MeshName; - local GFxObject DataObject; + local string SectionPath; + local string CurrentMesh; + local string SkinName, MeshName; + local GFxObject DataObject; - if( bWaitingCharList ) - return; + if( bWaitingCharList ) + return; - DataObject = CreateObject("Object"); + DataObject = CreateObject("Object"); - if(MeshIndex == `CLEARED_ATTACHMENT_INDEX) - { - DataObject.SetString( sectionFunctionName, class'KFGFxMenu_Gear'.Default.NoneString ); - } - else if( bIsCustomChar ) - { - if( MeshKey==class'KFGFxMenu_Gear'.Default.HeadMeshKey ) - { - SkinName = GetMenuName(CurrentCharInfo.HeadVariants[MeshIndex].SkinVariations[SkinIndex].Skin); - MeshName = GetMenuNameStr(CurrentCharInfo.HeadVariants[MeshIndex].MeshName); - } - else - { - SkinName = GetMenuName(CurrentCharInfo.BodyVariants[MeshIndex].SkinVariations[SkinIndex].Skin); - MeshName = GetMenuNameStr(CurrentCharInfo.BodyVariants[MeshIndex].MeshName); - } - DataObject.SetString( sectionFunctionName, MeshName @"\n" @SkinName ); - } - else - { - CurrentMesh = MeshKey$MeshIndex; - SectionPath = CharInfoPath$"."$CurrentMesh; + if(MeshIndex == `CLEARED_ATTACHMENT_INDEX) + { + DataObject.SetString( sectionFunctionName, class'KFGFxMenu_Gear'.Default.NoneString ); + } + else if( bIsCustomChar ) + { + if( MeshKey==class'KFGFxMenu_Gear'.Default.HeadMeshKey ) + { + SkinName = GetMenuName(CurrentCharInfo.HeadVariants[MeshIndex].SkinVariations[SkinIndex].Skin); + MeshName = GetMenuNameStr(CurrentCharInfo.HeadVariants[MeshIndex].MeshName); + } + else + { + SkinName = GetMenuName(CurrentCharInfo.BodyVariants[MeshIndex].SkinVariations[SkinIndex].Skin); + MeshName = GetMenuNameStr(CurrentCharInfo.BodyVariants[MeshIndex].MeshName); + } + + DataObject.SetString( sectionFunctionName, MeshName @"\n" @SkinName ); + } + else + { + CurrentMesh = MeshKey$MeshIndex; + SectionPath = CharInfoPath$"."$CurrentMesh; - SkinName = Localize(SectionPath, SkinKey$SkinIndex, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); - MeshName = Localize(CharInfoPath, CurrentMesh, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); - DataObject.SetString( sectionFunctionName, MeshName @"\n" @SkinName ); - } + SkinName = Localize(SectionPath, SkinKey$SkinIndex, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); + MeshName = Localize(CharInfoPath, CurrentMesh, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString); + DataObject.SetString( sectionFunctionName, MeshName @"\n" @SkinName ); + } - DataObject.SetInt( (sectionFunctionName$"Index"), MeshIndex); - DataObject.SetInt( (sectionFunctionName$"SkinIndex"), SkinIndex); + DataObject.SetInt( (sectionFunctionName$"Index"), MeshIndex); + DataObject.SetInt( (sectionFunctionName$"SkinIndex"), SkinIndex); - SetObject( sectionFunctionName, DataObject); + SetObject( sectionFunctionName, DataObject); } /** Update the labels for our currently equipped attachments */ function SetAttachmentButtons(string AttachmentMeshKey, string sectionFunctionName) { - local string FinishedString; - local GFxObject DataObject; - local byte i, AttachmentIndex; - local bool bCustom; + local GFxObject DataObject; + local int i, AttachmentIndex; + local bool bCustom; + + if( bWaitingCharList ) + return; + + bCustom = ExtPRI.UsesCustomChar(); + DataObject = CreateObject("Object"); - if( bWaitingCharList ) - return; + for(i = 0; i < `MAX_COSMETIC_ATTACHMENTS; i++) + { + AttachmentIndex = bCustom ? ExtPRI.CustomCharacter.AttachmentMeshIndices[i] : ExtPRI.RepCustomizationInfo.AttachmentMeshIndices[i]; + if( AttachmentIndex == `CLEARED_ATTACHMENT_INDEX ) + { + DataObject.SetString("selectedAttachment_"$i, "----"); + } + else + { + DataObject.SetString("selectedAttachment_"$i, bIsCustomChar ? GetMenuNameStr(CurrentCharInfo.CosmeticVariants[AttachmentIndex].MeshName) : Localize(string(CurrentCharInfo.CosmeticVariants[AttachmentIndex].AttachmentItem.Name), AttachmentMeshKey, class'KFGFxMenu_Gear'.default.KFCharacterInfoString)); + } + } - bCustom = ExtPRI.UsesCustomChar(); - DataObject = CreateObject("Object"); - - for(i = 0; i < `MAX_COSMETIC_ATTACHMENTS; i++) - { - AttachmentIndex = bCustom ? ExtPRI.CustomCharacter.AttachmentMeshIndices[i] : ExtPRI.RepCustomizationInfo.AttachmentMeshIndices[i]; - if( AttachmentIndex == `CLEARED_ATTACHMENT_INDEX ) - { - FinishedString $= "----"$"\n"; - } - else - { - FinishedString $= (bIsCustomChar ? GetMenuNameStr(CurrentCharInfo.CosmeticVariants[AttachmentIndex].MeshName) : Localize(string(CurrentCharInfo.CosmeticVariants[AttachmentIndex].AttachmentItem.Name), AttachmentMeshKey, class'KFGFxMenu_Gear'.Default.KFCharacterInfoString)$"\n"); - } - } - - DataObject.SetString( sectionFunctionName, FinishedString ); - - SetObject( sectionFunctionName, DataObject); + SetObject( sectionFunctionName, DataObject); } event OnClose() { - local PlayerController PC; + local PlayerController PC; - super.OnClose(); + super.OnClose(); - GetGameViewportClient().HandleInputAxis = none; + //GetGameViewportClient().HandleInputAxis = none; - if ( class'WorldInfo'.static.IsMenuLevel() ) - { - Manager.ManagerObject.SetBool("backgroundVisible", true); - } + if ( class'WorldInfo'.static.IsMenuLevel() ) + { + Manager.ManagerObject.SetBool("backgroundVisible", true); + } - // If we are alive, in game, with a playable pawn. switch back to first person view when leaving this menu - PC = GetPC(); - if( PC != none && PC.WorldInfo.GRI.bMatchHasBegun && PC.Pawn != none && !PC.Pawn.IsA('KFPawn_Customization') ) - { - PC.ServerCamera( 'FirstPerson' ); - } + // If we are alive, in game, with a playable pawn. switch back to first person view when leaving this menu + PC = GetPC(); + if( PC != none && PC.WorldInfo.GRI.bMatchHasBegun && PC.Pawn != none && !PC.Pawn.IsA('KFPawn_Customization') ) + { + PC.ServerCamera( 'FirstPerson' ); + } } event bool OnAxisModified( int ControllerId, name Key, float Delta, float DeltaTime, bool bGamepad ) { - if ( GetPC().PlayerInput.bUsingGamepad ) - { - if ( Key == 'XboxTypeS_RightX' && Abs(Delta) > class'KFGFxMenu_Gear'.Default.ControllerRotationThreshold) - { - Callback_RotateCamera(Delta * class'KFGFxMenu_Gear'.Default.ControllerRotationRate); - } - } - return false; + if ( GetPC().PlayerInput.bUsingGamepad ) + { + if ( Key == 'XboxTypeS_RightX' && Abs(Delta) > class'KFGFxMenu_Gear'.Default.ControllerRotationThreshold) + { + Callback_RotateCamera(Delta * class'KFGFxMenu_Gear'.Default.ControllerRotationRate); + } + } + return false; } //============================================================== // ActionScript Callbacks //============================================================== -function Callback_Emote(byte Index) +function Callback_Emote(int Index) { - local KFPlayerController KFPC; + local KFPlayerController KFPC; - KFPC = KFPlayerController(GetPC()); - if( KFPC != none ) - { - class'ExtEmoteList'.static.SaveEquippedEmote(EmoteList[Index].ID, ExtPlayerController(KFPC)); + KFPC = KFPlayerController(GetPC()); + if( KFPC != none ) + { + class'ExtEmoteList'.static.SaveEquippedEmote(EmoteList[Index].ID, ExtPlayerController(KFPC)); - if ( ExtPawn_Customization(KFPC.Pawn) != none ) - { - ExtPawn_Customization(KFPC.Pawn).PlayEmoteAnimation(); - } - } + if ( ExtPawn_Customization(KFPC.Pawn) != none ) + { + ExtPawn_Customization(KFPC.Pawn).PlayEmoteAnimation(); + } + } - SetEmoteButton(); + SetEmoteButton(); } function Callback_RotateCamera( int RotationDirection ) { - local KFPlayerCamera PlayerCamera; - - PlayerCamera = KFPlayerCamera( GetPC().PlayerCamera ); - if ( PlayerCamera != none ) - PlayerCamera.CustomizationCam.RotatedCamera( RotationDirection ); + local KFPlayerCamera PlayerCamera; + + PlayerCamera = KFPlayerCamera( GetPC().PlayerCamera ); + if ( PlayerCamera != none ) + PlayerCamera.CustomizationCam.RotatedCamera( RotationDirection ); } function Callback_EndRotateCamera() { - local KFPlayerCamera PlayerCamera; + local KFPlayerCamera PlayerCamera; - PlayerCamera = KFPlayerCamera( GetPC().PlayerCamera ); - if ( PlayerCamera != none ) - PlayerCamera.CustomizationCam.StartFadeRotation(); + PlayerCamera = KFPlayerCamera( GetPC().PlayerCamera ); + if ( PlayerCamera != none ) + PlayerCamera.CustomizationCam.StartFadeRotation(); } function Callback_Weapon( int ItemIndex, int SkinIndex ) { - local KFPawn_Customization KFP; + local KFPawn_Customization KFP; - KFP = KFPawn_Customization(GetPC().Pawn); - if(KFP != none) - KFP.AttachWeaponByItemDefinition(SkinIndex); + KFP = KFPawn_Customization(GetPC().Pawn); + if(KFP != none) + KFP.AttachWeaponByItemDefinition(SkinIndex); } function Callback_BodyCamera() { - if ( KFPlayerCamera( GetPC().PlayerCamera ) != none ) - KFPlayerCamera( GetPC().PlayerCamera ).CustomizationCam.SetBodyView( 0 ); + if ( KFPlayerCamera( GetPC().PlayerCamera ) != none ) + KFPlayerCamera( GetPC().PlayerCamera ).CustomizationCam.SetBodyView( 0 ); } function Callback_HeadCamera() { - if ( KFPlayerCamera( GetPC().PlayerCamera ) != none ) - KFPlayerCamera( GetPC().PlayerCamera ).CustomizationCam.SetBodyView( 1 ); + if ( KFPlayerCamera( GetPC().PlayerCamera ) != none ) + KFPlayerCamera( GetPC().PlayerCamera ).CustomizationCam.SetBodyView( 1 ); } -function Callback_Character(byte Index) +function Callback_Character(int Index) { - ExtPRI.ChangeCharacter(Index,!ExtPRI.UsesCustomChar()); - UpdateGear(); + ExtPRI.ChangeCharacter(Index,!ExtPRI.UsesCustomChar()); + UpdateGear(); } -function Callback_Head( byte MeshIndex, byte SkinIndex ) +function Callback_Head( int MeshIndex, int SkinIndex ) { - if( !ExtPRI.UsesCustomChar() ) // Force client to setup custom character now for this server. - ExtPRI.ChangeCharacter(ExtPRI.RepCustomizationInfo.CharacterIndex,true); - ExtPRI.UpdateCustomization(CO_Head, MeshIndex, SkinIndex); - SetGearButtons(MeshIndex, SkinIndex, class'KFGFxMenu_Gear'.Default.HeadMeshKey, class'KFGFxMenu_Gear'.Default.HeadSkinKey, class'KFGFxMenu_Gear'.Default.HeadFunctionKey); + if( !ExtPRI.UsesCustomChar() ) // Force client to setup custom character now for this server. + ExtPRI.ChangeCharacter(ExtPRI.RepCustomizationInfo.CharacterIndex,true); + ExtPRI.UpdateCustomization(CO_Head, MeshIndex, SkinIndex); + SetGearButtons(MeshIndex, SkinIndex, class'KFGFxMenu_Gear'.Default.HeadMeshKey, class'KFGFxMenu_Gear'.Default.HeadSkinKey, class'KFGFxMenu_Gear'.Default.HeadFunctionKey); } -function Callback_Body( byte MeshIndex, byte SkinIndex ) +function Callback_Body( int MeshIndex, int SkinIndex ) { - if( !ExtPRI.UsesCustomChar() ) // Force client to setup custom character now for this server. - ExtPRI.ChangeCharacter(ExtPRI.RepCustomizationInfo.CharacterIndex,true); - - ExtPRI.UpdateCustomization(CO_Body, MeshIndex, SkinIndex); - - // When assigning a new body mesh we may need to remove certain attachments - // refresh filters, and update the equipped accessories list - UpdateAttachmentsList(CurrentCharInfo.CosmeticVariants); - SetAttachmentButtons(class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentFunctionKey); + if( !ExtPRI.UsesCustomChar() ) // Force client to setup custom character now for this server. + ExtPRI.ChangeCharacter(ExtPRI.RepCustomizationInfo.CharacterIndex,true); + + ExtPRI.UpdateCustomization(CO_Body, MeshIndex, SkinIndex); + + // When assigning a new body mesh we may need to remove certain attachments + // refresh filters, and update the equipped accessories list + UpdateAttachmentsList(CurrentCharInfo.CosmeticVariants); + SetAttachmentButtons(class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentFunctionKey); - SetGearButtons(MeshIndex, SkinIndex, class'KFGFxMenu_Gear'.Default.BodyMeshKey, class'KFGFxMenu_Gear'.Default.BodySkinKey, class'KFGFxMenu_Gear'.Default.BodyFunctionKey); + SetGearButtons(MeshIndex, SkinIndex, class'KFGFxMenu_Gear'.Default.BodyMeshKey, class'KFGFxMenu_Gear'.Default.BodySkinKey, class'KFGFxMenu_Gear'.Default.BodyFunctionKey); } -function Callback_Attachment( byte MeshIndex, byte SkinIndex ) +function Callback_Attachment( int MeshIndex, int SkinIndex ) { - local int SlotIndex; - local KFPawn KFP; + local int SlotIndex; + local KFPawn KFP; - if( !ExtPRI.UsesCustomChar() ) // Force client to setup custom character now for this server. - ExtPRI.ChangeCharacter(ExtPRI.RepCustomizationInfo.CharacterIndex,true); + if( !ExtPRI.UsesCustomChar() ) // Force client to setup custom character now for this server. + ExtPRI.ChangeCharacter(ExtPRI.RepCustomizationInfo.CharacterIndex,true); - KFP = KFPawn(GetPC().Pawn); - if( KFP!=None ) - { - if( MeshIndex==`CLEARED_ATTACHMENT_INDEX ) - ExtPRI.RemoveAttachments(); - else - { - class'ExtCharacterInfo'.Static.DetachConflictingAttachments(CurrentCharInfo, MeshIndex, KFP, ExtPRI); - SlotIndex = CurrentCharInfo.GetAttachmentSlotIndex(MeshIndex, KFP); - ExtPRI.UpdateCustomization(CO_Attachment, MeshIndex, SkinIndex, SlotIndex); - } + KFP = KFPawn(GetPC().Pawn); + if( KFP!=None && ExtPRI!=None ) + { + if( MeshIndex==`CLEARED_ATTACHMENT_INDEX ) + ExtPRI.RemoveAttachments(); + else + { + class'ExtCharacterInfo'.Static.DetachConflictingAttachments(CurrentCharInfo, MeshIndex, KFP, ExtPRI); + SlotIndex = class'ExtCharacterInfo'.Static.GetAttachmentSlotIndex(CurrentCharInfo, MeshIndex, KFP, ExtPRI); + if(SlotIndex == INDEX_NONE) + { + return; + } + + ExtPRI.UpdateCustomization(CO_Attachment, MeshIndex, SkinIndex, SlotIndex); + } - SetAttachmentButtons(class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentFunctionKey); - } + SetAttachmentButtons(class'KFGFxMenu_Gear'.Default.AttachmentKey, class'KFGFxMenu_Gear'.Default.AttachmentFunctionKey); + } } defaultproperties diff --git a/ServerExt/Classes/ExtMoviePlayer_HUD.uc b/ServerExt/Classes/ExtMoviePlayer_HUD.uc index a275799..690ef7e 100644 --- a/ServerExt/Classes/ExtMoviePlayer_HUD.uc +++ b/ServerExt/Classes/ExtMoviePlayer_HUD.uc @@ -103,8 +103,8 @@ defaultproperties WidgetBindings.Add((WidgetName="PlayerBackpackWidget",WidgetClass=class'ExtHUD_PlayerBackpack')) WidgetBindings.Remove((WidgetName="WaveInfoContainer",WidgetClass=class'KFGFxHUD_WaveInfo')) WidgetBindings.Add((WidgetName="WaveInfoContainer",WidgetClass=class'ExtHUD_WaveInfo')) - WidgetBindings.Remove((WidgetName="bossHealthBar", WidgetClass=class'KFGFxWidget_BossHealthBar')) - WidgetBindings.Add((WidgetName="bossHealthBar", WidgetClass=class'ExtWidget_BossHealthBar')) + //WidgetBindings.Remove((WidgetName="bossHealthBar", WidgetClass=class'KFGFxWidget_BossHealthBar')) + //WidgetBindings.Add((WidgetName="bossHealthBar", WidgetClass=class'ExtWidget_BossHealthBar')) WidgetBindings.Remove((WidgetName="WeaponSelectContainer",WidgetClass=class'KFGFxHUD_WeaponSelectWidget')) WidgetBindings.Add((WidgetName="WeaponSelectContainer",WidgetClass=class'ExtHUD_WeaponSelectWidget')) } \ No newline at end of file diff --git a/ServerExt/Classes/ExtPlayerController.uc b/ServerExt/Classes/ExtPlayerController.uc index 343ed60..7d74739 100644 --- a/ServerExt/Classes/ExtPlayerController.uc +++ b/ServerExt/Classes/ExtPlayerController.uc @@ -144,7 +144,7 @@ reliable client event ReceiveLocalizedMessage( class Message, opti Super.ReceiveLocalizedMessage(Message,Switch,RelatedPRI_1,RelatedPRI_2,OptionalObject); } -function AddZedKill( class MonsterClass, byte Difficulty, class DT ) +function AddZedKill( class MonsterClass, byte Difficulty, class DT, bool bKiller ) { // Stats. if( ActivePerkManager!=None ) @@ -603,7 +603,7 @@ simulated function CancelConnection() else class'Engine'.Static.GetEngine().GameViewport.ConsoleCommand("Disconnect"); } -function NotifyLevelUp(class PerkClass, byte PerkLevel); +function NotifyLevelUp(class PerkClass, byte PerkLevel, byte NewPrestigeLevel); function ShowBossNameplate( KFInterface_MonsterBoss KFBoss, optional string PlayerName) { @@ -1167,6 +1167,16 @@ state Dead } } +exec function RequestSwitchTeam() +{ + ConsoleCommand("disconnect"); +} + +exec function SwitchTeam() +{ + ConsoleCommand("disconnect"); +} + defaultproperties { InputClass=Class'ExtPlayerInput' diff --git a/ServerExt/Classes/ExtPlayerReplicationInfo.uc b/ServerExt/Classes/ExtPlayerReplicationInfo.uc index 83b356c..4ba3d08 100644 --- a/ServerExt/Classes/ExtPlayerReplicationInfo.uc +++ b/ServerExt/Classes/ExtPlayerReplicationInfo.uc @@ -8,15 +8,14 @@ struct FCustomCharEntry }; struct FMyCustomChar // Now without constant. { - var int CharacterIndex,HeadMeshIndex,HeadSkinIndex,BodyMeshIndex,BodySkinIndex,AttachmentMeshIndices[`MAX_COSMETIC_ATTACHMENTS],AttachmentSkinIndices[`MAX_COSMETIC_ATTACHMENTS]; - - structdefaultproperties - { - CharacterIndex=255 - AttachmentMeshIndices[0]=255 - AttachmentMeshIndices[1]=255 - AttachmentMeshIndices[2]=255 - } + var int CharacterIndex,HeadMeshIndex,HeadSkinIndex,BodyMeshIndex,BodySkinIndex,AttachmentMeshIndices[`MAX_COSMETIC_ATTACHMENTS],AttachmentSkinIndices[`MAX_COSMETIC_ATTACHMENTS]; + + structdefaultproperties + { + AttachmentMeshIndices[0]=`CLEARED_ATTACHMENT_INDEX + AttachmentMeshIndices[1]=`CLEARED_ATTACHMENT_INDEX + AttachmentMeshIndices[2]=`CLEARED_ATTACHMENT_INDEX + } }; // For custom trader inventory. @@ -658,7 +657,7 @@ final function SaveCustomCharacter( ExtSaveDataBase Data ) c = 0; for( i=0; i<`MAX_COSMETIC_ATTACHMENTS; ++i ) { - if( CustomCharacter.AttachmentMeshIndices[i]!=255 ) + if( CustomCharacter.AttachmentMeshIndices[i]!=`CLEARED_ATTACHMENT_INDEX ) ++c; } @@ -668,7 +667,7 @@ final function SaveCustomCharacter( ExtSaveDataBase Data ) // Write attachments. for( i=0; i<`MAX_COSMETIC_ATTACHMENTS; ++i ) { - if( CustomCharacter.AttachmentMeshIndices[i]!=255 ) + if( CustomCharacter.AttachmentMeshIndices[i]!=`CLEARED_ATTACHMENT_INDEX ) { Data.SaveInt(i); Data.SaveInt(CustomCharacter.AttachmentMeshIndices[i]); @@ -748,6 +747,16 @@ static final function DummySaveChar( ExtSaveDataBase Data ) Data.SaveStr(""); } +simulated function Texture2D GetCurrentIconToDisplay() +{ + if(CurrentVoiceCommsRequest == VCT_NONE && ECurrentPerk != none) + { + return ECurrentPerk.default.PerkIcon; + } + + return class'KFLocalMessage_VoiceComms'.default.VoiceCommsIcons[CurrentVoiceCommsRequest]; +} + // Set admin levels without having to hard-reference to this mod. event BeginState(Name N) { diff --git a/ServerExt/Classes/ExtWidget_PartyInGame.uc b/ServerExt/Classes/ExtWidget_PartyInGame.uc index 6274f44..6125c3b 100644 --- a/ServerExt/Classes/ExtWidget_PartyInGame.uc +++ b/ServerExt/Classes/ExtWidget_PartyInGame.uc @@ -21,7 +21,7 @@ function GFxObject RefreshSlot( int SlotIndex, KFPlayerReplicationInfo KFPRI ) local bool bIsLeader; local bool bIsMyPlayer; local ExtPlayerController EPC; - local GFxObject PlayerInfoObject; + local GFxObject PlayerInfoObject, PerkIconObject; local ExtPlayerReplicationInfo EPRI; PlayerInfoObject = CreateObject("Object"); @@ -42,8 +42,11 @@ function GFxObject RefreshSlot( int SlotIndex, KFPlayerReplicationInfo KFPRI ) PlayerInfoObject.SetBool("myPlayer", bIsMyPlayer); if( ExtMemberSlots[SlotIndex].PerkClass != none ) { + PerkIconObject = CreateObject("Object"); + PerkIconObject.SetString("perkIcon", ExtMemberSlots[SlotIndex].PerkClass.static.GetPerkIconPath(EPRI.ECurrentPerkLevel)); + PlayerInfoObject.SetObject("perkImageSource", PerkIconObject); + PlayerInfoObject.SetString("perkLevel", string(EPRI.ECurrentPerkLevel)); - PlayerInfoObject.SetString("perkIconPath", ExtMemberSlots[SlotIndex].PerkClass.static.GetPerkIconPath(EPRI.ECurrentPerkLevel)); } if( !bIsMyPlayer ) { @@ -76,5 +79,4 @@ function GFxObject RefreshSlot( int SlotIndex, KFPlayerReplicationInfo KFPRI ) DefaultProperties { - PlayerSlots=12 } diff --git a/ServerExt/Classes/Ext_PerkBase.uc b/ServerExt/Classes/Ext_PerkBase.uc index d563abc..e163f3d 100644 --- a/ServerExt/Classes/Ext_PerkBase.uc +++ b/ServerExt/Classes/Ext_PerkBase.uc @@ -105,7 +105,7 @@ simulated final function bool IsWeaponOnPerk( KFWeapon W ) simulated static function string GetPerkIconPath( int Level ) { - return "img://"$PathName(Default.PerkIcon); + return "img://"$PathName(default.PerkIcon); } simulated function PostBeginPlay() diff --git a/ServerExt/Classes/KFExtendedHUD.uc b/ServerExt/Classes/KFExtendedHUD.uc index c723aef..971452b 100644 --- a/ServerExt/Classes/KFExtendedHUD.uc +++ b/ServerExt/Classes/KFExtendedHUD.uc @@ -446,97 +446,131 @@ final function RenderProgress() function DrawHUD() { - local KFPawn KFPH; - local KFPawn_Human H; + local KFPawn_Human KFPH; + local KFPawn_Scripted KFPS; + local vector ViewLocation, ViewVector, PlayerPartyInfoLocation, PawnLocation; + local rotator ViewRotation; + local array VisibleHumanPlayers; + local array HiddenHumanPlayers; local float ThisDot,DotScale; + local vector TargetLocation; + local Actor LocActor; local KFPawn_Monster M; local vector V; local bool bSpec; - local array VisibleHumanPlayers; - local array HiddenHumanPlayers; - local vector ViewLocation,PawnLocation; - local rotator ViewRotation; - Super(HUD).DrawHUD(); - - // Draw the crosshair for casual mode - if( bDrawCrosshair || bForceDrawCrosshair || (KFPlayerOwner != none && KFPlayerOwner.GetTeamNum() == 255) ) - { - if( KFPlayerOwner != none && !KFPlayerOwner.bCinematicMode ) - DrawCrosshair(); + // Draw weapon HUD underneath everything else + if( KFPlayerOwner != none && KFPlayerOwner.Pawn != none && KFPlayerOwner.Pawn.Weapon != none ) + { + KFPlayerOwner.Pawn.Weapon.DrawHUD( self, Canvas ); } + super.DrawHUD(); + + // Cache GRI + if( KFGRI == none ) + { + KFGRI = KFGameReplicationInfo( WorldInfo.GRI ); + } + + // Don't draw canvas HUD in cinematic mode + if( KFPlayerOwner != none && KFPlayerOwner.bCinematicMode ) + { + return; + } + LocActor = KFPlayerOwner.ViewTarget != none ? KFPlayerOwner.ViewTarget : KFPlayerOwner; + + // Draw the crosshair for casual mode + if( KFPlayerOwner != none && (bDrawCrosshair || bForceDrawCrosshair || KFPlayerOwner.GetTeamNum() == 255) ) + { + DrawCrosshair(); + } + + // Friendly player status bSpec = (PlayerOwner.PlayerReplicationInfo!=None && PlayerOwner.PlayerReplicationInfo.bOnlySpectator); if( bSpec || PlayerOwner.GetTeamNum()==0 ) { //Friendly player status if( !class'ExtPlayerController'.Default.bHideNameBeacons ) - { - if( KFPlayerOwner != none ) - { - KFPlayerOwner.GetPlayerViewPoint( ViewLocation, ViewRotation ); - } - - Canvas.EnableStencilTest(true); - foreach WorldInfo.AllPawns(class'KFPawn', KFPH) - { - if( KFPH == None ) - continue; - - H = KFPawn_Human(KFPH); - if( KFPH.PlayerReplicationInfo!=None && KFPH.PlayerReplicationInfo.Team!=None && KFPH.PlayerReplicationInfo.Team.TeamIndex==0 ) - { - V = KFPH.Location + KFPH.MTO_PhysSmoothOffset + KFPH.CylinderComponent.CollisionHeight * vect(0,0,1); - ThisDot = Normal(V - PLCameraLoc) dot Normal(PLCameraDir); + { + if( KFPlayerOwner != none ) + { + KFPlayerOwner.GetPlayerViewPoint( ViewLocation, ViewRotation ); + } + ViewVector = vector(ViewRotation); - if( KFPH.IsAliveAndWell() && KFPH != PlayerOwner.Pawn) - { - if((WorldInfo.TimeSeconds - KFPH.Mesh.LastRenderTime) < 0.4f && (ThisDot > 0 && ThisDot < 1.0) ) - { - if( H!=None ) - { - DrawFriendlyHUD(H); - VisibleHumanPlayers.AddItem( H.PlayerReplicationInfo ); - } - else DrawMonsterHUD(KFPH); - } - else if( H != None ) - { - HiddenHumanPlayers.Insert( 0, 1 ); - HiddenHumanPlayers[0].HumanPawn = H; - HiddenHumanPlayers[0].HumanPRI = H.PlayerReplicationInfo; - } - } - } - } + Canvas.EnableStencilTest(true); + foreach WorldInfo.AllPawns( class'KFPawn_Human', KFPH ) + { + if( KFPH.IsAliveAndWell() && KFPH != KFPlayerOwner.Pawn && KFPH.Mesh.SkeletalMesh != none && KFPH.Mesh.bAnimTreeInitialised ) + { + PlayerPartyInfoLocation = KFPH.Mesh.GetPosition() + ( KFPH.CylinderComponent.CollisionHeight * vect(0,0,1) ); + if(`TimeSince(KFPH.Mesh.LastRenderTime) < 0.2f && Normal(PlayerPartyInfoLocation - ViewLocation) dot ViewVector > 0.f ) + { + if( DrawFriendlyHumanPlayerInfo(KFPH) ) + { + VisibleHumanPlayers.AddItem( KFPH.PlayerReplicationInfo ); + } + else + { + HiddenHumanPlayers.Insert( 0, 1 ); + HiddenHumanPlayers[0].HumanPawn = KFPH; + HiddenHumanPlayers[0].HumanPRI = KFPH.PlayerReplicationInfo; + } + } + else + { + HiddenHumanPlayers.Insert( 0, 1 ); + HiddenHumanPlayers[0].HumanPawn = KFPH; + HiddenHumanPlayers[0].HumanPRI = KFPH.PlayerReplicationInfo; + } + } + } - // Draw hidden players - CheckAndDrawHiddenPlayerIcons( VisibleHumanPlayers, HiddenHumanPlayers ); + foreach WorldInfo.AllPawns(class'KFPawn_Scripted', KFPS) + { + if (KFPS.ShouldShowOnHUD()) + { + PlayerPartyInfoLocation = KFPS.Mesh.GetPosition() + (KFPS.CylinderComponent.CollisionHeight * vect(0,0,1)); + DrawScriptedPawnInfo(KFPS, Normal(PlayerPartyInfoLocation - ViewLocation) dot ViewVector, `TimeSince(KFPS.Mesh.LastRenderTime) < 0.2f); + } + } - // Draw last remaining zeds - CheckAndDrawRemainingZedIcons(); - - Canvas.EnableStencilTest(false); - - if( bSpec ) - { - // Draw zed health bars. - foreach WorldInfo.AllPawns(class'KFPawn_Monster', M) - { - ThisDot = (PLCameraDir Dot (M.Location + M.CylinderComponent.CollisionHeight * vect(0,0,1))) - PLCameraDot; - if( ThisDot>0 && ThisDot<8000.f && M.IsAliveAndWell() && M.PlayerReplicationInfo!=None && M!=PlayerOwner.Pawn && (WorldInfo.TimeSeconds - M.Mesh.LastRenderTime) < 0.4f ) - DrawFriendlyHUDZ(M); - } - } - } + if( !KFGRI.bHidePawnIcons ) + { + // Draw hidden players + CheckAndDrawHiddenPlayerIcons( VisibleHumanPlayers, HiddenHumanPlayers ); + + // Draw last remaining zeds + CheckAndDrawRemainingZedIcons(); + + //Draw our current objective location + if(KFGRI.CurrentObjective != none && KFGRI.ObjectiveInterface != none) + { + KFGRI.ObjectiveInterface.DrawHUD(self, Canvas); + + TargetLocation = KFGRI.ObjectiveInterface.GetIconLocation(); + ThisDot = Normal((TargetLocation + (class'KFPawn_Human'.default.CylinderComponent.CollisionHeight * vect(0, 0, 1))) - ViewLocation) dot ViewVector; + + if (ThisDot > 0 && + KFGRI.ObjectiveInterface.ShouldShowObjectiveHUD() && + (!KFGRI.ObjectiveInterFace.HasObjectiveDrawDistance() || VSizeSq(TargetLocation - LocActor.Location) < MaxDrawDistanceObjective)) + { + DrawObjectiveHUD(); + } + } + } + + Canvas.EnableStencilTest(false); + } } else if( KFPawn_Monster(PlayerOwner.Pawn)!=None ) { // Draw human health auras. DotScale = Canvas.ClipX*0.2f; - foreach WorldInfo.AllPawns(class'KFPawn_Human', H) + foreach WorldInfo.AllPawns(class'KFPawn_Human', KFPH) { - PawnLocation = H.Location; + PawnLocation = KFPH.Location; if( IsZero( PawnLocation ) ) { @@ -544,12 +578,12 @@ function DrawHUD() } ThisDot = (PLCameraDir Dot PawnLocation) - PLCameraDot; - if( H.IsAliveAndWell() && ThisDot>0.f && ThisDot<10000.f ) + if( KFPH.IsAliveAndWell() && ThisDot>0.f && ThisDot<10000.f ) { V = Canvas.Project(PawnLocation); if( V.X<-100 || V.X>(Canvas.SizeX+100) || V.Y<-100 || V.Y>(Canvas.SizeY+100) ) continue; - Canvas.DrawColor = GetHPColorScale(H); + Canvas.DrawColor = GetHPColorScale(KFPH); if( PlayerOwner.FastTrace(PawnLocation,PLCameraLoc) ) ThisDot*=1.75f; ThisDot = (DotScale/ThisDot)*350.f; @@ -560,6 +594,7 @@ function DrawHUD() if( !class'ExtPlayerController'.Default.bHideNameBeacons ) { + Canvas.EnableStencilTest(true); // Draw zed health bars. foreach WorldInfo.AllPawns(class'KFPawn_Monster', M) { @@ -567,52 +602,9 @@ function DrawHUD() if( ThisDot>0 && ThisDot<8000.f && M.IsAliveAndWell() && M.PlayerReplicationInfo!=None && M!=PlayerOwner.Pawn && (WorldInfo.TimeSeconds - M.Mesh.LastRenderTime) < 0.4f ) DrawFriendlyHUDZ(M); } + Canvas.EnableStencilTest(false); } } - - Canvas.Font = GetFontSizeIndex(0); - DrawActorOverlays(PLCameraLoc, PLCameraRot); -} - -function DrawHiddenHumanPlayerIcon( PlayerReplicationInfo PRI, vector IconWorldLocation ) -{ - local vector ScreenPos; - local float IconSizeMult; - local KFPlayerReplicationInfo KFPRI; - local Texture2D PlayerIcon; - local Color PerkColor; - local ExtPlayerReplicationInfo ExtPRI; - local Texture2D HumanIcon; - - KFPRI = KFPlayerReplicationInfo(PRI); - if( KFPRI == None ) - return; - - // Project world pos to canvas - ScreenPos = Canvas.Project( IconWorldLocation + vect(0,0,2.2f) * class'KFPAwn_Human'.default.CylinderComponent.CollisionHeight ); - - // Fudge by icon size - IconSizeMult = PlayerStatusIconSize * FriendlyHudScale * 0.5f; - ScreenPos.X -= IconSizeMult; - ScreenPos.Y -= IconSizeMult; - - if( ScreenPos.X < 0 || ScreenPos.X > Canvas.SizeX || ScreenPos.Y < 0 || ScreenPos.Y > Canvas.SizeY ) - { - return; - } - - ExtPRI = ExtPlayerReplicationInfo(KFPRI); - if( ExtPRI == None ) - return; - - HumanIcon = ExtPRI.ECurrentPerk != None ? ExtPRI.ECurrentPerk.Default.PerkIcon : GenericHumanIconTexture; - PlayerIcon = PlayerOwner.GetTeamNum() == 0 ? HumanIcon : GenericHumanIconTexture; - PerkColor = ExtPRI.HUDPerkColor; - - // Draw human icon - Canvas.SetDrawColor( PerkColor.R, PerkColor.G, PerkColor.B, PerkColor.A ); - Canvas.SetPos( ScreenPos.X, ScreenPos.Y ); - Canvas.DrawTile( PlayerIcon, PlayerStatusIconSize * FriendlyHudScale, PlayerStatusIconSize * FriendlyHudScale, 0, 0, 256, 256 ); } simulated static final function color GetHPColorScale( Pawn P ) @@ -642,8 +634,10 @@ simulated function DrawFriendlyHUDZ( KFPawn_Monster KFPH ) local vector ScreenPos, TargetLocation; local FontRenderInfo MyFontRenderInfo; local float FontScale; + local byte FadeAlpha; MyFontRenderInfo = Canvas.CreateFontRenderInfo( true ); + FadeAlpha = DrawToDistance(KFPH); BarLength = FMin(PlayerStatusBarLengthMax * (float(Canvas.SizeX) / 1024.f), PlayerStatusBarLengthMax) * FriendlyHudScale; BarHeight = FMin(8.f * (float(Canvas.SizeX) / 1024.f), 8.f) * FriendlyHudScale; @@ -656,16 +650,19 @@ simulated function DrawFriendlyHUDZ( KFPawn_Monster KFPH ) //Draw health bar Percentage = float(KFPH.Health) / float(KFPH.HealthMax); - DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor); + DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor, FadeAlpha); //Draw player name (Top) FontScale = class'KFGameEngine'.Static.GetKFFontScale() * FriendlyHudScale; Canvas.Font = class'KFGameEngine'.Static.GetKFCanvasFont(); - Canvas.SetDrawColorStruct(DrawToDistance(KFPH, PlayerBarTextColor)); + + Canvas.DrawColor = PlayerBarTextColor; + Canvas.DrawColor.A = FadeAlpha; + Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight * 2); Canvas.DrawText( KFPH.PlayerReplicationInfo.PlayerName,,FontScale,FontScale, MyFontRenderInfo ); } -simulated function DrawFriendlyHUD( KFPawn_Human KFPH ) +simulated function bool DrawFriendlyHumanPlayerInfo( KFPawn_Human KFPH ) { local float Percentage; local float BarHeight, BarLength; @@ -673,91 +670,122 @@ simulated function DrawFriendlyHUD( KFPawn_Human KFPH ) local ExtPlayerReplicationInfo KFPRI; local FontRenderInfo MyFontRenderInfo; local float FontScale; - local string S; + local float ResModifier; + local float PerkIconPosX, PerkIconPosY, SupplyIconPosX, SupplyIconPosY, PerkIconSize; + local color CurrentArmorColor, CurrentHealthColor, TextColor; + local string S; + local byte FadeAlpha; + ResModifier = WorldInfo.static.GetResolutionBasedHUDScale() * FriendlyHudScale; KFPRI = ExtPlayerReplicationInfo(KFPH.PlayerReplicationInfo); if( KFPRI == none ) - return; + { + return false; + } + FadeAlpha = DrawToDistance(KFPH); MyFontRenderInfo = Canvas.CreateFontRenderInfo( true ); + BarLength = FMin(PlayerStatusBarLengthMax * (Canvas.ClipX / 1024.f), PlayerStatusBarLengthMax) * ResModifier; + BarHeight = FMin(8.f * (Canvas.ClipX / 1024.f), 8.f) * ResModifier; - BarLength = FMin(PlayerStatusBarLengthMax * (float(Canvas.SizeX) / 1024.f), PlayerStatusBarLengthMax) * FriendlyHudScale; - BarHeight = FMin(8.f * (float(Canvas.SizeX) / 1024.f), 8.f) * FriendlyHudScale; - - TargetLocation = KFPH.Location + vect(0,0,1) * KFPH.GetCollisionHeight() * 1.2; - - ScreenPos = Canvas.Project(TargetLocation); - if( ScreenPos.X < 0 || ScreenPos.X > Canvas.SizeX || ScreenPos.Y < 0 || ScreenPos.Y > Canvas.SizeY ) - return; - - //Draw health bar - Percentage = FMin(float(KFPH.Health) / float(KFPH.HealthMax),1.f); - DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor, true); - - //Draw armor bar - Percentage = FMin(float(KFPH.Armor) / float(KFPH.MaxArmor),1.f); - DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight, ArmorColor); + TargetLocation = KFPH.Mesh.GetPosition() + ( KFPH.CylinderComponent.CollisionHeight * vect(0,0,2.5f) ); + ScreenPos = Canvas.Project( TargetLocation ); + if( ScreenPos.X < 0 || ScreenPos.X > Canvas.ClipX || ScreenPos.Y < 0 || ScreenPos.Y > Canvas.ClipY ) + { + return false; + } //Draw player name (Top) FontScale = class'KFGameEngine'.Static.GetKFFontScale() * FriendlyHudScale; Canvas.Font = class'KFGameEngine'.Static.GetKFCanvasFont(); - S = KFPRI.GetHumanReadableName(); + + // drop shadow for player name text + S = KFPRI.PlayerName; if( KFPRI.bBot ) { S = S$" (Bot)"; - Canvas.DrawColor = KFPRI.HUDPerkColor; + TextColor = KFPRI.HUDPerkColor; } else if( KFPRI.ShowAdminName() ) // Admin info. { S = S$" ("$KFPRI.GetAdminNameAbr()$")"; - Canvas.DrawColor = KFPRI.GetAdminColorC(); + TextColor = KFPRI.GetAdminColorC(); } - else Canvas.DrawColor = WhiteColor; - + else TextColor = PlayerBarTextColor; + if( bMeAdmin && KFPRI.FixedData>0 ) { - Canvas.SetDrawColor(255,0,0,255); - S $= " -"$KFPRI.GetDesc(); + TextColor = MakeColor(255,0,0,255); + S @= "-"$KFPRI.GetDesc(); } - Canvas.DrawColor = DrawToDistance(KFPH, Canvas.DrawColor); - - Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight * 3); - Canvas.DrawText( S,,FontScale,FontScale, MyFontRenderInfo ); + + TextColor.A = FadeAlpha; + + Canvas.DrawColor = PlayerBarShadowColor; + Canvas.DrawColor.A = FadeAlpha; + Canvas.SetPos(ScreenPos.X - (BarLength * 0.5f) + 1, ScreenPos.Y + 8); + Canvas.DrawText(S, , FontScale, FontScale, MyFontRenderInfo); - if( KFPRI.ECurrentPerk!=none ) + Canvas.DrawColor = TextColor; + Canvas.SetPos(ScreenPos.X - (BarLength * 0.5f), ScreenPos.Y + 7); + Canvas.DrawText(S, , FontScale, FontScale, MyFontRenderInfo); + + //Draw armor bar + Percentage = FMin(float(KFPH.Armor) / float(KFPH.MaxArmor), 100); + CurrentArmorColor = ClassicPlayerInfo ? ClassicArmorColor : ArmorColor; + CurrentArmorColor.A = FadeAlpha; + DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength * 0.5f), ScreenPos.Y + BarHeight + (36 * FontScale * ResModifier), CurrentArmorColor, FadeAlpha); + + //Draw health bar + Percentage = FMin(float(KFPH.Health) / float(KFPH.HealthMax), 100); + CurrentHealthColor = ClassicPlayerInfo ? ClassicHealthColor : HealthColor; + CurrentHealthColor.A = FadeAlpha; + DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength * 0.5f), ScreenPos.Y + BarHeight * 2 + (36 * FontScale * ResModifier), CurrentHealthColor, FadeAlpha, true); + + if( KFPRI.ECurrentPerk == None ) { - //draw perk icon - Canvas.DrawColor = DrawToDistance(KFPH, KFPRI.HUDPerkColor); - Canvas.SetPos(ScreenPos.X - (BarLength * 0.75), ScreenPos.Y - BarHeight * 2); - Canvas.DrawRect(PlayerStatusIconSize*FriendlyHudScale,PlayerStatusIconSize*FriendlyHudScale,KFPRI.ECurrentPerk.default.PerkIcon); - - //Draw perk level and name text - Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y + BarHeight); - Canvas.DrawText( KFPRI.GetPerkLevelStr()@KFPRI.ECurrentPerk.default.PerkName,,FontScale,FontScale, MyFontRenderInfo ); - - if( KFPRI.HasSupplier!=None ) - { - Canvas.DrawColor = DrawToDistance(KFPH, (KFPlayerOwner.Pawn==None || KFPRI.CanUseSupply(KFPlayerOwner.Pawn)) ? SupplierUsableColor : SupplierActiveColor); - Canvas.SetPos( ScreenPos.X + BarLength * 0.5f, ScreenPos.Y - BarHeight * 2 ); - Canvas.DrawRect( PlayerStatusIconSize*FriendlyHudScale, PlayerStatusIconSize*FriendlyHudScale, KFPRI.HasSupplier.Default.SupplyIcon); - } + return false; } - else if( KFPRI.bBot && KFPRI.CurrentPerkClass!=none ) - { - //draw perk icon - Canvas.SetPos(ScreenPos.X - (BarLength * 0.75), ScreenPos.Y - BarHeight * 2); - Canvas.DrawRect(PlayerStatusIconSize*FriendlyHudScale,PlayerStatusIconSize*FriendlyHudScale,KFPRI.CurrentPerkClass.default.PerkIcon); - //Draw name text - Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y + BarHeight); - Canvas.DrawText( KFPRI.CurrentPerkClass.default.PerkName,,FontScale,FontScale, MyFontRenderInfo ); - } + // drop shadow for perk name text + Canvas.DrawColor = PlayerBarShadowColor; + Canvas.DrawColor.A = FadeAlpha; + Canvas.SetPos(ScreenPos.X - (BarLength * 0.5f) + 1, ScreenPos.Y + BarHeight * 3 + (36 * FontScale * ResModifier) + 1); + Canvas.DrawText(KFPRI.GetPerkLevelStr()@KFPRI.ECurrentPerk.default.PerkName, , FontScale, FontScale, MyFontRenderInfo); + + //Draw perk level and name text + Canvas.DrawColor = PlayerBarTextColor; + Canvas.DrawColor.A = FadeAlpha; + Canvas.SetPos(ScreenPos.X - (BarLength * 0.5f), ScreenPos.Y + BarHeight * 3 + (36 * FontScale * ResModifier)); + Canvas.DrawText(KFPRI.GetPerkLevelStr()@KFPRI.ECurrentPerk.default.PerkName, , FontScale, FontScale, MyFontRenderInfo); + + // drop shadow for perk icon + Canvas.DrawColor = PlayerBarShadowColor; + Canvas.DrawColor.A = FadeAlpha; + PerkIconSize = PlayerStatusIconSize * ResModifier; + PerkIconPosX = ScreenPos.X - (BarLength * 0.5f) - PerkIconSize + 1; + PerkIconPosY = ScreenPos.Y + (36 * FontScale * ResModifier) + 1; + SupplyIconPosX = ScreenPos.X + (BarLength * 0.5f) + 1; + SupplyIconPosY = PerkIconPosY + 4 * ResModifier; + DrawPerkIcons(KFPH, PerkIconSize, PerkIconPosX, PerkIconPosY, SupplyIconPosX, SupplyIconPosY, true); + + //draw perk icon + Canvas.DrawColor = PlayerBarIconColor; + Canvas.DrawColor.A = FadeAlpha; + PerkIconPosX = ScreenPos.X - (BarLength * 0.5f) - PerkIconSize; + PerkIconPosY = ScreenPos.Y + (36 * FontScale * ResModifier); + SupplyIconPosX = ScreenPos.X + (BarLength * 0.5f); + SupplyIconPosY = PerkIconPosY + 4 * ResModifier; + DrawPerkIcons(KFPH, PerkIconSize, PerkIconPosX, PerkIconPosY, SupplyIconPosX, SupplyIconPosY, false); + + return true; } -simulated final function DrawPlayerInfoBar( KFPawn P, float BarPercentage, float BarLength, float BarHeight, float XPos, float YPos, Color BarColor, optional bool bDrawingHealth ) +simulated final function DrawPlayerInfoBar( KFPawn P, float BarPercentage, float BarLength, float BarHeight, float XPos, float YPos, Color BarColor, byte FadeAlpha, optional bool bDrawingHealth ) { //background for status bar - Canvas.SetDrawColorStruct(DrawToDistance(P, PlayerBarBGColor)); + Canvas.DrawColor = PlayerBarBGColor; + Canvas.DrawColor.A = FadeAlpha; Canvas.SetPos(XPos, YPos); Canvas.DrawTileStretched(PlayerStatusBarBGTexture, BarLength, BarHeight, 0, 0, 32, 32); @@ -767,7 +795,8 @@ simulated final function DrawPlayerInfoBar( KFPawn P, float BarPercentage, float BarHeight-=2; //Forground for status bar. - Canvas.SetDrawColorStruct(DrawToDistance(P, BarColor)); + Canvas.DrawColor = BarColor; + Canvas.DrawColor.A = FadeAlpha; Canvas.SetPos(XPos, YPos); Canvas.DrawTileStretched(PlayerStatusBarBGTexture, BarLength * BarPercentage, BarHeight, 0, 0, 32, 32); @@ -777,11 +806,76 @@ simulated final function DrawPlayerInfoBar( KFPawn P, float BarPercentage, float XPos+=(BarLength * BarPercentage); BarPercentage = FMin(float(ExtHumanPawn(P).RepRegenHP) / float(P.HealthMax),1.f-BarPercentage); - Canvas.DrawColor = DrawToDistance(P, MakeColor(255,128,128,255)); + Canvas.DrawColor = MakeColor(255,128,128,FadeAlpha); Canvas.SetPos(XPos, YPos); Canvas.DrawTileStretched(PlayerStatusBarBGTexture, BarLength * BarPercentage, BarHeight, 0, 0, 32, 32); } } +simulated function DrawPerkIcons(KFPawn_Human KFPH, float PerkIconSize, float PerkIconPosX, float PerkIconPosY, float SupplyIconPosX, float SupplyIconPosY, bool bDropShadow) +{ + local byte PrestigeLevel; + local ExtPlayerReplicationInfo KFPRI; + local color TempColor; + local float ResModifier; + + KFPRI = ExtPlayerReplicationInfo(KFPH.PlayerReplicationInfo); + + if (KFPRI == none) + { + return; + } + + PrestigeLevel = KFPRI.GetActivePerkPrestigeLevel(); + ResModifier = WorldInfo.static.GetResolutionBasedHUDScale() * FriendlyHudScale; + + if (KFPRI.CurrentVoiceCommsRequest == VCT_NONE && KFPRI.ECurrentPerk != none && PrestigeLevel > 0) + { + Canvas.SetPos(PerkIconPosX, PerkIconPosY); + Canvas.DrawTile(KFPRI.ECurrentPerk.default.BasePerk.default.PrestigeIcons[PrestigeLevel - 1], PerkIconSize, PerkIconSize, 0, 0, 256, 256); + } + + if (PrestigeLevel > 0) + { //icon slot in image is not centered + Canvas.SetPos(PerkIconPosX + (PerkIconSize * (1 - PrestigeIconScale)) / 2, PerkIconPosY + PerkIconSize * 0.05f); + Canvas.DrawTile(KFPRI.GetCurrentIconToDisplay(), PerkIconSize * PrestigeIconScale, PerkIconSize * PrestigeIconScale, 0, 0, 256, 256); + } + else + { + Canvas.SetPos(PerkIconPosX, PerkIconPosY); + Canvas.DrawTile(KFPRI.GetCurrentIconToDisplay(), PerkIconSize, PerkIconSize, 0, 0, 256, 256); + } + + if (KFPRI.PerkSupplyLevel > 0 && KFPRI.ECurrentPerk.default.BasePerk.static.GetInteractIcon() != none) + { + if (!bDropShadow) + { + if (KFPRI.PerkSupplyLevel == 2) + { + if (KFPRI.bPerkPrimarySupplyUsed && KFPRI.bPerkSecondarySupplyUsed) + { + TempColor = SupplierActiveColor; + } + else if (KFPRI.bPerkPrimarySupplyUsed || KFPRI.bPerkSecondarySupplyUsed) + { + TempColor = SupplierHalfUsableColor; + } + else + { + TempColor = SupplierUsableColor; + } + } + else if (KFPRI.PerkSupplyLevel == 1) + { + TempColor = KFPRI.bPerkPrimarySupplyUsed ? SupplierActiveColor : SupplierUsableColor; + } + + Canvas.SetDrawColorStruct(TempColor); + } + + Canvas.SetPos(SupplyIconPosX, SupplyIconPosY); //offset so that supplier icon shows up on the correct side of the player's health bar + Canvas.DrawTile(KFPRI.ECurrentPerk.default.BasePerk.static.GetInteractIcon(), (PlayerStatusIconSize * 0.75) * ResModifier, (PlayerStatusIconSize * 0.75) * ResModifier, 0, 0, 256, 256); + } +} simulated function DrawMonsterHUD( KFPawn KFPH ) { local float Percentage; @@ -790,11 +884,13 @@ simulated function DrawMonsterHUD( KFPawn KFPH ) local Ext_T_MonsterPRI PRI; local FontRenderInfo MyFontRenderInfo; local float FontScale; + local byte FadeAlpha; PRI = Ext_T_MonsterPRI(KFPH.PlayerReplicationInfo); if( PRI==None ) return; + FadeAlpha = DrawToDistance(KFPH); MyFontRenderInfo = Canvas.CreateFontRenderInfo( true ); BarLength = FMin(PlayerStatusBarLengthMax * (float(Canvas.SizeX) / 1024.f), PlayerStatusBarLengthMax) * FriendlyHudScale; @@ -808,12 +904,12 @@ simulated function DrawMonsterHUD( KFPawn KFPH ) //Draw health bar Percentage = FMin(float(KFPH.Health) / float(KFPH.HealthMax),1.f); - DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor); + DrawPlayerInfoBar(KFPH, Percentage, BarLength, BarHeight, ScreenPos.X - (BarLength *0.5f), ScreenPos.Y, HealthColor, FadeAlpha); //Draw player name (Top) FontScale = class'KFGameEngine'.Static.GetKFFontScale() * FriendlyHudScale; Canvas.Font = class'KFGameEngine'.Static.GetKFCanvasFont(); - Canvas.DrawColor = DrawToDistance(KFPH, (PRI.OwnerPRI==PlayerOwner.PlayerReplicationInfo ? MakeColor(32,250,32,255) : MakeColor(250,32,32,255))); + Canvas.DrawColor = PRI.OwnerPRI==PlayerOwner.PlayerReplicationInfo ? MakeColor(32,250,32,FadeAlpha) : MakeColor(250,32,32,FadeAlpha); Canvas.SetPos(ScreenPos.X - (BarLength *0.5f), ScreenPos.Y - BarHeight * 3); Canvas.DrawText( PRI.PlayerName,,FontScale,FontScale, MyFontRenderInfo ); @@ -866,18 +962,16 @@ simulated function DrawPetInfo() } } -function Color DrawToDistance(KFPawn Pawn, Color DrawColor) +function byte DrawToDistance(Actor A, optional float StartAlpha=255.f, optional float MinAlpha=90.f) { - local float Dist, fZoom; + local float Dist, fZoom; - Dist = VSize(Pawn.Location - PLCameraLoc) * 0.5; + Dist = VSize(A.Location - PLCameraLoc); if ( Dist <= HealthBarFullVisDist || PlayerOwner.PlayerReplicationInfo.bOnlySpectator ) fZoom = 1.0; else fZoom = FMax(1.0 - (Dist - HealthBarFullVisDist) / (HealthBarCutoffDist - HealthBarFullVisDist), 0.0); - - DrawColor.A = Clamp(255 * fZoom, 90, 255); - - return DrawColor; + + return Clamp(StartAlpha * fZoom, MinAlpha, StartAlpha); } final function AddNumberMsg( int Amount, vector Pos, byte Type ) @@ -1059,13 +1153,13 @@ simulated final function DrawItemsList() Canvas.TextSize(NewItems[i].Item,XS,YS,FontScale,FontScale); - if( NewItems[i].Icon!=None ) + /*if( NewItems[i].Icon!=None ) { Canvas.SetPos(XPos-YSize,YPos); Canvas.DrawRect(YSize,YSize,NewItems[i].Icon); XS = XPos-(YSize*1.1)-XS; } - else XS = XPos-XS; + else */XS = XPos-XS; Canvas.SetPos(XS,YPos); Canvas.DrawText("New Item:",,FontScale,FontScale); diff --git a/ServerExt/Classes/SRPerkManager.uc b/ServerExt/Classes/SRPerkManager.uc new file mode 100644 index 0000000..794570b --- /dev/null +++ b/ServerExt/Classes/SRPerkManager.uc @@ -0,0 +1,5 @@ +Class SRPerkManager extends ExtPerkManager; + +defaultproperties +{ +} \ No newline at end of file diff --git a/ServerExtMut/Classes/ServerExtMut.uc b/ServerExtMut/Classes/ServerExtMut.uc index 7b277b1..c50b4ee 100644 --- a/ServerExtMut/Classes/ServerExtMut.uc +++ b/ServerExtMut/Classes/ServerExtMut.uc @@ -49,6 +49,7 @@ var int LastWaveNum,NumWaveSwitches; var ExtSpawnPointHelper SpawnPointer; var bool bRespawnCheck,bSpecialSpawn,bGameHasEnded,bIsPostGame; var config bool bKillMessages,bDamageMessages,bEnableMapVote,bNoAdminCommands,bNoWebAdmin,bNoBoomstickJumping,bDumpXMLStats,bRagdollFromFall,bRagdollFromMomentum,bRagdollFromBackhit,bAddCountryTags; +var config bool bServerPerksMode; function PostBeginPlay() { @@ -426,7 +427,7 @@ final function GT_PlayerKilled( Controller Killer, Controller Killed, class