class ScrnBenelliShotgun extends BenelliShotgun;

var bool bChamberThisReload; //if full reload is uninterrupted, play chambering animation
var vector ReloadViewOffset, ReloadViewOffsetInterp, ReloadViewOffsetValue, TargetViewOffset; //offset used during reloads
var float ReloadTweenStartTime, ReloadTweenEndTime, ReloadTweenRate;

//copypaste from Scrn M14 and vanilla M14 for laser
var         LaserDot                    Spot;                       // The first person laser site dot
var()       float                       SpotProjectorPullback;      // Amount to pull back the laser dot projector from the hit location
var         bool                        bLaserActive;               // The laser site is active
var         LaserBeamEffect             Beam;                       // Third person laser beam effect

var()		class<InventoryAttachment>	LaserAttachmentClass;      // First person laser attachment class
var 		Actor 						LaserAttachment;           // First person laser attachment

var()    byte                                LaserType;       //current laser type
var const class<ScrnLocalLaserDot>          LaserDotClass;
var     ScrnLocalLaserDot                   LaserDot;
var     name                                LaserAttachmentBone;
var         float                         FireSpotRenrerTime;

//laser stuff
replication
{
    reliable if(Role < ROLE_Authority)
        ServerSetLaserType;
}

simulated function Destroyed()
{
	if (Spot != None)
		Spot.Destroy();

	if (Beam != None)
		Beam.Destroy();

    if (LaserDot != None)
        LaserDot.Destroy();

    if (LaserAttachment != None)
        LaserAttachment.Destroy();

    super(KFWeapon).Destroyed();
}

//bring Laser to current state, which is indicating by LaserType
simulated function ApplyLaserState()
{
    //bLaserActive = LaserType > 0;
    LaserType = 1; //always red laser
    bLaserActive = LaserType > 0;
    if( Role < ROLE_Authority  )
        ServerSetLaserType(LaserType);

    if ( ThirdPersonActor != none )
        ScrnLaserWeaponAttachment(ThirdPersonActor).SetLaserType(LaserType);

    if ( !Instigator.IsLocallyControlled() )
        return;

    if( bLaserActive ) {
        if ( LaserDot == none )
            LaserDot = Spawn(LaserDotClass, self);
        LaserDot.SetLaserType(LaserType);
        //spawn 1-st person laser attachment for weapon owner
        if ( LaserAttachment == none ) {
            LaserAttachment = Spawn(LaserAttachmentClass,,,,);
            AttachToBone(LaserAttachment, LaserAttachmentBone);
        }
        ConstantColor'ScrnTex.Laser.LaserColor'.Color =
            LaserDot.GetLaserColor(); // LaserAttachment's color
        LaserAttachment.bHidden = false;

    }
    else {
        if ( LaserAttachment != none )
            LaserAttachment.bHidden = true;
        if ( LaserDot != none )
            LaserDot.Destroy(); //bHidden = true;
    }
}

// Toggle laser modes: RED/GREEN/OFF
simulated function ToggleLaser()
{
    if( !Instigator.IsLocallyControlled() )
        return;

    if ( (++LaserType) > 2 )
        LaserType = 0;
    ApplyLaserState();
}

simulated function BringUp(optional Weapon PrevWeapon)
{
    ApplyLaserState();
    Super.BringUp(PrevWeapon);
    if ( Level.NetMode != NM_DedicatedServer )
    {
        ReloadViewOffset = Vect(0,0,0);
    }
}

simulated function ClientReload()
{
    bChamberThisReload = ( MagAmmoRemaining == 0 && (AmmoAmount(0) - MagAmmoRemaining > MagCapacity) ); //for chambering animation
    Super.ClientReload();
    TargetViewOffset = ReloadViewOffsetValue;
    ReloadTweenStartTime = Level.TimeSeconds;
    ReloadTweenEndTime = Level.TimeSeconds + ReloadTweenRate;
    ReloadViewOffsetInterp = ReloadViewOffset; //store values for interpolation
}

