Mostly Harmless
Legacy:Trystan/11 17 02c
11/17/02 Adding a Weapon[edit]
Parts of a weapon[edit]
- M16A2X.uc
- The main weapon class.
- M16A2Fire.uc
- The class that handles primary fire.
- M16A2AltFire.uc
- The class that handles secondary fire.
- M16A2Pickup.uc
- The class that handles a player or bot picking the item up.
- M16Arena.uc
- The class that substitutes your weapon for another, based on the XPaks.
Notes[edit]
Examining the structure of a weapon I think I'm ready to discuss how to add one without first dissecting Actor.uc, Inventory.uc, and Weapon.uc. I'll still examine them soon but I'm itching to get some solid results in.
There's two parts to a weapon: the weapon itself and the bullet it fires. We're not going to be using instant hit weapons; every weapon we create will be a projectile based weapon. So the first class we create is going to be M16A2X.
//============================================================================= // M16A2 //============================================================================= class M16A2X extends Weapon config(user); defaultproperties { FireModeClass(0) = Class'M16A2Fire' FireModeClass(1) = Class'M16A2AltFire' PickupClass = Class'M16A2Pickup' SelectAnim = "Pickup" PutDownAnim = "PutDown" SelectSound = Sound'WeaponSounds.FlakCannon.SwitchToFlakCannon' SelectForce = "SwitchToFlakCannon" AIRating = 0.750000 CurrentRating = 0.750000 EffectOffset = (X=200.000000,Y=32.000000,Z=-25.000000) DisplayFOV = 60.000000 Priority = 8 DefaultPriority = 8 InventoryGroup = 7 PlayerViewOffset = (X=-7.000000,Y=8.000000) PlayerViewPivot = (Yaw=16884,Roll=200) BobDamping = 1.400000 AttachmentClass = Class'XWeapons.FlakAttachment' IconMaterial = Texture'InterfaceContent.HUD.SkinA' IconCoords = (X1=322,Y1=100,X2=444,Y2=200) ItemName = "M16A2" LightType = LT_Steady LightEffect = LE_NonIncidence LightBrightness = 150.000000 LightRadius = 4.000000 LightHue = 30 LightSaturation = 150 Mesh = SkeletalMesh'Weapons.Flak_1st' UV2Texture = Shader'XGameShaders.WeaponShaders.WeaponEnvShader' }
We extend Weapon, and leave it at that. This is pretty much a complete rip of FlakCannon.uc as you can tell by the defaultproperties. We don't have an M16 model, bullet, or sounds yet – we're just itching to play around. Two important things I noted were the FireModeClass(0) and FireModeClass(1). They specify what class is called with primary or alternate fire is called. The pickup class is the class that happens when you actually pick the weapon up. What that means will make more sense in a few seconds I think.
Next class up is M16A2Fire.uc.
class M16A2Fire extends ProjectileFire; function InitEffects() { Super.InitEffects(); if( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } defaultproperties { ProjPerFire = 1 // was 9 ProjSpawnOffset = (X=25.000000,Y=5.000000,Z=-6.000000) FireEndAnim = "None" FireSound = SoundGroup'WeaponSounds.FlakCannon.FlakCannonFire' FireForce = "FlakCannonFire" FireRate = 0.150000 AmmoClass = Class'XWeapons.FlakAmmo' AmmoPerFire = 1 ShakeRotTime = 2.000000 ShakeOffsetMag = (X=-20.000000) ShakeOffsetRate = (X=-1000.000000) ShakeOffsetTime = 2.000000 ProjectileClass = Class'WorldAtWar.Bullet556mm' BotRefireRate = 0.700000 FlashEmitterClass = Class'XEffects.FlakMuzFlash1st' Spread = 40.000000 SpreadStyle = SS_Random }
We extend ProjectileFire and leave it pretty well at that. This code was based on FlakCannonFire.uc. One of the things that needs to be investigated more in the above code is SpreadStyle. For the M16A2 we don't really want a random spread style but we'll leave it alone for now. Declared herein is the ProjectileClass that's used when this gun fires, in this case Bullet556mm. We'll define that class in a second. AmmoPerFire and ProjPerFire are both important as well. They specify, respectively, the ammunition consumed per click of the fire button and the number of projectiles issued by each click. They can be different for various reasons.
Next up is M16A2AltFire.uc.
class M16A2AltFire extends ProjectileFire; function InitEffects() { Super.InitEffects(); if( FlashEmitter != None ) Weapon.AttachToBone(FlashEmitter, 'tip'); } defaultproperties { ProjPerFire = 3 // was 9 ProjSpawnOffset = (X=25.000000,Y=5.000000,Z=-6.000000) FireEndAnim = "None" FireSound = SoundGroup'WeaponSounds.FlakCannon.FlakCannonFire' FireForce = "FlakCannonFire" FireRate = 0.150000 AmmoClass = Class'XWeapons.FlakAmmo' AmmoPerFire = 3 ShakeRotTime = 2.000000 ShakeOffsetMag = (X=-20.000000) ShakeOffsetRate = (X=-1000.000000) ShakeOffsetTime = 2.000000 ProjectileClass = Class'WorldAtWar.Bullet556mm' BotRefireRate = 0.700000 FlashEmitterClass = Class'XEffects.FlakMuzFlash1st' Spread = 40.000000 SpreadStyle = SS_Random }
Here we've run into an interesting problem. I had wanted the M16A2's alternate fire to be semi auto so I used 3 for AmmoPerFire and 3 for ProjPerFire. The problem is that all three projectiles are fired at once, in what appears to be a large lump. I've yet to figure this out but I'm sure I will.
Problem found: Apparently no game time passes while you're in UnrealScript. So all three projectiles seem to be fired at the same time, at the same velocity, at the same angle. The solutions I've seen posted include setting a timer for whatever duration you want in between each bullet, and having the timer fire the bullets.
- Mychaeel: You might want to look into state code and latent functions – with that you can code sequences like that which are meant to progress over (game) time straightforwardly:
- Trystan: oooooooooooooooooooooo.. thank you.
state FiringThreeProjectiles { Begin: FireOneProjectile(); Sleep(0.5); // Sleep is a latent function FireOneProjectile(); Sleep(0.5); FireOneProjectile(); }
M16A2Pickup.uc
class M16A2Pickup extends WeaponPickup; function SetWeaponStay() { bWeaponStay = true; } function float GetRespawnTime() { return 5.0000; } defaultproperties { InventoryType=Class'M16A2X' PickupMessage="You got the M16A2." }
This is fairly simple. Of note is the SetWeaponStay() (does the weapon disappear after someone picks it up?) and the respawn time (only used if the weapon does not stay). In default properties you can see we specify the class attached to this weapon (M16A2X.uc) and the message given to the player when they pick an object of this type up.
We've defined our weapon, now we just have to give it ammunition to fire.
Return to Trystan/Developer Journal.