WARNING: THIS HELPFILE IS VERY OUT OF DATE AND WILL UNDERGO A REWRITE SOON!


This document explains the basics and some more advanced options for weapon modification. All the info you'd ever want to know about making weapons in NerfEd is in here in easy to understand format. Additional info will become available as I think of it.

New sections on weapon skinning, creating a custom shatter effect, texture pack storage, animating textures, Fire Textures, Maximum Healing modification, a Microsoft Paint .pcx file workaround, Triplestrike Alt-Fire editing and Class Dependency have been added.

 

3/30/09

New definitions of display properties were added.

Just so you know I, Rajada, can't be held responsible if you accidentally edit, delete or otherwise modify a file critical to the function of NAB or any of its components. However, if your copy of NAB is experiencing technical problems due to following or misunderstanding the instructions included in this help document, drop me an e-mail and I will try to help you to the best of my abilities.
---------------------------------------------------------------------------------------------------------------
 
 
 
 
 
 
 
 
1.Getting Started
 
Hi there, and welcome to Rajada's Simple Weapon Modification Guide. I'm going to assume you already have basic map creation skills, but if you don't know how the heck to make that red cube thingy go anywhere, I suggest you read Wolf's Tutorials first. Start off by making a 512 x 512 x 512 cube, add a light and a playerstart. Save your map as something and open the class browser. You'll use this cube to test your weaponry when necessary.

 

 
 
2.Creating a New Weapon Class
 
This is when the fun begins. Expand the class "INVENTORY" then expand "WEAPON". Now expand "NERFWEAPON". See those classes? Those are the basic classes for the default nerf weapons in the game. But we don't want to modify those, we want to create a sort of "copy" of one of those classes that can be modified freely. First, right click on the class "TURBOFIR". This is the class name for the Wild Fire. Now click the option "CREATE NEW CLASS BELOW TURBOFIR". This will bring up a window. Fill in the following info as follows.

 

 
 
NEW ACTOR CLASS NAME: The name for your blaster. It doesn't have to match what you are going to call it in the game, but it should be a unique name not used by any other class.

 

 
 
PACKAGE NAME: This is the name of the .u file this weapon will be created in. Once again, make it unique but remember you can add more than one thing into a package, such as more weapons or other custom classes.

 

 
 
Once you do this, a script window will pop up. Whenever you see this type of window, close it down. We won't be doing any scripting at first.

 

I called my gun the RAJBLASTER and saved it to RAJBLASTER.u. Now that we have a base weapon class set up, save your progress by clicking "SAVE" below the class browser. Then search the scroll down list until you find the name of YOUR package. Select it and hit save. You will have to do this every time you make a change to your package.

 

 
 
3.Making a New Projectile Class
 
Now, if we were to test our new weapon right now in the game, it would look, shoot and behave just like a regular Wild Fire. Then you'd be thinking "What a rip-off." Before ANYTHING will change, we must create one more custom class. Expand the class "PROJECTILE". These classes are all the things that are shot out of the default nerf weapons. Now, create a new class below "ROCKET". This is probably the easiest projectile to modify. Fill out NEW ACTOR CLAS NAME with something unique, and PACKAGE NAME with the same package as your weapon you made earlier. Close the script window that pops up, right click on your new class and hit "PROPERTIES".

 

 
 
4.Editing Your Projectile
 
Now here is where you customize what your new gun will shoot. Expand the option "COLLISION" These values change what the class does upon contacting an actor, wall, or player. Here are some quick definitions.

 

 
 
bBlockActors: The projectile will push actors or stop them from passing through the projectile.

 

 
 
bBlockPlayers: Same as above, but this one only affects players.

 

 
 
bCollideActors: The projectile will execute its function (in this case, exploding) when touched by an actor.

 

 
 
bCollideWorld: The projectile will execute its function when it touches a wall, or any part of the level.

 

 
 
CollisionHeight: The tallness of the area the projectile can collide with things in. (This is in UnrealEd units which I believe to be pixels, not feet or inches or anything else)

 

 
 
Collision Radius: The radius of the area the projectile can collide with things in.
 
Don't worry if these values are zero. Just leave them alone.

 

 
 
Just a quick note. The scripting in the class "ROCKET" tells the rocket what to do. When you create a class below it, the script for your custom class reads "class (your class name) expands Rocket;". This means all the scripting in the class "ROCKET" applies to the new class, unless you provide new script that tells the new class otherwise. Be sure you understand that before moving on, this is why you do not have to worry about alot of the options in your new class properties. All of them have already been "defined" by the "ROCKET’s properties and script.

 

 
 
Now, expand the option "DISPLAY". These options change what the projectile looks like. Here are some of the more important definitions.

 

 
 
AmbientGlow: Controls that pulsing light effect on weapons.

 

 
 
AnimFrame: Has to do with animations, I almost never use this anyway.

 

 
 
