Make a Shotgun
by Postal
//
This is designed to be a simple
method to make a shotgun, instead of reading through the whole of
Windex's irc log 3, but I do suggest that you read through the whole
log, it includes many things not in this short tutorial. The log can
be found at www.PlanetUnreal.com/WoD
//
Tutorial based on an irc chat lesson
by Windex. Also thanks to the myriads of people in that chat,
who talked so much that I could not edit it all out, and had to
rewrite the whole thing.
//
You ready to make a weapon of
destruction?
We are going to make a shotgun
capable of loading up multiple shells with alt fire, sort of like
how you can load up multiple rockets in the eightball, but not
quite.
We could make a shotgun that shoots
grenades in alt, or nuclear missiles, or black holes, or what ever
you can want, but not today.
Now this shot gun we are going to
make in primary fires one shell just like a normal shot gun, but
with alt fire you can load up more shells to fire in primary. So you
hit alt fire once you now will shoot *two* shells at once instead of
just one. This will have a maximum of 4.
//Note: About 30 pages of how a real
shotgun works in comparison to this game one was edited out here,
please send thanks in cash to Postal. :)
Ok Open up unrealed, henceforth
refereed to as ued, you should have at least UT version 436, but
this should work with all UT versions, and if not for a few of my
changes, all the unreal versions. We will be use ued 2.0, which will
deprive us of the old joys of ued 1.0 crashing and losing lots of
work.
Open the actor browser (view-actor
class browser) open up inventory, then weapon. Double click on
flakcannon to open it, minimize the window that opens up. Then
double clicks on automag, and minimizes that same window that popped
back up.
Now click on the weapon class to
highlight it the right click, click new. Package is what the *.u
file will be named, and name is what the thing you are making is
named. Type in MyMod for Package, and Shotgun for name and hit ok.
Maximize the window that pops up now. This is where you will edit
code.
On the left you will see a list of
the classes you have open, there will be automag, flakcannon, and
shotgun, you can switch between them by double clicking on those,
now double click on flakcannon. Find function fire can copy the
whole thing in to you shotgun. Do the same with function AltFire,
and state normal fire, and function PlayPostSelect. Now you can
close the flak cannon class by double clicking on it and hitting the
little icon all the way on the left of that bar on top. Now copy the
ProcessTraceHit function out of the automag into you shotgun
and
the automag.
//Warning Boring Part
You probably wonder what all that stuff
is, even if you don't here what it does, function fire and alt fire
tell the computer what to do ever time you pull the trigger *ahem*
click the mouse, the state of normal fire is used by function fire
for other parts of the firing process, there is a state altfiring,
but we are not using that. function PlayPostSelect is what the gun does when you
select it in the game, its that animation of it coming up and sounds
and so on.
Now for ProcessTraceHit, this has the computer make a line coming from where it was specified to start and until it hits something, well actually that's trace, but this is what effects are made where the trace hits, and so on.
//End boring part (be happy that was
not about 10 pages long like in original)
Back to code, delete everything in
the state normal fire except the begin so it looks like:
state
NormalFire
{
Begin:
}
Why?
Because we don't need any of that. Now look in the function fire,
you will see an if statement saying "if
(AmmoType.UseAmmo(1))" an { and a
lot of stuff then another } cut
everything inside that except for the GoToState('NormalFire'); and move it behind the
begin in the start NormalFire. All right now place before the
begin in the state normal fire "ignoresFire,
AltFire;" (minus the quotes) this keeps things from being
messed up by function fire and alt fire (tsk, tsk, tsk, no reloading
when shooting).
//Note if you copy and paste you may need to refresh the actor class browser by double click on the name of the class in that left column. OK we can clean up function fire to be only:
function Fire(
float Value )
{
if (AmmoType.UseAmmo(1))
{
GoToState('NormalFire');
}
}
Since
we are going to have more then one-shotgun shell, we are going to
need to keep track of them, so we make it a variable. add var int LoadCount; after the "class shotgun expands Weapon;"
Now we
don't need anything in the function alt fire that's currently there,
so we are going to remove it all, make you alt fire look like
this:
function AltFire( float Value
)
{
if (AmmoType.UseAmmo(1))
{
}
}
Now... Within that if/then we want to
put code to increment the LoadCount var every time someone presses
alt-fire but only up to 4, after 4, we want the gun to fire instead
of loading more.
So... in the ammotype if/then... we put
this code:
if (LoadCount <
4)
{
LoadCount++;
}
But
we don't want to load up to many shells so it end up
like:
function AltFire( float Value
)
{
if (AmmoType.UseAmmo(1))
{
if (LoadCount<=3)
{
LoadCount++;
GoToState('reload');
}
else
GoToState('NormalFire');
}
}
you
are probable wondering where the GoToState('Reload") came from, we what the gun
to look like it adding a shell, so that make its look like its
reloading. Thing is we need to make a state reload.
So... make a new state called "Reload" like this:
state Reload
{
Begin:
}
First
make it ignore fire and AltFire... Because we don't want to be able
to fire while the gun is cocking. :) Then... add this block of
code after the begin:
FinishAnim();
PlayAnim( 'Reload', 1.2, 0.05);
Owner.PlaySound(CockingSound,
SLOT_None,0.6*Pawn(Owner).SoundDampening);
FinishAnim();
PlayAnim( 'Fire', 1.2, 0.05);
FinishAnim();
Finish();
So it becomes:
state
Reload
{
ignores Fire, AltFire;
Begin:
FinishAnim();
PlayAnim( 'Reload', 1.2, 0.05);
Owner.PlaySound(CockingSound,
SLOT_None,0.6*Pawn(Owner).SoundDampening);
FinishAnim();
PlayAnim( 'Fire', 1.2, 0.05);
FinishAnim();
Finish();
}
Now
you are probable wondering what some of that means, well. .
.
FinishAnim() pauses execution until after the current animation is finished playing... So you don't start playing one animation in the middle of another.
PlayAnim()...
Well... Plays an animation... The first parameter is the name
of the animation.. Second and third have to do with speed and
framerates... I usually
just leave them alone... :)
PlaySound... Well... Plays a sound the SLOT has to do with where the sound is being played from...
SLOT_None is fine for our purposes :)
0.6*Pawn(Owner) is volume control and we play
FireAnim during reload because of a glitch in the mesh... The
reload animation ends on an odd frame... It leaves the
gun
sticking at an odd angle so the fire animation is played to
leave the gun in the right position.
Now let's modify the
PlayPostSelect function , since we are
using a different
mesh we need different code, place this in
replacement:
PlayAnim('Reload', 1.3,
0.05);
GoToState('ResetPos');
So... Now we have to make a ResetPos
state...
which should look like this:
state ResetPos
{
Begin:
FinishAnim();
PlayAnim('Fire', 0.9, 0.05);
Finish();
}
So when is PlayPostSelect called?
PlayPostSelect() is called just after the
weapon is brought up automatically. So that happens after
every time the weapon is brought up... So it is only going to
run ResetPos once every time you switch
to it.
Now go to the state normal fire and delete everything
between owner.makenoise
and PlayAnim
AdjustedAim = pawn(owner).AdjustAim(AltProjectileSpeed, Start, AimError,
True, bWarnTarget);
GetAxes(AdjustedAim,X,Y,Z);
Spawn(class'WeaponLight',,'',Start+X*20,rot(0,0,0));
Start = Start + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z *
Z;
Spawn( class 'MasterChunk',, '', Start, AdjustedAim);
Spawn( class 'Chunk2',, '', Start - Z, AdjustedAim);
Spawn( class 'Chunk3',, '', Start + 2 * Y + Z, AdjustedAim);
Spawn( class 'Chunk4',, '', Start - Y, AdjustedAim);
Spawn( class 'Chunk1',, '', Start + 2 * Y - Z, AdjustedAim);
Spawn( class 'Chunk2',, '', Start, AdjustedAim);
Spawn( class 'Chunk3',, '', Start + Y - Z, AdjustedAim);
Spawn( class 'Chunk4',, '', Start + 2 * Y + Z, AdjustedAim);
Gone so you have left:
state NormalFire
{
ignores Fire, AltFire;
Begin:
CheckVisibility();
bPointing=True;
Start = Owner.Location + CalcDrawOffset();
if ( PlayerPawn(Owner) != None )
{
PlayerPawn(Owner).ClientInstantFlash( -0.4, vect(650, 450, 190));
PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
}
Owner.MakeNoise(2.0 * Pawn(Owner).SoundDampening);
PlayAnim( 'Fire', 0.9, 0.05);
Owner.PlaySound(FireSound, SLOT_None,Pawn(Owner).SoundDampening*4.0);
}
We are now going to make the code that
makes the gunfire.
We are going to use to loops so go place
these variables in under where we place them first:
Var Int Loads;
Var Int Shots;
Now add this to the fire
code:
for(loads=0;loads {
for(shots=0;shots<10;shots++)
{
TraceFire(1.7);
}
}
This shoots 10 shots for each shell
loaded the TraceFire(1.7); tell the gun
to shoot a round randomly with in its designated radius of 1.7, a
larger number would be less accurate and 0 would be right on the dot
now add this at the end the state before the last }
LoadCount=1;
GoToState('reload');
Finish();
That preps the gun for the next round. Now for the last few parts. got to ProcessTraceHit. replace WallHitEffect with UT_LightWallHitEffect so it leaves bullet holds decals. and replace hitdamage with 5 so it does 5 damage per pellet.
Now go to normal fire and remove the line:
Start = Owner.Location + CalcDrawOffset();
Now compile it, hit the icon second to the left on that top bar of the window, there should be no errors.
Now minimize that window and go back to the actor classes window, right click on shotgun and click default properties.
Expand weapon and in ammo name type in flakammo, it should then change to Class'Botpack.FlakAmmo' close weapon and go to display and go to mesh and change that to LodMesh'UnrealI.QuadShotHeld' and close display. Open up inventory and place in pick up view mesh LodMesh'UnrealI.QuadShotHeld' place in third person mesh and player view mesh LodMesh'UnrealI.QuadShotHeld' now expand playerview offest and change x to 20, y to -10 and z to -20 change player view scale and thirdpersonscale to .7 Also look for the pickupammocount and change that to 20
Now exit out of the shotgun default properties, and in the actor class browser go down to the bottom and click the box MyMod, go to file and hit save selected packages, that saves your work, now exit out and get into UT, in game activate cheats and type in summon mymod.shotgun
Have fun!
Note: there are still many bugs and little details like no firing sound, but you now have a working weapon you can perfect.