class NiceDualiesFire extends NiceFire;
var bool bWasInZedTime;
var Emitter Flash2Emitter;
var Emitter ShellEject2Emitter;
var name    ShellEject2BoneName;
var name    FireAnim2, FireAimedAnim2;
var bool    bIsLeftShot;
var float   leftNextFireTime;
var float   rightNextFireTime;
var bool    bLastFiredLeft;
simulated function ModeTick(float delta){
    local float timeCutScale;
    local NicePlayerController nicePlayer;
    if(instigator != none)
       nicePlayer = NicePlayerController(instigator.controller);
    if(nicePlayer != none && nicePlayer.IsZedTimeActive() != bWasInZedTime){
       bWasInZedTime = !bWasInZedTime;
       timeCutScale = 1.0;
       if(bWasInZedTime)
           timeCutScale = KFGameType(Level.Game).ZedTimeSlomoScale;
       niceNextFireTime = Level.TimeSeconds + (niceNextFireTime - Level.TimeSeconds) * timeCutScale;
       nextFireTime = niceNextFireTime;
       leftNextFireTime = Level.TimeSeconds + (leftNextFireTime - Level.TimeSeconds) * timeCutScale;
       rightNextFireTime = Level.TimeSeconds + (rightNextFireTime - Level.TimeSeconds) * timeCutScale;
    }
    super.ModeTick(delta);
}
simulated function InitEffects(){
    local NiceDualies dualWeapon;
    dualWeapon = NiceDualies(Weapon);
    if((Level.NetMode == NM_DedicatedServer) || (AIController(Instigator.Controller) != none) || dualWeapon == none)
       return;
    if((FlashEmitterClass != none) && ((FlashEmitter == none) || FlashEmitter.bDeleteMe)){
       FlashEmitter = Weapon.Spawn(FlashEmitterClass);
       Weapon.AttachToBone(FlashEmitter, dualWeapon.default.FlashBoneName);
    }
    if((FlashEmitterClass != none) && ((Flash2Emitter == none) || Flash2Emitter.bDeleteMe)){
       Flash2Emitter = Weapon.Spawn(FlashEmitterClass);
       Weapon.AttachToBone(Flash2Emitter, dualWeapon.default.altFlashBoneName);
    }
    if((SmokeEmitterClass != none) && ((SmokeEmitter == none) || SmokeEmitter.bDeleteMe))
       SmokeEmitter = Weapon.Spawn(SmokeEmitterClass);
    if((ShellEjectClass != none) && ((ShellEjectEmitter == none) || ShellEjectEmitter.bDeleteMe)){
       ShellEjectEmitter = Weapon.Spawn(ShellEjectClass);
       Weapon.AttachToBone(ShellEjectEmitter, ShellEjectBoneName);
    }
    if((ShellEjectClass != none) && ((ShellEject2Emitter == none) || ShellEject2Emitter.bDeleteMe)){
       ShellEject2Emitter = Weapon.Spawn(ShellEjectClass);
       Weapon.AttachToBone(ShellEject2Emitter, ShellEject2BoneName);
    }
}
simulated function DestroyEffects(){
    super.DestroyEffects();
    if(ShellEject2Emitter != none)
       ShellEject2Emitter.Destroy();
    if(Flash2Emitter != none)
       Flash2Emitter.Destroy();
}
function DrawMuzzleFlash(Canvas Canvas){
    super.DrawMuzzleFlash(Canvas);
    if(ShellEject2Emitter != none)
       Canvas.DrawActor( ShellEject2Emitter, false, false, Weapon.DisplayFOV );
}
function FlashMuzzleFlash(){
    if(Flash2Emitter == none || FlashEmitter == none)
       return;
    if(KFWeap.bAimingRifle){
       if(FireAimedAnim == 'FireLeft_Iron'){
           Flash2Emitter.Trigger(Weapon, Instigator);
           if(ShellEjectEmitter != none)
               ShellEjectEmitter.Trigger(Weapon, Instigator);
       }
       else{
           FlashEmitter.Trigger(Weapon, Instigator);
           if(ShellEject2Emitter != none)
               ShellEject2Emitter.Trigger(Weapon, Instigator);
       }
    }
    else{
       if(FireAnim == 'FireLeft'){
           Flash2Emitter.Trigger(Weapon, Instigator);
           if(ShellEjectEmitter != none)
               ShellEjectEmitter.Trigger(Weapon, Instigator);
       }
       else{
           FlashEmitter.Trigger(Weapon, Instigator);
           if(ShellEject2Emitter != none)
               ShellEject2Emitter.Trigger(Weapon, Instigator);
       }
    }
}
simulated function ModeDoFireLeft(){
    local NiceDualies           dualWeapon;
    local NiceDualiesAttachment dualAttach, dualAttachAlt;
    dualWeapon = NiceDualies(Weapon);
    dualAttach = NiceDualiesAttachment(dualWeapon.ThirdPersonActor);
    dualAttachAlt = NiceDualiesAttachment(dualWeapon.altThirdPersonActor);
    if(dualWeapon == none || !AllowLeftFire())
       return;
    // Set shine turn
    if(dualAttach != none)
       dualAttach.bMyFlashTurn = false;
    if(dualAttachAlt != none)
       dualAttachAlt.bMyFlashTurn = true;
    // Swap bones and animations
    dualWeapon.FlashBoneName = dualWeapon.default.altFlashBoneName;
    dualWeapon.altFlashBoneName = dualWeapon.default.FlashBoneName;
    FireAnim = default.FireAnim2;
    FireAnim2 = default.FireAnim;
    FireAimedAnim = default.FireAimedAnim2;
    FireAimedAnim2 = default.FireAimedAnim;
    // Do left shot
    bIsLeftShot = true;
    super.ModeDoFire();
    leftNextFireTime = UpdateNextFireTimeSingle(leftNextFireTime);
    InitEffects();
    bLastFiredLeft = true;
}
simulated function ModeDoFireRight(){
    local NiceDualies           dualWeapon;
    local NiceDualiesAttachment dualAttach, dualAttachAlt;
    dualWeapon = NiceDualies(Weapon);
    dualAttach = NiceDualiesAttachment(dualWeapon.ThirdPersonActor);
    dualAttachAlt = NiceDualiesAttachment(dualWeapon.altThirdPersonActor);
    if(dualWeapon == none || !AllowRightFire())
       return;
    // Set shine turn
    if(dualAttach != none)
       dualAttach.bMyFlashTurn = true;
    if(dualAttachAlt != none)
       dualAttachAlt.bMyFlashTurn = false;
    // Default bones and animations
    dualWeapon.FlashBoneName = dualWeapon.default.FlashBoneName;
    dualWeapon.altFlashBoneName = dualWeapon.default.altFlashBoneName;
    FireAnim = default.FireAnim;
    FireAnim2 = default.FireAnim2;
    FireAimedAnim = default.FireAimedAnim;
    FireAimedAnim2 = default.FireAimedAnim2;
    // Do right shot
    bIsLeftShot = false;
    super.ModeDoFire();
    rightNextFireTime = UpdateNextFireTimeSingle(rightNextFireTime);
    InitEffects();
    bLastFiredLeft = false;
}
simulated function bool AllowLeftFire(){
    local NiceDualies niceDualWeap;
    niceDualWeap = NiceDualies(currentContext.sourceWeapon);
    if(niceDualWeap == none)
       return false;
    if(niceDualWeap.GetMagazineAmmoLeft() < default.AmmoPerFire && !bCanFireIncomplete)
       return false;
    return true;
}
simulated function bool AllowRightFire(){
    local NiceDualies niceDualWeap;
    niceDualWeap = NiceDualies(currentContext.sourceWeapon);
    if(niceDualWeap == none)
       return false;
    if(niceDualWeap.GetMagazineAmmoRight() < default.AmmoPerFire && !bCanFireIncomplete)
       return false;
    return true;
}
simulated function bool AllowFire(){
    return super.AllowFire() && (AllowLeftFire() || AllowRightFire());
}
event ModeDoFire(){
    local NiceDualies dualWeap;
    dualWeap = NiceDualies(Instigator.Weapon);
    if(dualWeap == none || niceNextFireTime > Level.TimeSeconds || !AllowFire())
       return;
    if(niceNextFireTime + FireRate < Level.TimeSeconds)
       bResetRecoil = true;
    // Choose correct pistol to fire
    if(Level.TimeSeconds > leftNextFireTime && Level.TimeSeconds > rightNextFireTime && AllowLeftFire() && AllowRightFire()){
       if(dualWeap.GetMagazineAmmoLeft() > dualWeap.GetMagazineAmmoRight())
           ModeDoFireLeft();
       else if(dualWeap.GetMagazineAmmoLeft() < dualWeap.GetMagazineAmmoRight())
           ModeDoFireRight();
       else if(bLastFiredLeft)
           ModeDoFireRight();
       else
           ModeDoFireLeft();
    }
    else if(Level.TimeSeconds > leftNextFireTime && AllowLeftFire())
       ModeDoFireLeft();
    else if(Level.TimeSeconds > rightNextFireTime && AllowRightFire())
       ModeDoFireRight();
}
simulated function ReduceAmmoClient(){
    local NiceDualies dualWeap;
    dualWeap = NiceDualies(currentContext.sourceWeapon);
    if(dualWeap == none)
       return;
    if(bIsLeftShot)
       dualWeap.MagAmmoRemLeftClient -= Load;
    else
       dualWeap.MagAmmoRemRightClient -= Load;
    if(dualWeap.MagAmmoRemLeftClient < 0)
       dualWeap.MagAmmoRemLeftClient = 0;
    if(dualWeap.MagAmmoRemRightClient < 0)
       dualWeap.MagAmmoRemRightClient = 0;
    // Force server's magazine size
    dualWeap.ServerReduceDualMag(dualWeap.MagAmmoRemLeftClient, dualWeap.MagAmmoRemRightClient, Level.TimeSeconds, ThisModeNum);
}
simulated function float UpdateNextFireTimeSingle(float fireTimeVar){
    FireRate *= 2;
    fireTimeVar = UpdateNextFireTime(fireTimeVar);
    FireRate = default.FireRate;
    return fireTimeVar;
}

