Jump to content

Jedi Academy turned 20 this year! We celebrated in a ton of different ways: mod contest, server event, podcast, etc. Thank you to all who have been a part of this game for the last two decades. Check out the anniversary content!

Read more

Welcome to JKHub

This community is dedicated to the games Star Wars: Jedi Outcast (2002) and Jedi Academy (2003). We host over 3,000 mods created by passionate fans around the world, and thousands of threads of people showcasing their works in progress and asking for assistance. From mods to art to troubleshooting help, we probably have it. If we don't, request or contribute!

Get started

This game turned 20 years old this year, and it is still one of the greatest Star Wars games of all time. If you're new or returning from a long hiatus, here are the basics of getting started with Star Wars Jedi Knight Jedi Academy in 2023.

Read more

Adding a New Weapon (Single Player game)


Asgarath83

JKHub staff note: TODO, this is broken

 

 

HOW TO MAKE A NEW WEAPON – SINGLE PLAYER

 

 

 

Before i start i wanna told that i am not an expert coder. i learn many of this studying the eezstreet tutorial about make a new weapon into the multiplayer, and searching into SP code all results about the WP_TUSKEN_RIFLE. so i locate all part i need to edit for add new weapon. this weapon i share with your is simply another blaster pistol with charge fire alt function, nothing more, nothing less. but an expert code can make every kind of wonderful weapon with any kind of shoot, alt shoot, damage and balistic of projectile. i am sure you can make best of me, all you need is to know as much C++ as you can. i really advice you to read all eezstreet tutorial for learn the basic about this.

 

add a new weapon into SP game is difficult and you need really a big amount of coding work.

 

are you ready? let we start!

 

 

 

Welcome to alls! In this tutorial i wanna tell you how you can add a new weapon to the weapons of the Single player game.

 

I wanna to share with you the code of my bloodgun weapon. It’s act like the blaster pistol, but do a little more damage.

 

 

 

What you need:

 

1 Microsoft visual studio 2010 \ 2012

 

2 OpenJk

 

3 a model of a textured and shaded shooting weapons.

 

4 efx of muzzle flash, alt muzzle flash, projectiles, wall impact, alt impacts and an optional flesh \ droid impacts.

 

5 a weapon icon.

 

You got all that?

 

Good! We start!

 

 

 

First off... add your weapon.

 

Open code/qcommon/q_shared.h

 

Find this line:

 

#define MAX_WEAPONS 28

edit to

 

 

 

#define MAX_WEAPONS 32

Attention: unfortunaley, without a large editing of the coding arrays system, you cannot add more of 32 weapons. According with ensiform and ent, more of 32 weapon enumerated will cause crashing of the savegames. The engine need to allocate memory for every new thing you add to code. If you are not expert programmers or coders, not add more of 32 weapons, you need really to edit a large amount of code for expand the storing cache memory. The 32 bit memory system of JKA cannot manage more of that value, sorry. I tryed to add more of 32 weapons, but the 33th weapon inexorabile still crashing.

 

 

 

Okay, now you need to add weapons to enumeration:

 

Go to.

 

Code/game/weapons.H

 

 

 

c[]
typedef enum //# weapon_e
{
  WP_NONE,

  // Player weapons
  WP_SABER, // player and NPC weapon
  WP_BLASTER_PISTOL, // player and NPC weapon
  WP_BLASTER, // player and NPC weapon
  WP_DISRUPTOR, // player and NPC weapon
  WP_BOWCASTER, // NPC weapon - player can pick this up, but never starts with them
  WP_REPEATER, // NPC weapon - player can pick this up, but never starts with them
  WP_DEMP2, // NPC weapon - player can pick this up, but never starts with them
  WP_FLECHETTE, // NPC weapon - player can pick this up, but never starts with them
  WP_ROCKET_LAUNCHER, // NPC weapon - player can pick this up, but never starts with them
  WP_THERMAL, // player and NPC weapon
  WP_TRIP_MINE, // NPC weapon - player can pick this up, but never starts with them
  WP_DET_PACK, // NPC weapon - player can pick this up, but never starts with them
  WP_CONCUSSION, // NPC weapon - player can pick this up, but never starts with them

  //extras
  WP_MELEE, // player and NPC weapon - Any ol' melee attack

  //when in atst
  WP_ATST_MAIN,
  WP_ATST_SIDE,

  // These can never be gotten directly by the player
  WP_STUN_BATON, // stupid weapon, should remove

  //NPC weapons
  WP_BRYAR_PISTOL, // NPC weapon - player can pick this up, but never starts with them

  WP_EMPLACED_GUN,

  WP_BOT_LASER, // Probe droid      - Laser blast

  WP_TURRET, // turret guns 

  WP_TIE_FIGHTER,

  WP_RAPID_FIRE_CONC,

  WP_JAWA,
  WP_TUSKEN_RIFLE,
  WP_TUSKEN_STAFF,
  WP_SCEPTER,
  WP_NOGHRI_STICK,
  WP_BLOODGUN,
  WP_CANNON,
  WP_POISON,

  //# #eol
  WP_NUM_WEAPONS
}
weapon_t;

#define FIRST_WEAPON WP_SABER // this is the first weapon for next and prev weapon switching
#define MAX_PLAYER_WEAPONS WP_POISON // WP_POISON         // this is the max you can switch to and get with the give all. - FIXME: it's actually this one *minus* one... why?
// WP_STUN_BATON

 

 

 

as you can see, i tryed to add more of 32 weapons, i put on green the weapons engine cannot supports. On SP game you can add only 3 new weapon. Put the new name at the end of the enumeration, between WP_NOGHRI_STICK and WP_NUM_WEAPONS. Why at the end of the enumeration? Because engine expect that some weapons get a specific value of the enum list. So is better to add at the end so, this not change the enumeration of the default weapons game. That’s avoid potentially conflict.

 

As you can see on the MAX_PLAYERS_WEAPONS i edited with the last weapon of my array. This unlock all npc weapons and you can give it to the player with the “give weapon_*NAME* cheat. Of the consolle. Jawa weapon is unfinished, atst side not work on player hands, and noghri stick crash when you fire. You are warning about this.

 

 

 

Okay now we pass to the second step.

 

Go down to weapons.h and you can see a large array of parameter relative of NPC damage and speed of every weapon.

 

You need to think about this. How will act your weapon? You wanna make a blaster pistol kind weapons? Or a flechette kind weapons? Or a concussion kind weapon? It’s time to think about this.

 

I assume you wanna make a new blaster pistol weapon. So you need to add these values:

 

// Blood Gun
//--------
#define BLOODGUN_VEL 2500
#define BLOODGUN_DAMAGE 20
#define BLOODGUN_CHARGE_UNIT 200.0 f // bryar charging gives us one more unit every 200ms--if you change this, you'll have to do the same in bg_pmove

you can define every kind amount of damage, npc damage, velocity of projectiles, and charging floating parameter if you wanna make a charging weapon. You need to copy the definition of the weapon you wanna use as example for you custom weapons and change they to the custom definition name. Remember this names. They are importart. Because they will called by all function that will make your weapons working.

 

 

 

We end on weapons.h

 

Open now code/game/g_items.h

 

Find this enumeration

 

// Items enums
enum {
  ITM_NONE,

