1
0
KF2-Dev-Scripts/KFGame/Classes/KFWeap_ScopedBase.uc
2020-12-13 18:01:13 +03:00

354 lines
11 KiB
Ucode

//=============================================================================
// 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;
/** Name of the parameter used to blend between scene capture texture (when in ironsights) and
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;
/** Template MIC used by the sniper scope. The MIC actually used by the scope should derive from this.
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;
/** Current length of the square scope texture. This is checked against before modifying the
ScopeTextureSize in the scenario when InitFOV is called multiple times with the same values */
var int CurrentScopeTextureSize;
var(Scope) float ScopedSensitivityMod;
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);
mesh.SetMaterial(2, ScopeLenseMIC);
}
}
/**
* 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 3d 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
}