diff --git a/sources/GUI/NiceInteraction.uc b/sources/GUI/NiceInteraction.uc index 2afc1e1..a52af06 100644 --- a/sources/GUI/NiceInteraction.uc +++ b/sources/GUI/NiceInteraction.uc @@ -107,10 +107,6 @@ function PostRender(Canvas C) local int x, y, center, barWidth, offset; local int missesWidth, missesHeight, missesSpace; local int missesX, missesY; - local TeamInfo team; - local int healthToGive, totalExpectedHealth; - local float textWidth, textHeight; - local string textToDraw; // local Vector CamPos, ViewDir; // local Rotator CamRot; // local float OffsetX, BarLength, BarHeight, XL, YL, posY; @@ -260,47 +256,6 @@ function PostRender(Canvas C) } } - //// Draw quad damage bar - if (nicePawn != none && nicePawn.quadDamageRemaining > 0.0) - { - C.SetDrawColor(255, 255, 255); - barTexture = redBar; - center = C.ClipX * 0.5; - y = C.ClipY * 0.45; - barWidth = C.ClipX * 0.2; - barWidth *= nicePawn.quadDamageRemaining / class'NiceSkillEnforcerBruteA'.default.maximumDamageAdded; - x = center - (barWidth / 2); - C.SetPos(x, y); - Log("DRAWING" @ x @ y @ barWidth); - C.DrawTile(barTexture, barWidth, 32, 0, 0, barTexture.MaterialUSize(), barTexture.MaterialVSize()); - }//native(466) final function DrawTile( material Mat, float XL, float YL, float U, float V, float UL, float VL ); - - team = C.ViewPort.Actor.Pawn.PlayerReplicationInfo.Team; - //// Draw health still in regen timer - healthToGive = ScrnHumanPawn(C.ViewPort.Actor.Pawn).clientHealthToGive; - if (healthToGive > 0) { - totalExpectedHealth = healthToGive + C.ViewPort.Actor.Pawn.health;; - C.Font = class'ROHUD'.Static.LoadSmallFontStatic(3); - if (totalExpectedHealth >= C.ViewPort.Actor.Pawn.healthMax) { - if(team.teamIndex == 0) { - C.SetDrawColor(255, 64, 64); - } - else { - C.SetDrawColor( - team.teamColor.R, - team.teamColor.G, - team.teamColor.B); - } - } - else { - C.SetDrawColor(128, 128, 128); - } - textToDraw = "+" $ healthToGive; - C.TextSize(textToDraw, textWidth, textHeight); - C.SetPos(C.ClipX * 0.05, C.ClipY * 0.9); - C.DrawText(textToDraw); - } - //// Draw cooldowns if (nicePlayer.abilityManager == none) return; @@ -318,7 +273,7 @@ function PostRender(Canvas C) { if (niceMutator.niceCounterSet[i].value != 0 || niceMutator.niceCounterSet[i].bShowZeroValue) { - DrawCounter(C, niceMutator.niceCounterSet[i], x, y, team); + DrawCounter(C, niceMutator.niceCounterSet[i], x, y, C.ViewPort.Actor.Pawn.PlayerReplicationInfo.Team); x += 128 + 4; } } @@ -328,7 +283,7 @@ function PostRender(Canvas C) function DrawCounter(Canvas C, NicePack.CounterDisplay counter, int x, int y, TeamInfo team){ local float borderSpace; local Texture textureToDraw; - local float textWidth, textHeight; + local float textWidth, textHeight; local string textToDraw; // Some per-defined values for drawing local int iconSize, backgroundWidth, backgroundHeight; @@ -365,7 +320,7 @@ function DrawAbilityCooldown(Canvas C, int abilityIndex){ local class niceVet; local int x, y; local string textToDraw; - local float textWidth, textHeight; + local float textWidth, textHeight; local NiceAbilityManager.EAbilityState abilityState; if(C == none) return; if(C.ViewPort == none) return; diff --git a/sources/NiceGameType.uc b/sources/NiceGameType.uc index 5eb9578..ca0aaa7 100644 --- a/sources/NiceGameType.uc +++ b/sources/NiceGameType.uc @@ -74,8 +74,6 @@ State MatchInProgress{ function ScoreKill(Controller Killer, Controller Other) { - local NicePlayerController niceKiller; - local NiceHumanPawn niceKillerPawn; local PlayerReplicationInfo OtherPRI; local float KillScore; local Controller C; @@ -200,15 +198,7 @@ function ScoreKill(Controller Killer, Controller Other) } /* End Marco's Kill Messages */ - niceKiller = NicePlayerController(killer); - if (niceKiller != none && niceKiller.abilityManager != none) { - niceKillerPawn = NiceHumanPawn(niceKiller.pawn); - niceKiller.abilityManager.AddToAllCooldowns(-1); - } - if ( niceKillerPawn != none && NiceBoomStick(niceKillerPawn.weapon) != none - && other != none && other.pawn != none && other.pawn.default.health >= 1000) { - niceKillerPawn.invincibilityTimer += 1.0; - } + } function DramaticEvent(float BaseZedTimePossibility, optional float DesiredZedTimeDuration){ diff --git a/sources/NiceHumanPawn.uc b/sources/NiceHumanPawn.uc index 58a48f7..18205da 100644 --- a/sources/NiceHumanPawn.uc +++ b/sources/NiceHumanPawn.uc @@ -46,11 +46,10 @@ struct InvincExtentions{ var array 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; + currentCalibrationState, calibrationScore, gunslingerTimer; reliable if(Role == ROLE_Authority) ClientChangeWeapon; reliable if(Role < ROLE_AUTHORITY) @@ -70,7 +69,7 @@ function ReplaceRequiredEquipment() RequiredEquipment[0] = string(class'NiceMachete'); RequiredEquipment[1] = string(class'Nice9mmPlus'); RequiredEquipment[2] = string(class'ScrnFrag'); - RequiredEquipment[3] = string(class'ScrnSyringe'); + RequiredEquipment[3] = string(class'NiceSyringe'); RequiredEquipment[4] = string(class'KFMod.Welder'); } @@ -421,10 +420,10 @@ function ServerBuyWeapon(class WClass, float ItemWeight){ 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 + if(class'ScrnBalance'.default.Mut.bBuyPerkedWeaponsOnly + && WP.default.CorrespondingPerkIndex != 7 && WP.default.CorrespondingPerkIndex != KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.default.PerkIndex ) - return; + return; } SellValue = Price * 0.75; Price = int(Price); @@ -508,11 +507,11 @@ function bool AddInventory(inventory NewItem){ if(weap != none){ if(Dualies(weap) != none){ if((DualDeagle(weap) != none || Dual44Magnum(weap) != none || DualMK23Pistol(weap) != none) - && weap.InventoryGroup != 4 ) { + && weap.InventoryGroup != 4 ) { if(KFPRI != none && ClassIsChildOf(KFPRI.ClientVeteranSkill, class'ScrnVetGunslinger')) weap.InventoryGroup = 3; - else + else weap.InventoryGroup = 2; GroupChanged = true; } @@ -522,7 +521,7 @@ function bool AddInventory(inventory NewItem){ } weap.bIsTier3Weapon = true; } - if(GroupChanged) + if(GroupChanged) ClientSetInventoryGroup(NewItem.class, NewItem.InventoryGroup); if(super(SRHumanPawn).AddInventory(NewItem)){ if(weap != none && weap.bTorchEnabled) @@ -569,7 +568,7 @@ simulated function ThrowGrenade() super.ThrowGrenade(); return; } - + if(playerGrenade == none) playerGrenade = FindPlayerGrenade(); if(playerGrenade != none && playerGrenade.HasAmmo()){ @@ -651,7 +650,7 @@ simulated function ApplyWeaponStats(Weapon NewWeapon){ 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; @@ -700,7 +699,7 @@ simulated function ModifyVelocity(float DeltaTime, vector OldVelocity){ GroundSpeed = StoryInv.ForcedGroundSpeed; return; } - } + } if(bTraderSpeedBoost && !KFGameReplicationInfo(Level.GRI).bWaveInProgress) MovementMod *= TraderSpeedBoost; if(Health < HealthMax && medicAdrenaliteTime > 0){ @@ -737,7 +736,6 @@ simulated function TakeDamage(int Damage, Pawn InstigatedBy, Vector Hitlocation, local float healPotency; local bool bOldArmorStops; local float adrResistance; - local float oldHealthToGive; local NicePlayerController nicePlayer; ApplyWeaponStats(Weapon); if(invincibilityTimer > 0) @@ -768,12 +766,7 @@ simulated function TakeDamage(int Damage, Pawn InstigatedBy, Vector Hitlocation, 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 @@ -796,7 +789,7 @@ simulated function TakeDamage(int Damage, Pawn InstigatedBy, Vector Hitlocation, if(ShieldStrength < 0) ShieldStrength = 0; health += HealAmount * 0.5; - TakeHealing(self, HealAmount * 0.5 + 1, HealPotency); + TakeHealing(self, HealAmount * 0.5, HealPotency); } if(ShieldStrength <= 0) getFreeJacket(); diff --git a/sources/NicePlayerController.uc b/sources/NicePlayerController.uc index dabd3d0..ccd38a9 100644 --- a/sources/NicePlayerController.uc +++ b/sources/NicePlayerController.uc @@ -212,6 +212,20 @@ simulated function ClientPostLogin(){ // Change HUD parameters class'ScrnHUD'.default.EnemyHealthBarHeight = 4.0; } + +// fix crooked camera after you die with active `ViewShake` +function StopViewShaking() { + ShakeRotMax = vect(0, 0, 0); + ShakeRotRate = vect(0, 0, 0); + ShakeRotTime = vect(0, 0, 0); + ShakeOffsetMax = vect(0, 0, 0); + ShakeOffsetRate = vect(0, 0, 0); + ShakeOffsetTime = vect(0, 0, 0); + // add missing variables + ShakeOffset = vect(0, 0, 0); + ShakeRot = Rot(0, 0, 0); +} + function ShowLobbyMenu(){ Super.ShowLobbyMenu(); } @@ -1225,7 +1239,7 @@ function LoadDualWieldables(){ local class WP; local class W; local int i; - + CPRL = class'ClientPerkRepLink'.Static.FindStats(self); if(CPRL == none || CPRL.ShopInventory.Length == 0) return; diff --git a/sources/NiceReplicationInfo.uc b/sources/NiceReplicationInfo.uc index 2267304..a685f4e 100644 --- a/sources/NiceReplicationInfo.uc +++ b/sources/NiceReplicationInfo.uc @@ -71,7 +71,6 @@ simulated function CalculateDamageScales( out float scale1, out float scale2, local Vector victimPoint1, victimPoint2; local float swap; victimPoint1 = victim.location; - victimPoint2.z += victim.CollisionHeight * 0.25; victimPoint2 = victim.location; victimPoint2.z += victim.CollisionHeight * 0.75; scale1 = GetDamageScale(victim, explosionLocation, victimPoint1, @@ -94,55 +93,40 @@ simulated function ServerExplode float momentum, Vector explLocation, Pawn instigator, + optional bool allowDoubleExplosion, optional Actor explosionTarget, - optional vector explosiveDirection, - optional bool preventProximityHeadDamage + optional vector explosiveDirection ){ local Actor victim; local int numKilled; local Vector dirToVictim; local Vector hitLocation; local float scale1, scale2; - local NiceMonster niceVictim; if(Role < ROLE_Authority) return; foreach VisibleActors(class'Actor', victim, explRadius, explLocation){ - if(victim == none || victim == self) continue; - if(victim.role < ROLE_Authority) continue; - if(ExtendedZCollision(victim) != none) continue; - if(Trigger(victim) != none) continue; - - niceVictim = NiceMonster(victim); - dirToVictim = Normal(victim.location - explLocation); - hitLocation = victim.location - 0.5 * - (victim.collisionHeight + victim.collisionRadius) * dirToVictim; - CalculateDamageScales( scale1, scale2, - victim, explLocation, explRadius, explExp); - // Deal head damage if explosion is close enough to the victim's head - if ( niceVictim != none && !preventProximityHeadDamage - && niceVictim.GetDistanceToHead(explLocation) <= explRadius * 0.1) - { - ServerDealDamage( victim, explDamage, instigator, - hitLocation, 0.0 * dirToVictim, - explDmgType, 0.5); - } - // Deal main damage - if(scale1 > 0 || scale2 > 0) { - ServerDealDamage( - victim, - explDamage * FMax(scale1, scale2), - instigator, - hitLocation, - FMax(scale1, scale2) * momentum * dirToVictim, - explDmgType); - } - if(niceVictim != none) { - if (niceVictim.health <= 0) { - numKilled += 1; - } - else { - niceVictim.concussionCountdown = 10.0; - } - } + if(victim == none || victim == self) continue; + if(victim.role < ROLE_Authority) continue; + if(ExtendedZCollision(victim) != none) continue; + if(Trigger(victim) != none) continue; + dirToVictim = Normal(victim.location - explLocation); + hitLocation = victim.location - 0.5 * + (victim.collisionHeight + victim.collisionRadius) * dirToVictim; + CalculateDamageScales( scale1, scale2, + victim, explLocation, explRadius, explExp); + // Deal main damage + if(scale1 > 0){ + ServerDealDamage( victim, explDamage * scale1, instigator, + hitLocation, scale1 * momentum * dirToVictim, + explDmgType); + } + // Deal secondary damage + if(allowDoubleExplosion && victim != none && scale2 > 0){ + ServerDealDamage( victim, explDamage * scale2, instigator, + hitLocation, scale2 * momentum * dirToVictim, + explDmgType); + } + if(NiceMonster(victim) != none && NiceMonster(victim).health <= 0) + numKilled ++; } if(numKilled >= 4) KFGameType(level.game).DramaticEvent(0.05); @@ -219,45 +203,34 @@ simulated function RemovePoisonAndBleed(NiceHumanPawn healed) } // Tells server to heal given human pawn. -simulated function ServerHealTarget( - NiceHumanPawn healed, - float charPotency, - Pawn instigator -) { +simulated function ServerHealTarget(NiceHumanPawn healed, float charPotency, + Pawn instigator){ local NiceHumanPawn healer; - local PlayerController healedPC; local KFPlayerReplicationInfo KFPRI; - local NiceMedicGun healingTool; local float healTotal; local float healPotency; - if(instigator == none || healed == none) return; if(healed.health <= 0 || healed.health >= healed.healthMax) return; KFPRI = KFPlayerReplicationInfo(instigator.PlayerReplicationInfo); - if(KFPRI == none || KFPRI.ClientVeteranSkill == none) return; + if(KFPRI == none || KFPRI.ClientVeteranSkill == none) + return; healer = NiceHumanPawn(instigator); - if(healer == none) return; - - healingTool = NiceMedicGun(healer.weapon); + if(healer == none) + return; healPotency = KFPRI.ClientVeteranSkill.static.GetHealPotency(KFPRI); healTotal = charPotency * healPotency; + healer.AlphaAmount = 255; - if(healingTool != none) { - healingTool.ClientSuccessfulHeal(healer, healed); - } - healedPC = PlayerController(healed.controller); - if(healedPC != none) { - healedPC.ClientMessage( - "You've been healed by" @ healer.GetPlayerName(), - 'CriticalEvent'); - } - if(healed.health >= healed.healthMax) { + if(NiceMedicGun(healer.weapon) != none) + NiceMedicGun(healer.weapon).ClientSuccessfulHeal(healer, healed); + if(healed.health >= healed.healthMax){ healed.GiveHealth(healTotal, healed.healthMax); return; } HandleNiceHealingMechanicsAndSkills(healer, healed, healPotency); - if(healed.health < healed.healthMax) { - healed.TakeHealing(healed, healTotal, healPotency, healingTool); + if(healed.health < healed.healthMax){ + healed.TakeHealing( healed, healTotal, healPotency, + KFWeapon(instigator.weapon)); } RemovePoisonAndBleed(healed); } @@ -288,6 +261,9 @@ simulated function HandleNiceDamageMechanicsAndSkills hasSkill(nicePlayer, class'NiceSkillCommandoTranquilizer'); hasZEDFrenzy = class'NiceVeterancyTypes'.static. hasSkill(nicePlayer, class'NiceSkillMedicZEDFrenzy'); + // Medic's suppression + if(hasTranquilizer) + niceZed.mind = FMin(niceZed.mind, 0.5); // Medic's frenzy if(hasZEDFrenzy && nicePlayer.IsZedTimeActive()){ niceZed.madnessCountDown = @@ -334,7 +310,7 @@ simulated function UpdateMeleeInvincibility nicePawn.TryExtendingInv(niceZed, false, headshotLevel > 0.0); // Handle melee-cases if(mainTarget && class(damageType) != none) - nicePawn.TryExtendingInv(niceZed, true, headshotLevel > 0.0); + nicePawn.TryExtendingInv(niceZed, true, headshotLevel > 0.0); nicePawn.ApplyWeaponStats(nicePawn.weapon); } simulated function UpdateArdour(bool isKill, NicePlayerController nicePlayer){ diff --git a/sources/NiceRules.uc b/sources/NiceRules.uc index e94c7df..b2defeb 100644 --- a/sources/NiceRules.uc +++ b/sources/NiceRules.uc @@ -128,7 +128,7 @@ function bool PreventDeath(Pawn Killed, Controller Killer, class dam class'NiceSkillDemoReactiveArmor'.default.explExponent, class'NiceDamTypeDemoSafeExplosion', class'NiceSkillDemoReactiveArmor'.default.explMomentum, - killed.location, killed + killed.location, killed, true ); return true; } diff --git a/sources/Perks/Abilities/NiceAbilityManager.uc b/sources/Perks/Abilities/NiceAbilityManager.uc index 4e96c95..96058e2 100644 --- a/sources/Perks/Abilities/NiceAbilityManager.uc +++ b/sources/Perks/Abilities/NiceAbilityManager.uc @@ -29,19 +29,19 @@ struct NiceAbilityDescription{ // Image to be used as an ability's icon var Texture icon; // Default cooldown duration - var int cooldownLength; + var float cooldownLength; // Can ability be canceled once activated? - var bool canBeCancelled; + var bool canBeCancelled; }; // Complete description of current status of an ability, // including it's complete description. struct NiceAbilityStatus{ // Complete description of ability in question - var NiceAbilityDescription description; + var NiceAbilityDescription description; // Current cooldown value - var int cooldown; + var float cooldown; // Current state of an ability - var EAbilityState myState; + var EAbilityState myState; }; var NiceAbilityStatus currentAbilities[5]; var int currentAbilitiesAmount; @@ -65,7 +65,7 @@ function AddAbility(NiceAbilityDescription description){ if(currentAbilities[i].description.ID ~= description.ID) return; newRecord.description = description; - newRecord.cooldown = 0; + newRecord.cooldown = 0.0; newRecord.myState = ASTATE_READY; currentAbilities[currentAbilitiesAmount] = newRecord; currentAbilitiesAmount += 1; @@ -120,34 +120,34 @@ function SetAbilityState(int abilityIndex, EAbilityState newState){ if(abilityIndex < 0 || abilityIndex >= currentAbilitiesAmount) return; currentState = currentAbilities[abilityIndex].myState; if(currentState == newState) - return; + return; if( currentState == ASTATE_ACTIVE && newState == ASTATE_READY - && !currentAbilities[abilityIndex].description.canBeCancelled) - return; + && !currentAbilities[abilityIndex].description.canBeCancelled) + return; currentAbilities[abilityIndex].myState = newState; if(newState == ASTATE_COOLDOWN){ - cooldown = currentAbilities[abilityIndex].description.cooldownLength; - events.static.CallModAbilityCooldown( - currentAbilities[abilityIndex].description.ID, - relatedPlayer, - cooldown - ); - currentAbilities[abilityIndex].cooldown = cooldown; + cooldown = currentAbilities[abilityIndex].description.cooldownLength; + events.static.CallModAbilityCooldown( + currentAbilities[abilityIndex].description.ID, + relatedPlayer, + cooldown + ); + currentAbilities[abilityIndex].cooldown = cooldown; } hackCounter ++; netUpdateTime = level.timeSeconds - 1; // Fire off events if(newState == ASTATE_ACTIVE){ - events.static.CallAbilityActivated( - currentAbilities[abilityIndex].description.ID, - relatedPlayer - ); + events.static.CallAbilityActivated( + currentAbilities[abilityIndex].description.ID, + relatedPlayer + ); } } // Changes ability's cooldown by a given amount. // If this brings cooldown to zero or below - // resets current ability to a 'ready' (ASTATE_READY) state. -function AddToCooldown(int abilityIndex, int delta){ +function AddToCooldown(int abilityIndex, float delta){ if(abilityIndex < 0 || abilityIndex >= currentAbilitiesAmount) return; if(currentAbilities[abilityIndex].myState != ASTATE_COOLDOWN) return; currentAbilities[abilityIndex].cooldown += delta; @@ -155,21 +155,12 @@ function AddToCooldown(int abilityIndex, int delta){ SetAbilityState(abilityIndex, ASTATE_READY); hackCounter ++; } - -function AddToAllCooldowns(int delta){ +function Tick(float deltaTime){ local int i; - - for (i = 0; i < currentAbilitiesAmount; i += 1) { - if (currentAbilities[i].myState == ASTATE_COOLDOWN) { - currentAbilities[i].cooldown += delta; - if(currentAbilities[i].cooldown <= 0) { - SetAbilityState(i, ASTATE_READY); - } - } - } - hackCounter ++; + if(Role != Role_AUTHORITY) return; + for(i = 0;i < currentAbilitiesAmount;i ++) + AddToCooldown(i, -deltaTime); } - defaultproperties { maxAbilitiesAmount=5 diff --git a/sources/Perks/Commando/NiceDamTypeMedicDart.uc b/sources/Perks/Commando/NiceDamTypeMedicDart.uc index c64ead0..260ac7a 100644 --- a/sources/Perks/Commando/NiceDamTypeMedicDart.uc +++ b/sources/Perks/Commando/NiceDamTypeMedicDart.uc @@ -1,4 +1,4 @@ -class NiceDamTypeMedicDart extends NiceDamageTypeVetDemolitions +class NiceDamTypeMedicDart extends NiceDamageTypeVetCommando abstract; defaultproperties { diff --git a/sources/Perks/Commando/NiceVetCommando.uc b/sources/Perks/Commando/NiceVetCommando.uc index 7e94b9f..db16fbc 100644 --- a/sources/Perks/Commando/NiceVetCommando.uc +++ b/sources/Perks/Commando/NiceVetCommando.uc @@ -35,16 +35,6 @@ static function float GetMagCapacityMod(KFPlayerReplicationInfo KFPRI, KFWeapon return class'NiceSkillCommandoLargerMags'.default.sizeBonus; return 1.0; } -// Change the cost of particular ammo -static function float GetAmmoCostScaling(KFPlayerReplicationInfo KFPRI, class Item) -{ - local class pickupClass; - pickupClass = class(Item); - if(IsPerkedPickup(pickupClass) && HasSkill(NicePlayerController(KFPRI.Owner), class'NiceSkillCommandoLargerMags')) { - return class'NiceSkillCommandoLargerMags'.default.sizeBonus; - } - return 1.0; -} static function float GetSyringeChargeRate(KFPlayerReplicationInfo KFPRI){ return 1.5; } @@ -112,7 +102,7 @@ defaultproperties OnHUDIcons(3)=(PerkIcon=Texture'ScrnTex.Perks.Perk_Commando_Blue',StarIcon=Texture'ScrnTex.Perks.Hud_Perk_Star_Blue',DrawColor=(B=255,G=255,R=255,A=255)) OnHUDIcons(4)=(PerkIcon=Texture'ScrnTex.Perks.Perk_Commando_Purple',StarIcon=Texture'ScrnTex.Perks.Hud_Perk_Star_Purple',DrawColor=(B=255,G=255,R=255,A=255)) OnHUDIcons(5)=(PerkIcon=Texture'ScrnTex.Perks.Perk_Commando_Orange',StarIcon=Texture'ScrnTex.Perks.Hud_Perk_Star_Orange',DrawColor=(B=255,G=255,R=255,A=255)) - CustomLevelInfo="Level up by doing damage with perked weapons|15% faster reload with all weapons|10% faster movement speed|You get four additional Zed-Time Extensions|See health and cloaked zeds from 16 meters distance|Better Syringe handling" + CustomLevelInfo="Level up by doing damage with perked weapons|15% faster reload with all weapons|10% faster movement speed|You get four additional Zed-Time Extensions|See health and cloacked zeds from 16 meters distance|Better Syringe handling" PerkIndex=3 OnHUDIcon=Texture'KillingFloorHUD.Perks.Perk_Commando' OnHUDGoldIcon=Texture'KillingFloor2HUD.Perk_Icons.Perk_Commando_Gold' diff --git a/sources/Perks/Demolitions/NiceDamTypeDemoExplosion.uc b/sources/Perks/Demolitions/NiceDamTypeDemoExplosion.uc index 78ab779..a640688 100644 --- a/sources/Perks/Demolitions/NiceDamTypeDemoExplosion.uc +++ b/sources/Perks/Demolitions/NiceDamTypeDemoExplosion.uc @@ -8,7 +8,6 @@ static function GetHitEffects(out class HitEffects[4], int VictimHealt } defaultproperties { - stoppingPower=0.5 stunMultiplier=0.600000 bIsExplosive=True DeathString="%o filled %k's body with shrapnel." diff --git a/sources/Perks/Demolitions/NiceVetDemolitions.uc b/sources/Perks/Demolitions/NiceVetDemolitions.uc index ea36af8..a0c1006 100644 --- a/sources/Perks/Demolitions/NiceVetDemolitions.uc +++ b/sources/Perks/Demolitions/NiceVetDemolitions.uc @@ -39,13 +39,12 @@ static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, perkDamage = float(InDamage); if(DmgType == class'NiceDamTypeDemoExplosion') return 1.6 * perkDamage; - if(IsPerkedPickup(pickupClass) && class(DmgType) != none) + if(IsPerkedPickup(pickupClass)) perkDamage *= 1.25; else if( pickupClass != none && pickupClass.default.weight <= class'NiceSkillDemoOffperk'.default.weightBound && HasSkill(NicePlayerController(KFPRI.Owner), class'NiceSkillDemoOffperk') ) perkDamage *= class'NiceSkillDemoOffperk'.default.damageBonus; - if( KFPRI != none && class(DmgType) == none - && IsPerkedPickup(pickupClass) + if( KFPRI != none && class(DmgType) != none && SomeoneHasSkill(NicePlayerController(KFPRI.Owner), class'NiceSkillDemoOnperk') ) perkDamage *= class'NiceSkillDemoOnperk'.default.damageBonus; return perkDamage; diff --git a/sources/Perks/Enforcer/NiceEnforcerAbilitiesAdapter.uc b/sources/Perks/Enforcer/NiceEnforcerAbilitiesAdapter.uc index 11946da..0f5116f 100644 --- a/sources/Perks/Enforcer/NiceEnforcerAbilitiesAdapter.uc +++ b/sources/Perks/Enforcer/NiceEnforcerAbilitiesAdapter.uc @@ -15,6 +15,7 @@ static function AbilityActivated( NicePlayerController relatedPlayer) { local NiceHumanPawn nicePawn; + local NiceMonster victim; if (relatedPlayer == none) return; nicePawn = NiceHumanPawn(relatedPlayer.pawn); @@ -36,23 +37,6 @@ static function AbilityActivated( { nicePawn.bruteTimer = class'NiceSkillEnforcerBruteA'.default.abilityDuration; - nicePawn.quadDamageRemaining = class'NiceSkillEnforcerBruteA'.default.maximumDamageAdded; - } -} - -static function ModAbilityCooldown( string abilityID, - NicePlayerController relatedPlayer, - out float cooldown) -{ - local NiceHumanPawn nicePawn; - - if (relatedPlayer == none) return; - nicePawn = NiceHumanPawn(relatedPlayer.pawn); - if (nicePawn == none) return; - - if (abilityID == "brute") - { - nicePawn.quadDamageRemaining = 0; } } diff --git a/sources/Perks/Enforcer/NiceVetEnforcer.uc b/sources/Perks/Enforcer/NiceVetEnforcer.uc index 141af22..76d120d 100644 --- a/sources/Perks/Enforcer/NiceVetEnforcer.uc +++ b/sources/Perks/Enforcer/NiceVetEnforcer.uc @@ -16,15 +16,12 @@ static function array GetProgressArray(byte ReqNum, optional out int Double // Other bonuses static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn DamageTaker, int InDamage, class DmgType) { - local int bruteAbilityIndex; - local float fDamage, addedDamage; + local float fDamage; local NicePlayerController nicePlayer; - local NiceHumanPawn nicePawn; local NiceMonster niceTarget; fDamage = float(InDamage); nicePlayer = NicePlayerController(KFPRI.Owner); - nicePawn = NiceHumanPawn(nicePlayer.pawn); niceTarget = NiceMonster(injured); if ( niceTarget != none && niceTarget.bFrozenZed @@ -34,20 +31,9 @@ static function int AddDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, (1 + class'NiceSkillEnforcerFinisherRounds'.default.damageBonus); } if( nicePlayer != none && nicePlayer.abilityManager != none - && nicePawn != none && nicePawn.quadDamageRemaining > 0 && nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID)) { - addedDamage = fDamage * class'NiceSkillEnforcerBruteA'.default.damageMult - fDamage; - if (addedDamage >= nicePawn.quadDamageRemaining) { - addedDamage = nicePawn.quadDamageRemaining; - nicePawn.quadDamageRemaining = 0.0; - bruteAbilityIndex = nicePlayer.abilityManager.GetAbilityIndex(class'NiceSkillEnforcerBruteA'.default.abilityID); - nicePlayer.abilityManager.SetAbilityState(bruteAbilityIndex, ASTATE_COOLDOWN); - } - else { - nicePawn.quadDamageRemaining -= addedDamage; - } - fDamage += addedDamage; + fDamage *= class'NiceSkillEnforcerBruteA'.default.damageMult; } return int(fDamage); } @@ -59,7 +45,7 @@ static function float GetPenetrationDamageMulti(KFPlayerReplicationInfo KFPRI, f return DefaultPenDamageReduction; if(HasSkill(NicePlayerController(KFPRI.Owner), class'NiceSkillSupportStubbornness')) bonusReduction = class'NiceSkillSupportStubbornness'.default.penLossRed; - PenDamageInverse = (1.0 - FMax(0, DefaultPenDamageReduction)); + PenDamageInverse = (1.0 - FMax(0, DefaultPenDamageReduction)); return DefaultPenDamageReduction + PenDamageInverse * (0.6 + 0.4 * bonusReduction); // 60% better penetrations + bonus } @@ -78,6 +64,15 @@ static function class GetNadeType(KFPlayerReplicationInfo KFPRI){ return class'NiceCryoNade'; } +static function float AddExtraAmmoFor(KFPlayerReplicationInfo KFPRI, Class AmmoType){ + local float bonusNades; + // Default bonus + bonusNades = 2; + if(AmmoType == class'FragAmmo') + return 1.0 + 0.2 * bonusNades; + return 1.0; +} + static function int ReduceDamage(KFPlayerReplicationInfo KFPRI, KFPawn Injured, Pawn Instigator, int InDamage, class DmgType){ local float fDamage; fDamage = float(inDamage); @@ -185,7 +180,7 @@ defaultproperties SkillGroupA(4)=class'NiceSkillEnforcerZEDBarrage' SkillGroupB(0)=class'NiceSkillEnforcerUnkillable' SkillGroupB(1)=class'NiceSkillEnforcerMultitasker' - SkillGroupB(2)=class'NiceSkillHeavySafeguard' + SkillGroupB(2)=class'NiceSkillEnforcerFinisherRounds' SkillGroupB(3)=class'NiceSkillEnforcerBruteA' SkillGroupB(4)=class'NiceSkillEnforcerZEDIceGiant' progressArray0(0)=100 diff --git a/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBombard.uc b/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBombard.uc index 8bdedfa..e38133a 100644 --- a/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBombard.uc +++ b/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBombard.uc @@ -7,5 +7,5 @@ defaultproperties stunMult=3.000000 spreadMult=0.500000 SkillName="Bombard" - SkillEffects="Your perked weapons are 3 times as good at stunning and have omly half as much spread." + SkillEffects="Your perked weapons are 3 times as good at stunning." } diff --git a/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBruteA.uc b/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBruteA.uc index e7a87df..8bf9399 100644 --- a/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBruteA.uc +++ b/sources/Perks/Enforcer/Skills/NiceSkillEnforcerBruteA.uc @@ -5,7 +5,6 @@ var string abilityID; var float coolDown; var float abilityDuration; var float damageMult; -var float maximumDamageAdded; function static SkillSelected(NicePlayerController nicePlayer) { @@ -30,7 +29,6 @@ function static SkillDeSelected(NicePlayerController nicePlayer) defaultproperties { - maximumDamageAdded=10000 abilityID="brute" cooldown=60.000000 abilityDuration=5.0 diff --git a/sources/Perks/NiceVeterancyTypes.uc b/sources/Perks/NiceVeterancyTypes.uc index 418c6b1..24560b4 100644 --- a/sources/Perks/NiceVeterancyTypes.uc +++ b/sources/Perks/NiceVeterancyTypes.uc @@ -219,6 +219,8 @@ static function int AddRegDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injure } // Allows to buff only fire component of damage. static function int AddFireDamage(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn DamageTaker, int InDamage, class DmgType){ + if(DmgType != none) + return InDamage * DmgType.default.heatPart; return InDamage; } static function float stunDurationMult(KFPlayerReplicationInfo KFPRI, KFMonster Injured, KFPawn DamageTaker, class DmgType){ diff --git a/sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyFire.uc b/sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyFire.uc index 59b48a3..9077bf8 100644 --- a/sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyFire.uc +++ b/sources/Weapons/BaseWeaponClasses/Heavy/NiceHeavyFire.uc @@ -2,6 +2,5 @@ class NiceHeavyFire extends NiceFire; defaultproperties { - maxBonusContLenght = 3 - aimingSpreadReductionCoefficient = 0.0 + maxBonusContLenght=3 } diff --git a/sources/Weapons/BaseWeaponClasses/Medic/NiceMedicGun.uc b/sources/Weapons/BaseWeaponClasses/Medic/NiceMedicGun.uc index f18064d..4f37338 100644 --- a/sources/Weapons/BaseWeaponClasses/Medic/NiceMedicGun.uc +++ b/sources/Weapons/BaseWeaponClasses/Medic/NiceMedicGun.uc @@ -66,19 +66,15 @@ simulated function WeaponTick(float dt){ } super.WeaponTick(dt); } - -simulated function ClientSuccessfulHeal( - NiceHumanPawn healer, - NiceHumanPawn healed -){ - if(healed == none) { - return; - } - if(instigator != none && PlayerController(instigator.controller) != none) { - PlayerController(instigator.controller).ClientMessage( - "You've healed" @ healed.GetPlayerName(), - 'CriticalEvent'); - } +simulated function ClientSuccessfulHeal(NiceHumanPawn healer, NiceHumanPawn healed){ + if(healed == none) + return; + if(instigator != none && PlayerController(instigator.controller) != none) + PlayerController(instigator.controller). + ClientMessage("You've healed"@healed.GetPlayerName(), 'CriticalEvent'); + if(NiceHumanPawn(instigator) != none && PlayerController(healed.controller) != none) + PlayerController(healed.controller). + ClientMessage("You've been healed by"@healer.GetPlayerName(), 'CriticalEvent'); } defaultproperties diff --git a/sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeFire.uc b/sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeFire.uc index f4cfd8c..23195ed 100644 --- a/sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeFire.uc +++ b/sources/Weapons/BaseWeaponClasses/Melee/NiceMeleeFire.uc @@ -272,19 +272,19 @@ simulated function HandleRecoil(float Rec){} defaultproperties { - weaponRange=70.000000 - damageDelay=0.300000 - ImpactShakeRotMag=(X=50.000000,Y=50.000000,Z=50.000000) - ImpactShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000) - ImpactShakeRotTime=2.000000 - ImpactShakeOffsetMag=(X=10.000000,Y=10.000000,Z=10.000000) - ImpactShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) - ImpactShakeOffsetTime=2.000000 - MeleeHitVolume=1.000000 - HitEffectClass=Class'KFMod.KFMeleeHitEffect' - WideDamageMinHitAngle=1.000000 - bFiringDoesntAffectMovement=True - FireEndAnim= - FireForce="ShockRifleFire" - aimerror=100.000000 + weaponRange=70.000000 + damageDelay=0.300000 + ImpactShakeRotMag=(X=50.000000,Y=50.000000,Z=50.000000) + ImpactShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000) + ImpactShakeRotTime=2.000000 + ImpactShakeOffsetMag=(X=10.000000,Y=10.000000,Z=10.000000) + ImpactShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) + ImpactShakeOffsetTime=2.000000 + MeleeHitVolume=1.000000 + HitEffectClass=Class'KFMod.KFMeleeHitEffect' + WideDamageMinHitAngle=1.000000 + bFiringDoesntAffectMovement=True + FireEndAnim= + FireForce="ShockRifleFire" + aimerror=100.000000 } diff --git a/sources/Weapons/BaseWeaponClasses/NiceScopedWeapon.uc b/sources/Weapons/BaseWeaponClasses/NiceScopedWeapon.uc index 009bf41..b5c5e03 100644 --- a/sources/Weapons/BaseWeaponClasses/NiceScopedWeapon.uc +++ b/sources/Weapons/BaseWeaponClasses/NiceScopedWeapon.uc @@ -3,7 +3,7 @@ class NiceScopedWeapon extends NiceWeapon #exec OBJ LOAD FILE=ScopeShaders.utx #exec OBJ LOAD FILE=..\Textures\NicePackT.utx #exec OBJ LOAD FILE=ScrnWeaponPack_T.utx -#exec OBJ LOAD FILE=ScrnWeaponPack_A.ukx +#exec OBJ LOAD FILE=ScrnWeaponPack_A.ukx var() Material ZoomMat; var() Sound ZoomSound; var() int lenseMaterialID; // used since material id's seem to change alot @@ -18,47 +18,31 @@ var Shader ScopeScriptedShader; // The shader that combi var Material ScriptedTextureFallback; // The texture to render if the users system doesn't support shaders // new scope vars var Combiner ScriptedScopeCombiner; -var Material TexturedScopeTexture; +var texture TexturedScopeTexture; var bool bInitializedScope; // Set to true when the scope has been initialized var string ZoomMatRef; var string ScriptedTextureFallbackRef; -var Material CrosshairTex; +var texture CrosshairTex; var string CrosshairTexRef; - -static function Material PreloadUnknownMaterial(string reference) { - local Material result; - - // Try to load as various types of materials - result = FinalBlend(DynamicLoadObject(reference, class'FinalBlend', true)); - if(result != none) { - return result; - } - result = Combiner(DynamicLoadObject(reference, class'Combiner', true)); - if(result != none) { - return result; - } - result = Shader(DynamicLoadObject(reference, class'Shader', true)); - if(result != none) { - return result; - } - result = Texture(DynamicLoadObject(reference, class'Texture', true)); - if(result != none) { - return result; - } - result = Material(DynamicLoadObject(reference, class'Material')); - return result; -} - static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount){ local NiceScopedWeapon W; super.PreloadAssets(Inv, bSkipRefCount); if(default.ZoomMat == none && default.ZoomMatRef != ""){ - default.ZoomMat = PreloadUnknownMaterial(default.ZoomMatRef); + // Try to load as various types of materials + default.ZoomMat = FinalBlend(DynamicLoadObject(default.ZoomMatRef, class'FinalBlend', true)); + if(default.ZoomMat == none) + default.ZoomMat = Combiner(DynamicLoadObject(default.ZoomMatRef, class'Combiner', true)); + if(default.ZoomMat == none) + default.ZoomMat = Shader(DynamicLoadObject(default.ZoomMatRef, class'Shader', true)); + if(default.ZoomMat == none) + default.ZoomMat = Texture(DynamicLoadObject(default.ZoomMatRef, class'Texture', true)); + if(default.ZoomMat == none) + default.ZoomMat = Material(DynamicLoadObject(default.ZoomMatRef, class'Material')); } if(default.ScriptedTextureFallback == none && default.ScriptedTextureFallbackRef != "") - default.ScriptedTextureFallback = PreloadUnknownMaterial(default.ScriptedTextureFallbackRef); + default.ScriptedTextureFallback = texture(DynamicLoadObject(default.ScriptedTextureFallbackRef, class'texture')); if(default.CrosshairTex == none && default.CrosshairTexRef != "") - default.CrosshairTex = PreloadUnknownMaterial(default.CrosshairTexRef); + default.CrosshairTex = Texture(DynamicLoadObject(default.CrosshairTexRef, class'texture')); W = NiceScopedWeapon(Inv); if(W != none){ W.ZoomMat = default.ZoomMat; diff --git a/sources/Weapons/BaseWeaponClasses/NiceWeaponDamageType.uc b/sources/Weapons/BaseWeaponClasses/NiceWeaponDamageType.uc index 2afb911..62fc867 100644 --- a/sources/Weapons/BaseWeaponClasses/NiceWeaponDamageType.uc +++ b/sources/Weapons/BaseWeaponClasses/NiceWeaponDamageType.uc @@ -14,7 +14,6 @@ var float prReqPrecise; // How precise must head-shot be var float lockonTime; var float flinchMultiplier; // How effective is weapon for flinching zeds var float stunMultiplier; // How effective is weapon for stunning zeds -var float stunLengthMultiplier; // For how long is weapon going to stun zeds var float heatPart; // How much of this damage should be a heat component? var float freezePower; // How good is weapon at freezing? var float bodyDestructionMult; // How much more damage do to body on a head-shot? @@ -28,7 +27,6 @@ var const int MediumZedMinHealth; // If zed's base Health >= this var float PenDmgReduction; // Penetration damage reduction after hitting small zed var float penDecapReduction; // Penetration decapitaion effectiveness reduction after hitting small zed var float penIncapReduction; // Penetration incapacitation (flinch or stun) effectiveness reduction after hitting small zed -var float stoppingPower; // How much stopping power the gun has - % amount zeds will be made to slow down when shot var bool bIsProjectile; // If original damage type's version was derived from 'KFProjectileWeaponDamageType', then set this to true // Scales exp gain according to given HardcoreLevel static function float getScale(int HL){ @@ -85,13 +83,11 @@ defaultproperties prReqPrecise=0.750000 flinchMultiplier=1.000000 stunMultiplier=1.000000 - stunLengthMultiplier=1.000000 bodyDestructionMult=1.000000 headSizeModifier=1.000000 BigZedPenDmgReduction=0.500000 BigZedMinHealth=1000 MediumZedPenDmgReduction=0.750000 - stoppingPower=0.0 MediumZedMinHealth=500 PenDmgReduction=0.700000 PawnDamageEmitter=None diff --git a/sources/Weapons/NiceBullet.uc b/sources/Weapons/NiceBullet.uc index 216ee99..6a60342 100644 --- a/sources/Weapons/NiceBullet.uc +++ b/sources/Weapons/NiceBullet.uc @@ -1,209 +1,202 @@ //====================================================================================================================== -// NicePack / NiceBullet +// NicePack / NiceBullet //====================================================================================================================== -// Bullet class that's supposed to take care of all damage-dealing projectile needs. -// Functionality: -// - Simulation of both linear and piece-wise motion -// - Collision detection that can be handled through the adapter class +// Bullet class that's supposed to take care of all damage-dealing projectile needs. +// Functionality: +// - Simulation of both linear and piece-wise motion +// - Collision detection that can be handled through the adapter class //====================================================================================================================== -// 'Nice pack' source -// Do whatever the fuck you want with it -// Author: dkanus -// E-mail: dkanus@gmail.com +// 'Nice pack' source +// Do whatever the fuck you want with it +// Author: dkanus +// E-mail: dkanus@gmail.com //====================================================================================================================== class NiceBullet extends Actor; - -// Link to interaction with the server +// Link to interaction with the server var NiceReplicationInfo niceRI; -// Controller of our instigator +// Controller of our instigator var NicePlayerController nicePlayer; -// Controller of local player +// Controller of local player var NicePlayerController localPlayer; -// Link to our mutator +// Link to our mutator var NicePack niceMutator; + //====================================================================================================================== -// Battle bullet characteristic -var float charOrigDamage; -var float charDamage; -var float decapMod; -var float incapMod; -var int charPenetrationCount; -var float charMomentumTransfer; +// Battle bullet characteristic +var float charOrigDamage; +var float charDamage; +var float decapMod; +var float incapMod; +var int charPenetrationCount; +var float charMomentumTransfer; var class charDamageType; var class charExplosionDamageType; -var float charExplosionDamage; -var float charExplosionRadius; -var float charExplosionExponent; -var float charExplosionMomentum; -var bool charIsDud; -var float charFuseTime; -var bool charExplodeOnFuse; -var bool charExplodeOnPawnHit; -var bool charExplodeOnWallHit; -var bool charAffectedByScream; -var float charMinExplosionDist; -var bool charWasHipFired; -var bool charCausePain; -var bool charIsSticky; -var float charContiniousBonus; -var bool bAlreadyHitZed; -var NiceWeapon sourceWeapon; -var NiceMonster lockonZed; -var float lockonTime; -var float bounceHeadMod; -var int insideBouncesLeft; -var bool bGrazing; +var float charExplosionDamage; +var float charExplosionRadius; +var float charExplosionExponent; +var float charExplosionMomentum; +var bool charIsDud; +var float charFuseTime; +var bool charExplodeOnFuse; +var bool charExplodeOnPawnHit; +var bool charExplodeOnWallHit; +var bool charAffectedByScream; +var float charMinExplosionDist; +var bool charWasHipFired; +var bool charCausePain; +var bool charIsSticky; +var float charContiniousBonus; +var bool bAlreadyHitZed; +var NiceWeapon sourceWeapon; +var NiceMonster lockonZed; +var float lockonTime; +var float bounceHeadMod; +var int insideBouncesLeft; +var bool bGrazing; //====================================================================================================================== -// Sticky projectile-related variables -var bool bStuck, bUseBone, bStuckToHead; -var name stuckBone; -var int stuckID; -// Data about explosive characteristics that must be transfered after projectile sticks on something +// Sticky projectile-related variables +var bool bStuck, bUseBone, bStuckToHead; +var name stuckBone; +var int stuckID; +// Data about explosive characteristics that must be transfered after projectile sticks on something struct ExplosionData{ - var Pawn instigator; - var NiceWeapon sourceWeapon; - var class bulletClass; + var Pawn instigator; + var NiceWeapon sourceWeapon; + var class bulletClass; var class explosionDamageType; - var float explosionDamage; - var float explosionRadius; - var float explosionExponent; - var float explosionMomentum; - var float fuseTime; - var bool explodeOnFuse; - var bool affectedByScream; - var bool stuckToHead; + var float explosionDamage; + var float explosionRadius; + var float explosionExponent; + var float explosionMomentum; + var float fuseTime; + var bool explodeOnFuse; + var bool affectedByScream; + var bool stuckToHead; }; //====================================================================================================================== -// Temporary variables that either need to be moved into config or generalized later -// How often trajectory is allowed to change direction? +// Temporary variables that either need to be moved into config or generalized later +// How often trajectory is allowed to change direction? var const float trajUpdFreq; -// How much tracing cycles to endure before declaring an infinite cycle? -var const int maxTraceCycles; -var bool bCanAngleDamage; +// How much tracing cycles to endure before declaring an infinite cycle? +var const int maxTraceCycles; +var bool bCanAngleDamage; //====================================================================================================================== -// State variables -// Indicates that all necessary values were recorded and we can process this bullet normally -var bool bInitFinished; -var bool bInitFinishDetected; -// Disables all the interaction of this bullet with the world and removes it / marks it for removal -var bool bBulletDead; -var bool bGhost; +// State variables +// Indicates that all necessary values were recorded and we can process this bullet normally +var bool bInitFinished; +var bool bInitFinishDetected; +// Disables all the interaction of this bullet with the world and removes it / marks it for removal +var bool bBulletDead; +var bool bGhost; //====================================================================================================================== -// Collision management -// Describes an actor that we don't wish to collide with +// Collision management +// Describes an actor that we don't wish to collide with struct IgnoreEntry{ - var Actor ignored; - // Set to true when 3rd party already disabled this actor before we had the chance - // Used to avoid re-enabling it later - var bool bExtDisabled; + var Actor ignored; + // Set to true when 3rd party already disabled this actor before we had the chance + // Used to avoid re-enabling it later + var bool bExtDisabled; }; -var array ignoredActors; -// 'true' if we're enforcing our collision rules on actors to ignore them -var bool bIgnoreIsActive; +var array ignoredActors; +// 'true' if we're enforcing our collision rules on actors to ignore them +var bool bIgnoreIsActive; //====================================================================================================================== -// Movement -// If 'true' disables any modifications to the bullet's movement, making it travel in a simple, linear path -var bool bDisableComplexMovement; -// Linear motion -var float movementSpeed; -var Vector movementDirection; -// Added vector acceleration -var Vector movementAcceleration; -var bool bShouldBounce; -// Amount of time our bullet should fall down after hitting a wall -var float movementFallTime; +// Movement +// If 'true' disables any modifications to the bullet's movement, making it travel in a simple, linear path +var bool bDisableComplexMovement; +// Linear motion +var float movementSpeed; +var Vector movementDirection; +// Added vector acceleration +var Vector movementAcceleration; +var bool bShouldBounce; +// Amount of time our bullet should fall down after hitting a wall +var float movementFallTime; //====================================================================================================================== -// Path building -// We will be building a piecewise linear path for projectiles, where each linear segment should be passable by -// projectile in time 'trajUpdFreq'. -// By changing trajectory in only preset point allow client to emulate non-linear paths, -// while keeping them more or less independent from the frame rate. -// Start and End point of the current linear segment +// Path building +// We will be building a piecewise linear path for projectiles, where each linear segment should be passable by +// projectile in time 'trajUpdFreq'. +// By changing trajectory in only preset point allow client to emulate non-linear paths, +// while keeping them more or less independent from the frame rate. +// Start and End point of the current linear segment var Vector pathSegmentS, pathSegmentE; -// Point in the segment, at which we've stopped after last movement +// Point in the segment, at which we've stopped after last movement var Vector shiftPoint; -// The part of current segment that we've already covered, changes from 0.0 to 1.0. -// Values above 1.0 indicate that segment was finished and we need to build another one. -// Values below 0.0 indicate that no segment has yet been built. +// The part of current segment that we've already covered, changes from 0.0 to 1.0. +// Values above 1.0 indicate that segment was finished and we need to build another one. +// Values below 0.0 indicate that no segment has yet been built. var float finishedSegmentPart; //====================================================================================================================== -// Visual effects -var class trailClass; +// Visual effects +var class trailClass; var class trailXClass; -var Emitter bulletTrail; -var xEmitter bulletXTrail; -// Describes effect that projectile should produce on hit -struct ImpactEffect { - // Is this effect too important to cut it due to effect limit? - var bool bImportanEffect; - // Should we play classic KF's hit effect ('ROBulletHitEffect')? - var bool bPlayROEffect; - // Decal to spawn; null to skip - var class decalClass; - // Emitter to spawn; null to skip - var class emitterClass; - // How much back (against direction of the shot) should we spawn emitter? Can be used to avoid clipping with walls - var float emitterShiftWall; // Shift for wall-hits - var float emitterShiftPawn; // Shift for pawn-hits - // Impact noise parameters - var Sound noise; - var string noiseRef; // Reference to 'Sound' to allow dynamic resource allocation - var float noiseVolume; +var Emitter bulletTrail; +var xEmitter bulletXTrail; +// Describes effect that projectile should produce on hit +struct ImpactEffect{ + // Is this effect too important to cut it due to effect limit? + var bool bImportanEffect; + // Should we play classic KF's hit effect ('ROBulletHitEffect')? + var bool bPlayROEffect; + // Decal to spawn; null to skip + var class decalClass; + // Emitter to spawn; null to skip + var class emitterClass; + // How much back (against direction of the shot) should we spawn emitter? Can be used to avoid clipping with walls + var float emitterShiftWall; // Shift for wall-hits + var float emitterShiftPawn; // Shift for pawn-hits + // Impact noise parameters + var Sound noise; + var string noiseRef; // Reference to 'Sound' to allow dynamic resource allocation + var float noiseVolume; }; -var ImpactEffect regularImpact; -var ImpactEffect explosionImpact; -var ImpactEffect disintegrationImpact; -var bool bGenRegEffectOnPawn; -var bool bShakeViewOnExplosion; -var Vector shakeRotMag; // how far to rot view -var Vector shakeRotRate; // how fast to rot view -var float shakeRotTime; // how much time to rot the instigator's view -var Vector shakeOffsetMag; // max view offset vertically -var Vector shakeOffsetRate; // how fast to offset view vertically -var float shakeOffsetTime; // how much time to offset view -var float shakeRadiusMult; +var ImpactEffect regularImpact; +var ImpactEffect explosionImpact; +var ImpactEffect disintegrationImpact; +var bool bGenRegEffectOnPawn; +var bool bShakeViewOnExplosion; +var Vector shakeRotMag; // how far to rot view +var Vector shakeRotRate; // how fast to rot view +var float shakeRotTime; // how much time to rot the instigator's view +var Vector shakeOffsetMag; // max view offset vertically +var Vector shakeOffsetRate; // how fast to offset view vertically +var float shakeOffsetTime; // how much time to offset view +var float shakeRadiusMult; //====================================================================================================================== -// References -// References to allow pre-loading of some resource objects, declared in parent classes +// References +// References to allow pre-loading of some resource objects, declared in parent classes var string meshRef; var string staticMeshRef; var string ambientSoundRef; //====================================================================================================================== -// Functions -static function PreloadAssets() { - if (default.ambientSound == none && default.ambientSoundRef != "") { - default.ambientSound = sound(DynamicLoadObject(default.ambientSoundRef, class'Sound', true)); - } - if (default.staticMesh == none && default.staticMeshRef != "") { - UpdateDefaultStaticMesh(StaticMesh(DynamicLoadObject(default.staticMeshRef, class'StaticMesh', true))); - } - if (default.mesh == none && default.meshRef != "") { - UpdateDefaultMesh(Mesh(DynamicLoadObject(default.meshRef, class'Mesh', true))); - } - if (default.regularImpact.noise == none && default.regularImpact.noiseRef != "") { - default.regularImpact.noise = - sound(DynamicLoadObject(default.regularImpact.noiseRef, class'Sound', true)); - } - if (default.explosionImpact.noise == none && default.explosionImpact.noiseRef != "") { - default.explosionImpact.noise = - sound(DynamicLoadObject(default.explosionImpact.noiseRef, class'Sound', true)); - } - if (default.disintegrationImpact.noise == none && default.disintegrationImpact.noiseRef != "") { - default.disintegrationImpact.noise = - sound(DynamicLoadObject(default.disintegrationImpact.noiseRef, class'Sound', true)); - } +// Functions +static function PreloadAssets(){ + if(default.ambientSound == none && default.ambientSoundRef != "") + default.ambientSound = sound(DynamicLoadObject(default.ambientSoundRef, class'Sound', true)); + if(default.staticMesh == none && default.staticMeshRef != "") + UpdateDefaultStaticMesh(StaticMesh(DynamicLoadObject(default.staticMeshRef, class'StaticMesh', true))); + if(default.mesh == none && default.meshRef != "") + UpdateDefaultMesh(Mesh(DynamicLoadObject(default.meshRef, class'Mesh', true))); + if(default.regularImpact.noise == none && default.regularImpact.noiseRef != "") + default.regularImpact.noise = + sound(DynamicLoadObject(default.regularImpact.noiseRef, class'Sound', true)); + if(default.explosionImpact.noise == none && default.explosionImpact.noiseRef != "") + default.explosionImpact.noise = + sound(DynamicLoadObject(default.explosionImpact.noiseRef, class'Sound', true)); + if(default.disintegrationImpact.noise == none && default.disintegrationImpact.noiseRef != "") + default.disintegrationImpact.noise = + sound(DynamicLoadObject(default.disintegrationImpact.noiseRef, class'Sound', true)); } - -static function bool UnloadAssets() { +static function bool UnloadAssets(){ default.AmbientSound = none; UpdateDefaultStaticMesh(none); UpdateDefaultMesh(none); @@ -212,494 +205,400 @@ static function bool UnloadAssets() { default.disintegrationImpact.noise = none; return true; } - -function PostBeginPlay() { +function PostBeginPlay(){ super.PostBeginPlay(); - bounceHeadMod = 1.0; + bounceHeadMod = 1.0; } - -function UpdateTrails() { +function UpdateTrails(){ local Actor trailBase; - // Do nothing on dedicated server - if (Level.NetMode == NM_DedicatedServer) { - return; - } + if(Level.NetMode == NM_DedicatedServer) + return; // Spawn necessary trails first - if (trailClass != none && bulletTrail == none) { - bulletTrail = Spawn(trailClass, self); - } - if (trailXClass != none && bulletXTrail == none) { - bulletXTrail = Spawn(trailXClass, self); - } + if(trailClass != none && bulletTrail == none) + bulletTrail = Spawn(trailClass, self); + if(trailXClass != none && bulletXTrail == none) + bulletXTrail = Spawn(trailXClass, self); // Handle positioning differently for stuck and regular projectiles - if (bStuck && base != none) { - if (bUseBone) { - if (bulletTrail != none) { - bulletTrail.SetBase(base); - base.AttachToBone(bulletTrail, stuckBone); - bulletTrail.SetRelativeLocation(relativeLocation); - bulletTrail.SetRelativeRotation(relativeRotation); - } - if (bulletXTrail != none) { - bulletXTrail.SetBase(base); - base.AttachToBone(bulletTrail, stuckBone); - bulletXTrail.SetRelativeLocation(relativeLocation); - bulletXTrail.SetRelativeRotation(relativeRotation); - } - } - } else { - trailBase = self; + if(bStuck && base != none){ + if(bUseBone){ + if(bulletTrail != none){ + bulletTrail.SetBase(base); + base.AttachToBone(bulletTrail, stuckBone); + bulletTrail.SetRelativeLocation(relativeLocation); + bulletTrail.SetRelativeRotation(relativeRotation); + } + if(bulletXTrail != none){ + bulletXTrail.SetBase(base); + base.AttachToBone(bulletTrail, stuckBone); + bulletXTrail.SetRelativeLocation(relativeLocation); + bulletXTrail.SetRelativeRotation(relativeRotation); + } + } } - + else + trailBase = self; // Update lifetime and base (latter is for non-bone attachments only) - if (bulletTrail != none) { - if (trailBase != none) { - bulletTrail.SetBase(trailBase); - } - bulletTrail.lifespan = lifeSpan; + if(bulletTrail != none){ + if(trailBase != none) + bulletTrail.SetBase(trailBase); + bulletTrail.lifespan = lifeSpan; } - if (bulletXTrail != none) { - if (trailBase != none) { - bulletXTrail.SetBase(trailBase); - } - bulletXTrail.lifespan = lifeSpan; + if(bulletXTrail != none){ + if(trailBase != none) + bulletXTrail.SetBase(trailBase); + bulletXTrail.lifespan = lifeSpan; } } - -function ResetPathBuilding() { +function ResetPathBuilding(){ finishedSegmentPart = -1.0; shiftPoint = location; } - -// Resets default values for this bullet. -// Must be called before each new use of a bullet. -function Renew() { - bInitFinished = false; - bBulletDead = false; - bCanAngleDamage = true; - SoundVolume = default.SoundVolume; +// Resets default values for this bullet. +// Must be called before each new use of a bullet. +function Renew(){ + bInitFinished = false; + bBulletDead = false; + bCanAngleDamage = true; + SoundVolume = default.SoundVolume; decapMod = 1.0f; incapMod = 1.0f; ResetIgnoreList(); ResetPathBuilding(); } - -simulated function Tick(float delta) { +simulated function Tick(float delta){ super.Tick(delta); - - if (localPlayer == none) { - localPlayer = NicePlayerController(Level.GetLocalPlayerController()); + if(localPlayer == none) + localPlayer = NicePlayerController(Level.GetLocalPlayerController()); + if(charFuseTime > 0){ + charFuseTime -= delta; + if(charFuseTime < 0){ + if(charExplodeOnFuse && !charIsDud){ + GenerateImpactEffects(explosionImpact, location, movementDirection); + if(bStuck) + class'NiceBulletAdapter'.static.Explode(self, niceRI, location, base); + else + class'NiceBulletAdapter'.static.Explode(self, niceRI, location); + } + if(!charExplodeOnFuse) + GenerateImpactEffects(disintegrationImpact, location, movementDirection); + KillBullet(); + } } - - if (charFuseTime > 0) { - charFuseTime -= delta; - if (charFuseTime < 0) { - if (charExplodeOnFuse && !charIsDud) { - GenerateImpactEffects(explosionImpact, location, movementDirection); - if (bStuck) { - class'NiceBulletAdapter'.static.Explode(self, niceRI, location, base); - } else { - class'NiceBulletAdapter'.static.Explode(self, niceRI, location); - } - } - if (!charExplodeOnFuse) { - GenerateImpactEffects(disintegrationImpact, location, movementDirection); - } - KillBullet(); - } + if(bInitFinished && !bInitFinishDetected){ + bInitFinishDetected = true; + UpdateTrails(); } - - if (bInitFinished && !bInitFinishDetected) { - bInitFinishDetected = true; - UpdateTrails(); - } - if (bInitFinished && !bBulletDead && !bStuck) { - DoProcessMovement(delta); - } - if (bInitFinished && bStuck) { - if (base == none || (KFMonster(base) != none && KFMonster(base).health <= 0)) { - nicePlayer.ExplodeStuckBullet(stuckID); - } + if(bInitFinished && !bBulletDead && !bStuck) + DoProcessMovement(delta); + if(bInitFinished && bStuck){ + if(base == none || (KFMonster(base) != none && KFMonster(base).health <= 0)) + nicePlayer.ExplodeStuckBullet(stuckID); } } - -// Extracts pawn actor from it's auxiliary collision -// @param other Actor we collided with -// @return Pawn we're interested in -function Actor GetMainActor(Actor other) { - if (other == none) { - return none; - } - - if (!other.IsA('KFPawn') && !other.IsA('KFMonster')) { - // Try owner - if (other.owner.IsA('KFPawn') || other.owner.IsA('KFMonster')) { - return other.owner; - } - // Try base - if (other.base.IsA('KFPawn') || other.base.IsA('KFMonster')) { - return other.base; - } - } - +// Extracts pawn actor from it's auxiliary collision +// @param other Actor we collided with +// @return Pawn we're interested in +function Actor GetMainActor(Actor other){ + if(other == none) + return none; + // Try owner + if( KFPawn(other) == none && KFMonster(other) == none + && (KFPawn(other.owner) != none || KFMonster(other.owner) != none) ) + other = other.owner; + // Try base + if( KFPawn(other) == none && KFMonster(other) == none + && (KFPawn(other.base) != none || KFMonster(other.base) != none) ) + other = other.base; return other; } - -// Returns 'true' if passed actor is either world geometry, 'Level' itself or nothing ('none') -// Neither of these related to pawn damage dealing -function bool IsLevelActor(Actor other) { - if (other == none) { - return true; - } +// Returns 'true' if passed actor is either world geometry, 'Level' itself or nothing ('none') +// Neither of these related to pawn damage dealing +function bool IsLevelActor(Actor other){ + if(other == none) + return true; return (other.bWorldGeometry || other == Level); } - -// Adds given actor and every colliding object connected to it to ignore list -// Removes their collision in case ignore is active (see 'bIgnoreIsActive') -function TotalIgnore(Actor other) { +// Adds given actor and every colliding object connected to it to ignore list +// Removes their collision in case ignore is active (see 'bIgnoreIsActive') +function TotalIgnore(Actor other){ // These mark what objects, associated with 'other' we also need to ignore - local KFPawn pawnOther; + local KFPawn pawnOther; local KFMonster zedOther; - - if (other == none) { - return; - } + if(other == none) + return; // Try to find main actor as KFPawn pawnOther = KFPawn(other); - if (pawnOther == none) { - pawnOther = KFPawn(other.base); - } - if (pawnOther == none) { - pawnOther = KFPawn(other.owner); - } + if(pawnOther == none) + pawnOther = KFPawn(other.base); + if(pawnOther == none) + pawnOther = KFPawn(other.owner); // Try to find main actor as KFMonster zedOther = KFMonster(other); - if (zedOther == none) { - zedOther = KFMonster(other.base); - } - if (zedOther == none) { - zedOther = KFMonster(other.owner); - } + if(zedOther == none) + zedOther = KFMonster(other.base); + if(zedOther == none) + zedOther = KFMonster(other.owner); // Ignore everything that's associated with this actor and can have collision IgnoreActor(other); IgnoreActor(other.base); IgnoreActor(other.owner); - if (pawnOther != none) { - IgnoreActor(pawnOther.AuxCollisionCylinder); - } - if (zedOther != none) { - IgnoreActor(zedOther.MyExtCollision); - } + if(pawnOther != none) + IgnoreActor(pawnOther.AuxCollisionCylinder); + if(zedOther != none) + IgnoreActor(zedOther.MyExtCollision); } - -// Adds a given actor to ignore list and removes it's collision in case ignore is active (see 'bIgnoreIsActive') -function IgnoreActor(Actor other) { - local int i; - local IgnoreEntry newIgnoredEntry; - +// Adds a given actor to ignore list and removes it's collision in case ignore is active (see 'bIgnoreIsActive') +function IgnoreActor(Actor other){ + local int i; + local IgnoreEntry newIgnoredEntry; // Check if that's a non-level actor and not already on the list - if (IsLevelActor(other)) { - return; - } - for (i = 0; i < ignoredActors.Length; i ++) { - if (ignoredActors[i].ignored == other) { - return; - } - } + if(IsLevelActor(other)) + return; + for(i = 0;i < ignoredActors.Length;i ++) + if(ignoredActors[i].ignored == other) + return; // Add actor to the ignore list & disable collision if needed - if (other != none) { - // Make entry - newIgnoredEntry.ignored = other; - newIgnoredEntry.bExtDisabled = !other.bCollideActors; - // Add and activate it - ignoredActors[ignoredActors.Length] = newIgnoredEntry; - if (bIgnoreIsActive) { - other.SetCollision(false); - } + if(other != none){ + // Make entry + newIgnoredEntry.ignored = other; + newIgnoredEntry.bExtDisabled = !other.bCollideActors; + // Add and activate it + ignoredActors[ignoredActors.Length] = newIgnoredEntry; + if(bIgnoreIsActive) + other.SetCollision(false); } } - -// Restores ignored state of the actors and zeroes our ignored arrays -function ResetIgnoreList() { +// Restores ignored state of the actors and zeroes our ignored arrays +function ResetIgnoreList(){ SetIgnoreActive(false); ignoredActors.Length = 0; } - -// Activates/deactivates ignore for actors on the ignore list. -// Ignore deactivation doesn't restore collision if actor was set to not collide prior most recent ignore activation. -// Activating ignore when it's already active does nothing; same with deactivation. -// Ignore deactivation is supposed to be used in the same function call in which activation took place before. -function SetIgnoreActive(bool bActive) { +// Activates/deactivates ignore for actors on the ignore list. +// Ignore deactivation doesn't restore collision if actor was set to not collide prior most recent ignore activation. +// Activating ignore when it's already active does nothing; same with deactivation. +// Ignore deactivation is supposed to be used in the same function call in which activation took place before. +function SetIgnoreActive(bool bActive){ local int i; - // Do nothing if we're already in a correct state - if (bActive == bIgnoreIsActive) { - return; - } + if(bActive == bIgnoreIsActive) + return; // Change ignore state & disable collision for ignored actors bIgnoreIsActive = bActive; - for (i = 0; i < ignoredActors.Length; i ++) { - if (ignoredActors[i].ignored != none) { - // Mark actors that were set to not collide before activation - if (bActive && !ignoredActors[i].ignored.bCollideActors) { - ignoredActors[i].bExtDisabled = true; - } - // Change collision for actors that weren't externally modified - if (!ignoredActors[i].bExtDisabled) { - ignoredActors[i].ignored.SetCollision(!bActive); - } - // After we deactivated our rules - forget about external modifications - if (!bActive) { - ignoredActors[i].bExtDisabled = false; - } - } - } + for(i = 0;i < ignoredActors.Length;i ++) + if(ignoredActors[i].ignored != none){ + // Mark actors that were set to not collide before activation + if(bActive && !ignoredActors[i].ignored.bCollideActors) + ignoredActors[i].bExtDisabled = true; + // Change collision for actors that weren't externally modified + if(!ignoredActors[i].bExtDisabled) + ignoredActors[i].ignored.SetCollision(!bActive); + // After we deactivated our rules - forget about external modifications + if(!bActive) + ignoredActors[i].bExtDisabled = false; + } } - -function SetHumanPawnCollision(bool bEnable) { +function SetHumanPawnCollision(bool bEnable){ local int i; - - if (niceMutator == none) { - niceMutator = class'NicePack'.static.Myself(Level); - } - - for (i = 0; i < niceMutator.recordedHumanPawns.Length; i ++) { - if (niceMutator.recordedHumanPawns[i] != none) { - niceMutator.recordedHumanPawns[i].bBlockHitPointTraces = bEnable; - } - } + if(niceMutator == none) + niceMutator = class'NicePack'.static.Myself(Level); + for(i = 0;i < niceMutator.recordedHumanPawns.Length;i ++) + if(niceMutator.recordedHumanPawns[i] != none) + niceMutator.recordedHumanPawns[i].bBlockHitPointTraces = bEnable; } - -function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDirection) { - local float hsMod; - local float precision; - local bool bIsShotgunBullet; - local NiceMonster niceZed; - local KFPlayerReplicationInfo KFPRI; +function float CheckHeadshot(KFMonster kfZed, Vector hitLocation, Vector hitDirection){ + local float hsMod; + local float precision; + local bool bIsShotgunBullet; + local NiceMonster niceZed; + local KFPlayerReplicationInfo KFPRI; local class niceVet; - niceZed = NiceMonster(kfZed); hitDirection = Normal(hitDirection); bIsShotgunBullet = ClassIsChildOf(charDamageType, class'NiceDamageTypeVetEnforcer'); - if (niceZed != none) { - hsMod = bounceHeadMod; // NICETODO: Add bounce and perk and damage type head-shot zones bonuses - hsMod *= charDamageType.default.headSizeModifier; - hsMod *= bounceHeadMod; - if (nicePlayer != none) { - KFPRI = KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo); - } - if (KFPRI != none) { - niceVet = class(KFPRI.ClientVeteranSkill); - } - if (niceVet != none) { - hsMod *= niceVet.static.GetHeadshotCheckMultiplier(KFPRI, charDamageType); - } - precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod); - if ( - precision <= 0.0 && - bIsShotgunBullet && - nicePlayer != none && - class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillSupportGraze') - ) { - bGrazing = true; - hsMod *= class'NiceSkillSupportGraze'.default.hsBonusZoneMult; - precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod); - } - return precision; - } else { - if (kfZed.IsHeadShot(hitLocation, hitDirection, 1.0)) { - return 1.0; - } else { - return 0.0; - } + if(niceZed != none){ + hsMod = bounceHeadMod; // NICETODO: Add bounce and perk and damage type head-shot zones bonuses + hsMod *= charDamageType.default.headSizeModifier; + hsMod *= bounceHeadMod; + if(nicePlayer != none) + KFPRI = KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo); + if(KFPRI != none) + niceVet = class(KFPRI.ClientVeteranSkill); + if(niceVet != none) + hsMod *= niceVet.static.GetHeadshotCheckMultiplier(KFPRI, charDamageType); + precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod); + if(precision <= 0.0 && bIsShotgunBullet && nicePlayer != none && class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillSupportGraze')){ + bGrazing = true; + hsMod *= class'NiceSkillSupportGraze'.default.hsBonusZoneMult; + precision = niceZed.IsHeadshotClient(hitLocation, hitDirection, niceZed.clientHeadshotScale * hsMod); + } + return precision; + } + else{ + if(kfZed.IsHeadShot(hitLocation, hitDirection, 1.0)) + return 1.0; + else + return 0.0; } } - -// Makes bullet trace a directed line segment given by start and end points. -// All traced actors and geometry are then properly affected by corresponding 'HandleHitPawn', 'HandleHitZed' and -// 'HandleHitWall' functions. -// Might have to do several traces in case it either hits a (several) target(s) -function DoTraceLine(Vector lineStart, Vector lineEnd) { - local float headshotLevel; +// Makes bullet trace a directed line segment given by start and end points. +// All traced actors and geometry are then properly affected by corresponding 'HandleHitPawn', 'HandleHitZed' and +// 'HandleHitWall' functions. +// Might have to do several traces in case it either hits a (several) target(s) +function DoTraceLine(Vector lineStart, Vector lineEnd){ + local float headshotLevel; // Amount of tracing iterations we had to do - local int iterationCount; + local int iterationCount; // Direction and length of traced line - local Vector lineDirection; + local Vector lineDirection; // Auxiliary variables for retrieving results of tracing - local Vector hitLocation, hitNormal; - local Actor tracedActor; - local array hitPoints; - local KFMonster tracedZed; - local KFPawn tracedPawn; - + local Vector hitLocation, hitNormal; + local Actor tracedActor; + local array hitPoints; + local KFMonster tracedZed; + local KFPawn tracedPawn; lineDirection = (lineEnd - lineStart); lineDirection = (lineDirection) / VSize(lineDirection); // Do not trace for disabled bullets and prevent infinite loops - while (!bBulletDead && iterationCount < maxTraceCycles) { - iterationCount++; - // Trace next object - if (!bGhost || localPlayer == none || localPlayer.tracesThisTick <= localPlayer.tracesPerTickLimit) { - if (Instigator != none) { - tracedActor = Instigator.Trace(hitLocation, hitNormal, lineEnd, lineStart, true); - } else { - tracedActor = none; - } - localPlayer.tracesThisTick++; - } else { - tracedActor = none; - } - if ( - charAffectedByScream && - !charIsDud && - localPlayer != none && - localPlayer.localCollisionManager != none && - localPlayer.localCollisionManager.IsCollidingWithAnything(lineStart, lineEnd) - ) { - HandleScream(lineStart, lineDirection); - } - if (tracedActor != none && IsLevelActor(tracedActor)) { - HandleHitWall(tracedActor, hitLocation, hitNormal); - break; - } else { - TotalIgnore(tracedActor); - tracedActor = GetMainActor(tracedActor); - } + while(!bBulletDead && iterationCount < maxTraceCycles){ + iterationCount ++; + // Trace next object + if(!bGhost || localPlayer == none || localPlayer.tracesThisTick <= localPlayer.tracesPerTickLimit){ + if(Instigator != none) + tracedActor = Instigator.Trace(hitLocation, hitNormal, lineEnd, lineStart, true); + else + tracedActor = none; + localPlayer.tracesThisTick ++; + } + else + tracedActor = none; + if(charAffectedByScream && !charIsDud && localPlayer != none && localPlayer.localCollisionManager != none && localPlayer.localCollisionManager.IsCollidingWithAnything(lineStart, lineEnd)) + HandleScream(lineStart, lineDirection); + if(tracedActor != none && IsLevelActor(tracedActor)){ + HandleHitWall(tracedActor, hitLocation, hitNormal); + break; + } + else{ + TotalIgnore(tracedActor); + tracedActor = GetMainActor(tracedActor); + } - // If tracing between current trace points haven't found anything and tracing step is less than segment's length - // -- shift tracing bounds - if (tracedActor == none) { - return; - } + // If tracing between current trace points haven't found anything and tracing step is less than segment's length + // -- shift tracing bounds + if(tracedActor == none) + return; - // First, try to handle pawn like a zed; if fails, - try to handle it like 'KFPawn' - tracedZed = KFMonster(tracedActor); - tracedPawn = KFPawn(tracedActor); - if ( - tracedPawn != none && - NiceHumanPawn(instigator) != none && - (NiceHumanPawn(instigator).ffScale <= 0 && NiceMedicProjectile(self) == none) - ) { - continue; - } - if (tracedZed != none) { - if (tracedZed.Health > 0) { - headshotLevel = CheckHeadshot(tracedZed, hitLocation, lineDirection); - HandleHitZed(tracedZed, hitLocation, lineDirection, headshotLevel); - } - } else if (tracedPawn != none && tracedPawn.Health > 0) { - if (tracedPawn.Health > 0) { - HandleHitPawn(tracedPawn, hitLocation, lineDirection, hitPoints); - } - } else { - HandleHitWall(tracedActor, hitLocation, hitNormal); - } + // First, try to handle pawn like a zed; if fails, - try to handle it like 'KFPawn' + tracedZed = KFMonster(tracedActor); + tracedPawn = KFPawn(tracedActor); + if(tracedPawn != none && NiceHumanPawn(instigator) != none && + (NiceHumanPawn(instigator).ffScale <= 0 && NiceMedicProjectile(self) == none) ) + continue; + if(tracedZed != none){ + if(tracedZed.Health > 0){ + headshotLevel = CheckHeadshot(tracedZed, hitLocation, lineDirection); + HandleHitZed(tracedZed, hitLocation, lineDirection, headshotLevel); + } + } + else if(tracedPawn != none && tracedPawn.Health > 0){ + if(tracedPawn.Health > 0) + HandleHitPawn(tracedPawn, hitLocation, lineDirection, hitPoints); + } + else + HandleHitWall(tracedActor, hitLocation, hitNormal); } } - -// Replaces current path segment with the next one. -// Doesn't check whether or not we've finished with the current segment. -function BuildNextPathSegment() { +// Replaces current path segment with the next one. +// Doesn't check whether or not we've finished with the current segment. +function BuildNextPathSegment(){ // Only set start point to our location when we build path segment for the first time // After that we can't even assume that bullet is exactly in the 'pathSegmentE' point - if (finishedSegmentPart < 0.0) { - pathSegmentS = Location; - } else { - pathSegmentS = pathSegmentE; - } + if(finishedSegmentPart < 0.0) + pathSegmentS = Location; + else + pathSegmentS = pathSegmentE; movementDirection += (movementAcceleration * trajUpdFreq) / movementSpeed; pathSegmentE = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq; finishedSegmentPart = 0.0; shiftPoint = pathSegmentS; } - -// Updates 'shiftPoint' to the next bullet position in current segment. -// Does nothing if current segment is finished or no segment was built at all. -// @param delta Amount of time bullet has to move through the segment. -// @return Amount of time left for bullet to move after this segment -function float ShiftInSegment(float delta) { +// Updates 'shiftPoint' to the next bullet position in current segment. +// Does nothing if current segment is finished or no segment was built at all. +// @param delta Amount of time bullet has to move through the segment. +// @return Amount of time left for bullet to move after this segment +function float ShiftInSegment(float delta){ // Time that bullet still has available to move after this segment local float remainingTime; // Part of segment we can pass in a given time local float segmentPartWeCanPass; - // Exit if there's no segment in progress - if (finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) { - return delta; - } + if(finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) + return delta; // [movementSpeed * delta] / [movementSpeed * trajUpdFreq] = [delta / trajUpdFreq] segmentPartWeCanPass = delta / trajUpdFreq; // If we can move through the rest of the segment - move to end point and mark it finished - if (segmentPartWeCanPass >= (1.0 - finishedSegmentPart)) { - remainingTime = delta - (1.0 - finishedSegmentPart) * trajUpdFreq; - finishedSegmentPart = 1.1; - shiftPoint = pathSegmentE; - } else { - // Otherwise compute new 'shiftPoint' normally - remainingTime = 0.0; - finishedSegmentPart += (delta / trajUpdFreq); - shiftPoint = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq * finishedSegmentPart; + if(segmentPartWeCanPass >= (1.0 - finishedSegmentPart)){ + remainingTime = delta - (1.0 - finishedSegmentPart) * trajUpdFreq; + finishedSegmentPart = 1.1; + shiftPoint = pathSegmentE; + } + // Otherwise compute new 'shiftPoint' normally + else{ + remainingTime = 0.0; + finishedSegmentPart += (delta / trajUpdFreq); + shiftPoint = pathSegmentS + movementDirection * movementSpeed * trajUpdFreq * finishedSegmentPart; } return remainingTime; } - -// Moves bullet according to settings and decides when and how much tracing should it do. -// @param delta Amount of time passed after previous bullet movement -function DoProcessMovement(float delta) { - local Vector tempVect; - +// Moves bullet according to settings and decides when and how much tracing should it do. +// @param delta Amount of time passed after previous bullet movement +function DoProcessMovement(float delta){ + local Vector tempVect; SetIgnoreActive(true); //SetHumanPawnCollision(true); - // Simple linear movement - if (bDisableComplexMovement) { - // Use 'traceStart' as a shift variable here - // Naming is bad in this case, but it avoids - tempVect = movementDirection * movementSpeed * delta; - DoTraceLine(location, location + tempVect); - Move(tempVect); - // Reset path building - // If in future complex movement would be re-enabled, - we want to set first point of the path to - // the location of bullet at a time and not use outdated information. - finishedSegmentPart = -1.0; - } else { - // Non-linear movement support - while(delta > 0.0) { - if (finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) { - BuildNextPathSegment(); - } - // Remember current 'shiftPoint'. That's where we stopped tracing last time and where we must resume. - tempVect = shiftPoint; - // Update 'shiftPoint' (bullet position) - // and update how much time we've got left after we wasted some to move. - delta = ShiftInSegment(delta); - // Trace between end point of previous tracing and end point of the new one. - DoTraceLine(tempVect, shiftPoint); - } - tempVect = shiftPoint - location; - Move(shiftPoint - location); + // Simple linear movement + if(bDisableComplexMovement){ + // Use 'traceStart' as a shift variable here + // Naming is bad in this case, but it avoids + tempVect = movementDirection * movementSpeed * delta; + DoTraceLine(location, location + tempVect); + Move(tempVect); + // Reset path building + // If in future complex movement would be re-enabled, - we want to set first point of the path to + // the location of bullet at a time and not use outdated information. + finishedSegmentPart = -1.0; + } + // Non-linear movement support + else{ + while(delta > 0.0){ + if(finishedSegmentPart < 0.0 || finishedSegmentPart > 1.0) + BuildNextPathSegment(); + // Remember current 'shiftPoint'. That's where we stopped tracing last time and where we must resume. + tempVect = shiftPoint; + // Update 'shiftPoint' (bullet position) + // and update how much time we've got left after we wasted some to move. + delta = ShiftInSegment(delta); + // Trace between end point of previous tracing and end point of the new one. + DoTraceLine(tempVect, shiftPoint); + } + tempVect = shiftPoint - location; + Move(shiftPoint - location); } SetRotation(Rotator(movementDirection)); - if (charMinExplosionDist > 0) { - charMinExplosionDist -= VSize(tempVect); - } + if(charMinExplosionDist > 0) + charMinExplosionDist -= VSize(tempVect); SetIgnoreActive(false); - // SetHumanPawnCollision(false); + //SetHumanPawnCollision(false); } - -function Stick(Actor target, Vector hitLocation) { - local Vector boneStrickOrig; +function Stick(Actor target, Vector hitLocation){ + local NiceMonster targetZed; + local name boneStick; + local float distToBone; + local float t; + local Vector boneStrickOrig; local ExplosionData expData; - local Actor resultTarget; - local NiceMonster targetZed; - local name boneStick; - local float distToBone, t; - - if (bGhost) { - return; - } - expData.instigator = instigator; - expData.sourceWeapon = sourceWeapon; - expData.bulletClass = class; + if(bGhost) + return; expData.explosionDamageType = charExplosionDamageType; expData.explosionDamage = charExplosionDamage; expData.explosionRadius = charExplosionRadius; @@ -708,310 +607,238 @@ function Stick(Actor target, Vector hitLocation) { expData.fuseTime = charFuseTime; expData.explodeOnFuse = charExplodeOnFuse; expData.affectedByScream = charAffectedByScream; - - if (!target.IsA('NiceMonster')) { - hitLocation = (hitLocation - target.location) << target.rotation; - boneStick = 'None'; - resultTarget = target; - } else { - targetZed = NiceMonster(target); - boneStick = targetZed.GetClosestBone(hitLocation, movementDirection, distToBone); - if (CheckHeadshot(targetZed, hitLocation, movementDirection) > 0.0) { - boneStick = targetZed.HeadBone; - } - if (boneStick == targetZed.HeadBone) { - expData.stuckToHead = true; - } - boneStrickOrig = targetZed.GetBoneCoords(boneStick).origin; - t = movementDirection.x * (boneStrickOrig.x - hitLocation.x) + - movementDirection.y * (boneStrickOrig.y - hitLocation.y) + - movementDirection.z * (boneStrickOrig.z - hitLocation.z); - t /= VSizeSquared(movementDirection); - t *= 0.5; - hitLocation = hitLocation + t * movementDirection; - hitLocation -= boneStrickOrig; - resultTarget = targetZed; + expData.sourceWeapon = sourceWeapon; + targetZed = NiceMonster(target); + if(targetZed == none){ + expData.bulletClass = class; + expData.instigator = instigator; + niceRI.ServerStickProjectile(KFHumanPawn(instigator), target, 'None', hitLocation - target.location, + Rotator(movementDirection), expData); + class'NiceProjectileSpawner'.static.StickProjectile(KFHumanPawn(instigator), target, 'None', + hitLocation - target.location, Rotator(movementDirection), expData); + } + else{ + expData.bulletClass = class; + expData.instigator = instigator; + boneStick = targetZed.GetClosestBone(hitLocation, movementDirection, distToBone); + if(CheckHeadshot(targetZed, hitLocation, movementDirection) > 0.0) + boneStick = targetZed.HeadBone; + if(boneStick == targetZed.HeadBone) + expData.stuckToHead = true; + boneStrickOrig = targetZed.GetBoneCoords(boneStick).origin; + t = movementDirection.x * (boneStrickOrig.x - hitLocation.x) + + movementDirection.y * (boneStrickOrig.y - hitLocation.y) + + movementDirection.z * (boneStrickOrig.z - hitLocation.z); + t /= VSizeSquared(movementDirection); + t *= 0.5; + hitLocation = hitLocation + t * movementDirection; + niceRI.ServerStickProjectile(KFHumanPawn(instigator), targetZed, boneStick, + hitLocation - boneStrickOrig, Rotator(movementDirection), expData); + class'NiceProjectileSpawner'.static.StickProjectile(KFHumanPawn(instigator), targetZed, boneStick, + hitLocation - boneStrickOrig, Rotator(movementDirection), expData); } - - niceRI.ServerStickProjectile( - KFHumanPawn(instigator), - resultTarget, - boneStick, - hitLocation, - Rotator(movementDirection), - expData - ); - class'NiceProjectileSpawner'.static.StickProjectile( - KFHumanPawn(instigator), - resultTarget, - boneStick, - hitLocation, - Rotator(movementDirection), - expData - ); - KillBullet(); } - -function DoExplode(Vector explLocation, Vector impactNormal) { - if (charIsDud) { - return; - } - if (bStuck) { - class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation, base); - } else { - class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation); - } +function DoExplode(Vector explLocation, Vector impactNormal){ + if(charIsDud) + return; + if(bStuck) + class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation, base); + else + class'NiceBulletAdapter'.static.Explode(self, niceRI, explLocation); GenerateImpactEffects(explosionImpact, explLocation, impactNormal, true, true); - if (bShakeViewOnExplosion) { - ShakeView(explLocation); - } + if(bShakeViewOnExplosion) + ShakeView(explLocation); KillBullet(); } - -function HandleHitWall(Actor wall, Vector hitLocation, Vector hitNormal) { - local bool bBulletTooWeak; - - if (charExplodeOnWallHit && !charIsDud && charMinExplosionDist <= 0.0) { - DoExplode(hitLocation, hitNormal); - return; - } else { - class'NiceBulletAdapter'.static.HitWall(self, niceRI, wall, hitLocation, hitNormal); - GenerateImpactEffects(regularImpact, hitLocation, hitNormal, true, true); - if (charIsSticky) { - Stick(wall, hitLocation); - } +function HandleHitWall(Actor wall, Vector hitLocation, Vector hitNormal){ + local bool bBulletTooWeak; + if(charExplodeOnWallHit && !charIsDud && charMinExplosionDist <= 0.0){ + DoExplode(hitLocation, hitNormal); + return; } - - if (bShouldBounce && !bDisableComplexMovement) { - movementDirection = (movementDirection - 2.0 * hitNormal * (movementDirection dot hitNormal)); - bBulletTooWeak = !class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false); - charPenetrationCount += 1; - ResetPathBuilding(); - ResetIgnoreList(); - bounceHeadMod *= 2; - } else if (movementFallTime > 0.0) { - charIsDud = true; - lifeSpan = movementFallTime; - movementFallTime = 0.0; - movementDirection = vect(0, 0, 0); - ResetPathBuilding(); - ResetIgnoreList(); - } else { - bBulletTooWeak = true; + else{ + class'NiceBulletAdapter'.static.HitWall(self, niceRI, wall, hitLocation, hitNormal); + GenerateImpactEffects(regularImpact, hitLocation, hitNormal, true, true); + if(charIsSticky) + Stick(wall, hitLocation); } - - if (bBulletTooWeak) { - KillBullet(); + if(bShouldBounce && !bDisableComplexMovement){ + movementDirection = (movementDirection - 2.0 * hitNormal * (movementDirection dot hitNormal)); + bBulletTooWeak = !class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false); + charPenetrationCount += 1; + ResetPathBuilding(); + ResetIgnoreList(); + bounceHeadMod *= 2; } + else if(movementFallTime > 0.0){ + charIsDud = true; + lifeSpan = movementFallTime; + movementFallTime = 0.0; + movementDirection = vect(0,0,0); + ResetPathBuilding(); + ResetIgnoreList(); + } + else + bBulletTooWeak = true; + if(bBulletTooWeak) + KillBullet(); } - -function HandleHitPawn(KFPawn hitPawn, Vector hitLocation, Vector hitDirection, array hitPoints) { - if (charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0) { - DoExplode(hitLocation, hitDirection); - GenerateImpactEffects(explosionImpact, hitLocation, hitDirection); - return; - } else { - class'NiceBulletAdapter'.static.HitPawn(self, niceRI, hitPawn, hitLocation, hitDirection, hitPoints); - if (bGenRegEffectOnPawn) { - GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false); - } +function HandleHitPawn(KFPawn hitPawn, Vector hitLocation, Vector hitDirection, array hitPoints){ + if(charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0){ + DoExplode(hitLocation, hitDirection); + GenerateImpactEffects(explosionImpact, hitLocation, hitDirection); + return; } - if (!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false)) { + else{ + class'NiceBulletAdapter'.static.HitPawn(self, niceRI, hitPawn, hitLocation, hitDirection, hitPoints); + if(bGenRegEffectOnPawn) + GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false); + } + if(!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false)){ charPenetrationCount += 1; KillBullet(); } } - -function HandleHitZed(KFMonster targetZed, Vector hitLocation, Vector hitDirection, float headshotLevel) { +function HandleHitZed(KFMonster targetZed, Vector hitLocation, Vector hitDirection, float headshotLevel){ local bool bHitZedCalled; - - if (class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillDemoDirectApproach')) { - class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel); - if (bGenRegEffectOnPawn) { - GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false); - } - bHitZedCalled = true; + if(class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillDemoDirectApproach')){ + class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel); + if(bGenRegEffectOnPawn) + GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false); + bHitZedCalled = true; } - - if (charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0) { - class'NiceBulletAdapter'.static.Explode(self, niceRI, hitLocation, targetZed); - GenerateImpactEffects(explosionImpact, hitLocation, hitDirection); - if (bShakeViewOnExplosion) { - ShakeView(hitLocation); - } - KillBullet(); - return; - } else { - if (!bHitZedCalled) { - class'NiceBulletAdapter'.static.HitZed( - self, - niceRI, - targetZed, - hitLocation, - hitDirection, - headshotLevel - ); - if (bGenRegEffectOnPawn) { - GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false); - } - } - bHitZedCalled = true; - if (!bGhost && !bAlreadyHitZed) { - bAlreadyHitZed = true; - if (nicePlayer != none && niceRI != none) { - niceRI.ServerJunkieExtension(nicePlayer, headshotLevel > 0.0); - } - } - if (charIsSticky) { - Stick(targetZed, hitLocation); - } + if(charExplodeOnPawnHit && !charIsDud && charMinExplosionDist <= 0.0){ + class'NiceBulletAdapter'.static.Explode(self, niceRI, hitLocation, targetZed); + GenerateImpactEffects(explosionImpact, hitLocation, hitDirection); + if(bShakeViewOnExplosion) + ShakeView(hitLocation); + KillBullet(); + return; } - if (!class'NiceBulletAdapter'.static.ZedPenetration( - charDamage, - self, - targetZed, - (headshotLevel > 0.0), - (headshotLevel > charDamageType.default.prReqPrecise) - ) - ) { + else{ + if(!bHitZedCalled){ + class'NiceBulletAdapter'.static.HitZed(self, niceRI, targetZed, hitLocation, hitDirection, headshotLevel); + if(bGenRegEffectOnPawn) + GenerateImpactEffects(regularImpact, hitLocation, hitDirection, false, false); + } + bHitZedCalled = true; + if(!bGhost && !bAlreadyHitZed){ + bAlreadyHitZed = true; + if(nicePlayer != none && niceRI != none) + niceRI.ServerJunkieExtension(nicePlayer, headshotLevel > 0.0); + } + if(charIsSticky) + Stick(targetZed, hitLocation); + } + if(!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, targetZed, (headshotLevel > 0.0), (headshotLevel > charDamageType.default.prReqPrecise))){ charPenetrationCount += 1; KillBullet(); } } - -function HandleScream(Vector disintegrationLocation, Vector entryDirection) { - if (!charIsDud) { - GenerateImpactEffects(disintegrationImpact, disintegrationLocation, entryDirection); - } +function HandleScream(Vector disintegrationLocation, Vector entryDirection){ + if(!charIsDud) + GenerateImpactEffects(disintegrationImpact, disintegrationLocation, entryDirection); class'NiceBulletAdapter'.static.HandleScream(self, niceRI, disintegrationLocation, entryDirection); } - -function GenerateImpactEffects( - ImpactEffect effect, - Vector hitLocation, - Vector hitNormal, - optional bool bWallImpact, - optional bool bGenerateDecal -) { - local float actualCullDistance; - local float actualImpactShift; - local bool generatedEffect; - +function GenerateImpactEffects(ImpactEffect effect, Vector hitLocation, Vector hitNormal, + optional bool bWallImpact, optional bool bGenerateDecal){ + local float actualCullDistance; + local float actualImpactShift; + local bool generatedEffect; // No need to play visuals on a server, for a dead bullets or in case there's no local player at all - if (Level.NetMode == NM_DedicatedServer || bBulletDead || localPlayer == none) { - return; - } - if (!localPlayer.CanSpawnEffect(bGhost) && !effect.bImportanEffect) { - return; - } + if(Level.NetMode == NM_DedicatedServer || bBulletDead || localPlayer == none) + return; + if(!localPlayer.CanSpawnEffect(bGhost) && !effect.bImportanEffect) + return; // -- Classic effect - if (effect.bPlayROEffect && !bBulletDead) { - Spawn(class'ROBulletHitEffect',,, hitLocation, rotator(-hitNormal)); - } + if(effect.bPlayROEffect && !bBulletDead) + Spawn(class'ROBulletHitEffect',,, hitLocation, rotator(-hitNormal)); // -- Generate decal - if (bGenerateDecal && effect.decalClass != none) { - // Find appropriate cull distance for this decal - actualCullDistance = effect.decalClass.default.cullDistance; - // Double cull distance if local player is an instigator - if (instigator != none && localPlayer == instigator.Controller) { - actualCullDistance *= 2; // NICETODO: magic number - } - // Spawn decal - if (!localPlayer.BeyondViewDistance(hitLocation, actualCullDistance)) { - Spawn(effect.decalClass, self,, hitLocation, rotator(- hitNormal)); - generatedEffect = true; - } + if(bGenerateDecal && effect.decalClass != none){ + // Find appropriate cull distance for this decal + actualCullDistance = effect.decalClass.default.cullDistance; + // Double cull distance if local player is an instigator + if(instigator != none && localPlayer == instigator.Controller) + actualCullDistance *= 2; // NICETODO: magic number + // Spawn decal + if(!localPlayer.BeyondViewDistance(hitLocation, actualCullDistance)){ + Spawn(effect.decalClass, self,, hitLocation, rotator(- hitNormal)); + generatedEffect = true; + } } // -- Generate custom effect - if (effect.emitterClass != none && EffectIsRelevant(hitLocation, false)) { - if (bWallImpact) { - actualImpactShift = effect.emitterShiftWall; - } else { - actualImpactShift = effect.emitterShiftPawn; - } - Spawn(effect.emitterClass,,, hitLocation - movementDirection * actualImpactShift, rotator(movementDirection)); - generatedEffect = true; + if(effect.emitterClass != none && EffectIsRelevant(hitLocation, false)){ + if(bWallImpact) + actualImpactShift = effect.emitterShiftWall; + else + actualImpactShift = effect.emitterShiftPawn; + Spawn(effect.emitterClass,,, hitLocation - movementDirection * actualImpactShift, rotator(movementDirection)); + generatedEffect = true; } // -- Generate custom sound - if (effect.noise != none) { - class'NiceSoundCls'.default.effectSound = effect.noise; - class'NiceSoundCls'.default.effectVolume = effect.noiseVolume; - Spawn(class'NiceSoundCls',,, hitLocation); - generatedEffect = true; - } - if (generatedEffect) { - localPlayer.AddEffect(); + if(effect.noise != none){ + class'NiceSoundCls'.default.effectSound = effect.noise; + class'NiceSoundCls'.default.effectVolume = effect.noiseVolume; + Spawn(class'NiceSoundCls',,, hitLocation); + generatedEffect = true; } + if(generatedEffect) + localPlayer.AddEffect(); } - -function ShakeView(Vector hitLocation) { +function ShakeView(Vector hitLocation){ local float distance, scale; - - if (nicePlayer == none || shakeRadiusMult < 0.0) { - return; - } + if(nicePlayer == none || shakeRadiusMult < 0.0) + return; distance = VSize(hitLocation - nicePlayer.ViewTarget.Location); - if (distance < charExplosionRadius * shakeRadiusMult) { - if (distance < charExplosionRadius) { - scale = 1.0; - } else { + if(distance < charExplosionRadius * shakeRadiusMult){ + if(distance < charExplosionRadius) + scale = 1.0; + else scale = (charExplosionRadius * ShakeRadiusMult - distance) / (charExplosionRadius); - } - nicePlayer.ShakeView( - shakeRotMag * scale, - shakeRotRate, - shakeRotTime, - shakeOffsetMag * scale, - shakeOffsetRate, - shakeOffsetTime - ); + nicePlayer.ShakeView(shakeRotMag*scale, shakeRotRate, shakeRotTime, shakeOffsetMag * scale, shakeOffsetRate, shakeOffsetTime); } } - -function KillBullet() { +function KillBullet(){ local int i; - - if (bulletTrail != none) { - for (i = 0; i < bulletTrail.Emitters.Length; i ++) { - if (bulletTrail.Emitters[i] == none) { - continue; - } - bulletTrail.Emitters[i].ParticlesPerSecond = 0; - bulletTrail.Emitters[i].InitialParticlesPerSecond = 0; - bulletTrail.Emitters[i].RespawnDeadParticles = false; - } - bulletTrail.SetBase(none); - bulletTrail.AutoDestroy = true; + if(bulletTrail != none){ + for(i = 0;i < bulletTrail.Emitters.Length;i ++){ + if(bulletTrail.Emitters[i] == none) + continue; + bulletTrail.Emitters[i].ParticlesPerSecond = 0; + bulletTrail.Emitters[i].InitialParticlesPerSecond = 0; + bulletTrail.Emitters[i].RespawnDeadParticles = false; + } + bulletTrail.SetBase(none); + bulletTrail.AutoDestroy = true; } - - if (bulletXTrail != none) { - bulletXTrail.mRegen = false; - bulletXTrail.LifeSpan = LifeSpan; + if(bulletXTrail != none){ + bulletXTrail.mRegen = false; + bulletXTrail.LifeSpan = LifeSpan; } bBulletDead = true; - bHidden = true; + bHidden = true; SoundVolume = 0; - LifeSpan = FMin(LifeSpan, 0.1); + LifeSpan = FMin(LifeSpan, 0.1); } - -event Destroyed() { +event Destroyed(){ KillBullet(); } -defaultproperties { - insideBouncesLeft=2 - trajUpdFreq=0.100000 - maxTraceCycles=128 - bDisableComplexMovement=True - trailXClass=Class'KFMod.KFTracer' - regularImpact=(bPlayROEffect=True) - StaticMeshRef="kf_generic_sm.Shotgun_Pellet" - DrawType=DT_StaticMesh - bAcceptsProjectors=False - LifeSpan=15.000000 - Texture=Texture'Engine.S_Camera' - bGameRelevant=True - bCanBeDamaged=True - SoundVolume=255 -} \ No newline at end of file +defaultproperties +{ + insideBouncesLeft=2 + trajUpdFreq=0.100000 + maxTraceCycles=128 + bDisableComplexMovement=True + trailXClass=Class'KFMod.KFTracer' + regularImpact=(bPlayROEffect=True) + StaticMeshRef="kf_generic_sm.Shotgun_Pellet" + DrawType=DT_StaticMesh + bAcceptsProjectors=False + LifeSpan=15.000000 + Texture=Texture'Engine.S_Camera' + bGameRelevant=True + bCanBeDamaged=True + SoundVolume=255 +} diff --git a/sources/Weapons/NiceBulletAdapter.uc b/sources/Weapons/NiceBulletAdapter.uc index beb7401..1ab2f91 100644 --- a/sources/Weapons/NiceBulletAdapter.uc +++ b/sources/Weapons/NiceBulletAdapter.uc @@ -9,132 +9,57 @@ // E-mail: dkanus@gmail.com //====================================================================================================================== class NiceBulletAdapter extends Object; - -var const int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big -var const int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size - -static function Explode( - NiceBullet bullet, - NiceReplicationInfo niceRI, - Vector hitLocation, - optional Actor explosionTarget -) { - if (!bullet.bGhost) { - niceRI.ServerExplode( - bullet.charExplosionDamage, - bullet.charExplosionRadius, - bullet.charExplosionExponent, - bullet.charExplosionDamageType, - bullet.charExplosionMomentum, - hitLocation, - bullet.instigator, - explosionTarget, - Vector(bullet.Rotation), - bullet.bStuck - ); - - if (KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) { - niceRI.ServerDealDamage( - KFMonster(bullet.base), - bullet.charExplosionDamage, - bullet.instigator, - hitLocation, - bullet.charExplosionMomentum * vect(0, 0, -1), - bullet.charExplosionDamageType, - 1.0 - ); - } +var const int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big +var const int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size +static function Explode(NiceBullet bullet, NiceReplicationInfo niceRI, Vector hitLocation, optional Actor explosionTarget){ + if(!bullet.bGhost){ + niceRI.ServerExplode(bullet.charExplosionDamage, bullet.charExplosionRadius, bullet.charExplosionExponent, + bullet.charExplosionDamageType, bullet.charExplosionMomentum, hitLocation, bullet.instigator, true, + explosionTarget, Vector(bullet.Rotation)); + if(KFMonster(bullet.base) != none && bullet.bStuck && bullet.bStuckToHead) + niceRI.ServerDealDamage(KFMonster(bullet.base), bullet.charExplosionDamage, bullet.instigator, hitLocation, + bullet.charExplosionMomentum * vect(0,0,-1), bullet.charExplosionDamageType, 1.0); } } - -static function HandleCalibration ( - bool isHeadshot, - NiceHumanPawn nicePawn, - NiceMonster targetZed -) { - if (nicePawn == none || nicePawn.currentCalibrationState != CALSTATE_ACTIVE) { - return; - } - +static function HandleCalibration + ( + bool isHeadshot, + NiceHumanPawn nicePawn, + NiceMonster targetZed + ){ + if(nicePawn == none) return; + if(nicePawn.currentCalibrationState != CALSTATE_ACTIVE) return; nicePawn.ServerUpdateCalibration(isHeadshot, targetZed); } - -static function HitWall( - NiceBullet bullet, - NiceReplicationInfo niceRI, - Actor targetWall, - Vector hitLocation, - Vector hitNormal -) { +static function HitWall(NiceBullet bullet, NiceReplicationInfo niceRI, Actor targetWall, + Vector hitLocation, Vector hitNormal){ local NicePlayerController nicePlayer; - nicePlayer = NicePlayerController(bullet.Instigator.Controller); - if (nicePlayer == none) { - return; - } - if (!bullet.bAlreadyHitZed) { - HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none); - } - if ( - !targetWall.bStatic && - !targetWall.bWorldGeometry && - nicePlayer != none && - (nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none) - ) { - niceRI.ServerDealDamage( - targetWall, - bullet.charOrigDamage, - bullet.Instigator, - hitLocation, - bullet.charMomentumTransfer * hitNormal, - bullet.charDamageType - ); - nicePlayer.wallHitsLeft --; + if(nicePlayer == none) + return; + if(!bullet.bAlreadyHitZed) + HandleCalibration(false, NiceHumanPawn(bullet.Instigator), none); + if(!targetWall.bStatic && !targetWall.bWorldGeometry && nicePlayer != none && (nicePlayer.wallHitsLeft > 0 || Projectile(targetWall) != none)){ + niceRI.ServerDealDamage(targetWall, bullet.charOrigDamage, bullet.Instigator, hitLocation, + bullet.charMomentumTransfer * hitNormal, bullet.charDamageType); + nicePlayer.wallHitsLeft --; } } - -static function HandleScream( - NiceBullet bullet, - NiceReplicationInfo niceRI, - Vector location, - Vector entryDirection -) { +static function HandleScream(NiceBullet bullet, NiceReplicationInfo niceRI, Vector location, Vector entryDirection){ bullet.charIsDud = true; } - -static function HitPawn( - NiceBullet bullet, - NiceReplicationInfo niceRI, - KFPawn targetPawn, - Vector hitLocation, - Vector hitNormal, - array hitPoints -) { +static function HitPawn(NiceBullet bullet, NiceReplicationInfo niceRI, KFPawn targetPawn, Vector hitLocation, + Vector hitNormal, array hitPoints){ local NiceMedicProjectile niceDart; - niceDart = NiceMedicProjectile(bullet); - if (niceDart == none) { - niceRI.ServerDealDamage( - targetPawn, - bullet.charDamage, - bullet.instigator, - HitLocation, - hitNormal * bullet.charMomentumTransfer, - bullet.charDamageType - ); - } else { - niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator); - } + if(niceDart == none) + niceRI.ServerDealDamage(targetPawn, bullet.charDamage, bullet.instigator, HitLocation, + hitNormal * bullet.charMomentumTransfer, bullet.charDamageType); + else + niceRI.ServerHealTarget(NiceHumanPawn(targetPawn), bullet.charDamage, bullet.instigator); } - -static function HitZed( - NiceBullet bullet, - NiceReplicationInfo niceRI, - KFMonster kfZed, - Vector hitLocation, - Vector hitNormal, - float headshotLevel -) { +static function HitZed(NiceBullet bullet, NiceReplicationInfo niceRI, KFMonster kfZed, Vector hitLocation, + Vector hitNormal, float headshotLevel){ local bool bIsHeadshot, bIsPreciseHeadshot; local float actualDamage; local int lockonTicks; @@ -143,113 +68,74 @@ static function HitZed( local NiceHumanPawn nicePawn; local NicePlayerController nicePlayer; local class niceVet; - nicePlayer = NicePlayerController(bullet.Instigator.Controller); - if ( - nicePlayer != none && - nicePlayer.abilityManager != none && - nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID) - ) { + if ( nicePlayer != none && nicePlayer.abilityManager != none + && nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillEnforcerBruteA'.default.abilityID)) { headshotLevel = 0.0; } bIsHeadshot = (headshotLevel > 0.0); bIsPreciseHeadshot = (headshotLevel > bullet.charDamageType.default.prReqPrecise); - if (!bullet.bAlreadyHitZed || bIsHeadshot) { - HandleCalibration(bIsHeadshot, NiceHumanPawn(bullet.Instigator), NiceMonster(kfZed)); - } - if (bIsHeadshot && bullet.sourceWeapon != none) { - bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds; - } - if (nicePlayer == none) { - return; - } + if(!bullet.bAlreadyHitZed || bIsHeadshot) + HandleCalibration(bIsHeadshot, NiceHumanPawn(bullet.Instigator), NiceMonster(kfZed)); + if(bIsHeadshot && bullet.sourceWeapon != none) + bullet.sourceWeapon.lastHeadshotTime = bullet.Level.TimeSeconds; + if(nicePlayer == none) + return; nicePawn = NiceHumanPawn(bullet.instigator); - if ( - !bIsHeadshot && - nicePawn != none && - nicePlayer.abilityManager != none && - nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID) - ) { - nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID); - } + if( !bIsHeadshot + && nicePawn != none + && nicePlayer.abilityManager != none + && nicePlayer.abilityManager.IsAbilityActive(class'NiceSkillSharpshooterReaperA'.default.abilityID)) + nicePawn.ServerCooldownAbility(class'NiceSkillSharpshooterReaperA'.default.abilityID); niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); - if (bullet.charCausePain) { - actualDamage = bullet.charOrigDamage; - } else { - actualDamage = bullet.charDamage; - } - if (headshotLevel > 0) { + if(bullet.charCausePain) + actualDamage = bullet.charOrigDamage; + else + actualDamage = bullet.charDamage; + if(headshotLevel > 0) actualDamage *= bullet.charContiniousBonus; - } - if (bullet.bGrazing) { + if(bullet.bGrazing) actualDamage *= class'NiceSkillSupportGraze'.default.grazeDamageMult; - } bullet.bGrazing = false; - if ( - kfZed == bullet.lockonZed && - bullet.lockonTime > bullet.sourceWeapon.stdFireRate && - niceVet != none && - niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed') - ) { - lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay; - lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1; - lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks); - // actualDamage *= 1.0 + - // 0.5 * lockonTicks * (lockonTicks + 1) * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; - // damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; - actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; - } - if (!bullet.bGhost) { - niceRI.ServerDealDamage( - kfZed, - actualDamage, - bullet.instigator, - hitLocation, - bullet.charMomentumTransfer * hitNormal, - bullet.charDamageType, - headshotLevel, - bullet.lockonTime - ); + if(kfZed == bullet.lockonZed && bullet.lockonTime > bullet.sourceWeapon.stdFireRate + && niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterKillConfirmed')){ + lockOnTickRate =class'NiceSkillSharpshooterKillConfirmed'.default.stackDelay; + lockonTicks = Ceil(bullet.lockonTime / lockOnTickRate) - 1; + lockonTicks = Min(class'NiceSkillSharpshooterKillConfirmed'.default.maxStacks, lockonTicks); + //actualDamage *= 1.0 + + // 0.5 * lockonTicks * (lockonTicks + 1) * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; + //damageMod *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; + actualDamage *= 1.0 + lockonTicks * class'NiceSkillSharpshooterKillConfirmed'.default.damageBonus; } + if(!bullet.bGhost) + niceRI.ServerDealDamage(kfZed, actualDamage, bullet.instigator, hitLocation, + bullet.charMomentumTransfer * hitNormal, bullet.charDamageType, headshotLevel, bullet.lockonTime); //// Handle angled shots angle = asin(hitNormal.Z); // Apply angled shots - if ((angle > 0.8 || angle < -0.45) && bullet.bCanAngleDamage && kfZed != none) { - bullet.bCanAngleDamage = false; - bullet.bAlreadyHitZed = true; - if (ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot)) { - HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel); - } + if((angle > 0.8 || angle < -0.45) && bullet.bCanAngleDamage && kfZed != none){ + bullet.bCanAngleDamage = false; + bullet.bAlreadyHitZed = true; + if(ZedPenetration(bullet.charDamage, bullet, kfZed, bIsHeadshot, bIsPreciseHeadshot)) + HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel); } //// 'Bore' support skill - if ( - niceVet != none && - nicePlayer.IsZedTimeActive() && - bullet.insideBouncesLeft > 0 && - niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore') - ) { - // Count one bounce - bullet.insideBouncesLeft --; - // Swap head-shot level - if (headshotLevel <= 0.0) { - headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision; - } else { - headshotLevel = -headshotLevel; - } - // Deal next batch of damage - ZedPenetration(bullet.charDamage, bullet, kfZed, false, false); - HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel); + if( niceVet != none && nicePlayer.IsZedTimeActive() && bullet.insideBouncesLeft > 0 + && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBore')){ + // Count one bounce + bullet.insideBouncesLeft --; + // Swap head-shot level + if(headshotLevel <= 0.0) + headshotLevel = class'NiceSkillSupportZEDBore'.default.minHeadshotPrecision; + else + headshotLevel = -headshotLevel; + // Deal next batch of damage + ZedPenetration(bullet.charDamage, bullet, kfZed, false, false); + HitZed(bullet, niceRI, kfZed, hitLocation, hitNormal, headshotLevel); } bullet.insideBouncesLeft = 2; } - -static function bool ZedPenetration( - out float Damage, - NiceBullet bullet, - KFMonster targetZed, - bool bIsHeadshot, - bool bIsPreciseHeadshot -) { +static function bool ZedPenetration(out float Damage, NiceBullet bullet, KFMonster targetZed, bool bIsHeadshot, bool bIsPreciseHeadshot){ local float reductionMod; local NiceMonster niceZed; local NicePlayerController nicePlayer; @@ -258,74 +144,52 @@ static function bool ZedPenetration( local class niceDmgType; // True if we can penetrate even body, but now penetrating a head and shouldn't reduce damage too much local bool bEasyHeadPenetration; - // Init variables niceZed = NiceMonster(targetZed); nicePlayer = NicePlayerController(bullet.Instigator.Controller); niceVet = none; - if (nicePlayer != none) { - niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); - } + if(nicePlayer != none) + niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); niceDmgType = bullet.charDamageType; bEasyHeadPenetration = bIsHeadshot && !niceDmgType.default.bPenetrationHSOnly; reductionMod = 1.0f; // Apply zed reduction and perk reduction of reduction` - if (niceZed != none) { - // Railgun skill exception - if ( - niceVet != none && - niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') && - nicePlayer.IsZedTimeActive() - ) { - return true; - } - if (niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration) { - reductionMod *= niceDmgType.default.BigZedPenDmgReduction; - } else if (niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) { - reductionMod *= niceDmgType.default.MediumZedPenDmgReduction; - } - } else { + if(niceZed != none){ + // Railgun skill exception + if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterZEDRailgun') && nicePlayer.IsZedTimeActive()) + return true; + if(niceZed.default.Health >= default.BigZedMinHealth && !bEasyHeadPenetration) + reductionMod *= niceDmgType.default.BigZedPenDmgReduction; + else if(niceZed.default.Health >= default.MediumZedMinHealth && !bEasyHeadPenetration) + reductionMod *= niceDmgType.default.MediumZedPenDmgReduction; + } + else reductionMod *= niceDmgType.default.BigZedPenDmgReduction; - } - if (niceVet != none) { - reductionMod = niceVet.static.GetPenetrationDamageMulti( - KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo), - reductionMod, - niceDmgType - ); - } - actualMaxPenetrations = niceDmgType.default.maxPenetrations; - if ( - niceVet != none && - !bullet.charWasHipFired && - niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') && - bIsHeadshot - ) { - actualMaxPenetrations += 1; - reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction); - } + if(niceVet != none) + reductionMod = niceVet.static.GetPenetrationDamageMulti(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo), reductionMod, niceDmgType); + actualMaxPenetrations = niceDmgType.default.maxPenetrations; + if(niceVet != none && !bullet.charWasHipFired && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSharpshooterSurgical') && bIsHeadshot){ + actualMaxPenetrations += 1; + reductionMod = FMax(reductionMod, class'NiceSkillSharpshooterSurgical'.default.penDmgReduction); + } // Assign new damage value and tell us if we should stop with penetration Damage *= reductionMod * niceDmgType.default.PenDmgReduction; bullet.decapMod *= reductionMod * niceDmgType.default.PenDecapReduction; bullet.incapMod *= reductionMod * niceDmgType.default.PenIncapReduction; - if (niceVet != none && actualMaxPenetrations >= 0) { - actualMaxPenetrations += - niceVet.static.GetAdditionalPenetrationAmount(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); - } - if (!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly) { - return false; - } - if (actualMaxPenetrations < 0) { - return true; - } - if (Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1) { - return false; - } - + if(niceVet != none && actualMaxPenetrations >= 0) + actualMaxPenetrations += + niceVet.static.GetAdditionalPenetrationAmount(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); + if(!bIsHeadshot && niceDmgType.default.bPenetrationHSOnly) + return false; + if(actualMaxPenetrations < 0) + return true; + if(Damage / bullet.charOrigDamage < (niceDmgType.default.PenDmgReduction ** (actualMaxPenetrations + 1)) + 0.0001 || Damage < 1) + return false; return true; } -defaultproperties { - BigZedMinHealth=1000 - MediumZedMinHealth=500 -} \ No newline at end of file +defaultproperties +{ + BigZedMinHealth=1000 + MediumZedMinHealth=500 +} diff --git a/sources/Weapons/NiceFire.uc b/sources/Weapons/NiceFire.uc index 969d8ec..a752d16 100644 --- a/sources/Weapons/NiceFire.uc +++ b/sources/Weapons/NiceFire.uc @@ -20,7 +20,6 @@ var() bool bSemiMustBurst; var() int MaxBurstLength; var() int burstShotsMade; var bool bResetRecoil; // Set this flag to 'true' to disable recoil for the next shot; flag will be automatically reset to 'false' after that -var float aimingSpreadReductionCoefficient; var bool zoomOutOnShot; var bool bShouldBounce; var bool bCausePain; @@ -39,10 +38,6 @@ var bool projAffectedByScream; var bool bShouldStick; var int resetTicks; var float niceNextFireTime; -var float minimalSpreadScale; -var float activeSpreadScale; -var float spreadGainedPerShot; -var float spreadLostPerSecond; struct FireModeContext{ var bool bHipfire; var NiceWeapon sourceWeapon; @@ -157,15 +152,9 @@ simulated function int GetBurstLength(){ } return currentContext.burstLength; } - simulated function ModeTick(float delta){ local float headLevel; local NiceMonster currTarget; - if (spreadLostPerSecond > 0 && activeSpreadScale > minimalSpreadScale - && niceNextFireTime + fireRate <= Level.TimeSeconds) { - activeSpreadScale -= spreadLostPerSecond * delta; - activeSpreadScale = FMax(minimalSpreadScale, activeSpreadScale); - } if(currentContext.Instigator == none) currentContext.Instigator = NiceHumanPawn(Instigator); if(currentContext.sourceWeapon == none) @@ -488,7 +477,7 @@ simulated function HandleRecoil(float Rec) KFW= KFWeapon(Weapon); if (KFW.bAimingRifle) { - Rec *= aimingSpreadReductionCoefficient; + Rec *= 0.5; } if (nicePawn.stationaryTime > 0.0 && class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillHeavyStablePosition')) { @@ -559,7 +548,7 @@ function DoFireEffect(){ if(!Weapon.WeaponCentered() && !KFWeap.bAimingRifle) StartProj = StartProj + Weapon.Hand * Y * ProjSpawnOffset.Y + Z * ProjSpawnOffset.Z; other = Weapon.Trace(HitLocation, HitNormal, StartProj, StartTrace, false); - activeSpread = fireShots[currentShot].spread * activeSpreadScale; + activeSpread = fireShots[currentShot].spread; if(class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, class'NiceSkillEnforcerBombard')){ bPinpoint = true; activeSpread *= class'NiceSkillEnforcerBombard'.default.spreadMult; @@ -618,15 +607,6 @@ function DoFireEffect(){ else if(Instigator.Physics == PHYS_Falling && Instigator.PhysicsVolume.Gravity.Z > class'PhysicsVolume'.default.Gravity.Z) Instigator.AddVelocity((KickMomentum * LowGravKickMomentumScale) >> Instigator.GetViewRotation()); } - if (activeSpreadScale < 1.0) { - if (KFWeap.bAimingRifle) { - activeSpreadScale += spreadGainedPerShot * 0.5; - } - else { - activeSpreadScale += spreadGainedPerShot; - } - activeSpreadScale = FMin(1.0, activeSpreadScale); - } } simulated function float TraceZed(out NiceMonster tracedZed, optional out Vector hitLoc, optional out Vector hitNorm, optional float hsMultiplier){ @@ -698,8 +678,7 @@ simulated function UpdateFireSpeed(){ ReloadAnimRate = default.ReloadAnimRate * fireSpeedMod; } // This function is called when next fire time needs to be updated -simulated function float UpdateNextFireTime(float fireTimeVar) { - local float usedFireRate; +simulated function float UpdateNextFireTime(float fireTimeVar){ local float burstSlowDown; local NiceHumanPawn nicePawn; local class niceVet; @@ -707,19 +686,11 @@ simulated function float UpdateNextFireTime(float fireTimeVar) { if(nicePawn != none) niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePawn.PlayerReplicationInfo); fireTimeVar = FMax(fireTimeVar, Level.TimeSeconds); - usedFireRate = fireRate; - if (maxBonusContLenght > 1) { - if (currentContLenght <= maxBonusContLenght) { - usedFireRate *= 0.8 + 0.2 * (maxBonusContLenght - currentContLenght); - } else { - usedFireRate *= 0.8; - } - } if(bFireOnRelease){ if(bIsFiring) - fireTimeVar += MaxHoldTime + usedFireRate; + fireTimeVar += MaxHoldTime + FireRate; else - fireTimeVar = Level.TimeSeconds + usedFireRate; + fireTimeVar = Level.TimeSeconds + FireRate; } else{ if(currentContext.bIsBursting && GetBurstLength() > 1){ @@ -730,10 +701,10 @@ simulated function float UpdateNextFireTime(float fireTimeVar) { burstSlowDown = 1.0; else burstSlowDown = 1.3; - fireTimeVar += usedFireRate * burstSlowDown; + fireTimeVar += FireRate * burstSlowDown; } else - fireTimeVar += usedFireRate; + fireTimeVar += FireRate; fireTimeVar = FMax(fireTimeVar, Level.TimeSeconds); } return fireTimeVar; @@ -741,19 +712,13 @@ simulated function float UpdateNextFireTime(float fireTimeVar) { defaultproperties { - zedTimeFireSpeedUp=1.000000 - ProjPerFire=1 - ProjectileSpeed=1524.000000 - MaxBurstLength=3 - bulletClass=class'NiceBullet' - contBonus=1.200000 - contBonusReset=True - maxBonusContLenght=1 - AmmoPerFire=1 - minimalSpreadScale=1 - activeSpreadScale=1 - spreadGainedPerShot=0 - spreadLostPerSecond=0 - RecoilVelocityScale = 0 - aimingSpreadReductionCoefficient = 0.5 + zedTimeFireSpeedUp=1.000000 + ProjPerFire=1 + ProjectileSpeed=1524.000000 + MaxBurstLength=3 + bulletClass=class'NiceBullet' + contBonus=1.200000 + contBonusReset=True + maxBonusContLenght=1 + AmmoPerFire=1 } diff --git a/sources/Weapons/NiceProjectileSpawner.uc b/sources/Weapons/NiceProjectileSpawner.uc index a8ee953..05dd281 100644 --- a/sources/Weapons/NiceProjectileSpawner.uc +++ b/sources/Weapons/NiceProjectileSpawner.uc @@ -1,160 +1,76 @@ class NiceProjectileSpawner extends Actor dependson(NiceBullet); - // NICETODO: use flags correctly -static function MakeProjectile( - Vector start, - Rotator dir, - NiceFire.ShotType shotParams, - NiceFire.FireModeContext fireContext, - optional bool bForceComplexTraj, - optional bool bDuplReal, - optional bool bSkipGhosts -) { +static function MakeProjectile(Vector start, Rotator dir, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, optional bool bForceComplexTraj, + optional bool bDuplReal, optional bool bSkipGhosts){ local int i; local NicePack niceMut; - niceMut = class'NicePack'.static.Myself(fireContext.Instigator.Level); - if (niceMut == none) { - return; - } - if (fireContext.Instigator.Role < ROLE_Authority || bDuplReal) { - SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj); - } - if (fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts) { - for (i = 0; i < niceMut.playersList.Length; i++) { - if (niceMut.playersList[i] != fireContext.Instigator.Controller) { - niceMut.playersList[i].ClientSpawnGhostProjectile( - start, - dir.pitch, - dir.yaw, - dir.roll, - shotParams, - fireContext, - bForceComplexTraj - ); - } - } + if(niceMut == none) + return; + if(fireContext.Instigator.Role < ROLE_Authority || bDuplReal) + SpawnProjectile(Start, Dir, shotParams, fireContext, false, bForceComplexTraj); + if(fireContext.Instigator.Role == ROLE_Authority && niceMut != none && !bSkipGhosts){ + for(i = 0;i < niceMut.playersList.Length;i ++){ + if(niceMut.playersList[i] != fireContext.Instigator.Controller) + niceMut.playersList[i].ClientSpawnGhostProjectile(start, dir.pitch, dir.yaw, dir.roll, shotParams, fireContext, bForceComplexTraj); + } } } - -static function StickProjectile( - KFHumanPawn instigator, - Actor base, - name bone, - Vector shift, - Rotator direction, - NiceBullet.ExplosionData expData, - optional bool bDuplReal, - optional bool bSkipGhosts -) { +static function StickProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, Rotator direction, + NiceBullet.ExplosionData expData, optional bool bDuplReal, optional bool bSkipGhosts){ local int i; local NicePack niceMut; - niceMut = class'NicePack'.static.Myself(expData.Instigator.Level); - if (niceMut == none) { - return; - } + if(niceMut == none) + return; niceMut.stuckCounter ++; - if (expData.Instigator.Role < ROLE_Authority) { - SpawnStuckProjectile( - instigator, - base, - bone, - shift, - direction, - expData, - false, - niceMut.stuckCounter - ); - } - if (expData.Instigator.Role == ROLE_Authority && niceMut != none) { - for (i = 0; i < niceMut.playersList.Length; i++) { - if ( - (niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts) || - (niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal) - ) { - niceMut.playersList[i].ClientStickGhostProjectile( - instigator, - base, - bone, - shift, - direction, - expData, - niceMut.stuckCounter - ); - } - } + if(expData.Instigator.Role < ROLE_Authority) + SpawnStuckProjectile(instigator, base, bone, shift, direction, expData, false, niceMut.stuckCounter); + if(expData.Instigator.Role == ROLE_Authority && niceMut != none){ + for(i = 0;i < niceMut.playersList.Length;i ++){ + if( (niceMut.playersList[i] != expData.Instigator.Controller && !bSkipGhosts) + || (niceMut.playersList[i] == expData.Instigator.Controller && bDuplReal) ) + niceMut.playersList[i].ClientStickGhostProjectile(instigator, base, bone, shift, direction, expData, + niceMut.stuckCounter); + } } } - -static function NiceBullet SpawnProjectile( - Vector Start, - Rotator Dir, - NiceFire.ShotType shotParams, - NiceFire.FireModeContext fireContext, - optional bool bIsGhost, - optional bool bForceComplexTraj -) { +static function NiceBullet SpawnProjectile(Vector Start, Rotator Dir, NiceFire.ShotType shotParams, NiceFire.FireModeContext fireContext, optional bool bIsGhost, optional bool bForceComplexTraj){ local Actor other; local NiceBullet niceProj; local Vector HitLocation, HitNormal; local NicePlayerController nicePlayer; local class niceVet; - // No class - no projectile - if (shotParams.bulletClass == none) { - return none; - } + if(shotParams.bulletClass == none) + return none; // Try to spawn - if (fireContext.Instigator != none) { - niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir); - } + if(fireContext.Instigator != none) + niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir); // Try harder - if (niceProj == none && fireContext.Instigator != none) { - other = fireContext.Instigator.Trace( - HitLocation, - HitNormal, - Start, - fireContext.Instigator.Location + fireContext.Instigator.EyePosition(), - false, - Vect(0, 0, 1) - ); - if (other != none) { - Start = HitLocation; - } - niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir); + if(niceProj == none && fireContext.Instigator != none){ + other = fireContext.Instigator.Trace(HitLocation, HitNormal, Start, fireContext.Instigator.Location + fireContext.Instigator.EyePosition(), false, Vect(0,0,1)); + if(other != none) + Start = HitLocation; + niceProj = fireContext.Instigator.Spawn(shotParams.bulletClass,,, Start, Dir); } // Give up if failed after these two attempts - if (niceProj == none) { - return none; - } + if(niceProj == none) + return none; niceProj.Renew(); // Initialize projectile - if (fireContext.Instigator != none) { - nicePlayer = NicePlayerController(fireContext.Instigator.Controller); - } - if (nicePlayer != none) { - niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePlayer.PlayerReplicationInfo); - } + if(fireContext.Instigator != none) + nicePlayer = NicePlayerController(fireContext.Instigator.Controller); + if(nicePlayer != none) + niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(nicePlayer.PlayerReplicationInfo); niceProj.bGhost = bIsGhost; // Fill-up data about what damage should projectile deal niceProj.charDamage = shotParams.damage; - if ( - niceVet != none && - fireContext.bIsBursting && - niceVet.static.hasSkill(nicePlayer, class'NiceSkillCommandoExplosivePower') - ) { + if(niceVet != none && fireContext.bIsBursting && niceVet.static.hasSkill(nicePlayer, class'NiceSkillCommandoExplosivePower')) niceProj.charDamage *= class'NiceSkillCommandoExplosivePower'.default.dmgMod; - } - if ( - niceVet != none && - niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBulletStorm') && - nicePlayer.IsZedTimeActive() - ) { + if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillSupportZEDBulletStorm') && nicePlayer.IsZedTimeActive()) niceProj.charDamage = shotParams.damage * class'NiceSkillSupportZEDBulletStorm'.default.damageCut; - } - niceProj.charOrigDamage = niceProj.charDamage; niceProj.charDamageType = shotParams.shotDamageType; niceProj.charExplosionDamageType = shotParams.explosionDamageType; @@ -176,95 +92,76 @@ static function NiceBullet SpawnProjectile( niceProj.charContiniousBonus = fireContext.continiousBonus; // Fill-up data about at what speed should projectile travel niceProj.movementSpeed = shotParams.projSpeed; - if (niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoOnperk')) { + if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoOnperk')) niceProj.movementSpeed *= class'NiceSkillDemoOnperk'.default.speedBonus; - } niceProj.movementDirection = Vector(niceProj.rotation); niceProj.charAffectedByScream = shotParams.projAffectedByScream; niceProj.charIsSticky = shotParams.bShouldStick; niceProj.nicePlayer = nicePlayer; - if (niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoVolatile')) { + if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoVolatile')){ niceProj.charExplosionRadius *= class'NiceSkillDemoVolatile'.default.explRangeMult; niceProj.charExplosionExponent *= class'NiceSkillDemoVolatile'.default.falloffMult; niceProj.charMinExplosionDist *= class'NiceSkillDemoVolatile'.default.safeDistanceMult; } - if ( - niceVet != none && - niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoZEDFullBlast') && - nicePlayer.IsZedTimeActive() - ) { - niceProj.charExplosionRadius *= class'NiceSkillDemoZEDFullBlast'.default.explRadiusMult; - niceProj.charExplosionExponent = 0.0; - } - if (bForceComplexTraj) { - niceProj.bDisableComplexMovement = false; - } - if (niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none) { - niceProj.niceRI = NicePlayerController(niceProj.Instigator.Controller).NiceRI; + if(niceVet != none && niceVet.static.hasSkill(nicePlayer, class'NiceSkillDemoZEDFullBlast') && nicePlayer.IsZedTimeActive()){ + niceProj.charExplosionRadius *= class'NiceSkillDemoZEDFullBlast'.default.explRadiusMult; + niceProj.charExplosionExponent = 0.0; } + if(bForceComplexTraj) + niceProj.bDisableComplexMovement = false; + if(niceProj.Instigator != none && NicePlayerController(niceProj.Instigator.Controller) != none) + niceProj.niceRI = NicePlayerController(niceProj.Instigator.Controller).NiceRI; // And some leftovers //niceProj.bShouldBounce = shotParams.bShouldBounce; niceProj.bInitFinished = true; - return niceProj; } - -static function SpawnStuckProjectile( - KFHumanPawn instigator, - Actor base, - name bone, - Vector shift, - Rotator direction, - NiceBullet.ExplosionData expData, - bool bIsGhost, - int stuckID -) { - local Pawn justPawn; - local NiceFire.ShotType shotParams; - local NiceFire.FireModeContext fireContext; - local NiceBullet spawnedBullet; - local NicePlayerController nicePlayer; - +static function SpawnStuckProjectile(KFHumanPawn instigator, Actor base, name bone, Vector shift, Rotator direction, + NiceBullet.ExplosionData expData, bool bIsGhost, int stuckID){ + local Pawn justPawn; + local NiceFire.ShotType shotParams; + local NiceFire.FireModeContext fireContext; + local NiceBullet spawnedBullet; + local NicePlayerController nicePlayer; nicePlayer = NicePlayerController(instigator.Controller); - if (base == none || nicePlayer == none) { - return; - } + if(base == none || nicePlayer == none) + return; justPawn = Pawn(base); - fireContext.instigator = NiceHumanPawn(instigator); - fireContext.sourceWeapon = expData.sourceWeapon; - shotParams.bulletClass = expData.bulletClass; - shotParams.explosionDamageType = expData.explosionDamageType; - shotParams.explosionDamage = expData.explosionDamage; - shotParams.explosionRadius = expData.explosionRadius; - shotParams.explosionExponent = expData.explosionExponent; - shotParams.explosionMomentum = expData.explosionMomentum; - shotParams.fuseTime = expData.fuseTime; - shotParams.explodeOnFuse = expData.explodeOnFuse; + fireContext.instigator = NiceHumanPawn(instigator); + fireContext.sourceWeapon = expData.sourceWeapon; + shotParams.bulletClass = expData.bulletClass; + shotParams.explosionDamageType = expData.explosionDamageType; + shotParams.explosionDamage = expData.explosionDamage; + shotParams.explosionRadius = expData.explosionRadius; + shotParams.explosionExponent = expData.explosionExponent; + shotParams.explosionMomentum = expData.explosionMomentum; + shotParams.fuseTime = expData.fuseTime; + shotParams.explodeOnFuse = expData.explodeOnFuse; shotParams.projAffectedByScream = expData.affectedByScream; spawnedBullet = SpawnProjectile(base.location, direction, shotParams, fireContext, bIsGhost); - if (spawnedBullet == none) { - return; - } + if(spawnedBullet == none) + return; spawnedBullet.stuckID = stuckID; spawnedBullet.bStuck = true; nicePlayer.RegisterStuckBullet(spawnedBullet); - if (justPawn != none) { - spawnedBullet.bStuckToHead = expData.stuckToHead; - spawnedBullet.SetBase(base); - justPawn.AttachToBone(spawnedBullet, bone); - spawnedBullet.SetRelativeLocation(shift); - spawnedBullet.SetRelativeRotation(Rotator(Vector(direction) << justPawn.GetBoneRotation(bone, 0))); - spawnedBullet.bUseBone = true; - spawnedBullet.stuckBone = bone; - } else { - spawnedBullet.SetBase(base); - spawnedBullet.SetRelativeLocation(shift); - spawnedBullet.SetRelativeRotation(direction - base.rotation); + if(justPawn != none){ + spawnedBullet.bStuckToHead = expData.stuckToHead; + spawnedBullet.SetBase(base); + justPawn.AttachToBone(spawnedBullet, bone); + spawnedBullet.SetRelativeLocation(shift); + spawnedBullet.SetRelativeRotation(Rotator(Vector(direction) << justPawn.GetBoneRotation(bone, 0))); + spawnedBullet.bUseBone = true; + spawnedBullet.stuckBone = bone; + } + else{ + spawnedBullet.SetBase(base); + spawnedBullet.SetRelativeLocation(shift); } } -defaultproperties { - bHidden=True - RemoteRole=ROLE_SimulatedProxy - LifeSpan=1.000000 -} \ No newline at end of file +defaultproperties +{ + bHidden=True + RemoteRole=ROLE_SimulatedProxy + LifeSpan=1.000000 +} diff --git a/sources/Weapons/NiceWeapon.uc b/sources/Weapons/NiceWeapon.uc index 7cada8c..b975465 100644 --- a/sources/Weapons/NiceWeapon.uc +++ b/sources/Weapons/NiceWeapon.uc @@ -146,7 +146,6 @@ var bool bAutoReloadPaused; // This is used to 'pause' auto relo var float autoReloadPauseFrame; // Frame at which current pause began var bool bAutoReloadRateApplied; // Flag that remembers whether or not we've already applied reload speed up for current auto reload (to avoid constant animation's speed updates) var float autoReloadSpeedModifier; -var bool updatedDefaultReloadValues; // Acrtive reload-related variables // Active reload state enum EActiveReloadState{ @@ -220,8 +219,6 @@ static function bool UnloadAssets(){ return default.ReferenceCount == 0; } simulated function PostBeginPlay(){ - local float swapSpeedMod, reloadSpeedMod; - if(default.recordedZoomTime < 0) default.recordedZoomTime = ZoomTime; recordedZoomTime = default.recordedZoomTime; @@ -243,31 +240,6 @@ simulated function PostBeginPlay(){ if(FireModeClass[0] != none) stdFireRate = FireModeClass[0].default.fireRate; super.PostBeginPlay(); - // Hack solution - speed up reload and swap speed - swapSpeedMod = 2.0; - reloadSpeedMod = 1.5; - bringUpTime /= swapSpeedMod; - putDownTime /= swapSpeedMod; - selectAnimRate *= swapSpeedMod; - putDownAnimRate *= swapSpeedMod; - quickPutDownTime /= swapSpeedMod; - quickBringUpTime /= swapSpeedMod; - if (!default.updatedDefaultReloadValues) { - if(reloadType == RTYPE_AUTO) { - if (fireModeClass[0] != none) { - fireModeClass[0].default.FireAnimRate *= reloadSpeedMod; - } - if (fireModeClass[1] != none) { - fireModeClass[1].default.FireAnimRate *= reloadSpeedMod; - } - } else { - reloadRate /= reloadSpeedMod; - reloadAnimRate *= reloadSpeedMod; - default.reloadRate = reloadRate; - default.reloadAnimRate = reloadAnimRate; - } - default.updatedDefaultReloadValues = true; - } } // Allows to prevent leaving iron sights unwillingly @@ -1122,7 +1094,6 @@ simulated function int GetMagazineAmmo(){ else return MagAmmoRemaining; } - simulated function bool AllowReload(){ local int actualMagSize; actualMagSize = GetMagazineAmmo(); @@ -1156,7 +1127,6 @@ simulated function float GetCurrentReloadMult(){ local NiceHumanPawn nicePawn; local NicePlayerController nicePlayer; local class niceVet; - nicePawn = NiceHumanPawn(Instigator); nicePlayer = NicePlayerController(Instigator.Controller); if(nicePawn != none) @@ -1654,17 +1624,17 @@ simulated function float GetAmmoMulti() defaultproperties { - recordedZoomTime=-1.000000 - SecondaryCharge=1 - LaserAttachmentClass=Class'ScrnLaserAttachmentFirstPerson' - LaserDotClass=Class'ScrnLocalLaserDot' - LaserAttachmentBone="LightBone" - MagazineBone="Magazine" - bHasChargePhase=True - autoReloadSpeedModifier=1.000000 - bCanActiveReload=True - activeSlowdown=0.850000 - activeSpeedup=1.150000 - activeWindow=0.060000 - bModeZeroCanDryFire=True + recordedZoomTime=-1.000000 + SecondaryCharge=1 + LaserAttachmentClass=Class'ScrnLaserAttachmentFirstPerson' + LaserDotClass=Class'ScrnLocalLaserDot' + LaserAttachmentBone="LightBone" + MagazineBone="Magazine" + bHasChargePhase=True + autoReloadSpeedModifier=1.000000 + bCanActiveReload=True + activeSlowdown=0.850000 + activeSpeedup=1.150000 + activeWindow=0.060000 + bModeZeroCanDryFire=True } diff --git a/sources/Weapons/Playable/AssaultRifles/AK12/NiceAK12Pickup.uc b/sources/Weapons/Playable/AssaultRifles/AK12/NiceAK12Pickup.uc index d910bd9..a9379e2 100644 --- a/sources/Weapons/Playable/AssaultRifles/AK12/NiceAK12Pickup.uc +++ b/sources/Weapons/Playable/AssaultRifles/AK12/NiceAK12Pickup.uc @@ -3,7 +3,7 @@ defaultproperties { Weight=6.000000 cost=750 - AmmoCost=25 + AmmoCost=19 BuyClipSize=40 PowerValue=55 SpeedValue=80 diff --git a/sources/Weapons/Playable/AssaultRifles/AK47/NiceAK47Pickup.uc b/sources/Weapons/Playable/AssaultRifles/AK47/NiceAK47Pickup.uc index 6dad7d2..db19d61 100644 --- a/sources/Weapons/Playable/AssaultRifles/AK47/NiceAK47Pickup.uc +++ b/sources/Weapons/Playable/AssaultRifles/AK47/NiceAK47Pickup.uc @@ -3,7 +3,7 @@ defaultproperties { Weight=6.000000 cost=750 - AmmoCost=26 + AmmoCost=19 BuyClipSize=30 PowerValue=40 SpeedValue=80 diff --git a/sources/Weapons/Playable/AssaultRifles/MKb42/NiceMKb42Pickup.uc b/sources/Weapons/Playable/AssaultRifles/MKb42/NiceMKb42Pickup.uc index 01e2aa8..c97c589 100644 --- a/sources/Weapons/Playable/AssaultRifles/MKb42/NiceMKb42Pickup.uc +++ b/sources/Weapons/Playable/AssaultRifles/MKb42/NiceMKb42Pickup.uc @@ -3,7 +3,7 @@ defaultproperties { Weight=6.000000 cost=750 - AmmoCost=19 + AmmoCost=22 BuyClipSize=30 PowerValue=40 SpeedValue=85 diff --git a/sources/Weapons/Playable/Explosives/LAW/NiceLAWFire.uc b/sources/Weapons/Playable/Explosives/LAW/NiceLAWFire.uc index 93016d8..096355b 100644 --- a/sources/Weapons/Playable/Explosives/LAW/NiceLAWFire.uc +++ b/sources/Weapons/Playable/Explosives/LAW/NiceLAWFire.uc @@ -19,7 +19,7 @@ defaultproperties StereoFireSoundRef="KF_LAWSnd.LAW_FireST" NoAmmoSoundRef="KF_LAWSnd.LAW_DryFire" DamageType=class'NiceDamTypeLAWBlunt' - DamageMax=350 + DamageMax=750 bSplashDamage=True bRecommendSplashDamage=True bWaitForRelease=True diff --git a/sources/Weapons/Playable/Grenades/NiceNade.uc b/sources/Weapons/Playable/Grenades/NiceNade.uc index b984b18..48b778b 100644 --- a/sources/Weapons/Playable/Grenades/NiceNade.uc +++ b/sources/Weapons/Playable/Grenades/NiceNade.uc @@ -39,32 +39,114 @@ function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Mo Explode(HitLocation, vect(0,0,1)); } } +simulated function HurtRadius( float DamageAmount, float DamageRadius, class DamageType, float Momentum, vector HitLocation ) +{ + local actor Victims; + local float damageScale, dist; + local vector dir; + local int NumKilled; + local KFMonster KFMonsterVictim; + local bool bMonster; + local Pawn P; + local KFPawn KFP; + local array CheckedPawns; + local int i; + local bool bAlreadyChecked; + local SRStatsBase Stats; -simulated function HurtRadius( - float damageAmount, - float damageRadius, - class damageType, - float momentum, - Vector hitLocation -) { - local NicePlayerController niceController; - local NiceReplicationInfo niceRI; + if ( bHurtEntry ) + return; + bHurtEntry = true; + + if( Role == ROLE_Authority && Instigator != none && Instigator.PlayerReplicationInfo != none ) + Stats = SRStatsBase(Instigator.PlayerReplicationInfo.SteamStatsAndAchievements); + + foreach CollidingActors (class 'Actor', Victims, DamageRadius, HitLocation) + { + P = none; + KFMonsterVictim = none; + bMonster = false; + KFP = none; + bAlreadyChecked = false; - if (instigator == none) return; - niceController = NicePlayerController(instigator.controller); - if (niceController == none) return; - niceRI = niceController.niceRI; - if (niceRI == none) return; + // don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag + if( (Victims != self) && (Hurtwall != Victims) && (Victims.Role == ROLE_Authority) && !Victims.IsA('FluidSurfaceInfo') + && ExtendedZCollision(Victims)==None ) + { + if( (Instigator==None || Instigator.Health<=0) && KFPawn(Victims)!=None ) + Continue; + dir = Victims.Location - HitLocation; + dist = FMax(1,VSize(dir)); + dir = dir/dist; + damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius); - Destroy(); + if ( Instigator == None || Instigator.Controller == None ) + { + Victims.SetDelayedDamageInstigatorController( InstigatorController ); + } - niceRI.ServerExplode(damageAmount, - damageRadius, - 1.0, - niceExplosiveDamage, - momentum, - hitLocation, - instigator); + P = Pawn(Victims); + if( P != none ) { + for (i = 0; i < CheckedPawns.Length; i++) { + if (CheckedPawns[i] == P) { + bAlreadyChecked = true; + break; + } + } + if( bAlreadyChecked ) + continue; + CheckedPawns[CheckedPawns.Length] = P; + + KFMonsterVictim = KFMonster(Victims); + if( KFMonsterVictim != none && KFMonsterVictim.Health <= 0 ) + KFMonsterVictim = none; + + KFP = KFPawn(Victims); + + if( KFMonsterVictim != none ) { + damageScale *= KFMonsterVictim.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity)); + bMonster = true; // in case TakeDamage() and further Die() deletes the monster + } + else if( KFP != none ) { + damageScale *= KFP.GetExposureTo(Location + 15 * -Normal(PhysicsVolume.Gravity)); + } + + if ( damageScale <= 0) + continue; + } + if(NiceMonster(Victims) != none) + Victims.TakeDamage(damageScale * DamageAmount,Instigator,Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir + ,(damageScale * Momentum * dir), niceExplosiveDamage); + else + Victims.TakeDamage(damageScale * DamageAmount,Instigator,Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir + ,(damageScale * Momentum * dir), DamageType); + + if( bMonster && (KFMonsterVictim == none || KFMonsterVictim.Health < 1) ) { + NumKilled++; + } + + if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0) + { + Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation); + } + } + } + + if( Role == ROLE_Authority ) + { + if ( bBlewInHands && NumKilled >= 5 && Stats != none ) + class'ScrnAchievements'.static.ProgressAchievementByID(Stats.Rep, 'SuicideBomber', 1); + + if ( NumKilled >= 4 ) + { + KFGameType(Level.Game).DramaticEvent(0.05); + } + else if ( NumKilled >= 2 ) + { + KFGameType(Level.Game).DramaticEvent(0.03); + } + } + bHurtEntry = false; } // Overridden to spawn different AvoidMarker simulated function HitWall( vector HitNormal, actor Wall ){ diff --git a/sources/Weapons/Playable/Heavy/M249/NiceM249Fire.uc b/sources/Weapons/Playable/Heavy/M249/NiceM249Fire.uc index 536e2ad..f531707 100644 --- a/sources/Weapons/Playable/Heavy/M249/NiceM249Fire.uc +++ b/sources/Weapons/Playable/Heavy/M249/NiceM249Fire.uc @@ -4,8 +4,8 @@ defaultproperties ProjectileSpeed=48250.000000 FireAimedAnim="Fire" RecoilRate=0.040000 - maxVerticalRecoilAngle=115 - maxHorizontalRecoilAngle=0 + maxVerticalRecoilAngle=550 + maxHorizontalRecoilAngle=225 ShellEjectClass=Class'ROEffects.KFShellEjectAK' ShellEjectBoneName="Shell_eject" bAccuracyBonusForSemiAuto=True diff --git a/sources/Weapons/Playable/Heavy/M41A/NiceDamTypeM41AAssaultRifle.uc b/sources/Weapons/Playable/Heavy/M41A/NiceDamTypeM41AAssaultRifle.uc index ea086e8..d7f796b 100644 --- a/sources/Weapons/Playable/Heavy/M41A/NiceDamTypeM41AAssaultRifle.uc +++ b/sources/Weapons/Playable/Heavy/M41A/NiceDamTypeM41AAssaultRifle.uc @@ -10,6 +10,4 @@ defaultproperties KDeathVel=1400.000000 KDeathUpKick=150.000000 VehicleDamageScaling=0.700000 - stunMultiplier=3.0 - stunLengthMultiplier=2.0 } diff --git a/sources/Weapons/Playable/Heavy/M41A/NiceM41AAmmo.uc b/sources/Weapons/Playable/Heavy/M41A/NiceM41AAmmo.uc index 06e02e2..6f7b45b 100644 --- a/sources/Weapons/Playable/Heavy/M41A/NiceM41AAmmo.uc +++ b/sources/Weapons/Playable/Heavy/M41A/NiceM41AAmmo.uc @@ -4,8 +4,8 @@ defaultproperties { WeaponPickupClass=class'NiceM41APickup' AmmoPickupAmount=66 - MaxAmmo=264 - InitialAmount=66 + MaxAmmo=300 + InitialAmount=75 PickupClass=class'NiceM41AAmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) diff --git a/sources/Weapons/Playable/Heavy/M41A/NiceM41APickup.uc b/sources/Weapons/Playable/Heavy/M41A/NiceM41APickup.uc index 4dc3f6f..610f503 100644 --- a/sources/Weapons/Playable/Heavy/M41A/NiceM41APickup.uc +++ b/sources/Weapons/Playable/Heavy/M41A/NiceM41APickup.uc @@ -3,7 +3,7 @@ class NiceM41APickup extends NiceM41APrimaryPickup; defaultproperties { crossPerkIndecies(0)=6 - AmmoCost=24 + AmmoCost=60 BuyClipSize=1 SecondaryAmmoShortName="M41A Frag Grenades" PrimaryWeaponPickup=class'NiceM41APrimaryPickup' diff --git a/sources/Weapons/Playable/Heavy/M41A/NiceM41APrimaryPickup.uc b/sources/Weapons/Playable/Heavy/M41A/NiceM41APrimaryPickup.uc index 808f48a..0f05cc6 100644 --- a/sources/Weapons/Playable/Heavy/M41A/NiceM41APrimaryPickup.uc +++ b/sources/Weapons/Playable/Heavy/M41A/NiceM41APrimaryPickup.uc @@ -3,7 +3,7 @@ defaultproperties { cost=750 Weight=7.000000 - AmmoCost=25 + AmmoCost=66 BuyClipSize=66 PowerValue=70 SpeedValue=100 diff --git a/sources/Weapons/Playable/Heavy/M41A/NiceM41AProjectileAmmo.uc b/sources/Weapons/Playable/Heavy/M41A/NiceM41AProjectileAmmo.uc index 1887b81..a778ca5 100644 --- a/sources/Weapons/Playable/Heavy/M41A/NiceM41AProjectileAmmo.uc +++ b/sources/Weapons/Playable/Heavy/M41A/NiceM41AProjectileAmmo.uc @@ -3,7 +3,7 @@ defaultproperties { WeaponPickupClass=class'NiceM41APickup' AmmoPickupAmount=1 - MaxAmmo=5 + MaxAmmo=8 InitialAmount=2 IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=434,Y1=253,X2=506,Y2=292) diff --git a/sources/Weapons/Playable/Heavy/RPK47/NiceRPK47Fire.uc b/sources/Weapons/Playable/Heavy/RPK47/NiceRPK47Fire.uc index 0bbd5bb..79b5528 100644 --- a/sources/Weapons/Playable/Heavy/RPK47/NiceRPK47Fire.uc +++ b/sources/Weapons/Playable/Heavy/RPK47/NiceRPK47Fire.uc @@ -5,8 +5,8 @@ defaultproperties contBonus=1.400000 FireAimedAnim="Fire_Iron" RecoilRate=0.050000 - maxVerticalRecoilAngle=100 - maxHorizontalRecoilAngle=0 + maxVerticalRecoilAngle=400 + maxHorizontalRecoilAngle=200 ShellEjectClass=Class'ROEffects.KFShellEjectAK' ShellEjectBoneName="Shell_eject" bAccuracyBonusForSemiAuto=True diff --git a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSW.uc b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSW.uc index 99f9056..a74b185 100644 --- a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSW.uc +++ b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSW.uc @@ -17,7 +17,7 @@ defaultproperties MagazineBone="clip" bHasScope=True ZoomedDisplayFOVHigh=50.000000 - MagCapacity=60 + MagCapacity=30 ReloadRate=3.500000 ReloadAnim="Reload" ReloadAnimRate=1.000000 diff --git a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmo.uc b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmo.uc index 0fc562c..f6abd5d 100644 --- a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmo.uc +++ b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmo.uc @@ -2,7 +2,7 @@ class NiceSA80LSWAmmo extends NiceAmmo; defaultproperties { WeaponPickupClass=class'NiceSA80LSWPickup' - AmmoPickupAmount=60 + AmmoPickupAmount=30 MaxAmmo=360 InitialAmount=90 PickupClass=class'NiceSA80LSWAmmoPickup' diff --git a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmoPickup.uc b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmoPickup.uc index 058a8e1..6c6ea5b 100644 --- a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmoPickup.uc +++ b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWAmmoPickup.uc @@ -1,7 +1,7 @@ class NiceSA80LSWAmmoPickup extends NiceAmmoPickup; defaultproperties { - AmmoAmount=60 + AmmoAmount=30 InventoryType=class'NiceSA80LSWAmmo' PickupMessage="5.56x45" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo' diff --git a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWFire.uc b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWFire.uc index 033030e..5108bae 100644 --- a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWFire.uc +++ b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWFire.uc @@ -4,8 +4,8 @@ defaultproperties ProjectileSpeed=46500.000000 FireAimedAnim="Iron_Idle" RecoilRate=0.050000 - maxVerticalRecoilAngle=75 - maxHorizontalRecoilAngle=0 + maxVerticalRecoilAngle=300 + maxHorizontalRecoilAngle=150 ShellEjectClass=Class'ROEffects.KFShellEjectBullpup' ShellEjectBoneName="Shell_eject" bAccuracyBonusForSemiAuto=True diff --git a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWPickup.uc b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWPickup.uc index 0083a16..f57be35 100644 --- a/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWPickup.uc +++ b/sources/Weapons/Playable/Heavy/SA80LSW/NiceSA80LSWPickup.uc @@ -3,8 +3,8 @@ defaultproperties { cost=200 Weight=5.000000 - AmmoCost=10 - BuyClipSize=60 + AmmoCost=5 + BuyClipSize=30 PowerValue=41 SpeedValue=60 RangeValue=60 diff --git a/sources/Weapons/Playable/Heavy/XMV/NiceXMV850Fire.uc b/sources/Weapons/Playable/Heavy/XMV/NiceXMV850Fire.uc index 1042ce3..d266c98 100644 --- a/sources/Weapons/Playable/Heavy/XMV/NiceXMV850Fire.uc +++ b/sources/Weapons/Playable/Heavy/XMV/NiceXMV850Fire.uc @@ -12,12 +12,12 @@ simulated function HandleRecoil(float Rec) defaultproperties { ProjectileSpeed=42650.000000 - maxBonusContLenght=10 + maxBonusContLenght=5 contBonusReset=false FireAimedAnim="FireLoop" RecoilRate=0.040000 - maxVerticalRecoilAngle=25 - maxHorizontalRecoilAngle=0 + maxVerticalRecoilAngle=450 + maxHorizontalRecoilAngle=225 ShellEjectClass=Class'ROEffects.KFShellEjectSCAR' ShellEjectBoneName="ejector" FireSoundRef="HMG_S.XMV.XMV-Fire-1" diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceDamTypeHFRAssaultRifle.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceDamTypeHFRAssaultRifle.uc new file mode 100644 index 0000000..4bd3a15 --- /dev/null +++ b/sources/Weapons/Playable/Incendiary/HFR/NiceDamTypeHFRAssaultRifle.uc @@ -0,0 +1,19 @@ +class NiceDamTypeHFRAssaultRifle extends NiceDamTypeFire + abstract; +defaultproperties +{ + heatPart=0.500000 + HeadShotDamageMult=6.000000 + bCheckForHeadShots=True + WeaponClass=class'NiceHFR' + DeathString="%k killed %o (Horzine Flame Rifle)." + FemaleSuicide="%o shot herself in the foot." + MaleSuicide="%o shot himself in the foot." + bRagdollBullet=True + PawnDamageEmitter=Class'ROEffects.ROBloodPuff' + LowGoreDamageEmitter=Class'ROEffects.ROBloodPuffNoGore' + LowDetailEmitter=Class'ROEffects.ROBloodPuffSmall' + KDamageImpulse=5500.000000 + KDeathVel=175.000000 + KDeathUpKick=15.000000 +} diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceHFR.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceHFR.uc index e5d0d55..15a1683 100644 --- a/sources/Weapons/Playable/Incendiary/HFR/NiceHFR.uc +++ b/sources/Weapons/Playable/Incendiary/HFR/NiceHFR.uc @@ -1,5 +1,316 @@ -class NiceHFR extends NiceScopedWeapon; +// Modification of the AAR525 weapons by: [B.R]HekuT +class NiceHFR extends KFWeapon; +#exec OBJ LOAD FILE=KillingFloorWeapons.utx +#exec OBJ LOAD FILE=KillingFloorHUD.utx +#exec OBJ LOAD FILE=Inf_Weapons_Foley.uax +#exec OBJ LOAD FILE=KF_Weapons5_Scopes_Trip_T.utx +var() Material ZoomMat; +var() int lenseMaterialID; +var() float scopePortalFOVHigh; +var() float scopePortalFOV; +var() vector XoffsetScoped; +var() vector XoffsetHighDetail; +var() int scopePitch; +var() int scopeYaw; +var() int scopePitchHigh; +var() int scopeYawHigh; +var ScriptedTexture ScopeScriptedTexture; +var Shader ScopeScriptedShader; +var Material ScriptedTextureFallback; +var Combiner ScriptedScopeCombiner; +var Combiner ScriptedScopeStatic; +var texture TexturedScopeTexture; +var bool bInitializedScope; +var string ZoomMatRef; +var string ScriptedTextureFallbackRef; +static function PreloadAssets(Inventory Inv, optional bool bSkipRefCount) +{ + super.PreloadAssets(Inv, bSkipRefCount); + default.ZoomMat = FinalBlend(DynamicLoadObject(default.ZoomMatRef, class'FinalBlend', true)); + default.ScriptedTextureFallback = texture(DynamicLoadObject(default.ScriptedTextureFallbackRef, class'texture', true)); + if ( M99SniperRifle(Inv) != none ) + { + M99SniperRifle(Inv).ZoomMat = default.ZoomMat; + M99SniperRifle(Inv).ScriptedTextureFallback = default.ScriptedTextureFallback; + } +} +static function bool UnloadAssets() +{ + if ( super.UnloadAssets() ) + { + default.ZoomMat = none; + default.ScriptedTextureFallback = none; + } + return true; +} +exec function pfov(int thisFOV) +{ + if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() ) + return; + scopePortalFOV = thisFOV; +} +exec function pPitch(int num) +{ + if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() ) + return; + scopePitch = num; + scopePitchHigh = num; +} +exec function pYaw(int num) +{ + if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() ) + return; + scopeYaw = num; + scopeYawHigh = num; +} +simulated exec function TexSize(int i, int j) +{ + if( !class'ROEngine.ROLevelInfo'.static.RODebugMode() ) + return; + ScopeScriptedTexture.SetSize(i, j); +} +simulated function bool ShouldDrawPortal() +{ + if( bAimingRifle ) + return true; + else + return false; +} +simulated function PostBeginPlay() +{ + super.PostBeginPlay(); + KFScopeDetail = class'KFMod.KFWeapon'.default.KFScopeDetail; + UpdateScopeMode(); +} +simulated function UpdateScopeMode() +{ + if (Level.NetMode != NM_DedicatedServer && Instigator != none && Instigator.IsLocallyControlled() && + Instigator.IsHumanControlled() ) + { + if( KFScopeDetail == KF_ModelScope ) + { + scopePortalFOV = default.scopePortalFOV; + ZoomedDisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV); + if (bAimingRifle) + { + PlayerViewOffset = XoffsetScoped; + } + if( ScopeScriptedTexture == none ) + { + ScopeScriptedTexture = ScriptedTexture(Level.ObjectPool.AllocateObject(class'ScriptedTexture')); + } + + ScopeScriptedTexture.FallBackMaterial = ScriptedTextureFallback; + ScopeScriptedTexture.SetSize(512,512); + ScopeScriptedTexture.Client = Self; + + if( ScriptedScopeCombiner == none ) + { + ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner')); + ScriptedScopeCombiner.Material1 = Texture'KF_Weapons5_Scopes_Trip_T.Scope.MilDot'; + ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader'; + ScriptedScopeCombiner.CombineOperation = CO_Multiply; + ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask; + ScriptedScopeCombiner.Material2 = ScopeScriptedTexture; + } + + if( ScopeScriptedShader == none ) + { + ScopeScriptedShader = Shader(Level.ObjectPool.AllocateObject(class'Shader')); + ScopeScriptedShader.Diffuse = ScriptedScopeCombiner; + ScopeScriptedShader.SelfIllumination = ScriptedScopeCombiner; + ScopeScriptedShader.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader'; + } + + bInitializedScope = true; + } + else if( KFScopeDetail == KF_ModelScopeHigh ) + { + scopePortalFOV = scopePortalFOVHigh; + ZoomedDisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOVHigh); + if (bAimingRifle) + { + PlayerViewOffset = XoffsetHighDetail; + } + + if( ScopeScriptedTexture == none ) + { + ScopeScriptedTexture = ScriptedTexture(Level.ObjectPool.AllocateObject(class'ScriptedTexture')); + } + ScopeScriptedTexture.FallBackMaterial = ScriptedTextureFallback; + ScopeScriptedTexture.SetSize(1024,1024); + ScopeScriptedTexture.Client = Self; + + if( ScriptedScopeCombiner == none ) + { + ScriptedScopeCombiner = Combiner(Level.ObjectPool.AllocateObject(class'Combiner')); + ScriptedScopeCombiner.Material1 = Texture'KF_Weapons5_Scopes_Trip_T.Scope.MilDot'; + ScriptedScopeCombiner.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader'; + ScriptedScopeCombiner.CombineOperation = CO_Multiply; + ScriptedScopeCombiner.AlphaOperation = AO_Use_Mask; + ScriptedScopeCombiner.Material2 = ScopeScriptedTexture; + } + + if( ScopeScriptedShader == none ) + { + ScopeScriptedShader = Shader(Level.ObjectPool.AllocateObject(class'Shader')); + ScopeScriptedShader.Diffuse = ScriptedScopeCombiner; + ScopeScriptedShader.SelfIllumination = ScriptedScopeCombiner; + ScopeScriptedShader.FallbackMaterial = Shader'ScopeShaders.Zoomblur.LensShader'; + } + + bInitializedScope = true; + } + else if (KFScopeDetail == KF_TextureScope) + { + ZoomedDisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV); + PlayerViewOffset.X = default.PlayerViewOffset.X; + + bInitializedScope = true; + } + } +} +simulated event RenderTexture(ScriptedTexture Tex) +{ + local rotator RollMod; + RollMod = Instigator.GetViewRotation(); + if(Owner != none && Instigator != none && Tex != none && Tex.Client != none) + Tex.DrawPortal(0,0,Tex.USize,Tex.VSize,Owner,(Instigator.Location + Instigator.EyePosition()), RollMod, scopePortalFOV ); +} +/** + * Handles all the functionality for zooming in including + * setting the parameters for the weapon, pawn, and playercontroller + * + * @param bAnimateTransition whether or not to animate this zoom transition + */ +simulated function ZoomIn(bool bAnimateTransition) +{ + super(BaseKFWeapon).ZoomIn(bAnimateTransition); + bAimingRifle = True; + if( KFHumanPawn(Instigator)!=none ) + KFHumanPawn(Instigator).SetAiming(True); + if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none ) + { + if( AimInSound != none ) + { + PlayOwnedSound(AimInSound, SLOT_Interact,,,,, false); + } + } +} +/** + * Handles all the functionality for zooming out including + * setting the parameters for the weapon, pawn, and playercontroller + * + * @param bAnimateTransition whether or not to animate this zoom transition + */ +simulated function ZoomOut(bool bAnimateTransition) +{ + super.ZoomOut(bAnimateTransition); + bAimingRifle = False; + if( KFHumanPawn(Instigator)!=none ) + KFHumanPawn(Instigator).SetAiming(False); + if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none ) + { + if( AimOutSound != none ) + { + PlayOwnedSound(AimOutSound, SLOT_Interact,,,,, false); + } + KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0); + } +} +simulated event OnZoomInFinished() +{ + local name anim; + local float frame, rate; + GetAnimParams(0, anim, frame, rate); + if (ClientState == WS_ReadyToFire) + { + if (anim == IdleAnim) + { + PlayIdle(); + } + } + if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none && + KFScopeDetail == KF_TextureScope ) + { + KFPlayerController(Instigator.Controller).TransitionFOV(PlayerIronSightFOV,0.0); + } +} +simulated event RenderOverlays(Canvas Canvas) +{ + local int m; + local PlayerController PC; + if (Instigator == none) + return; + PC = PlayerController(Instigator.Controller); + if(PC == none) + return; + if(!bInitializedScope && PC != none ) + { + UpdateScopeMode(); + } + Canvas.DrawActor(none, false, true); + for (m = 0; m < NUM_FIRE_MODES; m++) + { + if (FireMode[m] != none) + { + FireMode[m].DrawMuzzleFlash(Canvas); + } + } + + SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) ); + SetRotation( Instigator.GetViewRotation() + ZoomRotInterp); + PreDrawFPWeapon(); + + if(bAimingRifle && PC != none && (KFScopeDetail == KF_ModelScope || KFScopeDetail == KF_ModelScopeHigh)) + { + if (ShouldDrawPortal()) + { + if ( ScopeScriptedTexture != none ) + { + Skins[LenseMaterialID] = ScopeScriptedShader; + ScopeScriptedTexture.Client = Self; + ScopeScriptedTexture.Revision = (ScopeScriptedTexture.Revision +1); + } + } + + bDrawingFirstPerson = true; + Canvas.DrawBoundActor(self, false, false,DisplayFOV,PC.Rotation,rot(0,0,0),Instigator.CalcZoomedDrawOffset(self)); + bDrawingFirstPerson = false; + } + else if( KFScopeDetail == KF_TextureScope && PC.DesiredFOV == PlayerIronSightFOV && bAimingRifle) + { + Skins[LenseMaterialID] = ScriptedTextureFallback; + + SetZoomBlendColor(Canvas); + + Canvas.Style = ERenderStyle.STY_Normal; + Canvas.SetPos(0, 0); + Canvas.DrawTile(ZoomMat, (Canvas.SizeX - Canvas.SizeY) / 2, Canvas.SizeY, 0.0, 0.0, 8, 8); + Canvas.SetPos(Canvas.SizeX, 0); + Canvas.DrawTile(ZoomMat, -(Canvas.SizeX - Canvas.SizeY) / 2, Canvas.SizeY, 0.0, 0.0, 8, 8); + + Canvas.Style = 255; + Canvas.SetPos((Canvas.SizeX - Canvas.SizeY) / 2,0); + Canvas.DrawTile(ZoomMat, Canvas.SizeY, Canvas.SizeY, 0.0, 0.0, 1024, 1024); + + Canvas.Font = Canvas.MedFont; + Canvas.SetDrawColor(200,150,0); + + Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.43); + Canvas.DrawText("Zoom: 3.0"); + + Canvas.SetPos(Canvas.SizeX * 0.16, Canvas.SizeY * 0.47); + } + else + { + Skins[LenseMaterialID] = ScriptedTextureFallback; + bDrawingFirstPerson = true; + Canvas.DrawActor(self, false, false, DisplayFOV); + bDrawingFirstPerson = false; + } +} simulated function float CalcAspectRatioAdjustedFOV(float AdjustFOV) { local KFPlayerController KFPC; @@ -22,15 +333,204 @@ simulated function float CalcAspectRatioAdjustedFOV(float AdjustFOV) return AdjustFOV; } } +simulated function AdjustIngameScope() +{ + local PlayerController PC; + if(Instigator == none || PlayerController(Instigator.Controller) == none) + return; + PC = PlayerController(Instigator.Controller); + if( !bHasScope ) + return; + switch (KFScopeDetail) + { + case KF_ModelScope: + if( bAimingRifle ) + DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV); + if ( PC.DesiredFOV == PlayerIronSightFOV && bAimingRifle ) + { + if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none ) + { + KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0); +} + } + break; + case KF_TextureScope: + if( bAimingRifle ) + DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV); + if ( bAimingRifle && PC.DesiredFOV != PlayerIronSightFOV ) + { + if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none ) + { + KFPlayerController(Instigator.Controller).TransitionFOV(PlayerIronSightFOV,0.0); + } + } + break; + + case KF_ModelScopeHigh: + if( bAimingRifle ) + { + if( ZoomedDisplayFOVHigh > 0 ) + { + DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOVHigh); + } + else + { + DisplayFOV = CalcAspectRatioAdjustedFOV(default.ZoomedDisplayFOV); + } + } + if ( bAimingRifle && PC.DesiredFOV == PlayerIronSightFOV ) + { + if( Level.NetMode != NM_DedicatedServer && KFPlayerController(Instigator.Controller) != none ) + { + KFPlayerController(Instigator.Controller).TransitionFOV(KFPlayerController(Instigator.Controller).DefaultFOV,0.0); + } + } + break; + } + UpdateScopeMode(); +} +simulated event Destroyed() +{ + if (ScopeScriptedTexture != none) + { + ScopeScriptedTexture.Client = none; + Level.ObjectPool.FreeObject(ScopeScriptedTexture); + ScopeScriptedTexture=none; + } + if (ScriptedScopeCombiner != none) + { + ScriptedScopeCombiner.Material2 = none; + Level.ObjectPool.FreeObject(ScriptedScopeCombiner); + ScriptedScopeCombiner = none; + } + if (ScopeScriptedShader != none) + { + ScopeScriptedShader.Diffuse = none; + ScopeScriptedShader.SelfIllumination = none; + Level.ObjectPool.FreeObject(ScopeScriptedShader); + ScopeScriptedShader = none; + } + Super.Destroyed(); +} +simulated function PreTravelCleanUp() +{ + if (ScopeScriptedTexture != none) + { + ScopeScriptedTexture.Client = none; + Level.ObjectPool.FreeObject(ScopeScriptedTexture); + ScopeScriptedTexture=none; + } + if (ScriptedScopeCombiner != none) + { + ScriptedScopeCombiner.Material2 = none; + Level.ObjectPool.FreeObject(ScriptedScopeCombiner); + ScriptedScopeCombiner = none; + } + if (ScopeScriptedShader != none) + { + ScopeScriptedShader.Diffuse = none; + ScopeScriptedShader.SelfIllumination = none; + Level.ObjectPool.FreeObject(ScopeScriptedShader); + ScopeScriptedShader = none; + } +} +state PendingClientWeaponSet +{ + simulated function Timer() + { + if ( Pawn(Owner) != none && !bIsReloading ) + { + ClientWeaponSet(bPendingSwitch); + } + + if ( IsInState('PendingClientWeaponSet') ) + { + SetTimer(0.1, false); + } + } + simulated function BeginState() + { + SetTimer(0.1, false); + } + simulated function EndState() + { + } +} +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; +} +function bool RecommendRangedAttack() +{ + return true; +} +function float SuggestAttackStyle() +{ + return -1.0; +} +function bool RecommendLongRangedAttack() +{ + return true; +} +simulated function AnimEnd(int channel) +{ + if(!FireMode[1].IsInState('FireLoop')) + { + Super.AnimEnd(channel); + } +} +simulated function WeaponTick(float dt) +{ + Super.WeaponTick(dt); +} +simulated function bool StartFire(int Mode) +{ + if( Mode == 0 ) + return super.StartFire(Mode); + if( !super.StartFire(Mode) ) + return false; + + if( AmmoAmount(0) <= 0 ) + { + return false; + } + AnimStopLooping(); + if( !FireMode[Mode].IsInState('FireLoop') && (AmmoAmount(0) > 0) ) + { + FireMode[Mode].StartFiring(); + return true; + } + else + { + return false; + } + return true; +} defaultproperties { - reloadPreEndFrame=0.339 - reloadEndFrame=0.732 - reloadChargeEndFrame=-1.000000 - reloadMagStartFrame=0.643 - reloadChargeStartFrame=-1.000000 - magazineBone="Magazine" lenseMaterialID=3 scopePortalFOVHigh=22.000000 scopePortalFOV=12.000000 @@ -38,13 +538,13 @@ defaultproperties ScriptedTextureFallbackRef="NicePackT.HFR.CBLens_cmb" bHasScope=True ZoomedDisplayFOVHigh=35.000000 - MagCapacity=50 + MagCapacity=10 ReloadRate=3.000000 ReloadAnim="Reload" ReloadAnimRate=0.600000 WeaponReloadAnim="Reload_M4" bSteadyAim=True - Weight=5.000000 + Weight=7.000000 bHasAimingMode=True IdleAimAnim="Idle" StandardDisplayFOV=60.000000 @@ -62,7 +562,7 @@ defaultproperties PlayerIronSightFOV=65.000000 ZoomedDisplayFOV=32.000000 FireModeClass(0)=class'NiceHFRPFire' - FireModeClass(1)=Class'KFMod.NoFire' + FireModeClass(1)=class'NiceHFRBurstFire' PutDownAnim="PutDown" AIRating=0.700000 CurrentRating=0.700000 diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmo.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmo.uc index 04466fc..2d11ca5 100644 --- a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmo.uc +++ b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmo.uc @@ -1,10 +1,10 @@ -class NiceHFRAmmo extends NiceAmmo; +class NiceHFRAmmo extends KFAmmunition; #EXEC OBJ LOAD FILE=KillingFloorHUD.utx defaultproperties { - AmmoPickupAmount=75 - MaxAmmo=300 - InitialAmount=75 + AmmoPickupAmount=15 + MaxAmmo=100 + InitialAmount=40 PickupClass=class'NiceHFRAmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmoPickup.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmoPickup.uc index 6eeaba4..40d9353 100644 --- a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmoPickup.uc +++ b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRAmmoPickup.uc @@ -1,7 +1,7 @@ -class NiceHFRAmmoPickup extends NiceAmmoPickup; +class NiceHFRAmmoPickup extends KFAmmoPickup; defaultproperties { - AmmoAmount=50 + AmmoAmount=15 InventoryType=class'NiceHFRAmmo' PickupMessage="Fire balloon" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo' diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRBullet.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRBullet.uc deleted file mode 100644 index 09fc990..0000000 --- a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRBullet.uc +++ /dev/null @@ -1,11 +0,0 @@ -class NiceHFRBullet extends NiceBullet; - -defaultproperties -{ - bDisableComplexMovement=False - trailXClass=None - StaticMeshRef="ZED_FX_SM.Energy.ZED_FX_Energy_Card" - DrawScale=0.500000 - ambientSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Projectile_Loop" - explosionImpact=(bImportanEffect=True,decalClass=Class'KFMod.FlameThrowerBurnMark_Medium',EmitterClass=Class'KFMod.ZEDMKIIPrimaryProjectileImpact',emitterShiftWall=20.000000,emitterShiftPawn=20.000000,noiseRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Projectile_Explode",noiseVolume=2.000000) -} diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPFire.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPFire.uc index 5d2d770..142fb8d 100644 --- a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPFire.uc +++ b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPFire.uc @@ -1,29 +1,25 @@ -class NiceHFRPFire extends NiceFire; - +class NiceHFRPFire extends KFFire; defaultproperties { - ProjectileSpeed=2000.000000 FireAimedAnim="Fire_Iron" - RecoilRate=0.070000 - maxVerticalRecoilAngle=70 - maxHorizontalRecoilAngle=35 + RecoilRate=0.120000 + maxVerticalRecoilAngle=500 bAccuracyBonusForSemiAuto=True bRandomPitchFireSound=False - FireSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Fire_M" - StereoFireSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Fire_S" - NoAmmoSoundRef="KF_ZEDGunSnd.KF_WEP_ZED_Dryfire" - DamageType=class'NiceDamTypeHFR' + FireSoundRef="KF_SP_LongmusketSnd.KFO_Sniper_Fire_M" + StereoFireSoundRef="KF_SP_LongmusketSnd.KFO_Sniper_Fire_S" + NoAmmoSoundRef="KF_AK47Snd.AK47_DryFire" + DamageType=class'NiceDamTypeHFRAssaultRifle' DamageMax=50 Momentum=8500.000000 - bWaitForRelease=False + bWaitForRelease=True TransientSoundVolume=1.200000 TransientSoundRadius=500.000000 FireLoopAnim="Fire" FireAnimRate=0.909000 TweenTime=0.025000 FireForce="AssaultRifleFire" - FireRate=0.096000 - bulletClass=class'NiceHFRBullet' + FireRate=0.600000 AmmoClass=class'NiceHFRAmmo' AmmoPerFire=1 ShakeRotMag=(X=50.000000,Y=50.000000,Z=350.000000) @@ -36,4 +32,5 @@ defaultproperties FlashEmitterClass=Class'ROEffects.MuzzleFlash1stSPSniper' aimerror=42.000000 Spread=0.015000 + SpreadStyle=SS_Random } diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPickup.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPickup.uc index 295e41d..8fc434a 100644 --- a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPickup.uc +++ b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRPickup.uc @@ -1,19 +1,18 @@ -class NiceHFRPickup extends NiceWeaponPickup; +class NiceHFRPickup extends KFWeaponPickup; defaultproperties { - Weight=5.000000 - AmmoCost=26 - BuyClipSize=50 + Weight=7.000000 + AmmoCost=30 + BuyClipSize=15 PowerValue=100 SpeedValue=100 RangeValue=40 - cost=750 Description="Advanced horzine flame rifle." ItemName="Horzine flame rifle" ItemShortName="HFR" AmmoItemName="Fire balloon" AmmoMesh=StaticMesh'KillingFloorStatics.FT_AmmoMesh' - CorrespondingPerkIndex=3 + CorrespondingPerkIndex=5 EquipmentCategoryID=3 InventoryType=class'NiceHFR' PickupMessage="You got the HFR." diff --git a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRTendril.uc b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRTendril.uc index 4d6c567..c175971 100644 --- a/sources/Weapons/Playable/Incendiary/HFR/NiceHFRTendril.uc +++ b/sources/Weapons/Playable/Incendiary/HFR/NiceHFRTendril.uc @@ -1,6 +1,6 @@ class NiceHFRTendril extends FlameTendril; defaultproperties { - Damage=16.000000 + Damage=36.000000 MyDamageType=class'NiceDamTypeHFR' } diff --git a/sources/Weapons/Playable/SMG/Kriss/NiceDamTypeKrissM.uc b/sources/Weapons/Playable/SMG/Kriss/NiceDamTypeKrissM.uc index 48b3dad..f728723 100644 --- a/sources/Weapons/Playable/SMG/Kriss/NiceDamTypeKrissM.uc +++ b/sources/Weapons/Playable/SMG/Kriss/NiceDamTypeKrissM.uc @@ -1,8 +1,6 @@ -class NiceDamTypeKrissM extends NiceDamageTypeVetDemolitions +class NiceDamTypeKrissM extends NiceDamageTypeVetCommando abstract; defaultproperties { - stoppingPower=0.25 - HeadShotDamageMult=1.500000 WeaponClass=class'NiceKrissMMedicGun' } diff --git a/sources/Weapons/Playable/SMG/Kriss/NiceKrissMFire.uc b/sources/Weapons/Playable/SMG/Kriss/NiceKrissMFire.uc index 60029e5..e47aedf 100644 --- a/sources/Weapons/Playable/SMG/Kriss/NiceKrissMFire.uc +++ b/sources/Weapons/Playable/SMG/Kriss/NiceKrissMFire.uc @@ -13,8 +13,8 @@ defaultproperties ShellEjectBoneName="Shell_eject" NoAmmoSoundRef="KF_MP7Snd.MP7_DryFire" DamageType=class'NiceDamTypeKrissM' - DamageMin=48 - DamageMax=48 + DamageMin=35 + DamageMax=35 Momentum=12500.000000 FireRate=0.040000 AmmoClass=class'NiceKrissMAmmo' @@ -27,8 +27,4 @@ defaultproperties FlashEmitterClass=Class'ROEffects.MuzzleFlash1stMP' Spread=500.0 SpreadStyle=SS_Random - minimalSpreadScale=0.0 - activeSpreadScale=0.0 - spreadGainedPerShot=0.125 - spreadLostPerSecond=0.5 } diff --git a/sources/Weapons/Playable/SMG/Kriss/NiceKrissMPickup.uc b/sources/Weapons/Playable/SMG/Kriss/NiceKrissMPickup.uc index 043b94d..d8ec776 100644 --- a/sources/Weapons/Playable/SMG/Kriss/NiceKrissMPickup.uc +++ b/sources/Weapons/Playable/SMG/Kriss/NiceKrissMPickup.uc @@ -17,7 +17,7 @@ defaultproperties AmmoItemName="45. ACP Ammo" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' EquipmentCategoryID=3 - CorrespondingPerkIndex=6 + CorrespondingPerkIndex=3 InventoryType=class'NiceKrissMMedicGun' PickupMessage="You got the KRISS Vector Medic Gun" PickupSound=Sound'KF_KrissSND.Handling.KF_WEP_KRISS_Handling_Pickup' diff --git a/sources/Weapons/Playable/SMG/M7A3/NiceDamTypeM7A3M.uc b/sources/Weapons/Playable/SMG/M7A3/NiceDamTypeM7A3M.uc index 9c584ce..e27b99e 100644 --- a/sources/Weapons/Playable/SMG/M7A3/NiceDamTypeM7A3M.uc +++ b/sources/Weapons/Playable/SMG/M7A3/NiceDamTypeM7A3M.uc @@ -1,8 +1,7 @@ -class NiceDamTypeM7A3M extends NiceDamageTypeVetDemolitions +class NiceDamTypeM7A3M extends NiceDamageTypeVetCommando abstract; defaultproperties { - stoppingPower=0.15 HeadShotDamageMult=2.000000 WeaponClass=class'NiceM7A3MMedicGun' } diff --git a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmo.uc b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmo.uc index e900e0c..0eda0d3 100644 --- a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmo.uc +++ b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmo.uc @@ -3,8 +3,8 @@ defaultproperties { WeaponPickupClass=class'NiceM7A3MPickup' AmmoPickupAmount=30 - MaxAmmo=160 - InitialAmount=40 + MaxAmmo=180 + InitialAmount=45 PickupClass=class'NiceM7A3MAmmoPickup' IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=336,Y1=82,X2=382,Y2=125) diff --git a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmoPickup.uc b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmoPickup.uc index 220b8fb..0f8acfc 100644 --- a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmoPickup.uc +++ b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MAmmoPickup.uc @@ -1,7 +1,7 @@ class NiceM7A3MAmmoPickup extends NiceAmmoPickup; defaultproperties { - AmmoAmount=30 + AmmoAmount=15 InventoryType=class'NiceM7A3MAmmo' PickupMessage="Rounds 7.6x40mm" StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo' diff --git a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MFire.uc b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MFire.uc index f8d867b..0376bf8 100644 --- a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MFire.uc +++ b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MFire.uc @@ -34,8 +34,4 @@ defaultproperties aimerror=42.000000 Spread=500.0 SpreadStyle=SS_Random - minimalSpreadScale=0.0 - activeSpreadScale=0.0 - spreadGainedPerShot=0.25 - spreadLostPerSecond=0.5 } diff --git a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MPickup.uc b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MPickup.uc index 826c735..3454139 100644 --- a/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MPickup.uc +++ b/sources/Weapons/Playable/SMG/M7A3/NiceM7A3MPickup.uc @@ -3,7 +3,7 @@ defaultproperties { Weight=5.000000 cost=1250 - AmmoCost=50 + AmmoCost=33 BuyClipSize=30 PowerValue=45 SpeedValue=60 @@ -14,7 +14,7 @@ defaultproperties AmmoItemName="7.6x40mm Ammo" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' EquipmentCategoryID=3 - CorrespondingPerkIndex=6 + CorrespondingPerkIndex=3 InventoryType=class'NiceM7A3MMedicGun' PickupMessage="You got the M7A3 Medic Gun" PickupSound=Sound'KF_M7A3Snd.M7A3_Pickup' diff --git a/sources/Weapons/Playable/SMG/MP5M/NiceDamTypeMP5M.uc b/sources/Weapons/Playable/SMG/MP5M/NiceDamTypeMP5M.uc index 89f2bcb..3af2db7 100644 --- a/sources/Weapons/Playable/SMG/MP5M/NiceDamTypeMP5M.uc +++ b/sources/Weapons/Playable/SMG/MP5M/NiceDamTypeMP5M.uc @@ -1,8 +1,7 @@ -class NiceDamTypeMP5M extends NiceDamageTypeVetDemolitions +class NiceDamTypeMP5M extends NiceDamageTypeVetCommando abstract; defaultproperties { - stoppingPower=0.15 HeadShotDamageMult=2.000000 WeaponClass=class'NiceMP5MMedicGun' } diff --git a/sources/Weapons/Playable/SMG/MP5M/NiceMP5MFire.uc b/sources/Weapons/Playable/SMG/MP5M/NiceMP5MFire.uc index d636895..ab4be61 100644 --- a/sources/Weapons/Playable/SMG/MP5M/NiceMP5MFire.uc +++ b/sources/Weapons/Playable/SMG/MP5M/NiceMP5MFire.uc @@ -5,9 +5,9 @@ defaultproperties FireEndStereoSoundRef="KF_MP5Snd.MP5_Fire_Loop_End_S" AmbientFireSoundRef="KF_MP5Snd.MP5_Fire_Loop" ProjectileSpeed=21250.000000 - RecoilRate=0.0100000 - maxVerticalRecoilAngle=40 - maxHorizontalRecoilAngle=20 + RecoilRate=0.0075000 + maxVerticalRecoilAngle=160 + maxHorizontalRecoilAngle=80 RecoilVelocityScale=0.000000 ShellEjectClass=Class'ROEffects.KFShellEjectMP5SMG' ShellEjectBoneName="Shell_eject" @@ -15,12 +15,8 @@ defaultproperties DamageType=class'NiceDamTypeMP5M' DamageMin=35 DamageMax=35 - Spread=750.0 + Spread=500.0 SpreadStyle=SS_Random - minimalSpreadScale=0.0 - activeSpreadScale=0.0 - spreadGainedPerShot=0.25 - spreadLostPerSecond=1.0 Momentum=5500.000000 FireRate=0.075000 AmmoClass=class'NiceMP5MAmmo' diff --git a/sources/Weapons/Playable/SMG/MP5M/NiceMP5MPickup.uc b/sources/Weapons/Playable/SMG/MP5M/NiceMP5MPickup.uc index dbd1e37..39f5464 100644 --- a/sources/Weapons/Playable/SMG/MP5M/NiceMP5MPickup.uc +++ b/sources/Weapons/Playable/SMG/MP5M/NiceMP5MPickup.uc @@ -14,7 +14,7 @@ defaultproperties AmmoItemName="9x19mm Ammo" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' EquipmentCategoryID=3 - CorrespondingPerkIndex=6 + CorrespondingPerkIndex=3 VariantClasses(0)=Class'KFMod.CamoMP5MPickup' InventoryType=class'NiceMP5MMedicGun' PickupMessage="You got the MP5M Medic Gun" diff --git a/sources/Weapons/Playable/SMG/MP7M/NiceDamTypeMP7M.uc b/sources/Weapons/Playable/SMG/MP7M/NiceDamTypeMP7M.uc index a6274cc..1076d20 100644 --- a/sources/Weapons/Playable/SMG/MP7M/NiceDamTypeMP7M.uc +++ b/sources/Weapons/Playable/SMG/MP7M/NiceDamTypeMP7M.uc @@ -1,10 +1,9 @@ -class NiceDamTypeMP7M extends NiceDamageTypeVetDemolitions +class NiceDamTypeMP7M extends NiceDamageTypeVetCommando abstract; defaultproperties { bPenetrationHSOnly=True MaxPenetrations=1 HeadShotDamageMult=2.250000 - stoppingPower=0.15 WeaponClass=class'NiceMP7MMedicGun' } diff --git a/sources/Weapons/Playable/SMG/MP7M/NiceMP7MFire.uc b/sources/Weapons/Playable/SMG/MP7M/NiceMP7MFire.uc index cc238c3..9806704 100644 --- a/sources/Weapons/Playable/SMG/MP7M/NiceMP7MFire.uc +++ b/sources/Weapons/Playable/SMG/MP7M/NiceMP7MFire.uc @@ -25,10 +25,6 @@ defaultproperties ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000) ShakeOffsetTime=1.250000 FlashEmitterClass=Class'ROEffects.MuzzleFlash1stMP' - Spread=750.0 + Spread=500.0 SpreadStyle=SS_Random - minimalSpreadScale=0.0 - activeSpreadScale=0.0 - spreadGainedPerShot=0.1 - spreadLostPerSecond=0.5 } diff --git a/sources/Weapons/Playable/SMG/MP7M/NiceMP7MPickup.uc b/sources/Weapons/Playable/SMG/MP7M/NiceMP7MPickup.uc index cf4f30b..95104e2 100644 --- a/sources/Weapons/Playable/SMG/MP7M/NiceMP7MPickup.uc +++ b/sources/Weapons/Playable/SMG/MP7M/NiceMP7MPickup.uc @@ -15,7 +15,7 @@ defaultproperties AmmoItemName="4.6x30mm Ammo" AmmoMesh=StaticMesh'KillingFloorStatics.L85Ammo' EquipmentCategoryID=3 - CorrespondingPerkIndex=6 + CorrespondingPerkIndex=3 InventoryType=class'NiceMP7MMedicGun' PickupMessage="You got the MP7M Medic Gun" PickupSound=Sound'KF_MP7Snd.MP7_Pickup' diff --git a/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickAltFire.uc b/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickAltFire.uc index 82bcb3c..4365656 100644 --- a/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickAltFire.uc +++ b/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickAltFire.uc @@ -1,13 +1,13 @@ class NiceBoomStickAltFire extends NiceBoomStickFire; // Overload to force last shot to have a different animation with reload // NICETODO: uncomment this -function name GetCorrectAnim(bool bLoop, bool bAimed) { +function name GetCorrectAnim(bool bLoop, bool bAimed){ if(currentContext.sourceWeapon != none && currentContext.sourceWeapon.MagAmmoRemainingClient > 0) - return super.GetCorrectAnim(bLoop, bAimed); + return super.GetCorrectAnim(bLoop, bAimed); if(bAimed) - return 'Fire_Last_Iron'; + return 'Fire_Last_Iron'; else - return 'Fire_Last'; + return 'Fire_Last'; return FireAnim; } defaultproperties diff --git a/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickFire.uc b/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickFire.uc index 837c195..ce35d5a 100644 --- a/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickFire.uc +++ b/sources/Weapons/Playable/Shotguns/Boomstick/NiceBoomStickFire.uc @@ -58,6 +58,5 @@ defaultproperties ShakeOffsetTime=3.500000 BotRefireRate=2.500000 aimerror=2.000000 - Spread=2000.000000 - FireAnimRate=1.25 + Spread=3000.000000 } diff --git a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGun.uc b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGun.uc index 6eaf758..b7d85ae 100644 --- a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGun.uc +++ b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGun.uc @@ -10,7 +10,7 @@ defaultproperties reloadMagStartFrame=0.278000 reloadChargeStartFrame=-1.000000 FirstPersonFlashlightOffset=(X=-20.000000,Y=-22.000000,Z=8.000000) - MagCapacity=42 + MagCapacity=28 ReloadRate=2.600000 ReloadAnim="Reload" ReloadAnimRate=1.000000 diff --git a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAltFire.uc b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAltFire.uc index 059a239..5650ed5 100644 --- a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAltFire.uc +++ b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAltFire.uc @@ -3,9 +3,6 @@ defaultproperties { bCanFireIncomplete=True ProjectileSpeed=3500.000000 - maxVerticalRecoilAngle=1250 - maxHorizontalRecoilAngle=750 - FireRate=0.600000 DamageType=class'NiceDamTypeNailGunWeak' AmmoPerFire=7 SpreadStyle=SS_Random diff --git a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAmmo.uc b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAmmo.uc index b0596d7..a005df5 100644 --- a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAmmo.uc +++ b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunAmmo.uc @@ -3,9 +3,9 @@ class NiceNailGunAmmo extends NiceAmmo; defaultproperties { WeaponPickupClass=class'NiceNailGunPickup' - AmmoPickupAmount=42 - MaxAmmo=210 - InitialAmount=52 + AmmoPickupAmount=28 + MaxAmmo=168 + InitialAmount=84 IconMaterial=Texture'KillingFloorHUD.Generic.HUD' IconCoords=(X1=451,Y1=445,X2=510,Y2=500) } diff --git a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunFire.uc b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunFire.uc index 969bcdf..f812f62 100644 --- a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunFire.uc +++ b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunFire.uc @@ -10,8 +10,8 @@ defaultproperties bShouldBounce=True bCausePain=True bulletClass=class'NiceNail' - maxVerticalRecoilAngle=0 - maxHorizontalRecoilAngle=0 + maxVerticalRecoilAngle=1250 + maxHorizontalRecoilAngle=750 bRandomPitchFireSound=True FireSoundRef="KF_NailShotgun.NailShotgun_Fire_Single_M" StereoFireSoundRef="KF_NailShotgun.NailShotgun_Fire_Single_S" @@ -19,7 +19,7 @@ defaultproperties DamageType=class'NiceDamTypeNailGun' DamageMax=66 FireAnimRate=1.250000 - FireRate=0.300000 + FireRate=0.400000 AmmoClass=class'NiceNailGunAmmo' ShakeRotTime=3.000000 ShakeOffsetTime=2.000000 diff --git a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunPickup.uc b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunPickup.uc index cfb7a50..fc10888 100644 --- a/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunPickup.uc +++ b/sources/Weapons/Playable/Shotguns/Nailgun/NiceNailGunPickup.uc @@ -3,8 +3,8 @@ defaultproperties { Weight=8.000000 cost=250 - AmmoCost=27 - BuyClipSize=42 + AmmoCost=17 + BuyClipSize=28 PowerValue=70 SpeedValue=55 RangeValue=25 diff --git a/sources/Weapons/Playable/Shotguns/Spas/NiceSpasAltFire.uc b/sources/Weapons/Playable/Shotguns/Spas/NiceSpasAltFire.uc index a5af9ef..8b97ecb 100644 --- a/sources/Weapons/Playable/Shotguns/Spas/NiceSpasAltFire.uc +++ b/sources/Weapons/Playable/Shotguns/Spas/NiceSpasAltFire.uc @@ -1,7 +1,6 @@ class NiceSpasAltFire extends NiceSpasFire; defaultproperties { - ProjPerFire=8 maxVerticalRecoilAngle=300 maxHorizontalRecoilAngle=180 FireAnimRate=0.650000 diff --git a/sources/Weapons/Playable/SniperWeapons/HuntingRifle/NiceHuntingRiflePickup.uc b/sources/Weapons/Playable/SniperWeapons/HuntingRifle/NiceHuntingRiflePickup.uc index 55477da..555932b 100644 --- a/sources/Weapons/Playable/SniperWeapons/HuntingRifle/NiceHuntingRiflePickup.uc +++ b/sources/Weapons/Playable/SniperWeapons/HuntingRifle/NiceHuntingRiflePickup.uc @@ -6,7 +6,7 @@ defaultproperties { Weight=6.000000 cost=750 - AmmoCost=22 + AmmoCost=34 BuyClipSize=5 PowerValue=55 SpeedValue=42 diff --git a/sources/Weapons/Playable/Tools/NiceSyringe.uc b/sources/Weapons/Playable/Tools/NiceSyringe.uc index 56ac0d6..48116c4 100644 --- a/sources/Weapons/Playable/Tools/NiceSyringe.uc +++ b/sources/Weapons/Playable/Tools/NiceSyringe.uc @@ -1,108 +1,8 @@ -class NiceSyringe extends NiceMeleeWeapon; +class NiceSyringe extends ScrnSyringe; -var () int HealBoostAmount; -var float RegenTimer; -var localized string SuccessfulHealMessage; - -replication -{ - reliable if( Role == ROLE_Authority ) - ClientSuccessfulHeal; - -} - -simulated function PostBeginPlay() -{ - // Weapon will handle FireMode instantiation - Super.PostBeginPlay(); - - if( Role == ROLE_Authority ) { - HealBoostAmount = default.HealBoostAmount; - } -} - -// The server lets the client know they successfully healed someone -simulated function ClientSuccessfulHeal(String HealedName) -{ - if( PlayerController(Instigator.Controller) != none ) - { - PlayerController(Instigator.controller).ClientMessage(SuccessfulHealMessage$HealedName, 'CriticalEvent'); - } -} - -simulated function Timer() -{ - Super.Timer(); - if( KFPawn(Instigator)!=None && KFPawn(Instigator).bIsQuickHealing>0 && ClientState==WS_ReadyToFire ) - { - if( KFPawn(Instigator).bIsQuickHealing==1 ) - { - if( !HackClientStartFire() ) - { - if( Instigator.Health>=Instigator.HealthMax || ChargeBar()<0.75 ) - KFPawn(Instigator).bIsQuickHealing = 2; // Was healed by someone else or some other error occurred. - SetTimer(0.2,False); - return; - } - KFPawn(Instigator).bIsQuickHealing = 2; - SetTimer(FireMode[1].FireRate+0.5,False); - } - else - { - Instigator.SwitchToLastWeapon(); - KFPawn(Instigator).bIsQuickHealing = 0; - } - } - else if( ClientState==WS_Hidden && KFPawn(Instigator)!=None ) - KFPawn(Instigator).bIsQuickHealing = 0; // Weapon was changed, ensure to reset this. -} - -simulated function bool HackClientStartFire() -{ - if( StartFire(1) ) - { - if( Role 1 && KFPlayerController(Instigator.Controller) != none && - KFSteamStatsAndAchievements(KFPlayerController(Instigator.Controller).SteamStatsAndAchievements) != none ) - { - KFSteamStatsAndAchievements(KFPlayerController(Instigator.Controller).SteamStatsAndAchievements).AddSelfHeal(); - } -} - -function Timer() -{ - local float HealSum, HealPotency; - local KFPlayerReplicationInfo KFPRI; - - KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo); - - HealSum = NiceSyringe(Weapon).HealBoostAmount; - - HealPotency = 1.0; - - if ( KFPRI != none && KFPRI.ClientVeteranSkill != none ) - HealPotency = KFPRI.ClientVeteranSkill.Static.GetHealPotency(KFPRI); - HealSum *= HealPotency; - - Load = 1; - ReduceAmmoClient(); - if ( NiceHumanPawn(Instigator) != none ) - NiceHumanPawn(Instigator).TakeHealing(NiceHumanPawn(Instigator), HealSum, HealPotency, KFWeapon(Instigator.Weapon)); - else - KFPawn(Instigator).GiveHealth(HealSum, Instigator.HealthMax); -} - -function bool AllowFire() -{ - if (Instigator.Health >= Instigator.HealthMax) - return false; - - return Weapon.AmmoAmount(ThisModeNum) >= AmmoPerFire; -} - -event ModeDoFire() -{ - Load = 1; - Super.ModeDoFire(); -} - -function PlayFiring() -{ - if ( Weapon.Mesh != None ) - { - if ( FireCount > 0 ) - { - if ( Weapon.HasAnim(FireLoopAnim) ) - { - Weapon.PlayAnim(FireLoopAnim, FireLoopAnimRate, 0.0); - } - else - { - Weapon.PlayAnim(FireAnim, FireAnimRate, 0.0); - } - } - else - { - Weapon.PlayAnim(FireAnim, FireAnimRate, 0.0); - } - } - Weapon.PlayOwnedSound(FireSound,SLOT_Interact,TransientSoundVolume,,TransientSoundRadius,Default.FireAnimRate/FireAnimRate,false); - ClientPlayForceFeedback(FireForce); // jdf - - FireCount++; -} - -defaultproperties { - AmmoClass=class'NiceSyringeAmmo' - AmmoPerFire=1 - TweenTime=0.1 - TransientSoundVolume=1.8 - FireAnim="AltFire" - FireRate=3.60000 - bModeExclusive=true - InjectDelay=0.1 - HealeeRange=70.000000 -} +class NiceSyringeAltFire extends ScrnSyringeAltFire; \ No newline at end of file diff --git a/sources/Weapons/Playable/Tools/NiceSyringeAmmo.uc b/sources/Weapons/Playable/Tools/NiceSyringeAmmo.uc deleted file mode 100644 index dc7731f..0000000 --- a/sources/Weapons/Playable/Tools/NiceSyringeAmmo.uc +++ /dev/null @@ -1,12 +0,0 @@ -class NiceSyringeAmmo extends NiceAmmo; - -defaultproperties { - WeaponPickupClass=class'NiceSyringePickup' - AmmoPickupAmount=0 - MaxAmmo=4 - InitialAmount=1 - PickupClass=class'NiceSyringeAmmoPickup' - IconMaterial=Texture'KillingFloorHUD.Generic.HUD' - IconCoords=(X1=336,Y1=82,X2=382,Y2=125) - ItemName="Healing juice" -} diff --git a/sources/Weapons/Playable/Tools/NiceSyringeAmmoPickup.uc b/sources/Weapons/Playable/Tools/NiceSyringeAmmoPickup.uc deleted file mode 100644 index 600369e..0000000 --- a/sources/Weapons/Playable/Tools/NiceSyringeAmmoPickup.uc +++ /dev/null @@ -1,8 +0,0 @@ -class NiceSyringeAmmoPickup extends NiceAmmoPickup; - -defaultproperties { - AmmoAmount=1 - InventoryType=class'NiceSyringe' - PickupMessage="Healing juice" - StaticMesh=StaticMesh'KillingFloorStatics.L85Ammo' -} diff --git a/sources/Weapons/Playable/Tools/NiceSyringeFire.uc b/sources/Weapons/Playable/Tools/NiceSyringeFire.uc index 287a10a..a632d12 100644 --- a/sources/Weapons/Playable/Tools/NiceSyringeFire.uc +++ b/sources/Weapons/Playable/Tools/NiceSyringeFire.uc @@ -1,208 +1,23 @@ -class NiceSyringeFire extends NiceMeleeFire; +class NiceSyringeFire extends ScrnSyringeFire; -var float LastHealAttempt; -var float HealAttemptDelay; -var float LastHealMessageTime; -var float HealMessageDelay; -var localized string NoHealTargetMessage; -var KFHumanPawn CachedHealee; -var transient float PendingHealTime; +// default == 80 +const SEARCH_RADIUS=120.0; -simulated function DestroyEffects() -{ - super.DestroyEffects(); - - if (CachedHealee != None) - CachedHealee = none; -} - -simulated function bool AllowFire() { - local KFHumanPawn Healtarget; - local string healeeName; - if (!super.AllowFire()) { - return false; - } - if (CanFindHealee()) { - if( CachedHealee.PlayerReplicationInfo != none && - CachedHealee.PlayerReplicationInfo.PlayerName != "") - { - HealeeName = CachedHealee.PlayerReplicationInfo.PlayerName; - } - else { - HealeeName = CachedHealee.MenuName; - } - NiceSyringe(Weapon).ClientSuccessfulHeal(HealeeName); - // Give the messages if we missed our heal, can't find a target, etc - if ( KFPlayerController(Instigator.Controller) != none ) - { - if ( LastHealAttempt + HealAttemptDelay < Level.TimeSeconds) - { - PlayerController(Instigator.controller).ClientMessage(NoHealTargetMessage, 'CriticalEvent'); - LastHealAttempt = Level.TimeSeconds; - } - - if ( Level.TimeSeconds - LastHealMessageTime > HealMessageDelay ) - { - // if there's a Player within 2 meters who needs healing, say that we're trying to heal them - foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', Healtarget, 100) - { - if ( Healtarget != Instigator && Healtarget.Health < Healtarget.HealthMax ) - { - PlayerController(Instigator.Controller).Speech('AUTO', 5, ""); - LastHealMessageTime = Level.TimeSeconds; - - break; - } - } - } - } - return true; - } - return false; -} - -function Timer() -{ - local KFPlayerReplicationInfo PRI; - local int MedicReward; - local KFHumanPawn Healed; - local float HealSum, HealPotency; // for modifying based on perks - - PRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo); - Healed = CachedHealee; - HealPotency = 1.0; - CachedHealee = none; - if ( Healed != none && Healed.Health > 0 && Healed != Instigator ) - { - Load = 1; - ReduceAmmoClient(); - - if ( PRI != none && PRI.ClientVeteranSkill != none ) - HealPotency = PRI.ClientVeteranSkill.Static.GetHealPotency(PRI); - - HealSum = NiceSyringe(Weapon).HealBoostAmount; - - HealSum *= HealPotency; - MedicReward = HealSum; - - if ( (Healed.Health + Healed.healthToGive + MedicReward) > Healed.HealthMax ) - { - MedicReward = Healed.HealthMax - (Healed.Health + Healed.healthToGive); - if ( MedicReward < 0 ) - { - MedicReward = 0; - } - } - - if ( NiceHumanPawn(Healed) != none ) - NiceHumanPawn(Healed).TakeHealing(NiceHumanPawn(Instigator), HealSum, HealPotency, KFWeapon(Instigator.Weapon)); - else - Healed.GiveHealth(HealSum, Healed.HealthMax); - - // Tell them we're healing them - PlayerController(Instigator.Controller).Speech('AUTO', 5, ""); - LastHealMessageTime = Level.TimeSeconds; - - if ( PRI != None ) - { - if ( MedicReward > 0 && KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements) != none ) - { - KFSteamStatsAndAchievements(PRI.SteamStatsAndAchievements).AddDamageHealed(MedicReward); - } - - // Give the medic reward money as a percentage of how much of the person's health they healed - MedicReward = int((FMin(float(MedicReward),Healed.HealthMax)/Healed.HealthMax) * 60); // Increased to 80 in Balance Round 6, reduced to 60 in Round 7 - - if ( class'ScrnBalance'.default.Mut.bMedicRewardFromTeam && Healed.PlayerReplicationInfo != none && Healed.PlayerReplicationInfo.Team != none ) { - // give money from team wallet - if ( Healed.PlayerReplicationInfo.Team.Score >= MedicReward ) { - Healed.PlayerReplicationInfo.Team.Score -= MedicReward; - PRI.Score += MedicReward; - } - } - else - PRI.Score += MedicReward; - - if ( KFHumanPawn(Instigator) != none ) - { - KFHumanPawn(Instigator).AlphaAmount = 255; - } - } - } -} - -function KFHumanPawn GetHealee() -{ +function KFHumanPawn GetHealee() { local KFHumanPawn KFHP, BestKFHP; local vector Dir; local float TempDot, BestDot; Dir = vector(Instigator.GetViewRotation()); - foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', KFHP, 80.0) - { - if ( KFHP.Health < KFHP.HealthMax && KFHP.Health > 0 ) - { + foreach Instigator.VisibleCollidingActors(class'KFHumanPawn', KFHP, SEARCH_RADIUS) { + if (KFHP.Health < KFHP.HealthMax && KFHP.Health > 0) { TempDot = Dir dot (KFHP.Location - Instigator.Location); - if ( TempDot > 0.7 && TempDot > BestDot ) - { + if (TempDot > 0.7 && TempDot > BestDot) { BestKFHP = KFHP; BestDot = TempDot; } } } - return BestKFHP; -} - -// Can we find someone to heal -function bool CanFindHealee() -{ - local KFHumanPawn Healtarget; - - Healtarget = GetHealee(); - CachedHealee = Healtarget; - - // Can't use syringe if we can't find a target - if ( Healtarget == none ) - { - if ( KFPlayerController(Instigator.Controller) != none ) - { - KFPlayerController(Instigator.Controller).CheckForHint(53); - } - - return false; - } - - // Can't use syringe if our target is already being healed to full health. - if ( (Healtarget.Health == Healtarget.Healthmax) || ((Healtarget.healthToGive + Healtarget.Health) >= Healtarget.Healthmax) ) - { - return false; - } - - return true; -} - -function float GetFireSpeed() -{ - if ( KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo) != none && KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill != none ) - { - return KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo).ClientVeteranSkill.Static.GetFireSpeedMod(KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo), Weapon); - } - - return 1; -} - -defaultproperties { - AmmoClass=class'NiceSyringeAmmo' - ammoPerFire=1 - - FireAnims(0)="Fire" - FireRate=2.800000 - damageDelay=0.36 - - HealAttemptDelay=0.5 - HealMessageDelay=10.0 - NoHealTargetMessage="You must be near another player to heal them!" - bWaitForRelease=true -} +} \ No newline at end of file diff --git a/sources/Weapons/Playable/Tools/NiceSyringePickup.uc b/sources/Weapons/Playable/Tools/NiceSyringePickup.uc index 424c4e4..a9673b6 100644 --- a/sources/Weapons/Playable/Tools/NiceSyringePickup.uc +++ b/sources/Weapons/Playable/Tools/NiceSyringePickup.uc @@ -1,19 +1,6 @@ -class NiceSyringePickup extends NiceWeaponPickup; +class NiceSyringePickup extends ScrnSyringePickup; defaultproperties { - ItemName="Med-Syringe" - InventoryType=Class'NicePack.NiceSyringe' - Weight=0.000000 - cost=100 - AmmoCost=40 - BuyClipSize=1 - PickupMessage="You got the Med-Syringe." - PickupSound=Sound'Inf_Weapons_Foley.AmmoPickup' - PickupForce="AssaultRiflePickup" - StaticMesh=StaticMesh'KF_pickups_Trip.Syringe_pickup' - CollisionHeight=5.000000 - EquipmentCategoryID=0 - ItemShortName="Syringe" - AmmoItemName="Healing juice" - Description="Basic equipment, necessary for survival." -} + ItemName="Nice Med-Syringe" + InventoryType=class'NiceSyringe' +} \ No newline at end of file diff --git a/sources/Zeds/Mean/MeanZombieFleshPound.uc b/sources/Zeds/Mean/MeanZombieFleshPound.uc index b7ac20b..3bb82a0 100644 --- a/sources/Zeds/Mean/MeanZombieFleshPound.uc +++ b/sources/Zeds/Mean/MeanZombieFleshPound.uc @@ -27,20 +27,23 @@ Ignores StartChargingFP; bFrustrated = false; if(Controller != none) NiceZombieFleshPoundController(Controller).RageFrustrationTimer = 0; + if( Health>0 && !bZapped ) + { + SetGroundSpeed(GetOriginalGroundSpeed()); + } if( Level.NetMode!=NM_DedicatedServer ) ClientChargingAnims(); NetUpdateTime = Level.TimeSeconds - 1; } - simulated function UpdateGroundSpeed() { - super(NiceMonster).UpdateGroundSpeed(); - if (!bShotAnim) { - groundSpeed *= 2.3; - } - } function Tick( float Delta ) { + if( !bShotAnim ) + { + SetGroundSpeed(OriginalGroundSpeed * 2.3);//2.0; + } + // Keep the flesh pound moving toward its target when attacking if( Role == ROLE_Authority && bShotAnim) { diff --git a/sources/Zeds/Mean/MeanZombieHusk.uc b/sources/Zeds/Mean/MeanZombieHusk.uc index efbb5fb..b0ada50 100644 --- a/sources/Zeds/Mean/MeanZombieHusk.uc +++ b/sources/Zeds/Mean/MeanZombieHusk.uc @@ -37,7 +37,7 @@ function RangedAttack(Actor A) { //Increment the number of consecutive shtos taken and apply the cool down if needed totalShots ++; consecutiveShots ++; - if(consecutiveShots < 3 && totalShots > maxNormalShots && VSize(a.location - location) <= 900) + if(consecutiveShots < 3 && totalShots > maxNormalShots) NextFireProjectileTime = Level.TimeSeconds; else{ NextFireProjectileTime = Level.TimeSeconds + ProjectileFireInterval + (FRand() * 2.0); diff --git a/sources/Zeds/Nice/NiceBloatVomit.uc b/sources/Zeds/Nice/NiceBloatVomit.uc new file mode 100644 index 0000000..7f3d37c --- /dev/null +++ b/sources/Zeds/Nice/NiceBloatVomit.uc @@ -0,0 +1,30 @@ +class NiceBloatVomit extends KFBloatVomit; + +// limit how much you can damage zeds +const DAMAGECOUNT=10; +var private transient int DamageTicked; + +auto state Flying { + simulated function ProcessTouch(Actor Other, Vector HitLocation) { + // add damage limit + if (DamageTicked >= DAMAGECOUNT) { + BlowUp(HitLocation); + return; + } + if (ExtendedZCollision(Other) != none) { + return; + } + if ( + Other != Instigator && + (Other.IsA('Pawn') || Other.IsA('DestroyableObjective') || Other.bProjTarget) + ) { + DamageTicked += 1; + // warn("DamageTicked: " $ DamageTicked); + // use server DelayedHurtRadius() instead? + HurtRadius(Damage, DamageRadius, MyDamageType, MomentumTransfer, HitLocation); + } + else if (Other != Instigator && Other.bBlockActors) { + HitWall(Normal(HitLocation - Location), Other); + } + } +} \ No newline at end of file diff --git a/sources/Zeds/Nice/NiceZombieBloat.uc b/sources/Zeds/Nice/NiceZombieBloat.uc index c3ab99b..459e04e 100644 --- a/sources/Zeds/Nice/NiceZombieBloat.uc +++ b/sources/Zeds/Nice/NiceZombieBloat.uc @@ -173,7 +173,8 @@ function SpawnTwoShots() if ( !SavedFireProperties.bInitialized ) { SavedFireProperties.AmmoClass = Class'SkaarjAmmo'; - SavedFireProperties.ProjectileClass = Class'KFBloatVomit'; + // use fixed bile class, to prevent super high damage to zeds + SavedFireProperties.ProjectileClass = Class'NiceBloatVomit'; SavedFireProperties.WarnTargetPct = 1; SavedFireProperties.MaxRange = 500; SavedFireProperties.bTossed = False; @@ -185,13 +186,13 @@ function SpawnTwoShots() // Turn off extra collision before spawning vomit, otherwise spawn fails ToggleAuxCollision(false); FireRotation = Controller.AdjustAim(SavedFireProperties,FireStart,600); - Spawn(Class'KFBloatVomit',,,FireStart,FireRotation); + Spawn(SavedFireProperties.ProjectileClass,,,FireStart,FireRotation); FireStart-=(0.5*CollisionRadius*Y); FireRotation.Yaw -= 1200; - spawn(Class'KFBloatVomit',,,FireStart, FireRotation); + spawn(SavedFireProperties.ProjectileClass,,,FireStart, FireRotation); FireStart+=(CollisionRadius*Y); FireRotation.Yaw += 2400; - spawn(Class'KFBloatVomit',,,FireStart, FireRotation); + spawn(SavedFireProperties.ProjectileClass,,,FireStart, FireRotation); // Turn extra collision back on ToggleAuxCollision(true); } diff --git a/sources/Zeds/Nice/NiceZombieBoss.uc b/sources/Zeds/Nice/NiceZombieBoss.uc index 2c53c56..8384766 100644 --- a/sources/Zeds/Nice/NiceZombieBoss.uc +++ b/sources/Zeds/Nice/NiceZombieBoss.uc @@ -915,16 +915,9 @@ state Charging // How many charge attacks we can do randomly 1-3 NumChargeAttacks = Rand(2) + 1; } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - if (bShotAnim) { - groundSpeed *= 1.25; - } else { - groundSpeed *= 2.5; - } - } function EndState() { + SetGroundSpeed(GetOriginalGroundSpeed()); bChargingPlayer = False; ChargeDamage = 0; if( Level.NetMode!=NM_DedicatedServer ) @@ -949,6 +942,7 @@ state Charging if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); } + SetGroundSpeed(OriginalGroundSpeed * 1.25); if( LookTarget!=none ) { Acceleration = AccelRate * Normal(LookTarget.Location - Location); @@ -962,6 +956,16 @@ state Charging if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); } + + // Zapping slows him down, but doesn't stop him + if( bZapped ) + { + SetGroundSpeed(OriginalGroundSpeed * 1.5); + } + else + { + SetGroundSpeed(OriginalGroundSpeed * 2.5); + } } Global.Tick(Delta); @@ -1067,6 +1071,7 @@ State Escaping extends Charging // Got hurt and running away... if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); } + SetGroundSpeed(GetOriginalGroundSpeed()); } else { @@ -1076,20 +1081,23 @@ State Escaping extends Charging // Got hurt and running away... if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); } + + // Zapping slows him down, but doesn't stop him + if( bZapped ) + { + SetGroundSpeed(OriginalGroundSpeed * 1.5); + } + else + { + SetGroundSpeed(OriginalGroundSpeed * 2.5); + } } Global.Tick(Delta); } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - if (bShotAnim) { - groundSpeed *= 1.25; - } else { - groundSpeed *= 2.5; - } - } function EndState() { + SetGroundSpeed(GetOriginalGroundSpeed()); bChargingPlayer = False; if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); diff --git a/sources/Zeds/Nice/NiceZombieBossBase.uc b/sources/Zeds/Nice/NiceZombieBossBase.uc index 3e5eea6..aa6cade 100644 --- a/sources/Zeds/Nice/NiceZombieBossBase.uc +++ b/sources/Zeds/Nice/NiceZombieBossBase.uc @@ -52,6 +52,7 @@ defaultproperties ClawMeleeDamageRange=85.000000 ImpaleMeleeDamageRange=45.000000 fuelRatio=0.400000 + bFrugalFuelUsage=False clientHeadshotScale=1.200000 ZapThreshold=5.000000 ZappedDamageMod=1.250000 @@ -97,9 +98,6 @@ defaultproperties HealthMax=8000.000000 Health=8000 HeadScale=1.300000 - stoppingRecoveryRate=0.1 - maxStoppingEffect=0.2 - minStoppingThreshold=0.6 MenuName="Nice Patriarch" MovementAnims(0)="WalkF" MovementAnims(1)="WalkF" diff --git a/sources/Zeds/Nice/NiceZombieBrute.uc b/sources/Zeds/Nice/NiceZombieBrute.uc index 26860fc..8e6c7f1 100644 --- a/sources/Zeds/Nice/NiceZombieBrute.uc +++ b/sources/Zeds/Nice/NiceZombieBrute.uc @@ -182,6 +182,18 @@ function TakeDamageClient(int Damage, Pawn InstigatedBy, Vector HitLocation, Vec if (bDecapitated) Died(InstigatedBy.Controller, damageType, HitLocation); } +function TakeFireDamage(int Damage, Pawn Instigator) +{ + Super.TakeFireDamage(Damage, Instigator); + // Adjust movement speed if not charging + if (!bChargingPlayer) + { + if (bBurnified) + GroundSpeed = GetOriginalGroundSpeed() * BurnGroundSpeedMul; + else + GroundSpeed = GetOriginalGroundSpeed(); + } +} function ClawDamageTarget() { local KFHumanPawn HumanTarget; @@ -299,16 +311,19 @@ Ignores StartCharging; NetUpdateTime = Level.TimeSeconds - 1; } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - groundSpeed = groundSpeed + ((groundSpeed * 0.75 / maxRageCounter * (rageCounter + 1) * rageSpeedTween)); - } function EndState() { bChargingPlayer = false; NiceZombieBruteController(Controller).RageFrustrationTimer = 0; + if (Health > 0) + { + GroundSpeed = GetOriginalGroundSpeed(); + if (bBurnified) + GroundSpeed *= BurnGroundSpeedMul; + } + if( Level.NetMode!=NM_DedicatedServer ) ClientChargingAnims(); @@ -316,8 +331,12 @@ Ignores StartCharging; } function Tick(float Delta) { - if (!bShotAnim) { + if (!bShotAnim) + { RageSpeedTween = FClamp(RageSpeedTween + (Delta * 0.75), 0, 1.0); + GroundSpeed = OriginalGroundSpeed + ((OriginalGroundSpeed * 0.75 / MaxRageCounter * (RageCounter + 1) * RageSpeedTween)); + if (bBurnified) + GroundSpeed *= BurnGroundSpeedMul; } Global.Tick(Delta); diff --git a/sources/Zeds/Nice/NiceZombieBruteBase.uc b/sources/Zeds/Nice/NiceZombieBruteBase.uc index 5780f19..58af2a0 100644 --- a/sources/Zeds/Nice/NiceZombieBruteBase.uc +++ b/sources/Zeds/Nice/NiceZombieBruteBase.uc @@ -33,6 +33,7 @@ var bool bServerBlock; var bool bClientBlock; var float BlockDmgMul; // Multiplier for damage taken from blocked shots var float BlockFireDmgMul; +var float BurnGroundSpeedMul; // Multiplier for ground speed when burning replication { reliable if(Role == ROLE_Authority) @@ -60,6 +61,7 @@ defaultproperties BlockAddScale=2.500000 BlockDmgMul=0.100000 BlockFireDmgMul=1.000000 + BurnGroundSpeedMul=0.700000 StunThreshold=4.000000 flameFuel=0.500000 clientHeadshotScale=1.300000 @@ -108,7 +110,6 @@ defaultproperties Health=1000 HeadHeight=2.500000 HeadScale=1.300000 - minStoppingThreshold=0.1 MenuName="Brute" MovementAnims(0)="BruteWalkC" MovementAnims(1)="BruteWalkC" @@ -122,7 +123,7 @@ defaultproperties AmbientSound=SoundGroup'ScrnZedPack_S.Brute.BruteIdle1Shot' Mesh=SkeletalMesh'ScrnZedPack_A.BruteMesh' PrePivot=(Z=0.000000) - Skins(0)=Texture'NicePackT.MonsterBrute.WPCBruteT' + Skins(0)=Combiner'ScrnZedPack_T.Brute.Brute_Final' Mass=600.000000 RotationRate=(Yaw=45000,Roll=0) } diff --git a/sources/Zeds/Nice/NiceZombieClot.uc b/sources/Zeds/Nice/NiceZombieClot.uc index 71f8939..57875e8 100644 --- a/sources/Zeds/Nice/NiceZombieClot.uc +++ b/sources/Zeds/Nice/NiceZombieClot.uc @@ -5,8 +5,6 @@ class NiceZombieClot extends NiceZombieClotBase; #exec OBJ LOAD FILE=KF_Specimens_Trip_T.utx #exec OBJ LOAD FILE=MeanZedSkins.utx -var float sirenBoostTimeout; - function ClawDamageTarget() { local vector PushDir; @@ -111,33 +109,9 @@ simulated function int DoAnimAction( name AnimName ) } return super.DoAnimAction( AnimName ); } -function DealDecapDamage( int damage, - Pawn instigatedBy, - Vector hitLocation, - Vector momentum, - class damageType, - float headshotLevel, - KFPlayerReplicationInfo KFPRI, - optional float lockonTime) { - if (sirenBoostTimeout > 0) { - RemoveHead(); - } else { - super.DealDecapDamage(damage, instigatedBy, hitLocation, momentum, - damageType, headshotLevel, KFPRI, lockonTime); - } -} -simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - if (sirenBoostTimeout > 0) { - groundSpeed *= 1.5; - } -} simulated function Tick(float DeltaTime) { super.Tick(DeltaTime); - if (sirenBoostTimeout >= 0) { - sirenBoostTimeout -= deltaTime; - } if( bShotAnim && Role == ROLE_Authority ) { if( LookTarget!=none ) diff --git a/sources/Zeds/Nice/NiceZombieCrawler.uc b/sources/Zeds/Nice/NiceZombieCrawler.uc index 43c0ad1..a4ce6cf 100644 --- a/sources/Zeds/Nice/NiceZombieCrawler.uc +++ b/sources/Zeds/Nice/NiceZombieCrawler.uc @@ -34,20 +34,17 @@ event Landed(vector HitNormal) } event Bump(actor Other) { - local int actualDamage; // TODO: is there a better way if(bPouncing && KFHumanPawn(Other)!=none ) { - actualDamage = MeleeDamage; - ModDamageFromZed(actualDamage, class'NiceZedMeleeDamageType'); - KFHumanPawn(Other).TakeDamage(((actualDamage * 0.95) + (actualDamage * (FRand() * 0.1))), self ,self.Location,self.velocity, class'NiceZedMeleeDamageType'); - if (KFHumanPawn(Other).Health <=0) - { - //TODO - move this to humanpawn.takedamage? Also see KFMonster.MeleeDamageTarget - KFHumanPawn(Other).SpawnGibs(self.rotation, 1); - } - //After impact, there'll be no momentum for further bumps - bPouncing=false; + KFHumanPawn(Other).TakeDamage(((MeleeDamage - (MeleeDamage * 0.05)) + (MeleeDamage * (FRand() * 0.1))), self ,self.Location,self.velocity, class'NiceZedMeleeDamageType'); + if (KFHumanPawn(Other).Health <=0) + { + //TODO - move this to humanpawn.takedamage? Also see KFMonster.MeleeDamageTarget + KFHumanPawn(Other).SpawnGibs(self.rotation, 1); + } + //After impact, there'll be no momentum for further bumps + bPouncing=false; } } // Blend his attacks so he can hit you in mid air. diff --git a/sources/Zeds/Nice/NiceZombieFleshPound.uc b/sources/Zeds/Nice/NiceZombieFleshPound.uc index 17c0fa5..1a7ea05 100644 --- a/sources/Zeds/Nice/NiceZombieFleshPound.uc +++ b/sources/Zeds/Nice/NiceZombieFleshPound.uc @@ -49,6 +49,7 @@ function SetMindControlled(bool bNewMindControlled) if( bNewMindControlled != bZedUnderControl ) { + SetGroundSpeed(OriginalGroundSpeed * 1.25); Health *= 1.25; HealthMax *= 1.25; } @@ -251,21 +252,21 @@ Ignores StartChargingFP; if(fpController == none) fpController.RageFrustrationTimer = 0; + if( Health>0 && !bZapped ) + { + SetGroundSpeed(GetOriginalGroundSpeed()); + } + if( Level.NetMode!=NM_DedicatedServer ) ClientChargingAnims(); NetUpdateTime = Level.TimeSeconds - 1; } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - if (!bShotAnim) { - groundSpeed *= 2.3; - } - } function Tick( float Delta ) { if( !bShotAnim ) { + SetGroundSpeed(OriginalGroundSpeed * 2.3);//2.0; if( !bFrustrated && !bZedUnderControl && Level.TimeSeconds>RageEndTime ) { GoToState(''); @@ -329,16 +330,11 @@ Ignores StartChargingFP; state ChargeToMarker extends RageCharging { Ignores StartChargingFP; - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - if (!bShotAnim) { - groundSpeed *= 2.3; - } - } function Tick( float Delta ) { if( !bShotAnim ) { + SetGroundSpeed(OriginalGroundSpeed * 2.3); if( !bFrustrated && !bZedUnderControl && Level.TimeSeconds>RageEndTime ) { GoToState(''); @@ -441,7 +437,7 @@ function SpinDamage(actor Target) local vector HitLocation; local Name TearBone; local Float dummy; - local int damageAmount; + local float DamageAmount; local vector PushDir; local KFHumanPawn HumanTarget; if(target==none) @@ -456,9 +452,8 @@ function SpinDamage(actor Target) } if (Target !=none && Target.IsA('KFDoorMover')) { - ModDamageFromZed(DamageAmount, class'NiceZedMeleeDamageType'); - Target.TakeDamage(DamageAmount , self ,HitLocation,pushdir, class'NiceZedMeleeDamageType'); - PlaySound(MeleeAttackHitSound, SLOT_Interact, 1.25); + Target.TakeDamage(DamageAmount , self ,HitLocation,pushdir, class'NiceZedMeleeDamageType'); + PlaySound(MeleeAttackHitSound, SLOT_Interact, 1.25); } if (KFHumanPawn(Target)!=none) { @@ -466,9 +461,8 @@ function SpinDamage(actor Target) if (HumanTarget.Controller != none) HumanTarget.Controller.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime); - ModDamageFromZed(DamageAmount, class'NiceZedMeleeDamageType'); - //TODO - line below was KFPawn. Does this whole block need to be KFPawn, or is it OK as KFHumanPawn? - KFHumanPawn(Target).TakeDamage(DamageAmount, self ,HitLocation,pushdir, class'NiceZedMeleeDamageType'); + //TODO - line below was KFPawn. Does this whole block need to be KFPawn, or is it OK as KFHumanPawn? + KFHumanPawn(Target).TakeDamage(DamageAmount, self ,HitLocation,pushdir, class'NiceZedMeleeDamageType'); if (KFHumanPawn(Target).Health <=0) { diff --git a/sources/Zeds/Nice/NiceZombieFleshpoundBase.uc b/sources/Zeds/Nice/NiceZombieFleshpoundBase.uc index 54fc8c3..6380eb1 100644 --- a/sources/Zeds/Nice/NiceZombieFleshpoundBase.uc +++ b/sources/Zeds/Nice/NiceZombieFleshpoundBase.uc @@ -80,8 +80,6 @@ defaultproperties Health=1650 HeadHeight=2.500000 HeadScale=1.300000 - maxStoppingEffect=0.05 - minStoppingThreshold=0.68 MenuName="Nice Flesh Pound" MovementAnims(0)="PoundWalk" MovementAnims(1)="WalkB" diff --git a/sources/Zeds/Nice/NiceZombieGorefast.uc b/sources/Zeds/Nice/NiceZombieGorefast.uc index a696b0e..6b75e97 100644 --- a/sources/Zeds/Nice/NiceZombieGorefast.uc +++ b/sources/Zeds/Nice/NiceZombieGorefast.uc @@ -45,6 +45,7 @@ function SetMindControlled(bool bNewMindControlled) if( bNewMindControlled != bZedUnderControl ) { + SetGroundSpeed(OriginalGroundSpeed * 1.25); Health *= 1.25; HealthMax *= 1.25; } @@ -72,6 +73,13 @@ function RangedAttack(Actor A){ if(!bShotAnim && !bDecapitated && VSize(A.Location - Location) <= 700) GoToState('RunningState'); } +simulated function Tick(float DeltaTime){ + super.Tick(DeltaTime); + if(IsInState('RunningState')) + SetGroundSpeed(GetOriginalGroundSpeed() * 1.875); + else + SetGroundSpeed(GetOriginalGroundSpeed()); +} state RunningState{ // Set the zed to the zapped behavior simulated function SetZappedBehavior(){ @@ -86,6 +94,7 @@ state RunningState{ if(bZapped) GoToState(''); else{ + SetGroundSpeed(OriginalGroundSpeed * 1.875); bRunning = true; if(Level.NetMode != NM_DedicatedServer) PostNetReceive(); @@ -94,6 +103,7 @@ state RunningState{ } } function EndState(){ + SetGroundSpeed(GetOriginalGroundSpeed()); bRunning = false; if(Level.NetMode != NM_DedicatedServer) PostNetReceive(); @@ -102,10 +112,6 @@ state RunningState{ NetUpdateTime = Level.TimeSeconds - 1; } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - groundSpeed *= 1.875; - } function RemoveHead(){ GoToState(''); Global.RemoveHead(); diff --git a/sources/Zeds/Nice/NiceZombieHuskBase.uc b/sources/Zeds/Nice/NiceZombieHuskBase.uc index 89b8a58..7c93117 100644 --- a/sources/Zeds/Nice/NiceZombieHuskBase.uc +++ b/sources/Zeds/Nice/NiceZombieHuskBase.uc @@ -60,7 +60,6 @@ defaultproperties HeadHeight=1.000000 HeadScale=1.350000 AmbientSoundScaling=8.000000 - stoppingRecoveryRate=0.05 MenuName="Nice Husk" MovementAnims(0)="WalkF" MovementAnims(1)="WalkB" diff --git a/sources/Zeds/Nice/NiceZombieJason.uc b/sources/Zeds/Nice/NiceZombieJason.uc index c32c255..ab0a1f6 100644 --- a/sources/Zeds/Nice/NiceZombieJason.uc +++ b/sources/Zeds/Nice/NiceZombieJason.uc @@ -105,11 +105,15 @@ State SawingLoop else GoToState(''); } } -simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - if (bWasRaged || bCharging) { - groundSpeed *= 3.5; - } +simulated function float GetOriginalGroundSpeed() +{ + local float result; + result = OriginalGroundSpeed; + if ( bWasRaged || bCharging ) + result *= 3.5; + else if( bZedUnderControl ) + result *= 1.25; + return result; } state RunningState { @@ -120,6 +124,7 @@ state RunningState GoToState(''); else { bCharging = true; + SetGroundSpeed(GetOriginalGroundSpeed()); if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); NetUpdateTime = Level.TimeSeconds - 1; @@ -128,6 +133,8 @@ state RunningState function EndState() { bCharging = False; + if( !bZapped ) + SetGroundSpeed(GetOriginalGroundSpeed()); if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); } @@ -156,8 +163,6 @@ defaultproperties ChallengeSound(2)=None ChallengeSound(3)=None ScoringValue=300 - maxStoppingEffect=0.25 - minStoppingThreshold=0.25 MenuName="Jason" AmbientSound=Sound'ScrnZedPack_S.Jason.Jason_Sound' Mesh=SkeletalMesh'ScrnZedPack_A.JasonMesh' diff --git a/sources/Zeds/Nice/NiceZombieScrake.uc b/sources/Zeds/Nice/NiceZombieScrake.uc index 22f2797..190e4fb 100644 --- a/sources/Zeds/Nice/NiceZombieScrake.uc +++ b/sources/Zeds/Nice/NiceZombieScrake.uc @@ -83,6 +83,7 @@ function SetMindControlled(bool bNewMindControlled) if( bNewMindControlled != bZedUnderControl ) { + SetGroundSpeed(OriginalGroundSpeed * 1.25); Health *= 1.25; HealthMax *= 1.25; } @@ -184,9 +185,8 @@ state RunningState { return false; } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - groundSpeed *= 3.5; + simulated function float GetOriginalGroundSpeed() { + return 3.5 * OriginalGroundSpeed; } function BeginState(){ local NiceHumanPawn rageTarget, rageCause; @@ -214,6 +214,7 @@ state RunningState if(bZapped) GoToState(''); else{ + SetGroundSpeed(OriginalGroundSpeed * 3.5); bCharging = true; if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); @@ -223,6 +224,10 @@ state RunningState } function EndState() { + if( !bZapped ) + { + SetGroundSpeed(GetOriginalGroundSpeed()); + } bCharging = False; if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); @@ -260,9 +265,8 @@ State SawingLoop { return false; } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - groundSpeed *= attackChargeRate; + simulated function float GetOriginalGroundSpeed() { + return OriginalGroundSpeed * AttackChargeRate; } function bool CanGetOutOfWay() { @@ -275,6 +279,7 @@ State SawingLoop // Randomly have the scrake charge during an attack so it will be less predictable if(Health/HealthMax < 0.5 || FRand() <= 0.95) { + SetGroundSpeed(OriginalGroundSpeed * AttackChargeRate); bCharging = true; if( Level.NetMode!=NM_DedicatedServer ) PostNetReceive(); @@ -322,6 +327,8 @@ State SawingLoop { AmbientSound=default.AmbientSound; MeleeDamage = Max( DifficultyDamageModifer() * default.MeleeDamage, 1 ); + + SetGroundSpeed(GetOriginalGroundSpeed()); bCharging = False; if(Level.NetMode != NM_DedicatedServer) PostNetReceive(); diff --git a/sources/Zeds/Nice/NiceZombieScrakeBase.uc b/sources/Zeds/Nice/NiceZombieScrakeBase.uc index 2905831..6ccd9f6 100644 --- a/sources/Zeds/Nice/NiceZombieScrakeBase.uc +++ b/sources/Zeds/Nice/NiceZombieScrakeBase.uc @@ -63,8 +63,6 @@ defaultproperties HealthMax=1000.000000 Health=1000 HeadHeight=2.200000 - maxStoppingEffect=0.15 - minStoppingThreshold=0.15 MenuName="Nice Scrake" MovementAnims(0)="SawZombieWalk" MovementAnims(1)="SawZombieWalk" diff --git a/sources/Zeds/Nice/NiceZombieShiver.uc b/sources/Zeds/Nice/NiceZombieShiver.uc index a28b0d1..fbd612a 100644 --- a/sources/Zeds/Nice/NiceZombieShiver.uc +++ b/sources/Zeds/Nice/NiceZombieShiver.uc @@ -3,7 +3,6 @@ class NiceZombieShiver extends NiceZombieShiverBase; var float TeleportBlockTime; var float HeadOffsetY; var transient bool bRunning, bClientRunning; -var float teleportAttackCooldownEndTime; replication { reliable if ( Role == ROLE_Authority) @@ -39,39 +38,6 @@ simulated function PostBeginPlay() } } } - -function bool CanAttack(Actor target) { - if (level.timeSeconds < teleportAttackCooldownEndTime) - return false; - return super.CanAttack(target); -} - -simulated event SetAnimAction(name NewAction) { - local int meleeAnimIndex; - - if (bFrozenZed) return; - if (newAction == '') return; - - if (newAction == 'Claw') { - meleeAnimIndex = Rand(2); // Shivers only have two animations now - newAction = meleeAnims[meleeAnimIndex]; - currentDamtype = zombieDamType[meleeAnimIndex]; - } else if(newAction == 'DoorBash') { - currentDamtype = zombieDamType[Rand(3)]; - } - expectingChannel = DoAnimAction(NewAction); - if (AnimNeedsWait(newAction)) { - bWaitForAnim = true; - } else { - bWaitForAnim = false; - } - if (level.netMode != NM_Client) { - animAction = newAction; - bResetAnimAct = True; - resetAnimActTime = level.timeSeconds + 0.3; - } -} - simulated function Destroyed() { if (Level.NetMode != NM_DedicatedServer && MatAlphaSkin != none) @@ -213,6 +179,7 @@ state Running Global.Tick(Delta); if (RunUntilTime < Level.TimeSeconds) GotoState(''); + GroundSpeed = GetOriginalGroundSpeed(); } function BeginState() { @@ -223,12 +190,13 @@ state Running function EndState() { bRunning = false; + GroundSpeed = global.GetOriginalGroundSpeed(); RunCooldownEnd = Level.TimeSeconds + PeriodRunCoolBase + FRand() * PeriodRunCoolRan; MovementAnims[0] = WalkAnim; } - simulated function UpdateGroundSpeed() { - super.UpdateGroundSpeed(); - groundSpeed *= 2.5; + function float GetOriginalGroundSpeed() + { + return global.GetOriginalGroundSpeed() * 2.5; } function bool CanSpeedAdjust() { @@ -251,6 +219,14 @@ simulated function bool AnimNeedsWait(name TestAnim) } return ExpectingChannel == 0; } +simulated function float GetOriginalGroundSpeed() +{ + local float result; + result = OriginalGroundSpeed; + if( bZedUnderControl ) + result *= 1.25; + return result; +} simulated function HandleAnimation(float Delta) { // hehehe @@ -315,7 +291,7 @@ simulated function Tick(float Delta) { SetCollision(true, true); FlashTeleport(); - SetCollision(true, false); + SetCollision(false, false); FadeStage = 2; } } @@ -356,7 +332,7 @@ function StartTeleport() { FadeStage = 1; AlphaFader = 255; - SetCollision(true, false); + SetCollision(false, false); bFlashTeleporting = true; } function FlashTeleport() @@ -414,7 +390,6 @@ function FlashTeleport() Teleported: bFlashTeleporting = false; LastFlashTime = Level.TimeSeconds; - teleportAttackCooldownEndTime = level.timeSeconds + 0.5; } function Died(Controller Killer, class damageType, vector HitLocation) { @@ -464,16 +439,10 @@ simulated function int DoAnimAction( name AnimName ) } defaultproperties { - headOffsetY=-3.000000 + HeadOffsetY=-3.000000 idleInsertFrame=0.468000 - onlineHeadshotOffset=(X=19.000000,Z=39.000000) - scoringValue=15 - headRadius=8.000000 - headHeight=3.000000 - // Override third animation just in case. - // However it shouldn't be required since we've already changed - // `SetAnimAction` function to only use first two animations - meleeAnims(0)="Claw" - meleeAnims(1)="Claw2" - meleeAnims(2)="Claw" + OnlineHeadshotOffset=(X=19.000000,Z=39.000000) + ScoringValue=15 + HeadRadius=8.000000 + HeadHeight=3.000000 } diff --git a/sources/Zeds/Nice/NiceZombieSiren.uc b/sources/Zeds/Nice/NiceZombieSiren.uc index aa15090..ad5b69b 100644 --- a/sources/Zeds/Nice/NiceZombieSiren.uc +++ b/sources/Zeds/Nice/NiceZombieSiren.uc @@ -223,10 +223,9 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class niceVet; - local NiceZombieClot niceClot; if (bHurtEntry || Health <= 0 || HeadHealth <= 0 || bIsStunned) return; @@ -244,10 +243,6 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class 0) @@ -286,12 +281,6 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class 0){ currScreamTime = Level.TimeSeconds - screamStartTime; diff --git a/sources/Zeds/Nice/NiceZombieTeslaHusk.uc b/sources/Zeds/Nice/NiceZombieTeslaHusk.uc index ff60b33..030c45f 100644 --- a/sources/Zeds/Nice/NiceZombieTeslaHusk.uc +++ b/sources/Zeds/Nice/NiceZombieTeslaHusk.uc @@ -709,6 +709,7 @@ defaultproperties HealEnergyDrain=0.200000 ProjectileFireInterval=5.000000 BurnDamageScale=1.000000 + mind=0.000000 bFireImmune=False MoanVoice=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Talk' BleedOutDuration=5.000000 diff --git a/sources/Zeds/NiceMonster.uc b/sources/Zeds/NiceMonster.uc index 64b37f5..04bb11d 100644 --- a/sources/Zeds/NiceMonster.uc +++ b/sources/Zeds/NiceMonster.uc @@ -24,7 +24,6 @@ class NiceMonster extends KFMonster #exec OBJ LOAD FILE=KF_EnemyGlobalSndTwo.uax #exec OBJ LOAD FILE=KFZED_FX_T.utx -var bool initializationComplete; //============================================================================== //============================================================================== // > Affliction system @@ -76,15 +75,13 @@ var float stunLoopStart, stunLoopEnd, idleInsertFrame; var bool bWasIdleStun; // Were we using idleanimation for stun? var float prevStunAnimFrame; // At which tick we were? //============================================================================== -// >> Another default stun system allows to stun zeds by repeatedly dealing +// >> Another default stun system allows tostuns zeds by repeatedly dealing // head damage to them fast enough: // 1. Dealing head damage increases accumulated damage // 2. If head damage was received for a certain time period, - // accumulated damage starts to decrease // 3. If accumulated damage is high enough, passes 'IsStunPossible' check -// - normal duration stun activates -// How much more time will this zed spend concussed? -var float concussionCountdown; +// and has low enough mind level - normal duration stun activates // Accumulated head damage var float accHeadDamage; // Rate (per second) at which accumulated head damage diminishes @@ -94,6 +91,16 @@ var float headRecoveryTime; // Count down variable for above mentioned time var float headRecoveryCountDown; +//============================================================================== +//============================================================================== +// > Mind system +// Largly underdeveloped and currently only exists to decide whether or not +// zed can be stunned by accumulating head damage +// Current mind level (1.0 - default and maximum value) +var float mind; +// Treshold, required for stun by accumulated head damage +var float accStunMindLvl; + //============================================================================== //============================================================================== // > Temperature system @@ -127,25 +134,10 @@ var float heatDissipationRate; var float heatTicksPerSecond; // Tracks last time heat tick occured var float lastHeatTick; -var float scorchmarkDamage; -var float MIN_HEAT, MAX_HEAT; - -//============================================================================== -//============================================================================== -// > Speed system -// Manages speed modifications from weapon attacks and other effects. -// -// This variable stores with how much stopping power zed was affected. -// Is a value from 0.0 to 1.0 and `1 - stoppingEffect` acts as speed multiplier -// for the zed -var float stoppingEffect; -// How much stopping effect would be recovred in a second -var float stoppingRecoveryRate; -// Maximum `stoppingEffect` value zed can accumulate -var float maxStoppingEffect; -// Minimal stopping threshold for the zed (supposed to be subtracted from -// incoming effects' strenght). -var float minStoppingThreshold; +// If set to 'true' - low-value ticks of fire DoT will waste accordingly small +// amount of fuel, otherwise they will always waste some minimal amount, +// resulting in a loss of potential damage +var bool bFrugalFuelUsage; //============================================================================== //============================================================================== @@ -230,7 +222,6 @@ simulated function PostBeginPlay(){ SavedExtCollision = MyExtCollision.bCollideActors; } } - initializationComplete = true; } //============================================================================== @@ -371,15 +362,6 @@ simulated function FearTick(float deltaTime){ + 0.75 * accelRate * Normal(Location - fearCenter); } //============================================================================== -// >> Decrease active stopping power on the zed as the time goes by -simulated function StoppingPowerTick(float deltaTime) { - if (stoppingEffect <= 0.0 || concussionCountdown > 0.0) { - return; - } - stoppingEffect -= deltaTime * stoppingRecoveryRate; - stoppingEffect = FMax(0, stoppingEffect); -} -//============================================================================== // >> Set of functions to handle animation changes during stun simulated function CalcRemainigStunStructure( name seqName, float oFrame, @@ -469,14 +451,14 @@ simulated function StunTick(float deltaTime){ } //============================================================================== // >> Set of functions to handle stun from head damage accumulation -function AccumulateHeadDamage( float addDamage, +function AccumulateHeadDamage( float addDamage, bool bIsHeadshot, NicePlayerController nicePlayer){ if(bIsHeadshot){ - AccHeadDamage += addDamage * 0.5; + AccHeadDamage += addDamage; HeadRecoveryCountDown = HeadRecoveryTime; if(AccHeadDamage > (default.HeadHealth / 1.5) - && (concussionCountdown > 0.0 && IsStunPossible())) + && (Mind <= AccStunMindLvl && IsStunPossible())) DoStun(nicePlayer.pawn,,,, 1.0); } else if(HeadRecoveryCountDown > 0.0) @@ -484,13 +466,11 @@ function AccumulateHeadDamage( float addDamage, HeadRecoveryTime / 2); } function HeadDamageRecoveryTick(float delta){ - concussionCountdown -= delta; - concussionCountdown = FMax(0.0, concussionCountdown); - headRecoveryCountDown -= delta; - headRecoveryCountDown = FMax(0.0, headRecoveryCountDown); - if(headRecoveryCountDown <= 0.0) - accHeadDamage -= delta * HeadDamageRecoveryRate; - accHeadDamage = FMax(accHeadDamage, 0.0); + HeadRecoveryCountDown -= delta; + HeadRecoveryCountDown = FMax(0.0, HeadRecoveryCountDown); + if(HeadRecoveryCountDown <= 0.0) + AccHeadDamage -= delta * HeadDamageRecoveryRate; + AccHeadDamage = FMax(AccHeadDamage, 0.0); } //============================================================================== // >> Function that calls actual 'HeatTick' when needed @@ -500,11 +480,6 @@ simulated function FakeHeatTick(float deltaTime){ local float oFrame; local float oRate; local NiceMonsterController niceZedController; - if (bOnFire) { - // 100 of the scorchmark damage should restore every 1/10 of a second - scorchmarkDamage += deltaTime * 10 * 100; - scorchmarkDamage = FMin(scorchmarkDamage, 100); - } if(lastHeatTick + (1 / HeatTicksPerSecond) < Level.TimeSeconds){ if(bOnFire && !bBurningBehavior) SetBurningBehavior(); @@ -552,6 +527,15 @@ simulated function FakeHeatTick(float deltaTime){ // >> Ticks from TWI's code // Updates zed's speed if it's not relevant; // code, specific to standalone game and listen servers was cut out +simulated function NonRelevantSpeedupTick(float deltaTime){ + if(Level.netMode == NM_Client || !CanSpeedAdjust()) return; + if(Level.TimeSeconds - LastReplicateTime > 0.5) + SetGroundSpeed(default.GroundSpeed * (300.0 / default.GroundSpeed)); + else{ + LastSeenOrRelevantTime = Level.TimeSeconds; + SetGroundSpeed(GetOriginalGroundSpeed()); + } +} // Kill zed if it has been bleeding long enough simulated function BleedOutTick(float deltaTick) @@ -602,6 +586,7 @@ simulated function TWITick(float deltaTime){ // If we've flagged this character to be destroyed next tick, handle that if(bDestroyNextTick && TimeSetDestroyNextTickTime < Level.TimeSeconds) Destroy(); + NonRelevantSpeedupTick(deltaTime); // Reset AnimAction if(bResetAnimAct && ResetAnimActTime < Level.TimeSeconds){ AnimAction = ''; @@ -624,10 +609,8 @@ simulated function Tick(float deltaTime){ DecapTick(deltaTime); FearTick(deltaTime); StunTick(deltaTime); - StoppingPowerTick(deltaTime); HeadDamageRecoveryTick(deltaTime); FakeHeatTick(deltaTime); - UpdateGroundSpeed(); // TWI's tick TWITick(deltaTime); } @@ -684,19 +667,6 @@ simulated function float IsHeadshotClient( Vector Loc, return 1.0 - (distance / (headRadius * headScale * additionalScale)); return 0.0; } -// Calculates distance from `location` to this zed's head. -simulated function float GetDistanceToHead(Vector location) { - local Coords headBoneCoords; - local Vector headLocation; - - if(headBone == '') { - return 0.0; - } - headBoneCoords = GetBoneCoords(headBone); - headLocation = - headBoneCoords.Origin + headHeight * headScale * headBoneCoords.XAxis; - return VSize(location - headLocation); -} // In case of a future modifications: // check if it's a player doing damage before relying on it function ModDamage( out int damage, @@ -707,28 +677,28 @@ function ModDamage( out int damage, float headshotLevel, KFPlayerReplicationInfo KFPRI, optional float lockonTime){ - local NicePlayerController nicePlayer; - local bool hasGiantSlayer; - local int bonusDamageStacks; - if(KFPRI == none || KFPRI.ClientVeteranSkill == none) return; - // Add perked damage - damage = KFPRI.ClientVeteranSkill.Static.AddDamage( KFPRI, self, - KFPawn(instigatedBy), - damage, damageType); - // Skill bonuses - if(instigatedBy == none) - return; - nicePlayer = NicePlayerController(instigatedBy.controller); - if(nicePlayer == none) - return; - hasGiantSlayer = class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, - class'NiceSkillCommandoGiantSlayer'); - if(!hasGiantSlayer) - return; - bonusDamageStacks = - int(health / class'NiceSkillCommandoGiantSlayer'.default.healthStep); - damage *= 1.0f + bonusDamageStacks * - class'NiceSkillCommandoGiantSlayer'.default.bonusDamageMult; + local NicePlayerController nicePlayer; + local bool hasGiantSlayer; + local int bonusDamageStacks; + if(KFPRI == none || KFPRI.ClientVeteranSkill == none) return; + // Add perked damage + damage = KFPRI.ClientVeteranSkill.Static.AddDamage( KFPRI, self, + KFPawn(instigatedBy), + damage, damageType); + // Skill bonuses + if(instigatedBy == none) + return; + nicePlayer = NicePlayerController(instigatedBy.controller); + if(nicePlayer == none) + return; + hasGiantSlayer = class'NiceVeterancyTypes'.static.hasSkill(nicePlayer, + class'NiceSkillCommandoGiantSlayer'); + if(!hasGiantSlayer) + return; + bonusDamageStacks = + int(health / class'NiceSkillCommandoGiantSlayer'.default.healthStep); + damage *= 1.0f + bonusDamageStacks * + class'NiceSkillCommandoGiantSlayer'.default.bonusDamageMult; } function ModRegularDamage( out int damage, Pawn instigatedBy, @@ -750,6 +720,9 @@ function ModRegularDamage( out int damage, damage = niceVet.static.AddRegDamage( KFPRI, self, KFPawn(instigatedBy), damage, damageType); + // Add some damage against crispy zeds + if(bCrispified) + damage += (Max(1200 - default.Health, 0) * damage) / 1200; // Skills bonuses if(nicePlayer == none) return; hasOverkillSkill = class'NiceVeterancyTypes'.static. @@ -825,30 +798,26 @@ function int ModBodyDamage( out int damage, local NicePlayerController nicePlayer; painDamage = damage; bIsHeadShot = (headshotLevel > 0.0); - if (instigatedBy != none) + if(instigatedBy != none) nicePlayer = NicePlayerController(instigatedBy.Controller); - if (bFrozenZed && damageType != none && damageType.default.bIsExplosive) { - damage *= 1.5; - } // On damaging critical spot (so far only head) - do body destruction - if (bIsHeadShot && damageType != none) + if(bIsHeadShot && damageType != none) damage *= damageType.default.bodyDestructionMult; // Skill bonuses - if (nicePlayer == none) + if(nicePlayer == none) return painDamage; bHasMessy = class'NiceVeterancyTypes'.static. someoneHasSkill(nicePlayer, class'NiceSkillSharpshooterDieAlready'); return painDamage; } // Do effects, based on fire damage dealt to monster -function FireDamageEffects(out int damage, +function FireDamageEffects( int damage, Pawn instigatedBy, Vector hitLocation, Vector momentum, class damageType, float headshotLevel, KFPlayerReplicationInfo KFPRI){ - local float heatDelta, bonusFireDamage; damage = FMax(0.0, damage); iceCrustStrenght = FMax(0.0, iceCrustStrenght); if(bFrozenZed){ @@ -866,37 +835,24 @@ function FireDamageEffects(out int damage, } damage /= 10; } - if(damage <= 0) { - return; - } + if(damage <= 0) return; // Turn up the heat! // (we can only make it twice as hot with that damage, // but set limit at least at 50, as if we've dealt at least 25 heat damage) - heatDelta = (damage * HeatIncScale()) + heat += (damage * HeatIncScale()) * FMin(1.0, FMax(0.0, (2 - Abs(heat) / FMax(25, Abs(damage) )))); - if (concussionCountdown > 0) { - heat += heatDelta * 2; - } else { - heat += heatDelta; - } CapHeat(); // Change damage type if new one was stronger if(!bOnFire || damage * HeatIncScale() > lastBurnDamage){ fireDamageClass = damageType; burnInstigator = instigatedBy; } - // Double heat damage at the cost of the fuel, if zed is already on fire - if (bOnFire) { - bonusFireDamage = FMax(FMin(damage, flameFuel) * 0.25, 0); - flameFuel -= bonusFireDamage; - damage += bonusFireDamage; - } // Set on fire, if necessary if(heat > GetIgnitionPoint() && !bOnFire && bCanBurn){ bBurnified = true; bOnFire = true; burnInstigator = instigatedBy; - fireDamageClass = damageType; + fireDamageClass = damageType; lastHeatTick = Level.TimeSeconds; } } @@ -1013,7 +969,7 @@ function DealDecapDamage( int damage, hasSkill(nicePlayer, class'NiceSkillSharpshooterDieAlready')) ServerDropFaster(NiceHumanPawn(nicePlayer.pawn)); } -function DealHeadDamage( int damage, +function DealHeadDamage( int damage, Pawn instigatedBy, Vector hitLocation, Vector momentum, @@ -1031,11 +987,6 @@ function DealHeadDamage( int damage, // Actual damage effects // Skull injury killed a zed if(HeadHealth <= 0) return; - // Additional weakpoint damage to burning zeds from non-flame weapons - if (bOnFire) { - damage += scorchmarkDamage * (1 - damageType.default.heatPart); - scorchmarkDamage *= damageType.default.heatPart; - } HeadHealth -= damage; if(nicePlayer != none && IsFinisher(damage, damageType, nicePlayer, true)) HeadHealth -= damage; @@ -1218,9 +1169,6 @@ function EPainReaction GetRightPainReaction(int painDamage, local int stunScore, flinchScore; local bool bStunPass, bFlinchPass, bMiniFlinshPass; local class niceVet; - if (bOnFire) { - return PREACTION_NONE; - } if(KFPRI != none) niceVet = class(KFPRI.ClientVeteranSkill); stunScore = painDamage; @@ -1289,9 +1237,8 @@ function float GetstunDurationMult( Pawn instigatedBy, if(KFPRI == none) return stunDurationMultiplier; niceVet = class(KFPRI.ClientVeteranSkill); if(niceVet == none) return stunDurationMultiplier; - if(damageType == none) return stunDurationMultiplier; // Perk's bonuses out - return stunDurationMultiplier * damageType.default.stunLengthMultiplier * + return stunDurationMultiplier * niceVet.static.stunDurationMult( KFPRI, self, KFPawn(instigatedBy), damageType); } @@ -1623,13 +1570,13 @@ function Freeze(){ StopMovement(); Disable('AnimEnd'); StopAnimating(); - + if(Controller != none){ Controller.FocalPoint = Location + 512*vector(Rotation); Controller.Enemy = none; Controller.Focus = none; if(!Controller.IsInState('Freeze')) - Controller.GoToState('Freeze'); + Controller.GoToState('Freeze'); KFMonsterController(Controller).bUseFreezeHack = true; } bFrozenZed = true; @@ -1647,7 +1594,7 @@ function UnFreeze(){ GroundSpeed = GetOriginalGroundSpeed(); bFrozenZed = false; } -function TakeDamageClient( int damage, +function TakeDamageClient( int damage, Pawn instigatedBy, Vector hitLocation, Vector momentum, @@ -1666,26 +1613,24 @@ function TakeDamageClient( int damage, KFPRI = KFPlayerReplicationInfo(instigatedBy.PlayerReplicationInfo); if(headHealth <= 0) headshotLevel = 0.0; - // Handle special weapon effects - HandleStoppingPower(damageType, headshotLevel); // Handle elemental damage components - ExtractElementalDamage(regDamage, heatDamage, damage, + ExtractElementalDamage( regDamage, heatDamage, damage, instigatedBy, hitLocation, momentum, damageType, KFPRI, headshotLevel, lockonTime); - FireDamageEffects(HeatDamage, instigatedBy, hitLocation, - momentum, damageType, headshotLevel, KFPRI); - FrostEffects( instigatedBy, hitLocation, momentum, + FireDamageEffects( HeatDamage, instigatedBy, hitLocation, momentum, + damageType, headshotLevel, KFPRI); + FrostEffects( instigatedBy, hitLocation, momentum, damageType, headshotLevel, KFPRI); // Handle body parts damage components - ExtractPartsDamage( bodyDamage, headDamage, painDamage, + ExtractPartsDamage( bodyDamage, headDamage, painDamage, RegDamage + HeatDamage, instigatedBy, hitLocation, momentum, damageType, KFPRI, headshotLevel, lockonTime); - DoRightPainReaction( painDamage, instigatedBy, hitLocation, momentum, + DoRightPainReaction( painDamage, instigatedBy, hitLocation, momentum, damageType, headshotLevel, KFPRI); - DealPartsDamage( bodyDamage, headDamage, - instigatedBy, hitLocation, momentum, damageType, - KFPRI, headshotLevel, lockonTime); + DealPartsDamage( bodyDamage, headDamage, instigatedBy, + hitLocation, momentum, damageType, KFPRI, + headshotLevel, lockonTime); AddKillAssistant(instigatedBy, bodyDamage); // Rewrite values of last deal damage, instigator, etc. UpdateLastDamageVars( instigatedBy, bodyDamage, damageType, @@ -1694,28 +1639,6 @@ function TakeDamageClient( int damage, // like why the fuck is it being done HERE? Makes no fucking sense bBackstabbed = false; } -function HandleStoppingPower( - class damageType, - float headshotLevel -) { - local float strength; - local float actualMinStoppingThreshold, actualMaxStoppingEffect; - - strength = damageType.default.stoppingPower; - if (headshotLevel > 0.0) { - strength *= 2; - } - if (concussionCountdown > 0) { - actualMinStoppingThreshold = FMax(0.0, minStoppingThreshold - 0.2); - actualMaxStoppingEffect = FMin(0.9, maxStoppingEffect + 0.2); - } - else { - actualMinStoppingThreshold = minStoppingThreshold; - actualMaxStoppingEffect = maxStoppingEffect; - } - strength = FMax(0, strength - actualMinStoppingThreshold); - stoppingEffect = FMin(actualMaxStoppingEffect, stoppingEffect + strength); -} function TakeDamage(int damage, Pawn instigatedBy, Vector hitLocation, @@ -1761,12 +1684,15 @@ function TakeDamage(int damage, } } function TakeFireDamage(int damage, Pawn instigator){ + local bool bLowFuel, bHighHeat; local Vector DummyHitLoc, DummyMomentum; super(Skaarj).TakeDamage( damage, instigator, dummyHitLoc, dummyMomentum, fireDamageClass); lastBurnDamage = damage; // Melt em' :) - if(FlameFuel <= 0) + bHighHeat = heat > default.health / 20; + bLowFuel = FlameFuel < 0.75 * InitFlameFuel; + if(FlameFuel <= 0 || bHighHeat && bLowFuel) ZombieCrispUp(); } function TakeFrostDamage(int damage, Pawn instigator){ @@ -1790,40 +1716,33 @@ simulated function ZombieCrispUp(){ } simulated function HeatTick(){ local float iceDamage; - local float heatRelativeLevel, heatMultiplier; - - heatRelativeLevel = FMin(heat, flameFuel) / initFlameFuel; - if (heatRelativeLevel < 0.05) { - heatMultiplier = 1.5; - } else { - heatMultiplier = 1.1; - } // Update heat value if(!bOnFire || flameFuel <= 0) heat *= heatDissipationRate; - else { - if(flameFuel < heat) { - heat = flameFuel * heatMultiplier + (heat - flameFuel) * heatDissipationRate; - } else { - heat = heat * heatMultiplier; - } + else{ + if(flameFuel < heat) + heat = flameFuel * 1.1 + (heat - flameFuel) * heatDissipationRate; + else + heat = heat * 1.1; + if(bFrugalFuelUsage) + flameFuel -= heat; + else + flameFuel -= FMax(heat, InitFlameFuel / 15); } - flameFuel = FMax(0, flameFuel - heat); CapHeat(); if(Abs(heat) < 1) heat = 0.0; // Update on-fire status if(bOnFire){ - if(heat > 0) { - TakeFireDamage(heat, burnInstigator); - } - else { - bBurnified = false; - UnSetBurningBehavior(); - RemoveFlamingEffects(); - StopBurnFX(); - bOnFire = false; - } + if(heat > 0) + TakeFireDamage(heat + rand(5), burnInstigator); + else{ + bBurnified = false; + UnSetBurningBehavior(); + RemoveFlamingEffects(); + StopBurnFX(); + bOnFire = false; + } } // Update frozen status (always deal frost damage) iceCrustStrenght = FMax(iceCrustStrenght, heat); @@ -1842,9 +1761,9 @@ simulated function HeatTick(){ } simulated function SetBurningBehavior(){ bBurningBehavior = true; - if(default.Health >= 1000) { - return; - } + if(default.Health >= 1000) return; + if(Role == Role_Authority) + Intelligence = BRAINS_Retarded; MovementAnims[0] = BurningWalkFAnims[Rand(3)]; WalkAnims[0] = BurningWalkFAnims[Rand(3)]; MovementAnims[1] = BurningWalkAnims[0]; @@ -1860,6 +1779,7 @@ simulated function UnSetBurningBehavior(){ if(Role == Role_Authority){ Intelligence = default.Intelligence; if(!bZapped){ + SetGroundSpeed(GetOriginalGroundSpeed()); AirSpeed = default.AirSpeed; WaterSpeed = default.WaterSpeed; } @@ -1871,50 +1791,6 @@ simulated function UnSetBurningBehavior(){ WalkAnims[i] = default.WalkAnims[i]; } } -simulated function SetGroundSpeed(float newGroundSpeed) { - if (initializationComplete) { - UpdateGroundSpeed(); - } else { - // Let `KFMonster`'s code setup original speed for this zed. - // This is a hack to be removed later, when we'll be untangling - // initialization code - super.SetGroundSpeed(newGroundSpeed); - } -} -simulated function UpdateGroundSpeed() { - if (TryNonRelevantSpeedup()) { - return; - } - groundSpeed = GetOriginalGroundSpeed(); - groundSpeed *= (1.0 - stoppingEffect); - if (bDecapitated) { - groundSpeed *= 0.8; - } - if (bCrispified) { - groundSpeed *= 1.25; - } -} -simulated function ModDamageFromZed( - out int damage, - class damageType -) { - if (bCrispified) { - damage *= 2; - } -} -// If this function returns `true`, then we shouldn't touch speed further, -// because a speed hack was used for the zed -simulated function bool TryNonRelevantSpeedup(){ - if(level.netMode == NM_Client || !CanSpeedAdjust()) { - return false; - } - if(level.timeSeconds - lastReplicateTime > 0.5) { - groundSpeed = default.groundSpeed * (300.0 / default.groundSpeed); - return true; - } - lastSeenOrRelevantTime = level.timeSeconds; - return false; -} simulated function ServerDropFaster(NiceHumanPawn nicePawn){ if(nicePawn == none) return; if(Health > 0) @@ -1932,7 +1808,7 @@ simulated function RemoveHead(){ if(kfDmgType != none && kfDmgType.default.bIsMeleeDamage) bMeleeDecapitated = true; SetAnimAction('HitF'); - UpdateGroundSpeed(); + SetGroundSpeed(GroundSpeed *= 0.80); // No more raspy breathin'...cuz he has no throat or mouth :S AmbientSound = MiscSound; if(Health > 0) @@ -2131,8 +2007,8 @@ function float HeatIncScale(){ return 100.0 / default.health; } function CapHeat(){ - heat = FMin(heat, MAX_HEAT); - heat = FMax(heat, MIN_HEAT); + heat = FMin(heat, 135 + rand(10) - 5); + heat = FMax(heat, -150 + rand(10) - 5); } function bool TryMeleeReachTarget(out Vector hitLocation){ local Actor hitActor; @@ -2173,7 +2049,6 @@ function bool MeleeDamageTarget(int hitDamage, Vector pushDir){ local KFHumanPawn kfHumanPawn; if(Level.netMode == NM_Client) return false; if(controller == none || controller.target == none) return false; - ModDamageFromZed(hitDamage, niceZombieDamType); // Melee for doors kfHumanPawn = KFHumanPawn(controller.target); bTargetIsDoor = controller.target.IsA('KFDoorMover'); @@ -2326,10 +2201,13 @@ defaultproperties lastStunTime=-1.000000 headDamageRecoveryRate=100.000000 headRecoveryTime=1.000000 + mind=1.000000 + accStunMindLvl=0.500000 bCanBurn=True fuelRatio=0.750000 heatDissipationRate=0.666000 heatTicksPerSecond=3.000000 + bFrugalFuelUsage=True clientHeadshotScale=1.000000 FrozenMaterial=Texture'HTec_A.Overlay.IceOverlay' ShatteredIce=class'NiceIceChunkEmitter' @@ -2338,12 +2216,7 @@ defaultproperties DamageToMonsterScale=5.000000 RagdollLifeSpan=120.000000 ControllerClass=class'NiceMonsterController' - stoppingEffect=0.0 - stoppingRecoveryRate=0.025 - maxStoppingEffect=0.25 - minStoppingThreshold=0.0 - MIN_HEAT = -150.0 - MAX_HEAT = 200.0 + Begin Object Class=KarmaParamsSkel Name=KarmaParamsSkelN KConvulseSpacing=(Max=2.200000) KLinearDamping=0.150000 diff --git a/sources/Zeds/NiceMonsterController.uc b/sources/Zeds/NiceMonsterController.uc index 59fd849..1bcb5ab 100644 --- a/sources/Zeds/NiceMonsterController.uc +++ b/sources/Zeds/NiceMonsterController.uc @@ -480,7 +480,6 @@ function bool SetEnemy( pawn newEnemy, // Do fight if we can if(bCanForceFight) { - moveTarget = newEnemy; ChangeEnemy(newEnemy, true); FightEnemy(false); return true;