AnimRate: Has to do with how fast it animates, I almost never use this one either.

 

 
 
AnimSequence: Has to do with what animation it uses, this is how I achieved the moving bots in the Bot Blaster V2. It basically tells the mesh which of it's animations it should use, but this will only work if your display mesh HAS animations.

 

 
 
bUnlit: Sets whether lighting will affect it, or if it will have maximum brightness applied.
 

bMeshEnviroMap: Overrides the 'MultiSkins' settings (see below) and applies one texture (the one in the 'texture' field) to the mesh. This also makes the texture

 
 
DrawScale: Scales the projectile, relative to the size of its original mesh.

 

 
 
DrawType: Sets how the projectile will look. A 3d mesh, or a variety of types of 2d sprites.

 

 
 
Fatness: Bloats/contracts the mesh.

 

 
 
Mesh: Click the "..." button to view all meshes, then select the one you want and hit "USE" to set that mesh as the mesh of your projectile.

 

 
 
MultiSkins: Some things require more than one texture to look good, such as the Wild Fire dart ammo. It has a top/bottom texture and a side texture. This is also where you can change what color or texture your rocket will be.
 
 
MultiSkin 2 is the one you should change in this case.

 

 
 
Style: Makes the projectile masked, translucent, modulated or normal.

 

 
 
Now, let's expand the option "MOVEMENT"
 
The only one you really can try to mess with here is Physics. Different physics applied to different projectiles makes them behave differently. The basic guideline is "PHYS_PROJECTILE" makes it shoot straight ahead, no gravity will affect it. "PHYS_FALLING" is affected by gravity and any other setting generally makes it stand still and sometimes spin.

 

 
 
Now we can expand the option "PROJECTILE"

 

 
 
Damage: How much health it takes away, which can vary depending on how accurate the shot is.

 

 
 
ExploWallOut: Seems to make the explosion further from where it exploded, in other words, shifts the explosion.

 

 
 
ImpactSound: The sound played when it explodes.

 

 
 
MaxSpeed: The very fastest this projectile can move (when affected by environmental factors such as zone velocity) .

 

 
 
MiscSound: The usage of this sound depends on the projectile's script. Some use them, some don't.

 

 
 
MomentumTransfer: How far a player will fly when hit by the projectile. This also depends on accuracy.

 

 
 
MyDamageType: Some types of damage have names you can plug in such as Burned, Corroded or SpecialDamage. Some of these damage types affect players differently, such as 'Corrodded' will make the screen flash white.

 

 
 
SpawnSound: What sound will play when the projectile first appears.

 

 
 
speed: The default speed of the projectile when it first appears.

 

 
 
If you expand the option "LIGHTING" and set the "LightEffect" to "LE_Nonincedence", you can change the color, saturation and intensity of the projectile's "glow" in the "LIGHTCOLOR" option.

 

 
 
If you changed any of these settings, saved your pack and tested your weapon, it would STILL work like a Wild Fire. This is because we haven't told the weapon to shoot your custom projectile yet. To do this, right click your weapon (in the actor class browser), hit properties and expand the option "WEAPON". Then in the class browser, highlight your custom projectile and in your weapon's "ProjectileClass" and "AltProjectileClass" click "use". You can also type what appears manually, but this method is much faster. Note that the Alt Fire and Primary Fire don't have to be set to shoot the same projectile.

 

 
 
5.Test, Troubleshoot and Update
 
Be sure you have saved your package, and now your gun fires your custom projectile! If you experience problems with the projectile not touching the bots and just traveling through them, press F7 while in NerfEd. This will update your weapons but may also delete text in the weapon's name, death message or pick up message which are fields discussed below. You can also continue to edit the projectile after it has been set as the gun's projectile. Just don't edit a weapon's properties with a previous version still in the map. Be sure to delete old versions of custom weapons that may be hanging around the map. You can adjust these same properties on each weapon in a map, but this will only apply to the ones you have selected. It is MUCH smarter to edit these properties as previously discussed as new classes.

 

 
 
6.Death Message Editing
 
So you tried out your modified Wild Fire and liked it, but you realized whenever you kill someone, it says something to the extent of "(some unskilled bot) wears many darts from (your name)'s Wild Fire" despite the fact they were obviously blown up by a rocket. Well, what now? You could try yelling at your computer, but I think a more productive route begins by going into your weapon's properties again. Expand the option "WEAPON", then look at the slot named "DeathMessage". It reads something like this.

 

 
 
%o was knocked out by %k's %w.

 

 
 
%o stands for whoever was killed, %k stands for the killer and %w stands for the killer's weapon's name. You can change this message to anything you'd like, as long as %o, %k and %w are included, and it would be nice if it also made sense. An example would be...

 

 
 
%o was blown away by %k's %w.

 

 
 
