示例#1
0
void
Cmd_Help_f(edict_t *ent)
{
	if (!ent)
	{
		return;
	}

	/* this is for backwards compatibility */
	if (deathmatch->value)
	{
		Cmd_Score_f(ent);
		return;
	}

	ent->client->showinventory = false;
	ent->client->showscores = false;

	if (ent->client->showhelp)
	{
		ent->client->showhelp = false;
		return;
	}

	ent->client->showhelp = true;
	ent->client->pers.helpchanged = 0;
	HelpComputerMessage(ent);
	gi.unicast(ent, true);
}
示例#2
0
文件: p_hud.c 项目: ZwS/qudos
void
Cmd_HelpMin_f(edict_t * ent)
{
	/* this is for backwards compatability */
	if (deathmatch->value) {
		Cmd_Score_f(ent);
		return;
	}
	ent->client->showinventory = false;
	ent->client->showscores = false;

	if (ent->client->showhelp && (ent->client->pers.game_helpchanged == game.helpchanged)) {
		ent->client->showhelp = false;
		return;
	}
	ent->client->showhelp = true;
	ent->client->pers.helpchanged = 0;
	HelpComputerMin(ent);
}
/*
==================
Cmd_Help_f

Display the current help message
==================
*/
void Cmd_Help_f (edict_t *ent)
{
	// this is for backwards compatability
	if (deathmatch->value)
	{
		Cmd_Score_f (ent);
		return;
	}

	ent->client->showinventory = false;
	ent->client->showscores = false;
	ent->client->showabilities = false;		//TMF7 GHOST MODE ( ghud )
	ent->client->showcollection = false;		//TMF7 GHOST MODE ( ghud )

	if (ent->client->showhelp && (ent->client->pers.game_helpchanged == game.helpchanged))
	{
		ent->client->showhelp = false;
		return;
	}

	ent->client->showhelp = true;
	ent->client->pers.helpchanged = 0;
	HelpComputer (ent);
}
示例#4
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 );
		}
	}
}
示例#5
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 );
	}
}
void 
VehicleDeathImpl( GameEntity* self, GameEntity* inflictor, GameEntity* attacker, int damage, int meansOfDeath )
{
	GameEntity* ent;
	int			contents;
	int			killer;
	int			i;
	char		*killerName, *obit;
		
	if ( self->client_->ps_.pm_type == PM_DEAD ) 
		return;

	if ( theLevel.intermissiontime_ ) 
		return;

	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 < 1 || 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]++;
	
	if( attacker && attacker->client_ )
	{
		attacker->client_->lastkilled_client_ = self->s.number;

		if ( attacker == self || OnSameTeam (self, attacker ) )
		{
			AddScore( attacker, self->r.currentOrigin, -1 );
		}
		else
		{
			if( attacker->r.svFlags & SVF_BOT )
			{
				AddScore( attacker, self->r.currentOrigin, 1 );
			}
			else
			{
				if( meansOfDeath != MOD_VEHICLEEXPLOSION && 
					meansOfDeath != MOD_CRASH )
				{
					AddScore( attacker, self->r.currentOrigin, 1 );
				}
				// Easy way to prevent enemy from lossing score in collision as well cause he kills "himself"
				else
				{
					AddScore( attacker, self->r.currentOrigin, 1 );
				}

			}

			attacker->client_->lastKillTime_ = theLevel.time_;
		}
	}
	else
	{
		AddScore( self, self->r.currentOrigin, -1 );
	}

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

	// if I committed suicide, the flag does not fall, it returns.
	if (meansOfDeath == MOD_SUICIDE) 
	{
		if ( self->client_->ps_.objectives & OB_REDFLAG ) 
		{		
			// only happens in standard CTF
			Team_ReturnFlag( ClientBase::TEAM_RED );
			self->client_->ps_.objectives &= ~OB_REDFLAG;
		}
		else if ( self->client_->ps_.objectives & OB_BLUEFLAG ) 
		{	
			// only happens in standard CTF
			Team_ReturnFlag( ClientBase::TEAM_BLUE );
			self->client_->ps_.objectives &= ~OB_BLUEFLAG;
		}
	}

	// if client is in a nodrop area, don't drop anything (but return CTF flags!)
	contents = SV_PointContents( self->r.currentOrigin, -1 );
	if ( !( contents & CONTENTS_NODROP )) 
	{
		if( g_gametype.integer == GT_CTF ) 
			TossVehicleFlags( self );
	} 
	else 
	{
		if ( contents & CONTENTS_NODROP ) 
		{
			if ( self->client_->ps_.objectives & OB_REDFLAG ) 		// only happens in standard CTF
				Team_ReturnFlag( ClientBase::TEAM_RED );
			else if ( self->client_->ps_.objectives & OB_BLUEFLAG ) 	// only happens in standard CTF
				Team_ReturnFlag( ClientBase::TEAM_BLUE );
		}
	}

	// update scores
	Cmd_Score_f( self );
	
	// send updated scores to any clients that are following this one,
	// or they would get stale scoreboards
	for( i = 1 ; i <= theLevel.maxclients_ ; i++ )
	{
		GameClient* client = theLevel.getClient(i);// &level.clients[i];

		if( !client || client->pers_.connected_ != GameClient::ClientPersistant::CON_CONNECTED ) 
			continue;

		if( client->sess_.sessionTeam_ != ClientBase::TEAM_SPECTATOR ) 
			continue;

		if( client->sess_.spectatorClient_ == self->s.number ) 
			Cmd_Score_f( theLevel.getEntity(i) );// g_entities + i );
	}

	self->takedamage_ = true;	// can still be gibbed
	self->r.contents = CONTENTS_CORPSE;
	self->s.objectives = 0;
	self->s.loopSound = 0;
	self->r.maxs[2] = -8;

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

	if( (self->ONOFF_ & OO_LANDED) && self->health_ > GIB_HEALTH ) 
		self->health_ = GIB_HEALTH - 1;

	// always gib ground vehicles and lqms
	if( availableVehicles[self->client_->vehicle_].cat & CAT_GROUND ) 
		self->health_ = GIB_HEALTH - 1;

	// Adjust gib for LQM's
	if( self->health_ < 0 && self->health_ > GIB_HEALTH+20 )
		self->health_ = GIB_HEALTH+5;

	// to gib or not to gib? 
	if ( self->health_ <= GIB_HEALTH ) /* && !(contents & CONTENTS_NODROP) ) // never gib in a nodrop */
	{
		// create vehicle explosion
		ExplodeVehicle( self );

		// create radius explosion damage
		G_RadiusDamage( self->r.currentOrigin, self, 150, 150, self, MOD_VEHICLEEXPLOSION, CAT_ANY );

	}
	else if ( availableVehicles[self->client_->vehicle_].cat & CAT_LQM ) 
	{
		self->setDie(new VehicleBase::VehicleDie);
		self->client_->respawnTime_ = theLevel.time_ + 3000;
	}
	else
	{
		// create a smaller vehicle explosion
		G_AddEvent( self, EV_VEHICLE_DIE, 0, true );

		// wreck can be blown up (i.e on crash into ground)
		self->setDie(new VehicleBase::VehicleDie);

		// prevent early respawning during death anim (allows 30 seconds)
		self->client_->respawnTime_ = theLevel.time_ + 30000;
	}

	SV_LinkEntity( self );
}
示例#7
0
/*
=================
ClientCommand
=================
*/
void ClientCommand (edict_t *ent)
{
    char	*cmd;

    if (!ent->client)
        return;		// not fully in game yet

    cmd = gi.argv(0);

    if (Q_stricmp (cmd, "players") == 0)
    {
        Cmd_Players_f (ent);
        return;
    }
    if (Q_stricmp (cmd, "say") == 0)
    {
        Cmd_Say_f (ent, false, false);
        return;
    }
    if (Q_stricmp (cmd, "say_team") == 0)
    {
        Cmd_Say_f (ent, true, false);
        return;
    }
    if (Q_stricmp (cmd, "score") == 0)
    {
        Cmd_Score_f (ent);
        return;
    }
    if (Q_stricmp (cmd, "help") == 0)
    {
        Cmd_Help_f (ent);
        return;
    }

    if (level.intermissiontime)
        return;

    if (Q_stricmp (cmd, "use") == 0)
        Cmd_Use_f (ent);
    else if (Q_stricmp (cmd, "drop") == 0)
        Cmd_Drop_f (ent);
    else if (Q_stricmp (cmd, "give") == 0)
        Cmd_Give_f (ent);
    else if (Q_stricmp (cmd, "god") == 0)
        Cmd_God_f (ent);
    else if (Q_stricmp (cmd, "notarget") == 0)
        Cmd_Notarget_f (ent);
    else if (Q_stricmp (cmd, "noclip") == 0)
        Cmd_Noclip_f (ent);
    else if (Q_stricmp (cmd, "inven") == 0)
        Cmd_Inven_f (ent);
    else if (Q_stricmp (cmd, "invnext") == 0)
        SelectNextItem (ent, -1);
    else if (Q_stricmp (cmd, "invprev") == 0)
        SelectPrevItem (ent, -1);
    else if (Q_stricmp (cmd, "invnextw") == 0)
        SelectNextItem (ent, IT_WEAPON);
    else if (Q_stricmp (cmd, "invprevw") == 0)
        SelectPrevItem (ent, IT_WEAPON);
    else if (Q_stricmp (cmd, "invnextp") == 0)
        SelectNextItem (ent, IT_POWERUP);
    else if (Q_stricmp (cmd, "invprevp") == 0)
        SelectPrevItem (ent, IT_POWERUP);
    else if (Q_stricmp (cmd, "invuse") == 0)
        Cmd_InvUse_f (ent);
    else if (Q_stricmp (cmd, "invdrop") == 0)
        Cmd_InvDrop_f (ent);
    else if (Q_stricmp (cmd, "weapprev") == 0)
        Cmd_WeapPrev_f (ent);
    else if (Q_stricmp (cmd, "weapnext") == 0)
        Cmd_WeapNext_f (ent);
    else if (Q_stricmp (cmd, "weaplast") == 0)
        Cmd_WeapLast_f (ent);
    else if (Q_stricmp (cmd, "kill") == 0)
        Cmd_Kill_f (ent);
    else if (Q_stricmp (cmd, "putaway") == 0)
        Cmd_PutAway_f (ent);
    else if (Q_stricmp (cmd, "wave") == 0)
        Cmd_Wave_f (ent);
    else if (Q_stricmp(cmd, "playerlist") == 0)
        Cmd_PlayerList_f(ent);
    else	// anything that doesn't match a command will be a chat
        Cmd_Say_f (ent, false, true);
}
示例#8
0
文件: g_cmds.c 项目: yquake2/ctf
void
ClientCommand(edict_t *ent)
{
    char *cmd;

    if (!ent->client)
    {
        return; /* not fully in game yet */
    }

    cmd = gi.argv(0);

    if (Q_stricmp(cmd, "players") == 0)
    {
        Cmd_Players_f(ent);
        return;
    }

    if (Q_stricmp(cmd, "say") == 0)
    {
        Cmd_Say_f(ent, false, false);
        return;
    }

    if ((Q_stricmp(cmd, "say_team") == 0) || (Q_stricmp(cmd, "steam") == 0))
    {
        CTFSay_Team(ent, gi.args());
        return;
    }

    if (Q_stricmp(cmd, "score") == 0)
    {
        Cmd_Score_f(ent);
        return;
    }

    if (Q_stricmp(cmd, "help") == 0)
    {
        Cmd_Help_f(ent);
        return;
    }

    if (level.intermissiontime)
    {
        return;
    }

    if (Q_stricmp(cmd, "use") == 0)
    {
        Cmd_Use_f(ent);
    }
    else if (Q_stricmp(cmd, "drop") == 0)
    {
        Cmd_Drop_f(ent);
    }
    else if (Q_stricmp(cmd, "give") == 0)
    {
        Cmd_Give_f(ent);
    }
    else if (Q_stricmp(cmd, "god") == 0)
    {
        Cmd_God_f(ent);
    }
    else if (Q_stricmp(cmd, "notarget") == 0)
    {
        Cmd_Notarget_f(ent);
    }
    else if (Q_stricmp(cmd, "noclip") == 0)
    {
        Cmd_Noclip_f(ent);
    }
    else if (Q_stricmp(cmd, "inven") == 0)
    {
        Cmd_Inven_f(ent);
    }
    else if (Q_stricmp(cmd, "invnext") == 0)
    {
        SelectNextItem(ent, -1);
    }
    else if (Q_stricmp(cmd, "invprev") == 0)
    {
        SelectPrevItem(ent, -1);
    }
    else if (Q_stricmp(cmd, "invnextw") == 0)
    {
        SelectNextItem(ent, IT_WEAPON);
    }
    else if (Q_stricmp(cmd, "invprevw") == 0)
    {
        SelectPrevItem(ent, IT_WEAPON);
    }
    else if (Q_stricmp(cmd, "invnextp") == 0)
    {
        SelectNextItem(ent, IT_POWERUP);
    }
    else if (Q_stricmp(cmd, "invprevp") == 0)
    {
        SelectPrevItem(ent, IT_POWERUP);
    }
    else if (Q_stricmp(cmd, "invuse") == 0)
    {
        Cmd_InvUse_f(ent);
    }
    else if (Q_stricmp(cmd, "invdrop") == 0)
    {
        Cmd_InvDrop_f(ent);
    }
    else if (Q_stricmp(cmd, "weapprev") == 0)
    {
        Cmd_WeapPrev_f(ent);
    }
    else if (Q_stricmp(cmd, "weapnext") == 0)
    {
        Cmd_WeapNext_f(ent);
    }
    else if (Q_stricmp(cmd, "weaplast") == 0)
    {
        Cmd_WeapLast_f(ent);
    }
    else if (Q_stricmp(cmd, "kill") == 0)
    {
        Cmd_Kill_f(ent);
    }
    else if (Q_stricmp(cmd, "putaway") == 0)
    {
        Cmd_PutAway_f(ent);
    }
    else if (Q_stricmp(cmd, "wave") == 0)
    {
        Cmd_Wave_f(ent);
    }
    /* ZOID */
    else if (Q_stricmp(cmd, "team") == 0)
    {
        CTFTeam_f(ent);
    }
    else if (Q_stricmp(cmd, "id") == 0)
    {
        CTFID_f(ent);
    }
    else if (Q_stricmp(cmd, "yes") == 0)
    {
        CTFVoteYes(ent);
    }
    else if (Q_stricmp(cmd, "no") == 0)
    {
        CTFVoteNo(ent);
    }
    else if (Q_stricmp(cmd, "ready") == 0)
    {
        CTFReady(ent);
    }
    else if (Q_stricmp(cmd, "notready") == 0)
    {
        CTFNotReady(ent);
    }
    else if (Q_stricmp(cmd, "ghost") == 0)
    {
        CTFGhost(ent);
    }
    else if (Q_stricmp(cmd, "admin") == 0)
    {
        CTFAdmin(ent);
    }
    else if (Q_stricmp(cmd, "stats") == 0)
    {
        CTFStats(ent);
    }
    else if (Q_stricmp(cmd, "warp") == 0)
    {
        CTFWarp(ent);
    }
    else if (Q_stricmp(cmd, "boot") == 0)
    {
        CTFBoot(ent);
    }
    else if (Q_stricmp(cmd, "playerlist") == 0)
    {
        CTFPlayerList(ent);
    }
    else if (Q_stricmp(cmd, "observer") == 0)
    {
        CTFObserver(ent);
    }
    else /* anything that doesn't match a command will be a chat */
    {
        Cmd_Say_f(ent, false, true);
    }
}
示例#9
0
/*
==================
player_die
==================
*/
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	gentity_t   *ent;
	int anim;
	int contents = 0;
	int killer;
	int i;
	char        *killerName, *obit;
	qboolean nogib = qtrue;
	gitem_t     *item = NULL; // JPW NERVE for flag drop
	vec3_t launchvel;      // JPW NERVE
	gentity_t   *flag; // JPW NERVE

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

	if ( level.intermissiontime ) {
		return;
	}