  ITM_SABER_PICKUP,
  ITM_BLASTER_PISTOL_PICKUP,
  ITM_BLASTER_PICKUP,
  ITM_DISRUPTOR_PICKUP,
  ITM_BOWCASTER_PICKUP,
  ITM_REPEATER_PICKUP,
  ITM_DEMP2_PICKUP,

At the end add this after itm_sectury_key:

 

 

 

ITM_SECURITY_KEY_PICKUP,
ITM_BLOODGUN_PICKUP,

This is necessary if you want your weapon is recognized by weapons.dat external data. Now open g_itemload.cpp

 

Find this

 

 

 

else if (!Q_stricmp(tokenStr,"WP_NOGHRI_STICK"))
tag = WP_NOGHRI_STICK;

below add

 

 

 

else if (!Q_stricmp(tokenStr,"WP_BLOODGUN"))
tag = WP_BLOODGUN;

 

this is necessary also for MP client. Your weapons will be now recognized as item available and pickable on the map. If you don’t it, npcs and player cannot use it. Also you cannot use “give weapon_” fuction.

 

 

 

Now open the q3_interface.cpp

 

Search this string array

 

stringID_table_t WPTable[] = {
  {
    "NULL",
    WP_NONE
  },
  ENUM2STRING(WP_NONE),
  // Player weapons
  ENUM2STRING(WP_SABER), // NOTE: lots of code assumes this is the first weapon (... which is crap) so be careful -Ste.
  ENUM2STRING(WP_BLASTER_PISTOL), // apparently some enemy only version of the blaster
  ENUM2STRING(WP_BLASTER),
  ENUM2STRING(WP_DISRUPTOR),
  ENUM2STRING(WP_BOWCASTER),
  ENUM2STRING(WP_REPEATER),
  ENUM2STRING(WP_DEMP2),
  ENUM2STRING(WP_FLECHETTE),
  ENUM2STRING(WP_ROCKET_LAUNCHER),
  ENUM2STRING(WP_THERMAL),
  ENUM2STRING(WP_TRIP_MINE),
  ENUM2STRING(WP_DET_PACK),
  ENUM2STRING(WP_CONCUSSION),
  ENUM2STRING(WP_MELEE), // Any ol' melee attack
  //NOTE: player can only have up to 16 weapons), anything after that is enemy only
  ENUM2STRING(WP_STUN_BATON),
  // NPC enemy weapons
  ENUM2STRING(WP_BRYAR_PISTOL),
  ENUM2STRING(WP_EMPLACED_GUN),
  ENUM2STRING(WP_BOT_LASER), // Probe droid      - Laser blast
  ENUM2STRING(WP_TURRET), // turret guns 
  ENUM2STRING(WP_ATST_MAIN),
  ENUM2STRING(WP_ATST_SIDE),
  ENUM2STRING(WP_TIE_FIGHTER),
  ENUM2STRING(WP_RAPID_FIRE_CONC),
  ENUM2STRING(WP_JAWA),
  ENUM2STRING(WP_TUSKEN_RIFLE),
  ENUM2STRING(WP_TUSKEN_STAFF),
  ENUM2STRING(WP_SCEPTER),
  ENUM2STRING(WP_NOGHRI_STICK),
  ENUM2STRING(WP_BLOODGUN),
  ENUM2STRING(WP_CANNON),
  ENUM2STRING(WP_POISON),
  {
    "",
    0
  }
};

after noghri_stick you can add you new weapons.

 

What make this? This allow to the weapons to be recognized from external data files of JKA. On weapons.dat now you can define all paramter of your weapons relative to muzzleeffect, altmuzzleefx, kind of ammo, icon, etc etc. Also, with this you can get your new weapons to the Npcs! They can use the new weapon against you! When they die, the weapons will be dropped and you can pickup and gain ammo. This is the finality or this edit.

 

 

 

Now the hardest part. Open weapons.dat into ext_data folder of your mod.

 

After the noghri stick branks parameter you need to add the paramer of your new weapons. In that case...

 

// WP_BLOODGUN – PUT YOUR DESCRIPTION 
{
  weapontype WP_BLOODGUN
  weaponclass weapon_bloodgun
  weaponmodel models / weapons2 / bloodgun / bloodgun.md3
  weaponIcon gfx / hud / w_icon_bloodgun
  missileFuncName bloodgun_func
  altmissileFuncName bloodgun_alt_func
  ammotype 2
  ammolowcount 10
  energypershot 10
  firetime 600
  range 8192
  altenergypershot 20
  altfiretime 500
  altrange 8192
  muzzleEffect bloodgun / muzzle_flash
  altmuzzleEffect bloodgun / altmuzzle_flash
  altchargesound sound / weapons / bloodgun / altcharge.wav
  selectSound sound / weapons / bloodgun / select.wav
  selectforce fffx / weapons / bryar / select
  damage 40
  altdamage 50
}

Okay, now opens item.dat and add this on the item list:

 

{
  itemname ITM_BLOODGUN_PICKUP

  classname weapon_bloodgun
  worldmodel models / weapons2 / bloodgun / bloodgun.md3
    // Amount of ammo given with weapon
  count 500
  type IT_WEAPON
  tag WP_BLOODGUN
}

and now you understand why you need to edit the items.h and itemload.cpp file: because that’s allow items.dat to recognize your weapon as item usable and pickable.

 

Now the hardest part! Programming your weapon!

 

Open g_weaponload.cpp

 

 

 

At the start of the file you can see a large amount of void definition. They define the function of the visual efx of the weapons. Add this for your new pistol:

 

// Blood Gun shot
void FX_BloodGunProjectileThink(centity_t * cent,
  const struct weaponInfo_s * weapon);
void FX_BloodGunAltProjectileThink(centity_t * cent,
  const struct weaponInfo_s * weapon);

below you can find this:

 

// Table used to attach an extern missile function string to the actual cgame function
func_t funcs[] = {
    {
      "bryar_func",
      FX_BryarProjectileThink
    },
    {
      "bryar_alt_func",
      FX_BryarAltProjectileThink
    },

add into the table:

 

{"bloodgun_func", FX_BloodGunProjectileThink},
{"bloodgun_alt_func", FX_BloodGunAltProjectileThink},

this is used by weapon.dat for call the function of the efx of the projectiles of your weapons, for main and altfire.

 

 

 

Below, you can find this:

 

// This is used as a fallback for each new field, in case they're using base files --eez
const int defaultDamage[] = {
  0, // WP_NONE
  0, // WP_SABER                      // handled elsewhere
  BRYAR_PISTOL_DAMAGE, // WP_BLASTER_PISTOL
  BLASTER_DAMAGE, // WP_BLASTER
  DISRUPTOR_MAIN_DAMAGE, // WP_DISRUPTOR
  BOWCASTER_DAMAGE, // WP_BOWCASTER
  REPEATER_DAMAGE, // WP_REPEATER
  DEMP2_DAMAGE, // WP_DEMP2
  FLECHETTE_DAMAGE, // WP_FLECHETTE
  ROCKET_DAMAGE, // WP_ROCKET_LAUNCHER
  TD_DAMAGE, // WP_THERMAL
  LT_DAMAGE, // WP_TRIP_MINE
  FLECHETTE_MINE_DAMAGE, // WP_DET_PACK             // HACK, this is what the code sez.
  CONC_DAMAGE, // WP_CONCUSSION

  0, // WP_MELEE                      // handled by the melee attack function

  ATST_MAIN_DAMAGE, // WP_ATST_MAIN
  ATST_SIDE_MAIN_DAMAGE, // WP_ATST_SIDE

  STUN_BATON_DAMAGE, // WP_STUN_BATON

  BRYAR_PISTOL_DAMAGE, // WP_BRYAR_PISTOL
  EMPLACED_DAMAGE, // WP_EMPLACED_GUN
  BRYAR_PISTOL_DAMAGE, // WP_BOT_LASER
  0, // WP_TURRET               // handled elsewhere
  EMPLACED_DAMAGE, // WP_TIE_FIGHTER
  EMPLACED_DAMAGE, // WP_RAPID_FIRE_CONC,

  BRYAR_PISTOL_DAMAGE, // WP_JAWA
  0, // WP_TUSKEN_RIFLE
  0, // WP_TUSKEN_STAFF
  0, // WP_SCEPTER
  0, // WP_NOGHRI_STICK
  BLOODGUN_DAMAGE, // WP_BLOODGUN
  CANNON_DAMAGE, // WP_CANNON
  POISON_DAMAGE, // WP_POISON
};

the value follow the enumeration of weapons.h, at the position of the number of your new weapon you need to add a voice like i did. The kind of voice depend by the kind of your weapons. As you can see, the weapons there not use a limitated number of ammos get the 0 value.

 

You need to make the same thinks also for defaultaltdamage, splashdamage,splashradius, altsplashdamage, altsplashradius.

 

const int defaultAltDamage[] = {
  0, // WP_NONE
  0, // WP_SABER                            // handled elsewhere
  BRYAR_PISTOL_DAMAGE, // WP_BLASTER_PISTOL
  BLASTER_DAMAGE, // WP_BLASTER
  DISRUPTOR_ALT_DAMAGE, // WP_DISRUPTOR
  BOWCASTER_DAMAGE, // WP_BOWCASTER
  REPEATER_ALT_DAMAGE, // WP_REPEATER
  DEMP2_ALT_DAMAGE, // WP_DEMP2
  FLECHETTE_ALT_DAMAGE, // WP_FLECHETTE
  ROCKET_DAMAGE, // WP_ROCKET_LAUNCHER
  TD_ALT_DAMAGE, // WP_THERMAL
  LT_DAMAGE, // WP_TRIP_MINE
  FLECHETTE_MINE_DAMAGE, // WP_DET_PACK                   // HACK, this is what the code sez.
  CONC_ALT_DAMAGE, // WP_CONCUSION

  0, // WP_MELEE                            // handled by the melee attack function

  ATST_MAIN_DAMAGE, // WP_ATST_MAIN
  ATST_SIDE_ALT_DAMAGE, // WP_ATST_SIDE

  STUN_BATON_ALT_DAMAGE, // WP_STUN_BATON

  BRYAR_PISTOL_DAMAGE, // WP_BRYAR_PISTOL
  EMPLACED_DAMAGE, // WP_EMPLACED_GUN
  BRYAR_PISTOL_DAMAGE, // WP_BOT_LASER
  0, // WP_TURRET                     // handled elsewhere
  EMPLACED_DAMAGE, // WP_TIE_FIGHTER
  0, // WP_RAPID_FIRE_CONC            // repeater alt damage is used instead

  BRYAR_PISTOL_DAMAGE, // WP_JAWA
  0, // WP_TUSKEN_RIFLE
  0, // WP_TUSKEN_STAFF
  0, // WP_SCEPTER
  0, // WP_NOGHRI_STICK
  BLOODGUN_DAMAGE, // WP_BLOODGUN
  CANNON_ALT_DAMAGE, // WP_CANNON
  POISON_ALT_DAMAGE, // WP_POISON
};

const int defaultSplashDamage[] = {
  0, // WP_NONE
  0, // WP_SABER
  0, // WP_BLASTER_PISTOL
  0, // WP_BLASTER
  0, // WP_DISRUPTOR
  BOWCASTER_SPLASH_DAMAGE, // WP_BOWCASTER
  0, // WP_REPEATER
  0, // WP_DEMP2
  0, // WP_FLECHETTE
  ROCKET_SPLASH_DAMAGE, // WP_ROCKET_LAUNCHER
  TD_SPLASH_DAM, // WP_THERMAL
  LT_SPLASH_DAM, // WP_TRIP_MINE
  FLECHETTE_MINE_SPLASH_DAMAGE, // WP_DET_PACK       // HACK, this is what the code sez.
  CONC_SPLASH_DAMAGE, // WP_CONCUSSION

  0, // WP_MELEE

  0, // WP_ATST_MAIN
  ATST_SIDE_MAIN_SPLASH_DAMAGE, // WP_ATST_SIDE

  0, // WP_STUN_BATON

  0, // WP_BRYAR_PISTOL
  0, // WP_EMPLACED_GUN
  0, // WP_BOT_LASER
  0, // WP_TURRET
  0, // WP_TIE_FIGHTER
  0, // WP_RAPID_FIRE_CONC

  0, // WP_JAWA
  0, // WP_TUSKEN_RIFLE
  0, // WP_TUSKEN_STAFF
  0, // WP_SCEPTER
  0, // WP_NOGHRI_STICK
  0, // WP_BLOODGUN
  0, // WP_CANNON
  0, // WP_POISON
};

const float defaultSplashRadius[] = {
  0.0 f, // WP_NONE
  0.0 f, // WP_SABER
  0.0 f, // WP_BLASTER_PISTOL
  0.0 f, // WP_BLASTER
  0.0 f, // WP_DISRUPTOR
  BOWCASTER_SPLASH_RADIUS, // WP_BOWCASTER
  0.0 f, // WP_REPEATER
  0.0 f, // WP_DEMP2
  0.0 f, // WP_FLECHETTE
  ROCKET_SPLASH_RADIUS, // WP_ROCKET_LAUNCHER
  TD_SPLASH_RAD, // WP_THERMAL
  LT_SPLASH_RAD, // WP_TRIP_MINE
  FLECHETTE_MINE_SPLASH_RADIUS, // WP_DET_PACK       // HACK, this is what the code sez.
  CONC_SPLASH_RADIUS, // WP_CONCUSSION

  0.0 f, // WP_MELEE

  0.0 f, // WP_ATST_MAIN
  ATST_SIDE_MAIN_SPLASH_RADIUS, // WP_ATST_SIDE

  0.0 f, // WP_STUN_BATON

  0.0 f, // WP_BRYAR_PISTOL
  0.0 f, // WP_EMPLACED_GUN
  0.0 f, // WP_BOT_LASER
  0.0 f, // WP_TURRET
  0.0 f, // WP_TIE_FIGHTER
  0.0 f, // WP_RAPID_FIRE_CONC

  0.0 f, // WP_JAWA
  0.0 f, // WP_TUSKEN_RIFLE
  0.0 f, // WP_TUSKEN_STAFF
  0.0 f, // WP_SCEPTER
  0.0 f, // WP_NOGHRI_STICK
};

const int defaultAltSplashDamage[] = {
  0, // WP_NONE
  0, // WP_SABER                // handled elsewhere
  0, // WP_BLASTER_PISTOL
  0, // WP_BLASTER
  0, // WP_DISRUPTOR
  BOWCASTER_SPLASH_DAMAGE, // WP_BOWCASTER
  REPEATER_ALT_SPLASH_DAMAGE, // WP_REPEATER
  DEMP2_ALT_DAMAGE, // WP_DEMP2
  FLECHETTE_ALT_SPLASH_DAM, // WP_FLECHETTE
  ROCKET_SPLASH_DAMAGE, // WP_ROCKET_LAUNCHER
  TD_ALT_SPLASH_DAM, // WP_THERMAL
  TD_ALT_SPLASH_DAM, // WP_TRIP_MINE
  FLECHETTE_MINE_SPLASH_DAMAGE, // WP_DET_PACK       // HACK, this is what the code sez.
  0, // WP_CONCUSSION

  0, // WP_MELEE                // handled by the melee attack function

  0, // WP_ATST_MAIN
  ATST_SIDE_ALT_SPLASH_DAMAGE, // WP_ATST_SIDE

  0, // WP_STUN_BATON

  0, // WP_BRYAR_PISTOL
  0, // WP_EMPLACED_GUN
  0, // WP_BOT_LASER
  0, // WP_TURRET         // handled elsewhere
  0, // WP_TIE_FIGHTER
  0, // WP_RAPID_FIRE_CONC

  0, // WP_JAWA
  0, // WP_TUSKEN_RIFLE
  0, // WP_TUSKEN_STAFF
  0, // WP_SCEPTER
  0, // WP_NOGHRI_STICK
};

const float defaultAltSplashRadius[] = {
  0.0 f, // WP_NONE
  0.0 f, // WP_SABER          // handled elsewhere
  0.0 f, // WP_BLASTER_PISTOL
  0.0 f, // WP_BLASTER
  0.0 f, // WP_DISRUPTOR
  BOWCASTER_SPLASH_RADIUS, // WP_BOWCASTER
  REPEATER_ALT_SPLASH_RADIUS, // WP_REPEATER
  DEMP2_ALT_SPLASHRADIUS, // WP_DEMP2
  FLECHETTE_ALT_SPLASH_RAD, // WP_FLECHETTE
  ROCKET_SPLASH_RADIUS, // WP_ROCKET_LAUNCHER
  TD_ALT_SPLASH_RAD, // WP_THERMAL
  LT_SPLASH_RAD, // WP_TRIP_MINE
  FLECHETTE_ALT_SPLASH_RAD, // WP_DET_PACK       // HACK, this is what the code sez.
  0.0 f, // WP_CONCUSSION

  0.0 f, // WP_MELEE                // handled by the melee attack function

  0.0 f, // WP_ATST_MAIN
  ATST_SIDE_ALT_SPLASH_RADIUS, // WP_ATST_SIDE

  0.0 f, // WP_STUN_BATON

  0.0 f, // WP_BRYAR_PISTOL
  0.0 f, // WP_EMPLACED_GUN
  0.0 f, // WP_BOT_LASER
  0.0 f, // WP_TURRET         // handled elsewhere
  0.0 f, // WP_TIE_FIGHTER
  0.0 f, // WP_RAPID_FIRE_CONC

  0.0 f, // WP_JAWA
  0.0 f, // WP_TUSKEN_RIFLE
  0.0 f, // WP_TUSKEN_STAFF
  0.0 f, // WP_SCEPTER
  0.0 f, // WP_NOGHRI_STICK
  0.0 f, // WP_BLOODGUN
  CANNON_ALT_SPLASH_RAD, // WP_CANNON
  POISON_ALT_SPLASHRADIUS, // WP_POISON
};

 

i think this will allow you to customize these values on weapons.dat.

 

now go down and add entries for your weapons at the end of this array:

 

 

 

// FIXME : put this in an array (maybe a weaponDataInternal array???)
if (!Q_stricmp(tokenStr, "WP_NONE"))
  weaponNum = WP_NONE;
else if (!Q_stricmp(tokenStr, "WP_SABER"))
  weaponNum = WP_SABER;
else if (!Q_stricmp(tokenStr, "WP_BLASTER_PISTOL"))
  weaponNum = WP_BLASTER_PISTOL;
else if (!Q_stricmp(tokenStr, "WP_BRYAR_PISTOL"))
  weaponNum = WP_BRYAR_PISTOL;
else if (!Q_stricmp(tokenStr, "WP_BLASTER"))
  weaponNum = WP_BLASTER;
else if (!Q_stricmp(tokenStr, "WP_DISRUPTOR"))
  weaponNum = WP_DISRUPTOR;
else if (!Q_stricmp(tokenStr, "WP_BOWCASTER"))
  weaponNum = WP_BOWCASTER;
else if (!Q_stricmp(tokenStr, "WP_REPEATER"))
  weaponNum = WP_REPEATER;
else if (!Q_stricmp(tokenStr, "WP_DEMP2"))
  weaponNum = WP_DEMP2;
else if (!Q_stricmp(tokenStr, "WP_FLECHETTE"))
  weaponNum = WP_FLECHETTE;
else if (!Q_stricmp(tokenStr, "WP_ROCKET_LAUNCHER"))
  weaponNum = WP_ROCKET_LAUNCHER;
else if (!Q_stricmp(tokenStr, "WP_CONCUSSION"))
  weaponNum = WP_CONCUSSION;
else if (!Q_stricmp(tokenStr, "WP_THERMAL"))
  weaponNum = WP_THERMAL;
else if (!Q_stricmp(tokenStr, "WP_TRIP_MINE"))
  weaponNum = WP_TRIP_MINE;
else if (!Q_stricmp(tokenStr, "WP_DET_PACK"))
  weaponNum = WP_DET_PACK;
else if (!Q_stricmp(tokenStr, "WP_STUN_BATON"))
  weaponNum = WP_STUN_BATON;
else if (!Q_stricmp(tokenStr, "WP_BOT_LASER"))
  weaponNum = WP_BOT_LASER;
else if (!Q_stricmp(tokenStr, "WP_EMPLACED_GUN"))
  weaponNum = WP_EMPLACED_GUN;
else if (!Q_stricmp(tokenStr, "WP_MELEE"))
  weaponNum = WP_MELEE;
else if (!Q_stricmp(tokenStr, "WP_TURRET"))
  weaponNum = WP_TURRET;
else if (!Q_stricmp(tokenStr, "WP_ATST_MAIN"))
  weaponNum = WP_ATST_MAIN;
else if (!Q_stricmp(tokenStr, "WP_ATST_SIDE"))
  weaponNum = WP_ATST_SIDE;
else if (!Q_stricmp(tokenStr, "WP_TIE_FIGHTER"))
  weaponNum = WP_TIE_FIGHTER;
else if (!Q_stricmp(tokenStr, "WP_RAPID_FIRE_CONC"))
  weaponNum = WP_RAPID_FIRE_CONC;
else if (!Q_stricmp(tokenStr, "WP_JAWA"))
  weaponNum = WP_JAWA;
else if (!Q_stricmp(tokenStr, "WP_TUSKEN_RIFLE"))
  weaponNum = WP_TUSKEN_RIFLE;
else if (!Q_stricmp(tokenStr, "WP_TUSKEN_STAFF"))
  weaponNum = WP_TUSKEN_STAFF;
else if (!Q_stricmp(tokenStr, "WP_SCEPTER"))
  weaponNum = WP_SCEPTER;
else if (!Q_stricmp(tokenStr, "WP_NOGHRI_STICK"))
  weaponNum = WP_NOGHRI_STICK;
else if (!Q_stricmp(tokenStr, "WP_BLOODGUN"))
  weaponNum = WP_BLOODGUN;
else if (!Q_stricmp(tokenStr, "WP_CANNON"))
  weaponNum = WP_CANNON;
else if (!Q_stricmp(tokenStr, "WP_POISON"))
  weaponNum = WP_POISON;

as you can see, i added mines.

 

Now you end with g_weaponload.cpp. it was hard, phew.

 

Now you need really to program your weapon. Efx and functions of shooting. You can have two choice. You can create a new file of your solution of you can use the WP_ and FX_ file of the openjk solution. I prefear to use the default files.

 

So for our pistol now open that:

 

 

 

Wp_blaster_pistol.cpp

 

 

 

Add these functions:

 

// BLOODGUN 
//---------------------------------------------------------
void WP_FireBloodGun(gentity_t * ent, qboolean alt_fire)
  //---------------------------------------------------------
  {
    vec3_t start;
    int damage = !alt_fire ? weaponData[WP_BLOODGUN].damage : weaponData[WP_BLOODGUN].altDamage;

    VectorCopy(muzzle, start);
    WP_TraceSetStart(ent, start, vec3_origin, vec3_origin); //make sure our start point isn't on the other side of a wall

    if (!(ent - > client - > ps.forcePowersActive & (1 << FP_SEE)) || ent - > client - > ps.forcePowerLevel[FP_SEE] < FORCE_LEVEL_2) { //force sight 2+ gives perfect aim
      //FIXME: maybe force sight level 3 autoaims some?
      if (ent - > NPC && ent - > NPC - > currentAim < 5) {
        vec3_t angs;

        vectoangles(forwardVec, angs);

        if (ent - > client - > NPC_class == CLASS_IMPWORKER) { //*sigh*, hack to make impworkers less accurate without affecteing imperial officer accuracy
          angs[PITCH] += (crandom() * (BLASTER_NPC_SPREAD + (6 - ent - > NPC - > currentAim) * 0.25 f)); //was 0.5f
          angs[YAW] += (crandom() * (BLASTER_NPC_SPREAD + (6 - ent - > NPC - > currentAim) * 0.25 f)); //was 0.5f
        } else {
          angs[PITCH] += (crandom() * ((5 - ent - > NPC - > currentAim) * 0.25 f));
          angs[YAW] += (crandom() * ((5 - ent - > NPC - > currentAim) * 0.25 f));
        }

        AngleVectors(angs, forwardVec, NULL, NULL);
      }
    }

    WP_MissileTargetHint(ent, start, forwardVec);

    gentity_t * missile = CreateMissile(start, forwardVec, BLOODGUN_VEL, 10000, ent, alt_fire);

    missile - > classname = "bloodgun_proj";
    if (ent - > s.weapon == WP_BLOODGUN) { //*SIGH*... I hate our weapon system...
      missile - > s.weapon = ent - > s.weapon;
    } else {
      missile - > s.weapon = WP_BLASTER_PISTOL;
    }

    if (alt_fire) {
      int count = (level.time - ent - > client - > ps.weaponChargeTime) / BLOODGUN_CHARGE_UNIT;

      if (count < 1) {
        count = 1;
      } else if (count > 5) {
        count = 5;
      }

      damage *= count;
      missile - > count = count; // this will get used in the projectile rendering code to make a beefier effect
    }

    //    if ( ent->client && ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > 0 && ent->client->ps.powerups[PW_WEAPON_OVERCHARGE] > cg.time )
    //    {
    //          // in overcharge mode, so doing double damage
    //          missile->flags |= FL_OVERCHARGED;
    //          damage *= 2;
    //    }

    missile - > damage = damage;
    missile - > dflags = DAMAGE_DEATH_KNOCKBACK;

    if (alt_fire) {
      missile - > methodOfDeath = MOD_BLOODGUN_ALT;
    } else {
      missile - > methodOfDeath = MOD_BLOODGUN;
    }

    missile - > clipmask = MASK_SHOT | CONTENTS_LIGHTSABER;

    // we don't want it to bounce forever
    missile - > bounceCount = 8;

    if (ent - > weaponModel[1] > 0) { //dual pistols, toggle the muzzle point back and forth between the two pistols each time he fires
      ent - > count = (ent - > count) ? 0 : 1;
    }
  }

its exaclty like the weapon bryar and weapon blaster pistol behavour. Obvious you can set every kind of shooting function you desire.

 

Learn the coding and combine with your mind and fantasy! Your weapon can do every kind of thing you desire! You can use as example the function of the weapons of the game for studyng and understand it, but is really better if you will make something of your genius!

 

 

 

Now the same things for the FX.

 

open the FX_bryarpistol.cpp

 

add this and you can customize fx of your weapon.

 

void FX_BloodGunProjectileThink(  centity_t *cent, const struct weaponInfo_s *weapon )
{
      vec3_t forward;
 
      if ( VectorNormalize2( cent->gent->s.pos.trDelta, forward ) == 0.0f )
      {
            if ( VectorNormalize2( cent->currentState.pos.trDelta, forward ) == 0.0f )
            {
                  forward[2] = 1.0f;
            }
      }
 
      // hack the scale of the forward vector if we were just fired or bounced...this will shorten up the tail for a split second so tails don't clip so harshly
      int dif = cg.time - cent->gent->s.pos.trTime;
 
      if ( dif < 75 )
      {
            if ( dif < 0 )
            {
                  dif = 0;
            }
 
            float scale = ( dif / 75.0f ) * 0.95f + 0.05f;
 
            VectorScale( forward, scale, forward );
      }
 
      if ( cent->gent && cent->gent->owner && cent->gent->owner->s.number > 0 )
      {
            theFxScheduler.PlayEffect( "bloodgun/NPCshot", cent->lerpOrigin, forward );
      }
      else
      {
            theFxScheduler.PlayEffect( cgs.effects.bloodgunShotEffect, cent->lerpOrigin, forward );
      }
}

/*

 

-------------------------

 

FX_BryarHitWall

 

-------------------------

 

*/

 

void FX_BryarHitWall( vec3_t origin, vec3_t normal )
{
      theFxScheduler.PlayEffect( cgs.effects.bryarWallImpactEffect, origin, normal );
}
 
void FX_BloodGunHitWall( vec3_t origin, vec3_t normal )
{
      theFxScheduler.PlayEffect( cgs.effects.bloodgunWallImpactEffect, origin, normal );
}
= 1.0 f;
}
}