Of course though, your gun isn't a Wild Fire. So let's expand the option "INVENTORY" and see what's up. Look at the slot named "ItemName". It says Wild Fire right now, if we change this to the name of our new weapon, whatever you have decided to call it, your death message appears something like this.

 

 
 
(Some unskilled bot) was (your custom death verb) by (your player's name)'s (your weapon's name).

 

 
 
7.Weapon Name, Pickup Message and Group Editing
 
All that's left to do to in "INVENTORY" is change the slot labeled "PickupMessage". It can say anything from "u got da awesome gun" to "..." to "Let's rock!". It does not affect the death message or any other aspects of the weapon. Another option I use frequently is the "InventoryGroup" option. One through ten sets the weapon to a key, if the group is zero, pressing the "1" key will bring up a weapon in that group. Press it again to get to different weapons in that group. Eleven through two hundred fifty five do not have an assigned key, and can be reached by hitting your "next weapon" key.

 

 
 
8.Preparing to Skin Your Weapon
 
The next problem you'll encounter is that despite the obvious changes from its parent class, "Turbofir", your new weapon still looks like a Wild Fire. Most of the default weapon skins are stored in the "NERFWEAPON.UTX" texture file. This file is automatically loaded at the startup of NerfEd. Go ahead and locate it in your texture browser. At the very end of the list of pictures is what looks like a flattened Wild Fire. Right click on this image, click export, give it any name and save it to your desktop or anywhere else, you can easily locate it. Now you can open the image in any image editor you have available.

 

 
 
9.Skinning Output with Photoshop and Paint Programs
 
There is quite a variety of image editing software, some free and some you have to pay top dollar for. In this section, you'll learn a few tips for .pcx and .bmp manipulation in Photoshop and the more common Microsoft Paint.

 

 
 
If you happen to be lucky enough to own a copy of Photoshop, you can apply a great variety of effects to make your weapons look unique and professional. Or if you're not skilled with Photoshop, you can make them look really silly but either way, unique. A common problem with editing .pcx images is that they seem limited in Photoshop as they seem to "grey out" alot of the neat filters and options. This can be fixed very easily by changing the images "color mode" to "RGB Color". This is located in the "Image" pull down menu under the option "Mode". Once you've gotten your skin the way you like it, you can save it as a .pcx or a .bmp file as NerfEd can import these. If you save the image as a .pcx, you MUST change the "color mode" back to "indexed color". If you save as a .bmp, keep the "color mode" at "RGB Color".

 

 
 
For those of us with less advanced editing programs, which may not have a "color mode" option, you simply can save it as a .pcx, because it is already in "Indexed Color" mode. Saving over the original exported file will do just fine. You may also save it as a .bmp with "Indexed Color" but every so often, this causes problems in NerfEd.

10.A Paint Program .pcx File Work-Around

The following section is based off a contribution made by Catlover.

If you don't have photoshop, you can replace the .pcx extension with .bmp and enclose the file name in quotes. "Exampletex.bmp" and work with it in Microsoft Paint. However, you will have certain limitations on what colors you can paint depending on the colors in the texture you exported. this is because .pcx files only store the color info of colors used in the image. For example, an all one color, green .pcx file would only allow you to paint in that exact shade of green.

 
 
11.Importing Custom Textures and Skins into NerfEd
 
Importing is a fairly simple process that becomes over complicated by simple mistakes. Make sure your texture matches the following criteria:

 

 
1) Its dimensions in pixels are multiples of two, the most commonly used in NerfEd being 64, 128, 256 and 512. It doesn't have to be square.

 

 
2) Its not named like any other texture you'll be using in your map and preferably not named the same as any other texture.

 

 
3) Its color mode matches the recommendations described above.

 

 
Now I will explain the process itself. In the textures browser, click import and fill out the boxes appropriately.

 

 
 
Name: This defaults to the name of the texture you are importing. You can change it here if you want.

 

 
 
Package: The name of the .utx file the texture will be stored in. This can be pre-existing if you already have created a new .utx previous to this tutorial. In any other case, create a new one, keeping in mind more textures can be added to the same .utx file.

 

 
 
Group: This is used if you have alot of textures in one .utx file. It creates a group in the .utx file for easy organization.

 

 
 
Everything else can be left alone for now. Click yes and your new Wild Fire skin is imported and your new .utx created. Be sure to save your pack after importing any new textures.

 

 
 
12.Applying Custom Textures to Your Weapon
 
So, your new skin looks cool, but it would look alot cooler if it were wrapped around your weapon, right? Let's learn how to do so. Right click on your weapon, hit properties and expand the option "DISPLAY". Expand the option "Multiskins" and look at the slots. See the ones named "[1]" and "[3]"? Set these slots to your custom skin and you're set!

 

 
 
13.Custom Ammo Creation
 
