Example #1
0
void SP_gametype_item ( gentity_t* ent )
{
	gitem_t *item = NULL;
	char *value;
	int team = -1;

	G_SpawnString("teamfilter", "", &value);

	G_SetOrigin( ent, ent->s.origin );

	// If a team filter is set then override any team settings for the spawns
	if ( level.mTeamFilter[0] )
	{
		if ( Q_stricmp ( level.mTeamFilter, "red") == 0 )
		{
			team = TEAM_RED;
		}
		else if ( Q_stricmp ( level.mTeamFilter, "blue") == 0 )
		{
			team = TEAM_BLUE;
		}
	}

	if (ent->targetname && ent->targetname[0])
	{
		if (team != -1)
		{
			if (strstr(ent->targetname, "flag"))
			{
				if (team == TEAM_RED)
				{
					item = BG_FindItem("team_CTF_redflag");
				}
				else
				{ //blue
					item = BG_FindItem("team_CTF_blueflag");
				}
			}
		}
		else if (strstr(ent->targetname, "red_flag"))
		{
			item = BG_FindItem("team_CTF_redflag");
		}
		else if (strstr(ent->targetname, "blue_flag"))
		{
			item = BG_FindItem("team_CTF_blueflag");
		}
		else
		{
			item = NULL;
		}

		if (item)
		{
			ent->targetname = NULL;
			ent->classname = item->classname;
			G_SpawnItem( ent, item );
		}
	}
}
Example #2
0
/*
==============
ClearRegisteredItems
==============
*/
void ClearRegisteredItems( void ) {
	memset( itemRegistered, 0, sizeof( itemRegistered ) );

	// players always start with the base weapon
	RegisterItem( BG_FindItemForWeapon( WP_PISTOL ) );
	RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
	RegisterItem( BG_FindItem("Bag 'O Money" ) );
	RegisterItem( BG_FindItem("Hidden Stash" ) );
}
Example #3
0
/*QUAKED worldspawn(0 0 0) ? sun_cameraflare

Every map should have exactly one worldspawn.
"music"     Music wav file
"gravity"   800 is default gravity
"message" Text to print during connection process
"ambient"  Ambient light value(must use '_color')
"_color"    Ambient light color(must be used with 'ambient')
"sun"        Shader to use for 'sun' image
*/
void SP_worldspawn(void) {
	char *s;
	gitem_t *item; // JPW NERVE

	G_SpawnString("classname", "", &s);

	if (Q_stricmp(s, "worldspawn")) {
		G_Error("SP_worldspawn: The first entity isn't 'worldspawn'");
	}
	// make some data visible to connecting client
	trap_SetConfigstring(CS_GAME_VERSION, GAME_VERSION);

	trap_SetConfigstring(CS_LEVEL_START_TIME, va("%i", level.startTime));

	G_SpawnString("music", "", &s);
	trap_SetConfigstring(CS_MUSIC, s);

	G_SpawnString("message", "", &s);
	trap_SetConfigstring(CS_MESSAGE, s);             // map specific message

	trap_SetConfigstring(CS_MOTD, g_motd.string);    // message of the day

	G_SpawnString("gravity", "800", &s);
	trap_Cvar_Set("g_gravity", s);
	// (SA) FIXME: todo: sun shader set for worldspawn

	g_entities[ENTITYNUM_WORLD].s.number = ENTITYNUM_WORLD;
	g_entities[ENTITYNUM_WORLD].r.ownerNum = ENTITYNUM_NONE;
	g_entities[ENTITYNUM_WORLD].classname = "worldspawn";

	g_entities[ENTITYNUM_NONE].s.number = ENTITYNUM_NONE;
	g_entities[ENTITYNUM_NONE].r.ownerNum = ENTITYNUM_NONE;
	g_entities[ENTITYNUM_NONE].classname = "nothing";
	// see if we want a warmup time
	trap_SetConfigstring(CS_WARMUP, "");

	if (g_restarted.integer) {
		trap_Cvar_Set("g_restarted", "0");
		level.warmupTime = 0;
	}

// JPW NERVE change minigun overheat time for single player -- this array gets reloaded every time the server is reset, 
// so this is as good a place as any to do stuff like this
	if (g_gametype.integer != GT_SINGLE_PLAYER) {
		ammoTable[WP_VENOM].maxHeat *= 0.25;
		ammoTable[WP_DYNAMITE].uses = 0; // regens based on recharge time
		// reset ammo for subs to be distinct for multiplayer(so running out of rifle ammo doesn't deplete sidearm)
		// if player runs out of SMG ammunition, it shouldn't *also * deplete pistol ammunition. If you change this, change
		// g_spawn.c as well
		item = BG_FindItem("Thompson");
		item->giAmmoIndex = WP_THOMPSON;
		item = BG_FindItem("Sten");
		item->giAmmoIndex = WP_STEN;
		item = BG_FindItem("MP40");
		item->giAmmoIndex = WP_MP40;
	}
}
Example #4
0
/*
===========
TossPlayerGametypeItems

Drop CTF flag and Harvester cubes
===========
*/
void TossPlayerGametypeItems(gentity_t *ent) {
	int j;
	gitem_t *item;
	gentity_t *drop;
	int angle = 0;

	// drop flags in CTF
	item = NULL;
	j = 0;

	if ( ent->player->ps.powerups[ PW_REDFLAG ] ) {
		item = BG_FindItemForPowerup( PW_REDFLAG );
		j = PW_REDFLAG;
	} else if ( ent->player->ps.powerups[ PW_BLUEFLAG ] ) {
		item = BG_FindItemForPowerup( PW_BLUEFLAG );
		j = PW_BLUEFLAG;
	} else if ( ent->player->ps.powerups[ PW_NEUTRALFLAG ] ) {
		item = BG_FindItemForPowerup( PW_NEUTRALFLAG );
		j = PW_NEUTRALFLAG;
	}

	if ( item ) {
		drop = Drop_Item( ent, item, angle );
		angle += 45;
		// decide how many seconds it has left
		drop->count = ( ent->player->ps.powerups[ j ] - level.time ) / 1000;
		if ( drop->count < 1 ) {
			drop->count = 1;
		}
		ent->player->ps.powerups[ j ] = 0;
	}

#ifdef MISSIONPACK
	if ( g_gametype.integer == GT_HARVESTER ) {
		if ( ent->player->ps.tokens > 0 ) {
			if ( ent->player->sess.sessionTeam == TEAM_RED ) {
				item = BG_FindItem( "Blue Cube" );
			} else {
				item = BG_FindItem( "Red Cube" );
			}
			if ( item ) {
				for ( j = 0; j < ent->player->ps.tokens; j++ ) {
					drop = Drop_Item( ent, item, angle );
					if ( ent->player->sess.sessionTeam == TEAM_RED ) {
						drop->s.team = TEAM_BLUE;
					} else {
						drop->s.team = TEAM_RED;
					}
					angle += 45;
				}
			}
			ent->player->ps.tokens = 0;
		}
	}
#endif
}
Example #5
0
/*
==================
G_CheckTeamItems
==================
*/
void G_CheckTeamItems(void)
{

	// Set up team stuff
	Team_InitGame();

	if (g_gametype.integer == GT_CTF) {
		gitem_t *item;
		gentity_t *flag, *ent;

		// check for the two flags
		item = BG_FindItem("Silver Case");
		if (!item || !itemRegistered[item - bg_itemlist]) {
			G_Printf(S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map\n");
		}
		item = BG_FindItem("Black Case");
		if (!item || !itemRegistered[item - bg_itemlist]) {
			G_Printf(S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map\n");
		}

		// NiceAss: Find the red flag
		flag = NULL;
		while ((flag = G_Find(flag, FOFS(classname), "team_CTF_redflag")) != NULL) {
			if (!(flag->flags & FL_DROPPED_ITEM))
				break;
		}
		if (flag) {
			// Red team decal X
			ent = G_Spawn();
			ent->classname = "Decal";
			ent->s.eType = ET_DECAL;
			ent->s.pos.trType = TR_STATIONARY;
			ent->s.modelindex = TEAM_RED;
			G_SetOrigin(ent, flag->s.origin);
			trap_LinkEntity(ent);
		}

		// NiceAss: Find the blue flag
		flag = NULL;
		while ((flag = G_Find(flag, FOFS(classname), "team_CTF_blueflag")) != NULL) {
			if (!(flag->flags & FL_DROPPED_ITEM))
				break;
		}
		if (flag) {
			// Red team decal X
			ent = G_Spawn();
			ent->classname = "Decal";
			ent->s.eType = ET_DECAL;
			ent->s.pos.trType = TR_STATIONARY;
			ent->s.modelindex = TEAM_BLUE;
			G_SetOrigin(ent, flag->s.origin);
			trap_LinkEntity(ent);
		}
	}
}
Example #6
0
/*
==============
ClearRegisteredItems
==============
*/
void ClearRegisteredItems( void ) {
	memset( itemRegistered, 0, sizeof( itemRegistered ) );

	// !TODO: Have map determine the base weapons:
	// players always start with the base weapon
	RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) );
	RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
	if( g_gametype.integer == GT_HARVESTER ) {
		RegisterItem( BG_FindItem( "Red Cube" ) );
		RegisterItem( BG_FindItem( "Blue Cube" ) );
	}
}
Example #7
0
/*
==============
ClearRegisteredItems
==============
*/
void ClearRegisteredItems( void ) {
	memset( itemRegistered, 0, sizeof( itemRegistered ) );

	// players always start with the base weapon
	RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) );
	RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