//----(SA) commented out as we have no hook
//	if (self->client && self->client->hook)
//		Weapon_HookFree(self->client->hook);

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

	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]++;

	if ( attacker && attacker->client ) {
		if ( attacker == self || OnSameTeam( self, attacker ) ) {
			AddScore( attacker, -1 );
		} else {
			AddScore( attacker, 1 );

			// Ridah, not in single player
			if ( g_gametype.integer != GT_SINGLE_PLAYER ) {
				// done.
				if ( meansOfDeath == MOD_GAUNTLET ) {
					attacker->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT]++;
					attacker->client->ps.persistant[PERS_REWARD] = REWARD_GAUNTLET;
					attacker->client->ps.persistant[PERS_REWARD_COUNT]++;

					// add the sprite over the player's head
//					attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT /*| EF_AWARD_GAUNTLET*/ );
					//attacker->client->ps.eFlags |= EF_AWARD_GAUNTLET;
					attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;

					// also play humiliation on target
					self->client->ps.persistant[PERS_REWARD] = REWARD_GAUNTLET;
					self->client->ps.persistant[PERS_REWARD_COUNT]++;
				}

				// check for two kills in a short amount of time
				// if this is close enough to the last kill, give a reward sound
				if ( level.time - attacker->client->lastKillTime < CARNAGE_REWARD_TIME ) {
					attacker->client->ps.persistant[PERS_REWARD_COUNT]++;
					attacker->client->ps.persistant[PERS_REWARD] = REWARD_EXCELLENT;
					attacker->client->ps.persistant[PERS_EXCELLENT_COUNT]++;

					// add the sprite over the player's head
//					attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT /*| EF_AWARD_GAUNTLET*/ );
//					attacker->client->ps.eFlags |= EF_AWARD_EXCELLENT;
					attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
				}
				// Ridah
			}
			// done.
			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 ( self->client->ps.powerups[PW_BLUEFLAG] ) {
			item = BG_FindItem( "Blue Flag" );
		}
		launchvel[0] = crandom() * 20;
		launchvel[1] = crandom() * 20;
		launchvel[2] = 10 + random() * 10;
		if ( item ) {
			flag = LaunchItem( item,self->r.currentOrigin,launchvel );
			flag->s.modelindex2 = self->s.otherEntityNum2; // JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here
		}
	}