If you test your weapon, sooner or later you'll realize the weapon uses the same ammo as the Wild Fire, therefore draining both weapons' ammo. Using what you have learned, you can create a custom ammo class (under "INVENTORY>PICKUP>AMMO"), make it look however you want and set your weapon to use this ammo. The option to do this is found in your weapon's properties under "WEAPON" in the slot named "AmmoName". Highlight your custom ammo and just click "use". Be sure to look at the properties of your ammo and set the slots under the option "AMMO" to the appropriate values. Also, be sure to change the pick up message as you did with your weapon.

 

 
 
14.Making an Easy Custom Shatter Effect
 
This section details on making a generic shatter using a predefined explosion included in NAB. Under the actor class "EFFECTS" is a class called "BURST". Go ahead and make a new class under it. Right click on your custom "BURST" and let's edit some properties. This class will not "hurt" any actors or players, but will add a cool effect if the projectile fits the explosion. You can edit all of the previously taught display properties easily. One thing I will clear up is that wherever the "BURST" occurs, it will not move from that position unless acted upon by a "ZONEINFO" with "velocity" set. This doesn't mean it won't disappear, it will go away after the "exploding" animation plays. If you do in fact want the explosion to be affected by gravity, simply set it's "physics" to "PHYS_FALLING" as previously discussed. Now we need to set the projectile to use this explosion. This is where we do a little coding. Double click on your custom projectile class or right click and select "edit script". MOST projectiles will work fine with the following code:

 

 
 
 
//================================================
// yourproj.
//================================================
class yourproj expands Rocket;
simulated function ProcessTouch (Actor Other, Vector HitLocation)
{
if ((Other != instigator) && (Rocket(Other) == none))
Explode(HitLocation,
Normal(HitLocation-Other.Location));
}
function BlowUp(vector HitLocation)
{
if ( Level.Game.IsA('DeathMatchGame') ) //bigger damage radius
HurtRadius(Damage,200.0, 'exploded', MomentumTransfer, HitLocation );
else
HurtRadius(Damage,150.0, 'exploded', MomentumTransfer, HitLocation );
MakeNoise(1.0);
PlaySound(ImpactSound, SLOT_None, 2.3);
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
local yourburst s;
s = spawn(class'yourpack.yourburst',,,HitLocation + HitNormal*16);
s.RemoteRole = ROLE_None;
BlowUp(HitLocation);
Destroy();
}
}


Just remember to set all of the bold text to the correct names of your pack and class. Now hit F7, but be warned! As previously mentioned, this may delete most if not all of the text in your weapon's "DeathMessage", "ItemName" and/or "PickupMessage". You should always try to understand what the code your making does, but to be honest, alot of my weapons are created through experimentation. A recommendation is not to copy/paste this code, but type it manually as it will help you learn the code, similar to learning a foreign language. Remember to save your custom textures, classes and levels often.

 
 
15.A "Quick" Note on Texture Packs
 
When creating a custom texture pack, you should always try to group your textures in one .utx file. Think of a .utx file as a file cabinet. A neat option you get while importing textures is a text field called "Group". Think of a "Group" as a folder in the file cabinet. Let's take a hypothetical situation to help explain my point. Say you have a pile of red forms and a pile of blue forms. Both forms are filled out in order to let's say...purchase a house. You put the red forms in a FOLDER labeled "RED" and the blue forms in a FOLDER labeled "BLUE". Both of these folders can be put in the same CABINET, right? Let's say now legislation passed a bill requiring homebuyers to fill out a third, green form. You put a stack of these green forms in a FOLDER labeled "GREEN". Now, do you buy a whole new filing cabinet for this one folder? NO! That's a waste of time, money and space. Instead, you put the "GREEN" FOLDER in the same CABINET with the other two FOLDERS. The point I am trying to make is don't make a separate .utx file for weapon skins and a separate one for ammo skins. Create two "Groups" in one .utx file, possibly named "skins" and "ammo". It doesn't matter if you import the textures at different times as it wouldn't matter if you put more papers into a folder after the first time you put papers in. As long as the file names are not the same, the files will not be replaced.

 

 
 
Let's take one more situation for one more important point. The texture browser in NerfEd is a little angry. We'll call the texture browser Ace. Quite frankly, Ace doesn't give a flying flip about you. You could fall of a cliff and land on a pile of jagged rocks and it wouldn't care in the least. You just told Ace to give you two CABINETS; one called MYN00BTEX.utx and one called COOLTEXTURES.utx. Of course, Ace is a little cranky that he has to drag two heavy file CABINETS to you, but he will because it's his job. You ask him to open the CABINETS and find a certain FOLDER in each one. Coincidentally, these FOLDERS are named the same thing, but this is no problem whatsoever. Now you ask him to pull out an image named N00bcolor, which is a solid green color, out of MYN00BTEX.utx and apply it to a wall. But alas! The wall turns purple! This is what happened. Ace, because he is also not very intelligent, decided to look through ALL of the texture packs, despite that you said the image was in MYN00BTEX.utx. Ace looked through all of your loaded CABINETS, or texture packs, alphabetically and found a file with the same name in COOLTEXTURES.utx first. He gave you the first one, located in COOLTEXTURES.utx which happened to be a solid purple color. The purple image did not replace the green image, but if both texture packs are loaded that contain images with the same names, NerfEd will use the first one it finds. To fix this, either delete one of the textures and re-import it with a unique name, or don't use these textures in the same level or in actors in class packs.

 

 
 
