Post tutorial Report RSS Coding Tutorial 4: Basic Weapon Changes

Tutorials using Unreal Script specific to POSTAL 2.

Posted by on - Advanced Client Side Coding

Tutorial originally released on Running With Scissor's Postal website. Was taken down more than 10 years ago. Mirrored here for archival purposes.

Basic Weapon Changes

In POSTAL 2

Code Tutorial 4

You must be running the new Share the Pain version of POSTAL 2 for any of this to be relevant. Using these tutorials with older code may cause you problems.

These tutorials are to be completed in succession with one another. If you jump ahead to a later tutorial, I will be discussing things from earlier tutorials that you may not recognize. Following each one in order should greatly improve your learning experience.

This tutorial will take you through making a new weapon by extending an old weapon. It’s going to use all the textures, models, animations from POSTAL 2—no new art is expected to be done for this. Because of this, it’s going to be pretty goofy. As a programmer, I’m simply doing the programming. Hopefully you’ll be able to find a friend to flesh out the visuals later.

While this will be a fairly basic weapon, it will reach into many concepts in the engine and require a lot of changes.

The new, imaginary weapon to be completed here is the Party Bomb. Yeah, sounds silly, and surely will be, but hey, I just thought of it as a simple means to explain a lot of stuff about weapons in POSTAL 2/Unreal with a fun result.

More than likely the best way to make a new weapon is to extend an old one already there. I even did that when making the WMD or Plague weapon created for the 1337 patch. That simply shoots rockets. But if you think about it, it shoots much more like the Napalm launcher than it did the actual Rocket launcher. Because of this, I extended it from the NapalmWeapon.uc instead. This may not sound right, but from a code/gameplay standpoint is makes more sense. This is the sort of thing you must carefully consider when thinking about a new weapon. What gameplay does it match most closely?

Another thing to know, especially with the release of the MP patch, is that factoring in multiplayer code adds a huge amount of complexity to the already difficult to understand weapon code. Making a weapon work for single player—making any code work for SP for that matter—is much easier than making it work in multiplayer. We’ll be making this new weapon for single-player only.

Considering the Party Bomb, I imagine it being charged and thrown much like the grenades. It wouldn’t be thrown instantly like the scissors. I’m not positive if I’d like to give it an alt-fire yet, but I know I’d like the primary fire to simply charge and throw.

The bomb that is thrown would act more like a Molotov cocktail, in that it would explode on impact, throwing Party all around and doing explosive damage to things around it. This is an odd mix of functionality. We’ll probably use the weapon parent class the most so we’ll base most of our code off it. With this in mind we will use the GrenadeWeapon.uc as a parent class and work from there.

Unreal Weapon Basics:

Engine.Weapon>Postal2Game.P2Weapon> Inventory.GrenadeWeapon

This is the basic hierarchy. This weapon is the weapon that is held in your Inventory variable by your Pawn. It’s your first-person weapon. Visually you need a first-person mesh and animation (as opposed to a non-animating static mesh model).

Engine.Pickup> Engine.WeaponPickup> Postal2Game.P2WeaponPickup> Inventory.GrenadePickup

This is the actor that gets placed in a level to be gotten by the player walking around. It will create in the player pawn’s Inventory the actual GrenadeWeapon actor. Visually you need a third-person static mesh.

Engine.InventoryAttachment> Engine.WeaponAttachment> Postal2Game.P2WeaponAttachment> Inventory.GrenadeAttachment

This is the third person thing you see in a person’s hand, like when an NPC’s is going to throw a grenade at you, or when you’re looking at yourself in the mirror seeing a grenade in the Dude’s hand. You need a separate static mesh to represent this. The reason you don’t generally want to use the same static mesh as the pickup is because you may want to orient it separately and scale it differently, also you may put lower amounts of geometry/lower res textures on one vs. the other.

Engine.Ammunition> Postal2Game.P2AmmoInv> Inventory.GrenadeAmmoInv