// 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->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->r.contents = CONTENTS_CORPSE;
		self->s.weapon = WP_NONE;
	} else {
		self->client->limboDropWeapon = self->s.weapon; // store this so it can be dropped in limbo
	}
// jpw
	self->s.angles[0] = 0;
	self->s.angles[2] = 0;
	LookAtKiller( self, inflictor, attacker );

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

	self->s.loopSound = 0;

	self->r.maxs[2] = -8;

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

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

	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		trap_SendServerCommand( -1, "mu_play sound/music/l_failed_1.wav 0\n" );
		trap_SetConfigstring( CS_MUSIC_QUEUE, "" );  // clear queue so it'll be quiet after hit
		trap_SendServerCommand( -1, "cp missionfail0" );
	}


	// never gib in a nodrop
	if ( self->health <= GIB_HEALTH && !( contents & CONTENTS_NODROP ) && g_blood.integer ) {
//		if(self->client->ps.eFlags & EF_HEADSHOT)
//		{
//			GibHead(self, killer);
//		}
//		else	// gib death
//		{
		GibEntity( self, killer );
		nogib = qfalse;
//		}
	}

	if ( nogib ) {
		// normal death
		static int i;

		switch ( i ) {
		case 0:
			anim = BOTH_DEATH1;
			break;
		case 1:
			anim = BOTH_DEATH2;
			break;
		case 2:
		default:
			anim = BOTH_DEATH3;
			break;
		}

		// 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

		self->client->ps.legsAnim =
			( ( self->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
		self->client->ps.torsoAnim =
			( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;

		G_AddEvent( self, EV_DEATH1 + 1, killer );

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

		// globally cycle through the different death animations
		i = ( i + 1 ) % 3;
	}

	trap_LinkEntity( self );

	if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
		AICast_ScriptEvent( AICast_GetCastState( self->s.number ), "death", "" );
	}
}
示例#10
0
/*
==================
player_die
==================
*/
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	gentity_t	*ent;
	int			anim;
	int			contents;
	int			killer;
	int			i,counter2;
	char		*killerName, *obit;

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

	if ( level.intermissiontime ) {
		return;
	}

//unlagged - backward reconciliation #2
	// make sure the body shows up in the client's current position
	G_UnTimeShiftClient( self );
//unlagged - backward reconciliation #2
    //KK-OAX Here is where we run the streak logic. 
    G_RunStreakLogic( attacker, self );
    
	// check for an almost capture
	CheckAlmostCapture( self, attacker );
	// check for a player that almost brought in cubes
	CheckAlmostScored( self, attacker );

	if (self->client && self->client->hook) {
		Weapon_HookFree(self->client->hook);
	}
	if ((self->client->ps.eFlags & EF_TICKING) && self->activator) {
		self->client->ps.eFlags &= ~EF_TICKING;
		self->activator->think = G_FreeEntity;
		self->activator->nextthink = level.time;
	}
	self->client->ps.pm_type = PM_DEAD;

	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;
        //Sago: Hmmm... generic? Can I transmit anything I like? Like if it is a team kill? Let's try
        ent->s.generic1 = OnSameTeam (self, attacker);
        if( !((g_gametype.integer==GT_ELIMINATION || g_gametype.integer==GT_CTF_ELIMINATION) && level.time < level.roundStartTime) )
            ent->r.svFlags = SVF_BROADCAST;	// send to everyone (if not an elimination gametype during active warmup)
        else
            ent->r.svFlags = SVF_NOCLIENT;

	self->enemy = attacker;

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

	if (attacker && attacker->client) {
		attacker->client->lastkilled_client = self->s.number;

		if ( attacker == self || OnSameTeam (self, attacker ) ) {
			if(g_gametype.integer!=GT_LMS && !((g_gametype.integer==GT_ELIMINATION || g_gametype.integer==GT_CTF_ELIMINATION) && level.time < level.roundStartTime))
                            if( (g_gametype.integer <GT_TEAM && g_ffa_gt!=1 && self->client->ps.persistant[PERS_SCORE]>0) || level.numNonSpectatorClients<3) //Cannot get negative scores by suicide
                                AddScore( attacker, self->r.currentOrigin, -1 );
		} else {
			if(g_gametype.integer!=GT_LMS)
				AddScore( attacker, self->r.currentOrigin, 1 );

			if( meansOfDeath == MOD_GAUNTLET ) {
				
				// Attack gets a challenge complete:
				if(!(attacker->r.svFlags & SVF_BOT) && !(self->r.svFlags & SVF_BOT))
					ChallengeMessage(attacker,WEAPON_GAUNTLET_KILLS);
		
				// play humiliation on player
				attacker->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT]++;
                                G_LogPrintf( "Award: %i %i: %s gained the %s award!\n", attacker->client->ps.clientNum, 0, attacker->client->pers.netname, "GAUNTLET" );

				// add the sprite over the player's head
				attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
				attacker->client->ps.eFlags |= EF_AWARD_GAUNTLET;
				attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;

				// also play humiliation on target
				self->client->ps.persistant[PERS_PLAYEREVENTS] ^= PLAYEREVENT_GAUNTLETREWARD;
			}

                        //If neither attacker or taget is bots and not the same
                        if(!(attacker->r.svFlags & SVF_BOT) && !(self->r.svFlags & SVF_BOT) && self!=attacker)
                        {
                            switch(meansOfDeath)
                            {
                                case MOD_GAUNTLET:
                                    ChallengeMessage(attacker,WEAPON_GAUNTLET_KILLS);
                                    break;
                                case MOD_MACHINEGUN:
                                    ChallengeMessage(attacker,WEAPON_MACHINEGUN_KILLS);
                                    break;
                                case MOD_SHOTGUN:
                                    ChallengeMessage(attacker,WEAPON_SHOTGUN_KILLS);
                                    break;
                                case MOD_GRENADE:
                                case MOD_GRENADE_SPLASH:
                                    ChallengeMessage(attacker,WEAPON_GRANADE_KILLS);
                                    break;
                                case MOD_ROCKET:
                                case MOD_ROCKET_SPLASH:
                                    ChallengeMessage(attacker,WEAPON_ROCKET_KILLS);
                                    break;
                                case MOD_LIGHTNING:
                                    ChallengeMessage(attacker,WEAPON_LIGHTNING_KILLS);
                                    break;
                                case MOD_PLASMA:
                                case MOD_PLASMA_SPLASH:
                                    ChallengeMessage(attacker,WEAPON_PLASMA_KILLS);
                                    break;
                                case MOD_RAILGUN:
                                    if(g_instantgib.integer)
                                        ChallengeMessage(attacker,WEAPON_INSTANT_RAIL_KILLS);
                                    else
                                        ChallengeMessage(attacker,WEAPON_RAIL_KILLS);
                                    break;
                                case MOD_BFG:
                                case MOD_BFG_SPLASH:
                                    ChallengeMessage(attacker,WEAPON_BFG_KILLS);
                                    break;
                                case MOD_NAIL:
                                    ChallengeMessage(attacker,WEAPON_NAILGUN_KILLS);
                                    break;
                                case MOD_CHAINGUN:
                                    ChallengeMessage(attacker,WEAPON_CHAINGUN_KILLS);
                                    break;
                                case MOD_PROXIMITY_MINE:
                                    ChallengeMessage(attacker,WEAPON_MINE_KILLS);
                                    break;
                                case MOD_GRAPPLE:
                                    ChallengeMessage(attacker,WEAPON_GRAPPLE_KILLS);
                                    break;
                                case MOD_LAVA:
                                case MOD_SLIME:
                                case MOD_TRIGGER_HURT:
                                case MOD_FALLING:
                                    ChallengeMessage(attacker,WEAPON_PUSH_KILLS);
                                    break;
                                case MOD_CRUSH:
                                    ChallengeMessage(attacker,WEAPON_CRUSH_KILLS);
                                    break;
                                case MOD_TELEFRAG:
                                    ChallengeMessage(attacker,WEAPON_TELEFRAG_KILLS);
                                    break;
                            };
                            ChallengeMessage(attacker,GENERAL_TOTALKILLS);
                            ChallengeMessage(self,GENERAL_TOTALDEATHS);

                            //Lets count number of powerups:
                            i = 0;
                            counter2 = 0;

                            if(attacker->client->ps.powerups[PW_QUAD]) {
                                ChallengeMessage(attacker,POWERUP_QUAD_KILL);
                                counter2++;
                            }
                            if(self->client->ps.powerups[PW_QUAD]) {
                                ChallengeMessage(attacker,POWERUP_COUNTER_QUAD);
                                i++;
                            }

                            if(attacker->client->ps.powerups[PW_HASTE]) {
                                ChallengeMessage(attacker,POWERUP_SPEED_KILL);
                                counter2++;
                            }
                            if(self->client->ps.powerups[PW_HASTE]) {
                                ChallengeMessage(attacker,POWERUP_COUNTER_SPEED);
                                i++;
                            }

                            if(attacker->client->ps.powerups[PW_INVIS]) {
                                ChallengeMessage(attacker,POWERUP_INVIS_KILL);
                                counter2++;
                            }
                            if(self->client->ps.powerups[PW_INVIS]) {
                                ChallengeMessage(attacker,POWERUP_COUNTER_INVIS);
                                i++;
                            }

                            if(attacker->client->ps.powerups[PW_FLIGHT]) {
                                ChallengeMessage(attacker,POWERUP_FLIGHT_KILL);
                                counter2++;
                            }
                            if(self->client->ps.powerups[PW_FLIGHT]) {
                                ChallengeMessage(attacker,POWERUP_COUNTER_FLIGHT);
                                i++;
                            }

                            if(self->client->ps.powerups[PW_BATTLESUIT]) {
                                ChallengeMessage(attacker,POWERUP_COUNTER_ENVIR);
                                i++;
                            }

                            if(self->client->ps.powerups[PW_REGEN]) {
                                ChallengeMessage(attacker,POWERUP_COUNTER_REGEN);
                                i++;
                            }

                            if(i>1) //The target had more than one powerup
                                ChallengeMessage(attacker,POWERUP_COUNTER_MULTI);
                            if(counter2>1) //The attacker has more than one powerup
                                ChallengeMessage(attacker,POWERUP_MULTI_KILL);
                        }

			// check for two kills in a short amount of time
			// if this is close enough to the last kill, give a reward sound
			if ( level.time - attacker->client->lastKillTime < CARNAGE_REWARD_TIME ) {
				// KK-OAX
				// Check if Multikills are enabled
				if( g_altExcellent.integer ) {
				    attacker->client->pers.multiKillCount++;
				    G_checkForMultiKill( attacker );
				} // play excellent on player
				attacker->client->ps.persistant[PERS_EXCELLENT_COUNT]++;
                                G_LogPrintf( "Award: %i %i: %s gained the %s award!\n", attacker->client->ps.clientNum, 1, attacker->client->pers.netname, "EXCELLENT" );
                                if(!level.hadBots) //There has not been any bots
                                    ChallengeMessage(attacker,AWARD_EXCELLENT);
				// add the sprite over the player's head
				attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
				attacker->client->ps.eFlags |= EF_AWARD_EXCELLENT;
				attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
			} else { 
			    //KK-OAX Clear multikill count
			    //Must be 1 so the correct number of kills are displayed to the clients. 
			    attacker->client->pers.multiKillCount = 1;
			}
			attacker->client->lastKillTime = level.time;
		}
	} else {
		if(g_gametype.integer!=GT_LMS && !((g_gametype.integer==GT_ELIMINATION || g_gametype.integer==GT_CTF_ELIMINATION) && level.time < level.roundStartTime))
                    if(self->client->ps.persistant[PERS_SCORE]>0 || level.numNonSpectatorClients<3) //Cannot get negative scores by suicide
			AddScore( self, self->r.currentOrigin, -1 );
	}

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

	// if I committed suicide, the flag does not fall, it returns.
	if (meansOfDeath == MOD_SUICIDE) {
		if ( self->client->ps.powerups[PW_NEUTRALFLAG] ) {		// only happens in One Flag CTF
			Team_ReturnFlag( TEAM_FREE );
			self->client->ps.powerups[PW_NEUTRALFLAG] = 0;
		}
		else if ( self->client->ps.powerups[PW_REDFLAG] ) {		// only happens in standard CTF
			Team_ReturnFlag( TEAM_RED );
			self->client->ps.powerups[PW_REDFLAG] = 0;
		}
		else if ( self->client->ps.powerups[PW_BLUEFLAG] ) {	// only happens in standard CTF
			Team_ReturnFlag( TEAM_BLUE );
			self->client->ps.powerups[PW_BLUEFLAG] = 0;
		}
	}
        TossClientPersistantPowerups( self );
        if( g_gametype.integer == GT_HARVESTER ) {
                TossClientCubes( self );
        }
	// if client is in a nodrop area, don't drop anything (but return CTF flags!)
	TossClientItems( self );
