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

463 lines
14 KiB
Ucode

class AKBaseWeapon extends KFWeapon
abstract;
#exec OBJ LOAD FILE=KillingFloorWeapons.utx
#exec OBJ LOAD FILE=KillingFloorHUD.utx
#exec OBJ LOAD FILE=Inf_Weapons_Foley.uax
var name ReloadShortAnim;
var float ReloadShortRate;
var transient KFWeaponPickup PendingPickup;
var transient bool bShortReload;
var const int OriginalMaxAmmo;
var const bool bSharedAmmoPool;
var transient class<KFVeterancyTypes> LastClientVeteranSkill;
var transient int LastClientVeteranSkillLevel;
var KFPlayerReplicationInfo OwnerPRI; // don't access it directly! Use GetOwnerPRI() instead.
simulated function AltFire(float F)
{
// if(ReadyToFire(0))
// {
DoToggle();
// }
}
exec function SwitchModes()
{
DoToggle();
}
function byte BestMode()
{
return 0;
}
simulated function int MaxAmmo(int mode)
{
if ( Ammo[mode] != none )
return Ammo[mode].MaxAmmo;
if ( AmmoClass[mode] != None )
return AmmoClass[mode].default.MaxAmmo * GetAmmoMulti();
return 0;
}
function GiveAmmo(int m, WeaponPickup WP, bool bJustSpawned)
{
local bool bJustSpawnedAmmo;
local int addAmount, InitialAmount;
UpdateMagCapacity(Instigator.PlayerReplicationInfo);
if ( FireMode[m] != None && FireMode[m].AmmoClass != None )
{
Ammo[m] = Ammunition(Instigator.FindInventoryType(FireMode[m].AmmoClass));
bJustSpawnedAmmo = false;
if ( bNoAmmoInstances )
{
if ( (FireMode[m].AmmoClass == None) || ((m != 0) && (FireMode[m].AmmoClass == FireMode[0].AmmoClass)) )
return;
InitialAmount = FireMode[m].AmmoClass.Default.InitialAmount;
if(WP!=none && WP.bThrown==true)
InitialAmount = WP.AmmoAmount[m];
else
{
// Other change - if not thrown, give the gun a full clip
MagAmmoRemaining = MagCapacity;
}
if ( Ammo[m] != None )
{
addamount = InitialAmount + Ammo[m].AmmoAmount;
Ammo[m].Destroy();
}
else
addAmount = InitialAmount;
AddAmmo(addAmount,m);
}
else
{
if ( (Ammo[m] == None) && (FireMode[m].AmmoClass != None) )
{
Ammo[m] = Spawn(FireMode[m].AmmoClass, Instigator);
Instigator.AddInventory(Ammo[m]);
bJustSpawnedAmmo = true;
}
else if ( (m == 0) || (FireMode[m].AmmoClass != FireMode[0].AmmoClass) )
bJustSpawnedAmmo = ( bJustSpawned || ((WP != None) && !WP.bWeaponStay) );
// and here is the modification for instanced ammo actors
SetMaxAmmo();
if(WP!=none && WP.bThrown==true)
addAmount = WP.AmmoAmount[m];
else if ( bJustSpawnedAmmo ) {
if (default.MagCapacity == 0)
addAmount = 0; // prevent division by zero.
else
addAmount = Ammo[m].InitialAmount * (float(MagCapacity) / float(default.MagCapacity));
}
// Don't double add ammo if primary and secondary fire modes share the same ammo class
if ( WP != none && m > 0 && (FireMode[m].AmmoClass == FireMode[0].AmmoClass) )
return;
Ammo[m].AddAmmo(addAmount);
Ammo[m].GotoState('');
}
}
}
simulated function ClientWeaponSet(bool bPossiblySwitch)
{
super.ClientWeaponSet(bPossiblySwitch);
if ( Instigator != none )
SetMaxAmmo();
}
simulated function Destroyed()
{
SetMaxAmmo();
super.Destroyed();
}
exec simulated function SetMaxAmmo()
{
local Inventory Inv;
local AKBaseWeapon W;
local int c, NewMaxAmmo;
local Actor MyOwner;
local Ammunition MyAmmo;
if ( Instigator == none )
MyOwner = Instigator;
else
MyOwner = Owner;
if ( GetOwnerPRI() != none ) {
LastClientVeteranSkill = OwnerPRI.ClientVeteranSkill;
LastClientVeteranSkillLevel = OwnerPRI.ClientVeteranSkillLevel;
}
else
LastClientVeteranSkill = none;
if ( LastClientVeteranSkill != none )
LastAmmoResult = LastClientVeteranSkill.static.AddExtraAmmoFor(OwnerPRI, FireMode[0].AmmoClass);
else
LastAmmoResult = 1.0;
MyAmmo = Ammo[0];
if ( bSharedAmmoPool ) {
if ( PendingPickup == none && !bPendingDelete )
NewMaxAmmo = OriginalMaxAmmo;
for( Inv = MyOwner.Inventory; Inv!=none && (++c)<1000; Inv=Inv.Inventory ) {
W = AKBaseWeapon(Inv);
if ( W != none && W!= self && !W.bPendingDelete && W.Ammo[0] != none ) {
if ( W.Ammo[0] == MyAmmo )
NewMaxAmmo += W.OriginalMaxAmmo;
else if ( MyAmmo == none && W.Ammo[0].class == FireModeClass[0].default.AmmoClass ) {
MyAmmo = W.Ammo[0];
NewMaxAmmo += W.OriginalMaxAmmo;
}
}
}
}
if ( NewMaxAmmo == 0 )
NewMaxAmmo = FireMode[0].AmmoClass.default.MaxAmmo;
if ( MyAmmo != none ) {
MyAmmo.MaxAmmo = NewMaxAmmo * LastAmmoResult;
LastAmmoResult = float(MyAmmo.MaxAmmo) / MyAmmo.default.MaxAmmo; //used in GetAmmoMulti()
if ( MyAmmo.AmmoAmount > MyAmmo.MaxAmmo ) {
if ( PendingPickup != none ) {
PendingPickup.AmmoAmount[0] += MyAmmo.AmmoAmount - MyAmmo.MaxAmmo;
PendingPickup.MagAmmoRemaining = min(MagAmmoRemaining, PendingPickup.AmmoAmount[0]);
}
MyAmmo.AmmoAmount = MyAmmo.MaxAmmo;
}
if ( bSharedAmmoPool ) {
for( Inv = MyOwner.Inventory; Inv!=none && (++c)<1000; Inv=Inv.Inventory ) {
W = AKBaseWeapon(Inv);
if ( W != none && W != self ) {
W.LastAmmoResult = LastAmmoResult;
W.LastClientVeteranSkill = LastClientVeteranSkill;
W.LastClientVeteranSkillLevel = LastClientVeteranSkillLevel;
}
}
}
}
}
simulated function float GetAmmoMulti()
{
if ( GetOwnerPRI() == none ) {
LastClientVeteranSkill = none;
return 1.0;
}
if ( OwnerPRI.ClientVeteranSkill != LastClientVeteranSkill || OwnerPRI.ClientVeteranSkillLevel != LastClientVeteranSkillLevel )
SetMaxAmmo();
return LastAmmoResult;
}
simulated function KFPlayerReplicationInfo GetOwnerPRI()
{
if ( OwnerPRI == none ) {
if ( Instigator != none )
OwnerPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if ( OwnerPRI == none && Pawn(Owner) != none )
OwnerPRI = KFPlayerReplicationInfo(Pawn(Owner).PlayerReplicationInfo);
}
return OwnerPRI;
}
// ensures that other guns with the same ammunition don't have more bullets in magazine than available
simulated function CheckSharedMags()
{
local int MaxMagAmmo, c;
local Inventory Inv;
local AKBaseWeapon W;
if ( !bSharedAmmoPool || Instigator == none || Ammo[0] == none )
return;
MaxMagAmmo = AmmoAmount(0) - MagAmmoRemaining;
for( Inv = Instigator.Inventory; Inv!=none && (++c)<1000; Inv=Inv.Inventory ) {
W = AKBaseWeapon(Inv);
if ( W != none && W!= self && W.Ammo[0] == Ammo[0] ) {
if ( W.MagAmmoRemaining > MaxMagAmmo )
W.MagAmmoRemaining = min(MaxMagAmmo, W.MagCapacity);
MaxMagAmmo -= W.MagAmmoRemaining;
if ( MaxMagAmmo < 0)
MaxMagAmmo = 0;
}
}
}
simulated function GetAmmoCount(out float MaxAmmoPrimary, out float CurAmmoPrimary)
{
if ( Ammo[0] != None ) {
MaxAmmoPrimary = Ammo[0].MaxAmmo;
CurAmmoPrimary = Ammo[0].AmmoAmount;
}
else {
MaxAmmoPrimary = 0;
CurAmmoPrimary = 0;
}
}
function DropFrom(vector StartLocation)
{
local int m;
local Pickup Pickup;
local vector Direction;
if (!bCanThrow)
return;
ClientWeaponThrown();
for (m = 0; m < NUM_FIRE_MODES; m++)
{
if (FireMode[m].bIsFiring)
StopFire(m);
}
if ( Instigator != None )
{
DetachFromPawn(Instigator);
Direction = vector(Instigator.Rotation);
}
else if ( Owner != none )
{
Direction = vector(Owner.Rotation);
}
Pickup = Spawn(PickupClass,,, StartLocation);
if ( Pickup != None )
{
Pickup.InitDroppedPickupFor(self);
Pickup.Velocity = Velocity + (Direction * 100);
if (Instigator.Health > 0)
WeaponPickup(Pickup).bThrown = true;
}
PendingPickup = KFWeaponPickup(Pickup);
Destroy();
}
simulated function SetZoomBlendColor(Canvas c)
{
local Byte val;
local Color clr;
local Color fog;
clr.R = 255;
clr.G = 255;
clr.B = 255;
clr.A = 255;
if( Instigator.Region.Zone.bDistanceFog )
{
fog = Instigator.Region.Zone.DistanceFogColor;
val = 0;
val = Max( val, fog.R);
val = Max( val, fog.G);
val = Max( val, fog.B);
if( val > 128 )
{
val -= 128;
clr.R -= val;
clr.G -= val;
clr.B -= val;
}
}
c.DrawColor = clr;
}
// copy-pasted to add (MagCapacity+1)
simulated function bool AllowReload()
{
UpdateMagCapacity(Instigator.PlayerReplicationInfo);
if ( KFInvasionBot(Instigator.Controller) != none && !bIsReloading &&
MagAmmoRemaining < MagCapacity && AmmoAmount(0) > MagAmmoRemaining )
return true;
if ( KFFriendlyAI(Instigator.Controller) != none && !bIsReloading &&
MagAmmoRemaining < MagCapacity && AmmoAmount(0) > MagAmmoRemaining )
return true;
if( FireMode[0].IsFiring() || FireMode[1].IsFiring() ||
bIsReloading || MagAmmoRemaining >= MagCapacity ||
ClientState == WS_BringUp ||
AmmoAmount(0) <= MagAmmoRemaining ||
(FireMode[0].NextFireTime - Level.TimeSeconds) > 0.1 )
return false;
return 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 ( GetOwnerPRI() != none && OwnerPRI.ClientVeteranSkill != none )
{
ReloadMulti = OwnerPRI.ClientVeteranSkill.Static.GetReloadSpeedModifier(OwnerPRI, 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;
}
}
simulated function ClientReload()
{
local float ReloadMulti;
if ( bHasAimingMode && bAimingRifle )
{
FireMode[1].bIsFiring = False;
ZoomOut(false);
if( Role < ROLE_Authority)
ServerZoomOut(false);
}
if ( GetOwnerPRI() != none && OwnerPRI.ClientVeteranSkill != none )
ReloadMulti = OwnerPRI.ClientVeteranSkill.Static.GetReloadSpeedModifier(OwnerPRI, 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);
}
}
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();
}
}
simulated function ActuallyFinishReloading()
{
super.ActuallyFinishReloading();
if ( bSharedAmmoPool )
CheckSharedMags();
}
defaultproperties
{
ReloadShortAnim="Reload"
ReloadShortRate=3.000000
OriginalMaxAmmo=300
bSharedAmmoPool=True
}