示例#1
0
文件: g_items.c 项目: hettoo/racesow
/*
* G_PickupItem
*/
qboolean G_PickupItem( edict_t *ent, edict_t *other )
{
	gsitem_t	*it;
	qboolean taken = qfalse;

	if( !ent || !other )
		return qfalse;

	if( other->r.client && G_ISGHOSTING( other ) )
		return qfalse;

	if( !ent->item || !( ent->item->flags & ITFLAG_PICKABLE ) )
		return qfalse;

	it = ent->item;

	if( it->type & IT_WEAPON )
	{
		taken = Pickup_Weapon( ent, other );
	}
	else if( it->type & IT_AMMO )
	{
		taken = Pickup_Ammo( ent, other );
	}
	else if( it->type & IT_ARMOR )
	{
		taken = Pickup_Armor( ent, other );
	}
	else if( it->type & IT_HEALTH )
	{
		taken = Pickup_Health( ent, other );
	}
	else if( it->type & IT_POWERUP )
	{
		taken = Pickup_Powerup( ent, other );
	}

	if( taken && other->r.client )
		G_Gametype_ScoreEvent( other->r.client, "pickup", it->classname );

	return taken;
}
示例#2
0
/*
* G_PickupItem
*/
bool G_PickupItem( edict_t *other, const gsitem_t *it, int flags, int count, const int *invpack )
{
	bool taken = false;

	if( other->r.client && G_ISGHOSTING( other ) )
		return false;

	if( !it || !( it->flags & ITFLAG_PICKABLE ) )
		return false;

	if( it->type & IT_WEAPON )
	{
		taken = Pickup_Weapon( other, it, flags, count );
	}
	else if( it->type & IT_AMMO )
	{
		taken = Pickup_Ammo( other, it, count, invpack );
	}
	else if( it->type & IT_ARMOR )
	{
		taken = Pickup_Armor( other, it );
	}
	else if( it->type & IT_HEALTH )
	{
		taken = Pickup_Health( other, it, flags );
	}
	else if( it->type & IT_POWERUP )
	{
		taken = Pickup_Powerup( other, it, flags, count );
	}

	if( taken && other->r.client )
		G_Gametype_ScoreEvent( other->r.client, "pickup", it->classname );

	return taken;
}
示例#3
0
/*
===============
Touch_Item
===============
*/
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
	int			respawn;
	qboolean	predict;

	if (!other->client)
		return;
	if (other->health < 1)
		return;		// dead people can't pickup

	// the same pickup rules are used for client side and server side
	if ( !BG_CanItemBeGrabbed( g_gametype.integer, &ent->s, &other->client->ps ) ) {
		return;
	}

	G_LogPrintf( "Item: %i %s\n", other->s.number, ent->item->classname );

	predict = other->client->pers.predictItemPickup;

	// call the item-specific pickup function
	switch( ent->item->giType ) {
	case IT_WEAPON:
		respawn = Pickup_Weapon(ent, other);
//		predict = qfalse;
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo(ent, other);
//		predict = qfalse;
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor(ent, other);
		break;
	case IT_HEALTH:
		respawn = Pickup_Health(ent, other);
		break;
	case IT_POWERUP:
		respawn = Pickup_Powerup(ent, other);
		predict = qfalse;
		break;
#ifdef MISSIONPACK
	case IT_PERSISTANT_POWERUP:
		respawn = Pickup_PersistantPowerup(ent, other);
		break;
#endif
	case IT_TEAM:
		respawn = Pickup_Team(ent, other);
		break;
	case IT_HOLDABLE:
		respawn = Pickup_Holdable(ent, other);
		break;
	default:
		return;
	}

	if ( !respawn ) {
		return;
	}

	// play the normal pickup sound
	if (predict) {
		G_AddPredictableEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	} else {
		G_AddEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	}

	// powerup pickups are global broadcasts
	if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM) {
		// if we want the global sound to play
		if (!ent->speed) {
			gentity_t	*te;

			te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
			te->s.eventParm = ent->s.modelindex;
			te->r.svFlags |= SVF_BROADCAST;
		} else {
			gentity_t	*te;

			te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
			te->s.eventParm = ent->s.modelindex;
			// only send this temp entity to a single client
			te->r.svFlags |= SVF_SINGLECLIENT;
			te->r.singleClient = other->s.number;
		}
	}

	// fire item targets
	G_UseTargets (ent, other);

	// wait of -1 will not respawn
	if ( ent->wait == -1 ) {
		ent->r.svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->r.contents = 0;
		ent->unlinkAfterEvent = qtrue;
		return;
	}

	// non zero wait overrides respawn time
	if ( ent->wait ) {
		respawn = ent->wait;
	}

	// random can be used to vary the respawn time
	if ( ent->random ) {
		respawn += crandom() * ent->random;
		if ( respawn < 1 ) {
			respawn = 1;
		}
	}

	// dropped items will not respawn
	if ( ent->flags & FL_DROPPED_ITEM ) {
		ent->freeAfterEvent = qtrue;
	}

	// picked up items still stay around, they just don't
	// draw anything.  This allows respawnable items
	// to be placed on movers.
	ent->r.svFlags |= SVF_NOCLIENT;
	ent->s.eFlags |= EF_NODRAW;
	ent->r.contents = 0;

	// ZOID
	// A negative respawn times means to never respawn this item (but don't
	// delete it).  This is used by items that are respawned by third party
	// events such as ctf flags
	if ( respawn <= 0 ) {
		ent->nextthink = 0;
		ent->think = 0;
	} else {
		ent->nextthink = level.time + respawn * 1000;
		ent->think = RespawnItem;
	}
	trap_LinkEntity( ent );
}
示例#4
0
/*
===============
Touch_Item
===============
*/
void Touch_Item( gentity_t *ent, gentity_t *other, trace_t *trace ) {
	int respawn;
	int makenoise = EV_ITEM_PICKUP;

	// only activated items can be picked up
	if ( !ent->active ) {
		return;
	} else {
		// need to set active to false if player is maxed out
		ent->active = qfalse;
	}

	if ( !other->client ) {
		return;
	}
	if ( other->health < 1 ) {
		return;     // dead people can't pickup

	}
	// the same pickup rules are used for client side and server side
	if ( !BG_CanItemBeGrabbed( &ent->s, &other->client->ps ) ) {
		return;
	}

	G_LogPrintf( "Item: %i %s\n", other->s.number, ent->item->classname );

	// call the item-specific pickup function
	switch ( ent->item->giType ) {
	case IT_WEAPON:
		respawn = Pickup_Weapon( ent, other );
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo( ent, other );
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor( ent, other );
		break;
	case IT_HEALTH:
		respawn = Pickup_Health( ent, other );
		break;
	case IT_POWERUP:
		respawn = Pickup_Powerup( ent, other );
		break;
	case IT_TEAM:
		respawn = Pickup_Team( ent, other );
		break;
	case IT_HOLDABLE:
		respawn = Pickup_Holdable( ent, other );
		break;
	case IT_KEY:
		respawn = Pickup_Key( ent, other );
		break;
	case IT_TREASURE:
		respawn = Pickup_Treasure( ent, other );
		break;
	case IT_CLIPBOARD:
		respawn = Pickup_Clipboard( ent, other );
		// send the event to the client to request that the UI draw a popup
		// (specified by the configstring in ent->s.density).
		//G_AddEvent( other, EV_POPUP, ent->s.density);
		//if(ent->key)
		//G_AddEvent( other, EV_GIVEPAGE, ent->key );
		break;
	default:
		return;
	}

	if ( !respawn ) {
		return;
	}

	// play sounds
	if ( ent->noise_index ) {
		// (SA) a sound was specified in the entity, so play that sound
		// (this G_AddEvent) and send the pickup as "EV_ITEM_PICKUP_QUIET"
		// so it doesn't make the default pickup sound when the pickup event is recieved
		makenoise = EV_ITEM_PICKUP_QUIET;
		G_AddEvent( other, EV_GENERAL_SOUND, ent->noise_index );
	}


	// send the pickup event
	if ( other->client->pers.predictItemPickup ) {
		G_AddPredictableEvent( other, makenoise, ent->s.modelindex );
	} else {
		G_AddEvent( other, makenoise, ent->s.modelindex );
	}

	// powerup pickups are global broadcasts
	if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM ) {
		// (SA) probably need to check for IT_KEY here too... (coop?)
		gentity_t   *te;

		te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
		te->s.eventParm = ent->s.modelindex;
		te->r.svFlags |= SVF_BROADCAST;

		// (SA) set if we want this to only go to the pickup client
//		te->r.svFlags |= SVF_SINGLECLIENT;
//		te->r.singleClient = other->s.number;

	}

	// fire item targets
	G_UseTargets( ent, other );

	// wait of -1 will not respawn
	if ( ent->wait == -1 ) {
		ent->flags |= FL_NODRAW;
		//ent->r.svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->r.contents = 0;
		ent->unlinkAfterEvent = qtrue;
		return;
	}

	// wait of -2 will respawn but not be available for pickup anymore
	// (partial use things that leave a spent modle (ex. plate for turkey)
	if ( respawn == RESPAWN_PARTIAL_DONE ) {
		ent->s.density = ( 1 << 9 );    // (10 bits of data transmission for density)
		ent->active = qtrue;        // re-activate
		trap_LinkEntity( ent );
		return;
	}

	if ( respawn == RESPAWN_PARTIAL ) {    // multi-stage health
		ent->s.density--;
		if ( ent->s.density ) {        // still not completely used up ( (SA) this will change to == 0 and stage 1 will be a destroyable item (plate/etc.) )
			ent->active = qtrue;        // re-activate
			trap_LinkEntity( ent );
			return;
		}
	}


	// non zero wait overrides respawn time
	if ( ent->wait ) {
		respawn = ent->wait;
	}

	// random can be used to vary the respawn time
	if ( ent->random ) {
		respawn += crandom() * ent->random;
		if ( respawn < 1 ) {
			respawn = 1;
		}
	}

	// dropped items will not respawn
	if ( ent->flags & FL_DROPPED_ITEM ) {
		ent->freeAfterEvent = qtrue;
	}

	// picked up items still stay around, they just don't
	// draw anything.  This allows respawnable items
	// to be placed on movers.
	ent->r.svFlags |= SVF_NOCLIENT;
	ent->flags |= FL_NODRAW;
	//ent->s.eFlags |= EF_NODRAW;
	ent->r.contents = 0;

	// ZOID
	// A negative respawn times means to never respawn this item (but don't
	// delete it).  This is used by items that are respawned by third party
	// events such as ctf flags
	if ( respawn <= 0 ) {
		ent->nextthink = 0;
		ent->think = 0;
	} else {
		ent->nextthink = level.time + respawn * 1000;
		ent->think = RespawnItem;
	}
	trap_LinkEntity( ent );
}
示例#5
0
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
	int			respawn = 0;

	if (!other->client)
		return;
	if (other->health < 1)
		return;		// dead people can't pickup

	if ( other->client->ps.pm_time > 0 )
	{//cant pick up when out of control
		return;
	}

	// NPCs can pick it up
	if ((ent->spawnflags &  ITMSF_ALLOWNPC) && (!other->s.number))
	{
		return;
	}

	// Players cannot pick it up
	if ( (ent->spawnflags &  ITMSF_NOPLAYER) && (other->s.number) )
	{
		return;
	}

	if ( ent->noDamageTeam != TEAM_FREE && other->client->playerTeam != ent->noDamageTeam )
	{//only one team can pick it up
		return;
	}
	
	if ( !G_CanPickUpWeapons( other ) )
	{//FIXME: some flag would be better
		//droids can't pick up items/weapons!
		return;
	}

	//FIXME: need to make them run toward a dropped weapon when fleeing without one?
	//FIXME: need to make them come out of flee mode when pick up their old weapon?
	if ( CheckItemCanBePickedUpByNPC( ent, other ) )
	{
		if ( other->NPC && other->NPC->goalEntity && other->NPC->goalEntity == ent )
		{//they were running to pick me up, they did, so clear goal
			other->NPC->goalEntity	= NULL;
			other->NPC->squadState	= SQUAD_STAND_AND_SHOOT;
 			NPCInfo->tempBehavior	= BS_DEFAULT;
			TIMER_Set(other, "flee", -1); 
		}
		else
		{
			return;
		}
	}
	else if ( !(ent->spawnflags &  ITMSF_ALLOWNPC) )
	{// NPCs cannot pick it up
		if ( other->s.number != 0 )
		{// Not the player?
			return;
		}
	}

	// the same pickup rules are used for client side and server side
	if ( !BG_CanItemBeGrabbed( &ent->s, &other->client->ps ) ) {
		return;
	}

	if ( other->client )
	{
		if ( (other->client->ps.eFlags&EF_FORCE_GRIPPED) || (other->client->ps.eFlags&EF_FORCE_DRAINED) )
		{//can't pick up anything while being gripped
			return;
		}
		if ( PM_InKnockDown( &other->client->ps ) && !PM_InGetUp( &other->client->ps ) )
		{//can't pick up while in a knockdown
			return;
		}
	}
	if (!ent->item) {		//not an item!
		gi.Printf( "Touch_Item: %s is not an item!\n", ent->classname);
		return;
	}

	if ( ent->item->giType == IT_WEAPON
		&& ent->item->giTag == WP_SABER )
	{//a saber
		if ( ent->delay > level.time )
		{//just picked it up, don't pick up again right away
			return;
		}
	}

	if ( other->s.number < MAX_CLIENTS
		&& (ent->spawnflags&ITMSF_USEPICKUP) )
	{//only if player is holing use button
		if ( !(other->client->usercmd.buttons&BUTTON_USE) )
		{//not holding use?
			return;
		}
	}

	qboolean bHadWeapon = qfalse;
	// call the item-specific pickup function
	switch( ent->item->giType ) 
	{
	case IT_WEAPON:
		if ( other->NPC && other->s.weapon == WP_NONE )
		{//Make them duck and sit here for a few seconds
			int pickUpTime = Q_irand( 1000, 3000 );
			TIMER_Set( other, "duck", pickUpTime );
			TIMER_Set( other, "roamTime", pickUpTime );
			TIMER_Set( other, "stick", pickUpTime );
			TIMER_Set( other, "verifyCP", pickUpTime );
			TIMER_Set( other, "attackDelay", 600 );
			respawn = 0;
		}
		if ( other->client->ps.stats[STAT_WEAPONS] & ( 1 << ent->item->giTag ) )
		{
			bHadWeapon = qtrue;
		}
		respawn = Pickup_Weapon(ent, other);
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo(ent, other);
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor(ent, other);
		break;
	case IT_HEALTH:
		respawn = Pickup_Health(ent, other);
		break;
	case IT_HOLDABLE:
		respawn = Pickup_Holdable(ent, other);
		break;
	case IT_BATTERY:
		respawn = Pickup_Battery( ent, other );
		break;
	case IT_HOLOCRON:
		respawn = Pickup_Holocron( ent, other );
		break;
	default:
		return;
	}

	if ( !respawn ) 
	{
		return;
	}

	// play the normal pickup sound
	if ( !other->s.number && g_timescale->value < 1.0f  )
	{//SIGH... with timescale on, you lose events left and right
extern void CG_ItemPickup( int itemNum, qboolean bHadItem );
		// but we're SP so we'll cheat
		cgi_S_StartSound( NULL, other->s.number, CHAN_AUTO,	cgi_S_RegisterSound( ent->item->pickup_sound ) );
		// show icon and name on status bar
		CG_ItemPickup( ent->s.modelindex, bHadWeapon );
	}
	else
	{
		if ( bHadWeapon )
		{
			G_AddEvent( other, EV_ITEM_PICKUP, -ent->s.modelindex );
		} 
		else
		{
			G_AddEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
		}
	}

	// fire item targets
	G_UseTargets (ent, other);

	if ( ent->item->giType == IT_WEAPON
		&& ent->item->giTag == WP_SABER )
	{//a saber that was picked up
		if ( ent->count < 0 )
		{//infinite supply
			ent->delay = level.time + 500;
			return;
		}
		ent->count--;
		if ( ent->count > 0 )
		{//still have more to pick up
			ent->delay = level.time + 500;
			return;
		}
	}
	// wait of -1 will not respawn