//#endif

	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->s.weapon = WP_NONE;
	self->s.powerups = 0;
	self->r.contents = CONTENTS_CORPSE;

	self->s.angles[0] = 0;
	self->s.angles[2] = 0;
	LookAtKiller (self, inflictor, attacker);

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

	self->s.loopSound = 0;

	self->r.maxs[2] = -8;

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	self->client->respawnTime = level.time + 1700 +i;
        if(g_respawntime.integer>0) {
            for(i=0; self->client->respawnTime > i*g_respawntime.integer*1000;i++);

            self->client->respawnTime = i*g_respawntime.integer*1000;
        }
        //For testing:
        //G_Printf("Respawntime: %i\n",self->client->respawnTime);
	//However during warm up, we should respawn quicker!
	if(g_gametype.integer == GT_ELIMINATION || g_gametype.integer == GT_CTF_ELIMINATION || g_gametype.integer == GT_LMS)
		if(level.time<=level.roundStartTime && level.time>level.roundStartTime-1000*g_elimination_activewarmup.integer)
			self->client->respawnTime = level.time + rand()%800;

        RespawnTimeMessage(self,self->client->respawnTime);
		

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

	// never gib in a nodrop
	contents = trap_PointContents( self->r.currentOrigin, -1 );

	if ( (self->health <= GIB_HEALTH && !(contents & CONTENTS_NODROP) && g_blood.integer) || meansOfDeath == MOD_SUICIDE) {
		// gib death
		GibEntity( self, killer );
	} else {
		// normal death
		static int i;

		switch ( i ) {
		case 0:
			anim = BOTH_DEATH1;
			break;
		case 1:
			anim = BOTH_DEATH2;
			break;
		case 2:
		default:
			anim = BOTH_DEATH3;
			break;
		}

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

		self->client->ps.legsAnim = 
			( ( self->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
		self->client->ps.torsoAnim = 
			( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;

		G_AddEvent( self, EV_DEATH1 + i, killer );

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

		// globally cycle through the different death animations
		i = ( i + 1 ) % 3;

		if (self->s.eFlags & EF_KAMIKAZE) {
			Kamikaze_DeathTimer( self );
		}
	}

	trap_LinkEntity (self);

}
示例#11
0
/*
=================
ClientCommand
=================
*/
void ClientCommand( int clientNum ) {
	gentity_t *ent;
	char	cmd[MAX_TOKEN_CHARS];

	ent = g_entities + clientNum;
	if ( !ent->client ) {
		return;		// not fully in game yet
	}


	trap_Argv( 0, cmd, sizeof( cmd ) );

	if (Q_stricmp (cmd, "say") == 0) {
		Cmd_Say_f (ent, SAY_ALL, qfalse);
		return;
	}
	if (Q_stricmp (cmd, "say_team") == 0) {
		Cmd_Say_f (ent, SAY_TEAM, qfalse);
		return;
	}
	if (Q_stricmp (cmd, "tell") == 0) {
		Cmd_Tell_f ( ent );
		return;
	}
	if (Q_stricmp (cmd, "vsay") == 0) {
		Cmd_Voice_f (ent, SAY_ALL, qfalse, qfalse);
		return;
	}
	if (Q_stricmp (cmd, "vsay_team") == 0) {
		Cmd_Voice_f (ent, SAY_TEAM, qfalse, qfalse);
		return;
	}
	if (Q_stricmp (cmd, "vtell") == 0) {
		Cmd_VoiceTell_f ( ent, qfalse );
		return;
	}
	if (Q_stricmp (cmd, "vosay") == 0) {
		Cmd_Voice_f (ent, SAY_ALL, qfalse, qtrue);
		return;
	}
	if (Q_stricmp (cmd, "vosay_team") == 0) {
		Cmd_Voice_f (ent, SAY_TEAM, qfalse, qtrue);
		return;
	}
	if (Q_stricmp (cmd, "votell") == 0) {
		Cmd_VoiceTell_f ( ent, qtrue );
		return;
	}
	if (Q_stricmp (cmd, "vtaunt") == 0) {
		Cmd_VoiceTaunt_f ( ent );
		return;
	}
	if (Q_stricmp (cmd, "score") == 0) {
		Cmd_Score_f (ent);
		return;
	}

	// ignore all other commands when at intermission
	if (level.intermissiontime) {
		Cmd_Say_f (ent, qfalse, qtrue);
		return;
	}

	if (Q_stricmp (cmd, "give") == 0)
		Cmd_Give_f (ent);
	else if (Q_stricmp (cmd, "god") == 0)
		Cmd_God_f (ent);
	else if (Q_stricmp (cmd, "notarget") == 0)
		Cmd_Notarget_f (ent);
	else if (Q_stricmp (cmd, "noclip") == 0)
		Cmd_Noclip_f (ent);
	else if (Q_stricmp (cmd, "kill") == 0)
		Cmd_Kill_f (ent);
	else if (Q_stricmp (cmd, "teamtask") == 0)
		Cmd_TeamTask_f (ent);
	else if (Q_stricmp (cmd, "levelshot") == 0)
		Cmd_LevelShot_f (ent);
	else if (Q_stricmp (cmd, "follow") == 0)
		Cmd_Follow_f (ent);
	else if (Q_stricmp (cmd, "follownext") == 0)
		Cmd_FollowCycle_f (ent, 1);
	else if (Q_stricmp (cmd, "followprev") == 0)
		Cmd_FollowCycle_f (ent, -1);
	else if (Q_stricmp (cmd, "team") == 0)
		Cmd_Team_f (ent);
	else if (Q_stricmp (cmd, "where") == 0)
		Cmd_Where_f (ent);
	else if (Q_stricmp (cmd, "callvote") == 0)
		Cmd_CallVote_f (ent);
	else if (Q_stricmp (cmd, "vote") == 0)
		Cmd_Vote_f (ent);
	else if (Q_stricmp (cmd, "callteamvote") == 0)
		Cmd_CallTeamVote_f (ent);
	else if (Q_stricmp (cmd, "teamvote") == 0)
		Cmd_TeamVote_f (ent);
	else if (Q_stricmp (cmd, "gc") == 0)
		Cmd_GameCommand_f( ent );
	else if (Q_stricmp (cmd, "setviewpos") == 0)
		Cmd_SetViewpos_f( ent );
	else if (Q_stricmp (cmd, "stats") == 0)
		Cmd_Stats_f( ent );
	else
		trap_SendServerCommand( clientNum, va("print \"unknown cmd %s\n\"", cmd ) );
}
示例#12
0
文件: p_hud.c 项目: notr1ch/opentdm
/*
==================
Cmd_Help_f

Display the current help message
==================
*/
void Cmd_Help_f (edict_t *ent)
{
	// this is for backwards compatability
	Cmd_Score_f (ent);
}
示例#13
0
/*
=================
ClientCommand
=================
*/
void ClientCommand(edict_t *ent)
{
    char    *cmd;

    if (!ent->client)
        return;     // not fully in game yet

    if (ent->client->pers.connected <= CONN_CONNECTED) {
        return;
    }

    //ent->client->resp.activity_framenum = level.framenum;

    cmd = gi.argv(0);

    if (ent->client->pers.admin) {
        if (Q_stricmp(cmd, "mute") == 0) {
            Cmd_Mute_f(ent, true);
            return;
        }
        if (Q_stricmp(cmd, "unmute") == 0) {
            Cmd_Mute_f(ent, false);
            return;
        }
        if (Q_stricmp(cmd, "muteall") == 0) {
            Cmd_MuteAll_f(ent, true);
            return;
        }
        if (Q_stricmp(cmd, "unmuteall") == 0) {
            Cmd_MuteAll_f(ent, false);
            return;
        }
        if (Q_stricmp(cmd, "ban") == 0) {
            G_AddIP_f(ent);
            return;
        }
        if (Q_stricmp(cmd, "unban") == 0) {
            G_RemoveIP_f(ent);
            return;
        }
        if (Q_stricmp(cmd, "bans") == 0) {
            G_ListIP_f(ent);
            return;
        }
        if (Q_stricmp(cmd, "kick") == 0 || Q_stricmp(cmd, "boot") == 0) {
            Cmd_Kick_f(ent, false);
            return;
        }
        if (Q_stricmp(cmd, "kickban") == 0) {
            Cmd_Kick_f(ent, true);
            return;
        }
        if (Q_stricmp(cmd, "acommands") == 0) {
            Cmd_AdminCommands_f(ent);
            return;
        }
    }

    if (Q_stricmp(cmd, "say") == 0) {
        Cmd_Say_f(ent, CHAT_ALL);
        return;
    }
    if (Q_stricmp(cmd, "say_team") == 0) {
        Cmd_Say_f(ent, CHAT_TEAM);
        return;
    }
    if (Q_stricmp(cmd, "players") == 0 || Q_stricmp(cmd, "playerlist") == 0) {
        Cmd_Players_f(ent);
        return;
    }
    if (Q_stricmp(cmd, "highscore") == 0 || Q_stricmp(cmd, "highscores") == 0) {
        Cmd_HighScores_f(ent);
        return;
    }
    if (Q_stricmp(cmd, "stats") == 0 || Q_stricmp(cmd, "accuracy") == 0) {
        Cmd_Stats_f(ent, true);
        return;
    }
    if (Q_stricmp(cmd, "settings") == 0 || Q_stricmp(cmd, "matchinfo") == 0) {
        Cmd_Settings_f(ent);
        return;
    }
    if (Q_stricmp(cmd, "admin") == 0 || Q_stricmp(cmd, "referee") == 0) {
        Cmd_Admin_f(ent);
        return;
    }
    if (Q_stricmp(cmd, "commands") == 0) {
        Cmd_Commands_f(ent);
        return;
    }
    if (Q_stricmp(cmd, "id") == 0) {
        Cmd_Id_f(ent);
        return;
    }

    if (level.intermission_framenum)
        return;

    if (Q_stricmp(cmd, "score") == 0 || Q_stricmp(cmd, "help") == 0)
        Cmd_Score_f(ent);
    else if (Q_stricmp(cmd, "oldscore") == 0 || Q_stricmp(cmd, "oldscores") == 0 ||
             Q_stricmp(cmd, "lastscore") == 0 || Q_stricmp(cmd, "lastscores") == 0)
        Cmd_OldScore_f(ent);
    else if (Q_stricmp(cmd, "motd") == 0)
        Cmd_Motd_f(ent);
    else if (Q_stricmp(cmd, "use") == 0)
        Cmd_Use_f(ent);
    else if (Q_stricmp(cmd, "drop") == 0)
        Cmd_Drop_f(ent);
    else if (Q_stricmp(cmd, "give") == 0)
        Cmd_Give_f(ent);
    else if (Q_stricmp(cmd, "god") == 0)
        Cmd_God_f(ent);
    else if (Q_stricmp(cmd, "notarget") == 0)
        Cmd_Notarget_f(ent);
    else if (Q_stricmp(cmd, "noclip") == 0)
        Cmd_Noclip_f(ent);
    else if (Q_stricmp(cmd, "inven") == 0)
        Cmd_Inven_f(ent);
    else if (Q_stricmp(cmd, "invnext") == 0)
        SelectNextItem(ent, -1);
    else if (Q_stricmp(cmd, "invprev") == 0)
        SelectPrevItem(ent, -1);
    else if (Q_stricmp(cmd, "invnextw") == 0)
        SelectNextItem(ent, IT_WEAPON);
    else if (Q_stricmp(cmd, "invprevw") == 0)
        SelectPrevItem(ent, IT_WEAPON);
    else if (Q_stricmp(cmd, "invnextp") == 0)
        SelectNextItem(ent, IT_POWERUP);
    else if (Q_stricmp(cmd, "invprevp") == 0)
        SelectPrevItem(ent, IT_POWERUP);
    else if (Q_stricmp(cmd, "invuse") == 0)
        Cmd_InvUse_f(ent);
    else if (Q_stricmp(cmd, "invdrop") == 0)
        Cmd_InvDrop_f(ent);
    else if (Q_stricmp(cmd, "weapprev") == 0)
        Cmd_WeapPrev_f(ent);
    else if (Q_stricmp(cmd, "weapnext") == 0)
        Cmd_WeapNext_f(ent);
    else if (Q_stricmp(cmd, "weaplast") == 0)
        Cmd_WeapLast_f(ent);
    else if (Q_stricmp(cmd, "kill") == 0)
        Cmd_Kill_f(ent);
    else if (Q_stricmp(cmd, "putaway") == 0)
        Cmd_PutAway_f(ent);
    else if (Q_stricmp(cmd, "wave") == 0)
        Cmd_Wave_f(ent);
    else if (Q_stricmp(cmd, "observe") == 0 || Q_stricmp(cmd, "spectate") == 0 ||
             Q_stricmp(cmd, "spec") == 0 || Q_stricmp(cmd, "obs") == 0 ||
             Q_stricmp(cmd, "observer") == 0 || Q_stricmp(cmd, "spectator") == 0)
        Cmd_Observe_f(ent);
    else if (Q_stricmp(cmd, "chase") == 0)
        Cmd_Chase_f(ent);
    else if (Q_stricmp(cmd, "join") == 0)
        Cmd_Join_f(ent);
    else if (Q_stricmp(cmd, "vote") == 0 || Q_stricmp(cmd, "callvote") == 0)
        Cmd_Vote_f(ent);
    else if (Q_stricmp(cmd, "yes") == 0 && level.vote.proposal)
        Cmd_CastVote_f(ent, true);
    else if (Q_stricmp(cmd, "no") == 0 && level.vote.proposal)
        Cmd_CastVote_f(ent, false);
    else if (Q_stricmp(cmd, "menu") == 0)
        Cmd_Menu_f(ent);
    else    // anything that doesn't match a command will be a chat
        Cmd_Say_f(ent, CHAT_MISC);
}
示例#14
0
/*
==================
player_die
==================
*/
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	gentity_t	*ent;
	int			anim;
	int			contents;
	int			killer;
	int			i;
	char		*killerName, *obit;

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

	if ( level.intermissiontime ) {
		return;
	}

	//if we're in SP mode and player killed a bot, award score for the kill
	if ( IsBot( self ) ) {
		if ( self->parent && self->parent->health && attacker->client ) {
			AddScore( attacker, self->r.currentOrigin, self->parent->health );
			self->s.time = level.time;
		}
	}	

	if (self->client && self->client->hook) {
		Weapon_HookFree(self->client->hook);
	}
	self->client->ps.pm_type = PM_DEAD;

	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]++;

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

	// if client is in a nodrop area, don't drop anything (but return CTF flags!)
	contents = trap_PointContents( self->r.currentOrigin, -1 );
	TossClientItems( self );

	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->s.weapon = WP_NONE;
	self->s.powerups = 0;
	self->r.contents = CONTENTS_CORPSE;

	self->s.angles[0] = 0;
	self->s.angles[2] = 0;
	LookAtKiller (self, inflictor, attacker);

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

	self->s.loopSound = 0;

	self->r.maxs[2] = -8;

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	if ( !IsBot(self) )
		self->client->respawnTime = level.time + 1700;
	else
		self->client->respawnTime = level.time + 5000;	//keep bot bodies around slightly longer

	// 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) && g_blood.integer) || meansOfDeath == MOD_SUICIDE) {
		// gib death
		GibEntity( self, killer );
	} else {
		// normal death
		static int i;

		switch ( i ) {
		case 0:
			anim = BOTH_DEATH1;
			break;
		case 1:
			anim = BOTH_DEATH2;
			break;
		case 2:
		default:
			anim = BOTH_DEATH3;
			break;
		}

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

		self->client->ps.legsAnim = 
			( ( self->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
		self->client->ps.torsoAnim = 
			( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;

		G_AddEvent( self, EV_DEATH1 + i, killer );

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

		// globally cycle through the different death animations
		i = ( i + 1 ) % 3;
	}

	trap_LinkEntity (self);

	// Fire trigger_death and trigger_frag target entities and the deathtarget for the related target_botspawn 
	G_UseTriggerFragAndDeathEntities ( self, attacker );
	if ( self->parent )
		G_UseDeathTargets( self->parent, self );

	if ( !IsBot( self ) )
		G_FadeOut( 1.0 );
}
示例#15
0
/*
=================
ClientCommand
=================
*/
void ClientCommand (edict_t *ent)
{
	char	*cmd;

	if (!ent->client)
		return;		// not fully in game yet

	cmd = gi.argv(0);

	// if we're viewing thru the camera, only allow some things to happen
	if (ent->client->zCameraTrack && !level.intermissiontime)
	{
		if (Q_stricmp (cmd, "putaway") == 0)
			Cmd_PutAway_f(ent);
		else if (Q_stricmp(cmd, "use") == 0)
		{
			if (Q_stricmp(gi.args(), "Visor") == 0)
				Cmd_Use_f(ent);
		}
		else if (Q_stricmp (cmd, "invuse") == 0)
		{
			// only use the visor
			if (ent->client->pers.selected_item == ITEM_INDEX(FindItem("Visor")))
				Cmd_InvUse_f (ent);
		}
		else if (Q_stricmp (cmd, "invnext") == 0)
			SelectNextItem (ent, -1);
		else if (Q_stricmp (cmd, "invprev") == 0)
			SelectPrevItem (ent, -1);
	
		return;
	}

	if (Q_stricmp (cmd, "players") == 0)
	{
		Cmd_Players_f (ent);
		return;
	}
	if (Q_stricmp (cmd, "say") == 0)
	{
		Cmd_Say_f (ent, false, false);
		return;
	}
	if (Q_stricmp (cmd, "say_team") == 0)
	{
		Cmd_Say_f (ent, true, false);
		return;
	}
	if (Q_stricmp (cmd, "score") == 0)
	{
		Cmd_Score_f (ent);
		return;
	}
	if (Q_stricmp (cmd, "help") == 0)
	{
		Cmd_Help_f (ent);
		return;
	}
  
	if (level.intermissiontime)
		return;

	if (Q_stricmp (cmd, "use") == 0)
		Cmd_Use_f (ent);
	else if (Q_stricmp (cmd, "drop") == 0)
		Cmd_Drop_f (ent);
	else if (Q_stricmp (cmd, "give") == 0)
		Cmd_Give_f (ent);
	else if (Q_stricmp (cmd, "god") == 0)
		Cmd_God_f (ent);
	else if (Q_stricmp (cmd, "notarget") == 0)
		Cmd_Notarget_f (ent);
	else if (Q_stricmp (cmd, "noclip") == 0)
		Cmd_Noclip_f (ent);
	else if (Q_stricmp (cmd, "inven") == 0)
		Cmd_Inven_f (ent);
	else if (Q_stricmp (cmd, "invnext") == 0)
		SelectNextItem (ent, -1);
	else if (Q_stricmp (cmd, "invprev") == 0)
		SelectPrevItem (ent, -1);
	else if (Q_stricmp (cmd, "invnextw") == 0)
		SelectNextItem (ent, IT_WEAPON);
	else if (Q_stricmp (cmd, "invprevw") == 0)
		SelectPrevItem (ent, IT_WEAPON);
	else if (Q_stricmp (cmd, "invnextp") == 0)
		SelectNextItem (ent, IT_POWERUP);
	else if (Q_stricmp (cmd, "invprevp") == 0)
		SelectPrevItem (ent, IT_POWERUP);
	else if (Q_stricmp (cmd, "invuse") == 0)
		Cmd_InvUse_f (ent);
	else if (Q_stricmp (cmd, "invdrop") == 0)
		Cmd_InvDrop_f (ent);
	else if (Q_stricmp (cmd, "weapprev") == 0)
		Cmd_WeapPrev_f (ent);
	else if (Q_stricmp (cmd, "weapnext") == 0)
		Cmd_WeapNext_f (ent);
	else if (Q_stricmp (cmd, "weaplast") == 0)
		Cmd_WeapLast_f (ent);
	else if (Q_stricmp (cmd, "kill") == 0)
		Cmd_Kill_f (ent);
	else if (Q_stricmp (cmd, "putaway") == 0)
		Cmd_PutAway_f (ent);
	else if (Q_stricmp (cmd, "wave") == 0)
		Cmd_Wave_f (ent);
#if defined(_DEBUG) && defined(_Z_TESTMODE)
  else if(Q_stricmp (cmd, "linesize") == 0)
  {
    extern float lineSize;
    float ls = atof(gi.argv(1));

    if(ls <= 0.0)
    {
      gi.cprintf (ent, PRINT_HIGH, "LineSize must be greater than 0\n");
      return;
    }

    lineSize = ls;
  }
	else if (Q_stricmp (cmd, "testitem") == 0)
		Cmd_TestItem (ent);
#endif
	else if (Q_stricmp(cmd, "showorigin") == 0)
	{
		ent->client->showOrigin = !ent->client->showOrigin;
		if (ent->client->showOrigin)
			gi.cprintf(ent, PRINT_HIGH, "Show origin ON\n");
		else
			gi.cprintf(ent, PRINT_HIGH, "Show origin OFF\n");
	}
#if defined(_DEBUG) && defined(_Z_TESTMODE)
   else if(Q_stricmp (cmd, "anim") == 0)
      anim_player_cmd(ent);
#endif
	else	// anything that doesn't match a command will be a chat
		Cmd_Say_f (ent, false, true);
}
示例#16
0
/*
=================
ClientCommand
=================
*/
void ClientCommand (edict_t * ent)
{
	char *cmd;

	if (!ent->client)
		return;			// not fully in game yet
	// if (level.intermissiontime)
	// return;

	cmd = gi.argv (0);

	if (Q_stricmp (cmd, "players") == 0)
	{
		Cmd_Players_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "say") == 0)
	{
		Cmd_Say_f (ent, false, false, false);
		return;
	}
	else if (Q_stricmp (cmd, "say_team") == 0)
	{
		Cmd_Say_f (ent, true, false, false);
		return;
	}
	else if (Q_stricmp (cmd, "score") == 0)
	{
		Cmd_Score_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "help") == 0)
	{
		Cmd_Help_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "use") == 0)
	{
		if(pause_time)
			return;
		Cmd_Use_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "drop") == 0)
	{
		if(pause_time)
			return;
		Cmd_Drop_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "give") == 0)
	{
		Cmd_Give_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "god") == 0)
	{
		Cmd_God_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "notarget") == 0)
	{
		Cmd_Notarget_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "noclip") == 0)
	{
		Cmd_Noclip_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "inven") == 0)
	{
		Cmd_Inven_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "invnext") == 0)
	{
		SelectNextItem (ent, -1);
		return;
	}
	else if (Q_stricmp (cmd, "invprev") == 0)
	{
		SelectPrevItem (ent, -1);
		return;
	}
	else if (Q_stricmp (cmd, "invnextw") == 0)
	{
		SelectNextItem (ent, IT_WEAPON);
		return;
	}
	else if (Q_stricmp (cmd, "invprevw") == 0)
	{
		SelectPrevItem (ent, IT_WEAPON);
		return;
	}
	else if (Q_stricmp (cmd, "invnextp") == 0)
	{
		SelectNextItem (ent, IT_POWERUP);
		return;
	}
	else if (Q_stricmp (cmd, "invprevp") == 0)
	{
		SelectPrevItem (ent, IT_POWERUP);
		return;
	}
	else if (Q_stricmp (cmd, "invuse") == 0)
	{
		Cmd_InvUse_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "invdrop") == 0)
	{
		Cmd_InvDrop_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "weapprev") == 0)
	{
		if(pause_time)
			return;
		Cmd_WeapPrev_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "weapnext") == 0)
	{
		if(pause_time)
			return;
		Cmd_WeapNext_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "weaplast") == 0)
	{
		if(pause_time)
			return;
		Cmd_WeapLast_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "kill") == 0)
	{
		Cmd_Kill_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "putaway") == 0)
	{
		Cmd_PutAway_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "wave") == 0)
	{
		if(pause_time)
			return;
		Cmd_Wave_f (ent);
		return;
	}