#ifdef MISSIONPACK
	if( g_gametype.integer == GT_HARVESTER ) {
		RegisterItem( BG_FindItem( "Red Cube" ) );
		RegisterItem( BG_FindItem( "Blue Cube" ) );
	}
#endif
}
Example #8
0
void TossClientCubes(gentity_t * self)
{
	gitem_t        *item;
	gentity_t      *drop;
	vec3_t          velocity;
	vec3_t          angles;
	vec3_t          origin;

	self->client->ps.generic1 = 0;

	// this should never happen but we should never
	// get the server to crash due to skull being spawned in
	if(!G_EntitiesFree())
	{
		return;
	}

	if(self->client->sess.sessionTeam == TEAM_RED)
	{
		item = BG_FindItem("Red Cube");
	}
	else
	{
		item = BG_FindItem("Blue Cube");
	}

	angles[YAW] = (float)(level.time % 360);
	angles[PITCH] = 0;			// always forward
	angles[ROLL] = 0;

	AngleVectors(angles, velocity, NULL, NULL);
	VectorScale(velocity, 150, velocity);
	velocity[2] += 200 + crandom() * 50;

	if(neutralObelisk)
	{
		VectorCopy(neutralObelisk->s.pos.trBase, origin);
		origin[2] += 44;
	}
	else
	{
		VectorClear(origin);
	}

	drop = LaunchItem(item, origin, velocity);

	drop->nextthink = level.time + g_cubeTimeout.integer * 1000;
	drop->think = G_FreeEntity;
	drop->spawnflags = self->client->sess.sessionTeam;
}
Example #9
0
/*
==================
G_CheckTeamItems
==================
*/
void G_CheckTeamItems( void ) {
	if ( g_gametype.integer == GT_CTF ) {
		gitem_t *item;

		// make sure we actually have two flags...
		item = BG_FindItem( "Red Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Error( "No team_CTF_redflag in map" );
		}
		item = BG_FindItem( "Blue Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Error( "No team_CTF_blueflag in map" );
		}
	}
}
Example #10
0
void DropPortalDestination( gentity_t *player ) {
	gentity_t	*ent;
	vec3_t		snapped;

	// create the portal destination
	ent = G_Spawn();
	ent->s.modelindex = G_ModelIndex( "models/powerups/teleporter/tele_exit.md3" );

	VectorCopy( player->s.pos.trBase, snapped );
	SnapVector( snapped );
	G_SetOrigin( ent, snapped );
	VectorCopy( player->r.mins, ent->r.mins );
	VectorCopy( player->r.maxs, ent->r.maxs );

	ent->classname = "hi_portal destination";
	ent->s.pos.trType = TR_STATIONARY;

	ent->r.contents = CONTENTS_CORPSE;
	ent->takedamage = qtrue;
	ent->health = 200;
	ent->die = PortalDie;

	VectorCopy( player->s.apos.trBase, ent->s.angles );

	ent->think = G_FreeEntity;
	ent->nextthink = level.time + 2 * 60 * 1000;

	trap_LinkEntity( ent );

	player->client->portalID = ++level.portalSequence;
	ent->count = player->client->portalID;

	// give the item back so they can drop the source now
	player->client->ps.stats[STAT_HOLDABLE_ITEM] = BG_FindItem( "Portal" ) - bg_itemlist;
}
Example #11
0
Gametype_inf::Gametype_inf() {
	// Register the items
	// Boe!Man 11/29/12: Register items per gametype.
	gitem_t *item = BG_FindItem("briefcase");
	if (item){
		item->quantity = ITEM_BRIEFCASE;
	}
	// Boe!Man 11/29/12: Register triggers per gametype.
	gentity_t *find = NULL;
	while (NULL != (find = G_Find(find, FOFS(classname), "gametype_trigger")))
	{
		if (strcmp(find->targetname, (const char*) "briefcase_destination"))
		{
			continue;
		}

		// Assign the id to it.
		find->health = TRIGGER_EXTRACTION;
		find->touch = gametype_trigger_touch;
		trap_LinkEntity(find);
	}

	caseTakenSound = G_SoundIndex("sound/ctf_flag.mp3");
	caseCaptureSound = G_SoundIndex("sound/ctf_win.mp3");
	caseReturnSound = G_SoundIndex("sound/ctf_return.mp3");
}
Example #12
0
/*
==============
ClearRegisteredItems
==============
*/
void ClearRegisteredItems() 
{
#pragma message("this should probably be removed!")
	memset( itemRegistered, 0, sizeof( itemRegistered ) );
	// Always load health/ammo/fuel pickups
	RegisterItem( BG_FindItem( "5 Health" ) );
	RegisterItem( BG_FindItem( "25 Health" ) );
	RegisterItem( BG_FindItem( "50 Health" ) );
	RegisterItem( BG_FindItem( "Some Fuel" ) );
	RegisterItem( BG_FindItem( "More Fuel" ) );
	RegisterItem( BG_FindItem( "Shells" ) );
	RegisterItem( BG_FindItem( "Bullets" ) );
	RegisterItem( BG_FindItem( "Slugs" ) );
	RegisterItem( BG_FindItem( "Rockets" ) );
}
/*
==================
G_CheckTeamItems
==================
*/
void G_CheckTeamItems( void ) {

	// Set up team stuff
	Team_InitGame();

	if( g_gametype.integer == GT_CTF ) {
		gitem_t	*item;

		// check for the two flags
		item = BG_FindItem( "red Lolly" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_CTL_redlolly in map" );
		}
		item = BG_FindItem( "blue Lolly" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_CTL_bluelolly in map" );
		}
	}
}
Example #14
0
/*
==================
G_CheckTeamItems
==================
*/
void G_CheckTeamItems( void ) {

	// Set up team stuff
	Team_InitGame();

	if ( g_gametype.integer == GT_CTF ) {
		gitem_t	*item;

		// make sure we actually have two flags...
		item = BG_FindItem( "team_CTF_redflag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( "^1WARNING: No team_CTF_redflag in map" );
		}
		item = BG_FindItem( "team_CTF_blueflag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( "^1WARNING: No team_CTF_blueflag in map" );
		}
	}
}
Example #15
0
/*
===============
G_ParseGametypeItems
===============
*/
bool G_ParseGametypeItems ( TGPGroup* itemsGroup )
{
	TGPGroup	itemGroup;
	int			itemCount;
	char		temp[MAX_QPATH];
	gentity_t	*ent;

	// Handle NULL for convienience
	if ( !itemsGroup )
	{
		return false;
	}

	// Loop over all the items and add each 
	itemGroup = trap_GPG_GetSubGroups ( itemsGroup );
	itemCount = 0;

	while ( itemGroup )
	{	
		gitem_t*   item;
		
		// Parse out the pickup name
		trap_GPG_GetName ( itemGroup, temp );

		item = BG_FindItem ( temp );
		if ( !item )
		{
			item = &bg_itemlist[ MODELINDEX_GAMETYPE_ITEM + itemCount ];
			item->pickup_name = (char *)trap_VM_LocalStringAlloc ( temp );
			itemCount++;
		}

		// Handle the entity specific stuff by finding all matching items that 
		// were spawned.
		ent = NULL;
		while ( NULL != (ent = G_Find ( ent, FOFS(targetname), item->pickup_name ) ) )
		{
			// If not a gametype item then skip it
			if ( strcmp ( ent->classname, "gametype_item" ) )
			{
				continue;
			}

			// Setup the gametype data
			ent->item	   = item;
			ent->nextthink = level.time + 200;
			ent->think     = G_GametypeItemThink;
		}

		// Next sub group
		itemGroup = trap_GPG_GetNext(itemGroup);
	}

	return true;
}
Example #16
0
/*
==============
ClearRegisteredItems
==============
*/
void ClearRegisteredItems( void ) {
	memset( itemRegistered, 0, sizeof( itemRegistered ) );

	// players always start with the base weapon
	// (SA) Nope, not any more...

//----(SA)	this will be determined by the level or starting position, or the savegame
//			but for now, re-register the MP40 automatically
//	RegisterItem( BG_FindItemForWeapon( WP_MP40 ) );
	RegisterItem( BG_FindItem( "Med Health" ) );           // NERVE - SMF - this is so med packs properly display
}
Example #17
0
/*
==================
G_CheckTeamItems
==================
*/
void G_CheckTeamItems() 
{

	// Set up team stuff
	Team_InitGame();

	if( g_gametype.integer == GT_CTF ) {
		gitem_t	*item;

		// check for the two flags
		item = BG_FindItem( "Red Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			Com_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" );
		}
		item = BG_FindItem( "Blue Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			Com_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" );
		}
	}
}
Example #18
0
void ammo_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {
	int i, clientcount = 0, count;
	gentity_t* touchClients[MAX_CLIENTS];

	memset(touchClients, 0, sizeof(touchClients));

	if( other->client == NULL ) {
		return;
	}

	// flags is for the last entity number that got ammo
	if ( self->timestamp > level.time ) {
		return;
	}
	self->timestamp = level.time + 1000;

	for( i = 0; i < level.numConnectedClients; i++ ) {
		int j = level.sortedClients[i];

		if( trap_EntityContactCapsule( g_entities[j].r.absmin, g_entities[j].r.absmax, self ) && G_IsAllowedAmmo( &g_entities[j] ) ) {
			touchClients[clientcount] = &g_entities[j];
			clientcount++;
		}
	}
	
	if(clientcount == 0) {
		return;
	}

	// Gordon: if low, just give out what's left
	if(self->health == -9999) {
		count = clientcount;
	} else {
		count = min(clientcount, self->health / (float)self->damage );
	}

	for( i = 0; i < count; i++) {
		int ammoAdded = qfalse;

		// self->damage contains the amount of ammo to add
		ammoAdded = AddMagicAmmo(touchClients[i], self->damage);

		if (ammoAdded) {
			// add the ammo pack event (to get sound, etc.)
			G_AddPredictableEvent( touchClients[i], EV_ITEM_PICKUP, BG_FindItem("Ammo Pack")-bg_itemlist );
			if (self->health != -9999) {
				// reduce the ammount of available ammo by the added clip number
				self->health -= self->damage;
//				G_Printf("%i clips left\n", self->health );
			}
		}
	}
}
Example #19
0
File: g_items.c Project: Razish/QtZ
void G_CheckTeamItems( void ) {

	// Set up team stuff
	Team_InitGame();

	if( level.gametype == GT_FLAGS ) {
		const gitem_t	*item;

		// check for the two flags
		item = BG_FindItem( "team_redflag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			trap->Print( S_COLOR_YELLOW "WARNING: No team_redflag in map\n" );
		}
		item = BG_FindItem( "team_blueflag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			trap->Print( S_COLOR_YELLOW "WARNING: No team_blueflag in map\n" );
		}
	}
	if( level.gametype == GT_TROJAN ) {
		const gitem_t	*item;

		// check for all three flags
		item = BG_FindItem( "team_redflag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			trap->Print( S_COLOR_YELLOW "WARNING: No team_redflag in map\n" );
		}
		item = BG_FindItem( "team_blueflag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			trap->Print( S_COLOR_YELLOW "WARNING: No team_blueflag in map\n" );
		}
		item = BG_FindItem( "team_neutralflag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			trap->Print( S_COLOR_YELLOW "WARNING: No team_neutralflag in map\n" );
		}
	}
}
Example #20
0
/*
==================
Cmd_Give_f

Give items to a client
==================
*/
void Cmd_Give_f (gentity_t *ent)
{
	char		*name;
	gitem_t		*it;
	int			i;
	qboolean	give_all;
	gentity_t		*it_ent;
	trace_t		trace;

	if ( !CheatsOk( ent ) ) {
		return;
	}

	name = ConcatArgs( 1 );

	if (Q_stricmp(name, "all") == 0)
		give_all = qtrue;
	else
		give_all = qfalse;

	if (give_all || Q_stricmp( name, "health") == 0)
	{
		ent->health = ent->client->ps.stats[STAT_MAX_HEALTH];
		if (!give_all)
			return;
	}

	if (give_all || Q_stricmp(name, "weapons") == 0)
	{
		ent->client->ps.stats[STAT_WEAPONS] = (1 << WP_NUM_WEAPONS) - 1 - 
			( 1 << WP_GRAPPLING_HOOK ) - ( 1 << WP_NONE );
		if (!give_all)
			return;
	}

	if (give_all || Q_stricmp(name, "ammo") == 0)
	{
		for ( i = 0 ; i < MAX_WEAPONS ; i++ ) {
			ent->client->ps.ammo[i] = 999;
		}
		if (!give_all)
			return;
	}

	if (give_all || Q_stricmp(name, "armor") == 0)
	{
		ent->client->ps.stats[STAT_ARMOR] = 200;

		if (!give_all)
			return;
	}

	if (Q_stricmp(name, "excellent") == 0) {
		ent->client->ps.persistant[PERS_EXCELLENT_COUNT]++;
		return;
	}
	if (Q_stricmp(name, "impressive") == 0) {
		ent->client->ps.persistant[PERS_IMPRESSIVE_COUNT]++;
		return;
	}
	if (Q_stricmp(name, "gauntletaward") == 0) {
		ent->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT]++;
		return;
	}
	if (Q_stricmp(name, "defend") == 0) {
		ent->client->ps.persistant[PERS_DEFEND_COUNT]++;
		return;
	}
	if (Q_stricmp(name, "assist") == 0) {
		ent->client->ps.persistant[PERS_ASSIST_COUNT]++;
		return;
	}

	// spawn a specific item right on the player
	if ( !give_all ) {
		it = BG_FindItem (name);
		if (!it) {
			return;
		}

		it_ent = G_Spawn();
		VectorCopy( ent->r.currentOrigin, it_ent->s.origin );
		it_ent->classname = it->classname;
		G_SpawnItem (it_ent, it);
		FinishSpawningItem(it_ent );
		memset( &trace, 0, sizeof( trace ) );
		Touch_Item (it_ent, ent, &trace);
		if (it_ent->inuse) {
			G_FreeEntity( it_ent );
		}
	}
}
Example #21
0
/*
==================
G_CheckTeamItems
==================
*/
void G_CheckTeamItems( void ) {

	// Set up team stuff
	Team_InitGame();

	if( g_gametype.integer == GT_CTF ) {
		gitem_t	*item;

		// check for the two flags
		item = BG_FindItem( "Red Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" );
		}
		item = BG_FindItem( "Blue Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" );
		}
	}