AmmoInv is the ammunition used by the Weapon itself in the Pawn’s Inventory. You never see this ammo in the game, physically, but it is used to damage things and keep track of the grenades/bullets left to shoot.

Engine.Ammo> Postal2Game.P2AmmoPickup

AmmoPickup is the ammunition placed around the level when you want a gun to get more bullets, but not the weapon itself. I positively hate the naming convention for ‘ammunition’ and ‘ammo’ and as such, changed it to AmmoInv and AmmoPickup for POSTAL 2 to make it a little clearer. Unfortunately for this actor grenades were a bad example because there is no AmmoPickup for these. When you pick up the GrenadePickup you get the AmmoInv and the Weapon (so there is no need to get ammo for grenades separately). Only our guns use this class, so there is a PistolAmmoPickup to look at for reference.. That is a separate static mesh of a gun clip that only gives you more bullets—not the weapon itself.

Engine.Projectile> Postal2Game.P2Projectile> Inventory.GrenadeProjectile

This is the object thrown by the weapon. Gun weapons in POSTAL 2 generally don’t have this class. The grenade/Molotov/scissors do. It could potentially use a third static mesh, but instead for the grenade, we use the same one as the pickup.

Starting the First Person Weapon

Now that we have those ideas in our brains, let’s see what we need to make for our Party Bomb. As I mentioned before, I’m simply using items and weapon animations from the game as it is. Therefore, the first-person weapon animation I’ll keep as a grenade, yet it will throw a ‘wrapped gift’ as the actual bomb. If this were for real, I’d have someone make me the necessary first-person animations that mimic the grenade weapon but with the gift in the guy’s hands. Yes, with the grenade in the guy’s hand in first-person this won’t look as cool, but mine is not to explain how to animate and make models. I’m trying to get everything else across to you. And keep in mind that you will be able to do all I’m explaining right now, with the POSTAL 2 assets you started with.

Let’s get started by copying Inventory\Classes\GrenadeWeapon.uc over to SuperPack\Classes.

Rename the file to PartyWeapon.uc.

Open the file. As before, we need to strip most of it out, but some things we will keep. Change the class definition from this:

class GrenadeWeapon extends P2Weapon;

to this:

classPartyWeapon extends GrenadeWeapon;

We want to keep the default properties at the bottom. Everything else in between is functions and states for the weapon itself. What we want to change is that it throws our new PartyProjectile (no, you’re not dreaming, we haven’t made that yet, but we will) instead of the ‘GrenadeProjectile’. ThrowGrenade is the function that does the work. It’s called by another function called Notify_ThrowGrenade. This function is an ‘animation notification’.

Sidebar

At this point, unless you’re completely familiar with Unreal and anim notifies, I’d suggest you fire up PostEd.

Click on the big A at the top to bring up the animations in the viewer.

Go to File::Open and open the MP_Weapons.ukx package.

Where it says MP_LS_Baton, click that and find MP_LS_Grenade.

Select the ‘Shoot1’ animation. Play it with the little VCR controls at the bottom of the window (making it loop also, will make it easier to examine so you don’t have to keep playing it).

As it plays, look at the bottom where the scrubber is moving to the right, showing the passage of time as the arm throws the grenade. There is a small black mark on the far left—the start, and a small black mark at the far right—the end. Also, a little to the left of the middle is another black mark. This is an animation notify added by the animator in the editor. If you go to the upper right and click on Notify, you can eventually open up a few blocks there to show that the NotifyName it’s using is ‘Notify_ThrowGrenade’. This causes the grenade to only get thrown when we want it to—not necessarily right as soon as the animation starts. This makes it look better in the end, and tells the code when to make a grenade projectile.

Close the editor and let’s get back to the code!

End Sidebar

Inside our new PartyWeapon.uc we want to keep three groups of code:

  1. The class definition at the top
  2. The function ThrowGrenade
  3. The default properties at the bottom

The important thing is we need to replace what projectile this weapon throws.

Let’s go into ThrowGrenade and change the projectile line for primary firing from this:

gren = spawn(class'GrenadeProjectile',Instigator,,StartTrace, AdjustedAim);

to this:

gren = spawn(class'PartyProjectile',Instigator,,StartTrace, AdjustedAim);

The only thing we changed was the class name in the spawn function. We can keep the variable ‘gren’ which is a GrenadeProjectile because we will simply extend PartyProjectile from GrenadeProjectile. Even the part about spawning a ‘GrenadeAltProjectile’ is fine, because we’ll be turning off the alt-firing functionality.

Our next order of business is basically changing all occurrences of ‘grenade’ to the ‘Party’ versions in our default properties.

The first group should be near the top of the default properties:

ItemName="Grenade"

AmmoName=class'GrenadeAmmoInv'

PickupClass=class'GrenadePickup'

AttachmentClass=class'GrenadeAttachment'

They should be changed to :

ItemName="Party"

AmmoName=class'PartyAmmoInv'

PickupClass=class'PartyPickup'

AttachmentClass=class'PartyAttachment'

No, we don’t have all those classes yet, but we’ll make them soon.

The mesh we’ll leave alone. This is the first-person model and animation for our grenade weapon. Like I stated earlier, if I had someone make me a Party bomb mesh and animation for first-person I would change this line to point to my new package. But as it is, we’re leaving it like this:

Mesh=Mesh'MP_Weapons.MP_LS_Grenade'

Next change this:

FirstPersonMeshSuffix="Grenade"

To this:

FirstPersonMeshSuffix="Party"

This next group we’ll leave also. They control the animations in third-person for how the weapon is shot. Picking an already existing weapon in POSTAL 2 to be the basis for your weapon eliminates a lot of extra work. Because our Party bomb is to be thrown the same way, we can leave these along. Do searches on WEAPONHOLDSTYLE_Toss to see how it’s used and what other options there are. Look at other weapon’s styles and see what they look like in the game to know.

holdstyle=WEAPONHOLDSTYLE_Toss

switchstyle=WEAPONHOLDSTYLE_Toss

firingstyle=WEAPONHOLDSTYLE_Toss

A little further down is a group we will change. These variables control where in your weapon line-up your weapon will appear.

Make these two the same:

AutoSwitchPriority=6

InventoryGroup=6

This means it will be bound to the 6 key, and it will come after the gasoline/matches group but before the cowhead group. I’m going to leave it the same because it makes sense to me to have this bomb be grouped with the other throwing weapons.

This though must be changed:

GroupOffset=1

This means that the grenades come first within this subgroup. That’s fine, but for our weapon, I want to put it last. You’ll recall that the order is Grenades, Molotovs, Scissors. I will make my new weapon last in this list. Therefore, I’ll change the GroupOffset as such to this:

GroupOffset=4

When I finally pick up my weapon and scroll to it, it should come after Scissors and before the Cowhead.

Next we’ll change

bUsesAltFire=true

to

bUsesAltFire=false

Our weapon doesn’t use an alt-fire so we’ll block that with this variable.

The only other untidiness is at the end. Let’s change the alt-fire hints from this:

AltHint1="Secondary Fire(Right Mouse Button) to"

AltHint2="place unarmed grenades."

To this:

AltHint1=" "

AltHint2=" "

There are several other variables listed in between like bThrownByFiring and ChargeTimeModifier that you may be confused or interested in. I’d suggest doing a search on those in P2Weapon or GrenadeWeapon and reading the comments next to their definitions. Also, try to follow their usage in the code to get a better understanding those sorts of variables.

Our weapon is now ready to go, but it won’t compile correctly. We need all the other supporting files, so let’s quickly flesh those out.

Adding Supporting Files

We’ll be adding the following files next:

PartyAmmoInv.uc

PartyPickup.uc

PartyAttachment.uc

Let’s start with PartyAmmoInv.

A lot of this work following is copy/paste work and can easily be screwed up if you don’t pay attention to what you’re doing carefully. Copy and paste errors can be difficult to track down.

