2020-12-13 15:01:13 +00:00
|
|
|
//=============================================================================
|
|
|
|
// KFWeap_Rifle_RailGun
|
|
|
|
//=============================================================================
|
|
|
|
// A Horzine technology Rail Gun
|
|
|
|
//=============================================================================
|
|
|
|
// Killing Floor 2
|
|
|
|
// Copyright (C) 2016 Tripwire Interactive LLC
|
|
|
|
// John "Ramm-Jaeger" Gibson
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
class KFWeap_Rifle_RailGun extends KFWeap_ScopedBase;
|
|
|
|
|
|
|
|
var ScriptedTexture CanvasTexture;
|
|
|
|
|
|
|
|
/** 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 CurrentCanvasTextureSize;
|
|
|
|
|
|
|
|
/** Icon textures for lock on drawing */
|
|
|
|
var Texture2D LockedHitZoneIcon;
|
|
|
|
var Texture2D DefaultHitZoneIcon;
|
|
|
|
var LinearColor RedIconColor;
|
|
|
|
var LinearColor YellowIconColor;
|
|
|
|
var LinearColor BlueIconColor;
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* @name Weapon lock on support
|
|
|
|
**********************************************************************************************/
|
|
|
|
|
|
|
|
/** angle of the maximum FOV extents of the scope for rending things onto the scope canvas */
|
|
|
|
var float MaxScopeScreenDot;
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* @name Ambient sound
|
|
|
|
********************************************************************************************* */
|
|
|
|
/** Pilot light sound play event */
|
|
|
|
var AkEvent AmbientSoundPlayEvent;
|
|
|
|
|
|
|
|
/** Pilot light sound stop event */
|
|
|
|
var AkEvent AmbientSoundStopEvent;
|
|
|
|
|
|
|
|
/** Socket to attach the ambient sound to. */
|
|
|
|
var() name AmbientSoundSocketName;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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( CurrentCanvasTextureSize != NewScopeTextureSize )
|
|
|
|
{
|
|
|
|
CanvasTexture = ScriptedTexture(class'ScriptedTexture'.static.Create(NewScopeTextureSize, NewScopeTextureSize, PF_FloatRGB, MakeLinearColor(0,0,0,0)));
|
|
|
|
|
|
|
|
CanvasTexture.Render = OnRender;
|
|
|
|
CanvasTexture.bNeedsTwoCopies = true;
|
|
|
|
|
|
|
|
if( ScopeLenseMIC != none )
|
|
|
|
{
|
|
|
|
ScopeLenseMIC.SetTextureParameterValue('ScopeText', CanvasTexture);
|
|
|
|
}
|
|
|
|
CurrentCanvasTextureSize = NewScopeTextureSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function AltFireMode ()
|
|
|
|
{
|
|
|
|
super.AltFireMode();
|
|
|
|
TargetingComp.AdjustLockTarget(ETargetingMode_Zed, none);
|
|
|
|
TargetingComp.AdjustLockTarget(ETargetingMode_Player, none);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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() )
|
|
|
|
{
|
|
|
|
if( ScopeLenseMIC != none )
|
|
|
|
{
|
|
|
|
ScopeLenseMIC.SetTextureParameterValue('ScopeText', CanvasTexture);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function StartFire(byte FireModeNum)
|
|
|
|
{
|
|
|
|
// Attempt auto-reload
|
|
|
|
if ( FireModeNum == ALTFIRE_FIREMODE )
|
|
|
|
{
|
|
|
|
`log("Nope, use the default you dirty cheater :)");
|
|
|
|
FiremodeNum = DEFAULT_FIREMODE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Super.StartFire(FireModeNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Return true if this weapon should play the fire last animation for this shoot animation */
|
|
|
|
simulated function bool ShouldPlayFireLast(byte FireModeNum)
|
|
|
|
{
|
|
|
|
// if( SpareAmmoCount[GetAmmoType(FireModeNum)] == 0 )
|
|
|
|
// {
|
|
|
|
// return true;
|
|
|
|
// }
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Returns animation to play based on reload type and status */
|
|
|
|
simulated function name GetReloadAnimName( bool bTacticalReload )
|
|
|
|
{
|
|
|
|
if ( AmmoCount[0] > 0 )
|
|
|
|
{
|
|
|
|
// Disable half-reloads for now. This can happen if server gets out
|
|
|
|
// of sync, but choosing the wrong animation will just make it worse!
|
|
|
|
`warn("Railgun reloading with non-empty mag");
|
|
|
|
}
|
|
|
|
|
|
|
|
return bTacticalReload ? ReloadEmptyMagEliteAnim : ReloadEmptyMagAnim;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* @name Ambient sound
|
|
|
|
**********************************************************************************************/
|
|
|
|
/**
|
|
|
|
* Starts playing looping ambient sound
|
|
|
|
*/
|
|
|
|
simulated function StartAmbientSound()
|
|
|
|
{
|
|
|
|
if( Instigator != none && Instigator.IsLocallyControlled() && Instigator.IsFirstPerson() )
|
|
|
|
{
|
|
|
|
PostAkEventOnBone(AmbientSoundPlayEvent, AmbientSoundSocketName, false, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stops playing looping ambient sound
|
|
|
|
*/
|
|
|
|
simulated function StopAmbientSound()
|
|
|
|
{
|
|
|
|
PostAkEventOnBone(AmbientSoundStopEvent, AmbientSoundSocketName, false, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Detach weapon from skeletal mesh
|
|
|
|
*
|
|
|
|
* @param SkeletalMeshComponent weapon is attached to.
|
|
|
|
*/
|
|
|
|
simulated function DetachWeapon()
|
|
|
|
{
|
|
|
|
StopAmbientSound();
|
|
|
|
Super.DetachWeapon();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* @name Weapon lock on and targeting
|
|
|
|
**********************************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tick the weapon (used for simple updates)
|
|
|
|
*
|
|
|
|
* @param DeltaTime Elapsed time.
|
|
|
|
*/
|
|
|
|
simulated event Tick(float DeltaTime)
|
|
|
|
{
|
|
|
|
super.Tick(DeltaTime);
|
|
|
|
|
|
|
|
if (Instigator != none && Instigator.Controller != none && Instigator.IsLocallyControlled())
|
|
|
|
{
|
|
|
|
CanvasTexture.bNeedsUpdate = bUsingSights && TargetingComp.bTargetingUpdated;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Event called when weapon actor is destroyed */
|
|
|
|
simulated event Destroyed()
|
|
|
|
{
|
|
|
|
if( CanvasTexture != none )
|
|
|
|
{
|
|
|
|
CanvasTexture = none;
|
|
|
|
}
|
|
|
|
|
|
|
|
StopAmbientSound();
|
|
|
|
|
|
|
|
super.Destroyed();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Performs an 'Instant Hit' shot.
|
|
|
|
* Network: Local Player and Server
|
|
|
|
* Overriden to support the aim targeting of the railgun
|
|
|
|
*/
|
|
|
|
simulated function InstantFireClient()
|
|
|
|
{
|
|
|
|
local vector StartTrace, EndTrace;
|
|
|
|
local rotator AimRot;
|
|
|
|
local Array<ImpactInfo> ImpactList;
|
|
|
|
local int Idx;
|
|
|
|
local ImpactInfo RealImpact;
|
|
|
|
local float CurPenetrationValue;
|
|
|
|
local vector AimLocation;
|
|
|
|
|
|
|
|
// see Controller AimHelpDot() / AimingHelp()
|
|
|
|
bInstantHit = true;
|
|
|
|
|
|
|
|
// define range to use for CalcWeaponFire()
|
|
|
|
AimLocation = GetInstantFireAimLocation();
|
|
|
|
StartTrace = GetSafeStartTraceLocation();
|
|
|
|
if (!IsZero(AimLocation))
|
|
|
|
{
|
|
|
|
AimRot = rotator(Normal(AimLocation - StartTrace));
|
|
|
|
EndTrace = StartTrace + vector(AimRot) * GetTraceRange();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AimRot = GetAdjustedAim(StartTrace);
|
|
|
|
EndTrace = StartTrace + vector(AimRot) * GetTraceRange();
|
|
|
|
}
|
|
|
|
|
|
|
|
bInstantHit = false;
|
|
|
|
|
|
|
|
// Initialize penetration power
|
|
|
|
PenetrationPowerRemaining = GetInitialPenetrationPower(CurrentFireMode);
|
|
|
|
CurPenetrationValue = PenetrationPowerRemaining;
|
|
|
|
|
|
|
|
// Perform shot
|
|
|
|
RealImpact = CalcWeaponFire(StartTrace, EndTrace, ImpactList);
|
|
|
|
|
|
|
|
// Set flash location to trigger client side effects. Bypass Weapon.SetFlashLocation since
|
|
|
|
// that function is not marked as simulated and we want instant client feedback.
|
|
|
|
// ProjectileFire/IncrementFlashCount has the right idea:
|
|
|
|
// 1) Call IncrementFlashCount on Server & Local
|
|
|
|
// 2) Replicate FlashCount if ( !bNetOwner )
|
|
|
|
// 3) Call WeaponFired() once on local player
|
|
|
|
if( Instigator != None )
|
|
|
|
{
|
|
|
|
// If we have penetration, set the hitlocation to the last thing we hit
|
|
|
|
if( ImpactList.Length > 0 )
|
|
|
|
{
|
|
|
|
Instigator.SetFlashLocation( Self, CurrentFireMode, ImpactList[ImpactList.Length - 1].HitLocation );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Instigator.SetFlashLocation( Self, CurrentFireMode, RealImpact.HitLocation );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// local player only for clientside hit detection
|
|
|
|
if ( Instigator != None && Instigator.IsLocallyControlled() )
|
|
|
|
{
|
|
|
|
// allow weapon to add extra bullet impacts (useful for shotguns)
|
|
|
|
InstantFireClient_AddImpacts(StartTrace, AimRot, ImpactList);
|
|
|
|
|
|
|
|
for (Idx = 0; Idx < ImpactList.Length; Idx++)
|
|
|
|
{
|
|
|
|
ProcessInstantHitEx(CurrentFireMode, ImpactList[Idx],, CurPenetrationValue, Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( Instigator.Role < ROLE_Authority )
|
|
|
|
{
|
|
|
|
SendClientImpactList(CurrentFireMode, ImpactList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function vector GetInstantFireAimLocation()
|
|
|
|
{
|
|
|
|
return TargetingComp.LockedAimLocation[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* @name Targeting HUD
|
|
|
|
**********************************************************************************************/
|
|
|
|
|
|
|
|
/** Handle drawing items on the scope ScriptedTexture */
|
|
|
|
simulated function OnRender(Canvas C)
|
|
|
|
{
|
|
|
|
local int i;
|
|
|
|
|
|
|
|
if( !bUsingSights )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw the targeting locations on the scope
|
|
|
|
for (i = 0; i < TargetingComp.TargetVulnerableLocations_Zed.Length; i++)
|
|
|
|
{
|
|
|
|
if( !IsZero(TargetingComp.TargetVulnerableLocations_Zed[i]) )
|
|
|
|
{
|
|
|
|
DrawTargetingIcon( C, i );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CanvasTexture.bNeedsUpdate = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Draws an icon when human players are hidden but in the field of view
|
|
|
|
*
|
|
|
|
* @param PRI Player's PlayerReplicationInfo
|
|
|
|
* @param IconWorldLocation The "player's" location in the world
|
|
|
|
*/
|
|
|
|
simulated function DrawTargetingIcon( Canvas Canvas, int index )
|
|
|
|
{
|
|
|
|
local vector WorldPos;
|
|
|
|
local float IconSize, IconScale;
|
|
|
|
local vector2d ScreenPos;
|
|
|
|
|
|
|
|
// Project world pos to canvas
|
|
|
|
WorldPos = TargetingComp.TargetVulnerableLocations_Zed[index];
|
|
|
|
ScreenPos = WorldToCanvas(Canvas, WorldPos);
|
|
|
|
|
|
|
|
// calculate scale based on resolution and distance
|
|
|
|
IconScale = FMin(float(Canvas.SizeX) / 1024.f, 1.f);
|
|
|
|
// Scale down up to 40 meters away, with a clamp at 20% size
|
|
|
|
IconScale *= FClamp(1.f - VSize(WorldPos - Instigator.Location) / 4000.f, 0.2f, 1.f);
|
|
|
|
|
|
|
|
// Apply size scale
|
|
|
|
IconSize = 300.f * IconScale;
|
|
|
|
ScreenPos.X -= IconSize / 2.f;
|
|
|
|
ScreenPos.Y -= IconSize / 2.f;
|
|
|
|
|
|
|
|
// Off-screen check
|
|
|
|
if( ScreenPos.X < 0 || ScreenPos.X > Canvas.SizeX || ScreenPos.Y < 0 || ScreenPos.Y > Canvas.SizeY )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Canvas.SetPos( ScreenPos.X, ScreenPos.Y );
|
|
|
|
|
|
|
|
// Pick the color of the targeting box to draw
|
|
|
|
if( TargetingComp.LockedHitZone[0] >= 0 && index == TargetingComp.LockedHitZone[0] )
|
|
|
|
{
|
|
|
|
Canvas.DrawTile( LockedHitZoneIcon, IconSize, IconSize, 0, 0, LockedHitZoneIcon.SizeX, LockedHitZoneIcon.SizeY, RedIconColor);
|
|
|
|
}
|
|
|
|
else if( TargetingComp.PendingHitZone[0] >= 0 && index == TargetingComp.PendingHitZone[0] )
|
|
|
|
{
|
|
|
|
Canvas.DrawTile( LockedHitZoneIcon, IconSize, IconSize, 0, 0, LockedHitZoneIcon.SizeX, LockedHitZoneIcon.SizeY, YellowIconColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Canvas.DrawTile( DefaultHitZoneIcon, IconSize, IconSize, 0, 0, DefaultHitZoneIcon.SizeX, DefaultHitZoneIcon.SizeY, BlueIconColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Canvas.Project() doesn't work because our Canvas doesn't have a FSceneView, so
|
|
|
|
* we have to get the transforms out of the scene capture actor... or in this
|
|
|
|
* case we can make it work with angles
|
|
|
|
*/
|
|
|
|
simulated function vector2d WorldToCanvas( Canvas Canvas, vector WorldPoint)
|
|
|
|
{
|
|
|
|
local vector ViewLoc, ViewDir;
|
|
|
|
local rotator ViewRot;
|
|
|
|
local vector X,Y,Z;
|
|
|
|
local vector2d ScreenPoint;
|
|
|
|
local float DotToZedUpDown, DotToZedLeftRight, UpDownScale, LeftRightScale;
|
|
|
|
|
|
|
|
Instigator.Controller.GetPlayerViewPoint(ViewLoc, ViewRot);
|
|
|
|
GetAxes(ViewRot, X, Y, Z);
|
|
|
|
ViewDir = Normal(WorldPoint - ViewLoc);
|
|
|
|
|
|
|
|
DotToZedUpDown = Z dot ViewDir;
|
|
|
|
DotToZedLeftRight = Y dot ViewDir;
|
|
|
|
|
|
|
|
UpDownScale = DotToZedUpDown/MaxScopeScreenDot;
|
|
|
|
LeftRightScale = DotToZedLeftRight/MaxScopeScreenDot;
|
|
|
|
|
|
|
|
ScreenPoint.X = CanvasTexture.SizeX * (0.5 + LeftRightScale * 0.5);
|
|
|
|
ScreenPoint.Y = CanvasTexture.SizeY * (0.5 - UpDownScale * 0.5);
|
|
|
|
|
|
|
|
return ScreenPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
{
|
|
|
|
local vector V;
|
|
|
|
|
|
|
|
// transform by viewProjectionMatrix
|
|
|
|
V = TransformVector(SceneCapture.ViewMatrix * SceneCapture.ProjMatrix, WorldPoint);
|
|
|
|
|
|
|
|
// apply clip "matrix"
|
|
|
|
V.X = (Canvas.ClipX/2.f) + (V.X*(Canvas.ClipX/2.f));
|
|
|
|
V.Y *= -1.f;
|
|
|
|
V.Y = (Canvas.ClipY/2.f) + (V.Y*(Canvas.ClipY/2.f));
|
|
|
|
|
|
|
|
return V;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* state Inactive
|
|
|
|
* This state is the default state. It needs to make sure Zooming is reset when entering/leaving
|
|
|
|
*********************************************************************************************/
|
|
|
|
|
|
|
|
auto simulated state Inactive
|
|
|
|
{
|
|
|
|
simulated function BeginState(name PreviousStateName)
|
|
|
|
{
|
|
|
|
Super.BeginState(PreviousStateName);
|
|
|
|
StopAmbientSound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* State WeaponEquipping
|
|
|
|
* The Weapon is in this state while transitioning from Inactive to Active state.
|
|
|
|
* Typically, the weapon will remain in this state while its selection animation is being played.
|
|
|
|
* While in this state, the weapon cannot be fired.
|
|
|
|
*********************************************************************************************/
|
|
|
|
|
|
|
|
simulated state WeaponEquipping
|
|
|
|
{
|
|
|
|
simulated function BeginState(Name PreviousStateName)
|
|
|
|
{
|
|
|
|
super.BeginState(PreviousStateName);
|
|
|
|
StartAmbientSound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* State WeaponPuttingDown
|
|
|
|
* Putting down weapon in favor of a new one.
|
|
|
|
* Weapon is transitioning to the Inactive state.
|
|
|
|
*********************************************************************************************/
|
|
|
|
|
|
|
|
simulated state WeaponPuttingDown
|
|
|
|
{
|
|
|
|
simulated event BeginState(Name PreviousStateName)
|
|
|
|
{
|
|
|
|
super.BeginState(PreviousStateName);
|
|
|
|
StopAmbientSound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* State WeaponAbortEquip
|
|
|
|
* Special PuttingDown state used when WeaponEquipping is interrupted. Must come after
|
|
|
|
* WeaponPuttingDown definition or this willextend the super version.
|
|
|
|
*********************************************************************************************/
|
|
|
|
|
|
|
|
simulated state WeaponAbortEquip
|
|
|
|
{
|
|
|
|
simulated event BeginState(Name PreviousStateName)
|
|
|
|
{
|
|
|
|
super.BeginState(PreviousStateName);
|
|
|
|
StopAmbientSound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
defaultproperties
|
|
|
|
{
|
|
|
|
// Inventory / Grouping
|
|
|
|
InventorySize=9 //10
|
|
|
|
GroupPriority=100
|
|
|
|
WeaponSelectTexture=Texture2D'WEP_UI_RailGun_TEX.UI_WeaponSelect_Railgun'
|
|
|
|
AssociatedPerkClasses(0)=class'KFPerk_Sharpshooter'
|
|
|
|
|
|
|
|
// 2D scene capture
|
|
|
|
Begin Object Name=SceneCapture2DComponent0
|
|
|
|
//TextureTarget=TextureRenderTarget2D'Wep_Mat_Lib.WEP_ScopeLense_Target'
|
|
|
|
FieldOfView=23.0 // "1.5X" = 35.0(our real world FOV determinant)/1.5
|
|
|
|
End Object
|
|
|
|
|
|
|
|
ScopedSensitivityMod=16.0
|
|
|
|
|
|
|
|
ScopeLenseMICTemplate=MaterialInstanceConstant'WEP_1P_RailGun_MAT.Wep_1stP_RailGun_Lens_MIC'
|
|
|
|
|
|
|
|
// FOV
|
|
|
|
MeshIronSightFOV=27
|
|
|
|
PlayerIronSightFOV=70
|
|
|
|
|
|
|
|
// Depth of field
|
|
|
|
DOF_BlendInSpeed=3.0
|
|
|
|
DOF_FG_FocalRadius=0//70
|
|
|
|
DOF_FG_MaxNearBlurSize=3.5
|
|
|
|
|
|
|
|
// Content
|
|
|
|
PackageKey="RailGun"
|
|
|
|
FirstPersonMeshName="WEP_1P_RailGun_MESH.WEP_1stP_RailGun_Rig"
|
|
|
|
FirstPersonAnimSetNames(0)="WEP_1P_RailGun_ANIM.WEP_1P_RailGun_ANIM"
|
|
|
|
PickupMeshName="wep_3p_railgun_mesh.Wep_3rdP_RailGun_Pickup"
|
|
|
|
AttachmentArchetypeName="WEP_RailGun_ARCH.Wep_RailGun_3P_Updated"
|
|
|
|
MuzzleFlashTemplateName="WEP_RailGun_ARCH.Wep_RailGun_MuzzleFlash"
|
|
|
|
|
|
|
|
// Ammo
|
|
|
|
MagazineCapacity[0]=1
|
|
|
|
SpareAmmoCapacity[0]=32 //20
|
|
|
|
InitialSpareMags[0]=6
|
|
|
|
bCanBeReloaded=true
|
|
|
|
bReloadFromMagazine=true
|
|
|
|
AmmoPickupScale[0]=3.0
|
|
|
|
|
|
|
|
// Zooming/Position
|
|
|
|
PlayerViewOffset=(X=3.0,Y=7,Z=-2)
|
2022-09-01 15:58:51 +00:00
|
|
|
IronSightPosition=(X=-0.25,Y=0.005,Z=-0.005) // any further back along X and the scope clips through the camera during firing
|
2020-12-13 15:01:13 +00:00
|
|
|
|
|
|
|
// AI warning system
|
|
|
|
bWarnAIWhenAiming=true
|
|
|
|
AimWarningDelay=(X=0.4f, Y=0.8f)
|
|
|
|
AimWarningCooldown=0.0f
|
|
|
|
|
|
|
|
// Recoil
|
|
|
|
maxRecoilPitch=600
|
|
|
|
minRecoilPitch=450
|
|
|
|
maxRecoilYaw=250
|
|
|
|
minRecoilYaw=-250
|
|
|
|
RecoilRate=0.09
|
|
|
|
RecoilBlendOutRatio=1.1
|
|
|
|
RecoilMaxYawLimit=500
|
|
|
|
RecoilMinYawLimit=65035
|
|
|
|
RecoilMaxPitchLimit=1500
|
|
|
|
RecoilMinPitchLimit=64785
|
|
|
|
RecoilISMaxYawLimit=50
|
|
|
|
RecoilISMinYawLimit=65485
|
|
|
|
RecoilISMaxPitchLimit=500
|
|
|
|
RecoilISMinPitchLimit=65485
|
|
|
|
RecoilViewRotationScale=0.6
|
|
|
|
FallingRecoilModifier=1.5
|
|
|
|
HippedRecoilModifier=2.33333
|
|
|
|
|
|
|
|
// DEFAULT_FIREMODE
|
|
|
|
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'UI_SecondaryAmmo_TEX.UI_FireModeSelect_AutoTarget'
|
|
|
|
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
|
|
|
|
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
|
|
|
|
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_RailGun'
|
|
|
|
InstantHitDamage(DEFAULT_FIREMODE)=280 //375
|
|
|
|
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_RailGun'
|
|
|
|
FireInterval(DEFAULT_FIREMODE)=0.1 //0.4
|
|
|
|
PenetrationPower(DEFAULT_FIREMODE)=10.0
|
|
|
|
Spread(DEFAULT_FIREMODE)=0.005
|
|
|
|
FireOffset=(X=30,Y=3.0,Z=-2.5)
|
|
|
|
ForceReloadTimeOnEmpty=0.5
|
|
|
|
|
|
|
|
IronSightsSpreadMod=0.01
|
|
|
|
|
|
|
|
// ALT_FIREMODE
|
|
|
|
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'UI_SecondaryAmmo_TEX.UI_FireModeSelect_ManualTarget'
|
|
|
|
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
|
|
|
|
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_InstantHit
|
|
|
|
WeaponProjectiles(ALTFIRE_FIREMODE)=none
|
|
|
|
InstantHitDamage(ALTFIRE_FIREMODE)=560 //750
|
|
|
|
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_RailGun'
|
|
|
|
FireInterval(ALTFIRE_FIREMODE)=0.1 //0.4
|
|
|
|
PenetrationPower(ALTFIRE_FIREMODE)=10.0
|
|
|
|
Spread(ALTFIRE_FIREMODE)=0.005
|
|
|
|
|
|
|
|
|
|
|
|
// BASH_FIREMODE
|
|
|
|
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_RailGun'
|
|
|
|
InstantHitDamage(BASH_FIREMODE)=30
|
|
|
|
|
|
|
|
// Fire Effects
|
|
|
|
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_SA_Railgun.Play_WEP_SA_Railgun_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_SA_Railgun.Play_WEP_SA_Railgun_Fire_1P')
|
|
|
|
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_Railgun.Play_WEP_SA_Railgun_DryFire'
|
|
|
|
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_SA_Railgun.Play_WEP_SA_Railgun_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_SA_Railgun.Play_WEP_SA_Railgun_Fire_1P')
|
|
|
|
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_Railgun.Play_WEP_SA_Railgun_DryFire'
|
|
|
|
|
|
|
|
// Attachments
|
|
|
|
bHasIronSights=true
|
|
|
|
bHasFlashlight=false
|
|
|
|
|
|
|
|
// Custom animations
|
|
|
|
FireSightedAnims=(Shoot_Iron, Shoot_Iron2, Shoot_Iron3)
|
|
|
|
BonesToLockOnEmpty=(RW_TopLeft_RadShield1,RW_TopRight_RadShield1,RW_TopLeft_RadShield2,RW_TopRight_RadShield2,RW_TopLeft_RadShield3,RW_TopRight_RadShield3,RW_TopLeft_RadShield4,RW_TopRight_RadShield4,RW_TopLeft_RadShield5,RW_TopRight_RadShield5,RW_TopLeft_RadShield6,RW_TopRight_RadShield6,RW_BottomLeft_RadShield2,RW_BottomRight_RadShield2,RW_BottomLeft_RadShield3,RW_BottomRight_RadShield3,RW_BottomLeft_RadShield4,RW_BottomRight_RadShield4,RW_BottomLeft_RadShield5,RW_BottomRight_RadShield5,RW_BottomLeft_RadShield6,RW_BottomRight_RadShield6,RW_BottomLeft_RadShield1,RW_BottomRight_RadShield1,RW_Bullets1,RW_AcceleratorMagnetrons,RW_Bolt)
|
|
|
|
|
|
|
|
MaxScopeScreenDot=0.2
|
|
|
|
|
|
|
|
//Ambient Sounds
|
|
|
|
AmbientSoundPlayEvent=AkEvent'WW_WEP_SA_Railgun.Play_Railgun_Loop'
|
|
|
|
AmbientSoundStopEvent=AkEvent'WW_WEP_SA_Railgun.Stop_Railgun_Loop'
|
|
|
|
AmbientSoundSocketName=AmbientSound
|
|
|
|
|
|
|
|
// Lock on
|
|
|
|
TargetingCompClass=class'KFTargetingWeaponComponent_RailGun'
|
|
|
|
LockedHitZoneIcon=Texture2D'Wep_Scope_TEX.Wep_1stP_Yellow_Red_Target'
|
|
|
|
DefaultHitZoneIcon=Texture2D'Wep_Scope_TEX.Wep_1stP_Blue_Target'
|
|
|
|
RedIconColor=(R=1.f, G=0.f, B=0.f)
|
|
|
|
YellowIconColor=(R=1.f, G=1.f, B=0.f)
|
|
|
|
BlueIconColor=(R=0.25, G=0.6f, B=1.f)
|
|
|
|
|
|
|
|
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Heavy_Recoil_SingleShot'
|
|
|
|
|
|
|
|
// Weapon Upgrade stat boosts
|
|
|
|
//WeaponUpgrades[1]=(IncrementDamage=1.25f,IncrementWeight=1)
|
|
|
|
|
|
|
|
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.25f), (Stat=EWUS_Damage1, Scale=1.25f), (Stat=EWUS_Weight, Add=1)))
|
|
|
|
}
|