Poll

Think it's easy making a Add-on?

Yes
No
Sorta

Author Topic: How do you make Add-ons?  (Read 2237 times)

Please help! I don't know how to make a add-on. I kept searching but nope. So if you got any idea tell me or if you have to make it on a program give me a link to the program.

You going to be scripting or modeling? It's very complex , highly doubt you'll even be able to create anything if i linked a program.

search again, there's way too many topics about this and dedi's

For modelling.
Milkshape - Easy to learn, $35. Limited features and uses.
Blender - Harder to learn, free. Many more features and uses.

For scripting, use any text editor. I use Notepad++

You going to be scripting or modeling? It's very complex , highly doubt you'll even be able to create anything if i linked a program.
Meh, I just feel like trying, even if it takes a year or more.

if anyone eve tell  you how to make an add on please tell me a link

 Same here if you ever get a link give it to me  :cookie:

Same here if you ever get a link give it to me  :cookie:
If we gave you the link you would spam crappy add-ons that don't work.

I will show you an example code of the gun script. When you start scripting, its best just to "Borrow" scripts (with permission, exept from the default weapons of course) and looking at scripts will also help you learn how coding works.
Lets say I was going to make a "sniper rifle" type weapon. Heres an example single-shot gun: (zoom in to see)
Code: [Select]
//gun.cs

//audio
datablock AudioProfile(gunShot1Sound)
{
   filename    = "./gunShot1.wav";
   description = AudioClose3d;
   preload = true;
};
datablock AudioProfile(bulletHitSound)
{
   filename    = "./bulletHit.wav";
   description = AudioClose3d;
   preload = true;
};


//shell
datablock DebrisData(gunShellDebris)
{
   shapeFile = "./gunShell.dts";
   lifetime = 2.0;
   minSpinSpeed = -400.0;
   maxSpinSpeed = 200.0;
   elasticity = 0.5;
   friction = 0.2;
   numBounces = 3;
   staticOnMaxBounce = true;
   snapOnMaxBounce = false;
   fade = true;

   gravModifier = 2;
};


//muzzle flash effects
datablock ParticleData(gunFlashParticle)
{
   dragCoefficient      = 3;
   gravityCoefficient   = -0.5;
   inheritedVelFactor   = 0.2;
   constantAcceleration = 0.0;
   lifetimeMS           = 25;
   lifetimeVarianceMS   = 15;
   textureName          = "base/data/particles/star1";
   spinSpeed      = 10.0;
   spinRandomMin      = -500.0;
   spinRandomMax      = 500.0;
   colors[0]     = "0.9 0.9 0.0 0.9";
   colors[1]     = "0.9 0.5 0.0 0.0";
   sizes[0]      = 0.5;
   sizes[1]      = 1.0;

   useInvAlpha = false;
};
datablock ParticleEmitterData(gunFlashEmitter)
{
   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 1.0;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunFlashParticle";

   uiName = "Gun Flash";
};

datablock ParticleData(gunSmokeParticle)
{
   dragCoefficient      = 3;
   gravityCoefficient   = -0.5;
   inheritedVelFactor   = 0.2;
   constantAcceleration = 0.0;
   lifetimeMS           = 525;
   lifetimeVarianceMS   = 55;
   textureName          = "base/data/particles/cloud";
   spinSpeed      = 10.0;
   spinRandomMin      = -500.0;
   spinRandomMax      = 500.0;
   colors[0]     = "0.5 0.5 0.5 0.9";
   colors[1]     = "0.5 0.5 0.5 0.0";
   sizes[0]      = 0.15;
   sizes[1]      = 0.15;

   useInvAlpha = false;
};
datablock ParticleEmitterData(gunSmokeEmitter)
{
   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 1.0;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunSmokeParticle";

   uiName = "Gun Smoke";
};


datablock ParticleData(gunExplosionParticle)
{
   dragCoefficient      = 8;
   gravityCoefficient   = 1;
   inheritedVelFactor   = 0.2;
   constantAcceleration = 0.0;
   lifetimeMS           = 700;
   lifetimeVarianceMS   = 400;
   textureName          = "base/data/particles/cloud";
   spinSpeed      = 10.0;
   spinRandomMin      = -50.0;
   spinRandomMax      = 50.0;
   colors[0]     = "0.9 0.9 0.9 0.3";
   colors[1]     = "0.9 0.5 0.6 0.0";
   sizes[0]      = 0.25;
   sizes[1]      = 0.75;

   useInvAlpha = true;
};
datablock ParticleEmitterData(gunExplosionEmitter)
{
   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 2;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 89;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunExplosionParticle";

   useEmitterColors = true;
   uiName = "Gun Hit Dust";
};


