class ScrnM4203BulletFire extends ScrnM4Fire; 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 //those functions are used only in FireBurst function PlayFiring() { } function PlayFireEnd() { } function ServerPlayFiring() { } state WaitingForFireButtonRelease { ignores PlayFiring, ServerPlayFiring, PlayFireEnd, ModeDoFire; function ModeTick(float dt) { // allow fire as soon as player releases a fire button if ( Weapon.Instigator == none || Weapon.Instigator.Controller == none || Weapon.Instigator.Controller.bFire == 0 ) GotoState(''); } } state FireBurst { ignores PlayFiring, ServerPlayFiring; // ingnore because we play an anbient fire sound //ignores StopFiring; function BeginState() { //log ("ScrnM4Fire.FireBurst BEGIN STATE", 'ScrnBalance'); BurstShotCount = 0; NextFireTime = Level.TimeSeconds - 0.000001; //fire now! FireBurstEndTime = Level.TimeSeconds + ( FireRate * BurstSize ) + 0.1; // if shit happens - get us out of this state when this time hits if( KFWeap.bAimingRifle ) { Weapon.LoopAnim(FireLoopAimedAnim, FireLoopAnimRate, TweenTime); } else { Weapon.LoopAnim(FireLoopAnim, FireLoopAnimRate, TweenTime); } PlayAmbientSound(AmbientFireSound); } function EndState() { //log ("ScrnM4Fire.FireBurst END STATE", 'ScrnBalance'); super.PlayFireEnd(); Weapon.AnimStopLooping(); PlayAmbientSound(none); if( Weapon.Instigator != none && Weapon.Instigator.IsLocallyControlled() && Weapon.Instigator.IsFirstPerson() && StereoFireSound != none ) { Weapon.PlayOwnedSound(FireEndStereoSound,SLOT_None,AmbientFireVolume/127,,AmbientFireSoundRadius,,false); } else { Weapon.PlayOwnedSound(FireEndSound,SLOT_None,AmbientFireVolume/127,,AmbientFireSoundRadius); } ScrnM4203AssaultRifle(Weapon).ReallyStopFire(ThisModeNum); bIsFiring = false; // tbs } function StartFiring() { super(KFFire).StartFiring(); //bypass KFHighROFFire } function StopFiring() { GotoState(''); } function ModeTick(float dt) { //log ("ScrnM4Fire.FireBurst.ModeTick()", 'ScrnBalance'); Super.ModeTick(dt); if ( !bIsFiring || !AllowFire() ) GotoState(''); else if ( Level.TimeSeconds > FireBurstEndTime ) { GotoState(''); log("ScrnM4203BulletFire stuck inside FireBurst state after making "$BurstShotCount$" shots! Getting us out of it.", 'ScrnBalance'); } } //copy-pasted from KFFire //add stopping fire after reaching the burst amount function ModeDoFire() { local float Rec; local KFPlayerReplicationInfo KFPRI; if (!AllowFire()) return; if( Instigator==None || Instigator.Controller==none ) return; //log ("ScrnM4Fire.FireBurst.ModeDoFire()", 'ScrnBalance'); 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(); } HandleRecoil(Rec); } if ( ++BurstShotCount >= BurstSize ) { //log ("ScrnM4203BulletFire.ChangeFireBurstState", 'ScrnBalance'); //don't go to WaitingForFireButtonRelease state on server if ( Weapon.Instigator == none || Weapon.Instigator.Controller == none || !Weapon.Instigator.IsLocallyControlled() || Weapon.Instigator.Controller.bFire == 0 || KFWeapon(Weapon).MagAmmoRemaining < 1 || ScrnM4203AssaultRifle(Weapon).bTriggerReleased ) GotoState(''); else GotoState('WaitingForFireButtonRelease'); } } } defaultproperties { BurstSize=3 DamageType=Class'ScrnBalanceSrv.ScrnDamTypeM4203AssaultRifle' DamageMax=41 FireAnimRate=0.750000 FireLoopAnimRate=1.400000 FireRate=0.100000 AmmoClass=Class'KFMod.M4203Ammo' }