rott/kf_sources/ScrnBalanceSrv/Classes/ScrnFNFAL_ACOG_AssaultRifle.uc
2026-07-14 20:27:09 +07:00

228 lines
6.7 KiB
Ucode

class ScrnFNFAL_ACOG_AssaultRifle extends FNFAL_ACOG_AssaultRifle
config(user);
var int FireModeEx; // 0 - F/A, 1 - S/A, 2 - 2 bullet fire
var int FireModeExCount;
var name ReloadShortAnim;
var float ReloadShortRate;
var transient bool bShortReload;
var vector BulletMoveOffset; //for tactical reload
var bool bBulletMoveQueued; //for tactical reload
replication
{
reliable if(Role < ROLE_Authority)
ServerChangeFireModeEx;
}
// Toggle semi/auto fire
simulated function DoToggle ()
{
local PlayerController Player;
Player = Level.GetLocalPlayerController();
if ( Player!=None )
{
FireModeEx++;
if (FireModeEx >= FireModeExCount) FireModeEx = 0;
FireMode[0].bWaitForRelease = FireModeEx == 1;
Player.ReceiveLocalizedMessage(class'ScrnBalanceSrv.ScrnFireModeSwitchMessage',FireModeEx);
}
ServerChangeFireModeEx(FireModeEx);
}
// Set the new fire mode on the server
function ServerChangeFireModeEx(int NewFireModeEx)
{
FireModeEx = NewFireModeEx;
FireMode[0].bWaitForRelease = NewFireModeEx == 1;
}
simulated function bool StartFire(int Mode)
{
if ( FireModeEx <= 1 ) return super.StartFire(Mode);
if (FireMode[Mode].IsInState('WaitingForFireButtonRelease'))
return false;
if( !super(KFWeapon).StartFire(Mode) ) // returns false when mag is empty
return false;
if( AmmoAmount(0) <= 0 )
{
return false;
}
AnimStopLooping();
if( !FireMode[Mode].IsInState('FireBurst') && (AmmoAmount(0) > 0) )
{
ScrnFNFALFire(FireMode[Mode]).BurstSize = FireModeEx;
FireMode[Mode].GotoState('FireBurst');
return true;
}
return false;
}
simulated function StopFire(int Mode)
{
super.StopFire(Mode);
if (FireMode[Mode].IsInState('WaitingForFireButtonRelease'))
FireMode[Mode].GotoState('');
}
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 ( bShortReload )
ReloadRate = Default.ReloadShortRate / ReloadMulti;
else
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;
}
}
//make sure bullet doesn't have old offset when reload finishes
simulated function ClientFinishReloading()
{
Super.ClientFinishReloading();
ResetBulletPosition(); //undo offset
}
//ClientReloadEffects is called by WeaponTick halfway through reload, perfect for a tactical reload
simulated function ClientReloadEffects()
{
ResetBulletPosition(); //undo offset
}
simulated function ResetBulletPosition()
{
SetBoneLocation('Bullets', BulletMoveOffset, 0); //undo offset
}
simulated function MoveMagBullet()
{
SetBoneLocation('Bullets', BulletMoveOffset, 100); //apply offset
}
simulated function WeaponTick(float dt)
{
if (Level.NetMode != NM_DedicatedServer)
{
if ( bBulletMoveQueued && bIsReloading && MagAmmoRemaining > 1 && (Level.TimeSeconds - ReloadTimer) > ReloadRate*0.12 )
{
bBulletMoveQueued = false;
MoveMagBullet();
}
}
Super.WeaponTick(dt);
}
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;
if (MagAmmoRemaining <= 0)
{
PlayAnim(ReloadAnim, ReloadAnimRate*ReloadMulti, 0.1);
}
else if (MagAmmoRemaining >= 1)
{
PlayAnim(ReloadShortAnim, ReloadAnimRate*ReloadMulti, 0.1);
if (MagAmmoRemaining >= 2)
bBulletMoveQueued = true; //set flag for tactical reload
}
}
function AddReloadedAmmo()
{
local int a;
UpdateMagCapacity(Instigator.PlayerReplicationInfo);
a = MagCapacity;
if ( bShortReload )
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
{
FireModeExCount=3
ReloadShortAnim="Reload"
ReloadShortRate=2.550000
BulletMoveOffset=(Z=0.030000)
Weight=7.000000
FireModeClass(0)=Class'ScrnBalanceSrv.ScrnFNFALFire'
Description="Classic NATO battle rifle. Can penetrate small targets and has a fixed-burst mode."
PickupClass=Class'ScrnBalanceSrv.ScrnFNFAL_ACOG_Pickup'
ItemName="FNFAL SE"
}