#ifdef MISSIONPACK
	if( g_gametype.integer == GT_1FCTF ) {
		gitem_t	*item;

		// check for all three flags
		item = BG_FindItem( "Red Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" );
		}
		item = BG_FindItem( "Blue Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" );
		}
		item = BG_FindItem( "Neutral Flag" );
		if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_neutralflag in map" );
		}
	}

	if( g_gametype.integer == GT_OBELISK ) {
		gentity_t	*ent;

		// check for the two obelisks
		ent = NULL;
		ent = G_Find( ent, FOFS(classname), "team_redobelisk" );
		if( !ent ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map" );
		}

		ent = NULL;
		ent = G_Find( ent, FOFS(classname), "team_blueobelisk" );
		if( !ent ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map" );
		}
	}

	if( g_gametype.integer == GT_HARVESTER ) {
		gentity_t	*ent;

		// check for all three obelisks
		ent = NULL;
		ent = G_Find( ent, FOFS(classname), "team_redobelisk" );
		if( !ent ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_redobelisk in map" );
		}

		ent = NULL;
		ent = G_Find( ent, FOFS(classname), "team_blueobelisk" );
		if( !ent ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_blueobelisk in map" );
		}

		ent = NULL;
		ent = G_Find( ent, FOFS(classname), "team_neutralobelisk" );
		if( !ent ) {
			G_Printf( S_COLOR_YELLOW "WARNING: No team_neutralobelisk in map" );
		}
	}
