2020-12-13 15:01:13 +00:00
//=============================================================================
// KFWeap_ScopedBase
//=============================================================================
// Base class for weapons with scopes
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// John "Ramm-Jaeger" Gibson
//=============================================================================
class KFWeap _ScopedBase extends KFWeapon
abstract ;
/** component that renders the scene to a texture */
var ( Scope ) const TWSceneCapture2DDPGComponent SceneCapture ;
/** Ratio of the scope texture relative to screen resolution (Should be between 0.0-1.0) */
var ( Scope ) float ScopeTextureScale ;
/** Restrict the scene capture texture from getting too large, especially on ultra wide displays **/
var int MaxSceneCaptureSize ;
/ * * N a m e o f t h e p a r a m e t e r u s e d t o b l e n d b e t w e e n s c e n e c a p t u r e t e x t u r e ( w h e n i n i r o n s i g h t s ) a n d
regular texture ( when hipped )
1.0 => Scene capture texture
0.0 => Generic texture
* /
var ( Scope ) name InterpParamName ;
/** Texture target to which the above SceneCapture component renders to */
var TextureRenderTarget2D SniperScopeTextureTarget ;
/ * * T e m p l a t e M I C u s e d b y t h e s n i p e r s c o p e . T h e M I C a c t u a l l y u s e d b y t h e s c o p e s h o u l d d e r i v e f r o m t h i s .
This is necessary because Unreal warns against modifying an MIC in a package directly * /
var const MaterialInstanceConstant ScopeLenseMICTemplate ;
/** Actual MIC used by the scope */
var MaterialInstanceConstant ScopeLenseMIC ;
/ * * C u r r e n t l e n g t h o f t h e s q u a r e s c o p e t e x t u r e . T h i s i s c h e c k e d a g a i n s t b e f o r e m o d i f y i n g t h e
ScopeTextureSize in the scenario when InitFOV is called multiple times with the same values * /
var int CurrentScopeTextureSize ;
var ( Scope ) float ScopedSensitivityMod ;
2021-06-02 20:06:18 +00:00
/** MIC Index for the scope material */
var byte ScopeMICIndex ;
2020-12-13 15:01:13 +00:00
simulated exec function ScopeFOV ( float NewFOV )
{
//SetCaptureParameters( optional TextureRenderTarget2D NewTextureTarget = TextureTarget,
// optional float NewFOV = FieldOfView, optional float NewNearPlane = NearPlane,
// optional float NewFarPlane = FarPlane );
SceneCapture . SetCaptureParameters ( , NewFOV ) ;
}
/** Returns trader filter index based on weapon type (copied from riflebase) */
static simulated event EFilterTypeUI GetTraderFilter ( )
{
if ( default . FiringStatesArray [ DEFAULT _FIREMODE ] == 'WeaponFiring' || default . FiringStatesArray [ DEFAULT _FIREMODE ] == 'WeaponBurstFiring' )
{
return FT _Assault ;
}
else // if( FiringStatesArray[DEFAULT_FIREMODE] == 'WeaponSingleFiring')
{
return FT _Rifle ;
}
}
/ * *
* See Pawn . ProcessInstantHit
* @ param DamageReduction : Custom KF parameter to handle penetration damage reduction
* /
simulated function ProcessInstantHitEx ( byte FiringMode , ImpactInfo Impact , optional int NumHits , optional out float out _PenetrationVal , optional int ImpactNum )
{
local KFPerk InstigatorPerk ;
InstigatorPerk = GetPerk ( ) ;
if ( InstigatorPerk != none )
{
InstigatorPerk . UpdatePerkHeadShots ( Impact , InstantHitDamageTypes [ FiringMode ] , ImpactNum ) ;
}
super . ProcessInstantHitEx ( FiringMode , Impact , NumHits , out _PenetrationVal , ImpactNum ) ;
}
/ * *
* Initialize the FOV settings for this weapon , adjusting for aspect ratio
* @ param SizeX the X resolution of the screen
* @ param SizeY the Y resolution of the screen
* @ param DefaultPlayerFOV the default player FOV of the player holding this weapon
* /
simulated function InitFOV ( float SizeX , float SizeY , float DefaultPlayerFOV )
{
local int NewScopeTextureSize ;
super . InitFOV ( SizeX , SizeY , DefaultPlayerFOV ) ;
NewScopeTextureSize = int ( ScopeTextureScale * SizeX ) ;
if ( NewScopeTextureSize > MaxSceneCaptureSize )
NewScopeTextureSize = MaxSceneCaptureSize ;
if ( CurrentScopeTextureSize != NewScopeTextureSize )
{
SniperScopeTextureTarget = class 'TextureRenderTarget2D' . static . Create ( NewScopeTextureSize , NewScopeTextureSize , PF _FloatRGBA ) ;
SniperScopeTextureTarget . TargetGamma = 1. f ;
SceneCapture . SetCaptureParameters ( SniperScopeTextureTarget ) ;
if ( ScopeLenseMIC != none )
{
ScopeLenseMIC . SetTextureParameterValue ( 'ScopeTextureTarget' , SniperScopeTextureTarget ) ;
}
CurrentScopeTextureSize = NewScopeTextureSize ;
}
}
/ * *
* Set parameters for the weapon once replication is complete ( works in Standalone as well )
* /
reliable client function ClientWeaponSet ( bool bOptionalSet , optional bool bDoNotActivate )
{
Super . ClientWeaponSet ( bOptionalSet ) ;
// Only want to spawn sniper lenses on human players, but when PostBeginPlay
// gets called Instigator isn't valid yet. So using NetMode == NM_Client,
// since weapons should only exist on owning human clients with that netmode
if ( Instigator != none && Instigator . IsLocallyControlled ( ) && Instigator . IsHumanControlled ( ) )
{
ScopeLenseMIC = new class 'MaterialInstanceConstant' ;
ScopeLenseMIC . SetParent ( ScopeLenseMICTemplate ) ;
ScopeLenseMIC . SetTextureParameterValue ( 'ScopeTextureTarget' , SniperScopeTextureTarget ) ;
ScopeLenseMIC . SetScalarParameterValue ( InterpParamName , 0.0 ) ;
2021-06-02 20:06:18 +00:00
mesh . SetMaterial ( ScopeMICIndex , ScopeLenseMIC ) ;
2020-12-13 15:01:13 +00:00
}
}
/ * *
* This function aligns the gun model in the world
* /
simulated event SetPosition ( KFPawn Holder )
{
if ( ! Holder . IsFirstPerson ( ) )
return ;
super . SetPosition ( Holder ) ;
if ( ScopeLenseMIC != none )
{
ScopeLenseMIC . SetScalarParameterValue ( 'u_position_shadow' , - WeaponLag . Y ) ;
ScopeLenseMIC . SetScalarParameterValue ( 'v_position_shadow' , WeaponLag . Z ) ;
}
if ( bUsingSights )
{
SceneCapture . SetView ( Location , Rotation ) ;
}
}
/ * *
* Return an FOVAngle used by the PlayerInput class to determine how much to
* reduce the sensitivity when using sights / scopes . Added since the 3 d scope
* zooms in farther than the player ' s FOV .
* /
simulated function float GetModifiedFOVAngle ( )
{
if ( bUsingSights )
{
return default . PlayerIronSightFOV / SceneCapture . FieldOfView * ScopedSensitivityMod ;
}
else
{
return Super . GetModifiedFOVAngle ( ) ;
}
}
/ * *
* Attach Weapon Mesh , Weapon MuzzleFlash and Muzzle Flash Dynamic Light to a SkeletalMesh
*
* @ param who is the pawn to attach to
* /
simulated function AttachWeaponTo ( SkeletalMeshComponent MeshCpnt , optional Name SocketName )
{
Super . AttachWeaponTo ( MeshCpnt , SocketName ) ;
if ( Instigator != none )
{
Instigator . AttachComponent ( SceneCapture ) ;
}
}
/ * *
* Detach weapon from skeletal mesh
*
* @ param SkeletalMeshComponent weapon is attached to .
* /
simulated function DetachWeapon ( )
{
super . DetachWeapon ( ) ;
if ( Instigator != none )
{
Instigator . DetachComponent ( SceneCapture ) ;
}
}
/ * *
* Tick the weapon ( used for simple updates )
*
* @ param DeltaTime Elapsed time .
* /
simulated event Tick ( float DeltaTime )
{
local float InterpValue ;
local float DefaultZoomInTime ;
super . Tick ( DeltaTime ) ;
if ( ScopeLenseMIC == none )
{
return ;
}
if ( Instigator != none && Instigator . Controller != none && Instigator . IsHumanControlled ( ) )
{
if ( bZoomingOut )
{
InterpValue = ZoomTime / default . ZoomOutTime ;
ScopeLenseMIC . SetScalarParameterValue ( InterpParamName , InterpValue ) ;
}
else if ( bZoomingIn )
{
DefaultZoomInTime = default . ZoomInTime ;
InterpValue = - ZoomTime / DefaultZoomInTime + 1 ;
ScopeLenseMIC . SetScalarParameterValue ( InterpParamName , InterpValue ) ;
}
}
}
/ * *
* Called by the native code when the interpolation of the first person weapon to the zoomed position finishes
* /
simulated event OnZoomInFinished ( )
{
if ( ScopeLenseMIC != none )
{
ScopeLenseMIC . SetScalarParameterValue ( InterpParamName , 1.0 ) ;
}
super . OnZoomInFinished ( ) ;
}
/ * *
* Called by the native code when the interpolation of the first person weapon from the zoomed position finishes
* /
simulated event OnZoomOutFinished ( )
{
if ( ScopeLenseMIC != none )
{
ScopeLenseMIC . SetScalarParameterValue ( InterpParamName , 0.0 ) ;
}
super . OnZoomOutFinished ( ) ;
}
/ * *
* Handles all the functionality for zooming in including
* setting the parameters for the weapon , pawn , and playercontroller
*
* @ param bAnimateTransition whether or not to animate this zoom transition
* /
simulated function ZoomIn ( bool bAnimateTransition , float ZoomTimeToGo )
{
super . ZoomIn ( bAnimateTransition , ZoomTimeToGo ) ;
if ( SceneCapture != none && Instigator != none && ! Instigator . PlayerReplicationInfo . bBot )
{
SceneCapture . bEnabled = true ;
SceneCapture . SetFrameRate ( SceneCapture . default . FrameRate ) ;
}
ClearTimer ( nameof ( ZoomOutFastFinished ) ) ;
}
/ * *
* Handles all the functionality for zooming out including
* setting the parameters for the weapon , pawn , and playercontroller
*
* @ param bAnimateTransition whether or not to animate this zoom transition
* /
simulated function ZoomOut ( bool bAnimateTransition , float ZoomTimeToGo )
{
super . ZoomOut ( bAnimateTransition , ZoomTimeToGo ) ;
if ( ! bAnimateTransition )
{
SetTimer ( ZoomTimeToGo + 0.01 , false , nameof ( ZoomOutFastFinished ) ) ;
}
else
{
if ( SceneCapture != none && Instigator != none && ! Instigator . PlayerReplicationInfo . bBot )
{
SceneCapture . bEnabled = false ;
SceneCapture . SetFrameRate ( 0.0 ) ;
}
}
}
/ * *
* Handles zoom out cleanup / finish after a "quick" zoom out , which doesn ' t normally do notifies
* /
simulated function ZoomOutFastFinished ( )
{
// Finish blacking out the lense when the fast zoom out finishes
if ( ScopeLenseMIC != none )
{
ScopeLenseMIC . SetScalarParameterValue ( InterpParamName , 0.0 ) ;
}
// Stop updating the scope when the fast zoom out finishes
if ( SceneCapture != none && Instigator != none && ! Instigator . PlayerReplicationInfo . bBot )
{
SceneCapture . bEnabled = false ;
SceneCapture . SetFrameRate ( 0.0 ) ;
}
}
DefaultProperties
{
// 2D scene capture
Begin Object Class = TWSceneCapture2DDPGComponent Name = SceneCapture2DComponent0
NearPlane = 10
FarPlane = 0 // NOTE: Far plane of 0 translates to infinity. Any other value here throws off the projection matrix ever so slightly which causes artifacts when doing position reconstruction during deferred lighting
FieldOfView = 6.0 // "4X" (approximate, since you have to eyeball it with 3d scopes)
bEnabled = false
ViewMode = SceneCapView _Lit
FrameRate = 60
bEnableFog = true
bUpdateMatrices = false
bRenderWorldDPG = true
bRenderForegroundDPG = false
End Object
SceneCapture = SceneCapture2DComponent0
Components . Add ( SceneCapture2DComponent0 )
ScopedSensitivityMod = 6.0
InterpParamName = mat _blend _scaler
ScopeTextureScale = 0.5
//currently the materials don't go above 1024
MaxSceneCaptureSize = 1024
// BASH_FIREMODE
InstantHitDamage ( BASH _FIREMODE ) = 15.0
// Aim Assist
AimCorrectionSize = 40. f
2021-06-02 20:06:18 +00:00
ScopeMICIndex = 2
2020-12-13 15:01:13 +00:00
}