// hack the scale of the forward vector if we were just fired or bounced...this will shorten up the tail for a split second so tails don't clip so harshly
int dif = cg.time - cent - > gent - > s.pos.trTime;

if (dif < 75) {
if (dif < 0) {
dif = 0;
}

float scale = (dif / 75.0 f) * 0.95 f + 0.05 f;

VectorScale(forward, scale, forward);
}

// see if we have some sort of extra charge going on
for (int t = 1; t < cent - > gent - > count; t++) {
// just add ourselves over, and over, and over when we are charged
theFxScheduler.PlayEffect(cgs.effects.bryarPowerupShotEffect, cent - > lerpOrigin, forward);
}

theFxScheduler.PlayEffect(cgs.effects.bryarShotEffect, cent - > lerpOrigin, forward);
}

void FX_BloodGunAltProjectileThink(centity_t * cent,
const struct weaponInfo_s * weapon) {
vec3_t forward;

if (VectorNormalize2(cent - > gent - > s.pos.trDelta, forward) == 0.0 f) {
if (VectorNormalize2(cent - > currentState.pos.trDelta, forward) == 0.0 f) {
forward[2] = 1.0 f;
}
}

// hack the scale of the forward vector if we were just fired or bounced...this will shorten up the tail for a split second so tails don't clip so harshly
int dif = cg.time - cent - > gent - > s.pos.trTime;

if (dif < 75) {
if (dif < 0) {
dif = 0;
}

float scale = (dif / 75.0 f) * 0.95 f + 0.05 f;

VectorScale(forward, scale, forward);
}

// see if we have some sort of extra charge going on
for (int t = 1; t < cent - > gent - > count; t++) {
// just add ourselves over, and over, and over when we are charged
theFxScheduler.PlayEffect(cgs.effects.bloodgunPowerupShotEffect, cent - > lerpOrigin, forward);
}

theFxScheduler.PlayEffect(cgs.effects.bloodgunShotEffect, cent - > lerpOrigin, forward);
}