defaultproperties
{
     ShellEject2BoneName="Shell_eject_right"
     FireAnim2="FireLeft"
     FireAimedAnim2="FireLeft_Iron"
     FireAimedAnim="FireRight_Iron"
     RecoilRate=0.070000
     maxVerticalRecoilAngle=450
     maxHorizontalRecoilAngle=50
     ShellEjectClass=Class'ROEffects.KFShellEject9mm'
     ShellEjectBoneName="Shell_eject_left"
     DamageMin=35
     DamageMax=35
     Momentum=10500.000000
     bPawnRapidFireAnim=True
     bWaitForRelease=True
     bAttachSmokeEmitter=True
     TransientSoundVolume=1.800000
     FireAnim="FireRight"
     FireLoopAnim=
     FireEndAnim=
     TweenTime=0.025000
     FireForce="AssaultRifleFire"
     FireRate=0.087500
     AmmoClass=class'NiceSingleAmmo'
     ShakeRotMag=(X=75.000000,Y=75.000000,Z=250.000000)
     ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
     ShakeRotTime=3.000000
     ShakeOffsetMag=(X=6.000000,Y=3.000000,Z=10.000000)
     ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
     ShakeOffsetTime=2.000000
     BotRefireRate=0.250000
     FlashEmitterClass=Class'ROEffects.MuzzleFlash1stMP'
     aimerror=30.000000
}