datablock ParticleData(gunExplosionRingParticle)
{
   dragCoefficient      = 8;
   gravityCoefficient   = -0.5;
   inheritedVelFactor   = 0.2;
   constantAcceleration = 0.0;
   lifetimeMS           = 50;
   lifetimeVarianceMS   = 35;
   textureName          = "base/data/particles/star1";
   spinSpeed      = 500.0;
   spinRandomMin      = -500.0;
   spinRandomMax      = 500.0;
   colors[0]     = "1 1 0.0 0.9";
   colors[1]     = "0.9 0.0 0.0 0.0";
   sizes[0]      = 1;
   sizes[1]      = 0;

   useInvAlpha = false;
};
datablock ParticleEmitterData(gunExplosionRingEmitter)
{
   lifeTimeMS = 50;

   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 0;
   velocityVariance = 0.0;
   ejectionOffset   = 0.0;
   thetaMin         = 89;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunExplosionRingParticle";

   useEmitterColors = true;
   uiName = "Gun Hit Flash";
};

datablock ExplosionData(gunExplosion)
{
   //explosionShape = "";
   soundProfile = bulletHitSound;

   lifeTimeMS = 150;

   particleEmitter = gunExplosionEmitter;
   particleDensity = 5;
   particleRadius = 0.2;

   emitter[0] = gunExplosionRingEmitter;

   faceViewer     = true;
   explosionScale = "1 1 1";

   shakeCamera = false;
   camShakeFreq = "10.0 11.0 10.0";
   camShakeAmp = "1.0 1.0 1.0";
   camShakeDuration = 0.5;
   camShakeRadius = 10.0;

   // Dynamic light
   lightStartRadius = 0;
   lightEndRadius = 2;
   lightStartColor = "0.3 0.6 0.7";
   lightEndColor = "0 0 0";
};


AddDamageType("Gun",   '<bitmap:add-ons/Weapon_Gun/CI_gun> %1',    '%2 <bitmap:add-ons/Weapon_Gun/CI_gun> %1',0.2,1);
datablock ProjectileData(gunProjectile)
{
   projectileShapeName = "./bullet.dts";
   directDamage        = 30;
   directDamageType    = $DamageType::Gun;
   radiusDamageType    = $DamageType::Gun;

   brickExplosionRadius = 0;
   brickExplosionImpact = true;          //destroy a brick if we hit it directly?
   brickExplosionForce  = 10;
   brickExplosionMaxVolume = 1;          //max volume of bricks that we can destroy
   brickExplosionMaxVolumeFloati ng = 2;  //max volume of bricks that we can destroy if they aren't connected to the ground

   impactImpulse        = 400;
   verticalImpulse     = 400;
   explosion           = gunExplosion;
   particleEmitter     = ""; //bulletTrailEmitter;

   muzzleVelocity      = 90;
   velInheritFactor    = 1;

   armingDelay         = 00;
   lifetime            = 4000;
   fadeDelay           = 3500;
   bounceElasticity    = 0.5;
   bounceFriction      = 0.20;
   isBallistic         = false;
   gravityMod = 0.0;

   hasLight    = false;
   lightRadius = 3.0;
   lightColor  = "0 0 0.5";

   uiName = "Gun Bullet";
};

//////////
// item //
//////////
datablock ItemData(GunItem)
{
   category = "Weapon";  // Mission editor category
   className = "Weapon"; // For inventory system

    // Basic Item Properties
   shapeFile = "./pistol.dts";
   rotate = false;
   mass = 1;
   density = 0.2;
   elasticity = 0.2;
   friction = 0.6;
   emap = true;

   //gui stuff
   uiName = "Gun";
   iconName = "./icon_gun";
   doColorShift = true;
   colorShiftColor = "0.25 0.25 0.25 1.000";

    // Dynamic properties defined by the scripts
   image = gunImage;
   canDrop = true;
};

