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 ); }
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; clientInfo_t *ci; if (cent->ghoul2) { trap_G2API_CleanGhoul2Models(¢->ghoul2); } if (clientNum < 0 || clientNum >= MAX_CLIENTS) { return; } source = &cg_entities[ clientNum ]; ci = &cgs.clientinfo[ 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); } }
//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(¢->ghoul2); cent->ghoul2 = NULL; } if (cent->grip_arm && trap_G2_HaveWeGhoul2Models(cent->grip_arm)) { trap_G2API_CleanGhoul2Models(¢->grip_arm); cent->grip_arm = NULL; } if (cent->frame_hold && trap_G2_HaveWeGhoul2Models(cent->frame_hold)) { trap_G2API_CleanGhoul2Models(¢->frame_hold); cent->frame_hold = NULL; } if (cent->npcClient) { CG_DestroyNPCClient(¢->npcClient); } cent->isRagging = qfalse; //just in case. cent->ikStatus = qfalse; cent->localAnimIndex = 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); } }