[code] Mauser


(bacon) #1

This will show you how to add not only a weapon but a sniper rifle! It might look a bit messy…
New code is in red.
Altered code is in blue.

bg_public.h

// NOTE: we can only use up to 15 in the client-server stream
// SA NOTE: should be 31 now (I added 1 bit in msg.c)
// RF NOTE: if this changes, please update etmain\botfiles\inv.h
typedef enum {
	WP_NONE,				// 0
	WP_KNIFE,				// 1
	WP_LUGER,				// 2
	WP_MP40,				// 3
	WP_GRENADE_LAUNCHER,	// 4
	WP_PANZERFAUST,			// 5
	WP_FLAMETHROWER,		// 6

	WP_COLT,				// 7	// equivalent american weapon to german luger
	WP_THOMPSON,			// 8	// equivalent american weapon to german mp40
	WP_GRENADE_PINEAPPLE,	// 9
	WP_STEN,				// 10	// silenced sten sub-machinegun
	WP_MEDIC_SYRINGE,		// 11	// JPW NERVE -- broken out from CLASS_SPECIAL per Id request
	WP_AMMO,				// 12	// JPW NERVE likewise
	WP_ARTY,				// 13

	WP_SILENCER,			// 14	// used to be sp5
	WP_DYNAMITE,			// 15
	WP_SMOKETRAIL,			// 16
	WP_MAPMORTAR,			// 17	
	VERYBIGEXPLOSION,		// 18	// explosion effect for airplanes
	WP_MEDKIT,				// 19
	WP_BINOCULARS,			// 20

	WP_PLIERS,				// 21
	WP_SMOKE_MARKER,		// 22	// Arnout: changed name to cause less confusion
	WP_KAR98,				// 23	// WolfXP weapons
	WP_CARBINE,				// 24
	WP_GARAND,				// 25
	WP_LANDMINE,			// 26
	WP_SATCHEL,				// 27
	WP_SATCHEL_DET,			// 28
	WP_TRIPMINE,			// 29
	WP_SMOKE_BOMB,			// 30

	WP_MOBILE_MG42,			// 31
	WP_K43,					// 32
	WP_FG42,				// 33
	WP_DUMMY_MG42,          // 34 // Gordon: for storing heat on mounted mg42s...
	WP_MORTAR,				// 35
	WP_LOCKPICK,			// 36	// Mad Doc - TDF lockpick
	WP_AKIMBO_COLT,			// 37
	WP_AKIMBO_LUGER,		// 38

// Gordon: ONLY secondaries below this mark, as they are checked >= WP_GPG40 && < WP_NUM_WEAPONS

	WP_GPG40,				// 39

	WP_M7,					// 40
	WP_SILENCED_COLT,		// 41
	WP_GARAND_SCOPE,		// 42
	WP_K43_SCOPE,			// 43
	WP_FG42SCOPE,			// 44
	WP_MORTAR_SET,			// 45
	WP_MEDIC_ADRENALINE,	// 46
	WP_AKIMBO_SILENCEDCOLT,	// 47
	WP_AKIMBO_SILENCEDLUGER,// 48
	WP_MOBILE_MG42_SET,		// 49

	// bacon - mauser
	WP_MAUSER,				// 54
	WP_MAUSERSCOPE,			// 55

	WP_NUM_WEAPONS			// WolfMP: 32 WolfXP: 50
							// NOTE: this cannot be larger than 64 for AI/player weapons!
} weapon_t;
#define IS_AUTORELOAD_WEAPON(weapon) \
			(	\
				weapon==WP_LUGER	|| weapon==WP_COLT			|| weapon==WP_MP40			|| \
				weapon==WP_THOMPSON	|| weapon==WP_STEN		|| \
				weapon==WP_THOMPSON_DUMMY || weapon==WP_MP40_DUMMY || \
				weapon==WP_KAR98	|| weapon==WP_CARBINE		|| weapon==WP_GARAND_SCOPE	|| \
				weapon==WP_FG42		|| weapon==WP_K43			|| weapon==WP_MOBILE_MG42	|| \
				weapon==WP_SILENCED_COLT	|| weapon==WP_SILENCER		|| \
				weapon==WP_GARAND	|| weapon==WP_K43_SCOPE		|| weapon==WP_FG42SCOPE		||\
				weapon==WP_MAUSER || weapon==WP_MAUSERSCOPE \
			)

We’re going to add the mauser to the fourth (grenade) bank, so that we don’t have make changes to all banks.
bg_misc.c

int weapBanksMultiPlayer[MAX_WEAP_BANKS_MP][MAX_WEAPS_IN_BANK_MP] = {
	{0,						0,						0,					0,							0,						0,							0,				0,			0,			0,		0,				0	},	// empty bank '0'
	{WP_KNIFE,				0,						0,					0,							0,						0,							0,				0,			0,			0,		0,				0	},
	{WP_LUGER,				WP_COLT,				WP_AKIMBO_COLT,		WP_AKIMBO_LUGER,			WP_AKIMBO_SILENCEDCOLT,	WP_AKIMBO_SILENCEDLUGER,	0,				0,			0,			0,		0,				0	},
	{WP_MP40,				WP_THOMPSON,			WP_STEN,			WP_GARAND,					WP_PANZERFAUST,			WP_FLAMETHROWER,			WP_KAR98,		WP_CARBINE,	WP_FG42,	WP_K43,	WP_MOBILE_MG42,	WP_MORTAR	},
	{WP_GRENADE_LAUNCHER,	WP_GRENADE_PINEAPPLE,	WP_MAUSER,			0,							0,						0,							0,				0,			0,			0,		0,				0	},
	{WP_MEDIC_SYRINGE,		WP_PLIERS,				WP_SMOKE_MARKER,	WP_SMOKE_BOMB,				0,						0,							0,				0,			0,			0,		0,				0	},
	{WP_DYNAMITE,			WP_MEDKIT,				WP_AMMO,			WP_SATCHEL,					WP_SATCHEL_DET,			0,							0,				0,			0,			0,		0,				0	},
	{WP_LANDMINE,			WP_MEDIC_ADRENALINE,	0,					0,							0,						0,							0,				0,			0,			0,		0,				0	},
	{WP_BINOCULARS,			0,						0,					0,							0,						0,							0,				0,			0,			0,		0,				0	},
	{0,						0,						0,					0,							0,						0,							0,				0,			0,			0,		0,				0	},
};
{	24,				1,		8,		24,		8,		1500,	DELAY_PISTOL,	400,	0,		0,		MOD_SILENCED_COLT		},	// WP_SILENCED_COLT			// 41
	{	24,				1,		8,		16,		8,		1500,	DELAY_HIGH,		1700,	0,		0,		MOD_GARAND_SCOPE		},	// WP_GARAND_SCOPE			// 42		GARAND
	{	30,				1,		10,		20,		10,		2500,	DELAY_HIGH,		1700,	0,		0,		MOD_K43_SCOPE			},	// WP_K43_SCOPE				// 43		K43
	{	60,				1,		20,		40,		20,		2000,	DELAY_LOW,		200,	0,		0,		MOD_FG42SCOPE			},	// WP_FG42SCOPE				// 44
	{	16,				1,		1,		12,		0,		0,		750,			1400,	0,		0,		MOD_MORTAR				},	// WP_MORTAR_SET			// 45
	{	10,				1,		1,		0,		10,		1500,	50,				1000,	0,		0,		MOD_SYRINGE				},	// WP_MEDIC_ADRENALINE		// 46
	{	48,				1,		8,		48,		8,		2700,	DELAY_PISTOL,	200,	0,		0,		MOD_AKIMBO_SILENCEDCOLT	},	// WP_AKIMBO_SILENCEDCOLT	// 47
	{	48,				1,		8,		48,		8,		2700,	DELAY_PISTOL,	200,	0,		0,		MOD_AKIMBO_SILENCEDLUGER},	// WP_AKIMBO_SILENCEDLUGER	// 48
	{	450,			1,		150,	0,		150,	3000,	DELAY_LOW,		50,		1500,	300,	MOD_MOBILE_MG42			},	// WP_MOBILE_MG42_SET		// 49
	{	30,				1,		10,		20,		10,		2500,	DELAY_HIGH,		1700,	0,		0,		MOD_MAUSER				},	// WP_MAUSER				// 50
	{	30,				1,		10,		20,		10,		2500,	DELAY_HIGH,		1700,	0,		0,		MOD_MAUSERSCOPE			},	// WP_MAUSERSCOPE			// 51		MAUSER
WP_KAR98,			// 39 WP_GPG40
	WP_CARBINE,			// 40 WP_M7
	WP_COLT,			// 41 WP_SILENCED_COLT
	WP_GARAND,			// 42 WP_GARAND_SCOPE
	WP_K43,				// 43 WP_K43_SCOPE
	WP_FG42,			// 44 WP_FG42SCOPE
	WP_MORTAR,			// 45 WP_MORTAR_SET
	WP_NONE,			// 46 WP_MEDIC_ADRENALINE
	WP_NONE,			// 47 WP_AKIMBO_SILENCEDCOLT
	WP_NONE,			// 48 WP_AKIMBO_SILENCEDLUGER
	WP_MOBILE_MG42,		// 49 WP_MOBILE_MG42_SET

	WP_MAUSERSCOPE,		// 50 WP_MAUSER
	WP_MAUSER,			// 51 WP_MAUSERSCOPE
/*QUAKED weapon_mp40 (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
"stand" values:
	no value:	laying in a default position on it's side (default)
	2:			upright, barrel pointing up, slightly angled (rack mount)
-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
model="models\weapons2\mp40\mp40.md3"
*/
	{
		"weapon_mp40", 
		"sound/misc/w_pkup.wav",
		{	
			"models/weapons2/mp40/mp40.md3", 
			"models/weapons2/mp40/v_mp40.md3",
			0
		},

		"icons/iconw_mp40_1",	// icon
		"icons/ammo2",		// ammo icon
		"MP40",				// pickup
		30,
		IT_WEAPON,
		WP_MP40,
		WP_MP40,
		WP_MP40,
		"",					// precache
		"",					// sounds
//		{0,0,0,0,0}
	},

/*QUAKED weapon_mauser (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
"stand" values:
	no value:	laying in a default position on it's side (default)
	2:			upright, barrel pointing up, slightly angled (rack mount)
-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
model="models\weapons2\mauser\mauser.md3"
*/
	{
		"weapon_mauser", 
		"sound/misc/w_pkup.wav",
		{	
			"models/weapons2/mauser/mauser.md3", 
			"models/weapons2/mauser/v_mauser.md3",
			0
		},

		"icons/iconw_k43_1",	// icon
		"icons/ammo2",		// ammo icon
		"Mauser",			// pickup
		30,
		IT_WEAPON,
		WP_MAUSER,
		WP_MAUSER,
		WP_MAUSER,
		"",					// precache
		"",					// sounds
//		{0,0,0,0,0}
	},

/*QUAKED weapon_mauser_scope (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
"stand" values:
	no value:	laying in a default position on it's side (default)
	2:			upright, barrel pointing up, slightly angled (rack mount)
-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
model="models\weapons2\mauser\mauser.md3"
*/
	{
		"weapon_mauser_scope", 
		"sound/misc/w_pkup.wav",
		{	
			"models/weapons2/mauser/mauser.md3", 
			"models/weapons2/mauser/v_mauser.md3",
			0
		},

		"icons/iconw_k43_1",	// icon
		"icons/ammo2",		// ammo icon
		"Mauser Scope",			// pickup
		30,
		IT_WEAPON,
		WP_MAUSERSCOPE,
		WP_MAUSERSCOPE,
		WP_MAUSERSCOPE,
		"",					// precache
		"",					// sounds
//		{0,0,0,0,0}
	},
// DHM - Nerve :: returns qtrue if a weapon is indeed used in multiplayer
// Gordon: FIXME: er, we shouldnt really need this, just remove all the weapons we dont actually want :)
qboolean BG_WeaponInWolfMP( int weapon ) {
	switch ( weapon ) {
	case WP_KNIFE:
	case WP_LUGER:
	case WP_COLT:
	case WP_MP40:
	case WP_THOMPSON:
	case WP_STEN:
	case WP_GRENADE_LAUNCHER:
	case WP_GRENADE_PINEAPPLE:
	case WP_PANZERFAUST:
	case WP_FLAMETHROWER:
	case WP_AMMO:
	case WP_ARTY:
	case WP_SMOKETRAIL:
	case WP_MEDKIT:
	case WP_HELMET:
	case WP_PLIERS:
	case WP_SMOKE_MARKER:
	case WP_DYNAMITE:
	case WP_MEDIC_SYRINGE:
	case WP_MEDIC_ADRENALINE:
	case WP_BINOCULARS:
	case WP_KAR98:
	case WP_GPG40:
	case WP_CARBINE:
	case WP_M7:
	case WP_GARAND:
	case WP_GARAND_SCOPE:
	case WP_FG42:
	case WP_FG42SCOPE:
	case WP_LANDMINE:
	case WP_SATCHEL:
	case WP_SATCHEL_DET:
	//case WP_TRIPMINE:    // bye bye tripmines ;(
	case WP_SMOKE_BOMB:
	case WP_MOBILE_MG42:
	case WP_MOBILE_MG42_SET:
	case WP_SILENCER:
	case WP_SILENCED_COLT:
	case WP_K43:
	case WP_K43_SCOPE:
	case WP_MORTAR:
	case WP_MORTAR_SET:
	case WP_MAUSER:
	case WP_MAUSERSCOPE:
	case WP_AKIMBO_LUGER:
	case WP_AKIMBO_SILENCEDLUGER:
	case WP_AKIMBO_COLT:
	case WP_AKIMBO_SILENCEDCOLT:
		return qtrue;
	default:
		return qfalse;
	}
}
// Gordon: some weapons are duplicated for code puposes.... just want to treat them as a single 
weapon_t BG_DuplicateWeapon( weapon_t weap ) {
	switch( weap ) {
		case WP_M7:		return WP_GPG40;
		case WP_GARAND_SCOPE:		return WP_GARAND;
		case WP_K43_SCOPE:			return WP_K43;
		case WP_GRENADE_PINEAPPLE:	return WP_GRENADE_LAUNCHER;
		case WP_MAUSERSCOPE:		return WP_MAUSER;
		default:					return weap;
	}
}

bg_pmove.c

// See if we are moving
		float spd = VectorLength( pm->ps->velocity );
		qboolean userinput = abs(pm->cmd.forwardmove) + abs(pm->cmd.rightmove) > 10 ? qtrue : qfalse;

		if( userinput && spd > 40.f && !(pm->ps->eFlags & EF_PRONE_MOVING) ) {
			pm->ps->eFlags |= EF_PRONE_MOVING;

			switch( pm->ps->weapon ) {
				case WP_MAUSERSCOPE: PM_BeginWeaponChange( WP_MAUSERSCOPE, WP_MAUSER, qfalse ); break;
				case WP_FG42SCOPE: PM_BeginWeaponChange( WP_FG42SCOPE, WP_FG42, qfalse ); break;
				case WP_GARAND_SCOPE: PM_BeginWeaponChange( WP_GARAND_SCOPE, WP_GARAND, qfalse ); break;
				case WP_K43_SCOPE: PM_BeginWeaponChange( WP_K43_SCOPE, WP_K43, qfalse ); break;
			}
		} else if( !userinput && spd < 20.0f && (pm->ps->eFlags & EF_PRONE_MOVING) ) {
			pm->ps->eFlags &= ~EF_PRONE_MOVING;
		}
case WP_K43_SCOPE:
		case WP_GARAND_SCOPE:
		case WP_MAUSERSCOPE:
		case WP_FG42SCOPE:
			pm->ps->aimSpreadScale = 255;			// initially at lowest accuracy
			pm->ps->aimSpreadScaleFloat = 255.0f;	// initially at lowest accuracy
			break;
switch( weapon ) {
		case WP_FG42SCOPE:
		case WP_GARAND_SCOPE:
		case WP_MAUSERSCOPE:
		case WP_K43_SCOPE:
			if( reloadRequested && pm->ps->ammo[ammoWeap] && pm->ps->ammoclip[clipWeap] < GetAmmoTableData(weapon)->maxclip) {
				PM_BeginWeaponChange( weapon, weapAlts[weapon], !(pm->ps->ammo[ammoWeap]) ? qfalse : qtrue );
			}
			return;
		default:
			break;
	}
case WP_K43_SCOPE:
	case WP_GARAND_SCOPE:
	case WP_MAUSERSCOPE:
	case WP_FG42SCOPE:
		if( pm->skill[SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS] >= 3 ) {
			wpnScale = 5.f;
		} else {
			wpnScale = 10.f;
		}
		break;
case WP_K43:
		wpnScale = 0.5f;
		break;
	case WP_MAUSER:
		wpnScale = 0.9f;
		break;
case WP_LOCKPICK:

			if(!weaponstateFiring) {
				pm->ps->weaponDelay = GetAmmoTableData(pm->ps->weapon)->fireDelayTime;
			} else {
				if( pm->ps->eFlags & EF_PRONE ) {
					BG_AnimScriptEvent( pm->ps, pm->character->animModelInfo, ANIM_ET_FIREWEAPONPRONE, qtrue, qtrue );
				} else {
					BG_AnimScriptEvent( pm->ps, pm->character->animModelInfo, ANIM_ET_FIREWEAPON, qtrue, qtrue );
				}
			}
			break;
		case WP_PANZERFAUST:
		case WP_LUGER:
		case WP_COLT:
		case WP_GARAND:
		case WP_K43:
		case WP_KAR98:
		case WP_CARBINE:
		case WP_GPG40:
		case WP_M7:
		case WP_MAUSER:
		case WP_MAUSERSCOPE:
		case WP_SILENCER:
		case WP_SILENCED_COLT:
		case WP_GARAND_SCOPE:
		case WP_K43_SCOPE:
		case WP_AKIMBO_COLT:
		case WP_AKIMBO_SILENCEDCOLT:
		case WP_AKIMBO_LUGER:
		case WP_AKIMBO_SILENCEDLUGER:
	// some weapons not allowed to reload.  must switch back to primary first
				case WP_FG42SCOPE:
				case WP_GARAND_SCOPE:
				case WP_K43_SCOPE:
				case WP_MAUSERSCOPE:
					reloading = qfalse;
					break;
case WP_GARAND:
	case WP_K43:
	case WP_KAR98:
	case WP_MAUSER:
	case WP_CARBINE:
		addTime = GetAmmoTableData(pm->ps->weapon)->nextShotTime;
		aimSpreadScaleAdd = 50;
		break;

	case WP_GARAND_SCOPE:
	case WP_MAUSERSCOPE:
	case WP_K43_SCOPE:
		addTime = GetAmmoTableData(pm->ps->weapon)->nextShotTime;

		aimSpreadScaleAdd = 200;
		// jpw

		break;
	// set weapon recoil
	pm->pmext->lastRecoilDeltaTime = 0;

	switch( pm->ps->weapon ) {
	case WP_GARAND_SCOPE:
	case WP_MAUSERSCOPE:
	case WP_K43_SCOPE:
		pm->pmext->weapRecoilTime = pm->cmd.serverTime;
		pm->pmext->weapRecoilDuration = 300;
		pm->pmext->weapRecoilYaw = crandom() * .5f;

		if( pm->skill[SK_MILITARY_INTELLIGENCE_AND_SCOPED_WEAPONS] >= 3 ) {
			pm->pmext->weapRecoilPitch = .25f;
		} else {
			pm->pmext->weapRecoilPitch = .5f;
		}
		break;

bg_stats.c

{ WP_GPG40,				WS_GRENADELAUNCHER },
	{ WP_M7,				WS_GRENADELAUNCHER },
	{ WP_SILENCED_COLT,		WS_COLT },			// 50
	{ WP_GARAND_SCOPE,		WS_GARAND },
	{ WP_K43_SCOPE,			WS_K43 },
	{ WP_FG42SCOPE,			WS_FG42 },
	{ WP_MORTAR_SET,		WS_MORTAR },
	{ WP_MORTAR,			WS_MORTAR },
	{ WP_MEDIC_ADRENALINE,	WS_MAX },			// 55

	{ WP_AKIMBO_SILENCEDCOLT,	WS_COLT		},
	{ WP_AKIMBO_SILENCEDLUGER,	WS_LUGER	},
	{ WP_AKIMBO_COLT,			WS_COLT		},
	{ WP_AKIMBO_LUGER,			WS_LUGER	},

	{ WP_MAUSER,				WS_MAUSER },
	{ WP_MAUSERSCOPE,			WS_MAUSER },

g_client.c

case WP_GARAND:
					if( client->sess.sessionTeam == TEAM_AXIS ) {
						if( AddWeaponToPlayer( client, WP_K43, GetAmmoTableData(WP_K43)->defaultStartingAmmo, GetAmmoTableData(WP_K43)->defaultStartingClip, qtrue ) ) {
							AddWeaponToPlayer( client, WP_K43_SCOPE, GetAmmoTableData(WP_K43_SCOPE)->defaultStartingAmmo, GetAmmoTableData(WP_K43_SCOPE)->defaultStartingClip, qfalse );
						}
						break;
					} else {
						if( AddWeaponToPlayer( client, WP_GARAND, GetAmmoTableData(WP_GARAND)->defaultStartingAmmo, GetAmmoTableData(WP_GARAND)->defaultStartingClip, qtrue ) ) {
							AddWeaponToPlayer( client, WP_GARAND_SCOPE, GetAmmoTableData(WP_GARAND_SCOPE)->defaultStartingAmmo, GetAmmoTableData(WP_GARAND_SCOPE)->defaultStartingClip, qfalse );
						}
						break;
					}
				case WP_FG42:
					if( AddWeaponToPlayer( client, WP_FG42, GetAmmoTableData(WP_FG42)->defaultStartingAmmo, GetAmmoTableData(WP_FG42)->defaultStartingClip, qtrue ) ) {
						AddWeaponToPlayer( client, WP_FG42SCOPE, GetAmmoTableData(WP_FG42SCOPE)->defaultStartingAmmo, GetAmmoTableData(WP_FG42SCOPE)->defaultStartingClip, qfalse );
					}
					break;
				case WP_MAUSER:
					if( AddWeaponToPlayer( client, WP_MAUSER, GetAmmoTableData(WP_MAUSER)->defaultStartingAmmo, GetAmmoTableData(WP_MAUSER)->defaultStartingClip, qtrue ) ) {
						AddWeaponToPlayer( client, WP_MAUSERSCOPE, GetAmmoTableData(WP_MAUSERSCOPE)->defaultStartingAmmo, GetAmmoTableData(WP_MAUSERSCOPE)->defaultStartingClip, qfalse );
					}
					break;

g_items.c
if( weapon == WP_KAR98 ) {
COM_BitClear( client->ps.weapons, WP_GPG40 );
} else if ( weapon == WP_CARBINE ) {
COM_BitClear( client->ps.weapons, WP_M7 );
} else if ( weapon == WP_FG42 ) {
COM_BitClear( client->ps.weapons, WP_FG42SCOPE );
} else if( weapon == WP_K43 ) {
COM_BitClear( client->ps.weapons, WP_K43_SCOPE );
} else if( weapon == WP_MAUSER ) {
COM_BitClear( client->ps.weapons, WP_MAUSERSCOPE );
} else if( weapon == WP_GARAND ) {
COM_BitClear( client->ps.weapons, WP_GARAND_SCOPE );
} else if( weapon == WP_MORTAR ) {
COM_BitClear( client->ps.weapons, WP_MORTAR_SET );
} else if( weapon == WP_MOBILE_MG42 ) {
COM_BitClear( client->ps.weapons, WP_MOBILE_MG42_SET );
}

// Clear out empty weapon, change to next best weapon
G_AddEvent( ent, EV_WEAPONSWITCHED, 0 );


// DHM - Fixup mauser/sniper issues
if( ent->item->giTag == WP_FG42 ) {
COM_BitSet( other->client->ps.weapons, WP_FG42SCOPE);
} else if(ent->item->giTag == WP_GARAND) {
COM_BitSet( other->client->ps.weapons, WP_GARAND_SCOPE);
} else if( ent->item->giTag == WP_K43 ) {
COM_BitSet( other->client->ps.weapons, WP_K43_SCOPE );
} else if ( ent->item->giTag == WP_MAUSER ) {
COM_BitSet( other->client->ps.weapons, WP_MAUSERSCOPE );
} else if( ent->item->giTag == WP_MORTAR ) {
COM_BitSet( other->client->ps.weapons, WP_MORTAR_SET );
} else if( ent->item->giTag == WP_MOBILE_MG42 ) {
COM_BitSet( other->client->ps.weapons, WP_MOBILE_MG42_SET );
} else if( ent->item->giTag == WP_CARBINE ) {
COM_BitSet( other->client->ps.weapons, WP_M7 );
} else if( ent->item->giTag == WP_KAR98 ) {
COM_BitSet( other->client->ps.weapons, WP_GPG40 );
}



[b]g_weapon.c[/b]

case WP_MAPMORTAR:
case WP_GRENADE_LAUNCHER:
case WP_GRENADE_PINEAPPLE:
case WP_GPG40:
case WP_M7:
case WP_LANDMINE:
case WP_SATCHEL:
return 300;
case WP_PANZERFAUST:
case WP_MORTAR_SET:
case WP_DYNAMITE:
return 400;
case WP_MAUSER:
return 80;
case WP_MAUSERSCOPE:
return 90;



case WP_STEN:
return 200;
case WP_FG42SCOPE:
return 200;
case WP_FG42:
return 500;
case WP_GARAND:
case WP_CARBINE:
case WP_KAR98:
case WP_K43:
return 250;
case WP_GARAND_SCOPE:
case WP_K43_SCOPE:
return 700;
case WP_MOBILE_MG42:
case WP_MOBILE_MG42_SET:
return 2500;
case WP_MAUSER:
return 2000;
case WP_MAUSERSCOPE:
return 700;



#define FG42SCOPE_SPREAD G_GetWeaponSpread(WP_FG42SCOPE)
#define FG42SCOPE_DAMAGE G_GetWeaponDamage(WP_FG42SCOPE) // JPW
#define K43_SPREAD G_GetWeaponSpread(WP_K43)
#define K43_DAMAGE G_GetWeaponDamage(WP_K43)

#define GARANDSCOPE_SPREAD G_GetWeaponSpread(WP_GARAND_SCOPE)
#define GARANDSCOPE_DAMAGE G_GetWeaponDamage(WP_GARAND_SCOPE)

#define K43SCOPE_SPREAD G_GetWeaponSpread(WP_K43_SCOPE)
#define K43SCOPE_DAMAGE G_GetWeaponDamage(WP_K43_SCOPE)

#define MAUSER_SPREAD G_GetWeaponSpread(WP_MAUSER)
#define MAUSER_DAMAGE G_GetWeaponDamage(WP_MAUSER)

#define MAUSERSCOPE_SPREAD G_GetWeaponSpread(WP_MAUSERSCOPE)
#define MAUSERSCOPE_DAMAGE G_GetWeaponSpread(WP_MAUSERSCOPE)



case WP_MAUSER:
Bullet_Fire( ent, MAUSER_SPREADaimSpreadScale, MAUSER_DAMAGE, qtrue );
break;
case WP_MAUSERSCOPE:
Bullet_Fire( ent, MAUSERSCOPE_SPREAD
aimSpreadScale, MAUSERSCOPE_DAMAGE, qfalse );
case WP_MP40:
Bullet_Fire( ent, MP40_SPREADaimSpreadScale, MP40_DAMAGE, qtrue );
break;
case WP_THOMPSON:
Bullet_Fire( ent, THOMPSON_SPREAD
aimSpreadScale, THOMPSON_DAMAGE, qtrue );
break;





[b]CLIENT[/b]
[b]cg_draw.c[/b]

static void CG_DrawWeapReticle(void) {
vec4_t color = {0, 0, 0, 1};
qboolean fg, garand, k43, mauser;

// DHM - Nerve :: So that we will draw reticle
if ( (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg.demoPlayback ) {
	garand = (qboolean)(cg.snap->ps.weapon == WP_GARAND_SCOPE);
	k43 = (qboolean)(cg.snap->ps.weapon == WP_K43_SCOPE);
	fg = (qboolean)(cg.snap->ps.weapon == WP_FG42SCOPE);
	mauser = (qboolean)(cg.snap->ps.weapon == WP_MAUSERSCOPE);
} else {
	fg = (qboolean)(cg.weaponSelect == WP_FG42SCOPE);
	garand = (qboolean)(cg.weaponSelect == WP_GARAND_SCOPE);
	k43 = (qboolean)(cg.weaponSelect == WP_K43_SCOPE);
	mauser = (qboolean)(cg.weaponSelect == WP_MAUSERSCOPE);
}

if(fg) {
	// sides
	CG_FillRect (0, 0, 80, 480, color);
	CG_FillRect (560, 0, 80, 480, color);

	// center
	if(cgs.media.reticleShaderSimple)
		CG_DrawPic( 80, 0, 480, 480, cgs.media.reticleShaderSimple );

/* if(cgs.media.reticleShaderSimpleQ) {
trap_R_DrawStretchPic( x, 0, w, h, 0, 0, 1, 1, cgs.media.reticleShaderSimpleQ ); // tl
trap_R_DrawStretchPic( x+w, 0, w, h, 1, 0, 0, 1, cgs.media.reticleShaderSimpleQ ); // tr
trap_R_DrawStretchPic( x, h, w, h, 0, 1, 1, 0, cgs.media.reticleShaderSimpleQ ); // bl
trap_R_DrawStretchPic( x+w, h, w, h, 1, 1, 0, 0, cgs.media.reticleShaderSimpleQ ); // br
}*/

	// hairs
	CG_FillRect (84, 239, 150, 3, color);	// left
	CG_FillRect (234, 240, 173, 1, color);	// horiz center
	CG_FillRect (407, 239, 150, 3, color);	// right


	CG_FillRect (319, 2,   3, 151, color);	// top center top
	CG_FillRect (320, 153, 1, 114, color);	// top center bot

	CG_FillRect (320, 241, 1, 87, color);	// bot center top
	CG_FillRect (319, 327, 3, 151, color);	// bot center bot
} else if(garand) {
	// sides
	CG_FillRect (0, 0, 80, 480, color);
	CG_FillRect (560, 0, 80, 480, color);

	// center
	if(cgs.media.reticleShaderSimple)
		CG_DrawPic( 80, 0, 480, 480, cgs.media.reticleShaderSimple );

	// hairs
	CG_FillRect (84, 239, 177, 2, color);	// left
	CG_FillRect (320, 242, 1, 58, color);	// center top
	CG_FillRect (319, 300, 2, 178, color);	// center bot
	CG_FillRect (380, 239, 177, 2, color);	// right
} else if (k43) {
	// sides
	CG_FillRect (0, 0, 80, 480, color);
	CG_FillRect (560, 0, 80, 480, color);

	// center
	if(cgs.media.reticleShaderSimple)
		CG_DrawPic( 80, 0, 480, 480, cgs.media.reticleShaderSimple );

	// hairs
	CG_FillRect (84, 239, 177, 2, color);	// left
	CG_FillRect (320, 242, 1, 58, color);	// center top
	CG_FillRect (319, 300, 2, 178, color);	// center bot
	CG_FillRect (380, 239, 177, 2, color);	// right
} else if (mauser) {
	// sides
	CG_FillRect (0, 0, 80, 480, color);
	CG_FillRect (560, 0, 80, 480, color);

	// center
	if(cgs.media.reticleShaderSimple)
		CG_DrawPic( 80, 0, 480, 480, cgs.media.reticleShaderSimple );

	// hairs
	CG_FillRect (84, 239, 177, 2, color);	// left
	CG_FillRect (320, 242, 1, 58, color);	// center top
	CG_FillRect (319, 300, 2, 178, color);	// center bot
	CG_FillRect (380, 239, 177, 2, color);	// right
}


// special reticle for weapon
case WP_FG42SCOPE:
case WP_GARAND_SCOPE:
case WP_MAUSERSCOPE:
case WP_K43_SCOPE:
if(!BG_PlayerMounted(cg.snap->ps.eFlags)) {
// JPW NERVE – don’t let players run with rifles – speed 80 == crouch, 128 == walk, 256 == run
if (VectorLengthSquared(cg.snap->ps.velocity) > SQR(127)) {
if( cg.snap->ps.weapon == WP_FG42SCOPE ) {
CG_FinishWeaponChange( WP_FG42SCOPE, WP_FG42 );
}
if( cg.snap->ps.weapon == WP_GARAND_SCOPE ) {
CG_FinishWeaponChange( WP_GARAND_SCOPE, WP_GARAND );
}
if( cg.snap->ps.weapon == WP_K43_SCOPE ) {
CG_FinishWeaponChange( WP_K43_SCOPE, WP_K43 );
}
if( cg.snap->ps.weapon == WP_MAUSERSCOPE ) {
CG_FinishWeaponChange( WP_MAUSERSCOPE, WP_MAUSER );
}
}



[b]cg_event.c[/b]

// don’t ever autoswitch to secondary fire weapons
// Gordon: Leave autoswitch to secondary kar/carbine as they use alt ammo and arent zoomed: Note, not that it would do this anyway as it isnt in a bank…
if( itemid != WP_FG42SCOPE && itemid != WP_GARAND_SCOPE && itemid != WP_K43_SCOPE && itemid != WP_AMMO && itemid != WP_MAUSERSCOPE) { //----(SA) modified



switch(es->weapon) {
case WP_FG42SCOPE:
newweap = WP_FG42;
break;
case WP_GARAND_SCOPE:
newweap = WP_GARAND;
break;
case WP_K43_SCOPE:
newweap = WP_K43;
break;
case WP_MAUSERSCOPE:
newweap = WP_MAUSER;
break;
default:
break;
}



[b]cg_players.c[/b]

{ WP_MOBILE_MG42, “MOBILE MG42”, },
{ WP_K43, “K43”, },
{ WP_MORTAR, “MORTAR”, },
{ WP_COLT, “COLT”, },
{ WP_LUGER, “LUGER”, },
{ WP_AKIMBO_COLT, “AKIMBO COLTS”, },
{ WP_AKIMBO_LUGER, “AKIMBO LUGERS”,},
{ WP_SILENCED_COLT, “COLT”, },
{ WP_SILENCER, “LUGER”, },
{ WP_AKIMBO_SILENCEDCOLT, “AKIMBO COLTS”, },
{ WP_AKIMBO_SILENCEDLUGER, “AKIMBO LUGERS”,},
{ WP_MAUSER, “MAUSER” },



[b]cg_view.c[/b]

void CG_ZoomIn_f( void )
{
// Gordon: fixed being able to “latch” your zoom by weaponcheck + quick zoomin
// OSP - change for zoom view in demos
if( cg_entities[cg.snap->ps.clientNum].currentState.weapon == WP_GARAND_SCOPE ) {
CG_AdjustZoomVal(-(cg_zoomStepSniper.value), ZOOM_SNIPER);
} else if( cg_entities[cg.snap->ps.clientNum].currentState.weapon == WP_K43_SCOPE) {
CG_AdjustZoomVal(-(cg_zoomStepSniper.value), ZOOM_SNIPER);
} else if(cg.zoomedBinoc) {
CG_AdjustZoomVal(-(cg_zoomStepSniper.value), ZOOM_SNIPER); // JPW NERVE per atvi request all use same vals to match menu (was zoomStepBinoc, ZOOM_BINOC);
} else if (cg_entities[cg.snap->ps.clientNum].currentState.weapon == WP_MAUSERSCOPE) {
CG_AdjustZoomVal(-(cg_zoomStepSniper.value), ZOOM_SNIPER);
}
}

void CG_ZoomOut_f( void )
{
if( cg_entities[cg.snap->ps.clientNum].currentState.weapon == WP_GARAND_SCOPE ) {
CG_AdjustZoomVal(cg_zoomStepSniper.value, ZOOM_SNIPER);
} else if( cg_entities[cg.snap->ps.clientNum].currentState.weapon == WP_K43_SCOPE ) {
CG_AdjustZoomVal(cg_zoomStepSniper.value, ZOOM_SNIPER);
} else if(cg.zoomedBinoc) {
CG_AdjustZoomVal(cg_zoomStepSniper.value, ZOOM_SNIPER); // JPW NERVE per atvi request BINOC);
} else if ( cg_entities[cg.snap->ps.clientNum].currentState.weapon == WP_MAUSERSCOPE ) {
CG_AdjustZoomVal(cg_zoomStepSniper.value, ZOOM_SNIPER);
}
}



// check for scope wepon in use, and switch to if necessary
// OSP - spec/demo scaling allowances
if(cg.predictedPlayerState.weapon == WP_FG42SCOPE)
cg.zoomval = (cg.zoomval == 0) ? cg_zoomDefaultSniper.value : cg.zoomval; // JPW NERVE was DefaultFG, changed per atvi req
else if( cg.predictedPlayerState.weapon == WP_GARAND_SCOPE )
cg.zoomval = (cg.zoomval == 0) ? cg_zoomDefaultSniper.value : cg.zoomval;
else if( cg.predictedPlayerState.weapon == WP_K43_SCOPE )
cg.zoomval = (cg.zoomval == 0) ? cg_zoomDefaultSniper.value : cg.zoomval;
else if ( cg.predictedPlayerState.weapon == WP_MAUSERSCOPE )
cg.zoomval = (cg.zoomval == 0) ? cg_zoomDefaultSniper.value : cg.zoomval;
else if(!(cg.predictedPlayerState.eFlags & EF_ZOOMING))
cg.zoomval = 0;



// check for scope weapon in use, and switch to if necessary
if( cg.weaponSelect == WP_FG42SCOPE ) {
cg.zoomval = cg_zoomDefaultSniper.value; // JPW NERVE was DefaultFG, changed per atvi req
} else if( cg.weaponSelect == WP_GARAND_SCOPE ) {
cg.zoomval = cg_zoomDefaultSniper.value;
} else if( cg.weaponSelect == WP_K43_SCOPE ) {
cg.zoomval = cg_zoomDefaultSniper.value;
} else if( cg.weaponSelect == WP_MAUSERSCOPE ) {
cg.zoomval = cg_zoomDefaultSniper.value;
} else {
cg.zoomval = 0;
}



[b]cg_weapons.c[/b]

	case WP_KAR98:
	case WP_CARBINE:
	case WP_K43:
	case WP_MAUSER:
		re->hModel = cgs.media.machinegunBrassModel;
	case WP_MP40:
	case WP_THOMPSON:
	case WP_STEN:
	default:
		offset[0] = 16;
		offset[1] = -4;
		offset[2] = 24;
		break;
	}
	velocity[0] = -50+25*crandom();
	velocity[1] = -100+40*crandom(); 
	velocity[2] = 200+50*random();
	le->angles.trBase[0] = (rand()&15) + 82; // bullets should come out horizontal not vertical JPW NERVE
	le->angles.trBase[1] = rand()&255; // random spin from extractor
	le->angles.trBase[2] = rand()&31;
	le->angles.trDelta[0] = 2;
	le->angles.trDelta[1] = 1;
	le->angles.trDelta[2] = 0;


case WP_ARTY: return; // to shut the game up
case WP_TRIPMINE: filename = “dynamite.weap”; break;
case WP_MAUSER:
case WP_MAUSERSCOPE: filename = “mauser.weap”; break;
[color]



// don’t draw weapon stuff when looking through a scope
if( weaponNum == WP_FG42SCOPE || weaponNum == WP_GARAND_SCOPE || weaponNum == WP_K43_SCOPE [color=blue]|| weaponNum == WP_MAUSERSCOPE) {
if( isPlayer && !cg.renderingThirdPerson ) {
return;
}
}



case WP_K43_SCOPE:
cg.zoomval = cg_zoomDefaultSniper.value;
cg.zoomedScope = 900; // TODO: add to zoomTable
zoomindex = ZOOM_SNIPER;
break;
case WP_MAUSERSCOPE:
cg.zoomval = cg_zoomDefaultSniper.value;
cg.zoomedScope = 900;
zoomindex = ZOOM_SNIPER;
break;



// setup for a user call to CG_LastWeaponUsed_f()
if(lastweap == cg.lastFiredWeapon) {
// don’t set switchback for some weaps…
switch(lastweap) {
case WP_FG42SCOPE:
case WP_GARAND_SCOPE:
case WP_K43_SCOPE:
case WP_MAUSERSCOPE:
break;
default:
cg.switchbackWeapon = lastweap;
break;
}
} else {



case WP_GARAND:
case WP_KAR98:
case WP_CARBINE:
case WP_K43:
case WP_MAUSER:
//pitchAdd = 4+rand()%3;
//yawRandom = 4;
pitchAdd = 2; //----(SA) for DM
yawRandom = 1; //----(SA) for DM
break;
case WP_GARAND_SCOPE:
case WP_K43_SCOPE:
pitchAdd = 0.3;
break;
case WP_MAUSERSCOPE:
pitchAdd = 0.7;
break;
case WP_FG42SCOPE:
case WP_FG42:



case WP_K43_SCOPE:
case WP_MAUSER:
case WP_MAUSERSCOPE:
// actually yeah. meant that. very rare.
r = (rand() & 3) + 1; // JPW NERVE increased spark frequency so players can tell where rounds are coming from in MP



// (SA) small modification. only do this for non-rifles (so you can see your shots hitting when you’re zooming with a rifle scope)
if (weapon == WP_FG42SCOPE || weapon == WP_GARAND_SCOPE || weapon == WP_K43_SCOPE || weapon == WP_MAUSERSCOPE || (Distance( cg.refdef_current->vieworg, origin ) < 384)) {
if(clientNum) {
// mark and sound can potentially use the surface for override values