#endif
}
Example #22
0
/*
===========
ClientDisconnect

Called when a player drops from the server.
Will not be called between levels.

This should NOT be called directly by any game logic,
call trap_DropClient(), which will call this and do
server system housekeeping.
============
*/
void ClientDisconnect(int clientNum) {
	gentity_t *ent;
	gentity_t *flag = NULL;
	gitem_t   *item = NULL;
	vec3_t    launchvel;
	int       i;

	ent = g_entities + clientNum;
	if (!ent->client) {
		return;
	}

	G_RemoveClientFromFireteams(clientNum, qtrue, qfalse);
	G_RemoveFromAllIgnoreLists(clientNum);
	G_LeaveTank(ent, qfalse);

	// Nico, remove the client from all specInvited lists
	for (i = 0; i < level.numConnectedClients; ++i) {
		COM_BitClear(level.clients[level.sortedClients[i]].sess.specInvitedClients, clientNum);
	}

	// stop any following clients
	for (i = 0 ; i < level.numConnectedClients ; i++) {
		flag = g_entities + level.sortedClients[i];
		if (flag->client->sess.sessionTeam == TEAM_SPECTATOR
		    && flag->client->sess.spectatorState == SPECTATOR_FOLLOW
		    && flag->client->sess.spectatorClient == clientNum) {
			StopFollowing(flag);
		}
		if (flag->client->ps.pm_flags & PMF_LIMBO
		    && flag->client->sess.spectatorClient == clientNum) {
			Cmd_FollowCycle_f(flag, 1);
		}
	}

	G_FadeItems(ent, MOD_SATCHEL);

	// remove ourself from teamlists
	{
		mapEntityData_t      *mEnt;
		mapEntityData_Team_t *teamList;

		for (i = 0; i < 2; i++) {
			teamList = &mapEntityData[i];

			if ((mEnt = G_FindMapEntityData(&mapEntityData[0], ent - g_entities)) != NULL) {
				G_FreeMapEntityData(teamList, mEnt);
			}

			mEnt = G_FindMapEntityDataSingleClient(teamList, NULL, ent->s.number, -1);

			while (mEnt) {
				mapEntityData_t *mEntFree = mEnt;

				mEnt = G_FindMapEntityDataSingleClient(teamList, mEnt, ent->s.number, -1);

				G_FreeMapEntityData(teamList, mEntFree);
			}
		}
	}

	// send effect if they were completely connected
	if (ent->client->pers.connected == CON_CONNECTED
	    && ent->client->sess.sessionTeam != TEAM_SPECTATOR
	    && !(ent->client->ps.pm_flags & PMF_LIMBO)) {

		// They don't get to take powerups with them!
		// Especially important for stuff like CTF flags
		// New code for tossing flags
		if (ent->client->ps.powerups[PW_REDFLAG]) {
			item = BG_FindItem("Red Flag");
			if (!item) {
				item = BG_FindItem("Objective");
			}

			ent->client->ps.powerups[PW_REDFLAG] = 0;
		}
		if (ent->client->ps.powerups[PW_BLUEFLAG]) {
			item = BG_FindItem("Blue Flag");
			if (!item) {
				item = BG_FindItem("Objective");
			}

			ent->client->ps.powerups[PW_BLUEFLAG] = 0;
		}

		if (item) {
			// OSP - fix for suicide drop exploit through walls/gates
			launchvel[0] = 0;    //crandom()*20;
			launchvel[1] = 0;    //crandom()*20;
			launchvel[2] = 0;    //10+random()*10;

			flag                = LaunchItem(item, ent->r.currentOrigin, launchvel, ent - g_entities);
			flag->s.modelindex2 = ent->s.otherEntityNum2;    // JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here
			flag->message       = ent->message; // DHM - Nerve :: also restore item name
			// Clear out player's temp copies
			ent->s.otherEntityNum2 = 0;
			ent->message           = NULL;
		}
	}

	G_LogPrintf("ClientDisconnect: %i\n", clientNum);

	trap_UnlinkEntity(ent);
	ent->s.modelindex                     = 0;
	ent->inuse                            = qfalse;
	ent->classname                        = "disconnected";
	ent->client->pers.connected           = CON_DISCONNECTED;
	ent->client->ps.persistant[PERS_TEAM] = TEAM_FREE;
	i                                     = ent->client->sess.sessionTeam;
	ent->client->sess.sessionTeam         = TEAM_FREE;
	ent->active                           = 0;

	trap_SetConfigstring(CS_PLAYERS + clientNum, "");

	CalculateRanks();
}
Example #23
0
/*
============
G_SpawnItem

Sets the clipping size and plants the object on the floor.

Items can't be immediately dropped to floor, because they might
be on an entity that hasn't spawned yet.
============
*/
void G_SpawnItem(gentity_t *ent, gitem_t *item)
{
	char *MinHealth = "1";
	qboolean Egg = qfalse;

	G_SpawnFloat("random", "0", &ent->random);
	G_SpawnFloat("wait", "0", &ent->wait);

	if (item->giType == IT_TEAM)
	{
		if (g_gametype.integer == GT_INVASION || g_gametype.integer == GT_DESTROY)
		{
			if (!Q_stricmp(item->pickup_name, "Blue Flag"))
			{
				gitem_t *NewItem = BG_FindItem("Alien Egg");

				if (NewItem)
				{
					item = NewItem;
					MinHealth = "60";//2500;
					Egg = qtrue;
				}
				ent->classname = item->classname;
			}
			else if (!Q_stricmp(item->pickup_name, "Red Flag"))
			{
				gitem_t *NewItem = BG_FindItem("Teleporter");

				if (NewItem)
					item = NewItem;
				ent->classname = item->classname;
			}
			else if (!Q_stricmp(item->pickup_name, "Alien Egg"))
				Egg = qtrue;
		}

		RegisterItem(item);
	}

	if (G_ItemDisabled(item))
		return;

	if (Egg && g_gametype.integer == GT_DESTROY)
	{
		float Coeff, Radius;

		G_SpawnFloat("health", MinHealth, &Coeff);

		if (Coeff < 0.1f)
			Coeff = 0.1f;

		ent->health = Coeff * g_InvEggHealth.integer;

		if (ent->health < 1)//MinHealth)
			ent->health = 1;//MinHealth;
		else if (ent->health > 25000)
			ent->health = 25000;

		G_SpawnFloat("Radius", "6", &Radius);
		G_SpawnFloat("Height", "24", &Coeff);

		Radius = Com_Clamp(3, 50, Radius);
		Coeff = Com_Clamp(3, 200, Coeff);

		VectorSet(ent->r.mins, -Radius, -Radius, 0);
		VectorSet(ent->r.maxs, Radius, Radius, Coeff);

		G_SpawnInt("Number", "100", &ent->count);
		if (ent->count < 0)
			ent->count = 0;
	}

	ent->item = item;
	// some movers spawn on the second frame, so delay item
	// spawns until the third frame so they can ride trains
	ent->nextthink = level.time + FRAMETIME * 2;
	ent->think = FinishSpawningItem;

	ent->physicsBounce = 0.50;		// items are bouncy

	if (item->giType == IT_POWERUP)
	{
		G_SoundIndex("sound/items/poweruprespawn.wav");
		G_SpawnFloat("noglobalsound", "0", &ent->speed);
	}

#ifdef MISSIONPACK
	if (item->giType == IT_PERSISTANT_POWERUP)
	{
		ent->s.generic1 = ent->spawnflags;
	}
#endif
}
Example #24
0
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	int			contents = 0, i, killer = ENTITYNUM_WORLD;
	char		*killerName = "<world>";
	qboolean	nogib = qtrue;
	gitem_t		*item = NULL;
	gentity_t	*ent;
	qboolean	killedintank = qfalse;

	//float			timeLived;
	weapon_t	weap = BG_WeaponForMOD( meansOfDeath );

