Sun October 12 2003, 10:21 AM
ReaperCreeper// Grenade.
//
// RunePower or fire damage sets it alight. Once lit, there's a five second fuse.
// 1% chance for a grenade that explodes instantly when lit.
// 1% chance for a grenade with halved fuse length.
// 1% chance for a grenade with doubled fuse length.
// 3% chance for a grenade that does not explode.
//=============================================================================
class Grenade expands NonStow;
var() bool bFuseLit;
var() float TimeToBlow;
var() sound ExplodeSound;
var() int GrenMomentum;
var float FuseTimer;
var() enum EGrenadeType
{
GNormal,
GDud,
GLongFuse,
GShortFuse,
GNoFuse
} GrenadeType;
Function PostBeginPlay()
{
local int i;
bCanBePoweredUp = True;
i = Rand(100);
if (i == 0)
GrenadeType = GNoFuse;
if (i == 1)
GrenadeType = GShortFuse;
if (i == 2)
GrenadeType = GLongFuse;
if (i > 2 && i < 6)
GrenadeType = GDud;
Super.PostBeginPlay();
}
function PowerupInit()
{
SetOnFire(Pawn(Owner),0);
}
event bool JointDamaged(int Damage, Pawn EventInstigator, vector HitLoc, vector Momentum, name DamageType, int joint)
{
if (DamageType == 'fire')
SetOnFire(EventInstigator,joint);
return Super.JointDamaged(Damage,EventInstigator,HitLoc,Momentum,DamageType,joint);
}
function ZoneChange(ZoneInfo newZone)
{
local int i;
if(newZone.bWaterZone)
{
for (i=0; i<16; i++)
SkelGroupSkins[i] = Default.SkelGroupSkins[i]; // Force the weapon to use the default skin
SetDefaultPolygroups();
if (bPoweredUp)
PowerupEnd();
}
// Since there is no 'LavaZone' I get to use a cheap hack.
if (newZone.DamagePerSec > 0)
SetOnFire(None,0);
}
// Light this sucker.
function SetOnFire(Pawn EventInstigator, int joint)
{
local PawnFire F;
if (!bFuseLit)
{
bFuseLit = True;
Switch(GrenadeType)
{
case GNoFuse:
TimeToBlow = 0;
break;
case GShortFuse:
TimeToBlow *= 0.5;
break;
case GLongfuse:
TimeToBlow *= 2;
break;
case GDud:
bFuseLit = False;
FuseTimer = 0;
break;
default:
break;
}
}
}
Simulated Function Tick(Float DeltaTime)
{
if (bFuseLit && !IsInState('Sleeping'))
{
FuseTimer += DeltaTime;
if (FuseTimer >= TimeToBlow)
{
// Explosion Code.
Spawn(class'GrenadeBlastRadius',Self,,Location,RotRand(True));
Spawn(class'GrenadeBlastRadius',Self,,Location,RotRand(True));
HurtRadiusAll(0,320,'sever',GrenMomentum/2,Location);
HurtRadiusLimbs(120,320,'sever',0,Location);
HurtRadiusAll(45,320,'sever',0,Location);
HurtRadiusAll(0,320,'sever',GrenMomentum/2,Location);
// DoRadiusEffect();
PowerupEndingPulseOn();
if (Level.Game.ShouldRespawn(self))
{
FuseTimer = 0.0;
bFuseLit = False;
GoToState('Sleeping');
}
else
Destroy();
}
}
Super.Tick(DeltaTime);
}
function PowerupEndingPulseOn()
{
PlaySound(ExplodeSound,SLOT_Talk,255,True,3200,0.85 + FRand()*0.3);
}
//
// Hurt actors within the radius.
//
final function HurtRadiusAll( float DamageAmount, float DamageRadius, name DamageType, float Momentum, vector HitLocation )
{
local actor Victim;
local float damageScale, dist;
local vector dir;
local int bp;
local bool bHadLimb;
foreach VisibleCollidingActors( class 'Actor', Victim, DamageRadius, HitLocation )
{
if( Victim != self)
{
dir = Victim.Location - HitLocation;
dist = FMax(1,VSize(dir));
dir = dir/dist;
damageScale = 1 - FMax(0,(dist - Victim.CollisionRadius)/DamageRadius);
if (Victim.Skeletal != None && Victim.DrawType == DT_SkeletalMesh)
bp = Victim.BodyPartForJoint(Victim.ClosestJointTo(HitLocation));
else
bp = 0;
if (Pawn(Victim) != None && Pawn(Victim).BodyPartSeverable(bp))
bHadLimb = (Pawn(Victim).BodyPartHealth[bp] > 0);
Victim.AddVelocity(damageScale * Momentum * dir);
if (Pawn(Victim) != None && bHadLimb && Pawn(Victim).BodyPartSeverable(bp))
{
Pawn(Victim).BodyPartHealth[bp] -= damageScale * DamageAmount;
if (Pawn(Victim).BodyPartHealth[bp] < 1)
{
Pawn(Victim).BodyPartVisibility(bp, false);
Pawn(Victim).BodyPartCollision(bp, false);
Pawn(Victim).LimbSevered(bp, (damageScale * Momentum * dir));
}
}
Victim.JointDamaged(damageScale * DamageAmount,
Instigator,
Victim.Location - 0.5 * (Victim.CollisionHeight + Victim.CollisionRadius) * dir,
(damageScale * Momentum * dir),
DamageType,
0);
}
}
}
//
// Hurt actors within the radius.
// This deals the damage once to each of their limbs, so it deals triple damage.
//
// This function assumes that all Pawns have skeletal meshes.
final function HurtRadiusLimbs( float DamageAmount, float DamageRadius, name DamageType, float Momentum, vector HitLocation )
{
local actor Victim;
local float damageScale, dist;
local vector dir;
local int bp;
local bool bHadLimb;
foreach VisibleCollidingActors( class 'Actor', Victim, DamageRadius, HitLocation )
{
if( Victim != self)
{
dir = Victim.Location - HitLocation;
dist = FMax(1,VSize(dir));
dir = dir/dist;
damageScale = 1 - FMax(0,(dist - Victim.CollisionRadius)/DamageRadius);
bp = BODYPART_LARM1;
if (Pawn(Victim) != None && Pawn(Victim).BodyPartSeverable(bp))
bHadLimb = (Pawn(Victim).BodyPartHealth[bp] > 0);
if (Pawn(Victim) != None && bHadLimb && Pawn(Victim).BodyPartSeverable(bp))
{
Pawn(Victim).BodyPartHealth[bp] -= damageScale * DamageAmount;
if (Pawn(Victim).BodyPartHealth[bp] < 1)
{
Pawn(Victim).BodyPartVisibility(bp, false);
Pawn(Victim).BodyPartCollision(bp, false);
Pawn(Victim).LimbSevered(bp, (damageScale * Momentum * dir));
}
}
bp = BODYPART_RARM1;
if (Pawn(Victim) != None && Pawn(Victim).BodyPartSeverable(bp))
bHadLimb = (Pawn(Victim).BodyPartHealth[bp] > 0);
if (Pawn(Victim) != None && bHadLimb && Pawn(Victim).BodyPartSeverable(bp))
{
Pawn(Victim).BodyPartHealth[bp] -= damageScale * DamageAmount;
if (Pawn(Victim).BodyPartHealth[bp] < 1)
{
Pawn(Victim).BodyPartVisibility(bp, false);
Pawn(Victim).BodyPartCollision(bp, false);
Pawn(Victim).LimbSevered(bp, (damageScale * Momentum * dir));
}
}
bp = BODYPART_HEAD;
if (Pawn(Victim) != None && Pawn(Victim).BodyPartSeverable(bp))
bHadLimb = (Pawn(Victim).BodyPartHealth[bp] > 0);
if (Pawn(Victim) != None && bHadLimb && Pawn(Victim).BodyPartSeverable(bp))
{
Pawn(Victim).BodyPartHealth[bp] -= damageScale * DamageAmount;
if (Pawn(Victim).BodyPartHealth[bp] < 1)
{
Pawn(Victim).BodyPartVisibility(bp, false);
Pawn(Victim).BodyPartCollision(bp, false);
Pawn(Victim).LimbSevered(bp, (damageScale * Momentum * dir));
}
}
Victim.JointDamaged(damageScale * DamageAmount,
Instigator,
Victim.Location - 0.5 * (Victim.CollisionHeight + Victim.CollisionRadius) * dir,
(damageScale * Momentum * dir),
DamageType,
0);
Victim.JointDamaged(damageScale * DamageAmount,
Instigator,
Victim.Location - 0.5 * (Victim.CollisionHeight + Victim.CollisionRadius) * dir,
(damageScale * Momentum * dir),
DamageType,
0);
Victim.JointDamaged(damageScale * DamageAmount,
Instigator,
Victim.Location - 0.5 * (Victim.CollisionHeight + Victim.CollisionRadius) * dir,
(damageScale * Momentum * dir),
DamageType,
0);
}
}
}
function DoRadiusEffect()
{
local actor A;
local int i;
local bool bCollisionJoints;
local float dist,damageScale;
local vector dir;
foreach VisibleCollidingActors(class'actor', A, 320, Location)
{
if (A != None && A != self && !A.bHidden
&& (A.IsA('Carcass') || A.IsA('Pawn')))
{
if (A.IsA('Carcass'))
{
dir = A.Location - Location;
dist = FMax(1,VSize(dir));
dir = dir/dist;
damageScale = 1 - FMax(0,(dist - A.CollisionRadius)/320);
A.AddVelocity(damageScale * GrenMomentum * dir);
}
if (A.IsA('Pawn'))
{
// Set on fire
Pawn(A).PowerupBlaze(Pawn(Owner));
// Do some damage
A.JointDamaged(5, Pawn(Owner), A.Location, Normal(A.Location-Location)*50, 'fire', 0);
}
}
}
}
= >0 ' .‚›% 9 z//=============================================================================
// GrenadeBlastRadius.
//=============================================================================
class GrenadeBlastRadius expands BlastRadius;
simulated function Spawned()
{
TimePassed=0.0;
ScaleGlow = EffectTime;
} € á S1//=============================================================================
// FubarGrenade.
//=============================================================================
class FubarGrenade expands Grenade;
Simulated Function Tick(Float DeltaTime)
{
if (bFuseLit && !IsInState('Sleeping'))
{
FuseTimer += DeltaTime;
if (FuseTimer >= TimeToBlow)
{
// Explosion Code.
Spawn(class'GrenadeBlastRadius',Self,,Location,RotRand(True));
Spawn(class'GrenadeBlastRadius',Self,,Location,RotRand(True));
HurtRadiusLimbsNoDmg(120,320,'sever',0,Location);
HurtRadiusAll(0,320,'sever',GrenMomentum,Location);
// DoRadiusEffect();
PowerupEndingPulseOn();
if (Level.Game.ShouldRespawn(self))
{
FuseTimer = 0.0;
bFuseLit = False;
GoToState('Sleeping');
}
else
Destroy();
}
}
Super(NonStow).Tick(DeltaTime);
}
//
// Hurt actors within the radius.
// This deals damage to limbs, but not to health.
//
final function HurtRadiusLimbsNoDmg( float DamageAmount, float DamageRadius, name DamageType, float Momentum, vector HitLocation )
{
local actor Victim;
local float damageScale, dist;
local vector dir;
local int bp;
local bool bHadLimb;
foreach VisibleCollidingActors( class 'Actor', Victim, DamageRadius, HitLocation )
{
if( Victim != self)
{
dir = Victim.Location - HitLocation;
dist = FMax(1,VSize(dir));
dir = dir/dist;
damageScale = 1 - FMax(0,(dist - Victim.CollisionRadius)/DamageRadius);
bp = BODYPART_LARM1;
if (Pawn(Victim) != None && Pawn(Victim).BodyPartSeverable(bp))
bHadLimb = (Pawn(Victim).BodyPartHealth[bp] > 0);
if (Pawn(Victim) != None && bHadLimb && Pawn(Victim).BodyPartSeverable(bp))
{
Pawn(Victim).BodyPartHealth[bp] -= damageScale * DamageAmount;
if (Pawn(Victim).BodyPartHealth[bp] < 1)
{
Pawn(Victim).BodyPartVisibility(bp, false);
Pawn(Victim).BodyPartCollision(bp, false);
Pawn(Victim).LimbSevered(bp, (damageScale * Momentum * dir));
}
}
bp = BODYPART_RARM1;
if (Pawn(Victim) != None && Pawn(Victim).BodyPartSeverable(bp))
bHadLimb = (Pawn(Victim).BodyPartHealth[bp] > 0);
if (Pawn(Victim) != None && bHadLimb && Pawn(Victim).BodyPartSeverable(bp))
{
Pawn(Victim).BodyPartHealth[bp] -= damageScale * DamageAmount;
if (Pawn(Victim).BodyPartHealth[bp] < 1)
{
Pawn(Victim).BodyPartVisibility(bp, false);
Pawn(Victim).BodyPartCollision(bp, false);
Pawn(Victim).LimbSevered(bp, (damageScale * Momentum * dir));
}
}
bp = BODYPART_HEAD;
if (Pawn(Victim) != None && Pawn(Victim).BodyPartSeverable(bp))
bHadLimb = (Pawn(Victim).BodyPartHealth[bp] > 0);
if (Pawn(Victim) != None && bHadLimb && Pawn(Victim).BodyPartSeverable(bp))
{
Pawn(Victim).BodyPartHealth[bp] -= damageScale * DamageAmount;
if (Pawn(Victim).BodyPartHealth[bp] < 1)
{
Pawn(Victim).BodyPartVisibility(bp, false);
Pawn(Victim).BodyPartCollision(bp, false);
Pawn(Victim).LimbSevered(bp, (damageScale * Momentum * dir));
}
}
}
}
}