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

1167 lines
32 KiB
Ucode

//=============================================================================
// KFPawn - Assault
//=============================================================================
class KFHumanPawn extends KFPawn;
//#exec OBJ LOAD FILE=KFCharacters.utx
//#exec OBJ LOAD FILE=KFSoldiers.ukx
var float DrugBonusMovement;
var bool bOnDrugs;
var Emitter Blood;
var Sound BreathingSound;
//var int BreathingTime;
var Sound MiscSound; //So I can get the damn thing to shutup if the players dead.
//var UnderWaterBlur myHitBlur;
var bool bUsingHitBlur;
var float StopBlurTime;
var float BlurFadeOutTime; // Tracks how long we've spend fading out the blur
var(Blur) float StartingBlurFadeOutTime; // How long to spend fading out the blur
var(Blur) float NewSchoolHitBlurIntensity; // How intense to make the new school hit blur when you are hit
var config bool bUseBlurEffect; // Whether or not the blur effect should be used
var float CurrentBlurIntensity; // The Currently used blur intensity
// Jarring
var() float JarrMoveMag; // Magnitude to move the player
var() float JarrMoveRate; // Rate at which the player oscillates
var() float JarrMoveDuration; // scalar duration of the movement
var() float JarrRotateMag; // Magnitude the player 'rolls'
var() float JarrRotateRate; // Rate at which the player oscillates/rolls around
var() float JarrRotateDuration; // scalar duration of the roll
var int SpeedAdjustment; // Give our brave melee players a little bit more under the hood.
var float BaseMeleeIncrease;
var int InventorySpeedModifier; // Modifer to the player's speed based on the weapon they are carrying
var() float HealthSpeedModifier; // The maximum percentage of the default movement speed to reduce speed based on how low the player's health is
var() float WeightSpeedModifier; // The maximum percentage of the default movement speed to reduce speed based on how much weight the player is carrying
var int ScoreCounter; // Once it hits two, reset 3 second score in GRI
var bool bAimingRifle;
var CameraEffect CameraEffectFound;
var () float MaxCarryWeight;
var float CurrentWeight;
var bool bMeBeDoomed;
var int AlphaAmount ; // Amount of Alpha for Cash bonus HUD.
var() Material InjuredOverlay,CriticalOverlay;
var KFPlayerController KFPC;
var () int TorchBatteryLife;
var bool bTorchOn; // HUD var only.
var int TempScore; // temporary score.
var float LastDyingMessageTime;
var float DyingMessageDelay;
/* Should this pawn be allowed to switch Weapons ? */
var bool bLockWeaponSelection;
replication
{
reliable if ( bNetDirty && (Role == Role_Authority) )
bAimingRifle;
reliable if ( bNetDirty && (Role == Role_Authority) && bNetOwner )
CurrentWeight,MaxCarryWeight,AlphaAmount,bTorchOn,TorchBatteryLife,bOnDrugs,
InventorySpeedModifier;
reliable if(RemoteRole == ROLE_AutonomousProxy)
DoHitCamEffects, StopHitCamEffects;
reliable if(Role < ROLE_Authority)
SetAiming,ServerTossCarriedItems;
}
simulated function Setup(xUtil.PlayerRecord rec, optional bool bLoadNow)
{
super.Setup(rec, bLoadNow);
if( class<SoldierSpeciesRobot>(Species) != none )
{
BreathingSound = class'KFDARSoundGroup'.default.BreathingSound;
}
else if( class<AshHardingSpecies>(Species) != none )
{
BreathingSound = class'KFFemaleSoundGroup'.default.BreathingSound;
}
log(BreathingSound);
}
function VeterancyChanged()
{
local Inventory I;
local KFPlayerReplicationInfo KFPRI;
local int MaxAmmo;
MaxCarryWeight = Default.MaxCarryWeight;
KFPRI = KFPlayerReplicationInfo(PlayerReplicationInfo);
if ( KFPRI != none && KFPRI.ClientVeteranSkill != none )
{
MaxCarryWeight += KFPRI.ClientVeteranSkill.Static.AddCarryMaxWeight(KFPRI);
}
if ( CurrentWeight > MaxCarryWeight ) // Now carrying too much, drop something.
{
for ( I = Inventory; I != none; I = I.Inventory )
{
if ( KFWeapon(I) != none && !KFWeapon(I).bKFNeverThrow )
{
I.Velocity = Velocity;
I.DropFrom(Location + VRand() * 10);
if ( CurrentWeight <= MaxCarryWeight )
{
break; // Drop weapons until player is capable of carrying them all.
}
}
}
}
// Make sure nothing is over the Max Ammo amount when changing Veterancy
for ( I = Inventory; I != none; I = I.Inventory )
{
if ( Ammunition(I) != none )
{
MaxAmmo = Ammunition(I).default.MaxAmmo;
if ( KFPRI != none && KFPRI.ClientVeteranSkill != none )
{
MaxAmmo = float(MaxAmmo) * KFPRI.ClientVeteranSkill.static.AddExtraAmmoFor(KFPRI, Ammunition(I).Class);
}
if ( Ammunition(I).AmmoAmount > MaxAmmo )
{
Ammunition(I).AmmoAmount = MaxAmmo;
}
}
}
}
event PreBeginPlay()
{
Super.PreBeginPlay();
SetTimer(1.5,true);
}
// Just changed to pendingWeapon
simulated function ChangedWeapon()
{
if(PendingWeapon != none &&
AllowHoldWeapon(KFWeapon(PendingWeapon)))
{
Super.ChangedWeapon();
// Experience Level relate stuff .
if ( Weapon != none && KFWeapon(Weapon).bSpeedMeUp )
{
// Adjust Melee weapon speed bonuses depending on perk.
BaseMeleeIncrease = default.BaseMeleeIncrease;
if ( KFPlayerReplicationInfo(PlayerReplicationInfo) != none && KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
{
BaseMeleeIncrease += KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.Static.GetMeleeMovementSpeedModifier(KFPlayerReplicationInfo(PlayerReplicationInfo));
}
InventorySpeedModifier = ((default.GroundSpeed * BaseMeleeIncrease) - (KFWeapon(Weapon).Weight * 2));
}
else if ( Weapon == none || !KFWeapon(Weapon).bSpeedMeUp )
{
InventorySpeedModifier = 0;
}
}
else
{
PendingWeapon = none;
}
}
function ServerChangedWeapon(Weapon OldWeapon, Weapon NewWeapon)
{
super.ServerChangedWeapon(OldWeapon,NewWeapon);
// Experience Level relate stuff .
if( Weapon!= none && KFWeapon(Weapon).bSpeedMeUp )
{
// Adjust Melee weapon speed bonuses depending on perk.
BaseMeleeIncrease = default.BaseMeleeIncrease;
if ( KFPlayerReplicationInfo(PlayerReplicationInfo) != none && KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
{
BaseMeleeIncrease += KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.Static.GetMeleeMovementSpeedModifier(KFPlayerReplicationInfo(PlayerReplicationInfo));
}
InventorySpeedModifier = ((default.GroundSpeed * BaseMeleeIncrease) - (KFWeapon(Weapon).Weight * 2));
}
else if (Weapon == none || !KfWeapon(Weapon).bSpeedMeUp)
{
InventorySpeedModifier = 0;
}
}
simulated event ModifyVelocity(float DeltaTime, vector OldVelocity)
{
local float WeightMod, HealthMod;
local float EncumbrancePercentage;
local Inventory Inv;
super.ModifyVelocity(DeltaTime, OldVelocity);
if (Controller != none)
{
// Calculate encumbrance, but cap it to the maxcarryweight so when we use dev weapon cheats we don't move mega slow
EncumbrancePercentage = (FMin(CurrentWeight, MaxCarryWeight)/MaxCarryWeight);
// Calculate the weight modifier to speed
WeightMod = (1.0 - (EncumbrancePercentage * WeightSpeedModifier));
// Calculate the health modifier to speed
HealthMod = ((Health/HealthMax) * HealthSpeedModifier) + (1.0 - HealthSpeedModifier);
// Apply all the modifiers
GroundSpeed = default.GroundSpeed * HealthMod;
GroundSpeed *= WeightMod;
GroundSpeed += InventorySpeedModifier;
if ( KFPlayerReplicationInfo(PlayerReplicationInfo) != none && KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
{
GroundSpeed *= KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.GetMovementSpeedModifier(KFPlayerReplicationInfo(PlayerReplicationInfo), KFGameReplicationInfo(Level.GRI));
}
/* Give the pawn's inventory items a chance to modify his movement speed */
for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory )
{
GroundSpeed *= Inv.GetMovementModifierFor(self);
}
}
}
Simulated function tick(float DeltaTime)
{
local float BlurAmount;
super.Tick(deltaTime);
if (KFPC != none)
{
if (KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo).ThreeSecondScore > 0 && AlphaAmount > 0)
AlphaAmount -=2;
if (AlphaAmount <= 0)
{
KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo).ThreeSecondScore = 0;
ScoreCounter = 0;
}
}
if( IsLocallyControlled() )
{
if( !bUsingHitBlur && BlurFadeOutTime > 0 )
{
BlurFadeOutTime -= deltaTime;
BlurAmount = BlurFadeOutTime/StartingBlurFadeOutTime * CurrentBlurIntensity;
if( BlurFadeOutTime <= 0 )
{
BlurFadeOutTime = 0;
StopHitCamEffects();
}
else
{
if( bUseBlurEffect )
{
if( KFPC == none || !KFPC.PostFX_IsReady() )
{
if( CameraEffectFound != none )
{
UnderWaterBlur(CameraEffectFound).BlurAlpha = Lerp( BlurAmount, 255, UnderWaterBlur(CameraEffectFound).default.BlurAlpha );
}
}
else
{
KFPC.SetBlur(BlurAmount);
}
}
}
}
}
}
function SetAiming(bool IsAiming)
{
bAimingRifle = IsAiming;
}
simulated event HandleWhizSound()
{
local float Intensity;
// Don't play whizz sounds for bots, or from other players
if ( IsHumanControlled() && IsLocallyControlled() )
{
Spawn(class'ROBulletWhiz',,, mWhizSoundLocation);
//log("DistSquared of whiz is "$VSizeSquared(GetBoneCoords(HeadBone).Origin - mWhizSoundLocation));
Intensity = 1.0 - ((FMin(VSizeSquared(GetBoneCoords(HeadBone).Origin - mWhizSoundLocation),3600.0))/3600.0); // 3600 = (60*60) = Radius of bullet whiz cylinder squared
//log("Intensity of whiz is "$Intensity);
AddBlur(0.15, Intensity/2);
}
}
simulated function AddBlur(Float BlurDuration, float Intensity)
{
if( KFPC == none )
{
return;
}
if(!bUsingHitBlur)
{
// If we can't handle the post processing shaders, just do an old style motion blur effect
if( bUseBlurEffect )
{
StartingBlurFadeOutTime = BlurDuration;
BlurFadeOutTime = StartingBlurFadeOutTime;
if( CurrentBlurIntensity < Intensity )
{
CurrentBlurIntensity = Intensity;
}
if( !KFPC.PostFX_IsReady() )
{
if ( CameraEffectFound == none )
{
FindCameraEffect(class 'KFmod.UnderWaterBlur');
}
UnderWaterBlur(CameraEffectFound).BlurAlpha = UnderWaterBlur(CameraEffectFound).default.BlurAlpha;
}
else
{
KFPC.SetBlur(CurrentBlurIntensity);
}
}
}
}
function Timer()
{
//local Actor WallActor;
//local KFBloodSplatter Streak;
//local vector WallHit, WallNormal;
if (BurnDown > 0)
{
LastBurnDamage *= 0.5;
TakeFireDamage(LastBurnDamage, BurnInstigator);
}
else
{
RemoveFlamingEffects();
StopBurnFX();
}
// Flashlight Drain
if ( KFWeapon(Weapon)!=none && KFWeapon(Weapon).FlashLight!=none )
{
// Increment / Decrement battery life
if (KFWeapon(Weapon).FlashLight.bHasLight && TorchBatteryLife > 0)
TorchBatteryLife -= 10;
else if (!KFWeapon(Weapon).FlashLight.bHasLight && TorchBatteryLife < default.TorchBatteryLife)
{
TorchBatteryLife += 20;
if ( TorchBatteryLife > default.TorchBatteryLife )
{
TorchBatteryLife = default.TorchBatteryLife;
}
}
}
else if( TorchBatteryLife<default.TorchBatteryLife )
{
TorchBatteryLife += 20;
if ( TorchBatteryLife > default.TorchBatteryLife )
{
TorchBatteryLife = default.TorchBatteryLife;
}
}
if (Controller != none)
{
if(KFPC != none )
{
bOnDrugs = false;
// Update for the scoreboards.
if (Health <= 0)
{
PlaySound(MiscSound,SLOT_Talk);
return;
}
if ( Health < HealthMax * 0.25 )
{
PlaySound(BreathingSound, SLOT_Talk, ((50-Health)/5)*TransientSoundVolume,,TransientSoundRadius,, false);
// Commenting this streak code out because it doesn't work and spams the log - Ramm
//WallActor = Trace(WallHit, WallNormal, Location - 50 * Velocity, Location, false);
//Streak= spawn(class 'KFMod.KFBloodSplatter',,,vect(0,0,0), Rotation);
//if (Streak != none)
// Streak.SetRotation(Rotator(Velocity));
}
// Accuracy vs. Movement tweakage! - Alex
if (KFWeapon(Weapon) != none)
KFWeapon(Weapon).AccuracyUpdate(vsize(Velocity));
}
}
// TODO: WTF? central here
// Instantly set the animation to arms at sides Idle if we've got no weapon (rather than Pointing an invisible gun!)
if (Weapon != none)
{
if (WeaponAttachment(Weapon.ThirdPersonActor) == none && VSize(Velocity) <= 0)
IdleWeaponAnim = IdleRestAnim;
}
else if (Weapon == none)
IdleWeaponAnim = IdleRestAnim;
}
simulated function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if( Controller!=None && Controller.bGodMode )
return;
if ( KFMonster(InstigatedBy) != none )
{
KFMonster(InstigatedBy).bDamagedAPlayer = true;
}
// Don't allow momentum from a player shooting a player
if( InstigatedBy != none && KFHumanPawn(InstigatedBy) != none )
{
Momentum = vect(0,0,0);
}
Super.TakeDamage(Damage,instigatedBy,hitlocation,momentum,damageType);
//Bloody Overlays
if ((Health-Damage) <= 0.5*HealthMax)
SetOverlayMaterial(InjuredOverlay,0, true);
if ( Role == ROLE_Authority && Level.Game.NumPlayers > 1 && Health < 0.25 * HealthMax && Level.TimeSeconds - LastDyingMessageTime > DyingMessageDelay )
{
// Tell everyone we're dying
PlayerController(Instigator.Controller).Speech('AUTO', 6, "");
LastDyingMessageTime = Level.TimeSeconds;
}
if( Controller==none || PlayerController(Controller)==None )
return;
}
function TakeBileDamage()
{
local vector BileVect;
local int RandBileDamage;
local int actualDamage;
local vector HitMomentum;
RandBileDamage = 2+Rand(3);
Super(XPawn).TakeDamage(RandBileDamage, BileInstigator, Location, vect(0,0,0), LastBileDamagedByType);
healthtoGive-=5;
HitMomentum = vect(0,0,0);
actualDamage = Level.Game.ReduceDamage(RandBileDamage, self, BileInstigator, Location, HitMomentum, LastBileDamagedByType);
if( actualDamage <= 0 )
{
return;
}
//TODO: move this sanity check to DoHitCamEffect?
if(Controller == none || PlayerController(Controller) == None)
return;
if(Controller.bGodMode)
return;
BileVect.X=frand();
BileVect.Y=frand();
BileVect.Z=frand();
if( class<DamTypeBileDeckGun>(LastBileDamagedByType) != none )
{
DoHitCamEffects( BileVect, 0.25, 0.75, 0.5 );
}
else
{
DoHitCamEffects( BileVect, 0.35, 2.0,1.0 );
}
}
// Overridden to support view shake changes
function PlayTakeHit(vector HitLocation, int Damage, class<DamageType> DamageType)
{
local vector direction;
local rotator InvRotation;
local float jarscale;
super.PlayTakeHit( HitLocation, Damage, DamageType );
// for standalone and client
// Cooney
if ( Level.NetMode != NM_DedicatedServer )
{
// Get the approximate direction
// that the hit went into the body
direction = Location - HitLocation;
// No up-down jarring effects since
// I dont have the barrel valocity
direction.Z = 0.0f;
direction = normal(direction);
// We need to rotate the jarring direction
// in screen space so basically the
// exact opposite of the player's pawn's
// rotation.
InvRotation.Yaw = -Rotation.Yaw;
InvRotation.Roll = -Rotation.Roll;
InvRotation.Pitch = -Rotation.Pitch;
direction = direction >> InvRotation;
jarscale = 0.1f + (Damage/10.0f);
if ( jarscale > 1.0f )
{
jarscale = 1.0f;
}
DoHitCamEffects(direction,jarscale,2.0,1.0);
}
}
simulated function DoHitCamEffects(vector HitDirection, float JarrScale, float BlurDuration, float JarDurationScale )
{
local vector localShakeMoveMag;
local vector localShakeMoveRate;
local vector localShakeRotateMag;
local vector localShakeRotateRate;
if( KFPC == none )
{
return;
}
if( bUseBlurEffect )
{
if( !KFPC.PostFX_IsReady() )
{
CurrentBlurIntensity = 1.0;
}
else
{
CurrentBlurIntensity = NewSchoolHitBlurIntensity;
}
AddBlur(BlurDuration,CurrentBlurIntensity);
}
// Shake Moving
//
localShakeMoveMag = HitDirection * JarrMoveMag;
//
localShakeMoveRate.X = JarrMoveRate;
localShakeMoveRate.Y = JarrMoveRate;
localShakeMoveRate.Z = JarrMoveRate;
//
// Unfortunately, the HitDirection
// only transfers maximum offsets to
// the shake offset max. I have to
// check it's sign and move that into
// the rate so it moves the right direction.
if ( HitDirection.X < 0 )
localShakeMoveRate.X *= -1;
if ( HitDirection.Y < 0 )
localShakeMoveRate.Y *= -1;
if ( HitDirection.Z < 0 )
localShakeMoveRate.Z *= -1;
// Shake Rotation
//
localShakeRotateMag.X = JarrRotateMag*-HitDirection.X;
localShakeRotateMag.Z = JarrRotateMag*HitDirection.Y;
//
localShakeRotateRate.X = JarrRotateRate*-HitDirection.X;
localShakeRotateRate.Z = JarrRotateRate*HitDirection.Y;
KFPC.ShakeView(localShakeRotateMag*JarrScale,
localShakeRotateRate*(2.0f-JarrScale),
JarrRotateDuration * JarDurationScale,
localShakeMoveMag*JarrScale,
localShakeMoveRate*(2.0f-JarrScale),
JarrMoveDuration * JarDurationScale);
}
simulated function StopHitCamEffects()
{
CurrentBlurIntensity=0.0;
if( CameraEffectFound != none )
{
RemoveCameraEffect(CameraEffectFound);
}
if( KFPC != none )
{
KFPC.StopViewShaking();
KFPC.SetBlur(0);
}
}
simulated function died(Controller Killer, class<DamageType> damageType, vector HitLocation)
{
StopHitCamEffects();
super.Died(Killer, damageType, HitLocation);
}
simulated function Destroyed()
{
StopHitCamEffects();
Super.Destroyed();
}
simulated function CameraEffect FindCameraEffect(class<CameraEffect> CameraEffectClass)
{
local PlayerController PlayerControllerLocal;
local int i;
PlayerControllerLocal = Level.GetLocalPlayerController();
if ( PlayerControllerLocal != None )
{
for (i = 0; i < PlayerControllerLocal.CameraEffects.Length; i++)
if ( PlayerControllerLocal.CameraEffects[i].Class == CameraEffectClass )
{
CameraEffectFound = PlayerControllerLocal.CameraEffects[i];
break;
}
if ( CameraEffectFound == None )
CameraEffectFound = CameraEffect(Level.ObjectPool.AllocateObject(CameraEffectClass));
if ( CameraEffectFound != None )
PlayerControllerLocal.AddCameraEffect(CameraEffectFound);
}
return CameraEffectFound;
}
//=============================================================================
// RemoveCameraEffect
//
// Removes one reference to the CameraEffect from the CameraEffects array. If
// there are any more references to the same CameraEffect object, they remain
// there. The CameraEffect will be put back in the ObjectPool if no other
// references to it are left in the CameraEffects array.
//=============================================================================
simulated function RemoveCameraEffect(CameraEffect CameraEffect)
{
local PlayerController PlayerControllerLocal;
local int i;
PlayerControllerLocal = Level.GetLocalPlayerController();
if ( PlayerControllerLocal != None ) {
PlayerControllerLocal.RemoveCameraEffect(CameraEffect);
for (i = 0; i < PlayerControllerLocal.CameraEffects.Length; i++)
if ( PlayerControllerLocal.CameraEffects[i] == CameraEffect ) {
log(CameraEffect@"still in CameraEffects array");
return;
}
log("Freeing"@CameraEffect);
Level.ObjectPool.FreeObject(CameraEffect);
CameraEffectFound = none;
}
}
simulated function PrevWeapon()
{
if ( Level.Pauser != None )
return;
if ( Weapon == None && Controller != None )
{
Controller.SwitchToBestWeapon();
return;
}
if ( PendingWeapon != None )
{
if ( PendingWeapon.bForceSwitch )
return;
PendingWeapon = Inventory.PrevWeapon(None, PendingWeapon);
}
else
{
PendingWeapon = Inventory.PrevWeapon(None, Weapon);
}
if ( PendingWeapon != None )
Weapon.PutDown();
}
/* NextWeapon()
- switch to next inventory group weapon
*/
simulated function NextWeapon()
{
if ( Level.Pauser != None )
return;
if ( Weapon == None && Controller != None )
{
Controller.SwitchToBestWeapon();
return;
}
if ( PendingWeapon != None )
{
if ( PendingWeapon.bForceSwitch )
return;
PendingWeapon = Inventory.NextWeapon(None, PendingWeapon);
}
else
{
PendingWeapon = Inventory.NextWeapon(None, Weapon);
}
if ( PendingWeapon != None && Weapon != none )
Weapon.PutDown();
}
//This is a terribly ugly hack which allows us to silently give
//weapons to pawns in the case of buy menu consumables
function SilentGiveWeapon(string aClassName )
{
local class<Weapon> WeaponClass;
local Weapon NewWeapon;
WeaponClass = class<Weapon>(DynamicLoadObject(aClassName, class'Class'));
if( FindInventoryType(WeaponClass) != None )
return;
newWeapon = Spawn(WeaponClass);
if( newWeapon != None && KFWeapon(newWeapon) != None)
KFWeapon(newWeapon).SilentGiveTo(self);
else if(newWeapon != none)
newWeapon.GiveTo(self);
}
function bool AddInventory( inventory NewItem )
{
if( !super.AddInventory(NewItem) )
return false;
if( KFWeapon(NewItem) != none )
{
CurrentWeight += KFWeapon(NewItem).Weight;
}
return true;
}
// Remove Item from this pawn's inventory, if it exists.
function DeleteInventory( inventory Item )
{
local Inventory I;
local bool bFoundItem;
if ( Role != ROLE_Authority )
{
return;
}
for ( I = Inventory; I != none; I = I.Inventory )
{
if ( I == Item )
{
bFoundItem = true;
}
}
if ( bFoundItem )
{
if ( KFWeapon(Item) != none )
{
CurrentWeight -= KFWeapon(Item).Weight;
}
}
super.DeleteInventory(Item);
}
function Drugs()
{
// Still not sure what to do with this.
// It's some sort of drug heightened adrenal state where the player can run faster etc...
// Amusingly, it's incremental. So each "hit" (call of this function :P) will send you into
// a further....enhanced state for the duration of the drug's life (30 seconds max).
// call it like so :
// bOnDrugs = true;
// Drugs();
if(bOnDrugs)
{
// Log("You're on Some Drugs");
DrugBonusMovement = 150;
Groundspeed +=DrugBonusMovement;
PlaySound(BreathingSound, SLOT_Talk, TransientSoundVolume,,TransientSoundRadius,, false);
Weapon.StartBerserk();
KFPC.ShakeView(vect(30,-30,30),vect(200,-300,200),30,vect(-30,30,30),vect(300,-200,200),30);
}
}
function AddDefaultInventory()
{
local int i;
// Add this code in if you want to force bots to spawn without a weapon
/*if( !IsHumanControlled() )
{
return;
}*/
if ( KFSPGameType(Level.Game) != none )
{
Level.Game.AddGameSpecificInventory(self);
if ( Inventory != none )
Inventory.OwnerEvent('LoadOut');
return;
}
if ( IsLocallyControlled() )
{
for ( i = 0; i < 16; i++ )
if ( RequiredEquipment[i] != "" )
CreateInventory(RequiredEquipment[i]);
if ( KFPlayerReplicationInfo(PlayerReplicationInfo) != none && KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
{
KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.AddDefaultInventory(KFPlayerReplicationInfo(PlayerReplicationInfo), self);
}
for ( i = 0; i < 16; i++ )
if ( (SelectedEquipment[i] == 1) && (OptionalEquipment[i] != "") )
CreateInventory(OptionalEquipment[i]);
Level.Game.AddGameSpecificInventory(self);
}
else
{
Level.Game.AddGameSpecificInventory(self);
for ( i = 15; i >= 0; i-- )
if ( (SelectedEquipment[i] == 1) && (OptionalEquipment[i] != "") )
CreateInventory(OptionalEquipment[i]);
if ( KFPlayerReplicationInfo(PlayerReplicationInfo) != none && KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
{
KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.AddDefaultInventory(KFPlayerReplicationInfo(PlayerReplicationInfo), self);
}
for ( i = 15; i >= 0; i-- )
if ( RequiredEquipment[i] != "" )
CreateInventory(RequiredEquipment[i]);
}
// HACK FIXME
if ( Inventory != None )
Inventory.OwnerEvent('LoadOut');
Controller.ClientSwitchToBestWeapon();
}
function CreateInventoryVeterancy(string InventoryClassName, float SellValue)
{
local Inventory Inv;
local class<Inventory> InventoryClass;
InventoryClass = Level.Game.BaseMutator.GetInventoryClass(InventoryClassName);
if( (InventoryClass!=None) && (FindInventoryType(InventoryClass)==None) )
{
Inv = Spawn(InventoryClass);
if( Inv != none )
{
Inv.GiveTo(self);
if ( Inv != none )
Inv.PickupFunction(self);
if ( KFWeapon(Inv) != none )
{
KFWeapon(Inv).SellValue = SellValue;
}
if ( KFGameType(Level.Game) != none )
{
KFGameType(Level.Game).WeaponSpawned(Inv);
}
}
}
}
function bool CanCarry( float Weight )
{
if(Weight <= 0)
{
return true;
}
return ((CurrentWeight+Weight)<=MaxCarryWeight);
}
function bool PerformDodge(eDoubleClickDir DoubleClickMove, vector Dir, vector Cross)
{
Return False;
}
function bool ShowStalkers()
{
if ( KFPlayerReplicationInfo(PlayerReplicationInfo) != none && KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
{
return KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.Static.ShowStalkers(KFPlayerReplicationInfo(PlayerReplicationInfo));
}
return false;
}
function float GetStalkerViewDistanceMulti()
{
if ( KFPlayerReplicationInfo(PlayerReplicationInfo) != none && KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none )
{
return KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.Static.GetStalkerViewDistanceMulti(KFPlayerReplicationInfo(PlayerReplicationInfo));
}
return 0.0;
}
/* ============ AI - Monster threat assessment functionality ==============================
Clamped from -1 to 100, where 100 is the most threatening ==================================
===========================================================================================*/
function float AssessThreatTo(KFMonsterController Monster, optional bool CheckDistance)
{
if(Monster == none || Monster.Pawn == none)
{
return -1.f;
}
if(CheckDistance)
{
// 5000 == 100m, gives us a nice range of values
return 5000.f / VSize(Monster.Pawn.Location - Location);
}
return -1.f;
}
/* Returns true if this pawn is able to hold a weapon of the supplied type */
simulated function bool AllowHoldWeapon(Weapon InWeapon)
{
return true;
}
// The player wants to switch to weapon group number F.
simulated function SwitchWeapon(byte F)
{
local Weapon DesiredWeap;
local bool AllowSwitch;
DesiredWeap = Weapon.Inventory.WeaponChange(F, false);
if(DesiredWeap == none )
{
DesiredWeap = Inventory.WeaponChange(F, true);
}
if(DesiredWeap != none)
{
AllowSwitch = AllowHoldWeapon(DesiredWeap);
}
if(AllowSwitch)
{
Super.SwitchWeapon(F);
}
}
function bool AllowWeaponSwitching()
{
return !bLockWeaponSelection ;
}
/* @todo - unique bools ? */
function bool AllowGrenadeTossing()
{
return !bLockWeaponSelection ;
}
/* @todo - unique bools ? */
function bool AllowQuickHealing()
{
return !bLockWeaponSelection;
}
simulated exec function QuickHeal()
{
if(AllowQuickHealing())
{
Super.QuickHeal();
}
}
simulated function TossCarriedItems()
{
if(Role < Role_Authority)
{
ServerTossCarriedItems();
}
else
{
InternalTossCarriedItems();
}
}
function ServerTossCarriedItems()
{
InternalTossCarriedItems();
}
simulated function InternalTossCarriedItems()
{
local Inventory Inv;
local Vector X,Y,Z;
GetAxes(Rotation,X,Y,Z);
for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory )
{
if(Inv.IsThrowable())
{
Inv.Velocity = Vector(Rotation)* 250.f ;
Inv.DropFrom(Location + 0.8 * CollisionRadius * X - 0.5 * CollisionRadius * Y);
}
}
}
simulated function bool IsCarryingThrowableInventory()
{
local Inventory Inv;
for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory )
{
if(Inv.IsThrowable())
{
return true;
}
}
return false;
}
function ThrowGrenade()
{
if(AllowGrenadeTossing())
{
Super.ThrowGrenade();
}
}
// toss out a weapon
function TossWeapon(Vector TossVel)
{
TossCarriedItems();
Super.TossWeapon(TossVel);
}
defaultproperties
{
BreathingSound=Sound'KFPlayerSound.Malebreath'
BaseMeleeIncrease=0.200000
MaxCarryWeight=15.000000
InjuredOverlay=Shader'KFCharacters.BloodiedShader'
CriticalOverlay=Shader'KFCharacters.BloodiedShader'
bCanDodgeDoubleJump=False
MultiJumpRemaining=0
MaxMultiJump=0
RequiredEquipment(0)="KFMod.Knife" // Knife
RequiredEquipment(1)="KFMod.Single"// Single
RequiredEquipment(2)="KFMod.Frag"
RequiredEquipment(3)="KFMod.Syringe" // Syringe
RequiredEquipment(4)="KFMod.Welder" // Welder
//RequiredEquipment(5)="KFMod.FakeSyringe" // Welder
bCanDoubleJump=False
bCanWallDodge=False
bUseBlurEffect=true
AccelRate=1000.0
AirControl=+0.15
GroundSpeed=200.0
WaterSpeed=200.000000
AirSpeed=230.000000
JumpZ=325.000000
MaxFallSpeed=600.000000
BaseEyeHeight=44.0
EyeHeight=44.0
CrouchHeight=34.000000
ControllerClass=Class'KFMod.KFInvasionBot'
CrouchTurnRightAnim="CrouchR"
CrouchTurnLeftAnim="CrouchL"
bDramaticLighting=False
Mesh=SkeletalMesh'KF_Soldier_Trip.British_Soldier1'//SkeletalMesh'KFSoldiers.Soldier'
Skins(0)=Combiner'KF_Soldier_Trip_T.Uniforms.brit_soldier_I_cmb'//Texture'KFCharacters.DavinSkin'
//Skins(1)=Shader'KFCharacters.GasMaskShader'
CollisionHeight=50.000000
TorchBatteryLife=500
AmbientGlow=0
TurnRightAnim="TurnR"
TurnLeftAnim="TurnL"
StartingBlurFadeOutTime=0.5
NewSchoolHitBlurIntensity=0.8
HealthSpeedModifier=0.3
WeightSpeedModifier=0.13
DyingMessageDelay=10.0
// Jarring settings
JarrMoveMag=50.0
JarrMoveRate=200.0
JarrMoveDuration=3.0
JarrRotateMag=1000.0
JarrRotateRate=10000.0
JarrRotateDuration=4.0
HeadRadius=+7.0
HeadHeight=2.0
}