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

336 lines
9.6 KiB
Ucode

class stub_Pawn extends KFHumanPawn_Story;
struct FDualList
{
var class<KFWeapon> Single,Dual;
};
var array<FDualList> DualMap;
var int OtherPrice;
var class<KFWeapon> SecType;
var transient float cashtimer;
var transient byte CashCount;
//=============================================================================
// weapon == none fix
//=============================================================================
function ServerChangedWeapon(Weapon OldWeapon, Weapon NewWeapon)
{
local float InvisTime;
if (bInvis)
{
if ( (OldWeapon != none) && (OldWeapon.OverlayMaterial == InvisMaterial) )
InvisTime = OldWeapon.ClientOverlayCounter;
else
InvisTime = 20000;
}
if (HasUDamage() || bInvis)
SetWeaponOverlay(None, 0.f, true);
super(Pawn).ServerChangedWeapon(OldWeapon, NewWeapon);
if (bInvis)
SetWeaponOverlay(InvisMaterial, InvisTime, true);
else if (HasUDamage())
SetWeaponOverlay(UDamageWeaponMaterial, UDamageTime - Level.TimeSeconds, false);
// the fix
if (weapon == none)
return;
if (bBerserk)
Weapon.StartBerserk();
else if ( Weapon.bBerserk )
Weapon.StopBerserk();
}
//=============================================================================
// Dosh shit
//=============================================================================
// toss some of your cash away. (to help a cash-strapped ally or perhaps just to party like its 1994)
exec function TossCash(int Amount)
{
local Vector X,Y,Z;
local CashPickup CashPickup;
local Vector TossVel;
local Actor A;
// NEW check! and 0.3 sec delay between throws
if (Level.TimeSeconds < class'stub_Pawn'.default.cashtimer || PlayerReplicationInfo == none)
return;
class'stub_Pawn'.default.cashtimer = Level.TimeSeconds + 0.3f;
// 30 dosh at min
Amount = clamp(Amount, 30, int(Controller.PlayerReplicationInfo.Score));
// if (Amount<=0)
// Amount = 50;
Controller.PlayerReplicationInfo.Score = int(Controller.PlayerReplicationInfo.Score); // To fix issue with throwing 0 pounds.
if (Controller.PlayerReplicationInfo.Score<=0 || Amount<=0)
return;
Amount = Min(Amount, int(Controller.PlayerReplicationInfo.Score));
GetAxes(Rotation,X,Y,Z);
TossVel = Vector(GetViewRotation());
TossVel = TossVel * ((Velocity Dot TossVel) + 500) + Vect(0,0,200);
// added owner to cash pickup, 2020 finally
CashPickup = spawn(class'CashPickup', self,, Location + 0.8 * CollisionRadius * X - 0.5 * CollisionRadius * Y);
if (CashPickup != none)
{
CashPickup.CashAmount = Amount;
CashPickup.bDroppedCash = true;
CashPickup.RespawnTime = 0; // Dropped cash doesnt respawn. For obvious reasons.
CashPickup.Velocity = TossVel;
CashPickup.DroppedBy = Controller;
CashPickup.InitDroppedPickupFor(None);
Controller.PlayerReplicationInfo.Score -= Amount;
if ( Level.Game.NumPlayers > 1 && Level.TimeSeconds - LastDropCashMessageTime > DropCashMessageDelay )
{
PlayerController(Controller).Speech('AUTO', 4, "");
}
// Hack to get Slot machines to accept dosh that's thrown inside their collision cylinder.
foreach CashPickup.TouchingActors(class 'Actor', A)
{
if(A.IsA('KF_Slot_Machine'))
{
A.Touch(Cashpickup);
}
}
}
}
//=============================================================================
// Sound none on player death
//=============================================================================
// fix for none soundgroup calls on death
function Sound GetSound(xPawnSoundGroup.ESoundType soundType)
{
local int SurfaceTypeID;
local actor A;
local vector HL,HN,Start,End;
local material FloorMat;
// added this in case when player joins using a custom skin with a custom SoundGroupClass,
// which not present on the server
if ( SoundGroupClass == none )
SoundGroupClass = class'KFMod.KFMaleSoundGroup';
if( soundType == EST_Land || soundType == EST_Jump )
{
if ( (Base!=None) && (!Base.IsA('LevelInfo')) && (Base.SurfaceType!=0) )
{
SurfaceTypeID = Base.SurfaceType;
}
else
{
Start = Location - Vect(0,0,1)*CollisionHeight;
End = Start - Vect(0,0,16);
A = Trace(hl,hn,End,Start,false,,FloorMat);
if (FloorMat !=None)
SurfaceTypeID = FloorMat.SurfaceType;
}
}
return SoundGroupClass.static.GetSound(soundType, SurfaceTypeID);
}
// allows us to buy from trader menu from anywhere
function bool CanBuyNow()
{
local ShopVolume Sh;
if (class'o_Settings'.default.bBuyEverywhere)
return true;
if (KFGameType(Level.Game) == none || KFGameType(Level.Game).bWaveInProgress || PlayerReplicationInfo == none)
return false;
foreach TouchingActors(class'ShopVolume', Sh)
return true;
return false;
}
//=============================================================================
// Dualies Print Fix
//=============================================================================
function ServerBuyWeapon( class<Weapon> WClass, float ItemWeight )
{
local Inventory I, J;
local float Price;
if ( !CanBuyNow() || class<KFWeapon>(WClass) == none || class<KFWeaponPickup>(WClass.Default.PickupClass) == none || class'stub_Pawn'.static.HasWeaponClass(WClass) )
{
return;
}
Price = class<KFWeaponPickup>(WClass.default.PickupClass).default.Cost;
if ( KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
Price *= KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.GetCostScaling(KFPlayerReplicationInfo(PlayerReplicationInfo), WClass.Default.PickupClass);
// N.B. addition !
// ItemWeight = class<KFWeapon>(WClass).default.Weight;
if ( class'stub_Pawn'.static.IsDualWeapon(WClass,SecType) )
{
if ( WClass != class'Dualies' && class'stub_Pawn'.static.HasWeaponClass(class'stub_Pawn'.default.SecType, J) )
{
// ItemWeight -= class'stub_Pawn'.default.SecType.default.Weight;
Price *= 0.5f;
class'stub_Pawn'.default.OtherPrice = KFWeapon(J).SellValue;
if ( class'stub_Pawn'.default.OtherPrice == -1 )
{
class'stub_Pawn'.default.OtherPrice = class<KFWeaponPickup>(class'stub_Pawn'.default.SecType.Default.PickupClass).Default.Cost * 0.75;
if ( KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
class'stub_Pawn'.default.OtherPrice *= KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.GetCostScaling(KFPlayerReplicationInfo(PlayerReplicationInfo), SecType.Default.PickupClass);
}
}
}
else if ( class'stub_Pawn'.static.HasDualies(WClass,Inventory) )
return;
// add
Price = int(Price); // Truncuate price.
if ( !CanCarry(ItemWeight) )
{
return;
}
if ( PlayerReplicationInfo.Score < Price )
{
ClientMessage("Error: "$WClass.Name$" is too expensive ("$int(Price)$">"$int(PlayerReplicationInfo.Score)$")");
return; // Not enough CASH.
}
I = Spawn(WClass);
if ( I != none )
{
if ( KFGameType(Level.Game) != none )
KFGameType(Level.Game).WeaponSpawned(I);
KFWeapon(I).UpdateMagCapacity(PlayerReplicationInfo);
KFWeapon(I).FillToInitialAmmo();
KFWeapon(I).SellValue = Price * 0.75;
if (class'stub_Pawn'.default.OtherPrice > 0)
KFWeapon(I).SellValue += class'stub_Pawn'.default.OtherPrice;
I.GiveTo(self);
PlayerReplicationInfo.Score -= Price;
ClientForceChangeWeapon(I);
}
else
ClientMessage("Error: "$WClass.Name$" failed to spawn.");
SetTraderUpdate();
}
static final function bool HasWeaponClass( class<Inventory> IC, optional out Inventory Res )
{
local Inventory I;
for ( I=default.Inventory; I!=None; I=I.default.Inventory )
{
if( I.Class == IC )
{
Res = I;
return true;
}
}
return false;
}
static final function bool IsDualWeapon(class<Weapon> W, optional out class<KFWeapon> SingleType )
{
local int i;
if (W.Default.DemoReplacement != none)
{
SingleType = class<KFWeapon>(W.Default.DemoReplacement);
return true;
}
for( i=(Default.DualMap.Length-1); i>=0; --i )
{
if( W==Default.DualMap[i].Dual )
{
SingleType = Default.DualMap[i].Single;
return true;
}
}
return false;
}
static final function bool HasDualies( class<Weapon> W, Inventory InvList, optional out class<KFWeapon> DualType )
{
local int i;
local Inventory In;
for ( In=InvList; In!=None; In=In.Inventory )
{
if( Weapon(In)!=None && Weapon(In).DemoReplacement==W )
{
DualType = class<KFWeapon>(In.Class);
return true;
}
}
for ( i=(Default.DualMap.Length-1); i>=0; --i )
{
if ( W == Default.DualMap[i].Single )
{
DualType = Default.DualMap[i].Dual;
W = Default.DualMap[i].Dual;
for ( In=InvList; In!=None; In=In.Inventory )
{
if (In.Class == W)
return true;
}
return false;
}
}
return false;
}
function AddDefaultInventory()
{
CreateInventory("KFMod.Knife");
CreateInventory("KFMod.Single");
CreateInventory("KFMod.Frag");
CreateInventory("KFMod.Syringe");
CreateInventory("KFMod.Welder");
}
defaultproperties
{
DualMap[0]=(Single=class'Single',Dual=class'Dualies')
DualMap[1]=(Single=class'Magnum44Pistol',Dual=class'Dual44Magnum')
DualMap[2]=(Single=class'Deagle',Dual=class'DualDeagle')
DualMap[3]=(Single=class'FlareRevolver',Dual=class'DualFlareRevolver')
DualMap[4]=(Single=class'MK23Pistol',Dual=class'DualMK23Pistol')
}