//	G_Printf( "player_die\n" );

	if(attacker == self) {
		if(self->client) {
			self->client->pers.playerStats.suicides++;
			trap_PbStat ( self - g_entities , "suicide" , 
				va ( "%d %d %d" , self->client->sess.sessionTeam , self->client->sess.playerType , weap ) ) ;
		}
	} else if(OnSameTeam( self, attacker )) {
		G_LogTeamKill(	attacker,	weap );
	} else {
		G_LogDeath( self,		weap );
		G_LogKill(	attacker,	weap );

		if( g_gamestate.integer == GS_PLAYING ) {
			if( attacker->client ) {
				attacker->client->combatState |= (1<<COMBATSTATE_KILLEDPLAYER);
			}
		}
	}

	// RF, record this death in AAS system so that bots avoid areas which have high death rates
	if( !OnSameTeam( self, attacker ) )
	{
// LC - not needed
//		BotRecordTeamDeath( self->s.number );

		self->isProp = qfalse;	// were we teamkilled or not?
	} else {
		self->isProp = qtrue;
	}	

	// if we got killed by a landmine, update our map
	if( self->client && meansOfDeath == MOD_LANDMINE ) {
		// if it's an enemy mine, update both teamlists
		/*int teamNum;
		mapEntityData_t	*mEnt;
		mapEntityData_Team_t *teamList;
	
		teamNum = inflictor->s.teamNum % 4;

		teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[0] : &mapEntityData[1];
		if((mEnt = G_FindMapEntityData(teamList, inflictor-g_entities)) != NULL) {
			G_FreeMapEntityData( teamList, mEnt );
		}

		if( teamNum != self->client->sess.sessionTeam ) {
			teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[1] : &mapEntityData[0];
			if((mEnt = G_FindMapEntityData(teamList, inflictor-g_entities)) != NULL) {
				G_FreeMapEntityData( teamList, mEnt );
			}
		}*/
		mapEntityData_t	*mEnt;

		if((mEnt = G_FindMapEntityData(&mapEntityData[0], inflictor-g_entities)) != NULL) {
			G_FreeMapEntityData( &mapEntityData[0], mEnt );
		}

		if((mEnt = G_FindMapEntityData(&mapEntityData[1], inflictor-g_entities)) != NULL) {
			G_FreeMapEntityData( &mapEntityData[1], mEnt );
		}
	}

	{
		mapEntityData_t	*mEnt;
		mapEntityData_Team_t *teamList = self->client->sess.sessionTeam == TEAM_AXIS ? &mapEntityData[1] : &mapEntityData[0];	// swapped, cause enemy team

		mEnt = G_FindMapEntityDataSingleClient( teamList, NULL, self->s.number, -1 );
		
		while( mEnt ) {
			if( mEnt->type == ME_PLAYER_DISGUISED ) {
				mapEntityData_t* mEntFree = mEnt;

				mEnt = G_FindMapEntityDataSingleClient( teamList, mEnt, self->s.number, -1 );

				G_FreeMapEntityData( teamList, mEntFree );
			} else {
				mEnt = G_FindMapEntityDataSingleClient( teamList, mEnt, self->s.number, -1 );
			}
		}
	}

	if( self->tankLink ) {
		G_LeaveTank( self, qfalse );

		killedintank = qtrue;
	}

	if( self->client->ps.pm_type == PM_DEAD || g_gamestate.integer == GS_INTERMISSION ) {
		return;
	}

	// OSP - death stats handled out-of-band of G_Damage for external calls
	G_addStats(self, attacker, damage, meansOfDeath);
	// OSP

	self->client->ps.pm_type = PM_DEAD;

	G_AddEvent( self, EV_STOPSTREAMINGSOUND, 0);

	if(attacker) {
		killer = attacker->s.number;
		killerName = (attacker->client) ? attacker->client->pers.netname : "<non-client>";
	}

	if(attacker == 0 || killer < 0 || killer >= MAX_CLIENTS) {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if(g_gamestate.integer == GS_PLAYING) {
		char *obit;

		if(meansOfDeath < 0 || meansOfDeath >= sizeof(modNames) / sizeof(modNames[0])) {
			obit = "<bad obituary>";
		} else {
			obit = modNames[meansOfDeath];
		}

		G_LogPrintf("Kill: %i %i %i: %s killed %s by %s\n", killer, self->s.number, meansOfDeath, killerName, self->client->pers.netname, obit );
	}


	// broadcast the death event to everyone
	ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
	ent->s.eventParm = meansOfDeath;
	ent->s.otherEntityNum = self->s.number;
	ent->s.otherEntityNum2 = killer;
	ent->r.svFlags = SVF_BROADCAST;	// send to everyone

	self->enemy = attacker;

	self->client->ps.persistant[PERS_KILLED]++;

	// JPW NERVE -- if player is holding ticking grenade, drop it
	if ((self->client->ps.grenadeTimeLeft) && (self->s.weapon != WP_DYNAMITE) && (self->s.weapon != WP_LANDMINE) && (self->s.weapon != WP_SATCHEL) && (self->s.weapon != WP_TRIPMINE)) {
		vec3_t launchvel, launchspot;

		launchvel[0] = crandom();
		launchvel[1] = crandom();
		launchvel[2] = random();
		VectorScale( launchvel, 160, launchvel );
		VectorCopy(self->r.currentOrigin, launchspot);
		launchspot[2] += 40;
		
		{
			// Gordon: fixes premature grenade explosion, ta bani ;)
			gentity_t *m = fire_grenade(self, launchspot, launchvel, self->s.weapon);
			m->damage = 0;
		}
	}

	if (attacker && attacker->client) {
		if ( attacker == self || OnSameTeam (self, attacker ) ) {

			// DHM - Nerve :: Complaint lodging
			if( attacker != self && level.warmupTime <= 0 && g_gamestate.integer == GS_PLAYING) {
				if( attacker->client->pers.localClient ) {
					trap_SendServerCommand( self-g_entities, "complaint -4" );
				} else {
					if( meansOfDeath != MOD_CRUSH_CONSTRUCTION && meansOfDeath != MOD_CRUSH_CONSTRUCTIONDEATH && meansOfDeath != MOD_CRUSH_CONSTRUCTIONDEATH_NOATTACKER ) {
						if( g_complaintlimit.integer ) {

							if( !(meansOfDeath == MOD_LANDMINE && g_disableComplaints.integer & TKFL_MINES ) &&
								!((meansOfDeath == MOD_ARTY || meansOfDeath == MOD_AIRSTRIKE) && g_disableComplaints.integer & TKFL_AIRSTRIKE ) &&
								!(meansOfDeath == MOD_MORTAR && g_disableComplaints.integer & TKFL_MORTAR ) ) {
								trap_SendServerCommand( self-g_entities, va( "complaint %i", attacker->s.number ) );
								self->client->pers.complaintClient = attacker->s.clientNum;
								self->client->pers.complaintEndTime = level.time + 20500;
							}
						}
					}
				}
			}

			// high penalty to offset medic heal
/*			AddScore( attacker, WOLF_FRIENDLY_PENALTY ); */

			if( g_gametype.integer == GT_WOLF_LMS ) {
				AddKillScore( attacker, WOLF_FRIENDLY_PENALTY );
			}
		} else {

			//G_AddExperience( attacker, 1 );

			// JPW NERVE -- mostly added as conveneience so we can tweak from the #defines all in one place
			AddScore(attacker, WOLF_FRAG_BONUS);

			if( g_gametype.integer == GT_WOLF_LMS ) {
				if( level.firstbloodTeam == -1 )
					level.firstbloodTeam = attacker->client->sess.sessionTeam;

				AddKillScore( attacker, WOLF_FRAG_BONUS );
			}

			attacker->client->lastKillTime = level.time;
		}
	} else {
		AddScore( self, -1 );

		if( g_gametype.integer == GT_WOLF_LMS )
			AddKillScore( self, -1 );
	}

	// Add team bonuses
	Team_FragBonuses(self, inflictor, attacker);

	// drop flag regardless
	if (self->client->ps.powerups[PW_REDFLAG]) {
		item = BG_FindItem("Red Flag");
		if (!item)
			item = BG_FindItem("Objective");

		self->client->ps.powerups[PW_REDFLAG] = 0;
	}
	if (self->client->ps.powerups[PW_BLUEFLAG]) {
		item = BG_FindItem("Blue Flag");
		if (!item)
			item = BG_FindItem("Objective");

		self->client->ps.powerups[PW_BLUEFLAG] = 0;
	}

	if (item) {
		vec3_t launchvel = { 0, 0, 0 };
		gentity_t *flag = LaunchItem(item, self->r.currentOrigin, launchvel, self->s.number);

		flag->s.modelindex2 = self->s.otherEntityNum2;// JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here
		flag->message = self->message;	// DHM - Nerve :: also restore item name
		// Clear out player's temp copies
		self->s.otherEntityNum2 = 0;
		self->message = NULL;
	}

	// send a fancy "MEDIC!" scream.  Sissies, ain' they?
	if (self->client != NULL) {
		if( self->health > GIB_HEALTH && meansOfDeath != MOD_SUICIDE && meansOfDeath != MOD_SWITCHTEAM ) {
			G_AddEvent( self, EV_MEDIC_CALL, 0 );
		}
	}

	Cmd_Score_f( self );		// show scores

	// send updated scores to any clients that are following this one,
	// or they would get stale scoreboards
	for(i=0; i<level.numConnectedClients; i++) {
		gclient_t *client = &level.clients[level.sortedClients[i]];

		if(client->pers.connected != CON_CONNECTED) continue;
		if(client->sess.sessionTeam != TEAM_SPECTATOR) continue;

		if(client->sess.spectatorClient == self->s.number) {
			Cmd_Score_f(g_entities + level.sortedClients[i]);
		}
	}

	self->takedamage = qtrue;	// can still be gibbed
	self->r.contents = CONTENTS_CORPSE;

	//self->s.angles[2] = 0;
	self->s.powerups = 0;
	self->s.loopSound = 0;
	
	self->client->limboDropWeapon = self->s.weapon; // store this so it can be dropped in limbo

	LookAtKiller( self, inflictor, attacker );
	self->client->ps.viewangles[0] = 0;
	self->client->ps.viewangles[2] = 0;
	//VectorCopy( self->s.angles, self->client->ps.viewangles );

//	trap_UnlinkEntity( self );
	self->r.maxs[2] = self->client->ps.crouchMaxZ;	//%	0;			// ydnar: so bodies don't clip into world
	self->client->ps.maxs[2] = self->client->ps.crouchMaxZ;	//%	0;	// ydnar: so bodies don't clip into world
	trap_LinkEntity( self );

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	self->client->respawnTime = level.timeCurrent + 800;

	// remove powerups
	memset( self->client->ps.powerups, 0, sizeof(self->client->ps.powerups) );

	// never gib in a nodrop
	// FIXME: contents is always 0 here
	if ( self->health <= GIB_HEALTH && !(contents & CONTENTS_NODROP) ) {
		GibEntity( self, killer );
		nogib = qfalse;
	}

	if(nogib){
		// normal death
		// for the no-blood option, we need to prevent the health
		// from going to gib level
		if ( self->health <= GIB_HEALTH ) {
			self->health = GIB_HEALTH + 1;
		}

		// Arnout: re-enable this for flailing
/*		if( self->client->ps.groundEntityNum == ENTITYNUM_NONE ) {
			self->client->ps.pm_flags |= PMF_FLAILING;
			self->client->ps.pm_time = 750;
			BG_AnimScriptAnimation( &self->client->ps, ANIM_MT_FLAILING, qtrue );

			// Face explosion directory
			{
				vec3_t angles;

				vectoangles( self->client->ps.velocity, angles );
				self->client->ps.viewangles[YAW] = angles[YAW];
				SetClientViewAngle( self, self->client->ps.viewangles );
			}
		} else*/

			// DHM - Play death animation, and set pm_time to delay 'fallen' animation
			//if( G_IsSinglePlayerGame() && self->client->sess.sessionTeam == TEAM_ALLIES ) {
			//	// play "falldown" animation since allies bots won't ever die completely
			//	self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, self->client->pers.character->animModelInfo, ANIM_ET_FALLDOWN, qfalse, qtrue );
			//	G_StartPlayerAppropriateSound(self, "death");
			//} else {
				self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, self->client->pers.character->animModelInfo, ANIM_ET_DEATH, qfalse, qtrue );
				// death animation script already contains sound
			//}

			// record the death animation to be used later on by the corpse
			self->client->torsoDeathAnim = self->client->ps.torsoAnim;
			self->client->legsDeathAnim = self->client->ps.legsAnim;

			G_AddEvent( self, EV_DEATH1 + 1, killer );

		// the body can still be gibbed
		self->die = body_die;
	}

	if( meansOfDeath == MOD_MACHINEGUN ) {
		switch( self->client->sess.sessionTeam ) {
			case TEAM_AXIS:
				level.axisMG42Counter = level.time;
				break;
			case TEAM_ALLIES:
				level.alliesMG42Counter = level.time;
				break;
		}
	}

	G_FadeItems( self, MOD_SATCHEL );

	CalculateRanks();

	if( killedintank /*Gordon: automatically go to limbo from tank*/ ) {
		limbo( self, qfalse ); // but no corpse
	} else if ( (meansOfDeath == MOD_SUICIDE && g_gamestate.integer == GS_PLAYING) ) {
		limbo( self, qtrue );
	} else if( g_gametype.integer == GT_WOLF_LMS ) {
		if( !G_CountTeamMedics( self->client->sess.sessionTeam, qtrue ) ) {
			limbo( self, qtrue );
		}
	}
}
Example #25
0
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	gentity_t   *ent;
	// TTimo might be used uninitialized
	int contents = 0;
	int killer;
	int i;
	const char        *killerName, *obit;
	qboolean nogib = qtrue;
	gitem_t     *item = NULL; // JPW NERVE for flag drop
	vec3_t launchvel,launchspot;      // JPW NERVE
	gentity_t   *flag; // JPW NERVE

	if ( self->client->ps.pm_type == PM_DEAD ) {
		return;
	}

	if ( level.intermissiontime ) {
		return;
	}

	self->client->ps.pm_type = PM_DEAD;

	G_AddEvent( self, EV_STOPSTREAMINGSOUND, 0 );

	if ( attacker ) {
		killer = attacker->s.number;
		if ( attacker->client ) {
			killerName = attacker->client->pers.netname;
		} else {
			killerName = "<non-client>";
		}
	} else {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if ( killer < 0 || killer >= MAX_CLIENTS ) {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if ( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) ) {
		obit = "<bad obituary>";
	} else {
		obit = modNames[ meansOfDeath ];
	}

	G_LogPrintf( "Kill: %i %i %i: %s killed %s by %s\n",
				 killer, self->s.number, meansOfDeath, killerName,
				 self->client->pers.netname, obit );

	// broadcast the death event to everyone
	ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
	ent->s.eventParm = meansOfDeath;
	ent->s.otherEntityNum = self->s.number;
	ent->s.otherEntityNum2 = killer;
	ent->r.svFlags = SVF_BROADCAST; // send to everyone

	self->enemy = attacker;

	self->client->ps.persistant[PERS_KILLED]++;

// JPW NERVE -- if player is holding ticking grenade, drop it
	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		if ( ( self->client->ps.grenadeTimeLeft ) && ( self->s.weapon != WP_DYNAMITE ) ) {
			launchvel[0] = crandom();
			launchvel[1] = crandom();
			launchvel[2] = random();
			VectorScale( launchvel, 160, launchvel );
			VectorCopy( self->r.currentOrigin, launchspot );
			launchspot[2] += 40;
			fire_grenade( self, launchspot, launchvel, self->s.weapon );

		}
	}