////////////////
//weapon image//
////////////////
datablock ShapeBaseImageData(gunImage)
{
   // Basic Item properties
   shapeFile = "./pistol.dts";
   emap = true;

   // Specify mount point & offset for 3rd person, and eye offset
   // for first person rendering.
   mountPoint = 0;
   offset = "0 0 0";
   eyeOffset = 0; //"0.7 1.2 -0.5";
   rotation = eulerToMatrix( "0 0 0" );

   // When firing from a point offset from the eye, muzzle correction
   // will adjust the muzzle vector to point to the eye LOS point.
   // Since this weapon doesn't actually fire from the muzzle point,
   // we need to turn this off. 
   correctMuzzleVector = true;

   // Add the WeaponImage namespace as a parent, WeaponImage namespace
   // provides some hooks into the inventory system.
   className = "WeaponImage";

   // Projectile && Ammo.
   item = BowItem;
   ammo = " ";
   projectile = gunProjectile;
   projectileType = Projectile;

   casing = gunShellDebris;
   shellExitDir        = "1.0 -1.3 1.0";
   shellExitOffset     = "0 0 0";
   shellExitVariance   = 15.0;   
   shellVelocity       = 7.0;

   //melee particles shoot from eye node for consistancy
   melee = false;
   //raise your arm up or not
   armReady = true;

   doColorShift = true;
   colorShiftColor = gunItem.colorShiftColor;//"0.400 0.196 0 1.000";

   //casing = " ";

   // Images have a state system which controls how the animations
   // are run, which sounds are played, script callbacks, etc. This
   // state system is downloaded to the client so that clients can
   // predict state changes and animate accordingly.  The following
   // system supports basic ready->fire->reload transitions as
   // well as a no-ammo->dryfire idle state.

   // Initial start up state
   stateName[0]                     = "Activate";
   stateTimeoutValue[0]             = 0.15;
   stateTransitionOnTimeout[0]       = "Ready";
   stateSound[0]               = weaponSwitchSound;

   stateName[1]                     = "Ready";
   stateTransitionOnTriggerDown[1]  = "Fire";
   stateAllowImageChange[1]         = true;
   stateSequence[1]   = "Ready";

   stateName[2]                    = "Fire";
   stateTransitionOnTimeout[2]     = "Smoke";
   stateTimeoutValue[2]            = 0.14;
   stateFire[2]                    = true;
   stateAllowImageChange[2]        = false;
   stateSequence[2]                = "Fire";
   stateScript[2]                  = "onFire";
   stateWaitForTimeout[2]         = true;
   stateEmitter[2]               = gunFlashEmitter;
   stateEmitterTime[2]            = 0.05;
   stateEmitterNode[2]            = "muzzleNode";
   stateSound[2]               = gunShot1Sound;
   stateEjectShell[2]       = true;

   stateName[3] = "Smoke";
   stateEmitter[3]               = gunSmokeEmitter;
   stateEmitterTime[3]            = 0.05;
   stateEmitterNode[3]            = "muzzleNode";
   stateTimeoutValue[3]            = 0.01;
   stateTransitionOnTimeout[3]     = "Reload";

   stateName[4]         = "Reload";
   stateSequence[4]                = "Reload";
   stateTransitionOnTriggerUp[4]     = "Ready";
   stateSequence[4]   = "Ready";

};

function gunImage::onFire(%this,%obj,%slot)
{
   if(%obj.getDamagePercent() < 1.0)
      %obj.playThread(2, shiftAway);
   Parent::onFire(%this,%obj,%slot);   
}

Code: [Select]
It looks very long. But not as long as it looks.
Also, don't use sketchup alone. Possibly use it as a rough model and then import it into another modeling program.

Heres your tutor for Blender if you chose it: http://www.youtube.com/user/super3boy
And MS3D... Well not really sure but I garantee you its easier than Blender.

it souldent be easy cause i dont even no how

Holy stuff, people are still asking? [/sarcasm]
I'll make a topic after school. It'll take me a while.

If you're going to start making add-ons then I recommend you not release any of the first products unless you are ABSOLUTELY CERTAIN they don't have any errors in them. If you don't even know how to check for errors then just don't release anything at all. Furthermore, I recommend you not release anything unless it meets some simple criteria I'll list shortly.

Anyways as for add-on making in general it will depend on what content you want to work on, which come in some general flavours

- Items/vehicles/weapons (includes emitters and lights and other simple modifications)
- Maps
- Decals
- More elaborate functions and scripts (GUI systems, Events, complex utilities like the duplicator, etc.)