// Set the new fire mode on the server
function ServerSetLaserType(byte NewLaserType)
{
    LaserType = NewLaserType;
    bLaserActive = NewLaserType > 0;
    ScrnLaserWeaponAttachment(ThirdPersonActor).SetLaserType(LaserType);
}

simulated function bool PutDown()
{
    TurnOffLaser();
    if( Instigator.IsLocallyControlled() )
    {
        //don't do this stuff on dedicated servers
        TargetViewOffset = Vect(0,0,0);
        ReloadTweenStartTime = Level.TimeSeconds;
        ReloadTweenEndTime = Level.TimeSeconds + ReloadTweenRate;
        ReloadViewOffsetInterp = ReloadViewOffset; //store values for interpolation
    }
    return super(KFWeapon).PutDown();
}

simulated function TurnOffLaser()
{
    if( !Instigator.IsLocallyControlled() )
        return;

    if( Role < ROLE_Authority  )
        ServerSetLaserType(0);

    bLaserActive = false;
    //don't change Laser type here, because we need to restore it state
    //when next time weapon will be bringed up
    if ( LaserAttachment != none )
        LaserAttachment.bHidden = true;
    if (LaserDot != None)
        LaserDot.Destroy();
}

//tweens to reload offset when reloading and tweens back to 0,0,0 when reload ends or is interrupted by zoom or fire
simulated function TweenToReloadOffset()
{
    local float Alpha; //for lerp
    if (ReloadTweenEndTime == 0)
    {
        return; //do nothing
    }
    if (Level.TimeSeconds > ReloadTweenEndTime)
    {
        ReloadViewOffset = TargetViewOffset; //set target
        ReloadTweenEndTime = 0; //set this to 0
    }
    Alpha = (Level.TimeSeconds-ReloadTweenStartTime)/ReloadTweenRate; //returns float between 0 and 1
    if ( Level.NetMode != NM_DedicatedServer )
    {
        //lerp from current interp value to target
        ReloadViewOffset.X = Lerp(Alpha, ReloadViewOffsetInterp.X, TargetViewOffset.X);
        ReloadViewOffset.Y = Lerp(Alpha, ReloadViewOffsetInterp.Y, TargetViewOffset.Y);
        ReloadViewOffset.Z = Lerp(Alpha, ReloadViewOffsetInterp.Z, TargetViewOffset.Z);
    }
}

//added function to calculate and apply reload view offset
simulated function WeaponTick(float dt)
{
    Super.WeaponTick(dt);
    TweenToReloadOffset();
}

// Server forces the reload to be cancelled
simulated function bool InterruptReload()
{
    //solo testing kek
    if ( Level.NetMode != NM_DedicatedServer )
	{
        TargetViewOffset = Vect(0,0,0);
        ReloadTweenStartTime = Level.TimeSeconds;
        ReloadTweenEndTime = Level.TimeSeconds + ReloadTweenRate;
        ReloadViewOffsetInterp = ReloadViewOffset; //store values for interpolation
	}
    return Super.InterruptReload();
}

//supports laser and reload view offset
simulated function RenderOverlays( Canvas Canvas )
{
    local vector DrawOffset;
    local int i;
    local Vector StartTrace, EndTrace;
    local Vector HitLocation, HitNormal;
    local Actor Other;
    local vector X,Y,Z;
    local coords C;
    local KFShotgunFire KFSGM;
    local array<Actor> HitActors;

    if (Instigator == None)
        return;

    if ( Instigator.Controller != None )
        Hand = Instigator.Controller.Handedness;

    if ((Hand < -1.0) || (Hand > 1.0))
        return;

    // draw muzzleflashes/smoke for all fire modes so idle state won't
    // cause emitters to just disappear
    for ( i = 0; i < NUM_FIRE_MODES; ++i ) {
        if (FireMode[i] != None)
            FireMode[i].DrawMuzzleFlash(Canvas);
    }

    DrawOffset = (90/DisplayFOV * ReloadViewOffset) >> Instigator.GetViewRotation(); //calculate additional offset
    SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) + DrawOffset); //add additional offset
    SetRotation( Instigator.GetViewRotation() + ZoomRotInterp);

    KFSGM = KFShotgunFire(FireMode[0]);

    // Handle drawing the laser dot
    if ( LaserDot != None )
    {
        //move LaserDot during fire animation too  -- PooSH
        if( bIsReloading || (Level.TimeSeconds < KFSGM.LastClickTime + FireSpotRenrerTime) )
        {
            C = GetBoneCoords(LaserAttachmentBone);
            X = C.XAxis;
            Y = C.YAxis;
            Z = C.ZAxis;
        }
        else
            GetViewAxes(X, Y, Z);

        StartTrace = Instigator.Location + Instigator.EyePosition();
        EndTrace = StartTrace + 65535 * X; //65535

        while (true) {
            Other = Trace(HitLocation, HitNormal, EndTrace, StartTrace, true);
            if ( ROBulletWhipAttachment(Other) != none ) {
                HitActors[HitActors.Length] = Other;
                Other.SetCollision(false);
                StartTrace = HitLocation + X;
            }
            else {
                if (Other != None && Other != Instigator && Other.Base != Instigator )
                    EndBeamEffect = HitLocation;
                else
                    EndBeamEffect = EndTrace;
                break;
            }
        }
        // restore collision
        for ( i=0; i<HitActors.Length; ++i )
            HitActors[i].SetCollision(true);

        LaserDot.SetLocation(EndBeamEffect - X*LaserDot.ProjectorPullback);

        if(  Pawn(Other) != none ) {
            LaserDot.SetRotation(Rotator(X));
            LaserDot.SetDrawScale(LaserDot.default.DrawScale * 0.5);
        }
        else if( HitNormal == vect(0,0,0) ) {
            LaserDot.SetRotation(Rotator(-X));
            LaserDot.SetDrawScale(LaserDot.default.DrawScale);
        }
        else {
            LaserDot.SetRotation(Rotator(-HitNormal));
            LaserDot.SetDrawScale(LaserDot.default.DrawScale);
        }
    }

    //PreDrawFPWeapon();    // Laurent -- Hook to override things before render (like rotation if using a staticmesh)

    bDrawingFirstPerson = true;
    Canvas.DrawActor(self, false, false, DisplayFOV);
    bDrawingFirstPerson = false;
}

simulated function ClientFinishReloading()
{
    bIsReloading = false;

    //do reload tween stuff
    TargetViewOffset = Vect(0,0,0);
    ReloadTweenStartTime = Level.TimeSeconds;
    ReloadTweenEndTime = Level.TimeSeconds + ReloadTweenRate;
    ReloadViewOffsetInterp = ReloadViewOffset; //store values for interpolation

    //play chambering animation if finished reloading from empty
    if ( !bChamberThisReload )
    {
        PlayIdle();
    }
    bChamberThisReload = false;

    if(Instigator.PendingWeapon != none && Instigator.PendingWeapon != self)
        Instigator.Controller.ClientSwitchToBestWeapon();
}

defaultproperties
{
     ReloadViewOffsetValue=(X=10.000000,Y=-5.000000,Z=-10.000000)
     ReloadTweenRate=0.200000
     LaserAttachmentClass=Class'ScrnBalanceSrv.ScrnLaserAttachmentFirstPerson'
     LaserDotClass=Class'ScrnBalanceSrv.ScrnLocalLaserDot'
     LaserAttachmentBone="LightBone"
     FireSpotRenrerTime=1.500000
     ReloadRate=0.750000
     ReloadAnimRate=1.074000
     ModeSwitchAnim="LightOn"
     FireModeClass(0)=Class'ScrnBalanceSrv.ScrnBenelliFire'
     Description="A military tactical shotgun with semi automatic fire capability. Holds up to 6 shells. Special shell construction allow pellets to penetrate fat much easier."
     PickupClass=Class'ScrnBalanceSrv.ScrnBenelliPickup'
     PlayerViewPivot=(Pitch=-47,Yaw=-5)
     AttachmentClass=Class'ScrnBalanceSrv.ScrnBenelliAttachment'
     ItemName="Combat Shotgun SE"
}
