242 lines
8.2 KiB
Ucode
242 lines
8.2 KiB
Ucode
//=============================================================================
|
|
// SPShotgunAltFire
|
|
//=============================================================================
|
|
// Steampunk Shotgun Alt fire class.
|
|
//=============================================================================
|
|
// Killing Floor Source
|
|
// Copyright (C) 2013 Tripwire Interactive LLC
|
|
// - John "Ramm-Jaeger" Gibson
|
|
//=============================================================================
|
|
class SPShotgunAltFire extends KFShotgunFire;
|
|
|
|
var() InterpCurve AppliedMomentumCurve; // How much momentum to apply to a zed based on how much mass it has
|
|
var float WideDamageMinHitAngle; // The angle to do sweeping strikes in front of the player. If zero do no strikes
|
|
var float PushRange; // The range to push zeds away when firing
|
|
|
|
simulated function bool AllowFire()
|
|
{
|
|
if(KFWeapon(Weapon).bIsReloading)
|
|
return false;
|
|
if(KFPawn(Instigator).SecondaryItem!=none)
|
|
return false;
|
|
if(KFPawn(Instigator).bThrowingNade)
|
|
return false;
|
|
|
|
// No ammo so just always fire
|
|
return true;
|
|
}
|
|
|
|
function DoFireEffect()
|
|
{
|
|
local Vector StartProj, StartTrace, X,Y,Z;
|
|
local Rotator Aim;
|
|
local Vector HitLocation, HitNormal;
|
|
local Actor Other;
|
|
local Pawn Victims;
|
|
local vector dir, lookdir;
|
|
local float DiffAngle, VictimDist;
|
|
local float AppliedMomentum;
|
|
local vector Momentum;
|
|
|
|
Instigator.MakeNoise(1.0);
|
|
Weapon.GetViewAxes(X,Y,Z);
|
|
|
|
StartTrace = Instigator.Location + Instigator.EyePosition();// + X*Instigator.CollisionRadius;
|
|
StartProj = StartTrace + X*ProjSpawnOffset.X;
|
|
if ( !Weapon.WeaponCentered() && !KFWeap.bAimingRifle )
|
|
StartProj = StartProj + Weapon.Hand * Y*ProjSpawnOffset.Y + Z*ProjSpawnOffset.Z;
|
|
|
|
// check if projectile would spawn through a wall and adjust start location accordingly
|
|
Other = Weapon.Trace(HitLocation, HitNormal, StartProj, StartTrace, false);
|
|
|
|
if (Other != None)
|
|
{
|
|
StartProj = HitLocation;
|
|
}
|
|
|
|
Aim = AdjustAim(StartProj, AimError);
|
|
|
|
if( WideDamageMinHitAngle > 0 )
|
|
{
|
|
foreach Weapon.VisibleCollidingActors( class 'Pawn', Victims, (PushRange * 2), StartTrace )
|
|
{
|
|
if( Victims.Health <= 0 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if( Victims != Instigator )
|
|
{
|
|
// Don't push team mates or scripted characters (like the Ringmaster)
|
|
if( Victims.GetTeamNum() == Instigator.GetTeamNum()
|
|
|| Victims.IsA('KF_StoryNPC') )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
VictimDist = VSizeSquared(Instigator.Location - Victims.Location);
|
|
|
|
//log("VictimDist = "$VictimDist$" PushRange = "$(PushRange*PushRange));
|
|
|
|
if( VictimDist > (((PushRange * 1.1) * (PushRange * 1.1)) + (Victims.CollisionRadius * Victims.CollisionRadius)) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
lookdir = Normal(Vector(Instigator.GetViewRotation()));
|
|
dir = Normal(Victims.Location - Instigator.Location);
|
|
|
|
DiffAngle = lookdir dot dir;
|
|
|
|
dir = Normal((Victims.Location + Victims.EyePosition()) - Instigator.Location);
|
|
|
|
if( DiffAngle > WideDamageMinHitAngle )
|
|
{
|
|
AppliedMomentum = InterpCurveEval(AppliedMomentumCurve,Victims.Mass);
|
|
|
|
HandleAchievement( Victims );
|
|
|
|
//log("Shot would hit "$Victims$" DiffAngle = "$DiffAngle);
|
|
Momentum = (dir * AppliedMomentum)/Victims.Mass;
|
|
Victims.AddVelocity( Momentum );
|
|
if( KFMonster(Victims) != none )
|
|
{
|
|
KFMonster(Victims).BreakGrapple();
|
|
}
|
|
}
|
|
// else
|
|
// {
|
|
// log("Shot would miss "$Victims$" DiffAngle = "$DiffAngle);
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Instigator != none )
|
|
{
|
|
// Really boost the momentum for low grav. Weapon only gets momentum on low grav
|
|
if( Instigator.Physics == PHYS_Falling
|
|
&& Instigator.PhysicsVolume.Gravity.Z > class'PhysicsVolume'.default.Gravity.Z)
|
|
{
|
|
Instigator.AddVelocity((KickMomentum * 10.0) >> Instigator.GetViewRotation());
|
|
}
|
|
}
|
|
}
|
|
|
|
function HandleAchievement( Pawn Victim )
|
|
{
|
|
local KFSteamStatsAndAchievements KFSteamStats;
|
|
|
|
if ( Victim.IsA( 'ZombieScrake' ) )
|
|
{
|
|
if (PlayerController( Instigator.Controller ) != none )
|
|
{
|
|
KFSteamStats = KFSteamStatsAndAchievements(PlayerController(Instigator.Controller).SteamStatsAndAchievements);
|
|
if ( KFSteamStats != none )
|
|
{
|
|
KFSteamStats.CheckAndSetAchievementComplete( KFSteamStats.KFACHIEVEMENT_PushScrakeSPJ );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Handle setting new recoil
|
|
simulated function HandleRecoil(float Rec)
|
|
{
|
|
local rotator NewRecoilRotation;
|
|
local KFPlayerController KFPC;
|
|
local KFPawn KFPwn;
|
|
local vector AdjustedVelocity;
|
|
local float AdjustedSpeed;
|
|
|
|
if( Instigator != none )
|
|
{
|
|
KFPC = KFPlayerController(Instigator.Controller);
|
|
KFPwn = KFPawn(Instigator);
|
|
}
|
|
|
|
if( KFPC == none || KFPwn == none )
|
|
return;
|
|
|
|
if( !KFPC.bFreeCamera )
|
|
{
|
|
if( Weapon.GetFireMode(1).bIsFiring )
|
|
{
|
|
NewRecoilRotation.Pitch = RandRange( maxVerticalRecoilAngle * 0.5, maxVerticalRecoilAngle );
|
|
NewRecoilRotation.Yaw = RandRange( maxHorizontalRecoilAngle * 0.5, maxHorizontalRecoilAngle );
|
|
|
|
if( Rand( 2 ) == 1 )
|
|
NewRecoilRotation.Yaw *= -1;
|
|
|
|
if( Weapon.Owner != none && Weapon.Owner.Physics == PHYS_Falling &&
|
|
Weapon.Owner.PhysicsVolume.Gravity.Z > class'PhysicsVolume'.default.Gravity.Z )
|
|
{
|
|
AdjustedVelocity = Weapon.Owner.Velocity;
|
|
// Ignore Z velocity in low grav so we don't get massive recoil
|
|
AdjustedVelocity.Z = 0;
|
|
AdjustedSpeed = VSize(AdjustedVelocity);
|
|
//log("AdjustedSpeed = "$AdjustedSpeed$" scale = "$(AdjustedSpeed* RecoilVelocityScale * 0.5));
|
|
|
|
// Reduce the falling recoil in low grav
|
|
NewRecoilRotation.Pitch += (AdjustedSpeed* 3 * 0.5);
|
|
NewRecoilRotation.Yaw += (AdjustedSpeed* 3 * 0.5);
|
|
}
|
|
else
|
|
{
|
|
//log("Velocity = "$VSize(Weapon.Owner.Velocity)$" scale = "$(VSize(Weapon.Owner.Velocity)* RecoilVelocityScale));
|
|
NewRecoilRotation.Pitch += (VSize(Weapon.Owner.Velocity)* 3);
|
|
NewRecoilRotation.Yaw += (VSize(Weapon.Owner.Velocity)* 3);
|
|
}
|
|
|
|
NewRecoilRotation.Pitch += (Instigator.HealthMax / Instigator.Health * 5);
|
|
NewRecoilRotation.Yaw += (Instigator.HealthMax / Instigator.Health * 5);
|
|
NewRecoilRotation *= Rec;
|
|
|
|
KFPC.SetRecoil(NewRecoilRotation,RecoilRate * (default.FireRate/FireRate));
|
|
}
|
|
}
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
KickMomentum=(X=-35.000000,Z=5.000000)
|
|
ProjPerFire=0//7
|
|
bAttachSmokeEmitter=True
|
|
TransientSoundVolume=2.0
|
|
TransientSoundRadius=500.000000
|
|
FireSoundRef="KF_SP_ZEDThrowerSnd.KFO_Shotgun_Secondary_Fire_M"
|
|
StereoFireSoundRef="KF_SP_ZEDThrowerSnd.KFO_Shotgun_Secondary_Fire_S"
|
|
NoAmmoSoundRef="KF_AA12Snd.AA12_DryFire"
|
|
FireRate=1.2
|
|
FireAnimRate=1.0
|
|
AmmoClass=none
|
|
ProjectileClass=none
|
|
BotRefireRate=1.750000
|
|
FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSPShotgunAlt'
|
|
aimerror=1.000000
|
|
Spread=0
|
|
maxVerticalRecoilAngle=3200
|
|
maxHorizontalRecoilAngle=900
|
|
FireAimedAnim=Fire_Iron
|
|
bModeExclusive=false
|
|
|
|
//** View shake **//
|
|
ShakeOffsetMag=(X=6.0,Y=2.0,Z=6.0)
|
|
ShakeOffsetRate=(X=1000.0,Y=1000.0,Z=1000.0)
|
|
ShakeOffsetTime=1.25
|
|
ShakeRotMag=(X=50.0,Y=50.0,Z=250.0)
|
|
ShakeRotRate=(X=12500.0,Y=12500.0,Z=12500.0)
|
|
ShakeRotTime=3.0
|
|
bWaitForRelease=false
|
|
bRandomPitchFireSound=false
|
|
|
|
PushRange=150
|
|
WideDamageMinHitAngle=0.6
|
|
AmmoPerFire=0
|
|
|
|
AppliedMomentumCurve=(Points=((InVal=0.0,OutVal=10000.0),(InVal=350.0,OutVal=175000.0),(InVal=600.0,OutVal=250000.0)))
|
|
}
|