The 3 first parts can be handled easily by anyone and everyone but you'll probably be taking a wack at the first item on the list. All you'll need in that case is a Model with the correct nodes/joints and a script to go with it. Map making requires some particular programs, or if you know how to use the map editor you can change current maps (not recommended). Decal making is easy, however making good looking decals is hard. The last part requires some in-depth knowledge of Scripting, more particularly in the C++ field. I don't think you're ready for that yet.

*** Most people make a nice model, sure, but they neglect the script and just insert a pre-made script to go with the model (gun script, minigun script, rocket launcher script, etc.). NO ONE WILL DOWNLOAD YOUR ADD-ON IF IT'S ONLY A MODEL EDIT, EVEN IF THE MODEL IS FANTASTIC FOR WHATEVER REASON.

In all honesty, the current add-ons on blockland could look and handle allot better in almost every aspect, not just visually. Weapon and Vehicle scripts are probably the most overlooked aspects of add-ons, which is a shame because some weapon models are very pretty but end up firing gun bullets with rocket launcher explosions. Scripts are currently a copy-paste job in most cases. Please be original. If you want to make the absolute best add-ons then you'll have to scrutinize Everything, especially the script.


Things you'll need to make a good weapon:

- Originality ; and for that you'll need some good ideas. Go check out Suggestions and Requests if you can't think of anything.
- Custom weapon model and Custom projectile model ;  if it's required
- Custom script ;  with it's own unique Emitters/Explosion effects, projectile  effects, imageStates, etc.)
- Needs to be something like a toy ; as in Blocko. Not a WW2 m80 grahand 52K4 or whatever generic gun. There are more then enough of those already
- *** Needs to work ***

Vehicles are the same deal, however they are much more complex so we can expect you'll be fluent in this business by the time you become able to make vehicles at all.


There are several guides to modelling and general add-on making already on these forums. Use the button at the top of the page to search for specific items. Script related problems go in Coding Help. Model related is usually in General Modification Help. Modification Discussion is used to discuss projects and whatnot, check it out if you want to see what others are up to.

Finally, diligence pays off in the end. A single awesome add-on beats 10 other add-ons that you just pumped out on a "whim", so please invest time and effort into making them. You'll be up and making quality add-ons in no time, but in the meantime be patient and experiment only.
« Last Edit: January 12, 2009, 12:49:20 PM by Muffinmix »


:nes;
Lol screw up...
Code: [Select]
[size=3pt]//gun.cs

//audio
datablock AudioProfile(gunShot1Sound)
{
   filename    = "./gunShot1.wav";
   description = AudioClose3d;
   preload = true;
};
datablock AudioProfile(bulletHitSound)
{
   filename    = "./bulletHit.wav";
   description = AudioClose3d;
   preload = true;
};


//shell
datablock DebrisData(gunShellDebris)
{
shapeFile = "./gunShell.dts";
lifetime = 2.0;
minSpinSpeed = -400.0;
maxSpinSpeed = 200.0;
elasticity = 0.5;
friction = 0.2;
numBounces = 3;
staticOnMaxBounce = true;
snapOnMaxBounce = false;
fade = true;

gravModifier = 2;
};


//muzzle flash effects
datablock ParticleData(gunFlashParticle)
{
dragCoefficient      = 3;
gravityCoefficient   = -0.5;
inheritedVelFactor   = 0.2;
constantAcceleration = 0.0;
lifetimeMS           = 25;
lifetimeVarianceMS   = 15;
textureName          = "base/data/particles/star1";
spinSpeed = 10.0;
spinRandomMin = -500.0;
spinRandomMax = 500.0;
colors[0]     = "0.9 0.9 0.0 0.9";
colors[1]     = "0.9 0.5 0.0 0.0";
sizes[0]      = 0.5;
sizes[1]      = 1.0;

useInvAlpha = false;
};
datablock ParticleEmitterData(gunFlashEmitter)
{
   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 1.0;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunFlashParticle";

   uiName = "Gun Flash";
};

datablock ParticleData(gunSmokeParticle)
{
dragCoefficient      = 3;
gravityCoefficient   = -0.5;
inheritedVelFactor   = 0.2;
constantAcceleration = 0.0;
lifetimeMS           = 525;
lifetimeVarianceMS   = 55;
textureName          = "base/data/particles/cloud";
spinSpeed = 10.0;
spinRandomMin = -500.0;
spinRandomMax = 500.0;
colors[0]     = "0.5 0.5 0.5 0.9";
colors[1]     = "0.5 0.5 0.5 0.0";
sizes[0]      = 0.15;
sizes[1]      = 0.15;

useInvAlpha = false;
};
datablock ParticleEmitterData(gunSmokeEmitter)
{
   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 1.0;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunSmokeParticle";

   uiName = "Gun Smoke";
};


