Beispiel #1
0
/*
==================
CG_SetInitialSnapshot

This will only happen on the very first snapshot, or
on tourney restarts.  All other times will use 
CG_TransitionSnapshot instead.

FIXME: Also called by map_restart?
==================
*/
void CG_SetInitialSnapshot( snapshot_t *snap ) {
	int				i;
	centity_t		*cent;
	entityState_t	*state;

	cg.snap = snap; 

	if ((cg_entities[snap->ps.clientNum].ghoul2 == NULL) && trap_G2_HaveWeGhoul2Models(cgs.clientinfo[snap->ps.clientNum].ghoul2Model))
	{
		trap_G2API_DuplicateGhoul2Instance(cgs.clientinfo[snap->ps.clientNum].ghoul2Model, &cg_entities[snap->ps.clientNum].ghoul2);
		CG_CopyG2WeaponInstance(FIRST_WEAPON, cg_entities[snap->ps.clientNum].ghoul2);
	}
	BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].currentState, qfalse );

	// sort out solid entities
	CG_BuildSolidList();

	CG_ExecuteNewServerCommands( snap->serverCommandSequence );

	// set our local weapon selection pointer to
	// what the server has indicated the current weapon is
	CG_Respawn();

	for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
		state = &cg.snap->entities[ i ];
		cent = &cg_entities[ state->number ];

		memcpy(&cent->currentState, state, sizeof(entityState_t));
		//cent->currentState = *state;
		cent->interpolate = qfalse;
		cent->currentValid = qtrue;

		if ( jk2startversion == VERSION_1_02 )
		{ // MVSDK: Version Magic!
			cent->currentState.torsoAnim = MV_MapAnimation104( cent->currentState.torsoAnim );
			cent->currentState.legsAnim = MV_MapAnimation104( cent->currentState.legsAnim );
		}

		CG_ResetEntity( cent );

		// check for events
		CG_CheckEvents( cent );
	}
}
Beispiel #2
0
/*
==================
CG_SetInitialSnapshot

This will only happen on the very first snapshot, or
on tourney restarts.  All other times will use 
CG_TransitionSnapshot instead.

FIXME: Also called by map_restart?
==================
*/
void CG_SetInitialSnapshot( snapshot_t *snap ) {
	int				i;
	centity_t		*cent;
	entityState_t	*state;

	cg.snap = snap; 

	if ((cg_entities[snap->ps.clientNum].ghoul2 == NULL) && trap_G2_HaveWeGhoul2Models(cgs.clientinfo[snap->ps.clientNum].ghoul2Model))
	{
		trap_G2API_DuplicateGhoul2Instance(cgs.clientinfo[snap->ps.clientNum].ghoul2Model, &cg_entities[snap->ps.clientNum].ghoul2);
		CG_CopyG2WeaponInstance(&cg_entities[snap->ps.clientNum], FIRST_WEAPON, cg_entities[snap->ps.clientNum].ghoul2);
		
		if (trap_G2API_AddBolt(cg_entities[snap->ps.clientNum].ghoul2, 0, "face") == -1)
		{ //check now to see if we have this bone for setting anims and such
			cg_entities[snap->ps.clientNum].noFace = qtrue;
		}
	}
	BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].currentState, qfalse );

	// sort out solid entities
	CG_BuildSolidList();

	CG_ExecuteNewServerCommands( snap->serverCommandSequence );

	// set our local weapon selection pointer to
	// what the server has indicated the current weapon is
	CG_Respawn();

	for ( i = 0 ; i < cg.snap->numEntities ; i++ ) {
		state = &cg.snap->entities[ i ];
		cent = &cg_entities[ state->number ];

		memcpy(&cent->currentState, state, sizeof(entityState_t));
		//cent->currentState = *state;
		cent->interpolate = qfalse;
		cent->currentValid = qtrue;

		CG_ResetEntity( cent );

		// check for events
		CG_CheckEvents( cent );
	}
}
void CG_KillCEntityInstances()
{
	int i = 0;

	while (i < MAX_GENTITIES)
	{
		if (i >= MAX_CLIENTS)
		{ //do not clear G2 instances on client ents, they are constant
			if (cg_entities[i].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[i].ghoul2))
			{
				trap_G2API_CleanGhoul2Models(&(cg_entities[i].ghoul2));
			}
		}
		/*
		else
		{ //we must do this, because otherwise after a map_restart it seems to return bad angles in matrices produced by GetBoltMatrix
			if (cgs.clientinfo[i].ghoul2Model || cg_entities[i].ghoul2)
			{
				CG_LoadClientInfo(&cgs.clientinfo[i]);

				if (cg_entities[i].ghoul2 != cgs.clientinfo[i].ghoul2Model)
				{
					if (cg_entities[i].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[i].ghoul2))
					{
						trap_G2API_CleanGhoul2Models(&(cg_entities[i].ghoul2));
					}

					trap_G2API_DuplicateGhoul2Instance(cgs.clientinfo[i].ghoul2Model, &cg_entities[i].ghoul2);
				}
			}
		}
		*/

		cg_entities[i].isATST = 0;
		cg_entities[i].atstFootClang = 0;
		cg_entities[i].atstSwinging = 0;
		cg_entities[i].bolt1 = 0;
		cg_entities[i].bolt2 = 0;
		cg_entities[i].bolt3 = 0;
		cg_entities[i].bolt4 = 0;

		cg_entities[i].saberLength = SABER_LENGTH_MAX;
		cg_entities[i].saberExtendTime = 0;

		cg_entities[i].boltInfo = 0;

		cg_entities[i].frame_minus1_refreshed = 0;
		cg_entities[i].frame_minus2_refreshed = 0;
		cg_entities[i].dustTrailTime = 0;
		cg_entities[i].ghoul2weapon = NULL;
//		cg_entities[i].torsoBolt = 0;
		cg_entities[i].trailTime = 0;
		cg_entities[i].frame_hold_time = 0;
		cg_entities[i].frame_hold_refreshed = 0;
		cg_entities[i].trickAlpha = 0;
		cg_entities[i].trickAlphaTime = 0;
		VectorClear(cg_entities[i].turAngles);
		cg_entities[i].weapon = 0;
		cg_entities[i].teamPowerEffectTime = 0;
		cg_entities[i].teamPowerType = 0;

		i++;
	}
}
/*
=================
CG_ServerCommand

The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
static void CG_ServerCommand( void ) {
	const char	*cmd;
	char		text[MAX_SAY_TEXT];

	cmd = CG_Argv(0);

	if ( !cmd[0] ) {
		// server claimed the command
		return;
	}

	if ( !strcmp( cmd, "spd" ) ) 
	{
		const char *ID;
		int holdInt,count,i;
		char string[1204];

		count = trap_Argc();

		ID =  CG_Argv(1);
		holdInt = atoi(ID);

		memset( &string, 0, sizeof( string ) );

		Com_sprintf( string,sizeof(string)," \"%s\"", (const char *) CG_Argv(2));

		for (i=3;i<count;i++)
		{
			Com_sprintf( string,sizeof(string)," %s \"%s\"", string, (const char *) CG_Argv(i));
		}

		trap_SP_Print(holdInt, (byte *)string);
		return;
	}

	if ( !strcmp( cmd, "nfr" ) )
	{ //"nfr" == "new force rank" (want a short string)
		int doMenu = 0;
		int setTeam = 0;
		int newRank = 0;

		if (trap_Argc() < 3)
		{
#ifdef _DEBUG
			Com_Printf("WARNING: Invalid newForceRank string\n");
#endif
			return;
		}

		newRank = atoi(CG_Argv(1));
		doMenu = atoi(CG_Argv(2));
		setTeam = atoi(CG_Argv(3));

		trap_Cvar_Set("ui_rankChange", va("%i", newRank));

		trap_Cvar_Set("ui_myteam", va("%i", setTeam));

		if (!( trap_Key_GetCatcher() & KEYCATCH_UI ) && doMenu)
		{
			trap_OpenUIMenu(3);
		}

		return;
	}

	if ( !strcmp( cmd, "kg2" ) )
	{ //Kill a ghoul2 instance in this slot.
	  //If it has been occupied since this message was sent somehow, the worst that can (should) happen
	  //is the instance will have to reinit with its current info.
		int indexNum = 0;
		int argNum = trap_Argc();
		int i = 1;
		
		if (argNum < 1)
		{
			return;
		}

		while (i < argNum)
		{
			indexNum = atoi(CG_Argv(i));

			if (cg_entities[indexNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[indexNum].ghoul2))
			{
				if (indexNum < MAX_CLIENTS)
				{ //You try to do very bad thing!
#ifdef _DEBUG
					Com_Printf("WARNING: Tried to kill a client ghoul2 instance with a kg2 command!\n");
#endif
					return;
				}
				trap_G2API_CleanGhoul2Models(&(cg_entities[indexNum].ghoul2));
			}

			i++;
		}
		
		return;
	}

	if ( !strcmp( cmd, "cp" ) ) {
		char strEd[MAX_STRIPED_SV_STRING];
		CG_CheckSVStripEdRef(strEd, CG_Argv(1));
		CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cs" ) ) {
		CG_ConfigStringModified();
		return;
	}

	if ( !strcmp( cmd, "print" ) ) {
		char strEd[MAX_STRIPED_SV_STRING];
		CG_CheckSVStripEdRef(strEd, CG_Argv(1));
		CG_Printf( "%s", strEd );
		return;
	}

	if ( !strcmp( cmd, "chat" ) ) {
		if ( !cg_teamChatsOnly.integer ) {
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
			Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
			CG_RemoveChatEscapeChar( text );
			CG_Printf( "%s\n", text );
		}
		return;
	}

	if ( !strcmp( cmd, "tchat" ) ) {
		trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
		CG_AddToTeamChat( text );
		CG_Printf( "%s\n", text );
		return;
	}
	if ( !strcmp( cmd, "vchat" ) ) {
		CG_VoiceChat( SAY_ALL );
		return;
	}

	if ( !strcmp( cmd, "vtchat" ) ) {
		CG_VoiceChat( SAY_TEAM );
		return;
	}

	if ( !strcmp( cmd, "vtell" ) ) {
		CG_VoiceChat( SAY_TELL );
		return;
	}

	if ( !strcmp( cmd, "scores" ) ) {
		CG_ParseScores();
		return;
	}

	if ( !strcmp( cmd, "tinfo" ) ) {
		CG_ParseTeamInfo();
		return;
	}

	if ( !strcmp( cmd, "map_restart" ) ) {
		CG_MapRestart();
		return;
	}

  if ( Q_stricmp (cmd, "remapShader") == 0 ) {
		if (trap_Argc() == 4) {
			trap_R_RemapShader(CG_Argv(1), CG_Argv(2), CG_Argv(3));
		}
	}

	// loaddeferred can be both a servercmd and a consolecmd
	if ( !strcmp( cmd, "loaddefered" ) ) {	// FIXME: spelled wrong, but not changing for demo
		CG_LoadDeferredPlayers();
		return;
	}

	// clientLevelShot is sent before taking a special screenshot for
	// the menu system during development
	if ( !strcmp( cmd, "clientLevelShot" ) ) {
		cg.levelShot = qtrue;
		return;
	}

	CG_Printf( "Unknown client game command: %s\n", cmd );
}
Beispiel #5
0
//frees all ghoul2 stuff and npc stuff from a centity -rww
void CG_KillCEntityG2(int entNum)
{
	int j;
	clientInfo_t *ci = NULL;
	centity_t *cent = &cg_entities[entNum];

	if (entNum < MAX_CLIENTS)
	{
		ci = &cgs.clientinfo[entNum];
	}
	else
	{
		ci = cent->npcClient;
	}

	if (ci)
	{
		if (ci == cent->npcClient)
		{ //never going to be != cent->ghoul2, unless cent->ghoul2 has already been removed (and then this ptr is not valid)
			ci->ghoul2Model = NULL;
		}
		else if (ci->ghoul2Model == cent->ghoul2)
		{
			ci->ghoul2Model = NULL;
		}
		else if (ci->ghoul2Model && trap_G2_HaveWeGhoul2Models(ci->ghoul2Model))
		{
			trap_G2API_CleanGhoul2Models(&ci->ghoul2Model);
			ci->ghoul2Model = NULL;
		}

		//Clean up any weapon instances for custom saber stuff
		j = 0;
		while (j < MAX_SABERS)
		{
			if (ci->ghoul2Weapons[j] && trap_G2_HaveWeGhoul2Models(ci->ghoul2Weapons[j]))
			{
				trap_G2API_CleanGhoul2Models(&ci->ghoul2Weapons[j]);
				ci->ghoul2Weapons[j] = NULL;
			}

			j++;
		}
	}

	if (cent->ghoul2 && trap_G2_HaveWeGhoul2Models(cent->ghoul2))
	{
		trap_G2API_CleanGhoul2Models(&cent->ghoul2);
		cent->ghoul2 = NULL;
	}

	if (cent->grip_arm && trap_G2_HaveWeGhoul2Models(cent->grip_arm))
	{
		trap_G2API_CleanGhoul2Models(&cent->grip_arm);
		cent->grip_arm = NULL;
	}

	if (cent->frame_hold && trap_G2_HaveWeGhoul2Models(cent->frame_hold))
	{
		trap_G2API_CleanGhoul2Models(&cent->frame_hold);
		cent->frame_hold = NULL;
	}

	if (cent->npcClient)
	{
		CG_DestroyNPCClient(&cent->npcClient);
	}

	cent->isRagging = qfalse; //just in case.
	cent->ikStatus = qfalse;

	cent->localAnimIndex = 0;
}
Beispiel #6
0
static void CG_ServerCommand( void ) {
	const char	*cmd;
	char		text[MAX_SAY_TEXT];
	qboolean	IRCG = qfalse;

	cmd = CG_Argv(0);

	if ( !cmd[0] ) {
		// server claimed the command
		return;
	}

#if 0
	// never seems to get used -Ste
	if ( !strcmp( cmd, "spd" ) ) 
	{
		const char *ID;
		int holdInt,count,i;
		char string[1204];

		count = trap_Argc();

		ID =  CG_Argv(1);
		holdInt = atoi(ID);

		memset( &string, 0, sizeof( string ) );

		Com_sprintf( string,sizeof(string)," \"%s\"", (const char *) CG_Argv(2));

		for (i=3;i<count;i++)
		{
			Com_sprintf( string,sizeof(string)," %s \"%s\"", string, (const char *) CG_Argv(i));
		}

		trap_SP_Print(holdInt, (byte *)string);
		return;
	}
#endif

	if (!strcmp(cmd, "sxd"))
	{ //siege extended data, contains extra info certain classes may want to know about other clients
        CG_ParseSiegeExtendedData();
		return;
	}

	if (!strcmp(cmd, "sb"))
	{ //siege briefing display
		CG_SiegeBriefingDisplay(atoi(CG_Argv(1)), 0);
		return;
	}

	if ( !strcmp( cmd, "scl" ) )
	{
		//if (!( trap_Key_GetCatcher() & KEYCATCH_UI ))
		//Well, I want it to come up even if the briefing display is up.
		{
			trap_OpenUIMenu(UIMENU_CLASSSEL); //UIMENU_CLASSSEL
		}
		return;
	}

	if ( !strcmp( cmd, "spc" ) )
	{
		trap_Cvar_Set("ui_myteam", "3");
		trap_OpenUIMenu(UIMENU_PLAYERCONFIG); //UIMENU_CLASSSEL
		return;
	}

	if ( !strcmp( cmd, "nfr" ) )
	{ //"nfr" == "new force rank" (want a short string)
		int doMenu = 0;
		int setTeam = 0;
		int newRank = 0;

		if (trap_Argc() < 3)
		{
#ifdef _DEBUG
			Com_Printf("WARNING: Invalid newForceRank string\n");
#endif
			return;
		}

		newRank = atoi(CG_Argv(1));
		doMenu = atoi(CG_Argv(2));
		setTeam = atoi(CG_Argv(3));

		trap_Cvar_Set("ui_rankChange", va("%i", newRank));

		trap_Cvar_Set("ui_myteam", va("%i", setTeam));

		if (!( trap_Key_GetCatcher() & KEYCATCH_UI ) && doMenu)
		{
			trap_OpenUIMenu(UIMENU_PLAYERCONFIG);
		}

		return;
	}

	if ( !strcmp( cmd, "kg2" ) )
	{ //Kill a ghoul2 instance in this slot.
	  //If it has been occupied since this message was sent somehow, the worst that can (should) happen
	  //is the instance will have to reinit with its current info.
		int indexNum = 0;
		int argNum = trap_Argc();
		int i = 1;
		
		if (argNum < 1)
		{
			return;
		}

		while (i < argNum)
		{
			indexNum = atoi(CG_Argv(i));

			if (cg_entities[indexNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[indexNum].ghoul2))
			{
				if (indexNum < MAX_CLIENTS)
				{ //You try to do very bad thing!
#ifdef _DEBUG
					Com_Printf("WARNING: Tried to kill a client ghoul2 instance with a kg2 command!\n");
#endif
					return;
				}

				CG_KillCEntityG2(indexNum);
			}

			i++;
		}
		
		return;
	}

	if (!strcmp(cmd, "kls"))
	{ //kill looping sounds
		int indexNum = 0;
		int argNum = trap_Argc();
		centity_t *clent = NULL;
		centity_t *trackerent = NULL;
		
		if (argNum < 1)
		{
			assert(0);
			return;
		}

		indexNum = atoi(CG_Argv(1));

		if (indexNum != -1)
		{
			clent = &cg_entities[indexNum];
		}

		if (argNum >= 2)
		{
			indexNum = atoi(CG_Argv(2));

			if (indexNum != -1)
			{
				trackerent = &cg_entities[indexNum];
			}
		}

		if (clent)
		{
			CG_S_StopLoopingSound(clent->currentState.number, -1);
		}
		if (trackerent)
		{
			CG_S_StopLoopingSound(trackerent->currentState.number, -1);
		}

		return;
	}

	if (!strcmp(cmd, "ircg"))
	{ //this means param 2 is the body index and we want to copy to bodyqueue on it
		IRCG = qtrue;
	}

	if (!strcmp(cmd, "rcg") || IRCG)
	{ //rcg - Restore Client Ghoul (make sure limbs are reattached and ragdoll state is reset - this must be done reliably)
		int indexNum = 0;
		int argNum = trap_Argc();
		centity_t *clent;
		
		if (argNum < 1)
		{
			assert(0);
			return;
		}

		indexNum = atoi(CG_Argv(1));
		if (indexNum < 0 || indexNum >= MAX_CLIENTS)
		{
			assert(0);
			return;
		}

		clent = &cg_entities[indexNum];

		//assert(clent->ghoul2);
		if (!clent->ghoul2)
		{ //this can happen while connecting as a client
			return;
		}

#ifdef _DEBUG
		if (!trap_G2_HaveWeGhoul2Models(clent->ghoul2))
		{
			assert(!"Tried to reset state on a bad instance. Crash is inevitable.");
		}
#endif

		if (IRCG)
		{
			int bodyIndex = 0;
			int weaponIndex = 0;
			int side = 0;
			centity_t *body;

			assert(argNum >= 3);
			bodyIndex = atoi(CG_Argv(2));
			weaponIndex = atoi(CG_Argv(3));
			side = atoi(CG_Argv(4));

			body = &cg_entities[bodyIndex];

			if (side)
			{
				body->teamPowerType = qtrue; //light side
			}
			else
			{
				body->teamPowerType = qfalse; //dark side
			}

			CG_BodyQueueCopy(body, clent->currentState.number, weaponIndex);
		}

		//reattach any missing limbs
		if (clent->torsoBolt)
		{
			CG_ReattachLimb(clent);
		}

		//make sure ragdoll state is reset
		if (clent->isRagging)
		{
			clent->isRagging = qfalse;
			trap_G2API_SetRagDoll(clent->ghoul2, NULL); //calling with null parms resets to no ragdoll.
		}
		
		//clear all the decals as well
		trap_G2API_ClearSkinGore(clent->ghoul2);

		clent->weapon = 0;
		clent->ghoul2weapon = NULL; //force a weapon reinit

		return;
	}

	if ( !strcmp( cmd, "cp" ) ) {
		char strEd[MAX_STRINGED_SV_STRING];
		CG_CheckSVStringEdRef(strEd, CG_Argv(1));
		CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cps" ) ) {
		char strEd[MAX_STRINGED_SV_STRING];
		char *x = (char *)CG_Argv(1);
		if (x[0] == '@')
		{
			x++;
		}
		trap_SP_GetStringTextString(x, strEd, MAX_STRINGED_SV_STRING);
		CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.20, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cs" ) ) {
		CG_ConfigStringModified();
		return;
	}

	if ( !strcmp( cmd, "print" ) ) {
		char strEd[MAX_STRINGED_SV_STRING];
		CG_CheckSVStringEdRef(strEd, CG_Argv(1));
		CG_Printf( "%s", strEd );
		return;
	}

	if ( !strcmp( cmd, "chat" ) ) {
		if ( !cg_teamChatsOnly.integer ) {
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
			Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
			CG_RemoveChatEscapeChar( text );
			CG_ChatBox_AddString(text);
			CG_Printf( "*%s\n", text );
		}
		return;
	}

	if ( !strcmp( cmd, "tchat" ) ) {
		trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
		CG_ChatBox_AddString(text);
		CG_Printf( "*%s\n", text );

		return;
	}

	//chat with location, possibly localized.
	if ( !strcmp( cmd, "lchat" ) ) {
		if ( !cg_teamChatsOnly.integer ) {
			char name[MAX_STRING_CHARS];
			char loc[MAX_STRING_CHARS];
			char color[8];
			char message[MAX_STRING_CHARS];

			if (trap_Argc() < 4)
			{
				return;
			}

			strcpy(name, CG_Argv(1));
			strcpy(loc, CG_Argv(2));
			strcpy(color, CG_Argv(3));
			strcpy(message, CG_Argv(4));

			if (loc[0] == '@')
			{ //get localized text
				trap_SP_GetStringTextString(loc+1, loc, MAX_STRING_CHARS);
			}

			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
			//Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
			Com_sprintf(text, MAX_SAY_TEXT, "%s<%s>^%s%s", name, loc, color, message);
			CG_RemoveChatEscapeChar( text );
			CG_ChatBox_AddString(text);
			CG_Printf( "*%s\n", text );
		}
		return;
	}
	if ( !strcmp( cmd, "ltchat" ) ) {
		char name[MAX_STRING_CHARS];
		char loc[MAX_STRING_CHARS];
		char color[8];
		char message[MAX_STRING_CHARS];

		if (trap_Argc() < 4)
		{
			return;
		}

		strcpy(name, CG_Argv(1));
		strcpy(loc, CG_Argv(2));
		strcpy(color, CG_Argv(3));
		strcpy(message, CG_Argv(4));

		if (loc[0] == '@')
		{ //get localized text
			trap_SP_GetStringTextString(loc+1, loc, MAX_STRING_CHARS);
		}

		trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		//Q_strncpyz( text, CG_Argv(1), MAX_SAY_TEXT );
		Com_sprintf(text, MAX_SAY_TEXT, "%s<%s> ^%s%s", name, loc, color, message);
		CG_RemoveChatEscapeChar( text );
		CG_ChatBox_AddString(text);
		CG_Printf( "*%s\n", text );

		return;
	}

	if ( !strcmp( cmd, "scores" ) ) {
		CG_ParseScores();
		return;
	}

	if ( !strcmp( cmd, "tinfo" ) ) {
		CG_ParseTeamInfo();
		return;
	}

	if ( !strcmp( cmd, "map_restart" ) ) {
		CG_MapRestart();
		return;
	}

  if ( Q_stricmp (cmd, "remapShader") == 0 ) {
		if (trap_Argc() == 4) {
			trap_R_RemapShader(CG_Argv(1), CG_Argv(2), CG_Argv(3));
		}
	}

	// loaddeferred can be both a servercmd and a consolecmd
	if ( !strcmp( cmd, "loaddefered" ) ) {	// FIXME: spelled wrong, but not changing for demo
		CG_LoadDeferredPlayers();
		return;
	}

	// clientLevelShot is sent before taking a special screenshot for
	// the menu system during development
	if ( !strcmp( cmd, "clientLevelShot" ) ) {
		cg.levelShot = qtrue;
		return;
	}

	CG_Printf( "Unknown client game command: %s\n", cmd );
}
Beispiel #7
0
void SetupGameGhoul2Model(gclient_t *client, char *modelname)
{
	int handle;
	char		afilename[MAX_QPATH];
	char		/**GLAName,*/ *slash;
	char		GLAName[MAX_QPATH];
	vec3_t	tempVec = {0,0,0};

	// First things first.  If this is a ghoul2 model, then let's make sure we demolish this first.
	if (client->ghoul2 && trap_G2_HaveWeGhoul2Models(client->ghoul2))
	{
		trap_G2API_CleanGhoul2Models(&(client->ghoul2));
	}

	/*
	Com_sprintf( afilename, sizeof( afilename ), "models/players/%s/model.glm", modelname );
	handle = trap_G2API_InitGhoul2Model(&client->ghoul2, afilename, 0, 0, -20, 0, 0);
	if (handle<0)
	{
		Com_sprintf( afilename, sizeof( afilename ), "models/players/kyle/model.glm" );
		handle = trap_G2API_InitGhoul2Model(&client->ghoul2, afilename, 0, 0, -20, 0, 0);

		if (handle<0)
		{
			return;
		}
	}
	*/

	//rww - just load the "standard" model for the server"
	if (!precachedKyle)
	{
		Com_sprintf( afilename, sizeof( afilename ), "models/players/kyle/model.glm" );
		handle = trap_G2API_InitGhoul2Model(&precachedKyle, afilename, 0, 0, -20, 0, 0);

		if (handle<0)
		{
			return;
		}
	}

	if (precachedKyle && trap_G2_HaveWeGhoul2Models(precachedKyle))
	{
		trap_G2API_DuplicateGhoul2Instance(precachedKyle, &client->ghoul2);
	}
	else
	{
		return;
	}

	// The model is now loaded.

	GLAName[0] = 0;

	if (!BGPAFtextLoaded)
	{
		//get the location of the animation.cfg
		//GLAName = trap_G2API_GetGLAName( client->ghoul2, 0);
		trap_G2API_GetGLAName( client->ghoul2, 0, GLAName);

		if (!GLAName[0])
		{
			if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg"))
			{
				Com_Printf( "Failed to load animation file %s\n", afilename );
				return;
			}
			return;
		}
		Q_strncpyz( afilename, GLAName, sizeof( afilename ));
		slash = Q_strrchr( afilename, '/' );
		if ( slash )
		{
			strcpy(slash, "/animation.cfg");
		}	// Now afilename holds just the path to the animation.cfg
		else 
		{	// Didn't find any slashes, this is a raw filename right in base (whish isn't a good thing)
			return;
		}

		// Try to load the animation.cfg for this model then.
		if ( !BG_ParseAnimationFile( afilename ) )
		{	// The GLA's animations failed
			if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg"))
			{
				Com_Printf( "Failed to load animation file %s\n", afilename );
				return;
			}
		}
	}

	trap_G2API_AddBolt(client->ghoul2, 0, "*r_hand");
	trap_G2API_AddBolt(client->ghoul2, 0, "*l_hand");

	// NOTE - ensure this sequence of bolt and bone accessing are always the same because the client expects them in a certain order
	trap_G2API_SetBoneAnim(client->ghoul2, 0, "model_root", 0, 12, BONE_ANIM_OVERRIDE_LOOP, 1.0f, level.time, -1, -1);
	trap_G2API_SetBoneAngles(client->ghoul2, 0, "upper_lumbar", tempVec, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, NULL, 0, level.time);
	trap_G2API_SetBoneAngles(client->ghoul2, 0, "cranium", tempVec, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, NULL, 0, level.time);

	if (!g2SaberInstance)
	{
		trap_G2API_InitGhoul2Model(&g2SaberInstance, "models/weapons2/saber/saber_w.glm", 0, 0, -20, 0, 0);

		if (g2SaberInstance)
		{
			// indicate we will be bolted to model 0 (ie the player) on bolt 0 (always the right hand) when we get copied
			trap_G2API_SetBoltInfo(g2SaberInstance, 0, 0);
			// now set up the gun bolt on it
			trap_G2API_AddBolt(g2SaberInstance, 0, "*flash");
		}
	}

	if (g2SaberInstance)
	{
		trap_G2API_CopySpecificGhoul2Model(g2SaberInstance, 0, client->ghoul2, 1); 
	}
}
void JKG_DrawWeaponHolsters( centity_t *cent, refEntity_t legs, float shadowPlane )
{
    if (cent->currentState.weapon > 0  // UQ1: Issues with weapon 0???
            && !(cent->currentState.number == cg.predictedPlayerState.clientNum && !cg.renderingThirdPerson)
            && cent->currentState.number == cg.clientNum // UQ1: Enemy ones??? Best data transfer method???
            && (cent && cent->ghoul2 && cent->currentState.eType != ET_NPC))
    {
        int				HOLSTER_POINT = 0;
        int				NUM_HOLSTERS = 5; // UQ1: Extra 2 look stupid...
        int				i = 0;
        cgItemData_t	*LIGHT_ITEMS_LIST[5];
        cgItemData_t	*HEAVY_ITEMS_LIST[5];
        int				NUM_LIGHT_ITEMS = 0;
        int				NUM_HEAVY_ITEMS = 0;

#ifdef _DEBUG
        //CG_Printf("Adding holster items...\n");
#endif //_DEBUG

        for (i = 0; i < 3; i++) LIGHT_ITEMS_LIST[i] = NULL;
        for (i = 0; i < 2; i++) HEAVY_ITEMS_LIST[i] = NULL;

        // Create Light Items List...
        for (i = 0; i < MAX_ACI_SLOTS; i++)
        {
            unsigned int weap, var;

            // FIXME: How to get enemy player ACI list????
            //        Events? Even the data for just 4 holsters would be crazy...
            if (cg.playerACI[i] < 0) continue;

            if (cg.playerInventory[cg.playerACI[i]].id->weapon == cg.predictedPlayerState.weapon) continue;
            if (cg.playerInventory[cg.playerACI[i]].equipped) continue;
            if (!cg.playerInventory[cg.playerACI[i]].id) continue;

            weap = cg.playerInventory[cg.playerACI[i]].id->weapon;
            var = cg.playerInventory[cg.playerACI[i]].id->variation;

            // How did this get through equipped above???
            if (weap == cent->currentState.weapon) continue;

            // Quick and dirty choice of where to put guns based on weight...
            if (cg.playerInventory[cg.playerACI[i]].id->weight > 1) continue; // Too heavy for waist...

            // FIXME: Sort by new WEAPON_TYPE value...
            LIGHT_ITEMS_LIST[NUM_LIGHT_ITEMS] = cg.playerInventory[cg.playerACI[i]].id;
            NUM_LIGHT_ITEMS++;

            if (NUM_LIGHT_ITEMS >= 3) break; // Full...
        }

        // Create Heavy Items List...
        for (i = 0; i < MAX_ACI_SLOTS; i++)
        {
            unsigned int weap, var;

            // FIXME: How to get enemy player ACI list????
            //        Events? Even the data for just 4 holsters would be crazy...
            if (cg.playerACI[i] < 0) continue;

            if (cg.playerInventory[cg.playerACI[i]].equipped) continue;
            if (!cg.playerInventory[cg.playerACI[i]].id) continue;

            weap = cg.playerInventory[cg.playerACI[i]].id->weapon;
            var = cg.playerInventory[cg.playerACI[i]].id->variation;

            // How did this get through equipped above???
            if (weap == cent->currentState.weapon) continue;

            // Quick and dirty choice of where to put guns based on weight...
            if (cg.playerInventory[cg.playerACI[i]].id->weight <= 1) continue; // Too light for back...

            // FIXME: Sort by new WEAPON_TYPE value...
            HEAVY_ITEMS_LIST[NUM_HEAVY_ITEMS] = cg.playerInventory[cg.playerACI[i]].id;
            NUM_HEAVY_ITEMS++;

            if (NUM_HEAVY_ITEMS >= 2) break; // Full...
        }

        for(HOLSTER_POINT = 0; HOLSTER_POINT < NUM_HOLSTERS; HOLSTER_POINT++)
        {
            void			*weaponGhoul2 = NULL;
            refEntity_t		holsterRefEnt;
            int				WEAPON_NUM = 0;
            weaponInfo_t	*weapon = NULL;

            if (HOLSTER_POINT == 0 && NUM_LIGHT_ITEMS < 1) continue; // No more light items to draw...
            if (HOLSTER_POINT == 1 && NUM_LIGHT_ITEMS < 2) continue; // No more light items to draw...
            //if (HOLSTER_POINT == 2 && NUM_LIGHT_ITEMS < 3) continue; // No more light items to draw...
            if (HOLSTER_POINT == 2) continue; // Disabled...
            if (HOLSTER_POINT == 3 && NUM_HEAVY_ITEMS < 1) continue; // No more heavy items to draw...
            if (HOLSTER_POINT == 4 && NUM_HEAVY_ITEMS < 2) continue; // No more heavy items to draw...


            if (HOLSTER_POINT < 3)
            {
                if (LIGHT_ITEMS_LIST[HOLSTER_POINT])
                {   // Light Items (waist)...
                    WEAPON_NUM = LIGHT_ITEMS_LIST[HOLSTER_POINT]->weapon;

                    if (WEAPON_NUM <= 0) continue;

                    weapon = CG_WeaponInfo (WEAPON_NUM, LIGHT_ITEMS_LIST[HOLSTER_POINT]->variation);
                }
                else
                {
                    continue;
                }
            }
            else
            {
                if (HEAVY_ITEMS_LIST[HOLSTER_POINT-3])
                {   // Heavy Items (back)...
                    WEAPON_NUM = HEAVY_ITEMS_LIST[HOLSTER_POINT-3]->weapon;

                    if (WEAPON_NUM <= 0) continue;

                    weapon = CG_WeaponInfo (WEAPON_NUM, HEAVY_ITEMS_LIST[HOLSTER_POINT-3]->variation);
                }
                else
                {
                    continue;
                }
            }

            if (!weapon) continue;

            memset( &holsterRefEnt, 0, sizeof( holsterRefEnt ) );

            weaponGhoul2 = weapon->g2WorldModel;

            if (trap_G2_HaveWeGhoul2Models(weaponGhoul2))
            {
                char bone_name[MAX_QPATH];
                vec3_t	holsterAngles, end, fwd, rt, originalOrigin;

                // UQ1: Which bone are we using?
                if (HOLSTER_POINT == 0) Q_strncpyz( bone_name , "pelvis", sizeof( bone_name ) );
                if (HOLSTER_POINT == 1) Q_strncpyz( bone_name , "pelvis", sizeof( bone_name ) );
                if (HOLSTER_POINT == 2) Q_strncpyz( bone_name , "thoracic", sizeof( bone_name ) );
                if (HOLSTER_POINT == 3) Q_strncpyz( bone_name , "thoracic", sizeof( bone_name ) );
                if (HOLSTER_POINT == 4) Q_strncpyz( bone_name , "thoracic", sizeof( bone_name ) );
                //if (HOLSTER_POINT == 4) Q_strncpyz( bone_name , "ltibia", sizeof( bone_name ) ); // UQ1: These look really dumb....
                //if (HOLSTER_POINT == 5) Q_strncpyz( bone_name , "rtibia", sizeof( bone_name ) ); // UQ1: These look really dumb....

                // UQ1: Set exact org/angles for this bone...
                if (!CG_SnapRefEntToBone(cent, &holsterRefEnt, bone_name))
                {
#ifdef _DEBUG
                    CG_Printf("Holster point %i NOT drawn (snap to bone issue)...\n", HOLSTER_POINT);
                    assert(0);
#endif //

                    continue;
                }

                VectorCopy( legs.modelScale, holsterRefEnt.modelScale);
                holsterRefEnt.radius = legs.radius;

                VectorCopy(holsterRefEnt.origin, originalOrigin);
                VectorCopy(cent->lerpAngles, holsterAngles);
                holsterAngles[PITCH] = 0;
                holsterAngles[ROLL] = 0;

                AngleVectors( holsterAngles, fwd, rt, NULL );

                // UQ1: Now modify the org/angles...
                switch (HOLSTER_POINT)
                {
                case 0:
                    // "pelvis" left
                    VectorMA( originalOrigin, -2, fwd, end );
                    VectorMA( end, -6, rt, end );
                    VectorCopy(end, holsterRefEnt.origin);

                    holsterRefEnt.origin[2] += 8; // because the bones suck for placement...

                    //AxisToAngles(holsterRefEnt.axis, holsterAngles);

                    holsterAngles[PITCH] += 90;
                    //holsterAngles[YAW] -= 90;
                    holsterAngles[ROLL] += 90;

                    holsterAngles[PITCH] += 30;
                    holsterAngles[YAW] -= 50;
                    holsterAngles[ROLL] -= 50;

                    break;
                case 1:
                    // "pelvis" right
                    VectorMA( originalOrigin, -2, fwd, end );
                    VectorMA( end, 6, rt, end );
                    VectorCopy(end, holsterRefEnt.origin);

                    holsterRefEnt.origin[2] += 8; // because the bones suck for placement...

                    //AxisToAngles(holsterRefEnt.axis, holsterAngles);

                    holsterAngles[PITCH] += 90;
                    holsterAngles[YAW] += 180;
                    holsterAngles[ROLL] += 90;

                    holsterAngles[PITCH] -= 30;
                    holsterAngles[YAW] += 50;
                    holsterAngles[ROLL] += 50;

                    break;
                case 2:
                    // "thoracic" left - used for center pistol - where on the back is this meant to fit???
                    VectorMA( originalOrigin, -4, fwd, end );
                    VectorMA( end, -2, rt, end );
                    VectorCopy(end, holsterRefEnt.origin);

                    holsterRefEnt.origin[2] += 8; // because the bones suck for placement...

                    //AxisToAngles(holsterRefEnt.axis, holsterAngles);

                    holsterAngles[PITCH] += 90;
                    //holsterAngles[YAW] -= 90;
                    holsterAngles[ROLL] += 90;

                    holsterAngles[PITCH] += 10;//d_poff.value;
                    holsterAngles[YAW] += 0;//d_yoff.value;
                    holsterAngles[ROLL] += 0;//d_roff.value;

                    break;
                case 3:
                    // "thoracic" left
                    VectorMA( originalOrigin, -4, fwd, end );
                    VectorMA( end, -6, rt, end );
                    VectorCopy(end, holsterRefEnt.origin);

                    holsterRefEnt.origin[2] += 6; // because the bones suck for placement...

                    //AxisToAngles(holsterRefEnt.axis, holsterAngles);

                    holsterAngles[PITCH] += 90;
                    //holsterAngles[YAW] -= 90;
                    holsterAngles[ROLL] += 90;

                    holsterAngles[PITCH] += 10 + 25;
                    holsterAngles[YAW] += 50 + 15;
                    holsterAngles[ROLL] += 50;

                    break;
                case 4:
                    // "thoracic" right
                    VectorMA( originalOrigin, -4, fwd, end );
                    VectorMA( end, 6, rt, end );
                    VectorCopy(end, holsterRefEnt.origin);

                    holsterRefEnt.origin[2] += 6; // because the bones suck for placement...

                    //AxisToAngles(holsterRefEnt.axis, holsterAngles);

                    holsterAngles[PITCH] += 90;
                    holsterAngles[YAW] += 180;
                    holsterAngles[ROLL] += 90;

                    holsterAngles[PITCH] -= 10 + 25;
                    holsterAngles[YAW] -= 50 + 15;
                    holsterAngles[ROLL] -= 50;

                    break;
                /*case 5: // UQ1: These look really dumb....
                	// "ltibia"
                	VectorMA( originalOrigin, -4, fwd, end );
                	VectorMA( end, -4, rt, end );
                	VectorCopy(end, holsterRefEnt.origin);

                	holsterRefEnt.origin[2] += 8; // because the bones suck for placement...

                	holsterAngles[PITCH] += 90;
                	//holsterAngles[YAW] -= 90;
                	holsterAngles[ROLL] += 90;

                	holsterAngles[PITCH] -= d_poff.value;
                	holsterAngles[YAW] -= d_yoff.value;
                	holsterAngles[ROLL] -= d_roff.value;
                	break;
                case 6:  // UQ1: These look really dumb....
                	// "rtibia"
                	VectorMA( originalOrigin, -4, fwd, end );
                	VectorMA( end, 4, rt, end );
                	VectorCopy(end, holsterRefEnt.origin);

                	holsterRefEnt.origin[2] += 8; // because the bones suck for placement...

                	holsterAngles[PITCH] += 90;
                	holsterAngles[YAW] += 180;
                	holsterAngles[ROLL] += 90;

                	holsterAngles[PITCH] += d_poff.value;
                	holsterAngles[YAW] += d_yoff.value;
                	holsterAngles[ROLL] += d_roff.value;
                	break;*/
                default:
                    continue; // should never see this...
                    break;
                }

                holsterRefEnt.reType = RT_MODEL;
                holsterRefEnt.hModel = 0;
                holsterRefEnt.ghoul2 = weaponGhoul2;
                AnglesToAxis(holsterAngles, holsterRefEnt.axis);

                holsterRefEnt.shadowPlane = shadowPlane;

                CG_AddWeaponWithPowerups( &holsterRefEnt, cent->currentState.powerups );
#ifdef _DEBUG
                //CG_Printf("Holster point %i drawn at %f %f %f (P.ORG %f %f %f)...\n", HOLSTER_POINT, holsterRefEnt.origin[0], holsterRefEnt.origin[1], holsterRefEnt.origin[2], cent->lerpOrigin[0], cent->lerpOrigin[1], cent->lerpOrigin[2]);
#endif //_DEBUG
            }
#ifdef _DEBUG
            else
            {
                //CG_Printf("Holster point %i NOT drawn...\n", HOLSTER_POINT);
                //assert(0);
            }
#endif //_DEBUG
        }
    }
}