/*
-------------------------
FX_BryarAltHitWall
-------------------------
*/
void FX_BryarAltHitWall(vec3_t origin, vec3_t normal, int power) {
switch (power) {
case 4:
case 5:
theFxScheduler.PlayEffect(cgs.effects.bryarWallImpactEffect3, origin, normal);
break;

case 2:
case 3:
theFxScheduler.PlayEffect(cgs.effects.bryarWallImpactEffect2, origin, normal);
break;

default:
theFxScheduler.PlayEffect(cgs.effects.bryarWallImpactEffect, origin, normal);
break;
}
}

void FX_BloodGunAltHitWall(vec3_t origin, vec3_t normal, int power) {
switch (power) {
case 4:
case 5:
theFxScheduler.PlayEffect(cgs.effects.bloodgunWallImpactEffect3, origin, normal);
break;

case 2:
case 3:
theFxScheduler.PlayEffect(cgs.effects.bloodgunWallImpactEffect2, origin, normal);
break;

default:
theFxScheduler.PlayEffect(cgs.effects.bloodgunWallImpactEffect, origin, normal);
break;
}
}

/*
-------------------------
FX_BryarAltHitPlayer
-------------------------
*/
void FX_BryarAltHitPlayer(vec3_t origin, vec3_t normal, qboolean humanoid) {
theFxScheduler.PlayEffect(cgs.effects.bryarFleshImpactEffect, origin, normal);
}

void FX_BloodGunAltHitPlayer(vec3_t origin, vec3_t normal, qboolean humanoid) {
theFxScheduler.PlayEffect(cgs.effects.bloodgunFleshImpactEffect, origin, normal);
}




Now you end to programm your weapons. You told it how shoot, and what efx play when they shoot.

But you need to define again a lot of things.

For example, you need to declare the definition of your effect!

Go on cg_media.h and add this on the fxHandle_t field


 
[code=auto:0]// BLOODGUN
fxHandle_t bloodgunShotEffect;
fxHandle_t bloodgunPowerupShotEffect;
fxHandle_t bloodgunWallImpactEffect;
fxHandle_t bloodgunWallImpactEffect2;
fxHandle_t bloodgunWallImpactEffect3;
fxHandle_t bloodgunFleshImpactEffect;[/code]



that’s are the function called on the fx_bryarpistol.cpp effect.

So you have the definition and you have also used and called they. But... miss something right? Where is in the code that you tell exactly what kind of efx is played by bloodgunshoteffect? Here!

Find this on cg_weapons.cpp this manage the client game parameter of the weapons. That’s regard primary player and Npcs.



--------------------------------------------------------------------------------


 
[code=auto:0]case WP_BRYAR_PISTOL: //Edit the names in the the (" Bow shoot ")

cgs.effects.bowShotEffect = theFxScheduler.RegisterEffect("bow/shot");

theFxScheduler.RegisterEffect("bow/NPCshot");

cgs.effects.bowPowerupShotEffect = theFxScheduler.RegisterEffect("bow/crackleShot");

cgs.effects.bowWallImpactEffect = theFxScheduler.RegisterEffect("bow/wall_impact");

cgs.effects.bowWallImpactEffect2 = theFxScheduler.RegisterEffect("bow/wall_impact2");

cgs.effects.bowWallImpactEffect3 = theFxScheduler.RegisterEffect("bow/wall_impact3");

cgs.effects.bowFleshImpactEffect = theFxScheduler.RegisterEffect("bow/flesh_impact");

break;[/code]


------------------------------------------------------------------------------------------------------------