datablock ParticleData(gunExplosionParticle)
{
dragCoefficient      = 8;
gravityCoefficient   = 1;
inheritedVelFactor   = 0.2;
constantAcceleration = 0.0;
lifetimeMS           = 700;
lifetimeVarianceMS   = 400;
textureName          = "base/data/particles/cloud";
spinSpeed = 10.0;
spinRandomMin = -50.0;
spinRandomMax = 50.0;
colors[0]     = "0.9 0.9 0.9 0.3";
colors[1]     = "0.9 0.5 0.6 0.0";
sizes[0]      = 0.25;
sizes[1]      = 0.75;

useInvAlpha = true;
};
datablock ParticleEmitterData(gunExplosionEmitter)
{
   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 2;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 89;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunExplosionParticle";

   useEmitterColors = true;
   uiName = "Gun Hit Dust";
};


datablock ParticleData(gunExplosionRingParticle)
{
dragCoefficient      = 8;
gravityCoefficient   = -0.5;
inheritedVelFactor   = 0.2;
constantAcceleration = 0.0;
lifetimeMS           = 50;
lifetimeVarianceMS   = 35;
textureName          = "base/data/particles/star1";
spinSpeed = 500.0;
spinRandomMin = -500.0;
spinRandomMax = 500.0;
colors[0]     = "1 1 0.0 0.9";
colors[1]     = "0.9 0.0 0.0 0.0";
sizes[0]      = 1;
sizes[1]      = 0;

useInvAlpha = false;
};
datablock ParticleEmitterData(gunExplosionRingEmitter)
{
lifeTimeMS = 50;

   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 0;
   velocityVariance = 0.0;
   ejectionOffset   = 0.0;
   thetaMin         = 89;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvance = false;
   particles = "gunExplosionRingParticle";

   useEmitterColors = true;
   uiName = "Gun Hit Flash";
};

datablock ExplosionData(gunExplosion)
{
   //explosionShape = "";
soundProfile = bulletHitSound;

   lifeTimeMS = 150;

   particleEmitter = gunExplosionEmitter;
   particleDensity = 5;
   particleRadius = 0.2;

   emitter[0] = gunExplosionRingEmitter;

   faceViewer     = true;
   explosionScale = "1 1 1";

   shakeCamera = false;
   camShakeFreq = "10.0 11.0 10.0";
   camShakeAmp = "1.0 1.0 1.0";
   camShakeDuration = 0.5;
   camShakeRadius = 10.0;

   // Dynamic light
   lightStartRadius = 0;
   lightEndRadius = 2;
   lightStartColor = "0.3 0.6 0.7";
   lightEndColor = "0 0 0";
};


AddDamageType("Gun",   '<bitmap:add-ons/Weapon_Gun/CI_gun> %1',    '%2 <bitmap:add-ons/Weapon_Gun/CI_gun> %1',0.2,1);
datablock ProjectileData(gunProjectile)
{
   projectileShapeName = "./bullet.dts";
   directDamage        = 30;
   directDamageType    = $DamageType::Gun;
   radiusDamageType    = $DamageType::Gun;

   brickExplosionRadius = 0;
   brickExplosionImpact = true;          //destroy a brick if we hit it directly?
   brickExplosionForce  = 10;
   brickExplosionMaxVolume = 1;          //max volume of bricks that we can destroy
   brickExplosionMaxVolumeFloating = 2;  //max volume of bricks that we can destroy if they aren't connected to the ground

   impactImpulse      = 400;
   verticalImpulse   = 400;
   explosion           = gunExplosion;
   particleEmitter     = ""; //bulletTrailEmitter;

   muzzleVelocity      = 90;
   velInheritFactor    = 1;

   armingDelay         = 00;
   lifetime            = 4000;
   fadeDelay           = 3500;
   bounceElasticity    = 0.5;
   bounceFriction      = 0.20;
   isBallistic         = false;
   gravityMod = 0.0;

   hasLight    = false;
   lightRadius = 3.0;
   lightColor  = "0 0 0.5";

   uiName = "Gun Bullet";
};