// jpw

	if ( attacker && attacker->client ) {
		if ( attacker == self || OnSameTeam( self, attacker ) ) {

			// DHM - Nerve :: Complaint lodging
			if ( attacker != self && level.warmupTime <= 0 ) {
				if ( attacker->client->pers.localClient ) {
					trap_SendServerCommand( self - g_entities, "complaint -4" );
				} else {
					trap_SendServerCommand( self - g_entities, va( "complaint %i", attacker->s.number ) );
					self->client->pers.complaintClient = attacker->s.clientNum;
					self->client->pers.complaintEndTime = level.time + 20500;
				}
			}
			// dhm

			// JPW NERVE
			if ( g_gametype.integer >= GT_WOLF ) { // high penalty to offset medic heal
				AddScore( attacker, WOLF_FRIENDLY_PENALTY );
			} else {
				// jpw
				AddScore( attacker, -1 );
			}
		} else {
			// JPW NERVE -- mostly added as conveneience so we can tweak from the #defines all in one place
			if ( g_gametype.integer >= GT_WOLF ) {
				AddScore( attacker, WOLF_FRAG_BONUS );
			} else {
				// jpw
				AddScore( attacker, 1 );
			}

			attacker->client->lastKillTime = level.time;
		}
	} else {
		AddScore( self, -1 );
	}

	// Add team bonuses
	Team_FragBonuses( self, inflictor, attacker );

	// if client is in a nodrop area, don't drop anything
// JPW NERVE new drop behavior
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {   // only drop here in single player; in multiplayer, drop @ limbo
		contents = trap_PointContents( self->r.currentOrigin, -1 );
		if ( !( contents & CONTENTS_NODROP ) ) {
			TossClientItems( self );
		}
	}

	// drop flag regardless
	if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
		if ( self->client->ps.powerups[PW_REDFLAG] ) {
			item = BG_FindItem( "Red Flag" );
			if ( !item ) {
				item = BG_FindItem( "Objective" );
			}

			self->client->ps.powerups[PW_REDFLAG] = 0;
		}
		if ( self->client->ps.powerups[PW_BLUEFLAG] ) {
			item = BG_FindItem( "Blue Flag" );
			if ( !item ) {
				item = BG_FindItem( "Objective" );
			}

			self->client->ps.powerups[PW_BLUEFLAG] = 0;
		}

		if ( item ) {
			launchvel[0] = crandom() * 20;
			launchvel[1] = crandom() * 20;
			launchvel[2] = 10 + random() * 10;

			flag = LaunchItem( item,self->r.currentOrigin,launchvel,self->s.number );
			flag->s.modelindex2 = self->s.otherEntityNum2; // JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here
			flag->message = self->message;  // DHM - Nerve :: also restore item name
			// Clear out player's temp copies
			self->s.otherEntityNum2 = 0;
			self->message = NULL;
		}

		// send a fancy "MEDIC!" scream.  Sissies, ain' they?
		if ( self->client != NULL ) {
			if ( self->health > GIB_HEALTH && meansOfDeath != MOD_SUICIDE ) {

				if ( self->client->sess.sessionTeam == TEAM_RED ) {
					if ( random() > 0.5 ) {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/axis/g-medic2.wav" ) );
					} else {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/axis/g-medic3.wav" ) );
					}
				} else {
					if ( random() > 0.5 ) {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/allies/a-medic3.wav" ) );
					} else {
						G_AddEvent( self, EV_GENERAL_SOUND, G_SoundIndex( "sound/multiplayer/allies/a-medic2.wav" ) );
					}
				}
			}
		}
	}