below add this new case:

--------------------------------------------------------------------------------


 
[code=auto:0]case WP_BLOODGUN:/Edit the names in the the (" Prophet blood pistol ")

cgs.effects.bloodgunShotEffect= theFxScheduler.RegisterEffect( "bloodgun/shot" );

theFxScheduler.RegisterEffect( "bloodgun/NPCshot" );

cgs.effects.bloodgunPowerupShotEffect = theFxScheduler.RegisterEffect( "bloodgun/crackleShot" );

cgs.effects.bloodgunWallImpactEffect = theFxScheduler.RegisterEffect( "bloodgun/wall_impact" );

cgs.effects.bloodgunWallImpactEffect2 = theFxScheduler.RegisterEffect( "bloodgun/wall_impact2" );

cgs.effects.bloodgunWallImpactEffect3 = theFxScheduler.RegisterEffect( "bloodgun/wall_impact3" );

cgs.effects.bloodgunFleshImpactEffect = theFxScheduler.RegisterEffect( "bloodgun/flesh_impact" );[/code]
------------------------------------------------------------------------------------------------------------------------------



now you have ended with efx array. Your weapon have new definition, new effects and will shot that effects.

Now you need to make a last painful big amount of work. We are near to the end!

This concerned g_weapons.cpp and cg_weapons.cpp

Here are definied some important global function necessary for the correct working of your weapons. G weapons are global setting, cg weapons client game setting.

In this section you can find a large amount of data to edit for making working your new weapon. This data edit change at second of kind of weapon you want to add, so not expect this istruction is valid for all your project. You need to manual scroll the cg_weapons.cpp and also the g_weapons.cpp file and edit specific part of the code. i not told you exactly what edit you need to edit, but i can tell you the location of the place to edit and the finality of these edits.

Let we starts. Scrolling down cg_weapons.cpp until you see this:
 
