class NiceNade extends ScrnNade; var class AvoidMarkerClass; var class niceExplosiveDamage; // Overloaded to implement nade skills simulated function Explode(vector HitLocation, vector HitNormal){ local PlayerController LocalPlayer; local Projectile P; local byte i; bHasExploded = true; BlowUp(HitLocation); // null reference fix if(ExplodeSounds.length > 0) PlaySound(ExplodeSounds[rand(ExplodeSounds.length)],,2.0); for(i = Rand(6);i < 10;i ++){ P = Spawn(ShrapnelClass,,,,RotRand(True)); if(P != none) P.RemoteRole = ROLE_None; } for(i = Rand(6);i < 10;i ++){ P = Spawn(ShrapnelClass,,,,RotRand(True)); if(P != none) P.RemoteRole = ROLE_none; } if(EffectIsRelevant(Location,false)){ Spawn(Class'KFmod.KFNadeExplosion',,, HitLocation, rotator(vect(0,0,1))); Spawn(ExplosionDecal, self,, HitLocation, rotator(-HitNormal)); } // Shake nearby players screens LocalPlayer = Level.GetLocalPlayerController(); if((LocalPlayer != none) && (VSize(Location - LocalPlayer.ViewTarget.Location) < (DamageRadius * 1.5))) LocalPlayer.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime); Destroy(); } function TakeDamage(int Damage, Pawn InstigatedBy, Vector HitLocation, Vector Momentum, class damageType, optional int HitIndex){ if(Monster(instigatedBy) != none || instigatedBy == Instigator){ if(DamageType == class'SirenScreamDamage') Disintegrate(HitLocation, vect(0,0,1)); else Explode(HitLocation, vect(0,0,1)); } } simulated function HurtRadius( float damageAmount, float damageRadius, class damageType, float momentum, Vector hitLocation ) { local NicePlayerController niceController; local NiceReplicationInfo niceRI; if (instigator == none) return; niceController = NicePlayerController(instigator.controller); if (niceController == none) return; niceRI = niceController.niceRI; if (niceRI == none) return; Destroy(); niceRI.ServerExplode(damageAmount, damageRadius, 1.0, niceExplosiveDamage, momentum, hitLocation, instigator); } // Overridden to spawn different AvoidMarker simulated function HitWall( vector HitNormal, actor Wall ){ local Vector VNorm; local PlayerController PC; if((Pawn(Wall) != none) || (GameObjective(Wall) != none)){ Explode(Location, HitNormal); return; } if(!bTimerSet){ SetTimer(ExplodeTimer, false); bTimerSet = true; } // Reflect off Wall w/damping VNorm = (Velocity dot HitNormal) * HitNormal; Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel; RandSpin(100000); DesiredRotation.Roll = 0; RotationRate.Roll = 0; Speed = VSize(Velocity); if(Speed < 20){ bBounce = false; PrePivot.Z = -1.5; SetPhysics(PHYS_none); DesiredRotation = Rotation; DesiredRotation.Roll = 0; DesiredRotation.Pitch = 0; SetRotation(DesiredRotation); if(Fear == none){ Fear = Spawn(AvoidMarkerClass); Fear.SetCollisionSize(DamageRadius, DamageRadius); Fear.StartleBots(); } if(Trail != none) Trail.mRegen = false; // stop the emitter from regenerating } else{ if((Level.NetMode != NM_DedicatedServer) && (Speed > 50)) PlaySound(ImpactSound, SLOT_Misc ); else{ bFixedRotationDir = false; bRotateToDesired = true; DesiredRotation.Pitch = 0; RotationRate.Pitch = 50000; } if(!Level.bDropDetail && (Level.DetailMode != DM_Low) && (Level.TimeSeconds - LastSparkTime > 0.5) && EffectIsRelevant(Location,false)){ PC = Level.GetLocalPlayerController(); if ( (PC.ViewTarget != none) && VSize(PC.ViewTarget.Location - Location) < 6000 ) Spawn(HitEffectClass,,, Location, Rotator(HitNormal)); LastSparkTime = Level.TimeSeconds; } } } defaultproperties { AvoidMarkerClass=class'NiceAvoidMarkerExplosive' niceExplosiveDamage=class'NiceDamTypeDemoExplosion' }