//zucc
//      else if (Q_stricmp (cmd, "laser") == 0)
//              SP_LaserSight (ent);

	//SLIC2

	else if (Q_stricmp (cmd, "streak") == 0)
	{
		gi.cprintf(ent,PRINT_HIGH,"Your Killing Streak is: %d\n",ent->client->resp.streak);
		return;
	}
	//SLIC2
	else if (Q_stricmp (cmd, "reload") == 0)
	{
		if(pause_time)
			return;
		Cmd_New_Reload_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "weapon") == 0)
	{
		if(pause_time)
			return;
		Cmd_New_Weapon_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "opendoor") == 0)
	{
		if(pause_time)
			return;
		Cmd_OpenDoor_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "bandage") == 0)
	{
		if(pause_time)
			return;
		Cmd_Bandage_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "id") == 0)
	{
		Cmd_ID_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "irvision") == 0)
	{
		if(pause_time)
			return;
		Cmd_IR_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "playerlist") == 0)
	{
		Cmd_PlayerList_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "team") == 0 && teamplay->value)
	{
		Team_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "radio") == 0)
	{
		Cmd_Radio_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "radiogender") == 0)
	{
		Cmd_Radiogender_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "radio_power") == 0)
	{
		Cmd_Radio_power_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "radiopartner") == 0)
	{
		Cmd_Radiopartner_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "radioteam") == 0)
	{
		Cmd_Radioteam_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "channel") == 0)
	{
		Cmd_Channel_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "say_partner") == 0)
	{
		Cmd_Say_partner_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "partner") == 0)
	{
		Cmd_Partner_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "unpartner") == 0)
	{
		Cmd_Unpartner_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "motd") == 0)
	{
		PrintMOTD (ent);
		return;
	}
	else if (Q_stricmp (cmd, "deny") == 0)
	{
		Cmd_Deny_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "choose") == 0)
	{
		Cmd_Choose_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "tkok") == 0)
	{
		Cmd_TKOk (ent);
		return;
	}
	else if (Q_stricmp (cmd, "time") == 0)
	{
		Cmd_Time (ent);
		return;
	}
	else if (Q_stricmp (cmd, "voice") == 0)
	{
		if(pause_time)
			return;
		if(use_voice->value)
			Cmd_Voice_f (ent);
		return;
	}