//	if ( ent->wait == -1 ) 
	{
		//why not just remove me?
		G_FreeEntity( ent );
		/*
		//NOTE: used to do this:  (for respawning?)
		ent->svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->contents = 0;
		ent->unlinkAfterEvent = qtrue;
		*/
		return;
	}
}
示例#6
0
文件: g_items.cpp 项目: AlexXT/OpenJK
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
	int			respawn = 0;

	if (!other->client)
		return;
	if (other->health < 1)
		return;		// dead people can't pickup

	if ( other->client->ps.pm_time > 0 )
	{//cant pick up when out of control
		return;
	}

	// Only monsters can pick it up
	if ((ent->spawnflags &  ITMSF_MONSTER) && (other->client->playerTeam == TEAM_PLAYER))
	{
		return;
	}

	// Only starfleet can pick it up
	if ((ent->spawnflags &  ITMSF_TEAM) && (other->client->playerTeam != TEAM_PLAYER))
	{
		return;
	}


	if ( other->client->NPC_class == CLASS_ATST ||
		other->client->NPC_class == CLASS_GONK ||
		other->client->NPC_class == CLASS_MARK1 ||
		other->client->NPC_class == CLASS_MARK2 ||
		other->client->NPC_class == CLASS_MOUSE ||
		other->client->NPC_class == CLASS_PROBE ||
		other->client->NPC_class == CLASS_PROTOCOL ||
		other->client->NPC_class == CLASS_R2D2 ||
		other->client->NPC_class == CLASS_R5D2 ||
		other->client->NPC_class == CLASS_SEEKER ||
		other->client->NPC_class == CLASS_REMOTE ||
		other->client->NPC_class == CLASS_SENTRY )
	{//FIXME: some flag would be better
		//droids can't pick up items/weapons!
		return;
	}

	//FIXME: need to make them run toward a dropped weapon when fleeing without one?
	//FIXME: need to make them come out of flee mode when pick up their old weapon?
	if ( CheckItemCanBePickedUpByNPC( ent, other ) )
	{
		if ( other->NPC && other->NPC->goalEntity && other->NPC->goalEntity->enemy == ent )
		{//they were running to pick me up, they did, so clear goal
			other->NPC->goalEntity = NULL;
			other->NPC->squadState = SQUAD_STAND_AND_SHOOT;
		}
	}
	else if (!(ent->spawnflags &  ITMSF_TEAM) && !(ent->spawnflags &  ITMSF_MONSTER))
	{// Only player can pick it up
		if ( other->s.number != 0 )	// Not the player?
		{
			return;
		}
	}

	// the same pickup rules are used for client side and server side
	if ( !BG_CanItemBeGrabbed( &ent->s, &other->client->ps ) ) {
		return;
	}

	if ( other->client )
	{
		if ( other->client->ps.eFlags&EF_FORCE_GRIPPED )
		{//can't pick up anything while being gripped
			return;
		}
		if ( PM_InKnockDown( &other->client->ps ) && !PM_InGetUp( &other->client->ps ) )
		{//can't pick up while in a knockdown
			return;
		}
	}
	if (!ent->item) {		//not an item!
		gi.Printf( "Touch_Item: %s is not an item!\n", ent->classname);
		return;
	}
	qboolean bHadWeapon = qfalse;
	// call the item-specific pickup function
	switch( ent->item->giType )
	{
	case IT_WEAPON:
		if ( other->NPC && other->s.weapon == WP_NONE )
		{//Make them duck and sit here for a few seconds
			int pickUpTime = Q_irand( 1000, 3000 );
			TIMER_Set( other, "duck", pickUpTime );
			TIMER_Set( other, "roamTime", pickUpTime );
			TIMER_Set( other, "stick", pickUpTime );
			TIMER_Set( other, "verifyCP", pickUpTime );
			TIMER_Set( other, "attackDelay", 600 );
			respawn = 0;
		}
		if ( other->client->ps.stats[STAT_WEAPONS] & ( 1 << ent->item->giTag ) )
		{
			bHadWeapon = qtrue;
		}
		respawn = Pickup_Weapon(ent, other);
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo(ent, other);
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor(ent, other);
		break;
	case IT_HEALTH:
		respawn = Pickup_Health(ent, other);
		break;
	case IT_HOLDABLE:
		respawn = Pickup_Holdable(ent, other);
		break;
	case IT_BATTERY:
		respawn = Pickup_Battery( ent, other );
		break;
	case IT_HOLOCRON:
		respawn = Pickup_Holocron( ent, other );
		break;
	default:
		return;
	}

	if ( !respawn )
	{
		return;
	}

	// play the normal pickup sound
	if ( !other->s.number && g_timescale->value < 1.0f  )
	{//SIGH... with timescale on, you lose events left and right
extern void CG_ItemPickup( int itemNum, qboolean bHadItem );
		// but we're SP so we'll cheat
		cgi_S_StartSound( NULL, other->s.number, CHAN_AUTO,	cgi_S_RegisterSound( ent->item->pickup_sound ) );
		// show icon and name on status bar
		CG_ItemPickup( ent->s.modelindex, bHadWeapon );
	}
	else
	{
		if ( bHadWeapon )
		{
			G_AddEvent( other, EV_ITEM_PICKUP, -ent->s.modelindex );
		}
		else
		{
			G_AddEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
		}
	}

	// fire item targets
	G_UseTargets (ent, other);

	// wait of -1 will not respawn
//	if ( ent->wait == -1 )
	{
		//why not just remove me?
		G_FreeEntity( ent );
		/*
		//NOTE: used to do this:  (for respawning?)
		ent->svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->contents = 0;
		ent->unlinkAfterEvent = qtrue;
		*/
		return;
	}
}
示例#7
0
/*
===============
Touch_Item
===============
*/
void Touch_Item(gentity_t * ent, gentity_t * other, trace_t * trace)
{
	int respawn;
	qboolean predict;
	int bandolierFactor;

	//Makro - some checks
	if (other == NULL || ent == NULL)
		return;

	if (!other->client)
		return;
	if (other->health < 1)
		return;		// dead people can't pickup

	//Makro - even more bot hacks !
	//this way, we can remove the item from the bot's library for a few seconds
	//so bots won't get stuck in a loop between 2 items
	if ((ent->r.svFlags & MASK_BOTHACK) == MASK_BOTHACK) {
		if (ent->nextthink < level.time) {
			ent->nextthink = level.time + 45 * 1000;
		}
		return;
	}
	// the same pickup rules are used for client side and server side
	if (!BG_CanItemBeGrabbed(g_gametype.integer, &ent->s, &other->client->ps))
		return;

	predict = other->client->pers.predictItemPickup;

	if (other->client->ps.stats[STAT_HOLDABLE_ITEM] & (1 << HI_BANDOLIER))
		bandolierFactor = 2;
	else
		bandolierFactor = 1;

	//Elder: should check if the item was recently thrown ... if it was, then
	//don't allow it to be picked up ... or something like that

	// call the item-specific pickup function
	switch (ent->item->giType) {
	case IT_WEAPON:
		switch (ent->item->giTag) {
			//Blaze: Check to see if we already have the weapon,
			//If not so check and see if we have less then full ammo, if so pick up gun
			//Elder's version:
			//Accumulators (e.g. knife, grenade): if you have the weap AND the max limit, leave
			//Pistols: if you have akimbos AND max clips, leave
			//Akimbos: shouldn't pick them up b/c they shouldn't be dropped
			//Specials: if you have more than/equal to limit (remember bando later), leave
		case WP_KNIFE:
			if (((other->client->ps.stats[STAT_WEAPONS] & (1 << WP_KNIFE)) == (1 << WP_KNIFE)) &&
			    (other->client->ps.ammo[ent->item->giTag] >= RQ3_KNIFE_MAXCLIP * bandolierFactor))
				return;
			break;
		case WP_GRENADE:
			if (((other->client->ps.stats[STAT_WEAPONS] & (1 << WP_GRENADE)) == (1 << WP_GRENADE)) &&
			    (other->client->ps.ammo[ent->item->giTag] >= RQ3_GRENADE_MAXCLIP * bandolierFactor))
				return;
			break;
		case WP_PISTOL:
			//Elder: always have pistol - but extra ones give akimbo or clips
			if (((other->client->ps.stats[STAT_WEAPONS] & (1 << WP_AKIMBO)) == (1 << WP_AKIMBO)) &&
			    other->client->numClips[WP_PISTOL] >= RQ3_PISTOL_MAXCLIP * bandolierFactor) {
				//leave if we have max clips and akimbos
				return;
			}
			break;
		case WP_M3:
		case WP_HANDCANNON:
		case WP_MP5:
		case WP_M4:
		case WP_SSG3000:
			//Elder: check to see if it's in mid-air or over the limit
			if (other->client->uniqueWeapons >= g_RQ3_maxWeapons.integer + (bandolierFactor - 1) ||
			    ent->s.pos.trDelta[2] != 0)
				return;

			// Paril: fix/workaround for 4085
			// don't pick up dupe special weapons even if we could.
			if ((other->client->ps.stats[STAT_WEAPONS] & (1 << ent->item->giTag)) == (1 << ent->item->giTag))
				return;
			break;
		case WP_AKIMBO:
		default:
			//Elder: shouldn't be here
			G_Printf("Touch_Item received invalid IT_WEAPON giTag: %d\n", ent->item->giTag);
			return;
			break;
		}

		respawn = Pickup_Weapon(ent, other, bandolierFactor);

		//Elder: added pistol and knife condition
		if (ent->item->giTag == WP_GRENADE || ent->item->giTag == WP_PISTOL || ent->item->giTag == WP_KNIFE) {
			respawn = 30;
		} else {
			//Elder: moved here
			respawn = -1;	//Dont respawn weapons
		}

//              predict = qfalse;
		break;
	case IT_AMMO:
		switch (ent->item->giTag) {
			//Blaze: dont pick up the clip if we already have all the clips we can have
		case WP_KNIFE:
			if (other->client->numClips[ent->item->giTag] >= 0)
				return;	//No clips for knifes
			break;
		case WP_PISTOL:
			if (other->client->numClips[ent->item->giTag] >= RQ3_PISTOL_MAXCLIP * bandolierFactor)
				return;
			break;
		case WP_M3:
			if (other->client->numClips[ent->item->giTag] >= RQ3_M3_MAXCLIP * bandolierFactor)
				return;
			break;
		case WP_HANDCANNON:
			if (other->client->numClips[ent->item->giTag] >= RQ3_HANDCANNON_MAXCLIP * bandolierFactor)
				return;
			break;
		case WP_MP5:
			if (other->client->numClips[ent->item->giTag] >= RQ3_MP5_MAXCLIP * bandolierFactor)
				return;
			break;
		case WP_M4:
			if (other->client->numClips[ent->item->giTag] >= RQ3_M4_MAXCLIP * bandolierFactor)
				return;
			break;
		case WP_SSG3000:
			if (other->client->numClips[ent->item->giTag] >= RQ3_SSG3000_MAXCLIP * bandolierFactor)
				return;
			break;
		case WP_AKIMBO:
			if (other->client->numClips[ent->item->giTag] >= RQ3_AKIMBO_MAXCLIP * bandolierFactor)
				return;
			break;
		case WP_GRENADE:
			if (other->client->numClips[ent->item->giTag] >= 0)
				return;	//no clips for grenades
			break;
		}
		respawn = Pickup_Ammo(ent, other, bandolierFactor);
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor(ent, other);
		break;
	case IT_HEALTH:
		respawn = Pickup_Health(ent, other);
		break;
	case IT_POWERUP:
		respawn = Pickup_Powerup(ent, other);
		predict = qfalse;
		break;
	case IT_TEAM:
		// NiceAss: can't pick it up if it's in mid-flight (someone dropped it)
		if (ent->s.pos.trDelta[2] != 0.0f)
			return;
		respawn = Pickup_Team(ent, other);
		break;
	case IT_HOLDABLE:
		//Elder: check to see if it's in mid-air
		if (other->client->uniqueItems >= g_RQ3_maxItems.integer || ent->s.pos.trDelta[2] != 0)
			return;
		respawn = Pickup_Holdable(ent, other);
		break;
	default:
		return;
	}

	if (!respawn) {
		return;
	}

	// play the normal pickup sound
	if (predict) {
		G_AddPredictableEvent(other, EV_ITEM_PICKUP, ent->s.modelindex);
	} else {
		G_AddEvent(other, EV_ITEM_PICKUP, ent->s.modelindex);
	}

	// powerup pickups are global broadcasts
	if (ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM) {
		// if we want the global sound to play
		if (!ent->speed) {
			gentity_t *te;

			te = G_TempEntity(ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP);
			te->s.eventParm = ent->s.modelindex;
			te->r.svFlags |= SVF_BROADCAST;
		} else {
			gentity_t *te;

			te = G_TempEntity(ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP);
			te->s.eventParm = ent->s.modelindex;
			// only send this temp entity to a single client
			te->r.svFlags |= SVF_SINGLECLIENT;
			te->r.singleClient = other->s.number;
		}
	}
	// fire item targets
	G_UseTargets(ent, other);

	// wait of -1 will not respawn
	if (ent->wait == -1) {
		ent->r.svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->r.contents = 0;
		ent->unlinkAfterEvent = qtrue;
		return;
	}
	// non zero wait overrides respawn time
	if (ent->wait) {
		respawn = ent->wait;
	}
	// random can be used to vary the respawn time
	if (ent->random) {
		respawn += crandom() * ent->random;
		if (respawn < 1) {
			respawn = 1;
		}
	}
	// dropped items will not respawn
	if (ent->flags & FL_DROPPED_ITEM) {
		ent->freeAfterEvent = qtrue;
	}
	// picked up items still stay around, they just don't
	// draw anything.  This allows respawnable items
	// to be placed on movers.
	ent->r.svFlags |= SVF_NOCLIENT;
	ent->s.eFlags |= EF_NODRAW;
	ent->r.contents = 0;

	// ZOID
	// A negative respawn times means to never respawn this item (but don't
	// delete it).  This is used by items that are respawned by third party
	// events such as ctf flags
	if (respawn <= 0) {
		ent->nextthink = 0;
		ent->think = 0;
	} else {
		ent->nextthink = level.time + respawn * 1000;
		ent->think = RespawnItem;
	}
	trap_LinkEntity(ent);
}
示例#8
0
/*
===============
Touch_Item
===============
*/
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
	int			respawn;
	qboolean	predict;

	//instant gib
	if ((g_instantgib.integer || g_rockets.integer || g_gametype.integer == GT_CTF_ELIMINATION || g_elimination_allgametypes.integer)
                && ent->item->giType != IT_TEAM)
		return;

	//Cannot touch flag before round starts
	if(g_gametype.integer == GT_CTF_ELIMINATION && level.roundNumber != level.roundNumberStarted)
		return;

	//Cannot take ctf elimination oneway
	if(g_gametype.integer == GT_CTF_ELIMINATION && g_elimination_ctf_oneway.integer!=0 && (
			(other->client->sess.sessionTeam==TEAM_BLUE && (level.eliminationSides+level.roundNumber)%2 == 0 ) ||
			(other->client->sess.sessionTeam==TEAM_RED && (level.eliminationSides+level.roundNumber)%2 != 0 ) ))
		return;

	if (g_gametype.integer == GT_ELIMINATION || g_gametype.integer == GT_LMS)
		return;		//nothing to pick up in elimination

	if (!other->client)
		return;
	if (other->health < 1)
		return;		// dead people can't pickup

	// the same pickup rules are used for client side and server side
	if ( !BG_CanItemBeGrabbed( g_gametype.integer, &ent->s, &other->client->ps ) ) {
		return;
	}

	//In double DD we cannot "pick up" a flag we already got
	if(g_gametype.integer == GT_DOUBLE_D) {
		if( strcmp(ent->classname, "team_CTF_redflag") == 0 )
			if(other->client->sess.sessionTeam == level.pointStatusA)
				return;
		if( strcmp(ent->classname, "team_CTF_blueflag") == 0 )
			if(other->client->sess.sessionTeam == level.pointStatusB)
				return;
	}

	G_LogPrintf( "Item: %i %s\n", other->s.number, ent->item->classname );

	predict = other->client->pers.predictItemPickup;

	// call the item-specific pickup function
	switch( ent->item->giType ) {
	case IT_WEAPON:
		respawn = Pickup_Weapon(ent, other);
//		predict = qfalse;
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo(ent, other);
//		predict = qfalse;
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor(ent, other);
		break;
	case IT_HEALTH:
		respawn = Pickup_Health(ent, other);
		break;
	case IT_POWERUP:
		respawn = Pickup_Powerup(ent, other);
		predict = qfalse;
		break;
	case IT_PERSISTANT_POWERUP:
		respawn = Pickup_PersistantPowerup(ent, other);
		break;
	case IT_TEAM:
		respawn = Pickup_Team(ent, other);
                //If touching a team item remove spawnprotection
                if(other->client->spawnprotected)
                    other->client->spawnprotected = qfalse;
		break;
	case IT_HOLDABLE:
		respawn = Pickup_Holdable(ent, other);
		break;
	default:
		return;
	}

	if ( !respawn ) {
		return;
	}

	// play the normal pickup sound
	if (predict) {
		G_AddPredictableEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	} else {
		G_AddEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	}

	// powerup pickups are global broadcasts
	if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM) {
		// if we want the global sound to play
		if (!ent->speed) {
			gentity_t	*te;

			te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
			te->s.eventParm = ent->s.modelindex;
			te->r.svFlags |= SVF_BROADCAST;
		} else {
			gentity_t	*te;

			te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
			te->s.eventParm = ent->s.modelindex;
			// only send this temp entity to a single client
			te->r.svFlags |= SVF_SINGLECLIENT;
			te->r.singleClient = other->s.number;
		}
	}

	// fire item targets
	G_UseTargets (ent, other);

	// wait of -1 will not respawn
	if ( ent->wait == -1 ) {
		ent->r.svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->r.contents = 0;
		ent->unlinkAfterEvent = qtrue;
		return;
	}

	// non zero wait overrides respawn time
	if ( ent->wait ) {
		respawn = ent->wait;
	}

	// random can be used to vary the respawn time
	if ( ent->random ) {
		respawn += crandom() * ent->random;
		if ( respawn < 1 ) {
			respawn = 1;
		}
	}

	// dropped items will not respawn
	if ( ent->flags & FL_DROPPED_ITEM ) {
		ent->freeAfterEvent = qtrue;
	}

	// picked up items still stay around, they just don't
	// draw anything.  This allows respawnable items
	// to be placed on movers.
	ent->r.svFlags |= SVF_NOCLIENT;
	ent->s.eFlags |= EF_NODRAW;
	ent->r.contents = 0;

	// ZOID
	// A negative respawn times means to never respawn this item (but don't 
	// delete it).  This is used by items that are respawned by third party 
	// events such as ctf flags
	if ( respawn <= 0 ) {
		ent->nextthink = 0;
		ent->think = 0;
	} else {
		ent->nextthink = level.time + respawn * 1000;
		ent->think = RespawnItem;
	}
	trap_LinkEntity( ent );
}
示例#9
0
	virtual void execute( GameEntity *other, trace_t *trace ) 
	{
		int		respawn;
		bool	predict;
		GameEntity*	self = self_;  // Since we may delete our current think()

		if( !other->client_ )
			return;
		if( other->health_ < 1 )
			return;		// dead people can't pickup
		if( other->client_->ps_.pm_type == PM_SPECTATOR )
			return;

		// the same pickup rules are used for client side and server side
		if ( !BG_CanItemBeGrabbed( g_gametype.integer, &self->s, &other->client_->ps_, other->client_->vehicle_ ) ) 
			return;

		G_LogPrintf( "Item: %i %s\n", other->s.number, self->item_->classname );

		predict = other->client_->pers_.predictItemPickup_;

		// call the item-specific pickup function
		switch( self->item_->giType )
		{
		case IT_AMMO:
			respawn = Pickup_Ammo(self, other);
			break;
		case IT_HEALTH:
			respawn = Pickup_Health(self, other);
			break;
		case IT_FUEL:
			respawn = Pickup_Fuel(self, other);
			break;
		case IT_TEAM:
			respawn = Pickup_Team(self, other);
			break;
		default:
			return;
		}

		if ( !respawn ) 
			return;

		// play the normal pickup sound
		if( predict ) 
			G_AddPredictableEvent( other, EV_ITEM_PICKUP, self->s.modelindex );
		else 
			G_AddEvent( other, EV_ITEM_PICKUP, self->s.modelindex, true );

		// powerup pickups are global broadcasts
		if( self->item_->giType == IT_TEAM) 
		{
			// if we want the global sound to play
			if( !self->speed_ ) 
			{
				GameEntity	*te;
				te = G_TempEntity( self->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
				te->s.eventParm = self->s.modelindex;
				te->r.svFlags |= SVF_BROADCAST;
			} 
			else 
			{
				GameEntity	*te;
				te = G_TempEntity( self->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
				te->s.eventParm = self->s.modelindex;
				// only send this temp entity to a single client
				te->r.svFlags |= SVF_SINGLECLIENT;
				te->r.singleClient = other->s.number;
			}
		}

		// fire item targets
		G_UseTargets (self, other);

		// wait of -1 will not respawn
		if( self->wait_ == -1 ) 
		{
			self->r.svFlags |= SVF_NOCLIENT;
			self->s.eFlags |= EF_NODRAW;
			self->r.contents = 0;
			self->unlinkAfterEvent_ = true;
			return;
		}

		// non zero wait overrides respawn time
		if( self->wait_ ) 
			respawn = self->wait_;

		// random can be used to vary the respawn time
		if( self->random_ ) 
		{
			respawn += crandom() * self->random_;
			if ( respawn < 1 ) 
				respawn = 1;
		}

		// dropped items will not respawn
		if( self->flags_ & FL_DROPPED_ITEM ) 
			self->freeAfterEvent_ = true;

		// picked up items still stay around, they just don't
		// draw anything.  This allows respawnable items
		// to be placed on movers.
		self->r.svFlags |= SVF_NOCLIENT;
		self->s.eFlags |= EF_NODRAW;
		self->r.contents = 0;

		// ZOID
		// A negative respawn times means to never respawn this item (but don't 
		// delete it).  This is used by items that are respawned by third party 
		// events such as ctf flags
		if( respawn <= 0 ) 
		{
			self->nextthink_ = 0;
			self->setThink(0);
		} 
		else 
		{
			self->nextthink_ = theLevel.time_ + respawn * 1000;
			self->setThink(new Think_RespawnItem);
		}
		SV_LinkEntity( self );
	}
示例#10
0
/*
===============
Touch_Item

defcon-X: just keep this for bots!
===============
*/
void Pick_Item( gentity_t *ent, gentity_t *other, trace_t *trace ) {
	int respawn;

	if ( !other->client ) {
		return;
	}
	if ( other->health < 1 ) {
		return;     // dead people can't pickup
	}
	if ( !BG_CanItemBeGrabbed( g_gametype.integer, &ent->s, &other->client->ps ) ) {
		return;
	}

	// call the item-specific pickup function
	switch ( ent->item->giType ) {
	case IT_WEAPON:
		respawn = Pickup_Weapon( ent, other );
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo( ent, other );
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor( ent, other );
		break;
	case IT_TEAM:
		respawn = Pickup_Team( ent, other );
		break;
	default:
		return;
	}

	if ( !respawn ) {
		return;
	}

	// play the normal pickup sound
	if ( ( ent->item->giTag != PW_BRIEFCASE_RETURN ) && ( ent->item->giTag != PW_BRIEFCASE ) ) {
		if ( ent->item->giType != IT_BOTROAM ) {
			G_AddEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
		}
	}
	// Navy Seals ++

	// fire item targets
	G_UseTargets( ent, other );

	// wait of -1 will not respawn
	if ( ent->wait == -1 ) {
		ent->r.svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->r.contents = 0;
		ent->unlinkAfterEvent = qtrue;
		return;
	}

	// non zero wait overrides respawn time
	if ( ent->wait ) {
		respawn = ent->wait;
	}

	// random can be used to vary the respawn time
	if ( ent->random ) {
		respawn += crandom() * ent->random;
		if ( respawn < 1 ) {
			respawn = 1;
		}
	}

	// dropped items will not respawn
	if ( ent->flags & FL_DROPPED_ITEM ) {
		ent->freeAfterEvent = qtrue;
	}

	// picked up items still stay around, they just don't
	// draw anything.  This allows respawnable items
	// to be placed on movers.
	ent->r.svFlags |= SVF_NOCLIENT;
	ent->s.eFlags |= EF_NODRAW;
	ent->r.contents = 0;

	// ZOID
	// A negative respawn times means to never respawn this item (but don't
	// delete it).  This is used by items that are respawned by third party
	// events such as ctf flags
	if ( respawn <= 0 ) {
		ent->nextthink = 0;
		ent->think = 0;
	} else {
		ent->nextthink = level.time + respawn * 1000;
		ent->think = RespawnItem;
	}
	trap_LinkEntity( ent );
}
示例#11
0
/*
===============
Touch_Item
===============
*/
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
	int			respawn;

	if (!other->client)
		return;
	if (other->health < 1)
		return;		// dead people can't pickup

    // RPG-X: Marcin: Press USE to pick up items. - 03/12/2008
    if ( !(other->client->pers.cmd.buttons & BUTTON_USE) || other->client->pressedUse == qtrue) {
        return;
	} else {
		other->client->pressedUse = qtrue;
	}

	// If ghosted, then end the ghost-ness in favor of the pickup.
	//RPG-X: RedTechie - Keep ghost all the time
	/*if (other->client->ps.powerups[PW_GHOST] >= level.time)
	{
		other->client->ps.powerups[PW_GHOST] = 0;	// Unghost the player.  This
	}*/

	// the same pickup rules are used for client side and server side
	if ( !BG_CanItemBeGrabbed( &ent->s, &other->client->ps, Max_Weapon(other->client->ps.weapon) )
		&& IsAdmin( other ) == qfalse )
	{
		return;
	}

	numTotalDropped--;

	G_LogPrintf( "Item: %i %s\n", other->s.number, ent->item->classname );

	// call the item-specific pickup function

	switch( ent->item->giType )
	{
	case IT_WEAPON:
		respawn = Pickup_Weapon(ent, other);
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo(ent, other);
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor(ent, other);
		break;
	case IT_HEALTH:
		respawn = Pickup_Health(ent, other);
		break;
	case IT_POWERUP:
		respawn = Pickup_Powerup(ent, other);
		break;
	case IT_TEAM:
		respawn = Pickup_Team(ent, other);
		break;
	case IT_HOLDABLE:
		respawn = Pickup_Holdable(ent, other);
		break;
	default:
		return;
	}

	if ( !respawn) {
		return;
	}

	// play the normal pickup sound
	if ( other->client->pers.predictItemPickup ) {
		G_AddPredictableEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	} else {
		G_AddEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	}

	// powerup pickups are global broadcasts
	if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM) {
		gentity_t	*te;

		te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
		te->s.eventParm = ent->s.modelindex;
		// tell us which client fired off this global sound
		te->s.otherEntityNum = other->s.number;
		te->r.svFlags |= SVF_BROADCAST;
	}

	// fire item targets
	G_UseTargets (ent, other);

    if ( rpg_weaponsStay.integer == 1 && IsAdmin( ent->parent ) == qtrue && IsAdmin( other ) == qfalse ) {
        return;
    }

    if ( ent->item->giTag == WP_3 ) {
        Padd_Remove( ent );
    }
    
    // wait of -1 will not respawn
	if ( ent->wait == -1 ) {
		ent->r.svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->r.contents = 0;
		ent->unlinkAfterEvent = qtrue;
		return;
	}

	// non zero wait overrides respawn time
	if ( ent->wait ) {
		respawn = ent->wait;
	}

	// random can be used to vary the respawn time
	if ( ent->random ) {
		respawn += crandom() * ent->random;
		if ( respawn < 1 ) {
			respawn = 1;
		}
	}

	// dropped items will not respawn
	if ( ent->flags & FL_DROPPED_ITEM ) {
		ent->freeAfterEvent = qtrue;
	}

	// picked up items still stay around, they just don't
	// draw anything.  This allows respawnable items
	// to be placed on movers.

	if (ent->item->giType==IT_WEAPON || ent->item->giType==IT_POWERUP)
	{
		ent->s.eFlags |= EF_ITEMPLACEHOLDER;
	}
	else
	{
//	this line used to prevent items that were picked up from being drawn, but we now want to draw the techy grid thing instead
		ent->s.eFlags |= EF_NODRAW;
		ent->r.svFlags |= SVF_NOCLIENT;
	}

	ent->r.contents = 0;

// ***************
	// ZOID
	// A negative respawn times means to never respawn this item (but don't 
	// delete it).  This is used by items that are respawned by third party 
	// events such as ctf flags
	if ( respawn <= 0 ) {
		ent->nextthink = 0;
		ent->think = 0;
	} else {
        ent->nextthink = level.time + respawn * 1000;
		ent->think = RespawnItem;
	}
	trap_LinkEntity( ent );
}