Copy Inventory\Classes\GrenadeAmmoInv.uc over to SuperPack\Classes and rename it as PartyAmmoInv.uc.

There’s not much in this file. One difference here is we’re going to extend this from P2AmmoInv instead of GrenadeAmmoInv like this:

///////////////////////////////////////////////////////////////////////////////
// PartyAmmoInv
// Party ammo inventory item (as opposed to pickup).
///////////////////////////////////////////////////////////////////////////////

class PartyAmmoInv extends P2AmmoInv;

I’m not extending GrenadeAmmoInv basically because with such few changes it’s easier to keep track of what we want for this class as compared to the parent. With the weapon there was a lot of code inside GrenadeWeapon itself that we wanted to preserve. Here, there are only a few default properties some of which we’ll probably change anyway. Because of this, we’re extending the parent class. Another reason would be that in the future there might be lower level changes to GrenadeAmmoInv that I wouldn’t want to extend into my PartyAmmoInv. Again, with the weapon side of things I wanted it very, very closely related to that it. That was simply because of the functionality needed for the weapon. If it were vastly different from other weapons, I may have simply extended PartyWeapon from P2Weapon instead, much like this situation.

Let’s look at the default properties now. We will be adding our own projectile class so we’ll change this too:

///////////////////////////////////////////////////////////////////////////////
// Default properties
///////////////////////////////////////////////////////////////////////////////
defaultproperties
{       

          ProjectileClass=Class'PartyProjectile'

The next thing we don’t want is the same ammo amounts. I’m arbitrarily picking some new ones now:

MaxAmmo=30

MaxAmmoMP=12

The last thing to change is the texture icon shown where weapon icon is displayed on the HUD. In POSTAL 2, the HUD reaches into the AmmoInv and checks the Texture variable for that value. Since our Party bomb is going to be throwing the gift static mesh used in the ‘Uncle Dave’s Birthday errand’, we’ll simply use that same icon here instead, for our weapon.

Texture=Texture'HUDPack.Icon_Inv_Gift'

}

That image is simply a single texture displayed by the hud, but to make it fit in that area on the HUD it should conform to the sizes of the other icons in HUDPack.utx. (You can see them in the editor under Textures).

You may have also seen the lines:

DamageAmount=13

DamageTypeInflicted=class'GrenadeDamage'

Let’s keep them too. For the moment we will not change these in order to avoid further confusion. The first step I’m taking is to get our all our classes in place such that when thrown, the Party bomb acts identically to the grenade. This may not seem like fun yet, but a several-pass method to coding and be easier to digest. Later will give it more unique attributes. At that point, we’ll probably come back to change these values.


Now, on to PartyPickup!

You should be getting used to this—copy Inventory\Classes\GrenadePickup.uc over to SuperPack\Classes and rename it as PartyPickup.uc.

Watch out for copy/paste errors!

Open PartyPickup.uc.

Oh boy! Another easy class!

Change the header to this:

///////////////////////////////////////////////////////////////////////////////
// PartyPickup
//
///////////////////////////////////////////////////////////////////////////////
class PartyPickup extends P2WeaponPickup;

Again, I’m not extending this from GrenadePickup simply because there’s not enough unique code that we’d want to preserve.

Let’s change some default properties:


defaultproperties
          {
          AmmoGiveCount=1
          MPAmmoGiveCount=1

I’d rather you only get one when you pick this weapon up, instead of 4.

DeadNPCAmmoGiveRange=(Min=1,Max=1)

Keeping it the same.

InventoryType=class'PartyWeapon'

Changing it to match the new class we’ve made.

ShortSleeveType=None

The short sleeve type is the weapon class to be used by short-sleeved characters in MP games only. The weapon we’re making is for single player only. Because of this, we’re ‘stubbing’ this out. The keyword None can be used for most class variables. It’s like a null pointer in C or a 0 for an integer. (look at me giving hints about Unreal Script, while all along I know you already know all of this because of all the other tutorials you’ve been reading before this!)

PickupMessage="You picked up some <strong>Party Bombs</strong>."

This is the message in the lower left that happens when you get this. We make it more appropriate for our new weapon. (The text has to be generic, so while you’ll only get 1 bomb usually, you could theoretically drop 5 bombs, and then pick them all up at once. Either way, the text won’t be grammatically correct.)

DrawType=DT_StaticMesh

StaticMesh=StaticMesh'stuff.stuff1.gift'

This is important; we’re changing the image of the pickup as seen by the player walking up to it. We’ll use the one from the GiftPickup because that’s the model we’re stealing for our weapon in general.


          CollisionRadius=35.000000
          CollisionHeight=20.000000
          BounceSound=Sound'WeaponSounds.grenade_bounce'
          bNoBotPickup=true
          MaxDesireability = -1.0
          }

And everything else we’re keeping the same. That wraps up another class—let’s keeping going!

Now we’ll make PartyAttachment.

Copy Inventory\Classes\GrenadeAttachment.uc over to SuperPack\Classes and rename it as PartyAttachment.uc.

Change the class name at the top like this:

classPartyAttachment extends P2WeaponAttachment;

Again, because it’s little use to extend GrenadeAttachment, we’re extending the parent class P2WeaponAttachment.

The few default property changes are to link it to the new weapon:

WeapClass=class'PartyWeapon'

And to change the static mesh for the visuals:

StaticMesh=StaticMesh'stuff.stuff1.Gift

Yes, this is the same mesh we’re using for the pickup. This is just to make our life easier for the moment. If you wanted to put more work in it, then you could make a more specific mesh for the attachment.

Remember, this attachment is simply the visual that will be in people’s hands when they’re using our weapon.

The final default properties block should look much like this:

defaultproperties

{

DrawType=DT_StaticMesh

StaticMesh=StaticMesh'stuff.stuff1.Gift'

WeapClass=class'PartyWeapon'

}

Shew… another class finished! That does it for all the piddly supporting classes, but we have one more big one to go before we can compile.

Adding the Projectile

The last piece to the weapon puzzle for this example is the projectile. Not all weapons use them. If you simply want to make a new model for the machinegun, then it’s simpler than the PartyBomb example. The pistol, machinegun, and shotgun in POSTAL 2 simply use instant-hit collision tests to trace out the path of the bullet. There are no real bullets like you see in Max Payne in slow-motion. The only gun that has an actual bullet that moves through space in POSTAL 2 is the sniper rifle.

Our projectile, PartyProjectile, is the physical, visual bomb we’ll see flying through the air that will hit the ground and eventually generate an explosion.

Copy Inventory\Classes\GrenadeProjectile.uc over to SuperPack\Classes and rename it as PartyProjectile.uc.

We will be extending this from GrenadeProjectile because there is a significant amount of code to be retained. So you’re first lines should look something like this:

//////////////////////////////////////////////////////////////////////////////
// PartyProjectile.
///////////////////////////////////////////////////////////////////////////////
class PartyProjectile extends GrenadeProjectile;

The next thing is to make sure you have a clear understanding of how you want your projectile to behave. Will it deliver an explosion? Will it explode on contact? Does it bounce off of some things but explode on others? Does it cause instant damage (like the RifleProjectile) rather than exploding?

In our case I want the Party Bomb to blow up on impact with anything. The grenade does not do this exactly. The grenade bounces off walls, but blows up when it hits people. We will have to rework the functions some to make it blow up on contact with anything. What we want is much simpler than the grenade, but we still like some of its other attributes.

Let’s identify the functions we need to modify and keep. It terms of collision, HitWall is called when it hits a static wall. The function Touch calls the function ProcessTouch to say it’s hit any other actor. What we want is for our bomb to explode when touching anything. In both functions then, we would want GenExplosion to be called by both HitWall and ProcessTouch.

Strip out everything from below the class definitions all the way down to this:

///////////////////////////////////////////////////////////////////////////////
// Bounces off walls
///////////////////////////////////////////////////////////////////////////////
simulated function HitWall( vector HitNormal, actor Wall )

Next we call GenExplosion and pass in the variables from HitWall.

{
GenExplosion(Location + ExploWallOut * HitNormal, HitNormal, Wall);
}

The first is the position of the explosion, the second is the normal direction, and the last is simply the actor that got hit. This portion of code is a little confusing looking:

Location + ExploWallOut * HitNormal

All this is meant to do is take the position of the bomb, and move the explosion’s position out away from the wall a little. This ensures that the explosion doesn’t occur inside geometry and generally makes it look nicer and not clip into the ground as much.

Now we need to make the explosion always happen in ProcessTouch also.

You should’ve already replaced the large block of code that was the HitWall function body with your own short version from above. Right after that function is another function we don’t need. So cut out all of the function MakePickup right down to this code:

///////////////////////////////////////////////////////////////////////////////
// We can hurt ourselves with this if its bounced once.
// Otherwise, it hurts everyone else all the same
///////////////////////////////////////////////////////////////////////////////
simulated function ProcessTouch(Actor Other, Vector HitLocation)

We want to keep this header, but replace the body of the function so delete that part also. The body here is simple, we just want to have it call the function GenExplosion.

Let’s do that now:

{
          GenExplosion(HitLocation,Normal(HitLocation-Other.Location), Other);
}

HitLocation a vector location is passed into ProcessTouch. The variable Other is the actor that is getting hit by our bomb.

This part in the middle of the function we just added is simply creating a ‘vector normal’.

Normal(HitLocation-Other.Location)

This is a direction in 3-D space, essentially (if you’re not familiar with these, they’re important to understand, so I’d suggest reading about them on the web some before proceeding).

Go ahead and cut out the Timer function and it’s body, but leave the function GenExplosion. We’ll try to expand on that in a later tutorial.

The only thing left to examine then is the default properties. Because we’re inheriting from GrenadeProjectile, we only need to add in the ones we want to change. I’ll keep this very simple and suggest that the only thing we should really change for the moment is the visuals:

defaultproperties
{
StaticMesh=StaticMesh'stuff.stuff1.gift'


I suppose just for fun, I would also make these bombs float a little more than grenades… to do that I would just change the downward (Z) component of the acceleration on the bomb. I’ll make it a little less to make it float more.

So wrap up the default props with this:

                   Acceleration=(Z=-700)
}

You’re new PartyProjectile should be pretty small. It should look something like this:

//////////////////////////////////////////////////////////////////////////////
// PartyProjectile.
///////////////////////////////////////////////////////////////////////////////
class PartyProjectile extends GrenadeProjectile;

///////////////////////////////////////////////////////////////////////////////
// We want to explode even when hitting walls
///////////////////////////////////////////////////////////////////////////////
simulated function HitWall( vector HitNormal, actor Wall )
{
          GenExplosion(Location + ExploWallOut * HitNormal, HitNormal, Wall);
}

///////////////////////////////////////////////////////////////////////////////
// Explode on contact with anything!
///////////////////////////////////////////////////////////////////////////////
simulated function ProcessTouch(Actor Other, Vector HitLocation)
{
          GenExplosion(HitLocation,Normal(HitLocation-Other.Location), Other);
}
defaultproperties
{
          StaticMesh=StaticMesh'stuff.stuff1.gift'

                    Acceleration=(Z=-700)
}

Done with that! Oh, and if you’ll notice I changed some of the comments to better reflect what our code is now doing. Whine all you want, but relative comments really help trying to understand code you wrote a while ago. So do well-named variables and functions! Naming conventions help! Preach, preach, preach… I know... sigh… anyway.

Compiling the Fun

Alright!! We’re finally ready to compile this beast. For a recap we should have the following in our SuperPack\Classes folder:

PartyAmmoInv.uc

PartyAttachment.uc

PartyPickup.uc

PartyProjectile.uc