//  else if (Q_stricmp (cmd, "addpoint") == 0 && sv_cheats->value)
//    {
//      Cmd_Addpoint_f (ent);	// See TF's additions below
//      return;
//    }
	else if (Q_stricmp (cmd, "setflag1") == 0 && sv_cheats->value)
	{
		Cmd_SetFlag1_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "setflag2") == 0 && sv_cheats->value)
	{
		Cmd_SetFlag2_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "saveflags") == 0 && sv_cheats->value)
	{
		Cmd_SaveFlags_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "punch") == 0)
	{
		if(pause_time)
			return;
		Cmd_Punch_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "menu") == 0)
	{
		Cmd_Menu_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "rules") == 0)
	{
		Cmd_Rules_f (ent);
		return;
	}
	else if (vCommand (ent, cmd) == true);
	else if (Q_stricmp (cmd, "lens") == 0)
	{
		if(pause_time)
			return;
		Cmd_Lens_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "%cpsi") == 0)
	{
		Cmd_CPSI_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "%!fc") == 0)
	{
		Cmd_VidRef_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "sub") == 0)
	{
		Cmd_Sub_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "captain") == 0)
	{
		Cmd_Captain_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "ready") == 0)
	{
		Cmd_Ready_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "teamname") == 0)
	{
		Cmd_Teamname_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "teamskin") == 0)
	{
		Cmd_Teamskin_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "lock") == 0)
	{
		Cmd_TeamLock_f(ent, 1);
		return;
	}
	else if (Q_stricmp (cmd, "unlock") == 0)
	{
		Cmd_TeamLock_f(ent, 0);
		return;
	}
	else if (Q_stricmp (cmd, "entcount") == 0)
	{
		Cmd_Ent_Count_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "stats") == 0)
	{
		Cmd_Stats_f (ent, gi.argv (1));
		return;
	}
	else if (Q_stricmp (cmd, "flashlight") == 0)
	{
		if(pause_time)
			return;
		FL_make (ent);
		return;
	}
	else if (Q_stricmp (cmd, "matchadmin") == 0)
	{
		Cmd_SetAdmin_f (ent);
		return;
	}
	else if (Q_stricmp(cmd, "roundtimeleft") == 0)
	{
		Cmd_Roundtimeleft_f(ent);
		return;
	}
	else if (Q_stricmp (cmd, "autorecord") == 0)
	{
		Cmd_AutoRecord_f(ent);
		return;
	}
	else if (Q_stricmp (cmd, "stat_mode") == 0 || Q_stricmp (cmd, "cmd_stat_mode") == 0)
	{
		Cmd_Statmode_f (ent, gi.argv (1));
		return;
	}
	else if (Q_stricmp (cmd, "ghost") == 0)
	{
		Cmd_Ghost_f (ent);
		return;
	}
	else if (Q_stricmp (cmd, "pausegame") == 0)
	{
		Cmd_TogglePause_f(ent, true);
		return;
	}
	else if (Q_stricmp (cmd, "unpausegame") == 0)
	{
		Cmd_TogglePause_f(ent, false);
		return;
	}
	else if (Q_stricmp(cmd, "resetscores") == 0)
	{
		Cmd_ResetScores_f(ent);
	}
	else				// anything that doesn't match a command will be a chat
		Cmd_Say_f (ent, false, true, false);
}
示例#17
0
/*
==================
player_die
==================
*/
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	gentity_t	*ent;
	int			anim;
	int			contents;
	int			killer;
	int			i;
	char		*killerName, *obit;

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

	if ( level.intermissiontime ) {
		return;
	}

	// check for an almost capture
	CheckAlmostCapture( self, attacker );
	// check for a player that almost brought in cubes
	CheckAlmostScored( self, attacker );

	if (self->client && self->client->hook) {
		Weapon_HookFree(self->client->hook);
	}
#ifdef MISSIONPACK
	if ((self->client->ps.eFlags & EF_TICKING) && self->activator) {
		self->client->ps.eFlags &= ~EF_TICKING;
		self->activator->think = G_FreeEntity;
		self->activator->nextthink = level.time;
	}
#endif
	self->client->ps.pm_type = PM_DEAD;

	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 >= ARRAY_LEN( modNames ) ) {
		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]++;

	if (attacker && attacker->client) {
		attacker->client->lastkilled_client = self->s.number;

		if ( attacker == self || OnSameTeam (self, attacker ) ) {
			AddScore( attacker, self->r.currentOrigin, -1 );
		} else {
			AddScore( attacker, self->r.currentOrigin, 1 );

			if( meansOfDeath == MOD_GAUNTLET ) {
				
				// play humiliation on player
				attacker->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT]++;

				// add the sprite over the player's head
				attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
				attacker->client->ps.eFlags |= EF_AWARD_GAUNTLET;
				attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;

				// also play humiliation on target
				self->client->ps.persistant[PERS_PLAYEREVENTS] ^= PLAYEREVENT_GAUNTLETREWARD;
			}

			// check for two kills in a short amount of time
			// if this is close enough to the last kill, give a reward sound
			if ( level.time - attacker->client->lastKillTime < CARNAGE_REWARD_TIME ) {
				// play excellent on player
				attacker->client->ps.persistant[PERS_EXCELLENT_COUNT]++;

				// add the sprite over the player's head
				attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
				attacker->client->ps.eFlags |= EF_AWARD_EXCELLENT;
				attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
			}
			attacker->client->lastKillTime = level.time;

		}
	} else {
		AddScore( self, self->r.currentOrigin, -1 );
	}

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

	// if I committed suicide, the flag does not fall, it returns.
	if (meansOfDeath == MOD_SUICIDE) {
		if ( self->client->ps.powerups[PW_NEUTRALFLAG] ) {		// only happens in One Flag CTF
			Team_ReturnFlag( TEAM_FREE );
			self->client->ps.powerups[PW_NEUTRALFLAG] = 0;
		}
		else if ( self->client->ps.powerups[PW_REDFLAG] ) {		// only happens in standard CTF
			Team_ReturnFlag( TEAM_RED );
			self->client->ps.powerups[PW_REDFLAG] = 0;
		}
		else if ( self->client->ps.powerups[PW_BLUEFLAG] ) {	// only happens in standard CTF
			Team_ReturnFlag( TEAM_BLUE );
			self->client->ps.powerups[PW_BLUEFLAG] = 0;
		}
	}

	// if client is in a nodrop area, don't drop anything (but return CTF flags!)
	contents = trap_PointContents( self->r.currentOrigin, -1 );
	if ( !( contents & CONTENTS_NODROP )) {
		TossClientItems( self );
	}
	else {
		if ( self->client->ps.powerups[PW_NEUTRALFLAG] ) {		// only happens in One Flag CTF
			Team_ReturnFlag( TEAM_FREE );
		}
		else if ( self->client->ps.powerups[PW_REDFLAG] ) {		// only happens in standard CTF
			Team_ReturnFlag( TEAM_RED );
		}
		else if ( self->client->ps.powerups[PW_BLUEFLAG] ) {	// only happens in standard CTF
			Team_ReturnFlag( TEAM_BLUE );
		}
	}
