NicePack/sources/NiceHumanPawn.uc

905 lines
35 KiB
Ucode

class NiceHumanPawn extends ScrnHumanPawn
dependson(NiceWeapon);
var bool bReactiveArmorUsed;
var float maniacTimeout;
var float stationaryTime;
var float forcedZedTimeCountDown;
var bool bGotFreeJacket;
var float lastHMGShieldUpdateTime;
var int hmgShieldLevel;
var ScrnHUD scrnHUDInstance;
// Position value means it's a count down for how much invincibility is left,
// Negative value is for counting down a cool-down after a failed head-shot with a melee weapon
var float invincibilityTimer;
var int safeMeleeMisses;
var float ffScale;
var float medicAdrenaliteTime;
var float regenTime;
var bool bZedTimeInvincible;
var float nextFreezeTime;
enum ECalibrationState{
// Calibration isn't available due to lack of ability
CALSTATE_NOABILITY,
CALSTATE_ACTIVE,
CALSTATE_FINISHED
};
var float gunslingerTimer;
var ECalibrationState currentCalibrationState;
var int calibrationScore;
var int calibrationHits, calibrationTotalShots;
var float calibrationRemainingTime;
var array<NiceMonster> calibrateUsedZeds;
var int nicePrevPerkLevel;
var class<NiceVeterancyTypes> nicePrevPerkClass;
struct WeaponTimePair{
var NiceWeapon niceWeap;
var float reloadTime;
};
var array<WeaponTimePair> holsteredReloadList;
var float holsteredReloadCountDown;
var const float defaultInvincibilityDuration;
struct InvincExtentions{
var NiceMonster zed;
var bool hadMiss;
var int extentionsDone;
};
var array<InvincExtentions> zedInvExtList;
var int headshotStack;
var float bruteTimer;
var float quadDamageRemaining;
replication{
reliable if(Role == ROLE_Authority)
headshotStack, hmgShieldLevel, forcedZedTimeCountDown, maniacTimeout, invincibilityTimer, safeMeleeMisses, ffScale,
currentCalibrationState, calibrationScore, gunslingerTimer, quadDamageRemaining;
reliable if(Role == ROLE_Authority)
ClientChangeWeapon;
reliable if(Role < ROLE_AUTHORITY)
ServerUpdateCalibration, ServerCooldownAbility;
}
simulated function bool IsZedExtentionsRecorded(NiceMonster niceZed){
local int i;
for(i = 0;i < zedInvExtList.length;i ++)
if(zedInvExtList[i].zed == niceZed)
return true;
return false;
}
// TODO remove this Scrn func
function ReplaceRequiredEquipment()
{
RequiredEquipment[0] = string(class'NiceMachete');
RequiredEquipment[1] = string(class'Nice9mmPlus');
RequiredEquipment[2] = string(class'ScrnFrag');
RequiredEquipment[3] = string(class'ScrnSyringe');
RequiredEquipment[4] = string(class'KFMod.Welder');
}
simulated function int CalculateCalibrationScore(){
local float accuracy;
accuracy = (float(calibrationHits)) / (float(calibrationTotalShots));
if(calibrationTotalShots <= 0)
return 3;
// Very low accuracy (<60%) or not enough shots (<2) - 1 star
if(accuracy < 0.6)
return 1;
// Here we definitely have at least 60% accuracy and 2 shots.
// Low accuracy (<80%) or not enough shots (<5) - 2 stars.
if(accuracy < 0.8)
return 2;
// Here we definitely have at least 80% accuracy and 5 shots.
// If amount of shots is below 7 - it's 3 stars at most.
if(calibrationTotalShots < 7)
return 3;
// Here we definitely have at least 80% accuracy and 7 shots.
// Unless accuracy is 100% and player made 10 shots - it's 4 stars.
if(accuracy < 1.0 || calibrationTotalShots < 10)
return 4;
// Here we definitely have 100% accuracy and at least 10 shots.
// 5 stars.
return 5;
}
function ServerUpdateCalibration(bool isHit, NiceMonster targetMonster){
local int i;
if(isHit){
for(i = 0;i < calibrateUsedZeds.length;i ++)
if(calibrateUsedZeds[i] == targetMonster)
return;
calibrationHits += 1;
}
calibrationTotalShots += 1;
calibrateUsedZeds[calibrateUsedZeds.length] = targetMonster;
}
simulated function int GetZedExtentionsIndex(NiceMonster niceZed){
local int i;
local int foundIndex;
local InvincExtentions newRecord;
local array<InvincExtentions> newList;
if(niceZed == none || niceZed.health <= 0)
return -1;
foundIndex = -1;
for(i = 0;i < zedInvExtList.Length;i ++)
if(zedInvExtList[i].zed != none && zedInvExtList[i].zed.health > 0){
newList[newList.Length] = zedInvExtList[i];
if(zedInvExtList[i].zed == niceZed)
foundIndex = newList.Length - 1;
}
if(foundIndex < 0){
foundIndex = newList.Length;
newRecord.zed = niceZed;
newList[foundIndex] = newRecord;
}
zedInvExtList = newList;
return foundIndex;
}
simulated function bool TryExtendingInv(NiceMonster niceZed,
bool meleeAttempt, bool wasHeadshot){
local class<NiceVeterancyTypes> niceVet;
local int zedExtIndex;
local bool success;
if(niceZed == none) return false;
niceVet = class'NiceVeterancyTypes'.static.
GetVeterancy(PlayerReplicationInfo);
if(niceVet == none)
return false;
if (niceVet == class'NiceVetEnforcer')
return false;
zedExtIndex = GetZedExtentionsIndex(niceZed);
if(zedExtIndex >= 0 && !wasHeadshot)
zedInvExtList[zedExtIndex].hadMiss = true;
if(zedExtIndex >= 0){
success = zedInvExtList[zedExtIndex].extentionsDone
<= niceVet.static.GetInvincibilityExtentions(KFPRI);
success = success && !zedInvExtList[zedExtIndex].hadMiss;
}
else
success = wasHeadshot;
if(invincibilityTimer < 0)
success = false;
if(success){
if(zedExtIndex >= 0)
zedInvExtList[zedExtIndex].extentionsDone ++;
invincibilityTimer = niceVet.static.GetInvincibilityDuration(KFPRI);
safeMeleeMisses = niceVet.static.GetInvincibilitySafeMisses(KFPRI);
return true;
}
if(wasHeadshot)
return false;
if(meleeAttempt){
safeMeleeMisses --;
if(safeMeleeMisses < 0)
ResetMeleeInvincibility();
return false;
}
if(niceVet.static.hasSkill( NicePlayerController(controller),
class'NiceSkillZerkGunzerker')){
invincibilityTimer = class'NiceSkillZerkGunzerker'.default.cooldown;
return false;
}
}
simulated function int FindInHolsteredList(NiceWeapon niceWeap){
local int i;
for(i = 0;i < holsteredReloadList.Length;i ++)
if(holsteredReloadList[i].niceWeap == niceWeap)
return i;
return -1;
}
simulated function ProgressHeadshotStack(bool bIncrease, int minStack, int maxStack, int maxSoftLimit){
if(bIncrease && headshotStack < maxStack)
headshotStack ++;
if(!bIncrease && headshotStack > minStack){
if(headshotStack > maxSoftLimit)
headshotStack = maxSoftLimit;
else
headshotStack --;
}
headshotStack = Max(minStack, headshotStack);
headshotStack = Min(maxStack, headshotStack);
}
simulated function int GetHeadshotStack(int minStack, int maxStack){
headshotStack = Max(minStack, headshotStack);
headshotStack = Min(maxStack, headshotStack);
return headshotStack;
}
simulated function int GetTimeDilationStage(float dilation){
if(dilation <= 0.1)
return 0;
else if(dilation < 1.1)
return 1;
else
return 2;
}
simulated function ResetMeleeInvincibility(){
invincibilityTimer = 0.0;
safeMeleeMisses = 0;
ApplyWeaponStats(weapon);
}
function ServerCooldownAbility(string abilityID){
local int index;
local NicePlayerController nicePlayer;
nicePlayer = NicePlayerController(controller);
if(nicePlayer == none || nicePlayer.abilityManager == none)
return;
index = nicePlayer.abilityManager.GetAbilityIndex(abilityID);
if(index >= 0)
nicePlayer.abilityManager.SetAbilityState(index, ASTATE_COOLDOWN);
}
simulated function Tick(float deltaTime)
{
local int index;
local Inventory Item;
local NiceMonster niceZed;
local NiceWeapon niceWeap;
local WeaponTimePair newPair;
local array<WeaponTimePair> newWTPList;
local NicePlayerController nicePlayer;
nicePlayer = NicePlayerController(Controller);
if (Role == Role_AUTHORITY)
{
// Brutal carnage
if (bruteTimer > 0)
{
bruteTimer -= deltaTime;
if (bruteTimer <= 0)
{
if(nicePlayer != none && nicePlayer.abilityManager != none)
{
nicePlayer.abilityManager.SetAbilityState(1, ASTATE_COOLDOWN);
}
}
}
// Ice giant NiceSkillEnforcerZEDIceGiant
if( nicePlayer != none && nicePlayer.IsZedTimeActive()
&& nextFreezeTime < level.timeSeconds
&& class'NiceVeterancyTypes'.static.hasSkill(
nicePlayer, class'NiceSkillEnforcerZEDIceGiant'))
{
nextFreezeTime =
level.timeSeconds + class'NiceCryoNade'.default.freezeRate;
foreach CollidingActors(
class 'NiceMonster', niceZed,
class'NiceCryoNade'.default.damageRadius,
location)
{
if(niceZed.Health <= 0) {
continue;
}
niceZed.TakeDamage(
class'NiceCryoNade'.default.damage,
self,
niceZed.location,
vect(0,0,0),
class'NiceCryoNade'.default.myDamageType);
}
}
// Calibration
if( currentCalibrationState == CALSTATE_ACTIVE
&& calibrationRemainingTime > 0.0){
calibrationScore = CalculateCalibrationScore();
calibrationRemainingTime -= deltaTime;
if(calibrationRemainingTime <= 0 || calibrationScore == 5){
currentCalibrationState = CALSTATE_FINISHED;
calibrateUsedZeds.length = 0;
if(nicePlayer != none && nicePlayer.abilityManager != none)
nicePlayer.abilityManager.SetAbilityState(0, ASTATE_COOLDOWN);
}
}
// Gunslinger
if( gunslingerTimer > 0
&& nicePlayer != none && nicePlayer.abilityManager != none){
gunslingerTimer -= deltaTime;
if(gunslingerTimer <= 0)
nicePlayer.abilityManager.SetAbilityState(1, ASTATE_COOLDOWN);
}
// Regen
if(class'NiceVeterancyTypes'.static.hasSkill(NicePlayerController(Controller), class'NiceSkillCommandoRegeneration')){
if(health < healthMax)
regenTime += deltaTime;
while(regenTime > class'NiceSkillCommandoRegeneration'.default.regenFrequency){
if(health < healthMax)
health += 1;
else
regenTime = 0.0;
regenTime -= class'NiceSkillCommandoRegeneration'.default.regenFrequency;
}
}
// Update adrenaline
medicAdrenaliteTime -= deltaTime;
// This needs updating
if(Level.Game != none)
ffScale = TeamGame(Level.Game).FriendlyFireScale;
else
ffScale = 0;
// Manage melee-invincibility
if(invincibilityTimer < 0){
invincibilityTimer += deltaTime;
if(invincibilityTimer > 0)
ResetMeleeInvincibility();
}
if(invincibilityTimer > 0){
invincibilityTimer -= deltaTime;
if(invincibilityTimer < 0)
ResetMeleeInvincibility();
}
// Manage demo's 'Maniac' skill
maniacTimeout -= deltaTime;
}
super.Tick(deltaTime);
// Restore icons
if(Role < Role_AUTHORITY){
if(scrnHUDInstance == none && nicePlayer != none)
scrnHUDInstance = ScrnHUD(nicePlayer.myHUD);
if(scrnHUDInstance != none && NiceWeapon(weapon) == none){
scrnHUDInstance.ClipsIcon.WidgetTexture = Texture'KillingFloorHUD.HUD.Hud_Ammo_Clip';
scrnHUDInstance.BulletsInClipIcon.WidgetTexture = Texture'KillingFloorHUD.HUD.Hud_Bullets';
scrnHUDInstance.SecondaryClipsIcon.WidgetTexture = Texture'KillingFloor2HUD.HUD.Hud_M79';
}
}
// Update stationary time
if(bIsCrouched && VSize(Velocity) <= 0.0)
stationaryTime += deltaTime;
else
stationaryTime = 0.0;
// Update zed countdown time
if(forcedZedTimeCountDown > 0)
forcedZedTimeCountDown -= deltaTime;
else
forcedZedTimeCountDown = 0.0;
if(!class'NiceVeterancyTypes'.static.hasSkill(NicePlayerController(Controller), class'NiceSkillEnforcerMultitasker'))
return;
// Auto-reload holstered weapons
holsteredReloadCountDown -= deltaTime;
if(holsteredReloadCountDown <= 0.0){
// Progress current list
for(Item = Inventory; Item != none; Item = Item.Inventory){
niceWeap = NiceWeapon(Item);
if(niceWeap == none || niceWeap == weapon || niceWeap.IsMagazineFull())
continue;
index = FindInHolsteredList(niceWeap);
if(index >= 0){
// Detract time
holsteredReloadList[index].reloadTime -=
0.25 / class'NiceSkillEnforcerMultitasker'.default.reloadSlowDown;
// Add ammo if time is up
if(holsteredReloadList[index].reloadTime < 0.0)
niceWeap.ClientReloadAmmo();
}
}
// Make new list
for(Item = Inventory; Item != none; Item = Item.Inventory){
niceWeap = NiceWeapon(Item);
if(niceWeap == none)
continue;
// Reset holstered completion timer
if(niceWeap == weapon || niceWeap.IsMagazineFull()){
niceWeap.holsteredCompletition = 0.0;
continue;
}
// Update list
index = FindInHolsteredList(niceWeap);
if(index < 0 || holsteredReloadList[index].reloadTime <= 0.0){
newPair.niceWeap = niceWeap;
newPair.reloadTime = niceWeap.TimeUntillReload();
newWTPList[newWTPList.Length] = newPair;
}
else
newWTPList[newWTPList.Length] = holsteredReloadList[index];
// Update holstered completion timer
niceWeap.holsteredCompletition = newWTPList[newWTPList.Length - 1].reloadTime / niceWeap.TimeUntillReload();
niceWeap.holsteredCompletition = 1.0 - niceWeap.holsteredCompletition;
}
holsteredReloadList = newWTPList;
holsteredReloadCountDown = 0.25;
}
}
function ServerBuyWeapon(class<Weapon> WClass, float ItemWeight){
local Inventory I;
local NiceSingle nicePistol;
local class<NiceWeaponPickup> WP;
local float Price, Weight, SellValue;
nicePistol = NiceSingle(FindInventoryType(WClass));
if(nicePistol != none && nicePistol.class != WClass)
nicePistol = none;
if((nicePistol != none && nicePistol.bIsDual))
return;
if(nicePistol == none)
super.ServerBuyWeapon(WClass, ItemWeight);
else{
if(!CanBuyNow() || class<NiceWeapon>(WClass) == none)
return;
WP = class<NiceWeaponPickup>(WClass.Default.PickupClass);
if(WP == none)
return;
if(PerkLink == none)
PerkLink = FindStats();
if(PerkLink != none && !PerkLink.CanBuyPickup(WP))
return;
Price = WP.Default.Cost;
if(KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none){
Price *= KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.GetCostScaling(KFPlayerReplicationInfo(PlayerReplicationInfo), WP);
if(class'ScrnBalance'.default.Mut.bBuyPerkedWeaponsOnly
&& WP.default.CorrespondingPerkIndex != 7
&& WP.default.CorrespondingPerkIndex != KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.default.PerkIndex )
return;
}
SellValue = Price * 0.75;
Price = int(Price);
Weight = Class<KFWeapon>(WClass).default.Weight;
if(nicePistol.default.DualClass != none)
Weight = nicePistol.default.DualClass.default.Weight - Weight;
if((Weight > 0 && !CanCarry(Weight)) || PlayerReplicationInfo.Score < Price)
return;
I = Spawn(WClass, self);
if(I != none){
if(KFGameType(Level.Game) != none)
KFGameType(Level.Game).WeaponSpawned(I);
KFWeapon(I).UpdateMagCapacity(PlayerReplicationInfo);
KFWeapon(I).SellValue = SellValue;
I.GiveTo(self);
PlayerReplicationInfo.Score -= Price;
UsedStartCash(Price);
}
else
ClientMessage("Error: Weapon failed to spawn.");
SetTraderUpdate();
}
}
function ServerSellWeapon(class<Weapon> WClass){
local NiceSingle nicePistol;
local NiceDualies niceDual;
nicePistol = NiceSingle(FindInventoryType(WClass));
niceDual = NiceDualies(FindInventoryType(WClass));
if(niceDual != none && niceDual.class != WClass)
niceDual = none;
if(niceDual == none){
// If this a single pistol that is part of dual pistol weapon - double the cost, because it will be cut back by parent 'ServerSellWeapon'
if(nicePistol != none && nicePistol.bIsDual)
nicePistol.SellValue *= 2;
super.ServerSellWeapon(WClass);
}
else{
nicePistol = niceDual.ServerSwitchToSingle();
if(nicePistol == none)
return;
else{
nicePistol.RemoveDual(CurrentWeight);
nicePistol.SellValue *= 0.5;
PlayerReplicationInfo.Score += nicePistol.SellValue;
SetTraderUpdate();
}
}
}
// NICETODO: do we even need this one?
simulated function ClientChangeWeapon(NiceWeapon newWeap){
weapon = newWeap;
PendingWeapon = newWeap;
if(newWeap != none){
newWeap.ClientState = WS_Hidden;
ChangedWeapon();
}
PendingWeapon = none;
}
// Validate that client is not hacking.
function bool CanBuyNow()
{
local NiceGameType NiceGT;
NiceGT = NiceGameType(Level.Game);
if (NicePlayerController(Controller) == none)
return false;
if (NiceGT != none && NiceGT.NicePackMutator != none
&& NiceGT.NicePackMutator.bIsPreGame)
return true;
// skip Scrn code!
return super(KFPawn).CanBuyNow();
}
// Overridden to not modify dual pistols' weapon group
function bool AddInventory(inventory NewItem){
local KFWeapon weap;
local bool GroupChanged;
weap = KFWeapon(NewItem);
if(weap != none){
if(Dualies(weap) != none){
if((DualDeagle(weap) != none || Dual44Magnum(weap) != none || DualMK23Pistol(weap) != none)
&& weap.InventoryGroup != 4 ) {
if(KFPRI != none &&
ClassIsChildOf(KFPRI.ClientVeteranSkill, class'ScrnVetGunslinger'))
weap.InventoryGroup = 3;
else
weap.InventoryGroup = 2;
GroupChanged = true;
}
}
else if(weap.class == class'Single'){
weap.bKFNeverThrow = false;
}
weap.bIsTier3Weapon = true;
}
if(GroupChanged)
ClientSetInventoryGroup(NewItem.class, NewItem.InventoryGroup);
if(super(SRHumanPawn).AddInventory(NewItem)){
if(weap != none && weap.bTorchEnabled)
AddToFlashlightArray(weap.class);
return true;
}
return false;
}
simulated function CookGrenade(){
local ScrnFrag aFrag;
local NiceWeapon niceWeap;
niceWeap = NiceWeapon(Weapon);
if(niceWeap != none)
niceWeap.ClientForceInterruptReload(CANCEL_COOKEDNADE);
if(secondaryItem != none)
return;
if(scrnPerk == none || !scrnPerk.static.CanCookNade(KFPRI, Weapon))
return;
aFrag = ScrnFrag(FindPlayerGrenade());
if(aFrag == none)
return;
if( !aFrag.HasAmmo() || bThrowingNade
|| aFrag.bCooking || aFrag.bThrowingCooked
|| level.timeSeconds - aFrag.cookExplodeTimer <= 0.1)
return;
if( niceWeap == none
|| (niceWeap.bIsReloading && !niceWeap.InterruptReload()))
return;
aFrag.CookNade();
niceWeap.ClientGrenadeState = GN_TempDown;
niceWeap.PutDown();
}
simulated function ThrowGrenade()
{
local NiceWeapon niceWeap;
niceWeap = NiceWeapon(Weapon);
if(niceWeap != none)
niceWeap.ClientForceInterruptReload(CANCEL_NADE);
if(bThrowingNade || SecondaryItem != none)
return;
if(niceWeap == none || (niceWeap.bIsReloading && !niceWeap.InterruptReload()))
{
super.ThrowGrenade();
return;
}
if(playerGrenade == none)
playerGrenade = FindPlayerGrenade();
if(playerGrenade != none && playerGrenade.HasAmmo()){
niceWeap.clientGrenadeState = GN_TempDown;
niceWeap.PutDown();
}
}
simulated function HandleNadeThrowAnim()
{
if(NiceM14EBRBattleRifle(Weapon) != none || NiceMaulerRifle(Weapon) != none)
SetAnimAction('Frag_M14');
else if(NiceWinchester(Weapon) != none)
SetAnimAction('Frag_Winchester');
else if(Crossbow(Weapon) != none)
SetAnimAction('Frag_Crossbow');
else if(NiceM99SniperRifle(Weapon) != none)
SetAnimAction('Frag_M4203');
else if(NiceAK47AssaultRifle(Weapon) != none)
SetAnimAction('Frag_AK47');
else if(NiceBullpup(Weapon) != none || NiceNailGun(Weapon) != none)
SetAnimAction('Frag_Bullpup');
else if(NiceBoomStick(Weapon) != none)
SetAnimAction('Frag_HuntingShotgun');
else if(NiceShotgun(Weapon) != none || NiceBenelliShotgun(Weapon) != none || NiceTrenchgun(Weapon) != none)
SetAnimAction('Frag_Shotgun');
else if(NiceSCARMK17AssaultRifle(Weapon) != none)
SetAnimAction('Frag_SCAR');
else if(NiceAA12AutoShotgun(Weapon) != none || NiceFNFAL_ACOG_AssaultRifle(Weapon) != none || NiceSPAutoShotgun(Weapon) != none)
SetAnimAction('Frag_AA12');
else if(NiceM4AssaultRifle(Weapon) != none || NiceMKb42AssaultRifle(Weapon) != none)
SetAnimAction('Frag_M4');
else if(NiceThompsonDrumSMG(Weapon) != none)
SetAnimAction('Frag_IJC_spThompson_Drum');
Super.HandleNadeThrowAnim();
}
// Remove blur for sharpshooter with a right skill
function bool ShouldBlur(){
local class<NiceVeterancyTypes> niceVet;
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(PlayerReplicationInfo);
if(niceVet != none && niceVet.static.hasSkill(NicePlayerController(Controller), class'NiceSkillEnforcerUnstoppable'))
return false;
return true;
}
simulated function AddBlur(Float BlurDuration, float Intensity){
if(shouldBlur())
Super.AddBlur(BlurDuration, Intensity);
}
simulated exec function ToggleFlashlight(){
local NiceWeapon niceWeap;
niceWeap = NiceWeapon(Weapon);
if(niceWeap != none && niceWeap.bUseFlashlightToToggle)
niceWeap.SecondDoToggle();
}
simulated function ApplyWeaponStats(Weapon NewWeapon){
local KFWeapon Weap;
local float weaponWeight;
local class<NiceVeterancyTypes> niceVet;
BaseMeleeIncrease = default.BaseMeleeIncrease;
InventorySpeedModifier = 0;
Weap = KFWeapon(NewWeapon);
SetAmmoStatus();
if(KFPRI != none && Weap != none){
Weap.bIsTier3Weapon = Weap.default.bIsTier3Weapon;
if(Weap.bSpeedMeUp){
if(KFPRI.ClientVeteranSkill != none)
BaseMeleeIncrease += KFPRI.ClientVeteranSkill.Static.GetMeleeMovementSpeedModifier(KFPRI);
InventorySpeedModifier = (default.GroundSpeed * BaseMeleeIncrease);
}
if ( ScrnPerk != none ) {
InventorySpeedModifier +=
default.GroundSpeed * ScrnPerk.static.GetWeaponMovementSpeedBonus(KFPRI, NewWeapon);
}
// Mod speed depending on current weapon's weight
niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(PlayerReplicationInfo);
if(niceVet != none)
weaponWeight = niceVet.static.GetPerceivedWeight(KFPlayerReplicationInfo(PlayerReplicationInfo), Weap);
else
weaponWeight = Weap.weight;
InventorySpeedModifier += default.GroundSpeed * (8 - weaponWeight) * 0.025;
// ScrN Armor can slow down players (or even boost) -- PooSH
InventorySpeedModifier -= default.GroundSpeed * GetCurrentVestClass().default.SpeedModifier;
}
}
simulated function ModifyVelocity(float DeltaTime, vector OldVelocity){
local NicePack NicePackMutator;
local NicePlayerController nicePlayer;
local float MovementMod;
local float WeightMod, HealthMod, TempMod;
local float EncumbrancePercentage;
local Inventory Inv;
local KF_StoryInventoryItem StoryInv;
local bool bAllowSlowDown;
local float adrSpeedBonus;
bAllowSlowDown = true;
nicePlayer = NicePlayerController(Controller);
if(class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillEnforcerUnstoppable'))
bAllowSlowDown = false;
super(KFPawn).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) / default.MaxCarryWeight); //changed MaxCarryWeight to default.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;
MovementMod = 1.0;
if(bAllowSlowDown || HealthMod > 1.0)
MovementMod *= HealthMod;
if(bAllowSlowDown || WeightMod > 1.0)
MovementMod *= WeightMod;
if(KFPRI != none && KFPRI.ClientVeteranSkill != none){
MovementMod *= KFPRI.ClientVeteranSkill.static.GetMovementSpeedModifier(KFPRI, KFGameReplicationInfo(Level.GRI));
}
for(Inv = Inventory;Inv != none;Inv = Inv.Inventory){
TempMod = Inv.GetMovementModifierFor(self);
if(bAllowSlowDown || TempMod > 1.0)
MovementMod *= TempMod;
StoryInv = KF_StoryInventoryItem(Inv);
if(StoryInv != none && StoryInv.bUseForcedGroundSpeed)
{
GroundSpeed = StoryInv.ForcedGroundSpeed;
return;
}
}
if(bTraderSpeedBoost && !KFGameReplicationInfo(Level.GRI).bWaveInProgress)
MovementMod *= TraderSpeedBoost;
if(Health < HealthMax && medicAdrenaliteTime > 0){
// Calulate boos from adrenaline
adrSpeedBonus = Health * (1 - class'NiceSkillCommandoAdrenalineShot'.default.speedBoost) +
(100 * class'NiceSkillCommandoAdrenalineShot'.default.speedBoost - class'NiceSkillCommandoAdrenalineShot'.default.minHealth);
adrSpeedBonus /= (100 - class'NiceSkillCommandoAdrenalineShot'.default.minHealth);
adrSpeedBonus = FMin(adrSpeedBonus, class'NiceSkillCommandoAdrenalineShot'.default.speedBoost);
adrSpeedBonus = FMax(adrSpeedBonus, 1.0);
MovementMod *= adrSpeedBonus;
}
GroundSpeed = default.GroundSpeed * MovementMod;
AccelRate = default.AccelRate * MovementMod;
if(bAllowSlowDown || InventorySpeedModifier > 0)
GroundSpeed += InventorySpeedModifier;
if(nicePlayer != none && nicePlayer.IsZedTimeActive() && class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillZerkZEDAccelerate'))
AccelRate *= 100;
}
NicePackMutator = class'NicePack'.static.Myself(Level);
if(NicePackMutator != none && NicePackMutator.bIsPreGame && NicePackMutator.bInitialTrader && NicePackMutator.bStillDuringInitTrader)
GroundSpeed = 1;
}
function getFreeJacket(){
if(!bGotFreeJacket && ShieldStrength < LightVestClass.default.ShieldCapacity && class'NiceVeterancyTypes'.static.SomeoneHasSkill(NicePlayerController(Controller), class'NiceSkillSupportArmory')){
if(SetVestClass(LightVestClass)){
ShieldStrength = LightVestClass.default.ShieldCapacity;
bGotFreeJacket = true;
}
}
}
simulated function TakeDamage(int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex){
local int needArmor;
local int healAmount;
local float healPotency;
local bool bOldArmorStops;
local float adrResistance;
local float oldHealthToGive;
local NicePlayerController nicePlayer;
ApplyWeaponStats(Weapon);
if(invincibilityTimer > 0)
return;
nicePlayer = NicePlayerController(Controller);
if(bZedTimeInvincible){
if(nicePlayer != none && nicePlayer.IsZedTimeActive())
return;
else
bZedTimeInvincible = false;
}
// Adrenaline damage decrease
if(medicAdrenaliteTime > 0){
adrResistance = Health * (1 - class'NiceSkillCommandoAdrenalineShot'.default.resistBoost) +
(100 * class'NiceSkillCommandoAdrenalineShot'.default.resistBoost - class'NiceSkillCommandoAdrenalineShot'.default.minHealth);
adrResistance /= (100 - class'NiceSkillCommandoAdrenalineShot'.default.minHealth);
adrResistance = FMin(adrResistance, class'NiceSkillCommandoAdrenalineShot'.default.resistBoost);
adrResistance = FMax(adrResistance, 1.0);
Damage *= adrResistance;
}
if(nicePlayer != none && nicePlayer.IsZedTimeActive()
&& class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillZerkZEDUnbreakable'))
return;
lastHMGShieldUpdateTime = Level.TimeSeconds;
if(damageType != none && class<NiceDamTypeDrug>(damageType) == none){
bOldArmorStops = damageType.default.bArmorStops;
if(class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillEnforcerCoating'))
damageType.default.bArmorStops = true;
}
lastExplosionDistance = 0.0; // hack, but scrn fucks with usotherwise
oldHealthToGive = healthToGive; // remember this to restore this value, in case we are using safeguard skill
super.TakeDamage(Damage, InstigatedBy, hitLocation, Momentum, damageType, HitIndex);
if (class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillHeavySafeguard')) {
healthToGive = oldHealthToGive;
clientHealthToGive = healthToGive;
}
// Commando's zed time
if( forcedZedTimeCountDown <= 0.0
&& health < class'NiceSkillCommandoCriticalFocus'.default.healthBoundary && KFGameType(Level.Game) != none
&& class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillCommandoCriticalFocus') ){
KFGameType(Level.Game).DramaticEvent(1.0);
forcedZedTimeCountDown = class'NiceSkillCommandoCriticalFocus'.default.cooldown;
}
if(damageType != none)
damageType.default.bArmorStops = bOldArmorStops;
// Do heavy mg's armor healing
if(class'NiceVeterancyTypes'.static.HasSkill(nicePlayer, class'NiceSkillHeavySafeguard') && health < HealthMax * 0.5 && ShieldStrength > 0){
healAmount = HealthMax - health;
healPotency = 1.0;
if(health < HealthMax * 0.25)
healPotency = 2.0;
else if(health < HealthMax * 0.1)
healPotency = 10.0;
needArmor = float(healAmount) * healPotency * class'NiceSkillHeavySafeguard'.default.healingCost;
ShieldStrength -= needArmor;
if(ShieldStrength < 0)
ShieldStrength = 0;
health += HealAmount * 0.5;
TakeHealing(self, HealAmount * 0.5 + 1, HealPotency);
}
if(ShieldStrength <= 0)
getFreeJacket();
}
function int ShieldAbsorb(int damage){
if(ShieldStrength > 0 && class'NiceVeterancyTypes'.static.HasSkill(NicePlayerController(Controller), class'NiceSkillHeavySafeguard'))
return damage;
return super.ShieldAbsorb(damage);
}
function Timer(){
if(BurnDown > 0 && BurnInstigator != self && KFPawn(BurnInstigator) != none)
LastBurnDamage *= 1.8;
super(SRHumanPawn).Timer();
// tick down health if it's greater than max
if(Health > HealthMax){
if(Health > 100)
Health -= 5;
if(Health < HealthMax)
Health = HealthMax;
}
SetAmmoStatus();
ApplyWeaponFlashlight(true);
}
simulated function Fire(optional float F){
local bool bRecManualReload;
local NiceSingle singleWeap;
local ScrnPlayerController PC;
singleWeap = NiceSingle(weapon);
PC = ScrnPlayerController(Controller);
if(PC != none && singleWeap != none && singleWeap.bIsDual && singleWeap.otherMagazine > 0){
bRecManualReload = PC.bManualReload;
PC.bManualReload = false;
super.Fire(F);
PC.bManualReload = bRecManualReload;
}
else
super.Fire(F);
}
function float AssessThreatTo(KFMonsterController Monster, optional bool CheckDistance){
return super(SRHumanPawn).AssessThreatTo(Monster, CheckDistance);
}
function VeterancyChanged(){
local NicePlayerController nicePlayer;
if(KFPRI == none)
return;
nicePlayer = NicePlayerController(Controller);
nicePrevPerkLevel = KFPRI.ClientVeteranSkillLevel;
nicePrevPerkClass = class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill);
if(nicePlayer != none && nicePlayer.abilityManager != none)
nicePlayer.abilityManager.ClearAbilities();
if(nicePrevPerkClass != none && Role == Role_AUTHORITY)
nicePrevPerkClass.static.SetupAbilities(KFPRI);
if(nicePlayer != none){
nicePlayer.TriggerSelectEventOnPerkChange(nicePrevPerkClass,
class<NiceVeterancyTypes>(KFPRI.ClientVeteranSkill));
}
super.VeterancyChanged();
}
simulated function AltFire(optional float F){
if(NiceMedicGun(Weapon) != none)
super(SRHumanPawn).AltFire(F);
else
super.AltFire(F);
}
// added copy-cated function to disable some log
simulated function Setup(xUtil.PlayerRecord rec, optional bool bLoadNow)
{
local ScrnPlayerController PC;
local string CN;
PC = ScrnPlayerController(Controller);
if ( PC != none && IsLocallyControlled() )
{
// check this only on player side, because it stores
// RedCharacter & BlueCharacter in the config
CN = rec.DefaultName;
if ( !PC.ValidateCharacter(CN) ) {
// character invalid, change it valid one, which was set up in ValidateCharacter()
rec = class'xUtil'.static.FindPlayerRecord(CN);
PC.ChangeCharacter(CN);
}
}
super(KFPawn).Setup(rec, bLoadNow);
if( class<SoldierSpeciesRobot>(Species) != none )
{
BreathingSound = class'KFDARSoundGroup'.default.BreathingSound;
}
else if( class<AshHardingSpecies>(Species) != none )
{
BreathingSound = class'KFFemaleSoundGroup'.default.BreathingSound;
}
// disable the log!!!
// log(BreathingSound);
}
defaultproperties
{
defaultInvincibilityDuration=2.000000
BaseMeleeIncrease=0.000000
}