//============================================================================= // 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))) }