Renaming a file that is already in use by a level or actor will cause major problems. I recommend selecting the texture you wish to rename, whether it is in a level or in an actor, and changing it to a bright texture you haven't used so it will be easy to spot. If the texture is used in a level, an easy way to do this is hit "Shift" and "T". This will select ALL walls using the texture or textures on the selected wall or walls. Change it to a texture not yet used in your level, then when you rename and re-import the texture, you can use Shift T to select all of the walls that were previously your custom texture that you had to delete. With actors, you will have to change the texture back manually in the already described "MultiSkins" text field.

 

 
 
16.Animating Textures
 
Animating textures can be used for a variety of things including explosions, skins or just a texture in a level. Please note that animating textures are not the same as "Fire Textures", which I will explain later. An animated texture consists of 2 or more textures linked in a way as to either create an illusion of movement or some other dynamic effect.

 

 
Say you have a few textures loaded in your texture browser that you want to animate. Right click on the first one you want, and click "Edit TextureNameHere Properties". Expand the option "Animation". The field "AnimNext" tells you which texture it will change to next. Change this to the next texture you wish to animate to. The other three fields tell you how fast it will animate. Adjust the minimum and maximum frame rate as you'd like, depending on how fast the animation should be. Repeat this process for any other textures.

 

17.Fire Textures and Application to Classes
 
Fire textures can be used in the same ways as animating textures, but Fire Textures consist of one self-animating texture, instead of several different textures linked together. To make a Fire Texture, in your texture browser, click "New". Give it a unique name, set the group and package as you desire and make sure "Class" is set to fire texture. Click "Create this texture" then expand the option "FirePaint". Under the field "SparkType" is all of the neat flames, sparks and other fireworks-ish effects you can "paint" with. Expand the option "Texture". The field "Palette" shows you the name of the color scheme the texture will use. This texture can be changed to one of the pre-made palettes found in Palettes.utx or can be set to any other texture for a variety of bizarre results. A more detailed walkthrough on the process of creating Fire, Ice and Water textures can be found here. I am going to focus on the application of these textures to weapons, ammo, projectiles and other classes.
 
 
If you were to simply apply a fire texture to a weapon or projectile, the texture would not "animate". If you were to apply it to ammo, then hit "Paths Define" your system would either lock up or NerfEd would shut down. In order to apply a fire texture to a class, a small amount of extra scripting is required. In the script for the class, you must put the following script at the very beginning.

 

 
 
function PostBeginPlay()
{
Super.PostBeginPlay();
SetDisplayProperties(ERenderStyle.STY_Translucent, //set this to STY_Translucent, STY_Masked or whatever effect you are looking for
FireTexture'your package name.your texture name',
true,
true);
}

 

 
 
The fourth line can be used to change the "Style" of the class. The word "Translucent" can be replaced with "Masked", "Modulated" or "Normal". "None" can also be used, but it generally has the same effect as "Normal".

 

 
 
18.Maximum Healing Modification
 
If you've played any of my PM-CW levels, chances are you've seen my "Ultra Power" pickup based off of the “MegaPower”. While normal Suit Power Plus and Suit Powers can only heal you 100, if you modifed their properties by expanding "SuitPower" and setting "bSuperHeal" to true, they can heal you up to 200. The same effect can be found in a "MegaPower". Let's say you wanted to make a modified "MegaPower" that heals you to 300 as I made in PM-CW7. If you tried to set the healing amount, found under the option "MegaPower", to 200, it would still only heal you to 200 health, even if you had full health. In order to make it heal more than 200, you must plug in the following code.

 

 
 
