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.