336 lines
9.6 KiB
Ucode
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')
|
|
} |