From 2f3385583cd92a9f2d81846f35c73a4e65d167ab Mon Sep 17 00:00:00 2001 From: Shtoyan Date: Sun, 9 Apr 2023 01:35:25 +0400 Subject: [PATCH 1/4] Apply new formatting for NiceBullet --- sources/Weapons/NiceBullet.uc | 1563 ++++++++++++++++++--------------- 1 file changed, 877 insertions(+), 686 deletions(-) diff --git a/sources/Weapons/NiceBullet.uc b/sources/Weapons/NiceBullet.uc index 6a60342..d402fd7 100644 --- a/sources/Weapons/NiceBullet.uc +++ b/sources/Weapons/NiceBullet.uc @@ -1,202 +1,209 @@ //====================================================================================================================== -// 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 -var NiceReplicationInfo niceRI; -// Controller of our instigator -var NicePlayerController nicePlayer; -// Controller of local player -var NicePlayerController localPlayer; -// Link to our mutator -var NicePack niceMutator; +// Link to interaction with the server +var NiceReplicationInfo niceRI; +// Controller of our instigator +var NicePlayerController nicePlayer; +// Controller of local player +var NicePlayerController localPlayer; +// 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); @@ -205,400 +212,498 @@ 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); - } - } + 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; } - 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(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 (localPlayer == none) { + localPlayer = NicePlayerController(Level.GetLocalPlayerController()); } - if(bInitFinished && !bInitFinishDetected){ - bInitFinishDetected = true; - UpdateTrails(); + + 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 && !bBulletDead && !bStuck) - DoProcessMovement(delta); - if(bInitFinished && bStuck){ - if(base == none || (KFMonster(base) != none && KFMonster(base).health <= 0)) - nicePlayer.ExplodeStuckBullet(stuckID); + + 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); + } } } -// 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; + +// 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; + 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; + 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); -} -// 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; - // 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 (pawnOther != none) { + IgnoreActor(pawnOther.AuxCollisionCylinder); + } + if (zedOther != none) { + IgnoreActor(zedOther.MyExtCollision); } } -// Restores ignored state of the actors and zeroes our ignored arrays -function ResetIgnoreList(){ + +// 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; + } + } + // 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); + } + } +} + +// 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; - } - // Otherwise compute new 'shiftPoint' normally - else{ - 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; + } else { + // Otherwise compute new 'shiftPoint' normally + 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; - } - // 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); + // 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); } 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 NiceMonster targetZed; - local name boneStick; - local float distToBone; - local float t; - 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; - if(bGhost) - return; + + if (bGhost) { + return; + } expData.explosionDamageType = charExplosionDamageType; expData.explosionDamage = charExplosionDamage; expData.explosionRadius = charExplosionRadius; @@ -609,236 +714,322 @@ function Stick(Actor target, Vector hitLocation){ expData.affectedByScream = charAffectedByScream; 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); + + 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 + ); } - 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); - } - 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); - GenerateImpactEffects(explosionImpact, explLocation, impactNormal, true, true); - 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); - } - 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); - } - if(!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false)){ - charPenetrationCount += 1; - KillBullet(); - } -} -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(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(!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); - 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; - // 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; - // -- Classic effect - 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; - } - } - // -- 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; - } - // -- 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(); -} -function ShakeView(Vector hitLocation){ - local float distance, scale; - if(nicePlayer == none || shakeRadiusMult < 0.0) - return; - distance = VSize(hitLocation - nicePlayer.ViewTarget.Location); - 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); - } -} -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(bulletXTrail != none){ - bulletXTrail.mRegen = false; - bulletXTrail.LifeSpan = LifeSpan; - } - bBulletDead = true; - bHidden = true; - SoundVolume = 0; - LifeSpan = FMin(LifeSpan, 0.1); -} -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 +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); + } + 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); + } + } + + 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); + } + } + if (!class'NiceBulletAdapter'.static.ZedPenetration(charDamage, self, none, false, false)) { + charPenetrationCount += 1; + KillBullet(); + } +} + +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 (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 (!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); + } + 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; + + // 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; + } + // -- Classic effect + 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; + } + } + // -- 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; + } + // -- 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(); + } +} + +function ShakeView(Vector hitLocation) { + local float distance, scale; + + if (nicePlayer == none || shakeRadiusMult < 0.0) { + return; + } + distance = VSize(hitLocation - nicePlayer.ViewTarget.Location); + 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 + ); + } +} + +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 (bulletXTrail != none) { + bulletXTrail.mRegen = false; + bulletXTrail.LifeSpan = LifeSpan; + } + bBulletDead = true; + bHidden = true; + SoundVolume = 0; + LifeSpan = FMin(LifeSpan, 0.1); +} + +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 -- 2.20.1 From 3b5f46c2b5b5be568468f2ab1fa410baba7fa31a Mon Sep 17 00:00:00 2001 From: Shtoyan Date: Sun, 9 Apr 2023 14:30:28 +0400 Subject: [PATCH 2/4] Optimize code flow --- sources/Weapons/NiceBullet.uc | 100 ++++++++++++++-------------------- 1 file changed, 41 insertions(+), 59 deletions(-) diff --git a/sources/Weapons/NiceBullet.uc b/sources/Weapons/NiceBullet.uc index d402fd7..8e03861 100644 --- a/sources/Weapons/NiceBullet.uc +++ b/sources/Weapons/NiceBullet.uc @@ -332,22 +332,15 @@ function Actor GetMainActor(Actor other) { 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; + 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; + } } return other; @@ -694,16 +687,19 @@ function DoProcessMovement(float delta) { } 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; expData.explosionDamageType = charExplosionDamageType; expData.explosionDamage = charExplosionDamage; expData.explosionRadius = charExplosionRadius; @@ -712,31 +708,13 @@ function Stick(Actor target, Vector hitLocation) { expData.fuseTime = charFuseTime; expData.explodeOnFuse = charExplodeOnFuse; expData.affectedByScream = charAffectedByScream; - 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 - ); + if (!target.IsA('NiceMonster')) { + hitLocation -= target.location; + boneStick = 'None'; + resultTarget = target; } else { - expData.bulletClass = class; - expData.instigator = instigator; + targetZed = NiceMonster(target); boneStick = targetZed.GetClosestBone(hitLocation, movementDirection, distToBone); if (CheckHeadshot(targetZed, hitLocation, movementDirection) > 0.0) { boneStick = targetZed.HeadBone; @@ -751,23 +729,27 @@ function Stick(Actor target, Vector hitLocation) { 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 - ); + hitLocation -= boneStrickOrig; + resultTarget = targetZed; } + + niceRI.ServerStickProjectile( + KFHumanPawn(instigator), + resultTarget, + boneStick, + hitLocation, + Rotator(movementDirection), + expData + ); + class'NiceProjectileSpawner'.static.StickProjectile( + KFHumanPawn(instigator), + resultTarget, + boneStick, + hitLocation, + Rotator(movementDirection), + expData + ); + KillBullet(); } -- 2.20.1 From 78ca66acddc10d64f32808bf2e39de1e3f70590b Mon Sep 17 00:00:00 2001 From: Shtoyan Date: Sun, 9 Apr 2023 14:52:39 +0400 Subject: [PATCH 3/4] Apply new formatting for NiceBulletAdapter --- sources/Weapons/NiceBulletAdapter.uc | 386 ++++++++++++++++++--------- 1 file changed, 261 insertions(+), 125 deletions(-) diff --git a/sources/Weapons/NiceBulletAdapter.uc b/sources/Weapons/NiceBulletAdapter.uc index 1ab2f91..4234c72 100644 --- a/sources/Weapons/NiceBulletAdapter.uc +++ b/sources/Weapons/NiceBulletAdapter.uc @@ -9,57 +9,132 @@ // 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, 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); + +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) return; - if(nicePawn.currentCalibrationState != CALSTATE_ACTIVE) return; + +static function HandleCalibration ( + bool isHeadshot, + NiceHumanPawn nicePawn, + NiceMonster targetZed +) { + if (nicePawn == none || 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; @@ -68,74 +143,113 @@ static function HitZed(NiceBullet bullet, NiceReplicationInfo niceRI, KFMonster 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; - nicePawn = NiceHumanPawn(bullet.instigator); - 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) - actualDamage *= bullet.charContiniousBonus; - 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.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); + } + niceVet = class'NiceVeterancyTypes'.static.GetVeterancy(KFPlayerReplicationInfo(nicePlayer.PlayerReplicationInfo)); + if (bullet.charCausePain) { + actualDamage = bullet.charOrigDamage; + } else { + actualDamage = bullet.charDamage; + } + if (headshotLevel > 0) { + actualDamage *= bullet.charContiniousBonus; + } + 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(!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; @@ -144,52 +258,74 @@ static function bool ZedPenetration(out float Damage, NiceBullet bullet, KFMonst 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 -} +defaultproperties { + BigZedMinHealth=1000 + MediumZedMinHealth=500 +} \ No newline at end of file -- 2.20.1 From bf53b53b31fd906893306cd96633ba94a938fb74 Mon Sep 17 00:00:00 2001 From: Shtoyan Date: Sun, 9 Apr 2023 15:15:00 +0400 Subject: [PATCH 4/4] Apply new formatting for NiceProjectileSpawner --- sources/Weapons/NiceProjectileSpawner.uc | 282 +++++++++++++++-------- 1 file changed, 192 insertions(+), 90 deletions(-) diff --git a/sources/Weapons/NiceProjectileSpawner.uc b/sources/Weapons/NiceProjectileSpawner.uc index 05dd281..5334af4 100644 --- a/sources/Weapons/NiceProjectileSpawner.uc +++ b/sources/Weapons/NiceProjectileSpawner.uc @@ -1,76 +1,160 @@ 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; @@ -92,76 +176,94 @@ static function NiceBullet SpawnProjectile(Vector Start, Rotator Dir, NiceFire.S 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 ( + 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(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); + 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 -} +defaultproperties { + bHidden=True + RemoteRole=ROLE_SimulatedProxy + LifeSpan=1.000000 +} \ No newline at end of file -- 2.20.1