var() int HealingAmount;
var() bool bSuperHeal;
function PostBeginPlay()
{
PickupViewMesh=Mesh(DynamicLoadObject("NerfI.MegaPower", class'Mesh'));
Super.PostBeginPlay();
}
event float BotDesireability(Pawn Bot)
{
local float desire;
desire = HealingAmount;
if ( !bSuperHeal )
desire = Min(desire, 100 - Bot.Health);
if ( (Bot.Weapon != None) && (Bot.Weapon.AIRating > 0.3) )
desire *= 2;
if ( Bot.Health < 40 )
return ( FMin(0.03 * desire, 2) );
else if ( Bot.Health < 100 )
return ( 0.01 * desire );
else
return 0;
}
auto state Pickup
{
function Touch( actor Other )
{
local int HealMax;

if ( ValidTouch(Other) )
{
HealMax = Pawn(Other).default.health;
if (bSuperHeal) HealMax = HealMax * 2.0;
if (Pawn(Other).Health < HealMax)
{
Pawn(Other).Health += HealingAmount;
if (Pawn(Other).Health > HealMax) Pawn(Other).Health = HealMax;
if (Level.Game.LocalLog != None)
Level.Game.LocalLog.LogPickup(Self, Pawn(Other));
if (Level.Game.WorldLog != None)
Level.Game.WorldLog.LogPickup(Self, Pawn(Other));
if ( PickupMessageClass == None )
Pawn(Other).ClientMessage(PickupMessage, 'Pickup');
else
Pawn(Other).ReceiveLocalizedMessage( PickupMessageClass, 0, None, None, Self.Class );
PlaySound (PickupSound,,2.5);
if ( Level.Game.Difficulty > 1 )
Other.MakeNoise(0.1 * Level.Game.Difficulty);
SetRespawn();
}
}
}
}

 

 
 
See the bold number? That is the maximum healing multiplier. Set it to 3.0 and the modified "MegaPower" will allow you to heal up to 300. But remember, you must set the "HealingAmount" to the amount you want. Here are a few examples...

 

 
In this situation, you have an initial amount of health and you made a modified "MegaPower" that can heal up to 400. These are some examples of what different healing amounts will do.

 

 
 