// jpw

	Cmd_Score_f( self );        // show scores
	// send updated scores to any clients that are following this one,
	// or they would get stale scoreboards
	for ( i = 0 ; i < level.maxclients ; i++ ) {
		gclient_t   *client;

		client = &level.clients[i];
		if ( client->pers.connected != CON_CONNECTED ) {
			continue;
		}
		if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
			continue;
		}
		if ( client->sess.spectatorClient == self->s.number ) {
			Cmd_Score_f( g_entities + i );
		}
	}

	self->takedamage = qtrue;   // can still be gibbed
	self->r.contents = CONTENTS_CORPSE;

	self->s.powerups = 0;
// JPW NERVE -- only corpse in SP; in MP, need CONTENTS_BODY so medic can operate
	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		self->s.weapon = WP_NONE;
		self->s.angles[0] = 0;
	} else {
		self->client->limboDropWeapon = self->s.weapon; // store this so it can be dropped in limbo
	}
// jpw
	self->s.angles[2] = 0;
	LookAtKiller( self, inflictor, attacker );

	VectorCopy( self->s.angles, self->client->ps.viewangles );
	self->s.loopSound = 0;

	trap_UnlinkEntity( self );
	self->r.maxs[2] = 0;
	self->client->ps.maxs[2] = 0;
	trap_LinkEntity( self );

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	self->client->respawnTime = level.time + 800;

	// remove powerups
	memset( self->client->ps.powerups, 0, sizeof( self->client->ps.powerups ) );

	// never gib in a nodrop
	if ( self->health <= GIB_HEALTH && !( contents & CONTENTS_NODROP ) ) {
		GibEntity( self, killer );
		nogib = qfalse;
	}

	if ( nogib ) {
		// normal death
		// for the no-blood option, we need to prevent the health
		// from going to gib level
		if ( self->health <= GIB_HEALTH ) {
			self->health = GIB_HEALTH + 1;
		}

// JPW NERVE for medic
		self->client->medicHealAmt = 0;
// jpw

		// DHM - Play death animation, and set pm_time to delay 'fallen' animation
		self->client->ps.pm_time = BG_AnimScriptEvent( &self->client->ps, ANIM_ET_DEATH, qfalse, qtrue );

		G_AddEvent( self, EV_DEATH1 + 1, killer );

		// the body can still be gibbed
		self->die = body_die;
	}

	trap_LinkEntity( self );

	if ( g_gametype.integer >= GT_WOLF && meansOfDeath == MOD_SUICIDE ) {
		limbo( self, qtrue );
	}
}
Example #26
0
File: g_cmds.c Project: Razish/QtZ
static void G_Give( gentity_t *ent, const char *name, const char *args, int argc ) {
	const gitem_t *it;
	int			i;
	qboolean	give_all = qfalse;
	gentity_t	*it_ent;
	trace_t		trace;

	if ( !Q_stricmp( name, "all" ) )
		give_all = qtrue;

	if ( give_all || !Q_stricmp( name, "health") )
	{
		if ( argc == 3 )
			ent->health = Q_clampi( 1, atoi( args ), MAX_HEALTH );
		else
			ent->health = MAX_HEALTH;
		if ( !give_all )
			return;
	}

	if ( give_all || !Q_stricmp( name, "armor" ) || !Q_stricmp( name, "shield" ) )
	{
		if ( argc == 3 )
			ent->client->ps.stats[STAT_ARMOR] = Q_clampi( 0, atoi( args ), MAX_ARMOR );
		else
			ent->client->ps.stats[STAT_ARMOR] = MAX_ARMOR;

		if ( !give_all )
			return;
	}

	if ( give_all || !Q_stricmp( name, "weapons" ) )
	{
		ent->client->ps.stats[STAT_WEAPONS] = (1 << (WP_NUM_WEAPONS)) - (1 << WP_NONE);
		if ( !give_all )
			return;
	}
	
	if ( !give_all && !Q_stricmp( name, "weaponnum" ) )
	{
		ent->client->ps.stats[STAT_WEAPONS] |= (1 << atoi( args ));
		return;
	}

	if ( give_all || !Q_stricmp( name, "ammo" ) )
	{
		int num = 999;
		if ( argc == 3 )
			num = atoi( args );
		for ( i=0; i<MAX_WEAPONS; i++ )
			ent->client->ps.ammo[i] = num;
		if ( !give_all )
			return;
	}

	// spawn a specific item right on the player
	if ( !give_all ) {
		it = BG_FindItem( name );
		if ( !it )
			return;

		it_ent = G_Spawn();
		VectorCopy( &ent->r.currentOrigin, &it_ent->s.origin );
		it_ent->classname = it->classname;
		G_SpawnItem( it_ent, it );
		FinishSpawningItem( it_ent );
		memset( &trace, 0, sizeof( trace ) );
		Touch_Item( it_ent, ent, &trace );
		if ( it_ent->inuse )
			G_FreeEntity( it_ent );
	}
}
Example #27
0
void CG_Drop_f( void ) {
	char	command[ 128 ];
	char	message[ 128 ];
	gitem_t	*item;
	int	j;

	if ( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR ) {
		return;
	}
	if ( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 ) {
		CG_Printf( "You must be alive to use this command.\n" );
		return;
	}
	trap_Args( message, 128 );
	item = BG_FindItem( message );
	if ( !item ) {
		CG_Printf( "unknown item: %s\n", message );
		return;
	}

	if ( !cg_items[ item->giTag ].registered ) {
		return;
	}

	j = item->giTag;
	switch ( item->giType ) {
	case IT_WEAPON:
		if ( cgs.dmflags & 256 ) {
			return;
		}
		if ( !( cg.snap->ps.stats[ STAT_WEAPONS ] & ( 1 << j ) ) ) {
			CG_Printf( "Out of item: %s\n", message );
			return;
		}
		if ( cg.snap->ps.weaponstate != WEAPON_READY ) {
			return;
		}
		if ( j == cg.snap->ps.weapon ) {
			return;
		}
		if ( j <= WP_MACHINEGUN || j == WP_GRAPPLING_HOOK ) {
			CG_Printf( "Item is not dropable.\n" );
			return;
		}
	case IT_AMMO:
		if ( cg.snap->ps.ammo[ j ] < 1 ) {
			CG_Printf( "Out of item: %s\n", message );
			return;
		}
		break;
	case IT_POWERUP:
		if ( cg.snap->ps.powerups[ j ] <= cg.time ) {
			CG_Printf( "Out of item: %s\n", message );
			return;
		}
		break;
	case IT_HOLDABLE:
		if ( j == HI_KAMIKAZE ) {
			CG_Printf( "Item is not dropable.\n" );
			return;
		}
		if ( bg_itemlist[ cg.snap->ps.stats[ STAT_HOLDABLE_ITEM ] ].giTag != j ) {
			CG_Printf( "Out of item: %s\n", message );
			return;
		}
		break;
	default:
		CG_Printf( "Item is not dropable.\n" );
		return;
	}

	Com_sprintf( command, 128, "drop %s", message );
	trap_SendClientCommand( command );
}
Example #28
0
/*
==============
ClearRegisteredItems
==============
*/
void ClearRegisteredItems( void ) {
	memset( itemRegistered, 0, sizeof( itemRegistered ) );

	if(g_instantgib.integer) {
            if(g_instantgib.integer & 2)
                RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
            //RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) );
            RegisterItem( BG_FindItemForWeapon( WP_RAILGUN ) );
	}
        else
	if(g_rockets.integer) {
		//RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
		//RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) );
		RegisterItem( BG_FindItemForWeapon( WP_ROCKET_LAUNCHER ) );
	}
	else
	{
		// players always start with the base weapon
		RegisterItem( BG_FindItemForWeapon( WP_MACHINEGUN ) );
		RegisterItem( BG_FindItemForWeapon( WP_GAUNTLET ) );
		if(g_gametype.integer == GT_ELIMINATION || g_gametype.integer == GT_CTF_ELIMINATION 
                        || g_gametype.integer == GT_LMS || g_elimination_allgametypes.integer)
		{
			RegisterItem( BG_FindItemForWeapon( WP_SHOTGUN ) );
			RegisterItem( BG_FindItemForWeapon( WP_GRENADE_LAUNCHER ) );
			RegisterItem( BG_FindItemForWeapon( WP_ROCKET_LAUNCHER ) );
			RegisterItem( BG_FindItemForWeapon( WP_LIGHTNING ) );
			RegisterItem( BG_FindItemForWeapon( WP_RAILGUN ) );
			RegisterItem( BG_FindItemForWeapon( WP_PLASMAGUN ) );
			RegisterItem( BG_FindItemForWeapon( WP_BFG ) );
			RegisterItem( BG_FindItemForWeapon( WP_NAILGUN ) );
			RegisterItem( BG_FindItemForWeapon( WP_PROX_LAUNCHER ) );
			RegisterItem( BG_FindItemForWeapon( WP_CHAINGUN ) );
		}
	}
	if( g_gametype.integer == GT_HARVESTER ) {
		RegisterItem( BG_FindItem( "Red Cube" ) );
		RegisterItem( BG_FindItem( "Blue Cube" ) );
	}
        
	if(g_gametype.integer == GT_DOUBLE_D ) {
		RegisterItem( BG_FindItem( "Point A (Blue)" ) );
		RegisterItem( BG_FindItem( "Point A (Red)" ) );
		RegisterItem( BG_FindItem( "Point A (White)" ) );
		RegisterItem( BG_FindItem( "Point B (Blue)" ) );
		RegisterItem( BG_FindItem( "Point B (Red)" ) );
		RegisterItem( BG_FindItem( "Point B (White)" ) );
	}

	if(g_gametype.integer == GT_DOMINATION ) {
		RegisterItem( BG_FindItem( "Neutral domination point" ) );
		RegisterItem( BG_FindItem( "Red domination point" ) );
		RegisterItem( BG_FindItem( "Blue domination point" ) );
	}
	
}
Example #29
0
/*
================
Bot_ScriptInitBot
================
*/
qboolean Bot_ScriptInitBot(int entnum)
{
	gentity_t      *ent, *trav;
	bot_state_t    *bs;
	char            userinfo[MAX_INFO_STRING];
	bot_script_global_data_t *bsgd;
	char           *token, *p, *pBackup;
	int             i, val = 0;
	int             weapons[2];
	gitem_t        *item = NULL;
	char           *name;

	//
	bs = &botstates[entnum];
	if(!bs->inuse)
	{
		return qfalse;
	}
	if(bs->script.data)
	{
		return qtrue;
	}
	// set starting defaults
	bs->script.status.eventIndex = -1;
	bs->script.data = NULL;
	//
	ent = BotGetEntity(bs->entitynum);
	trap_GetUserinfo(bs->entitynum, userinfo, sizeof(userinfo));
	name = Info_ValueForKey(userinfo, "scriptName");
	if(!name || !name[0])
	{
		return qfalse;
	}

	// find the script data for this bot
	bsgd = botCharacterScriptData;
	for(i = 0; i < numScriptCharacters; i++, bsgd++)
	{
		if(Q_stricmp(name, bsgd->name) != 0)
		{
			continue;
		}
		// check params
		p = bsgd->params;
		//
		// eliminate them with each condition not met
		while(qtrue)
		{
			token = COM_ParseExt(&p, qfalse);
			if(!token || !token[0])
			{
				// we're done, we found a match
				break;
			}
			//
			if(token[0] != '/')
			{
				G_Error("BotScript, line %i: condition identifier expected, '%s' found\n", bsgd->lineNum, token);
			}
			//
			if(!Q_stricmp(token, "/team"))
			{
				token = COM_ParseExt(&p, qfalse);
				if(!token || !token[0] || token[0] == '/')
				{
					G_Error("BotScript, line %i: unexpected end of /team parameter", bsgd->lineNum);
				}
				//
				if(!Q_stricmp(token, "axis"))
				{
					val = TEAM_AXIS;
				}
				else if(!Q_stricmp(token, "allies"))
				{
					val = TEAM_ALLIES;
				}
				else
				{
					G_Error("BotScript, line %i: unknown team \"%s\"", bsgd->lineNum, token);
				}
				// eliminate player
				if(bs->mpTeam != val)
				{
					break;
				}
			}
			else
				//
			if(!Q_stricmp(token, "/class"))
			{
				token = COM_ParseExt(&p, qfalse);
				if(!token || !token[0] || token[0] == '/')
				{
					G_Error("BotScript, line %i: unexpected end of /class parameter", bsgd->lineNum);
				}
				//
				val = Team_ClassForString(token);
				if(val < 0)
				{
					G_Error("BotScript, line %i: unknown class \"%s\"", bsgd->lineNum, token);
				}
				if(bs->mpClass != val)
				{
					break;
				}
			}
			else
				//
			if(!Q_stricmp(token, "/weapon"))
			{
				memset(weapons, 0, sizeof(weapons));
				// for each weapon
				while(qtrue)
				{
					// read the weapon
					token = COM_ParseExt(&p, qfalse);
					if(!token || !token[0] || token[0] == '/')
					{
						G_Error("BotScript, line %i: unexpected end of /weapon parameter", bsgd->lineNum);
					}
					//
					if((item = BG_FindItem(token)))
					{
						if(!item->giTag)
						{
							G_Error("BotScript, line %i: unknown weapon \"%s\"", bsgd->lineNum, token);
						}
						COM_BitSet(weapons, item->giTag);
					}
					else
					{
						G_Error("BotScript, line %i: unknown weapon \"%s\"", bsgd->lineNum, token);
					}
					//
					pBackup = p;
					token = COM_ParseExt(&p, qfalse);
					if(Q_stricmp(token, "or") != 0)
					{
						// not OR, so drop out of here
						p = pBackup;
						break;
					}
				}
				if(!(ent->client->ps.weapons[0] & weapons[0]) && !(ent->client->ps.weapons[1] & weapons[1]))
				{
					break;
				}
			}
			else
				//
			if(!Q_stricmp(token, "/within_range"))
			{
				// targetname
				token = COM_ParseExt(&p, qfalse);
				if(!token || !token[0] || token[0] == '/')
				{
					G_Error("BotScript, line %i: unexpected end of /within_range parameter", bsgd->lineNum);
				}
				trav = G_FindByTargetname(NULL, token);
				if(!trav)
				{
					G_Error("BotScript, line %i: unknown spawn point \"%s\"", bsgd->lineNum, token);
				}
				// range
				token = COM_ParseExt(&p, qfalse);
				if(!token || !token[0] || token[0] == '/')
				{
					G_Error("BotScript, line %i: range expected, not found", bsgd->lineNum);
				}
				//
				// eliminate players
				if(VectorDistanceSquared(ent->r.currentOrigin, trav->s.origin) > SQR(atof(token)))
				{
					break;
				}
			}
		}
		//
		// if there is a NOT a valid token waiting, then we passed all checks
		if(!token[0])
		{
			break;
		}
	}
	//
	if(i < numScriptCharacters)
	{
		// we found a script for this character
		bs->script.data = bsgd->data;
		return qtrue;
	}
	//
	return qfalse;
}
Example #30
0
static void Cmd_Spawn_f (gentity_t *ent)
{
	gentity_t *s;
	gitem_t *item;
	vec3_t origin;
	vec3_t forward;
	char name[MAX_STRING_CHARS];
	char valBuffer[128];
	float f;
	trace_t trace;

	if (!g_cheats.integer) {
        trap_SendServerCommand(ent-g_entities, va("print \"Cheats are not enabled on this server.\n\""));
        return;
    }
	if (trap_Argc() < 2) {
		trap_SendServerCommand(ent-g_entities, "print \"usage: spawn <item classname> [forward amount]\n\"");
		return;
	}

	if (trap_Argc() > 2) {
		trap_Argv(2, valBuffer, sizeof(valBuffer));
		f = atof(valBuffer);
	} else {
		f = 100;
	}

	trap_Argv(1, name, sizeof(name));

	s = G_Spawn();

	AngleVectors(ent->s.apos.trBase, forward, NULL, NULL);
	VectorNormalize(forward);
	VectorCopy(ent->s.pos.trBase, origin);
	VectorMA(origin, f, forward, origin);

	memset(&trace, 0, sizeof(trace));
	trap_Trace(&trace, ent->s.pos.trBase, NULL, NULL, origin, ent - g_entities, MASK_SOLID);
	//VectorCopy(origin, s->s.pos.trBase);
	//VectorCopy(origin, s->r.currentOrigin);
	//VectorCopy(origin, s->s.origin);
	VectorCopy(trace.endpos, s->s.origin);

	item = BG_FindItem (name);
	if (item) {
		s->classname = item->classname;
		G_SpawnItem(s, item);
		FinishSpawningItem(s);
		return;
	}

#if 0
	// check item spawn functions
	for ( item=bg_itemlist+1 ; item->classname ; item++ ) {
		//if ( !strcmp(item->classname, name) ) {
			s->classname = item->classname;

			G_SpawnItem(s, item);
			FinishSpawningItem(s);
			//memset( &trace, 0, sizeof( trace ) );
			//Touch_Item (it_ent, ent, &trace);
			//if (it_ent->inuse) {
			//	G_FreeEntity( it_ent );
			//}

			return;
		}
	}