PartyWeapon.uc

(If you have the other classes like SuperCheatManager.uc from the other tutorials—that’s fine too.)

Head to your dos window and use your batch file to compile SuperPack.u.

Run the editor and open your test level.

Click open the Actor browser, through Pickup, WeaponPickup, P2WeaponPickup, until you finally reach your new PartyPickup.

Confession

To make sure these tutorials are doable and make sense, I’ve been coding everything I’ve been describing as I’ve gone along. When I first compiled after all the new weapon stuff we’ve added, I popped open the editor only to find that PartyPickup wasn’t in the list! Arrggh!! It’s very frustrating, but hopefully it will help you understand the path you need to follow to get things to work. I had watched the dos window as it compiled and it said everything was fine—but obviously something was wrong. The first thing I did was pop open PartyPickup.uc and look for any misspellings. Nothing seemed out of the ordinary. The next I did was open up the System\ucc.log that was generated after the compile. Sure enough as I scrolled down to the bottom where it was compiling my files I found several errors:

Log: Compiling PartyPickup

Warning: Failed to load 'Class Inventory.PartyWeapon': Can't find file for package 'Inventory'

What’s the problem here?

It’s specifying the Inventory package but that class is actually in the SuperPack package. As a default, if no package is specified the code will use it’s current package for those classes. Because all of those classes are defined in the same package, SuperPack, we can leave off the package description.

When I looked in the default properties of my PartyPickup.uc I found this line:

InventoryType=class'Inventory.PartyWeapon'

That should be like this:

InventoryType=class'PartyWeapon'

After I fixed that and recompiled I found the pickup showed up in the Actor list in the editor as expected.

End confession

Place a few PartyPickups in the level!

(If PartyPickup still isn’t showing up in the list of placeable WeaponPickups (it won’t be under Weapon itself), then make sure you added both lines for your new package in the Postal2.ini concerning EditPackages. Look through Code Tutorial 3 again).

The pickups should show up looking like the white, wrapped gifts—if they’re still grenades check the static mesh in your pickup class.

Save the level. (You don’t have to rebuild an SP level if you only placed pickups).

Exit the editor.

Run the level.

Testing and Fixing Bugs

Go grab some Party bombs and try to throw them. What happens? Right now it’s broken! As soon as you try to throw a bomb, it blows up immediately. Why? Well when we made it explode on contact with anything, it means anything!

To fix this, exit the game and open up PartyProjectile.uc.

The function ProcessTouch handles all moving actors that have hit our bomb. The Instigator is a variable that all actors have. It’s supposed to be the Pawn that has created us. In our case, it will be the Dude throwing the bomb. We need to check the variable Other against our Instigator (the guy throwing the bomb) and make sure they’re not equal. So what we really want is for everything but our guy to blow up on contact with it.

///////////////////////////////////////////////////////////////////////////////
// Explode on contact with anything except our thrower!
///////////////////////////////////////////////////////////////////////////////
simulated function ProcessTouch(Actor Other, Vector HitLocation)
{
          if(Other != Instigator)
                    GenExplosion(HitLocation,Normal(HitLocation, Other.Location), Other);
}

I simply added a conditional if-statement before the explosion to make sure it’s not the Instigator we’re hitting.

Compile SuperPack again.

Run the game again.

This time you should see the arm cock back (with a grenade in his hand) and when he releases a twirling, wrapped present should fly through the air and explode on the ground!

Congratulations! Yeah, it’s pretty basic really, but you now have a complete weapon that is separate from all the POSTAL 2 content! Go ahead and play around with the weapon a little and change some things as you like. Perhaps you’d like it to be on the same number button as the Shovel, or maybe you want the bomb to be thrown farther and faster. Maybe you want more bombs with each pickup. I suggest experimenting with a few of those variables to get a feel for them, now that you have your own weapon to tinker with.

In the next tutorial I’d like to expand on the Party Bomb and add more unique programming to it, to give it more character.

Nathan Fouts

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: