static void CG_RestoreClientGhoul_f( void ) { //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->Cmd_Argc(); centity_t *clent; qboolean IRCG = qfalse; if ( !strcmp( CG_Argv( 0 ), "ircg" ) ) IRCG = qtrue; 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 ); //this can happen while connecting as a client if ( !clent->ghoul2 ) 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 }
static void CG_BodyQueueCopy(centity_t *cent, int clientNum, int knownWeapon) { centity_t *source; animation_t *anim; float animSpeed; int flags=BONE_ANIM_OVERRIDE_FREEZE; if (cent->ghoul2) { trap->G2API_CleanGhoul2Models(¢->ghoul2); } if (clientNum < 0 || clientNum >= MAX_CLIENTS) { return; } source = &cg_entities[ clientNum ]; if (!source) { return; } if (!source->ghoul2) { return; } cent->isRagging = qfalse; //reset in case it's still set from another body that was in this cent slot. cent->ownerRagging = source->isRagging; //if the owner was in ragdoll state, then we want to go into it too right away. #if 0 VectorCopy(source->lerpOriginOffset, cent->lerpOriginOffset); #endif cent->bodyFadeTime = 0; cent->bodyHeight = 0; cent->dustTrailTime = source->dustTrailTime; trap->G2API_DuplicateGhoul2Instance(source->ghoul2, ¢->ghoul2); if (source->isRagging) { //just reset it now. source->isRagging = qfalse; trap->G2API_SetRagDoll(source->ghoul2, NULL); //calling with null parms resets to no ragdoll. } //either force the weapon from when we died or remove it if it was a dropped weapon if (knownWeapon > WP_BRYAR_PISTOL && trap->G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 1)) { trap->G2API_RemoveGhoul2Model(&(cent->ghoul2), 1); } else if (trap->G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 1)) { trap->G2API_CopySpecificGhoul2Model(CG_G2WeaponInstance(cent, knownWeapon), 0, cent->ghoul2, 1); } if (!cent->ownerRagging) { int aNum; int eFrame; qboolean fallBack = qfalse; //anim = &bgAllAnims[cent->localAnimIndex].anims[ cent->currentState.torsoAnim ]; if (!BG_InDeathAnim(source->currentState.torsoAnim)) { //then just snap the corpse into a default anim = &bgAllAnims[source->localAnimIndex].anims[ BOTH_DEAD1 ]; fallBack = qtrue; } else { anim = &bgAllAnims[source->localAnimIndex].anims[ source->currentState.torsoAnim ]; } animSpeed = 50.0f / anim->frameLerp; if (!fallBack) { //this will just set us to the last frame of the animation, in theory aNum = cgs.clientinfo[source->currentState.number].frame+1; while (aNum >= anim->firstFrame+anim->numFrames) { aNum--; } if (aNum < anim->firstFrame-1) { //wrong animation...? aNum = (anim->firstFrame+anim->numFrames)-1; } } else { aNum = anim->firstFrame; } eFrame = anim->firstFrame + anim->numFrames; //if (!cgs.clientinfo[source->currentState.number].frame || (cent->currentState.torsoAnim) != (source->currentState.torsoAnim) ) //{ // aNum = (anim->firstFrame+anim->numFrames)-1; //} trap->G2API_SetBoneAnim(cent->ghoul2, 0, "upper_lumbar", aNum, eFrame, flags, animSpeed, cg.time, -1, 150); trap->G2API_SetBoneAnim(cent->ghoul2, 0, "model_root", aNum, eFrame, flags, animSpeed, cg.time, -1, 150); trap->G2API_SetBoneAnim(cent->ghoul2, 0, "Motion", aNum, eFrame, flags, animSpeed, cg.time, -1, 150); } //After we create the bodyqueue, regenerate any limbs on the real instance if (source->torsoBolt) { CG_ReattachLimb(source); } }
static void CG_ServerCommand( void ) { const char *cmd; char text[MAX_NOTIFICATION_CHARS]; // extra bytes for name qboolean IRCG = qfalse; cmd = CG_Argv(0); if ( !cmd[0] ) { // server claimed the command return; } // Jedi Knight Galaxies // Check the crossover if ( uiImports->HandleServerCommand( cmd ) ) return; if (!strcmp(cmd, "svr")) { // Server redirect CG_ServerRedirect(); return; } if (!strcmp(cmd, "cin")) { Cin_ProcessCinematic_f(); return; } if (!strcmp(cmd, "cinb")) { Cin_ProcessCinematicBinary_f(); return; } if (!strcmp(cmd, "cb")) { CinBuild_Cmd_f(); return; } if (!strcmp(cmd, "cbb")) { Cmd_CBB_f(); return; } if (!strcmp(cmd, "dc")) { cg.deathcamFadeStart = cg.time; cg.deathcamTime = atoi(_Cmd_Argv(1)); cg.deathcamRadius = atoi(_Cmd_Argv(2)); VectorSet(cg.deathcamCenter, atof(_Cmd_Argv(3)),atof(_Cmd_Argv(4)),atof(_Cmd_Argv(5))); ChatBox_CloseChat(); return; } if (!strcmp(cmd, "dcr")) { cg.deathcamFadeStart = 0; cg.deathcamTime = 0; cg.deathcamRadius = 0; VectorSet(cg.deathcamCenter, 0, 0, 0); return; } // Forced weapon change if (!strcmp(cmd, "chw")) { cg.weaponSelect = atoi(CG_Argv(1)); return; } if (!strcmp(cmd, "clearinv")) { cg.playerInventory->clear(); 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->Cmd_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->Cmd_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->Cmd_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; } //eezstreet add if ( !strcmp (cmd, "aciset") ) { int number = atoi(CG_Argv(1)); cg.weaponSelect = number; return; } if ( !strcmp (cmd, "ieq") ) { if ( trap->Cmd_Argc() == 3 ) { int newItem = atoi (CG_Argv (1)); int oldItem = atoi (CG_Argv (2)); (*cg.playerInventory)[newItem].equipped = true; if (oldItem != -1) { (*cg.playerInventory)[oldItem].equipped = false; } uiImports->InventoryNotify( INVENTORYNOTIFY_UPDATE ); } return; } if ( !strcmp (cmd, "iueq") ) { if ( trap->Cmd_Argc() == 2 ) { int slot = atoi (CG_Argv (1)); (*cg.playerInventory)[slot].equipped = false; uiImports->InventoryNotify( INVENTORYNOTIFY_UPDATE ); } return; } if ( !strcmp (cmd, "inventory_update") ) { cg.predictedPlayerState.credits = atoi(CG_Argv(1)); uiImports->InventoryNotify (INVENTORYNOTIFY_UPDATE); return; } if(!strcmp(cmd, "frcaci")) { // Force ACI JKG_CG_FillACISlot(atoi(CG_Argv(0)), atoi(CG_Argv(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->Cmd_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 weaponVariation = 0; int side = 0; centity_t *body; assert(argNum >= 4); bodyIndex = atoi(CG_Argv(2)); weaponIndex = atoi(CG_Argv(3)); weaponVariation = atoi (CG_Argv (4)); side = atoi(CG_Argv(5)); body = &cg_entities[bodyIndex]; if (side) { body->teamPowerType = qtrue; //light side } else { body->teamPowerType = qfalse; //dark side } CG_BodyQueueCopy(body, clent->currentState.number, weaponIndex, weaponVariation); } //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->SE_GetStringTextString(x, strEd, MAX_STRINGED_SV_STRING); CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); return; } if ( !strcmp( cmd, "cs" ) ) { CG_ConfigStringModified(); return; } // Warzone Tickets... if ( !strcmp( cmd, "tkt" ) ) { //CG_Printf("CG_Argv(0) = %s. CG_Argv(1) = %s. CG_Argv(2) = %s. CG_Argv(3) = %s.\n", CG_Argv(0), CG_Argv(1), CG_Argv(2), CG_Argv(3)); cgs.redtickets = atoi(CG_Argv(1)); cgs.bluetickets = atoi(CG_Argv(2)); return; } if ( !strcmp( cmd, "print" ) ) { char strEd[MAX_STRINGED_SV_STRING]; CG_CheckSVStringEdRef(strEd, CG_Argv(1)); trap->Print( "%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(2), sizeof (text) ); CG_RemoveChatEscapeChar( text ); CG_ChatBox_AddString(text, atoi(CG_Argv(1))); trap->Print( "*%s\n", text ); } return; } if ( !strcmp( cmd, "tchat" ) ) { trap->S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND ); Q_strncpyz( text, CG_Argv(2), MAX_SAY_TEXT ); CG_RemoveChatEscapeChar( text ); CG_ChatBox_AddString(text, atoi(CG_Argv(1))); trap->Print( "*%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]; int fadeLevel; if (trap->Cmd_Argc() < 4) { return; } fadeLevel = atoi(CG_Argv(1)); strcpy(name, CG_Argv(2)); strcpy(loc, CG_Argv(3)); strcpy(color, CG_Argv(4)); strcpy(message, CG_Argv(5)); if (loc[0] == '@') { //get localized text trap->SE_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, fadeLevel); trap->Print( "*%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]; int fadeLevel; if (trap->Cmd_Argc() < 4) { return; } fadeLevel = atoi(CG_Argv(1)); strcpy(name, CG_Argv(2)); strcpy(loc, CG_Argv(3)); strcpy(color, CG_Argv(4)); strcpy(message, CG_Argv(5)); if (loc[0] == '@') { //get localized text trap->SE_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, fadeLevel); trap->Print( "*%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 ( !strcmp( cmd, "fmrefresh" ) ) { JKG_FireModeUpdate(); return; } //[OverflowProtection] //this command was vulnerable to buffer overflow and could cause problems due to not properly returning //after processing the command. if ( !strcmp( cmd, "remapShader" ) ) { if ( trap->Cmd_Argc() == 4 ) { char shader1[MAX_QPATH]; char shader2[MAX_QPATH]; Q_strncpyz( shader1, CG_Argv( 1 ), sizeof( shader1 ) ); Q_strncpyz( shader2, CG_Argv( 2 ), sizeof( shader2 ) ); trap->R_RemapShader( shader1, shader2, CG_Argv( 3 ) ); return; } return; } //[/OverflowProtection] // 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; } // Team Party List if ( !strcmp( cmd, "tpl" )) { int i, iID, iLen; for ( i = 0, iLen = (( trap->Cmd_Argc() - 1 ) / 5 ); i < iLen; i++ ) { iID = atoi( CG_Argv( i * 5 + 1 )); cgs.partyList[iID].id = atoi( CG_Argv( i * 5 + 2 )); cgs.partyList[iID].classId = atoi( CG_Argv( i * 5 + 3 )); cgs.partyList[iID].time = atoi( CG_Argv( i * 5 + 4 )); Q_strncpyz( cgs.partyList[iID].message, ( char * ) CG_Argv( i * 5 + 5 ), sizeof( cgs.partyList[iID].message )); if ( cgs.partyList[iID].time > cgs.partyListTime ) { cgs.partyListTime = cgs.partyList[iID].time; } } /* Notify UI */ uiImports->PartyMngtNotify( PARTYNOTIFY_UPDATESEEKERS ); return; } // Team Party Invites if ( !strcmp( cmd, "tpi" )) { /* Can't do this with an active party o.o */ cgs.party.active = 0; /* Scan the incoming string into the party struct */ sscanf( CG_Argv( 1 ), "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", &cgs.party.invites[0].id, &cgs.party.invites[0].leaderId, &cgs.party.invites[0].memberCount, &cgs.party.invites[1].id, &cgs.party.invites[1].leaderId, &cgs.party.invites[1].memberCount, &cgs.party.invites[2].id, &cgs.party.invites[2].leaderId, &cgs.party.invites[2].memberCount, &cgs.party.invites[3].id, &cgs.party.invites[3].leaderId, &cgs.party.invites[3].memberCount, &cgs.party.invites[4].id, &cgs.party.invites[4].leaderId, &cgs.party.invites[4].memberCount ); /* Win cake */ /* Notify UI */ uiImports->PartyMngtNotify( PARTYNOTIFY_UPDATESTATE ); return; } // Team Party Update if ( !strcmp( cmd, "tpu" )) { int i; /* Set the party status to active */ cgs.party.active = 1; /* Scan the incoming string into the party struct */ sscanf( CG_Argv( 1 ), "%i %i %i %i %i %i %i %i %i %i %i", &cgs.party.number, &cgs.party.members[0].id, &cgs.party.members[0].classId, &cgs.party.members[1].id, &cgs.party.members[1].classId, &cgs.party.members[2].id, &cgs.party.members[2].classId, &cgs.party.members[3].id, &cgs.party.members[3].classId, &cgs.party.members[4].id, &cgs.party.members[4].classId ); /* Parse the members and fix the status and ID's! */ for ( i = 0; i < 5; i++ ) { if ( cgs.party.members[i].id < 0 ) { cgs.party.members[i].id = abs( cgs.party.members[i].id + 1 ); cgs.party.members[i].status = -1; } else { cgs.party.members[i].status = 0; } } /* Set the party leader status accordingly */ cgs.party.members[0].status = 1; /* Notify UI */ uiImports->PartyMngtNotify( PARTYNOTIFY_UPDATESTATE ); return; } if( !strcmp( cmd, "pInv" )) { BG_ReceivedItemPacket(BG_ItemPacketFromName(CG_Argv(1))); uiImports->ItemsUpdated(); return; } if (!strcmp(cmd, "pTrade")) { BG_ReceivedTradePacket(BG_TradePacketFromName(CG_Argv(1))); uiImports->ItemsUpdated(); return; } // UQ1: Use an event!!!! // eez: Again, this is only getting sent to one client, so no go if( !strcmp( cmd, "hitmarker") ) { // All this does is make a hitmarker display. Nothing too fancy. trap->S_StartSound(NULL, cg.clientNum, CHAN_AUTO, cgs.media.hitmarkerSound); cg.hitmarkerLastTime = cg.time + 1000; return; } if( !strcmp( cmd, "notify") ) { // add a notification to the display CG_Notifications_Add((char *)CG_Argv(2), qfalse); // first arg is ignored. it's supposed to specify the type of message but it's unused. return; } if (!strcmp(cmd, "apc")) { // Ammo price check response uiImports->InventoryPriceCheckResult(atoi(CG_Argv(1)), atoi(CG_Argv(2))); return; } if (!strcmp(cmd, "cbi")) { // Client bought item char* playerName = va("%s", CG_Argv(2)); for (int i = 3; i < trap->Cmd_Argc(); i++) { playerName = va("%s %s", playerName, CG_Argv(i)); } JKG_ClientBoughtItem(playerName, atoi(CG_Argv(1))); return; } //eezstreet end trap->Print( "Unknown client game command: %s\n", cmd ); }
// 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]; qboolean IRCG = qfalse; if ( JPLua_Event_ServerCommand() ) return; cmd = CG_Argv( 0 ); // server claimed the command if ( !cmd[0] ) return; 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 ) ), qfalse ); return; } if ( !strcmp( cmd, "scl" ) ) { trap->OpenUIMenu( UIMENU_CLASSSEL ); return; } if ( !strcmp( cmd, "spc" ) ) { if ( !cg.demoPlayback ) { trap->Cvar_Set( "ui_myteam", "3" ); trap->OpenUIMenu( UIMENU_PLAYERCONFIG ); } return; } if ( !strcmp( cmd, "nfr" ) ) { // new force rank int doMenu = 0, setTeam = 0, newRank = 0; if ( trap->Cmd_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 && !cg.demoPlayback ) 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 i, indexNum = 0, argNum = trap->Cmd_Argc(); if ( argNum < 1 ) return; for ( i = 1; i < argNum; i++ ) { 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 ); } } return; } if ( !strcmp( cmd, "kls" ) ) { // kill looping sounds int indexNum = 0, argNum = trap->Cmd_Argc(); centity_t *clent = NULL, *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; } // this means param 2 is the body index and we want to copy to bodyqueue on it if ( !strcmp( cmd, "ircg" ) ) 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, argNum = trap->Cmd_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]; // this can happen while connecting as a client if ( !clent->ghoul2 ) 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, weaponIndex = 0, 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]; body->teamPowerType = side ? 1 : 0; 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.30f, BIGCHAR_WIDTH ); return; } if ( !strcmp( cmd, "cps" ) ) { char strEd[MAX_STRINGED_SV_STRING]; char *x = (char *)CG_Argv( 1 ); if ( x[0] == '@' ) x++; trap->SE_GetStringTextString( x, strEd, MAX_STRINGED_SV_STRING ); //Raz: From OJP // CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.30f, BIGCHAR_WIDTH ); CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.20f, 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_LogPrintf( cg.log.console, strEd ); trap->Print( "%s", strEd ); return; } if ( !strcmp( cmd, "chat" ) ) { char *msg = JPLua_Event_ChatMessageRecieved( CG_Argv( 1 ) ); //If a JPLua plugin cancelled it, bail if ( !msg ) return; if ( !cg_teamChatsOnly.integer ) { char cbName[MAX_CHATBOX_IDENTIFIER_SIZE] = "normal"; trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND ); Q_strncpyz( text, msg, MAX_SAY_TEXT ); if ( CG_ContainsChannelEscapeChar( text ) ) Q_strncpyz( cbName, CG_RemoveChannelEscapeChar( text ), sizeof(cbName) ); CG_RemoveChatEscapeChar( text ); CG_LogPrintf( cg.log.console, va( "%s\n", text ) ); if ( cg_newChatbox.integer ) CG_ChatboxAddMessage( text, qfalse, cbName ); else CG_ChatBox_AddString( text ); trap->Print( "*%s\n", text ); Q_CleanString( text, STRIP_COLOUR ); CG_LogPrintf( cg.log.chat, va( "%s\n", text ) ); } return; } if ( !strcmp( cmd, "tchat" ) ) { trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND ); Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT ); CG_RemoveChatEscapeChar( text ); CG_LogPrintf( cg.log.console, va( "%s\n", text ) ); if ( cg_newChatbox.integer ) CG_ChatboxAddMessage( text, qfalse, "team" ); else CG_ChatBox_AddString( text ); trap->Print( "*%s\n", text ); Q_CleanString( text, STRIP_COLOUR ); CG_LogPrintf( cg.log.chat, va( "%s\n", text ) ); return; } //chat with location, possibly localized. if ( !strcmp( cmd, "lchat" ) ) { if ( !cg_teamChatsOnly.integer ) { char name[MAX_STRING_CHARS], loc[MAX_STRING_CHARS], color[8], message[MAX_STRING_CHARS]; if ( trap->Cmd_Argc() < 4 ) return; Q_strncpyz( name, CG_Argv( 1 ), sizeof(name) ); Q_strncpyz( loc, CG_Argv( 2 ), sizeof(loc) ); Q_strncpyz( color, CG_Argv( 3 ), sizeof(color) ); Q_strncpyz( message, CG_Argv( 4 ), sizeof(message) ); if ( loc[0] == '@' ) trap->SE_GetStringTextString( loc + 1, loc, sizeof(loc) ); trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND ); // Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT ); Com_sprintf( text, sizeof(text), "%s" S_COLOR_WHITE "<%s> ^%s%s", name, loc, color, message ); CG_RemoveChatEscapeChar( text ); //Raz: Siege chat now uses the fancy new chatbox if ( cg_newChatbox.integer ) CG_ChatboxAddMessage( text, qfalse, "normal" ); else CG_ChatBox_AddString( text ); trap->Print( "*%s\n", text ); Q_CleanString( text, STRIP_COLOUR ); CG_LogPrintf( cg.log.chat, va( "%s\n", text ) ); } return; } if ( !strcmp( cmd, "ltchat" ) ) { char name[MAX_STRING_CHARS], loc[MAX_STRING_CHARS], color[8], message[MAX_STRING_CHARS]; if ( trap->Cmd_Argc() < 4 ) return; Q_strncpyz( name, CG_Argv( 1 ), sizeof(name) ); Q_strncpyz( loc, CG_Argv( 2 ), sizeof(loc) ); Q_strncpyz( color, CG_Argv( 3 ), sizeof(color) ); Q_strncpyz( message, CG_Argv( 4 ), sizeof(message) ); if ( loc[0] == '@' ) trap->SE_GetStringTextString( loc + 1, loc, sizeof(loc) ); trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND ); // Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT ); Com_sprintf( text, sizeof(text), "%s" S_COLOR_WHITE "<%s> ^%s%s", name, loc, color, message ); CG_RemoveChatEscapeChar( text ); if ( cg_newChatbox.integer ) CG_ChatboxAddMessage( text, qfalse, "team" ); else CG_ChatBox_AddString( text ); trap->Print( "*%s\n", text ); Q_CleanString( text, STRIP_COLOUR ); CG_LogPrintf( cg.log.chat, va( "%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" ) ) { if ( trap->Cmd_Argc() == 4 ) { char shader1[MAX_QPATH], shader2[MAX_QPATH]; Q_strncpyz( shader1, CG_Argv( 1 ), sizeof(shader1) ); Q_strncpyz( shader2, CG_Argv( 2 ), sizeof(shader2) ); trap->R_RemapShader( shader1, shader2, CG_Argv( 3 ) ); return; } return; } // 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; } trap->Print( "Unknown client game command: %s\n", cmd ); }
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 ); }