This is a pretty straightforward mod that creates a smoke
grenade class, a subclass of grenade, and a very slightly modified new
eightball class, subclassed from the original eightball. The SmokeGrenade
will be launched from the modified eightball in the same manner a normal
eightball fires the normal grenade.
The SmokeGrenade's life is a
little longer than the normal grenade. It causes no damage, and doesn't
bounce around. It emits a cloud of smoke (which is configurable in many
areas) that lingers above the grenade until it runs out.
This is
an updated version to my old SmokeGrenade, which had some unnecessary
elements. This one also looks better.
There are two new classes
that you will need to make. The first class is the SmokeGrenade, which
will be a subclass of the standard Eightball's grenade. The next class
will be the SmokeGun, which obviously is a subclass of the Eightball.
//==================================================
// SmokeGrenade by Zarniwoop.
//==================================================
//
// Note that some settings here can cause pretty big lag issues-
// puffsize, etc combined with the number of people using the grenades
// could cause some real lag disasters (I'm guessing). So be careful
// how you set it and be sure to test it out with different settings
// for performance.
#exec AUDIO IMPORT FILE="Sounds\Pupae\hiss1.WAV" NAME="hiss1pp" GROUP="SmokeGrenade"
class SmokeGrenade expands Grenade;
// These variables control the settings for the smoke that the
// grenade spews. All can be set in the smoke grenade's default
// property setup.
var() float SmokeSpeed;
var() float SmokeRate;
var() Vector SmokeAccel;
var() float SmokeDelay;
var() float SmokeDelayVariance;
var() float SpeedVariance;
var() float BasePuffSize; // Size of cloud
var() float SizeVariance;
// This is (to start) a fuction of the parent grenade class, but
// see changes below.
function PostBeginPlay()
{
local vector X,Y,Z;
local rotator RandRot;
Super.PostBeginPlay();
PlayAnim('WingIn');
GetAxes(Instigator.ViewRotation,X,Y,Z);
Velocity = X * (Instigator.Velocity Dot
X)*0.4+Vector(Rotation)*Speed+FRand()*100*Vector(Rotation);
Velocity.z += 210;
// Different timer setting- you want these lasting longer than a
// regular explosive grenade.. Adjust here for longer/shorter
// durations.
SetTimer(5+FRand()*0.5,false);
RandRot.Pitch = FRand() * 1400 -700;
RandRot.Yaw = FRand() * 1400 - 700;
RandRot.Roll = FRand() * 1400 - 700;
MaxSpeed = 1000;
Velocity = Velocity >> RandRot;
RandSpin(50000);
bCanHitOwner = False;
}
// Differs from the parent class in that timer is started here.
function BeginPlay()
{
// Start the timer
Enable('Timer');
SmokeRate = 0.03;
}
// Here is where the smoke effect is generated in the grenade.
// See comments below.
simulated function Tick(float DeltaTime)
{
// Define the RisingSmoke (white)
local RisingSpriteSmokePuff b;
// Define the BlackSmoke (black (doh!))
local BlackSmoke p;
// Start creating the white cloudy smoke effect now
b = Spawn(class'RisingSpriteSmokePuff');
b.DrawScale = BasePuffSize+FRand()*SizeVariance*5;
// Set the smoke's acceleration
b.Acceleration = SmokeAccel;
// Timer for grenade smoke effect
Count += DeltaTime;
if ( (Count>Frand()*SmokeRate+SmokeRate+
NumExtraGrenades*10.03) &&
(Level.NetMode!=NM_DedicatedServer) )
{
// Randomly generate some black smoke
// If there's lag, tweak it or remove altogether
if (FRand() < 0.5)
{
p = Spawn(class'BlackSmoke');
p.RemoteRole = ROLE_None;
Count=0;
}
// No black smoke, but reset anyway
else
Count=0;
}
}
// This changes the parent ProcessTouch so nothing will
// occur if the SmokeGrenade hits someone, rather than causing
// the grenade to explode.
function ProcessTouch( actor Other, vector HitNormal )
{
HitWall( HitNormal, None );
}
// This is a modified version of the grenade's HitWall function.
// These grenades don't bounce, but if one hits a wall you don't
// want it to just stick there- it needs to fall.
simulated function HitWall( vector HitNormal, actor Wall )
{
bCanHitOwner = False;
Velocity = 0.8*(( Velocity dot HitNormal )*HitNormal*(-2.0)+Velocity);
RandSpin(100000);
speed = VSize(Velocity);
PlaySound(ImpactSound, SLOT_Misc, FMax(0.5, speed/800) );
SetPhysics(PHYS_Falling);
}
// The SmokeGrenade doesn't actually explode- instead the smoke
// dissipates and the grenade disappears in a red sort of explosion.
// See the comments below about adding damage to this "explosion."
function Explosion(vector HitLocation)
{
PlaySound(SpawnSound);
// Want to cause some damage to anyone nearby when the grenade dies?
// Uncomment the next line, and you may want to lower damage.
// HurtRadius(damage, 200, 'exploded', MomentumTransfer, HitLocation);
// Create a fancy red burst when it "explodes"
Spawn(class'SpriteRedE',,,HitLocation);
Destroy();
}
Ok, now that you've gotten this far, it's time to add the
SmokeGun. Make it a subclass of the Eightball. The changes to make here
are so simple that I'm not including the whole SmokeGun script, and will
instead only show you what to change.
First, create the new class
under the Eightball. Then go to the Eightball script and copy these two
things:
Function PreBeginPlay() and state FireRockets
This turns out to be the majority of the original
Eightball's script. Now all you have to do is change the occurances of
'Grenade' to 'SmokeGrenade'. You'll have to change three of them - two in
PreBeginPlay() and one near the end of state FireRockets (you can easily
do a search for 'Grenade' to find it if you're having trouble).
Now you should be able to go try out the SmokeGrenade and
experiment. There's a lot of things that you can do with these, as far as
effects go.
|