Initial Health.......................Healing Amount.........................Outcome
100.......................................... 100 ..........................................200
100 ..........................................200 ..........................................300
100.......................................... 300 ..........................................400
50............................................300 ..........................................350
300 .........................................300...........................................400
 
 
As you can see, because we made its maximum 400, we can never breach 400 health. “Suit Power”s set to bSuperHeal will ONLY heal you up to 200, no matter what "MegaPower" you may have picked up. If you have 200 or more health, you simply will not be able to pick up a bSuperHeal "SuitPower". PM-CW7 is available here.
 
 
19.Triplestrike Alt Fire
If you've edited a Triplestrike before, you probably noticed the alternate fire still shot red rockets no matter what you set the "altprojectileclass" to be. This is because it must also be changed in its code.
 
 
//=============================================================================
//Your weapon's class name.
//=============================================================================
class Your weapon's class name expands TripleShot;
var int RocketsLoaded;
var bool bFireLoad;
var float Offset[3];
var int RoxInBarrel;
replication
{
// Things the server should send to the client.
reliable if( Role==ROLE_Authority && bNetOwner )
RoxInBarrel;
}
function float RateSelf( out int bUseAltMode )
{
local float EnemyDist;
local bool bRetreating;
local vector EnemyDir;
if ( AmmoType.AmmoAmount <=0 )
return -2;
if ( Pawn(Owner).Enemy == None )
{
bUseAltMode = 0;
return AIRating;
}
EnemyDir = Pawn(Owner).Enemy.Location - Owner.Location;
EnemyDist = VSize(EnemyDir);
if ( EnemyDist < 270 )
{
bUseAltMode = 0;
return -0.1;
}
if ( Owner.Physics == PHYS_Falling )
bUseAltMode = 0;
else if ( EnemyDist < -1.5 * EnemyDir.Z )
bUseAltMode = int( FRand() < 0.5 );
else
{
bRetreating = ( ((EnemyDir/EnemyDist) Dot Owner.Velocity) < -0.7 );
bUseAltMode = 0;
if ( ((EnemyDist < 600) || (bRetreating && (EnemyDist < 800)))
&& (FRand() < 0.4) )
bUseAltMode = 1;
}
return AIRating;
}
// return delta to combat style
function float SuggestAttackStyle()
{
local float EnemyDist;
EnemyDist = VSize(Pawn(Owner).Enemy.Location - Owner.Location);
if ( EnemyDist < 500 )
return -0.6;
else
return -0.2;
}
function setHand(float Hand)
{
local rotator newRot;
Super.SetHand(Hand);
if ( Hand == 1 )
Mesh = Mesh(DynamicLoadObject("NerfWeapon.TripleShotL", class'Mesh'));
else if ( Hand == -1 )
Mesh = Mesh'TripleShotR';
else
{
PlayerViewOffset.Y = 0;
FireOffset.Y = 0;
bHideWeapon = true;
}
}
simulated function TweenDown()
{
local float animerate;
if ( (AnimSequence != '') && (GetAnimGroup(AnimSequence) == 'Select') )
TweenAnim( AnimSequence, AnimFrame * 0.4 );
else
{
if ((Level.Game != None) && (Level.Game.bFastWeaponSwitch))
animerate = 2.0;
else
animerate = 1.0;
switch (RoxInBarrel)
{
case 0: PlayAnim('Down_03', animerate, 0.05);
break;
case 1: PlayAnim('Down_02', animerate, 0.05);
break;
case 2: PlayAnim('Down_01', animerate, 0.05);
break;
case 3: PlayAnim('Down', animerate, 0.05);
break;
}
}
}
simulated function TweenToStill()
{
switch (RoxInBarrel)
{
case 1: TweenAnim('Still_03', 0.1);
break;
case 2: TweenAnim('Still_02', 0.1);
break;
case 3: TweenAnim('Still_01', 0.1);
break;
}
}
simulated function PlaySelect()
{
local float animerate;
if (RoxInBarrel <= 0)
{
if (AmmoType.Ammoamount >= 3)
RoxInBarrel = 3;
else
RoxInBarrel = AmmoType.Ammoamount;
}
if ((Level.Game != None) && (Level.Game.bFastWeaponSwitch))
animerate = 2.0;
else
animerate = 1.0;
switch (RoxInBarrel)
{
case 1: PlayAnim('Select_02', animerate, 0.0);
break;
case 2: PlayAnim('Select_01', animerate, 0.0);
break;
case 3: PlayAnim('Select', animerate, 0.0);
break;
}
Owner.PlaySound(SelectSound, SLOT_Misc, Pawn(Owner).SoundDampening);
}
simulated function PlayLoading()
{
PlayAnim('Load', 1.0, 0.05);
}
simulated function PlayFiring()
{
// log(class$ " WES: RoxInBarrel in PlayFiring" @RoxInBarrel);
Owner.PlaySound(FireSound, SLOT_Misc,Pawn(Owner).SoundDampening);
if (RoxInBarrel == 3)
{
PlayAnim('Fire_01', 0.5, 0.05);
RoxInBarrel--;
}
else if (RoxInBarrel == 2)
{
PlayAnim('Fire_02', 0.5, 0.05);
RoxInBarrel--;
}
else if (RoxInBarrel == 1)
{
PlayAnim('Fire_03', 0.5, 0.05);
RoxInBarrel=3;
}
}
simulated function PlayPumping()
{
PlayAnim('idle_alt', 1.0, 0.05);
}
/*************************************************************************************/
State AltFireLoading
{
function Fire(float F)
{
}
function AltFire(float F)
{
}
Begin:
FinishAnim();
PlayAnim('idle_alt', 1.0, 0.05);
FinishAnim();
Sleep(0.2);
Finish();
}
simulated function PlayAltFiring()
{
Owner.PlaySound(AltFireSound, SLOT_Misc,Pawn(Owner).SoundDampening);
if (RoxInBarrel == 3)
{
PlayAnim('Fire_alt', 0.5, 0.05);
}
else if (RoxInBarrel == 2)
{
PlayAnim('Fire_alt_02', 0.5, 0.05);
}
else if (RoxInBarrel == 1)
{
PlayAnim('Fire_03', 0.5, 0.05);
}
if (AmmoType.Ammoamount > 3)
RoxInBarrel=3;
else
RoxInBarrel=AmmoType.Ammoamount;
}
///////////////////////////////////////////////////////
simulated function TraceRoxFire(class ProjClass, float ProjSpeed, bool bWarn)
{
local Vector Start, X,Y,Z;
local Projectile RR;
local int i;
local Rotator FirRot, AltRotation;
Owner.MakeNoise(Pawn(Owner).SoundDampening);
GetAxes(Pawn(owner).ViewRotation,X,Y,Z);
for (i=0; i < RocketsLoaded; i++)
{
if (i == 0)
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + (FireOffset.Y - 5) * Y + (FireOffset.Z -5 ) * Z;
else if ( i == 1 )
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + (FireOffset.Y + 5) * Y + (FireOffset.Z -5 ) * Z;
else
Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;

AdjustedAim = pawn(owner).AdjustAim(AltProjectileClass.Default.Speed, Start, 2.4*AimError, False, False);
if (i == 0)
AdjustedAim.Yaw += 300;
else if (i == 1)
AdjustedAim.Yaw -= 300;
else
AdjustedAim.Pitch += 300;
Spawn(class'YOURPACKAGE.YOURPROJECTILE',,, Start,AdjustedAim);
}
}
simulated function PlayIdleAnim()
{
TweenToStill();
}
/*****************************************************************************/
simulated function bool ClientFire( float Value )
{
if ( bCanClientFire && ((Role == ROLE_Authority) || (AmmoType == None) || (AmmoType.AmmoAmount > 0)) )
{
if ( (PlayerPawn(Owner) != None)
&& ((Level.NetMode == NM_Standalone) || PlayerPawn(Owner).Player.IsA('ViewPort')) )
{
if ( InstFlash != 0.0 )
PlayerPawn(Owner).ClientInstantFlash( InstFlash, InstFog);
PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert);
if ( Affector != None )
Affector.FireEffect();
}
GotoState('NormalFire');
return true;
}
return false;
}
function Fire( float Value )
{
if ( AmmoType.UseAmmo(1) )
{
bPointing=True;
bCanClientFire = true;
ClientFire(Value);
if ( bRapidFire || (FiringSpeed > 0) )
Pawn(Owner).PlayRecoil(FiringSpeed);
}
}
state NormalFire
{
function AnimEnd()
{
}
simulated function FireRox()
{
PlayFiring();
ProjectileFire(ProjectileClass, ProjectileSpeed, bWarnTarget);
}
simulated function CheckLoad()
{
if ((AmmoType.Ammoamount > 0) && (RoxInBarrel == 3))
PlayLoading();
}
Begin:
FireRox();
FinishAnim();
CheckLoad();
FinishAnim();
Sleep(0.4);
Finish();
}
/*****************************************************************************/
state ClientAltFiring
{
simulated function BeginState()
{
if (AmmoType.Ammoamount > 0 )
{
PlayPumping();
}
}
function Fire( float Value )
{
}
function AltFire( float Value )
{
}
simulated function AnimEnd()
{
if ( (Pawn(Owner) == None)
|| ((AmmoType != None) && (AmmoType.AmmoAmount <= 0)) )
{
// log(class$ " WES: State ClientAltFiring Pawn is None or Ammo is None");
PlayIdleAnim();
GotoState('idle');
}
else if ( !bCanClientFire )
{
// log(class$ " WES: State ClientAltFiring !bCanClientFire");
GotoState('idle');
}
else if ( Pawn(Owner).bFire != 0 )
{
// log(class$ " WES: State ClientAltFiring Call ClientFire");
Global.ClientFire(0);
}
else if ( Pawn(Owner).bAltFire != 0 )
{
// log(class$ " WES: State ClientAltFiring Call ClientAltFire");
Pawn(Owner).bAltFire = 0;
bForceFire = False;
// Global.ClientAltFire(0);
}
else
{
// log(class$ " WES: State ClientAltFiring Call PlayIdleAnim");
PlayIdleAnim();
GotoState('idle');
}
}
simulated function EndState()
{
// log(class$ " WES: State ClientAltFiring EndState");
AmbientSound = None;
}
Begin:
Sleep(0.0);
}
function AltFire( float Value )
{
if (AmmoType.UseAmmo(RoxInBarrel))
{
RocketsLoaded=RoxInBarrel;
}
else
{
RocketsLoaded=AmmoType.AmmoAmount;
RoxInBarrel=RocketsLoaded;
AmmoType.UseAmmo(RocketsLoaded);
}
bPointing=True;
bCanClientFire = true;
ClientAltFire(Value);
GotoState('AltFiring');
if ( bRapidFire || (FiringSpeed > 0) )
Pawn(Owner).PlayRecoil(FiringSpeed);
TraceRoxFire(AltProjectileClass, AltProjectileSpeed, bAltWarnTarget);
if (AmmoType.Ammoamount > 0)
{
PlayPumping();
}
}
 
