class ScrnDualies extends Dualies; var name ReloadShortAnim; var float ReloadShortRate; var float ReloadHalfShortRate; var transient bool bShortReload; var transient bool bHalfShortReload; var bool bTweeningSlide; var bool bTweenLeftSlide; var bool bTweenRightSlide; var bool bAnimatingLeftHammer; var bool bAnimatingRightHammer; var float LeftHammerRotateForwardTime; var float RightHammerRotateForwardTime; var float LeftHammerRotateBackTime; var float RightHammerRotateBackTime; var transient float HammerRotateMult; var transient float HammerRotateRate; var float DefaultHammerRotateMult; var float DefaultHammerRotateRate; var float TweenEndTime; var vector PistolSlideOffset; //for tactical reload var rotator PistolHammerRotation; var transient int NumKillsWithoutReleasingTrigger; var transient int ClientMagAmmoRemaining; var transient int FiringRound; simulated function PostNetReceive() { super.PostNetReceive(); if ( Role < ROLE_Authority ) { if ( ClientMagAmmoRemaining != MagAmmoRemaining ) { if ( MagAmmoRemaining > ClientMagAmmoRemaining ) { // mag update after reload ScrnDualiesFire(GetFireMode(0)).SetPistolFireOrder( (MagAmmoRemaining%2) == 1 ); } if ( MagAmmoRemaining <= 1 ) { LockRightSlideBack(); if ( MagAmmoRemaining == 0 ) LockLeftSlideBack(); } ClientMagAmmoRemaining = MagAmmoRemaining; } } } simulated function Fire(float F) { FiringRound = MagAmmoRemaining; super.Fire(f); } function DropFrom(vector StartLocation) { local int m; local KFWeaponPickup Pickup; local Inventory I; local int AmmoThrown,OtherAmmo; if( !bCanThrow ) return; AmmoThrown = AmmoAmount(0); ClientWeaponThrown(); for (m = 0; m < NUM_FIRE_MODES; m++) { if (FireMode[m].bIsFiring) StopFire(m); } if ( Instigator != None ) DetachFromPawn(Instigator); if( Instigator.Health>0 ) { OtherAmmo = AmmoThrown/2; AmmoThrown-=OtherAmmo; I = Spawn(Class'ScrnBalanceSrv.ScrnSingle'); I.GiveTo(Instigator); Weapon(I).Ammo[0].AmmoAmount = OtherAmmo; Single(I).MagAmmoRemaining = MagAmmoRemaining/2; MagAmmoRemaining = Max(MagAmmoRemaining-Single(I).MagAmmoRemaining,0); } Pickup = Spawn(class'ScrnBalanceSrv.ScrnSinglePickup',,, StartLocation); if ( Pickup != None ) { Pickup.InitDroppedPickupFor(self); Pickup.DroppedBy = PlayerController(Instigator.Controller); Pickup.Velocity = Velocity; Pickup.AmmoAmount[0] = AmmoThrown; Pickup.MagAmmoRemaining = MagAmmoRemaining; if (Instigator.Health > 0) Pickup.bThrown = true; } Destroyed(); Destroy(); } function ServerStopFire(byte Mode) { super.ServerStopFire(Mode); NumKillsWithoutReleasingTrigger = 0; } simulated function BringUp(optional Weapon PrevWeapon) { Super.BringUp(PrevWeapon); if (Level.NetMode != NM_DedicatedServer) { RotateHammersBack(); //always do this now if (MagAmmoRemaining == 0) { LockLeftSlideBack(); LockRightSlideBack(); } if (MagAmmoRemaining == 1) LockRightSlideBack(); } } simulated function RotateHammersBack() { SetBoneRotation( '9mm_hammer', -1*PistolHammerRotation, , 100); //set hammer rotation for empty reload SetBoneRotation( '9mm_hammer01', -1*PistolHammerRotation, , 100); //set hammer rotation for empty reload } //this function sets the times for left hammer drop simulated function DoLeftHammerDrop(float FireRateMod) { bAnimatingLeftHammer = True; HammerRotateRate = DefaultHammerRotateRate/FireRateMod; //0.08 LeftHammerRotateForwardTime = Level.TimeSeconds + HammerRotateRate; //set time LeftHammerRotateBackTime = Level.TimeSeconds + 4*HammerRotateRate; //set time (3 times longer than) } //this function sets the times for right hammer drop simulated function DoRightHammerDrop(float FireRateMod) { bAnimatingRightHammer = True; HammerRotateRate = DefaultHammerRotateRate/FireRateMod; //0.08 RightHammerRotateForwardTime = Level.TimeSeconds + HammerRotateRate; //set time RightHammerRotateBackTime = Level.TimeSeconds + 4*HammerRotateRate; //set time (3 times longer than) } simulated function RotateLeftHammerBack() { SetBoneRotation( '9mm_hammer01', -1*PistolHammerRotation, , 100); //set hammer rotation } simulated function RotateRightHammerBack() { SetBoneRotation( '9mm_hammer', -1*PistolHammerRotation, , 100); //set hammer rotation } //used for enhanced hammer rotation forwards during firing simulated function RotateLeftHammerSmooth(float rate, bool bRotatingHammerBack) { local float RateMult; //calculate how much rate should be multiplied by to give 100 at end RateMult = 100/HammerRotateRate; if(bRotatingHammerBack ) SetBoneRotation( '9mm_hammer01', -DefaultHammerRotateMult*PistolHammerRotation, ,100 - Rate*RateMult/3 ); //needs to move from 0 to -120 else SetBoneRotation( '9mm_hammer01', 0.3*DefaultHammerRotateMult*PistolHammerRotation, , 100- Rate*RateMult ); //needs to move from 0 to 45 } //used for enhanced hammer rotation forwards during firing simulated function RotateRightHammerSmooth(float rate, bool bRotatingHammerBack) { local float RateMult; //calculate how much rate should be multiplied by to give 100 at end RateMult = 100/HammerRotateRate; if(bRotatingHammerBack ) SetBoneRotation( '9mm_hammer', -DefaultHammerRotateMult*PistolHammerRotation, ,100 - Rate*RateMult/3 ); //needs to move from 0 to -120 else SetBoneRotation( '9mm_hammer', 0.3*DefaultHammerRotateMult*PistolHammerRotation, , 100- Rate*RateMult ); //needs to move from 0 to 45 } simulated function ResetLeftSlidePosition() { SetBoneLocation( '9mm_slide01', PistolSlideOffset, 0 ); //reset Slide position } simulated function ResetRightSlidePosition() { SetBoneLocation( '9mm_slide', PistolSlideOffset, 0 ); //reset Slide position } simulated function LockLeftSlideBack() { SetBoneLocation( '9mm_slide01', -1*PistolSlideOffset, 100 ); //lock slide back } simulated function LockRightSlideBack() { SetBoneLocation( '9mm_slide', -1*PistolSlideOffset, 100 ); //lock slide back } simulated function InterpolateRightSlide(float time) { local rotator AdjustedHammerPitch; AdjustedHammerPitch.Pitch = 120*time*5; SetBoneLocation( '9mm_slide', PistolSlideOffset, (time*500)); //after tactical reload tween this from 100 to 0 //SetBoneRotation( '9mm_hammer', AdjustedHammerPitch-PistolHammerRotation, ,100 ); //(Pitch=120,Yaw=0,Roll=0) } simulated function InterpolateLeftSlide(float time) { local rotator AdjustedHammerPitch; AdjustedHammerPitch.Pitch = 120*time*5; SetBoneLocation( '9mm_slide01', PistolSlideOffset, (time*500)); //after tactical reload tween this from 100 to 0 //SetBoneRotation( '9mm_hammer01', AdjustedHammerPitch-PistolHammerRotation, ,100 ); //(Pitch=120,Yaw=0,Roll=0) } //handles all slide movement simulated function HandleSlideMovement() { if (bTweeningSlide && TweenEndTime > 0) { if (Level.TimeSeconds < TweenEndTime ) { if (bTweenRightSlide) InterpolateRightSlide(TweenEndTime - Level.TimeSeconds); if (bTweenLeftSlide) InterpolateLeftSlide(TweenEndTime - Level.TimeSeconds); } if (Level.TimeSeconds > TweenEndTime ) { ResetLeftSlidePosition(); ResetRightSlidePosition(); TweenEndTime = 0; bTweeningSlide = false; bTweenLeftSlide = false; bTweenRightSlide = false; } } } //handles all hammer rotation function HandleHammerRotation() { if (bAnimatingLeftHammer) { if (Level.TimeSeconds < LeftHammerRotateForwardTime && Level.TimeSeconds < LeftHammerRotateBackTime ) RotateLeftHammerSmooth(LeftHammerRotateForwardTime - Level.TimeSeconds, false); //rotate hammer forwards if (Level.TimeSeconds > LeftHammerRotateForwardTime ) RotateLeftHammerSmooth(LeftHammerRotateBackTime - Level.TimeSeconds, true); //rotate hammer backwards if (Level.TimeSeconds > LeftHammerRotateBackTime ) { bAnimatingLeftHammer = false; //finished rotating hammer RotateLeftHammerBack(); //reset it to normal position } } if (bAnimatingRightHammer) { if (Level.TimeSeconds < RightHammerRotateForwardTime && Level.TimeSeconds < RightHammerRotateBackTime ) RotateRightHammerSmooth(RightHammerRotateForwardTime - Level.TimeSeconds, false); //rotate hammer forwards if (Level.TimeSeconds > RightHammerRotateForwardTime ) RotateRightHammerSmooth(RightHammerRotateBackTime - Level.TimeSeconds, true); //rotate hammer backwards if (Level.TimeSeconds > RightHammerRotateBackTime ) { bAnimatingRightHammer = false; //finished rotating hammer RotateRightHammerBack(); //reset it to normal position } } } simulated function WeaponTick(float dt) { if (Level.NetMode != NM_DedicatedServer) { HandleSlideMovement(); HandleHammerRotation(); } Super.WeaponTick(dt); } simulated function StartTweeningSlide() { bTweeningSlide = true; //start Slide tweening TweenEndTime = Level.TimeSeconds + 0.2; } //after reload tween slide back if tactical reload simulated function ClientFinishReloading() { RotateHammersBack(); //always if(bShortReload) { StartTweeningSlide(); //allow tweening of both slides } else if (bHalfShortReload) { StartTweeningSlide(); //allow tweening of both slides, only left should trigger SetBoneLocation( '9mm_slide', PistolSlideOffset, 0 ); //reset right Slide position } else { SetBoneLocation( '9mm_slide01', PistolSlideOffset, 0 ); //reset left slide position SetBoneLocation( '9mm_slide', PistolSlideOffset, 0 ); //reset right slide position } Super.ClientFinishReloading(); } //added slide offset to reload animation simulated function ClientReload() { local float ReloadMulti; if ( bHasAimingMode && bAimingRifle ) { FireMode[1].bIsFiring = False; ZoomOut(false); if( Role < ROLE_Authority) ServerZoomOut(false); } if ( KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill != none ) ReloadMulti = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill.Static.GetReloadSpeedModifier(KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo), self); else ReloadMulti = 1.0; bIsReloading = true; bAnimatingLeftHammer = false; bAnimatingRightHammer = false; if (MagAmmoRemaining <= 0) { bShortReload = false; bHalfShortReload = false; PlayAnim(ReloadAnim, ReloadAnimRate*ReloadMulti, 0.001); ResetLeftSlidePosition(); //use reload animation's ResetRightSlidePosition(); //use reload animation's } else if (MagAmmoRemaining == 1) { bShortReload = false; bHalfShortReload = true; PlayAnim(ReloadAnim, ReloadAnimRate*ReloadMulti, 0.001); ResetRightSlidePosition(); //use reload animation's for right slide SetBoneLocation( '9mm_slide01', PistolSlideOffset, 100 ); //move left slide forward bTweenLeftSlide = true; } else if (MagAmmoRemaining >= 2) { bShortReload = true; bHalfShortReload = false; PlayAnim(ReloadAnim, ReloadAnimRate*ReloadMulti, 0.001); SetBoneLocation( '9mm_slide', PistolSlideOffset, 100 ); //move slide forward SetBoneLocation( '9mm_slide01', PistolSlideOffset, 100 ); //move slide forward bTweenLeftSlide = true; bTweenRightSlide = true; } } exec function ReloadMeNow() { local float ReloadMulti; if(!AllowReload()) return; if ( bHasAimingMode && bAimingRifle ) { FireMode[1].bIsFiring = False; ZoomOut(false); if( Role < ROLE_Authority) ServerZoomOut(false); } if ( KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill != none ) ReloadMulti = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill.Static.GetReloadSpeedModifier(KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo), self); else ReloadMulti = 1.0; bIsReloading = true; ReloadTimer = Level.TimeSeconds; bShortReload = MagAmmoRemaining > 0; if ( MagAmmoRemaining >= 2 ) ReloadRate = default.ReloadShortRate / ReloadMulti; else if (MagAmmoRemaining == 1) ReloadRate = default.ReloadHalfShortRate / ReloadMulti; else if (MagAmmoRemaining <= 0) ReloadRate = default.ReloadRate / ReloadMulti; if( bHoldToReload ) { NumLoadedThisReload = 0; } ClientReload(); Instigator.SetAnimAction(WeaponReloadAnim); if ( Level.Game.NumPlayers > 1 && KFGameType(Level.Game).bWaveInProgress && KFPlayerController(Instigator.Controller) != none && Level.TimeSeconds - KFPlayerController(Instigator.Controller).LastReloadMessageTime > KFPlayerController(Instigator.Controller).ReloadMessageDelay ) { KFPlayerController(Instigator.Controller).Speech('AUTO', 2, ""); KFPlayerController(Instigator.Controller).LastReloadMessageTime = Level.TimeSeconds; } } function AddReloadedAmmo() { local int a; UpdateMagCapacity(Instigator.PlayerReplicationInfo); a = MagCapacity; if ( bShortReload ) a+=2; // 2 bullets already bolted if ( bHalfShortReload ) a++; // 1 bullet already bolted if ( AmmoAmount(0) >= a ) MagAmmoRemaining = a; else MagAmmoRemaining = AmmoAmount(0); // this seems redudant -- PooSH // if( !bHoldToReload ) // { // ClientForceKFAmmoUpdate(MagAmmoRemaining,AmmoAmount(0)); // } if ( PlayerController(Instigator.Controller) != none && KFSteamStatsAndAchievements(PlayerController(Instigator.Controller).SteamStatsAndAchievements) != none ) { KFSteamStatsAndAchievements(PlayerController(Instigator.Controller).SteamStatsAndAchievements).OnWeaponReloaded(); } } defaultproperties { ReloadShortRate=2.930000 ReloadHalfShortRate=3.230000 DefaultHammerRotateMult=1.000000 DefaultHammerRotateRate=0.020000 PistolSlideOffset=(X=0.023300) PistolHammerRotation=(Pitch=145) MagAmmoRemaining=30 Weight=1.000000 FireModeClass(0)=Class'ScrnBalanceSrv.ScrnDualiesFire' DemoReplacement=Class'ScrnBalanceSrv.ScrnSingle' PickupClass=Class'ScrnBalanceSrv.ScrnDualiesPickup' ItemName="Dual 9mms SE" }