#ifdef MISSIONPACK
	TossClientPersistantPowerups( self );
	if( g_gametype.integer == GT_HARVESTER ) {
		TossClientCubes( self );
	}
#endif

	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->s.weapon = WP_NONE;
	self->s.powerups = 0;
	self->r.contents = CONTENTS_CORPSE;

	self->s.angles[0] = 0;
	self->s.angles[2] = 0;
	LookAtKiller (self, inflictor, attacker);

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

	self->s.loopSound = 0;

	self->r.maxs[2] = -8;

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

	// 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) && g_blood.integer) || meansOfDeath == MOD_SUICIDE) {
		// gib death
		GibEntity( self, killer );
	} else {
		// normal death
		static int i;

		switch ( i ) {
		case 0:
			anim = BOTH_DEATH1;
			break;
		case 1:
			anim = BOTH_DEATH2;
			break;
		case 2:
		default:
			anim = BOTH_DEATH3;
			break;
		}

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

		self->client->ps.legsAnim = 
			( ( self->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
		self->client->ps.torsoAnim = 
			( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;

		G_AddEvent( self, EV_DEATH1 + i, killer );

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

		// globally cycle through the different death animations
		i = ( i + 1 ) % 3;

#ifdef MISSIONPACK
		if (self->s.eFlags & EF_KAMIKAZE) {
			Kamikaze_DeathTimer( self );
		}
#endif
	}

	trap_LinkEntity (self);

}
示例#18
0
/*
=================
ClientCommand
=================
*/
void ClientCommand (edict_t *ent)
{
	char	*cmd;

	if (!ent->client)
		return;		// not fully in game yet

	cmd = gi.argv(0);

	if (Q_stricmp (cmd, "players") == 0)
	{
		Cmd_Players_f (ent);
		return;
	}
	if (Q_stricmp (cmd, "say") == 0)
	{
		Cmd_Say_f (ent, false, false);
		return;
	}
	if (Q_stricmp (cmd, "say_team") == 0)
	{
		Cmd_Say_f (ent, true, false);
		return;
	}
	if (Q_stricmp (cmd, "score") == 0)
	{
		Cmd_Score_f (ent);
		return;
	}
	if (Q_stricmp (cmd, "help") == 0)
	{
		Cmd_Help_f (ent);
		return;
	}

	if (level.intermissiontime)
		return;

	if (Q_stricmp (cmd, "use") == 0)
		Cmd_Use_f (ent);
	else if (Q_stricmp (cmd, "drop") == 0)
		Cmd_Drop_f (ent);
	else if (Q_stricmp (cmd, "give") == 0)
		Cmd_Give_f (ent);
	else if (Q_stricmp (cmd, "god") == 0)
		Cmd_God_f (ent);
	else if (Q_stricmp (cmd, "notarget") == 0)
		Cmd_Notarget_f (ent);
	else if (Q_stricmp (cmd, "noclip") == 0)
		Cmd_Noclip_f (ent);
	else if (Q_stricmp(cmd, "angles") == 0)
	{
		gi.cprintf(ent, PRINT_HIGH, "Angles(YPR): %g %g %g\n", ent->s.angles[YAW],
			ent->s.angles[PITCH] * -3.0f, ent->s.angles[ROLL]);
		gi.cprintf(ent, PRINT_HIGH, "_sun_angle: %g %g\n", ent->s.angles[YAW] + 180.0f,
			ent->s.angles[PITCH] * 3.0f); // 1.831 - handy for mappers.
	}
	else if (Q_stricmp (cmd, "inven") == 0)
		Cmd_Inven_f (ent);
	else if (Q_stricmp (cmd, "invnext") == 0)
		SelectNextItem (ent, -1);
	else if (Q_stricmp (cmd, "invprev") == 0)
		SelectPrevItem (ent, -1);
	else if (Q_stricmp (cmd, "invnextw") == 0)
		SelectNextItem (ent, IT_WEAPON);
	else if (Q_stricmp (cmd, "invprevw") == 0)
		SelectPrevItem (ent, IT_WEAPON);
	else if (Q_stricmp (cmd, "invnextp") == 0)
		SelectNextItem (ent, IT_POWERUP);
	else if (Q_stricmp (cmd, "invprevp") == 0)
		SelectPrevItem (ent, IT_POWERUP);
	else if (Q_stricmp (cmd, "invuse") == 0)
		Cmd_InvUse_f (ent);
	else if (Q_stricmp (cmd, "invdrop") == 0)
		Cmd_InvDrop_f (ent);
	else if (Q_stricmp (cmd, "weapprev") == 0)
		Cmd_WeapPrev_f (ent);
	else if (Q_stricmp (cmd, "weapnext") == 0)
		Cmd_WeapNext_f (ent);
	else if (Q_stricmp (cmd, "weaplast") == 0)
		Cmd_WeapLast_f (ent);
	else if (Q_stricmp (cmd, "kill") == 0)
		Cmd_Kill_f (ent);
	else if (Q_stricmp (cmd, "putaway") == 0)
		Cmd_PutAway_f (ent);
	else if (Q_stricmp (cmd, "wave") == 0)
		Cmd_Wave_f (ent);
	else if (Q_stricmp(cmd, "playerlist") == 0)
		Cmd_PlayerList_f(ent);
	else	// anything that doesn't match a command will be a chat
		Cmd_Say_f (ent, false, true);
}