312 lines
9.4 KiB
Ucode
312 lines
9.4 KiB
Ucode
class ScrnFNFALFire extends FNFALFire;
|
|
|
|
var int BurstSize;
|
|
var transient int BurstShotCount; //how many bullets were fired in the current burst?
|
|
var transient float FireBurstEndTime; //this is just to be sure we don't stuck inside FireBurst state, if shit happens
|
|
|
|
// fixes double shot bug -- PooSH
|
|
state FireLoop
|
|
{
|
|
function BeginState()
|
|
{
|
|
super.BeginState();
|
|
|
|
NextFireTime = Level.TimeSeconds - 0.000001; //fire now!
|
|
}
|
|
}
|
|
|
|
state WaitingForFireButtonRelease
|
|
{
|
|
function PlayFiring() {}
|
|
function ServerPlayFiring() {}
|
|
function PlayFireEnd() {}
|
|
function ModeDoFire() {}
|
|
}
|
|
|
|
state FireBurst
|
|
{
|
|
function BeginState()
|
|
{
|
|
NumShotsInBurst = 0;
|
|
BurstShotCount = 0;
|
|
NextFireTime = Level.TimeSeconds - 0.0001; //fire now!
|
|
FireBurstEndTime = Level.TimeSeconds + ( FireRate * BurstSize ) + 0.1; // if shit happens - get us out of this state when this time hits
|
|
}
|
|
|
|
function EndState()
|
|
{
|
|
PlayFireEnd();
|
|
}
|
|
|
|
function StopFiring()
|
|
{
|
|
GotoState('');
|
|
}
|
|
|
|
function ModeTick(float dt)
|
|
{
|
|
Super.ModeTick(dt);
|
|
|
|
if ( !bIsFiring || !AllowFire() ) // stopped firing, magazine empty
|
|
GotoState('');
|
|
else if ( Level.TimeSeconds > FireBurstEndTime )
|
|
{
|
|
GotoState('');
|
|
log("ScrnM4203BulletFire stuck inside FireBurst state after making "$BurstShotCount$" shots! Getting us out of it.", 'ScrnBalance');
|
|
}
|
|
}
|
|
|
|
// Calculate modifications to spread
|
|
simulated function float GetSpread()
|
|
{
|
|
local float NewSpread;
|
|
local float AccuracyMod;
|
|
|
|
AccuracyMod = 1.0;
|
|
|
|
// Spread bonus for firing aiming
|
|
if( KFWeap.bAimingRifle )
|
|
{
|
|
AccuracyMod *= 0.5;
|
|
}
|
|
|
|
// Small spread bonus for firing crouched
|
|
if( Instigator != none && Instigator.bIsCrouched )
|
|
{
|
|
AccuracyMod *= 0.85;
|
|
}
|
|
|
|
NumShotsInBurst++;
|
|
|
|
// Small spread bonus for firing in semi auto mode
|
|
// make spread bonus for first 2 shots -- PooSH
|
|
if( NumShotsInBurst < 2 || (bAccuracyBonusForSemiAuto && bWaitForRelease) )
|
|
{
|
|
AccuracyMod *= 0.85;
|
|
}
|
|
|
|
|
|
if ( Level.TimeSeconds - LastFireTime > 0.5 ) {
|
|
NewSpread = Default.Spread;
|
|
NumShotsInBurst=0;
|
|
}
|
|
else if (BurstSize <= 2) {
|
|
//2-nd shot doesn't get spread penalty
|
|
NewSpread = Default.Spread;
|
|
}
|
|
else {
|
|
// Decrease accuracy up to MaxSpread by the number of recent shots up to a max of six
|
|
NewSpread = FMin(Default.Spread + (NumShotsInBurst * (MaxSpread/6.0)),MaxSpread);
|
|
}
|
|
|
|
NewSpread *= AccuracyMod;
|
|
|
|
return NewSpread;
|
|
}
|
|
|
|
//copy-pasted from KFFire
|
|
function ModeDoFire()
|
|
{
|
|
local float Rec;
|
|
local KFPlayerReplicationInfo KFPRI;
|
|
|
|
if (!AllowFire())
|
|
return;
|
|
|
|
if( Instigator==None || Instigator.Controller==none )
|
|
return;
|
|
|
|
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
|
|
|
|
Spread = GetSpread();
|
|
|
|
Rec = GetFireSpeed();
|
|
FireRate = default.FireRate/Rec;
|
|
FireAnimRate = default.FireAnimRate*Rec;
|
|
ReloadAnimRate = default.ReloadAnimRate*Rec;
|
|
Rec = 1;
|
|
|
|
if ( KFPRI != none && KFPRI.ClientVeteranSkill != none )
|
|
{
|
|
Spread *= KFPRI.ClientVeteranSkill.Static.ModifyRecoilSpread(KFPRI, self, Rec);
|
|
}
|
|
|
|
LastFireTime = Level.TimeSeconds;
|
|
|
|
if (Weapon.Owner != none && AllowFire() && !bFiringDoesntAffectMovement)
|
|
{
|
|
if (FireRate > 0.25)
|
|
{
|
|
Weapon.Owner.Velocity.x *= 0.1;
|
|
Weapon.Owner.Velocity.y *= 0.1;
|
|
}
|
|
else
|
|
{
|
|
Weapon.Owner.Velocity.x *= 0.5;
|
|
Weapon.Owner.Velocity.y *= 0.5;
|
|
}
|
|
}
|
|
|
|
Super(WeaponFire).ModeDoFire();
|
|
|
|
// client
|
|
if (Instigator.IsLocallyControlled())
|
|
{
|
|
if( bDoClientRagdollShotFX && Weapon.Level.NetMode == NM_Client )
|
|
{
|
|
DoClientOnlyFireEffect();
|
|
}
|
|
//reduce recoil for first 2 bullets
|
|
if (NumShotsInBurst <= 1) {
|
|
maxVerticalRecoilAngle = default.maxVerticalRecoilAngle * 0.1;
|
|
maxHorizontalRecoilAngle = default.maxHorizontalRecoilAngle * 0.1;
|
|
}
|
|
HandleRecoil(Rec);
|
|
//restore defaults
|
|
maxVerticalRecoilAngle = default.maxVerticalRecoilAngle;
|
|
maxHorizontalRecoilAngle = default.maxHorizontalRecoilAngle;
|
|
}
|
|
|
|
if ( ++BurstShotCount >= BurstSize ) {
|
|
GotoState('WaitingForFireButtonRelease');
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//add 1 penetration
|
|
function DoTrace(Vector Start, Rotator Dir)
|
|
{
|
|
local Vector X,Y,Z, End, HitLocation, HitNormal, ArcEnd;
|
|
local Actor Other;
|
|
local byte HitCount,HCounter;
|
|
local float HitDamage;
|
|
local array<int> HitPoints;
|
|
local KFPawn HitPawn;
|
|
local array<Actor> IgnoreActors;
|
|
local Actor DamageActor;
|
|
local int i;
|
|
|
|
MaxRange();
|
|
|
|
Weapon.GetViewAxes(X, Y, Z);
|
|
if ( Weapon.WeaponCentered() )
|
|
{
|
|
ArcEnd = (Instigator.Location + Weapon.EffectOffset.X * X + 1.5 * Weapon.EffectOffset.Z * Z);
|
|
}
|
|
else
|
|
{
|
|
ArcEnd = (Instigator.Location + Instigator.CalcDrawOffset(Weapon) + Weapon.EffectOffset.X * X +
|
|
Weapon.Hand * Weapon.EffectOffset.Y * Y + Weapon.EffectOffset.Z * Z);
|
|
}
|
|
|
|
X = Vector(Dir);
|
|
End = Start + TraceRange * X;
|
|
HitDamage = DamageMax;
|
|
While( (HitCount++)<2 ) // 1 penetration
|
|
{
|
|
DamageActor = none;
|
|
|
|
Other = Instigator.HitPointTrace(HitLocation, HitNormal, End, HitPoints, Start,, 1);
|
|
if( Other==None )
|
|
{
|
|
Break;
|
|
}
|
|
else if( Other==Instigator || Other.Base == Instigator )
|
|
{
|
|
IgnoreActors[IgnoreActors.Length] = Other;
|
|
Other.SetCollision(false);
|
|
Start = HitLocation;
|
|
Continue;
|
|
}
|
|
|
|
if( ExtendedZCollision(Other)!=None && Other.Owner!=None )
|
|
{
|
|
IgnoreActors[IgnoreActors.Length] = Other;
|
|
IgnoreActors[IgnoreActors.Length] = Other.Owner;
|
|
Other.SetCollision(false);
|
|
Other.Owner.SetCollision(false);
|
|
DamageActor = Pawn(Other.Owner);
|
|
}
|
|
|
|
if ( !Other.bWorldGeometry && Other!=Level )
|
|
{
|
|
HitPawn = KFPawn(Other);
|
|
|
|
if ( HitPawn != none )
|
|
{
|
|
// Hit detection debugging
|
|
/*log("PreLaunchTrace hit "$HitPawn.PlayerReplicationInfo.PlayerName);
|
|
HitPawn.HitStart = Start;
|
|
HitPawn.HitEnd = End;*/
|
|
if(!HitPawn.bDeleteMe)
|
|
HitPawn.ProcessLocationalDamage(int(HitDamage), Instigator, HitLocation, Momentum*X,DamageType,HitPoints);
|
|
|
|
// Hit detection debugging
|
|
/*if( Level.NetMode == NM_Standalone)
|
|
HitPawn.DrawBoneLocation();*/
|
|
|
|
IgnoreActors[IgnoreActors.Length] = Other;
|
|
IgnoreActors[IgnoreActors.Length] = HitPawn.AuxCollisionCylinder;
|
|
Other.SetCollision(false);
|
|
HitPawn.AuxCollisionCylinder.SetCollision(false);
|
|
DamageActor = Other;
|
|
}
|
|
else
|
|
{
|
|
if( KFMonster(Other)!=None )
|
|
{
|
|
IgnoreActors[IgnoreActors.Length] = Other;
|
|
Other.SetCollision(false);
|
|
DamageActor = Other;
|
|
}
|
|
else if( DamageActor == none )
|
|
{
|
|
DamageActor = Other;
|
|
}
|
|
Other.TakeDamage(int(HitDamage), Instigator, HitLocation, Momentum*X, DamageType);
|
|
}
|
|
if( (HCounter++)>=3 || Pawn(DamageActor)==None )
|
|
{
|
|
Break;
|
|
}
|
|
//Big zeds (Blot, Husk, SC, FP) significantly reduce further penetration damage
|
|
if (KFMonster(Other) != none && KFMonster(Other).default.Health >= 500)
|
|
HitDamage*=0.25;
|
|
else
|
|
HitDamage*=0.75;
|
|
Start = HitLocation;
|
|
}
|
|
else if ( HitScanBlockingVolume(Other)==None )
|
|
{
|
|
if( KFWeaponAttachment(Weapon.ThirdPersonActor)!=None )
|
|
KFWeaponAttachment(Weapon.ThirdPersonActor).UpdateHit(Other,HitLocation,HitNormal);
|
|
Break;
|
|
}
|
|
}
|
|
|
|
// Turn the collision back on for any actors we turned it off
|
|
if ( IgnoreActors.Length > 0 )
|
|
{
|
|
for (i=0; i<IgnoreActors.Length; i++)
|
|
{
|
|
if ( IgnoreActors[i] != none )
|
|
IgnoreActors[i].SetCollision(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
BurstSize=2
|
|
maxVerticalRecoilAngle=500
|
|
maxHorizontalRecoilAngle=250
|
|
DamageType=Class'ScrnBalanceSrv.ScrnDamTypeFNFALAssaultRifle'
|
|
FireAnimRate=0.571333
|
|
FireLoopAnimRate=0.571333
|
|
FireRate=0.150000
|
|
AmmoClass=Class'ScrnBalanceSrv.ScrnFNFALAmmo'
|
|
Spread=0.007500
|
|
}
|