The bold sections are the ones that you will need to change to your appropriate classes.
 
20.Class Dependency
So far, I have told you to create weapon classes that expand other weapon classes. This means that a RAJBLASTER that expands Turbofir is considered a RAJBLASTER and a Turbofir. You might ask "Is this a problem?" The answer is not in most cases. Chances are if you are reading this guide you are new to class editing or still learning, therefore creating classes that expand other classes is a good way to learn. It is important to know that if you become more advanced, it is better to have your weapons expand "NERFWEAPON" rather than a specific weapon. While doing this gives you alot more work, it is the only way to create weapons that require highly modified behaviors or that you wish to use in mutators. Let's take an example to explain this more clearly. A common mutator is a weapon replacing mutator such as the M-16 Mutator. It replaces all of the Nerf Cannons in a level with a M-16. If you used a version of the M-16 that expanded "MightyMo" (Nerf Cannon's class name), the mutator would replace the Nerf Cannons with your M-16, then replace your M-16 with a M-16, looping forever. While this works to an extent, it does create errors often and if you added a second weapon replacement that expands the same weapon, both would be replaced by the M-16. This may sound a bit confusing but the moral of the story is don't use weapons or ammo that expand specific nerf weapons or ammo in mutators.
 
 
 
 
 
21.Further Support
 
With the help of this guide, you have hopefully learned enough to create and modify your own weapons. Many of my custom weapons took lots of scripting and experience that can be gained through learning Unreal Script with more advanced tutorials. I am always available for tech support and when the good ol' NAB forums or I can't provide the answers, look for Unreal Forums as they contain many more advanced scripters.
 
 
Evily yours,

 

 
 
Rajada.