[code=auto:0]// Do special charge bits
//-----------------------
if ((ps - > weaponstate == WEAPON_CHARGING_ALT && ps - > weapon == WP_BRYAR_PISTOL)

add in this entry your weapon.if((ps - > weaponstate == WEAPON_CHARGING_ALT && ps - > weapon == WP_BRYAR_PISTOL) || (ps - > weaponstate == WEAPON_CHARGING_ALT && ps - > weapon == WP_BLASTER_PISTOL) || (ps - > weapon == WP_BOWCASTER && ps - > weaponstate == WEAPON_CHARGING) || (ps - > weapon == WP_DEMP2 && ps - > weaponstate == WEAPON_CHARGING_ALT) || (ps - > weapon == WP_BLOODGUN && ps - > weaponstate == WEAPON_CHARGING_ALT) || (ps - > weapon == WP_POISON && ps - > weaponstate == WEAPON_CHARGING_ALT)[/code]

this is a if condition. It mean “if your weapon are in alt fire mode and are charging a shoot they...

will use some custom shader in front of their barrel


 
[code=auto:0]{
int shader = 0;
float val = 0.0 f, scale = 1.0 f;
vec3_t WHITE = {
1.0 f,
1.0 f,
1.0 f
};

if (ps - > weapon == WP_BRYAR_PISTOL) {
// Hardcoded max charge time of 1 second
val = (cg.time - ps - > weaponChargeTime) * 0.001 f;
shader = cgi_R_RegisterShader("gfx/effects/bryarFrontFlash");
}
if (ps - > weapon == WP_BLASTER_PISTOL) {
// Hardcoded max charge time of 1 second
val = (cg.time - ps - > weaponChargeTime) * 0.001 f;
shader = cgi_R_RegisterShader("gfx/damage/burnmark3");
} else if (ps - > weapon == WP_BLOODGUN) {
// Hardcoded max charge time of 1 second
val = (cg.time - ps - > weaponChargeTime) * 0.001 f;
shader = cgi_R_RegisterShader("gfx/damage/burnmark3");
} else if (ps - > weapon == WP_BOWCASTER) {
// Hardcoded max charge time of 1 second
val = (cg.time - ps - > weaponChargeTime) * 0.001 f;
shader = cgi_R_RegisterShader("gfx/effects/bryarFrontFlash");
} else if (ps - > weapon == WP_DEMP2) {
// Hardcoded max charge time of 1 second
val = (cg.time - ps - > weaponChargeTime) * 0.001 f;
shader = cgi_R_RegisterShader("gfx/misc/lightningFlash");
scale = 1.75 f;
} else if (ps - > weapon == WP_POISON) {
// Hardcoded max charge time of 1 second
val = (cg.time - ps - > weaponChargeTime) * 0.001 f;
shader = cgi_R_RegisterShader("gfx/effects/greenFrontFlash");
scale = 1.5 f;
}[/code]

if you make some weapons that need a charging efx like bowcaster, bryar, blaster, demp2, and you are searching for the code part that set the shader used for charge flash of the weapons, you can find here... and you can change, customize and define it here.

So now your weapon can have a custom flash infront of his barrel when is charging is letal shoot.

Cool, isn’t it?



We now continue to dive the cg_weapons.cpp code.

The next step we will make is this!

Hud!

You need to set make your weapons usable by player! You need that your weapons can be selected and scrolled on HUD weapons list after the player pick up or obtain they. So search for this:

CG_NextWeapon_f



You will found a raven hacked part of the code, when they have insert the WP_CONCUSSION into the hud slide. You can use this for add a new else if entry for put your weapon into the weapons slide, i make this also with the NPC weapons i wanna play with my player. But in your case you need simply to add your weapons in this array.
 
[code=auto:0]for (i = 0; i <= MAX_PLAYER_WEAPONS; i++) {

//*SIGH*... Hack to put concussion rifle before rocketlauncher
if (cg.weaponSelect == WP_FLECHETTE) {
cg.weaponSelect = WP_CONCUSSION;
} else if (cg.weaponSelect == WP_CONCUSSION) {
cg.weaponSelect = WP_ROCKET_LAUNCHER;
} else if (cg.weaponSelect == WP_DET_PACK) {
cg.weaponSelect = WP_MELEE;
} else if (cg.weaponSelect == WP_MELEE) {
cg.weaponSelect = WP_ATST_MAIN;
} else if (cg.weaponSelect == WP_ATST_MAIN) {
cg.weaponSelect = WP_STUN_BATON;
} else if (cg.weaponSelect == WP_STUN_BATON) {
cg.weaponSelect = WP_BRYAR_PISTOL;
} else if (cg.weaponSelect == WP_BRYAR_PISTOL) {
cg.weaponSelect = WP_JAWA;
} else if (cg.weaponSelect == WP_JAWA) {
cg.weaponSelect = WP_TUSKEN_RIFLE;
} else if (cg.weaponSelect == WP_TUSKEN_RIFLE) {
cg.weaponSelect = WP_BLOODGUN;
} else if (cg.weaponSelect == WP_BLOODGUN) {
cg.weaponSelect = WP_CANNON;
} else if (cg.weaponSelect == WP_CANNON) {
cg.weaponSelect = WP_POISON;
} else if (cg.weaponSelect == WP_POISON) {
cg.weaponSelect = firstWeapon;
} else {
cg.weaponSelect++;
}[/code]

you need to put a question when you make this: what weapon you want is selected on the HUD BEFORE and AFTER the yours? Well. Now you know what you need to put into this array! As you can see, after my last weapon (WP_POISON) the slide will select the firstWeapon. FirstWeapon is the saber. So this close the Hud cycle.

You need to make the same thing also with previous weapon function and for each the two datapad function, so your weapon will appear also in datapad.

as you will can see, if player get the last weapon of the array, using the previous weapon key can equip the weapon swithing by the first weapoin, the saber, to the last enumerated weapons. Understood?
 
[code=auto:0]/*
===============
CG_PrevWeapon_f
===============
*/
void CG_PrevWeapon_f(void) {
int i;
int original;

if (!cg.snap) {
return;
}
/*
if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) {
return;
}
*/

if (g_entities[0].flags & FL_LOCK_PLAYER_WEAPONS) {
CG_PlayerLockedWeaponSpeech(qfalse);
return;
}

if (g_entities[0].client && g_entities[0].client - > NPC_class == CLASS_ATST) {
CG_ToggleATSTWeapon();
return;
}

if (cg.snap - > ps.eFlags & EF_LOCKED_TO_WEAPON) {
// can't do any sort of weapon switching when in the emplaced gun
return;
}

if (cg.snap - > ps.viewEntity) {
// yeah, probably need a better check here
if (g_entities[cg.snap - > ps.viewEntity].client && (g_entities[cg.snap - > ps.viewEntity].client - > NPC_class == CLASS_R5D2 || g_entities[cg.snap - > ps.viewEntity].client - > NPC_class == CLASS_R2D2 || g_entities[cg.snap - > ps.viewEntity].client - > NPC_class == CLASS_MOUSE)) {
return;
}
}

original = cg.weaponSelect;

int firstWeapon = FIRST_WEAPON;
if (G_IsRidingVehicle( & g_entities[cg.snap - > ps.viewEntity])) {
firstWeapon = 0; // include WP_NONE here
}

for (i = 0; i <= MAX_PLAYER_WEAPONS; i++) {

//*SIGH*... Hack to put concussion rifle before rocketlauncher
if (cg.weaponSelect == WP_ROCKET_LAUNCHER) {
cg.weaponSelect = WP_CONCUSSION;
} else if (cg.weaponSelect == WP_CONCUSSION) {
cg.weaponSelect = WP_FLECHETTE;
} else if (cg.weaponSelect == WP_MELEE) {
cg.weaponSelect = WP_DET_PACK;
} else if (cg.weaponSelect == WP_ATST_MAIN) {
cg.weaponSelect = WP_MELEE;
} else if (cg.weaponSelect == WP_STUN_BATON) {
cg.weaponSelect = WP_ATST_MAIN;
} else if (cg.weaponSelect == WP_BRYAR_PISTOL) {
cg.weaponSelect = WP_STUN_BATON;
} else if (cg.weaponSelect == WP_JAWA) {
cg.weaponSelect = WP_BRYAR_PISTOL;
} else if (cg.weaponSelect == WP_TUSKEN_RIFLE) {
cg.weaponSelect = WP_JAWA;
} else if (cg.weaponSelect == WP_BLOODGUN) {
cg.weaponSelect = WP_TUSKEN_RIFLE;
} else if (cg.weaponSelect == WP_CANNON) {
cg.weaponSelect = WP_BLOODGUN;
} else if (cg.weaponSelect == WP_POISON) {
cg.weaponSelect = WP_CANNON;
} else {
cg.weaponSelect--;
}

if (cg.weaponSelect < firstWeapon || cg.weaponSelect > MAX_PLAYER_WEAPONS) {
cg.weaponSelect = MAX_PLAYER_WEAPONS;
}

if (CG_WeaponSelectable(cg.weaponSelect, original, qfalse)) {
SetWeaponSelectTime();
// cg.weaponSelectTime = cg.time;
return;
}
}

cg.weaponSelect = original;
}[/code]

Now you need to specific a thing. When the projectile hit a wall or a player, the projectile need to start the FX function that play the effect of the impact. This can be setted here:
 
[code=auto:0]void CG_MissileHitWall[/code]

add this into the switch case of weapons
 
[code=auto:0]case WP_BLOODGUN:
if (altFire) {
parm = 0;

if (cent - > gent) {
parm += cent - > gent - > count;
}

FX_BloodGunAltHitWall(origin, dir, parm);
} else {
FX_BloodGunHitWall(origin, dir);
}
break;[/code]

now do the same with the hitting of players.
 
[code=auto:0]void CG_MissileHitPlayer( centity_t *cent, int weapon, vec3_t origin, vec3_t dir, qboolean altFire )[/code]



[code=auto:0]case WP_BLOODGUN:
if (altFire) {
FX_BloodGunAltHitPlayer(origin, dir, humanoid);
} else {
FX_BloodGunHitPlayer(origin, dir, humanoid);
}
break;[/code]

Okay men! You did it with cg_weapons. Now is the turn of g_weapons.cpp

Locate the weapon helper velocity array and add your weapons at the end of the list. Important: you need to respect the enumeration order of weapons in weapons.h


 
[code=auto:0]// Weapon Helper Functions
float weaponSpeed[WP_NUM_WEAPONS][2] = {
{
0,
0
}, //WP_NONE,
{
0,
0
}, //WP_SABER, // NOTE: lots of code assumes this is the first weapon (... which is crap) so be careful -Ste.
{
BRYAR_PISTOL_VEL,
BRYAR_PISTOL_VEL
}, //WP_BLASTER_PISTOL,
{
BLASTER_VELOCITY,
BLASTER_VELOCITY
}, //WP_BLASTER,
{
Q3_INFINITE,
Q3_INFINITE
}, //WP_DISRUPTOR,
{
BOWCASTER_VELOCITY,
BOWCASTER_VELOCITY
}, //WP_BOWCASTER,
{
REPEATER_VELOCITY,
REPEATER_ALT_VELOCITY
}, //WP_REPEATER,
{
DEMP2_VELOCITY,
DEMP2_ALT_RANGE
}, //WP_DEMP2,
{
FLECHETTE_VEL,
FLECHETTE_MINE_VEL
}, //WP_FLECHETTE,
{
ROCKET_VELOCITY,
ROCKET_ALT_VELOCITY
}, //WP_ROCKET_LAUNCHER,
{
TD_VELOCITY,
TD_ALT_VELOCITY
}, //WP_THERMAL,
{
0,
0
}, //WP_TRIP_MINE,
{
0,
0
}, //WP_DET_PACK,
{
CONC_VELOCITY,
Q3_INFINITE
}, //WP_CONCUSSION,
{
0,
0
}, //WP_MELEE, // Any ol' melee attack
{
0,
0
}, //WP_STUN_BATON,
{
BRYAR_PISTOL_VEL,
BRYAR_PISTOL_VEL
}, //WP_BRYAR_PISTOL,
{
EMPLACED_VEL,
EMPLACED_VEL
}, //WP_EMPLACED_GUN,
{
BRYAR_PISTOL_VEL,
BRYAR_PISTOL_VEL
}, //WP_BOT_LASER, // Probe droid - Laser blast
{
0,
0
}, //WP_TURRET, // turret guns
{
ATST_MAIN_VEL,
ATST_MAIN_VEL
}, //WP_ATST_MAIN,
{
ATST_SIDE_MAIN_VELOCITY,
ATST_SIDE_ALT_NPC_VELOCITY
}, //WP_ATST_SIDE,
{
EMPLACED_VEL,
EMPLACED_VEL
}, //WP_TIE_FIGHTER,
{
EMPLACED_VEL,
REPEATER_ALT_VELOCITY
}, //WP_RAPID_FIRE_CONC,
{
0,
0
}, //WP_JAWA,
{
TUSKEN_RIFLE_VEL,
TUSKEN_RIFLE_VEL
}, //WP_TUSKEN_RIFLE,
{
0,
0
}, //WP_TUSKEN_STAFF,
{
0,
0
}, //WP_SCEPTER,
{
0,
0
}, //WP_NOGHRI_STICK,
{
BLOODGUN_VEL,
BLOODGUN_VEL
}, //WP_BLOODGUN,
{
CANNON_VEL,
CANNON_MINE_VEL
}, //WP_CANNON,
{
POISON_VELOCITY,
POISON_VELOCITY
}, //WP_POISON,
};[/code]

Now locate this:


 
[code=auto:0]qboolean W_AccuracyLoggableWeapon(int weapon, qboolean alt_fire, int mod) {
if (mod != MOD_UNKNOWN) {
switch (mod) {
//standard weapons
case MOD_BRYAR:
case MOD_BRYAR_ALT:
case MOD_CANNON:
case MOD_CANNON_ALT:
case MOD_SONIC:
case MOD_SONIC_ALT:
case MOD_BLOODGUN:
case MOD_BLOODGUN_ALT:
case MOD_BLASTER:
case MOD_BLASTER_ALT:
case MOD_DISRUPTOR:
case MOD_SNIPER:
case MOD_BOWCASTER:
case MOD_BOWCASTER_ALT:
case MOD_POISON:
case MOD_POISON_ALT:
case MOD_ROCKET:
case MOD_ROCKET_ALT:
case MOD_CONC:
case MOD_CONC_ALT:
return qtrue;
break;
//non-alt standard
case MOD_REPEATER:
case MOD_DEMP2:
case MOD_FLECHETTE:
case MOD_ALCHEMIC:
return qtrue;
break;
//emplaced gun
case MOD_EMPLACED:
return qtrue;
break;
//atst
case MOD_ENERGY:
case MOD_EXPLOSIVE:
if (weapon == WP_ATST_MAIN || weapon == WP_ATST_SIDE) {
return qtrue;
}
break;
}
} else if (weapon != WP_NONE) {
switch (weapon) {
case WP_BRYAR_PISTOL:
case WP_BLOODGUN:
case WP_BLASTER_PISTOL:
case WP_BLASTER:
case WP_DISRUPTOR:
case WP_BOWCASTER:
case WP_ROCKET_LAUNCHER:
case WP_CONCUSSION:
return qtrue;
break;
//non-alt standard
case WP_REPEATER:
case WP_DEMP2:
case WP_FLECHETTE:
case WP_CANNON:
case WP_POISON:
if (!alt_fire) {
return qtrue;
}
break;
//emplaced gun
case WP_EMPLACED_GUN:
return qtrue;
break;
//atst
case WP_ATST_MAIN:
case WP_ATST_SIDE:
return qtrue;
break;
}
}
return qfalse;
}[/code]

now scroll down until it:


 
[code=auto:0]void CalcMuzzlePoint( gentity_t *const ent, vec3_t forwardVec, vec3_t right, vec3_t up, vec3_t muzzlePoint, float lead_in )
/---------------------------------------------------------[/code]



this place the muzzle flash position coordinates of your weapons.

Because my weapon is a gun, i added it to the bryar \ blaster pistol case.
 
[code=auto:0]switch (ent - > s.weapon) {
case WP_BRYAR_PISTOL:
case WP_BLASTER_PISTOL:
case WP_BLOODGUN:
ViewHeightFix(ent);
muzzlePoint[2] += ent - > client - > ps.viewheight; //By eyes
muzzlePoint[2] -= 16;
VectorMA(muzzlePoint, 28, forwardVec, muzzlePoint);
VectorMA(muzzlePoint, 6, vrightVec, muzzlePoint);
break;[/code]

there’s another setting, an array, a matrix that setting coordinates of muzzle flash point on xyz axis.


 
[code=auto:0]// Muzzle point table...
vec3_t WP_MuzzlePoint[WP_NUM_WEAPONS] =

{ // Fwd, right, up.
{
0,
0,
0
}, // WP_NONE,
{
8,
16,
0
}, // WP_SABER,
{
12,
6,
-6
}, // WP_BLASTER_PISTOL,
{
12,
6,
-6
}, // WP_BLASTER,
{
12,
6,
-6
}, // WP_DISRUPTOR,
{
12,
2,
-6
}, // WP_BOWCASTER,
{
12,
4.5,
-6
}, // WP_REPEATER,
{
12,
6,
-6
}, // WP_DEMP2,
{
12,
6,
-6
}, // WP_FLECHETTE,
{
12,
8,
-4
}, // WP_ROCKET_LAUNCHER,
{
12,
0,
-4
}, // WP_THERMAL,
{
12,
0,
-10
}, // WP_TRIP_MINE,
{
12,
0,
-4
}, // WP_DET_PACK,
{
12,
8,
-4
}, // WP_CONCUSSION,
{
0,
8,
0
}, // WP_MELEE,
{
0,
0,
0
}, // WP_ATST_MAIN,
{
0,
0,
0
}, // WP_ATST_SIDE,
{
0,
8,
0
}, // WP_STUN_BATON,
{
12,
6,
-6
}, // WP_BRYAR_PISTOL,
{
12,
6,
-6
}, // WP_BLOODGUN,
{
12,
6,
-6
}, // WP_CANNON,
{
12,
6,
-6
}, // WP_POISON,

};[/code]

also here, you need to respect the the enumeration position of your weapon in weapon.h. so be careful.



Now go down... now... you wanna your weapons shoots, right? You not want is a simple toy XD. So here you can set the function of shooting of your weapons, you need just to add your weapoin into the switch case sequence.
 
[code=auto:0]// fire the specific weapon
switch (ent - > s.weapon)
case WP_BLOODGUN:
WP_FireBloodGun(ent, alt_fire);
break;

case WP_BLASTER:
WP_FireBlaster(ent, alt_fire);
break;

case WP_TUSKEN_RIFLE:
if (alt_fire) {
WP_FireTuskenRifle(ent);
} else {
WP_Melee(ent);
}
break;

case WP_DISRUPTOR:
alert = 50; // if you want it to alert enemies, remove this
WP_FireDisruptor(ent, alt_fire);
break;[/code]

that’s will call the function you putted on WP_BLASTER_PISTOL.CPP and will execute it. So weapon will shoots!

We end with g_weapons setup!



A little thing... open w_local.h

There are the list of the void that declair the definition of the fire weapons function. Add the custom fire void definition of your weapon here!
 
[code=auto:0]void WP_FireBloodGun( gentity_t *ent, qboolean alt_fire );[/code]

Now, if you remember, on the blaster_pistol.cpp you used new custom MOD for your weapons. MOD mean MeansOfDeath. Every kind of thing can kills clints... for clients i mean player, npcs etc XD you need to add the new MOD for the your new weapons. Is not necessary, because you can use the same mod of default weapons, but in this case i teach you how do it. if you remember, we added also the mod of your weapon on cg_weapons into the accuracy switch.



Open bg_public.h

And add your new MOD at the end of enum MeansofDeathlist
 
[code=auto:0]// means of death
typedef enum {

MOD_UNKNOWN,

// weapons
MOD_SABER,
MOD_BRYAR,
MOD_BRYAR_ALT,
MOD_BLASTER,
MOD_BLASTER_ALT,
MOD_DISRUPTOR,
MOD_SNIPER,
MOD_BOWCASTER,
MOD_BOWCASTER_ALT,
MOD_REPEATER,
MOD_REPEATER_ALT,
MOD_DEMP2,
MOD_DEMP2_ALT,
MOD_FLECHETTE,
MOD_FLECHETTE_ALT,
MOD_ROCKET,
MOD_ROCKET_ALT,
//NEW for JKA weapons:
MOD_CONC,
MOD_CONC_ALT,
//END JKA weapons.
MOD_THERMAL,
MOD_THERMAL_ALT,
MOD_DETPACK,
MOD_LASERTRIP,
MOD_LASERTRIP_ALT,
MOD_MELEE,
MOD_SEEKER,
MOD_FORCE_GRIP,
MOD_FORCE_LIGHTNING,
MOD_FORCE_DRAIN,
MOD_EMPLACED,

// world / generic
MOD_ELECTROCUTE,
MOD_EXPLOSIVE,
MOD_EXPLOSIVE_SPLASH,
MOD_KNOCKOUT,
MOD_ENERGY,
MOD_ENERGY_SPLASH,
MOD_WATER,
MOD_SLIME,
MOD_LAVA,
MOD_CRUSH,
MOD_IMPACT,
MOD_FALLING,
MOD_SUICIDE,
MOD_TRIGGER_HURT,
MOD_GAS,
MOD_SONIC,
MOD_SONIC_ALT,
MOD_CANNON,
MOD_CANNON_ALT,
MOD_BLOODGUN,
MOD_BLOODGUN_ALT,[/code]

Looong, isnt’it?

Now is the turn of CG_weapons.cpp

You need to set what MOD are used by your player when equip a weapon you can add the new mod or set the new mod to your weapon in this switch case:


 
[code=auto:0]if (weapon == WP_NONE) {
switch (mod) {
case MOD_SABER:
weapon = WP_SABER;
break;
case MOD_BRYAR:
case MOD_BRYAR_ALT:
weapon = WP_BLASTER_PISTOL;
break;
case MOD_BLASTER:
case MOD_BLASTER_ALT:
weapon = WP_BLASTER;
break;
case MOD_DISRUPTOR:
case MOD_SNIPER:
weapon = WP_DISRUPTOR;
break;
case MOD_BOWCASTER:
case MOD_BOWCASTER_ALT:
weapon = WP_BOWCASTER;
break;
case MOD_REPEATER:
case MOD_REPEATER_ALT:
weapon = WP_REPEATER;
break;
case MOD_DEMP2:
case MOD_DEMP2_ALT:
weapon = WP_DEMP2;
break;
case MOD_FLECHETTE:
case MOD_FLECHETTE_ALT:
weapon = WP_FLECHETTE;
break;
case MOD_ROCKET:
case MOD_ROCKET_ALT:
weapon = WP_ROCKET_LAUNCHER;
break;
case MOD_CONC:
case MOD_CONC_ALT:
weapon = WP_CONCUSSION;
break;
case MOD_THERMAL:
case MOD_THERMAL_ALT:
weapon = WP_THERMAL;
break;
case MOD_DETPACK:
weapon = WP_DET_PACK;
break;
case MOD_LASERTRIP:
case MOD_LASERTRIP_ALT:
weapon = WP_TRIP_MINE;
break;
case MOD_MELEE:
if (self - > s.weapon == WP_STUN_BATON) {
weapon = WP_STUN_BATON;
} else if (self - > s.weapon == WP_MELEE) {
weapon = WP_MELEE;
}
break;
case MOD_SONIC:
case MOD_SONIC_ALT:
weapon = WP_JAWA;
break;
case MOD_CANNON:
case MOD_CANNON_ALT:
weapon = WP_BRYAR_PISTOL;
break;
case MOD_BLOODGUN:
case MOD_BLOODGUN_ALT:
weapon = WP_BLOODGUN;
break;[/code]

Now... maybe you want your weapon make more damage to some kind of enemy instead of another... you want maybe to make a light side or dark side weapon that is letal for sith of jedi? Or maybe a weapon letal for organic people and letal for droid?

Go to g_combat.cpp and search about the MOD_DEMP2 array



You need to make something like this:
 
[code=auto:0]if (mod == MOD_BLOODGUN || mod == MOD_BLOODGUN_ALT) {
if (client) {
if (
client - > NPC_class == CLASS_TAVION ||
client - > NPC_class == CLASS_DESANN ||
client - > NPC_class == CLASS_SAND_CREATURE ||
client - > NPC_class == CLASS_ATST
) {
// DEMP2 does more damage to these guys.
damage *= 0;
} else if (client - > NPC_class == CLASS_MOUSE || client - > NPC_class == CLASS_JAWA || client - > NPC_class == CLASS_RANCOR ||
client - > NPC_class == CLASS_R2D2 || client - > NPC_class == CLASS_R5D2 || client - > NPC_class == CLASS_COMMANDO ||
client - > NPC_class == CLASS_MURJJ) {
// DEMP2 does way more damage to these guys.
damage *= 1.5;
} else if (client - > NPC_class == CLASS_BOBAFETT || client - > NPC_class == CLASS_MORGANKATARN ||
client - > NPC_class == CLASS_WAMPA || client - > NPC_class == CLASS_MINEMONSTER ||
client - > NPC_class == CLASS_REELO
) {
// DEMP2 does way more damage to these guys.
damage *= 0.5;
} else if (client - > NPC_class == CLASS_INTERROGATOR || client - > NPC_class == CLASS_PRISONER || client - > NPC_class == CLASS_TRANDOSHAN) {
// DEMP2 does way more damage to these guys.
damage *= 3;
} else if (client - > NPC_class == CLASS_BESPIN_COP || client - > NPC_class == CLASS_REBEL ||
client - > NPC_class == CLASS_RODIAN || client - > NPC_class == CLASS_GALAK || client - > NPC_class == CLASS_STORMTROOPER ||
client - > NPC_class == CLASS_IMPWORKER || client - > NPC_class == CLASS_LANDO
) {
// DEMP2 does way more damage to these guys.
damage *= 1.5;
} else if (client - > NPC_class == CLASS_IMPERIAL || client - > NPC_class == CLASS_JAN) {
// DEMP2 does way more damage to these guys.
damage *= 1.25;
} else if (client - > NPC_class == CLASS_TUSKEN || client - > NPC_class == CLASS_GLIDER ||
client - > NPC_class == CLASS_NOGHRI || client - > NPC_class == CLASS_FLIER2 || client - > NPC_class == CLASS_WEEQUAY ||
client - > NPC_class == CLASS_LIZARD || client - > NPC_class == CLASS_SWAMPTROOPER || client - > NPC_class == CLASS_FISH || client - > NPC_class == CLASS_FLIER2 || client - > NPC_class == CLASS_GRAN ||
client - > NPC_class == CLASS_CLAW || client - > NPC_class == CLASS_JEDI || client - > NPC_class == CLASS_REBORN ||
client - > NPC_class == CLASS_ALORA || client - > NPC_class == CLASS_MONMOTHA
) {
// DEMP2 does way more damage to these guys.
damage *= 2;
} else if (client - > NPC_class == CLASS_KYLE || client - > NPC_class == CLASS_LUKE) {
// DEMP2 does way more damage to these guys.
damage *= 1.75;
}
} else if (targ - > s.weapon == WP_TURRET) {
damage *= 0; // more damage to turret things
}
}[/code]

this can add weakness or resistance of damage to your new weapon! At the end of this array you will found also the code part that making hazardtrooper resistance to the WP_SABER.
 
[code=auto:0]if (client && client - > NPC_class == CLASS_HAZARD_TROOPER) {
if (mod == MOD_SABER && damage > 0 && !(dflags & DAMAGE_NO_PROTECTION)) {
damage /= 10;
}
}[/code]

in that case every swing of saber damage is divided by 10

you can add your mod also there, and putanother value for reduce the damage by a division on certain classes.

For example


 
[code=auto:0]if (client && client - > NPC_class == CLASS_JEDI) {
if (mod == MOD_BLOODGUN && damage > 0 && !(dflags & DAMAGE_NO_PROTECTION)) {
damage /= 10;
}
}[/code]

As you can see, blood gun weapon now will not much efficiently against a jedi XD. When a jedi take a wouund by the gun, his damage is reduced of ten times. So if he take 50 HP of damage point, it get just 5!
 
[code=auto:0]if (client && client - > NPC_class == CLASS_JEDI) {
if (mod == MOD_BLOODGUN && damage > 0 && !(dflags & DAMAGE_NO_PROTECTION)) {
damage /= 7;
}
}[/code]

same thing for example, but now dmg is divided for seven. Understood? You can make some kind of rpg MOD playing with the MOD weakness and resistance to the weapons. You can also make classes resistance or immune to force drain or grip or force lightning. All this is possible on g_combat.cpp i really need to notice you to examinate this part of code. You will found a lot of useful thing about customization of combat of your mod.





On g_combat at the start of file there is also another thing: add your weapon in this switch if you want weapon will be dropped when ends his ammo.
 
[code=auto:0]if (weapon == WP_THERMAL && self - > client - > ps.torsoAnim == BOTH_ATTACK10) { //we were getting ready to throw the thermal, drop it!
self - > client - > ps.weaponChargeTime = level.time - FRAMETIME; //so it just kind of drops it
dropped = WP_DropThermal(self);
} else { // find the item type for this weapon
item = FindItemForWeapon((weapon_t) weapon);
}
if (item && !dropped) {
// spawn the item
dropped = Drop_Item(self, item, 0, qtrue);
//TEST: dropped items never go away
dropped - > e_ThinkFunc = thinkF_NULL;
dropped - > nextthink = -1;

if (!self - > s.number) { //player's dropped items never go away
//dropped->e_ThinkFunc = thinkF_NULL;
//dropped->nextthink = -1;
dropped - > count = 0; //no ammo
} else { //FIXME: base this on the NPC's actual amount of ammo he's used up...
switch (weapon) {
case WP_BRYAR_PISTOL:
case WP_BLASTER_PISTOL:
dropped - > count = 20;
break;
case WP_BLASTER:
dropped - > count = 20;
break;
case WP_DISRUPTOR:
dropped - > count = 20;
break;
case WP_BOWCASTER:
dropped - > count = 20;
break;
case WP_REPEATER:
dropped - > count = 20;
break;
case WP_DEMP2:
dropped - > count = 20;
break;
case WP_FLECHETTE:
dropped - > count = 20;
break;
case WP_ROCKET_LAUNCHER:
dropped - > count = 3;
break;
case WP_CONCUSSION:
dropped - > count = 100; //12;
break;
case WP_THERMAL:
dropped - > count = 5;
break;
case WP_TRIP_MINE:
dropped - > count = 3;
break;
case WP_DET_PACK:
dropped - > count = 1;
break;
case WP_STUN_BATON:
dropped - > count = 20;
break;
case WP_ATST_MAIN:
dropped - > count = 10;
break;
case WP_ATST_SIDE:
dropped - > count = 15;
break;
case WP_EMPLACED_GUN:
dropped - > count = 20;
break;
case WP_TUSKEN_RIFLE:
dropped - > count = 10;
break;
case WP_BLOODGUN:
dropped - > count = 15;
break;
case WP_CANNON:
dropped - > count = 12;
break;
case WP_POISON:
dropped - > count = 10;
break;
default:
dropped - > count = 0;
break;

}
}[/code]
you can set also the minimal ammo value when weapon is dropped. Weapon will not shoot more when reach this number of ammo.



Now two last thing. Concern the NPCs, go to NPC_combat.cpp. you need to set the delay between shots of the npcs when they attack you with new weapons, if you not do this, they will shot you with a powerful repeater XDDD


 
[code=auto:0]case WP_BLASTER_PISTOL:
ent - > NPC - > aiFlags &= ~NPCAI_BURST_WEAPON;
if (ent - > weaponModel[1] > 0) { //commando
ent - > NPC - > aiFlags |= NPCAI_BURST_WEAPON;
ent - > NPC - > burstMin = 4;
ent - > NPC - > burstMax = 12;
if (g_spskill - > integer == 0)
ent - > NPC - > burstSpacing = 600; //attack debounce
else if (g_spskill - > integer == 1)
ent - > NPC - > burstSpacing = 400; //attack debounce
else
ent - > NPC - > burstSpacing = 250; //attack debounce
} else if (ent - > client - > NPC_class == CLASS_SABOTEUR) {
if (g_spskill - > integer == 0)
ent - > NPC - > burstSpacing = 900; //attack debounce
else if (g_spskill - > integer == 1)
ent - > NPC - > burstSpacing = 600; //attack debounce
else
ent - > NPC - > burstSpacing = 400; //attack debounce
} else {
// ent->NPC->burstSpacing = 1000;//attackdebounce
if (g_spskill - > integer == 0)
ent - > NPC - > burstSpacing = 1000; //attack debounce
else if (g_spskill - > integer == 1)
ent - > NPC - > burstSpacing = 750; //attack debounce
else
ent - > NPC - > burstSpacing = 500; //attack debounce
}
break;[/code]

after blaster pistol i will add this case: for my weapon Imperials will shoot more fast and quick then other classes. 


 
[code=auto:0]case WP_BLOODGUN:
ent - > NPC - > aiFlags &= ~NPCAI_BURST_WEAPON;
if (ent - > client - > NPC_class == CLASS_IMPERIAL) {
if (g_spskill - > integer == 0)
ent - > NPC - > burstSpacing = 750; //attack debounce
else if (g_spskill - > integer == 1)
ent - > NPC - > burstSpacing = 500; //attack debounce
else
ent - > NPC - > burstSpacing = 250; //attack debounce
} else {
// ent->NPC->burstSpacing = 1000;//attackdebounce
if (g_spskill - > integer == 0)
ent - > NPC - > burstSpacing = 800; //attack debounce
else if (g_spskill - > integer == 1)
ent - > NPC - > burstSpacing = 600; //attack debounce
else
ent - > NPC - > burstSpacing = 400; //attack debounce
}
break;[/code]



Okay, the works is big, but not surrounder now! We are ending just now! Remaing only one thing: Animations ! Which animation you want npc and player use when they shoot with the new weapons? You can set on Bg_animate.cpp



Locate this at the end of files:
 
[code=auto:0]case WP_BRYAR_PISTOL:
if (pm - > ps - > weaponstate == WEAPON_CHARGING_ALT || weaponBusy) {
PM_SetAnim(pm, SETANIM_TORSO, TORSO_WEAPONREADY2, SETANIM_FLAG_NORMAL);[/code]

there is a switch case that allow you to customize animation for the shooting and weaponready of every kind of your weapons


 
[code=auto:0]case WP_BLOODGUN:
if (pm - > ps - > weaponstate == WEAPON_CHARGING_ALT || weaponBusy) {
PM_SetAnim(pm, SETANIM_TORSO, TORSO_WEAPONREADY2, SETANIM_FLAG_NORMAL);
} else if (PM_RunningAnim(pm - > ps - > legsAnim) || PM_WalkingAnim(pm - > ps - > legsAnim) || PM_JumpingAnim(pm - > ps - > legsAnim) || PM_SwimmingAnim(pm - > ps - > legsAnim)) { //running w/1-handed weapon uses full-body anim
PM_SetAnim(pm, SETANIM_TORSO, pm - > ps - > legsAnim, SETANIM_FLAG_NORMAL);
} else {
PM_SetAnim(pm, SETANIM_TORSO, TORSO_WEAPONIDLE2, SETANIM_FLAG_NORMAL);
}
break;

you can set every kind of animation you desire ^^

 

 

 

Last thing. In case your are making a Charging weapons. You need your weapon charging the shoot when you push the alt attack button. For allow this, add the weapon in this array!

 

//---------------------------------------

static bool PM_DoChargedWeapons(void)

//---------------------------------------

{

qboolean charging = qfalse,

altFire = qfalse;

 

//FIXME: make jedi aware they're being aimed at with a charged-up weapon (strafe and be evasive?)

// If you want your weapon to be a charging weapon, just set this bit up

switch (pm - > ps - > weapon) {

//------------------

case WP_BRYAR_PISTOL:

case WP_BLASTER_PISTOL:

case WP_BLOODGUN:

case WP_POISON:

 

// alt-fire charges the weapon

if (pm - > cmd.buttons & BUTTON_ALT_ATTACK) {

charging = qtrue;

altFire = qtrue;

}

break;

 

//------------------

case WP_DISRUPTOR:

 

// alt-fire charges the weapon...but due to zooming being controlled by the alt-button, the main button actually charges...but only when zoomed.

// lovely, eh?

if ((pm - > ps - > clientNum < MAX_CLIENTS || PM_ControlledByPlayer())) {

if (cg.zoomMode == 2) {

if (pm - > cmd.buttons & BUTTON_ATTACK) {

charging = qtrue;

altFire = qtrue; // believe it or not, it really is an alt-fire in this case!

}

}

} else if (pm - > gent && pm - > gent - > NPC) {

if ((pm - > gent - > NPC - > scriptFlags & SCF_ALT_FIRE)) {

if (pm - > gent - > fly_sound_debounce_time > level.time) {

charging = qtrue;

altFire = qtrue;

}

}

}

break;

 

//------------------

case WP_BOWCASTER:

 

// main-fire charges the weapon

if (pm - > cmd.buttons & BUTTON_ATTACK) {

charging = qtrue;

}

break;

 

//------------------

case WP_DEMP2:

// alt-fire charges the weapon

if (pm - > cmd.buttons & BUTTON_ALT_ATTACK) {

charging = qtrue;

altFire = qtrue;

}

break;

 

//------------------

case WP_ROCKET_LAUNCHER:

 

// Not really a charge weapon, but we still want to delay fire until the button comes up so that we can

// implement our alt-fire locking stuff

if (pm - > cmd.buttons & BUTTON_ALT_ATTACK) {

charging = qtrue;

altFire = qtrue;

}

break;

 

//------------------

case WP_THERMAL:

// FIXME: Really should have a wind-up anim for player

// as he holds down the fire button to throw, then play

// the actual throw when he lets go...

if (pm - > cmd.buttons & BUTTON_ALT_ATTACK) {

altFire = qtrue; // override default of not being an alt-fire

charging = qtrue;

} else if (pm - > cmd.buttons & BUTTON_ATTACK) {

charging = qtrue;

}

break;

 

} // end switch

 

 

 

Okay, we should have end. Build the code, fix your error of syntax, and enjoy your new weapon into your mod! :D you need to build the release of openjk86_sp.exe and the jagamex86.dll

 

I hope all this can be useful for you.

 

Have a good time! :D


User Feedback

Recommended Comments

There are no comments to display.



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...