Picking up all weapons


(Madras) #1

Hi again!
I’ve got question for You. Where is part of ET source which determines that I can’t pick up some weapons. For example I can’t pick up a Panzerfasut when I’m a medic.

Sorry for my poor English, but I think You will understand whats going on. Thanks! :smiley:


(Mateos) #2

Hi Madras,

Since the mods can do so, I’m not sure you need to edit the source code of ET? Or am I wrong?


(Cambodunum) #3

If i remember correctly … somewhere in bg_classes.c

greetz Cambo


(Madras) #4

I’m making my own mod based on the ET 2.60 solution. There are two bg_classes.c files (on the client-siede and server-side) Must I edit both bg_classed.c files?
Thanks :slight_smile:

EDIT: There’s no info about picking up weapons in these files (in included headers too). ;/ :o


(Cambodunum) #5

Damnit … then its g_items.c

( a second bg_classes.c in cgame sounds weird )

greetz & sorry
Cambo


(Madras) #6

I found these fragments, but I’m not shure where to edit the source exactly. It’s too complicated for beginner (I have been programming since three days :D). I think you are able to help me.

Here I am sharing three interesting functions.

weapon_t G_GetPrimaryWeaponForClient( gclient_t *client )
{
	int i;
	bg_playerclass_t *classInfo;

	if( client->sess.sessionTeam != TEAM_ALLIES && client->sess.sessionTeam != TEAM_AXIS ) {
		return WP_NONE;
	}

	if( client->sess.skill[SK_HEAVY_WEAPONS] < 4 ) {
		if( COM_BitCheck( client->ps.weapons, WP_THOMPSON ) )
			return WP_THOMPSON;
		if( COM_BitCheck( client->ps.weapons, WP_MP40 ) )
			return WP_MP40;
	}

	classInfo = &bg_allies_playerclasses[client->sess.playerType];
	for( i = 0; i < MAX_WEAPS_PER_CLASS; i++) {
		if( classInfo->classWeapons[i] == WP_MP40 || classInfo->classWeapons[i] == WP_THOMPSON )
			continue;

		if( COM_BitCheck( client->ps.weapons, classInfo->classWeapons[i] ) ) {
			return classInfo->classWeapons[i];
		}
	}

	classInfo = &bg_axis_playerclasses[client->sess.playerType];
	for( i = 0; i < MAX_WEAPS_PER_CLASS; i++) {
		if( classInfo->classWeapons[i] == WP_MP40 || classInfo->classWeapons[i] == WP_THOMPSON )
			continue;

		if( COM_BitCheck( client->ps.weapons, classInfo->classWeapons[i] ) ) {
			return classInfo->classWeapons[i];
		}
	}

	return WP_NONE;
}
qboolean G_CanPickupWeapon( weapon_t weapon, gentity_t* ent ) {
	if( ent->client->sess.sessionTeam == TEAM_AXIS ) {
		if( weapon == WP_THOMPSON ) {
			weapon = WP_MP40;
		} else if( weapon == WP_CARBINE ) {
			weapon = WP_KAR98;
		} else if( weapon == WP_GARAND ) {
			weapon = WP_K43;
		}
		
	} else if( ent->client->sess.sessionTeam == TEAM_ALLIES ) {
		if( weapon == WP_MP40 ) {
			weapon = WP_THOMPSON;
		} else if( weapon == WP_KAR98 ) {
			weapon = WP_CARBINE;
		} else if( weapon == WP_K43 ) {
			weapon = WP_GARAND;
		}
	}

	if( ent->client->sess.skill[SK_HEAVY_WEAPONS] >= 4 && ( weapon == WP_THOMPSON || weapon == WP_MP40 ) ) {
		return qfalse;
	}

	return BG_WeaponIsPrimaryForClassAndTeam( ent->client->sess.playerType, ent->client->sess.sessionTeam, weapon );
}



int Pickup_Weapon( gentity_t *ent, gentity_t *other ) {
	int			quantity;
	qboolean	alreadyHave = qfalse;

	// JPW NERVE -- magic ammo for any two-handed weapon
	if( ent->item->giTag == WP_AMMO ) {
		AddMagicAmmo( other, ent->count );

		// if LT isn't giving ammo to self or another LT or the enemy, give him some props
		if( other->client->ps.stats[STAT_PLAYER_CLASS] != PC_FIELDOPS ) {
			if ( ent->parent && ent->parent->client && other->client->sess.sessionTeam == ent->parent->client->sess.sessionTeam ) {
				if (!(ent->parent->client->PCSpecialPickedUpCount % LT_SPECIAL_PICKUP_MOD)) {
					AddScore(ent->parent, WOLF_AMMO_UP);
					if(ent->parent && ent->parent->client) {
						G_LogPrintf("Ammo_Pack: %d %d
", ent->parent - g_entities, other - g_entities);	// OSP
					}
				}
				ent->parent->client->PCSpecialPickedUpCount++;
				G_AddSkillPoints( ent->parent, SK_SIGNALS, 1.f );
				G_DebugAddSkillPoints( ent->parent, SK_SIGNALS, 1.f, "ammo pack picked up" ); 

				// extracted code originally here into AddMagicAmmo -xkan, 9/18/2002
				// add 1 clip of magic ammo for any two-handed weapon
			}
			return RESPAWN_SP;
		}
	}

	quantity = ent->count;

	// check if player already had the weapon
	alreadyHave = COM_BitCheck( other->client->ps.weapons, ent->item->giTag );

	// JPW NERVE  prevents drop/pickup weapon "quick reload" exploit
	if( alreadyHave ) {
		Add_Ammo( other, ent->item->giTag, quantity, qfalse );

		// Gordon: secondary weapon ammo
		if( ent->delay ) {
			Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
		}
	} else {
		if( level.time - other->client->dropWeaponTime < 1000 ) {
			return 0;
		}

		if( other->client->ps.weapon == WP_MORTAR_SET || other->client->ps.weapon == WP_MOBILE_MG42_SET ) {
			return 0;
		}

		// See if we can pick it up
		if( G_CanPickupWeapon( ent->item->giTag, other ) ) {
			weapon_t primaryWeapon = G_GetPrimaryWeaponForClient( other->client );

			// rain - added parens around ambiguous &&
			if( primaryWeapon || 
				(other->client->sess.playerType == PC_SOLDIER && other->client->sess.skill[SK_HEAVY_WEAPONS] >= 4) ) {

				if( primaryWeapon ) {
					// drop our primary weapon
					G_DropWeapon( other, primaryWeapon );
				}

				// now pickup the other one
				other->client->dropWeaponTime = level.time;

				// add the weapon
				COM_BitSet( other->client->ps.weapons, ent->item->giTag );

				// 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_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 );
				}

				other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = 0;
				other->client->ps.ammo[BG_FindAmmoForWeapon(ent->item->giTag)] = 0;

				if( ent->item->giTag == WP_MORTAR ) {
					other->client->ps.ammo[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						Add_Ammo( other, weapAlts[ ent->item->giTag ], ent->delay, qfalse );
					}
				} else {
					other->client->ps.ammoclip[BG_FindClipForWeapon(ent->item->giTag)] = quantity;

					// Gordon: secondary weapon ammo
					if( ent->delay ) {
						other->client->ps.ammo[ weapAlts[ ent->item->giTag ] ] = ent->delay;
					}
				}
			}
		} else {
			return 0;
		}
	}

	// TAT 1/6/2003 - If we are a bot, call the pickup function
	if( other->r.svFlags & SVF_BOT )
		BotPickupWeapon( other->s.number, ent->item->giTag, alreadyHave );

	return -1;
}

(Madras) #7

OK, I used the ETPub src. Previously I didn’t know that ETPub has got this option.


(Soak) #8

Yeah does anyone know where I could get an updated copy of the ETPub source? Took a quick look around but nothing came up.


(Madras) #9

The latest ETPub version: http://svn2.assembla.com/svn/etpub/trunk/
To download the solution you need Tortoise SVN: http://tortoisesvn.net/downloads


(Soak) #10

This is the section of code you want:

qboolean G_CanPickupWeapon( weapon_t weapon, gentity_t* ent ) {
	if( ent->client->sess.sessionTeam == TEAM_AXIS ) {
		if( weapon == WP_THOMPSON ) {
			weapon = WP_MP40;
		} else if( weapon == WP_CARBINE ) {
			weapon = WP_KAR98;
		} else if( weapon == WP_GARAND ) {
			weapon = WP_K43;
		}
		
	} else if( ent->client->sess.sessionTeam == TEAM_ALLIES ) {
		if( weapon == WP_MP40 ) {
			weapon = WP_THOMPSON;
		} else if( weapon == WP_KAR98 ) {
			weapon = WP_CARBINE;
		} else if( weapon == WP_K43 ) {
			weapon = WP_GARAND;
		}
	}

	if( ent->client->sess.skill[SK_HEAVY_WEAPONS] >= 4 && ( weapon == WP_THOMPSON || weapon == WP_MP40 ) ) {
		return qfalse;
	}

	return BG_WeaponIsPrimaryForClassAndTeam( ent->client->sess.playerType, ent->client->sess.sessionTeam, weapon );
}

This takes a player and a primary weapon as arguments, then gets the equivalent weapon from the player’s team. It then returns whether or not the equivalent weapon is a primary weapon for the class and team:

BG_WeaponIsPrimaryForClassAndTeam( ent->client->sess.playerType, ent->client->sess.sessionTeam, weapon )

There is also a check to make sure soldiers with smgs in their second (i.e. heavy weapons 4+) slot can’t pick up another smg. You may be able to check this - a level 4 soldier with pistols should not be able to pick up an smg based on this code.

Since you want players to be able to pick up anything the solution is simple - replace everything with:

return qtrue;

Let me know how it works out (not 100% sure this will work, you may need to change something else) - and good luck :slight_smile:

Soak