//////////
// item //
//////////
datablock ItemData(GunItem)
{
category = "Weapon";  // Mission editor category
className = "Weapon"; // For inventory system

// Basic Item Properties
shapeFile = "./pistol.dts";
rotate = false;
mass = 1;
density = 0.2;
elasticity = 0.2;
friction = 0.6;
emap = true;

//gui stuff
uiName = "Gun";
iconName = "./icon_gun";
doColorShift = true;
colorShiftColor = "0.25 0.25 0.25 1.000";

// Dynamic properties defined by the scripts
image = gunImage;
canDrop = true;
};

////////////////
//weapon image//
////////////////
datablock ShapeBaseImageData(gunImage)
{
   // Basic Item properties
   shapeFile = "./pistol.dts";
   emap = true;

   // Specify mount point & offset for 3rd person, and eye offset
   // for first person rendering.
   mountPoint = 0;
   offset = "0 0 0";
   eyeOffset = 0; //"0.7 1.2 -0.5";
   rotation = eulerToMatrix( "0 0 0" );

   // When firing from a point offset from the eye, muzzle correction
   // will adjust the muzzle vector to point to the eye LOS point.
   // Since this weapon doesn't actually fire from the muzzle point,
   // we need to turn this off. 
   correctMuzzleVector = true;

   // Add the WeaponImage namespace as a parent, WeaponImage namespace
   // provides some hooks into the inventory system.
   className = "WeaponImage";

   // Projectile && Ammo.
   item = BowItem;
   ammo = " ";
   projectile = gunProjectile;
   projectileType = Projectile;

casing = gunShellDebris;
shellExitDir        = "1.0 -1.3 1.0";
shellExitOffset     = "0 0 0";
shellExitVariance   = 15.0;
shellVelocity       = 7.0;

   //melee particles shoot from eye node for consistancy
   melee = false;
   //raise your arm up or not
   armReady = true;

   doColorShift = true;
   colorShiftColor = gunItem.colorShiftColor;//"0.400 0.196 0 1.000";

   //casing = " ";

   // Images have a state system which controls how the animations
   // are run, which sounds are played, script callbacks, etc. This
   // state system is downloaded to the client so that clients can
   // predict state changes and animate accordingly.  The following
   // system supports basic ready->fire->reload transitions as
   // well as a no-ammo->dryfire idle state.

   // Initial start up state
stateName[0]                     = "Activate";
stateTimeoutValue[0]             = 0.15;
stateTransitionOnTimeout[0]       = "Ready";
stateSound[0] = weaponSwitchSound;

stateName[1]                     = "Ready";
stateTransitionOnTriggerDown[1]  = "Fire";
stateAllowImageChange[1]         = true;
stateSequence[1] = "Ready";

stateName[2]                    = "Fire";
stateTransitionOnTimeout[2]     = "Smoke";
stateTimeoutValue[2]            = 0.14;
stateFire[2]                    = true;
stateAllowImageChange[2]        = false;
stateSequence[2]                = "Fire";
stateScript[2]                  = "onFire";
stateWaitForTimeout[2] = true;
stateEmitter[2] = gunFlashEmitter;
stateEmitterTime[2] = 0.05;
stateEmitterNode[2] = "muzzleNode";
stateSound[2] = gunShot1Sound;
stateEjectShell[2]       = true;

stateName[3] = "Smoke";
stateEmitter[3] = gunSmokeEmitter;
stateEmitterTime[3] = 0.05;
stateEmitterNode[3] = "muzzleNode";
stateTimeoutValue[3]            = 0.01;
stateTransitionOnTimeout[3]     = "Reload";

stateName[4] = "Reload";
stateSequence[4]                = "Reload";
stateTransitionOnTriggerUp[4]     = "Ready";
stateSequence[4] = "Ready";

};

function gunImage::onFire(%this,%obj,%slot)
{
if(%obj.getDamagePercent() < 1.0)
%obj.playThread(2, shiftAway);
Parent::onFire(%this,%obj,%slot);
}
[/size]
1. Fixed
2. What. The. forget.

Honestly before you even try you should do both of these:

1. Learn to model which is basically simple.

2. Before getting into ANYTHING complex try to mess with an existing weapon script. ex.: Make the gun blue, change the sounds it makes, and make it shake the screen.

Hope I was of any help.