//----------------------------------------------------------------------------- // // $Id$ // //----------------------------------------------------------------------------- // // $Log$ // Revision 1.10 2003/03/22 20:29:26 jbravo // wrapping linkent and unlinkent calls // // Revision 1.9 2002/09/24 05:06:16 blaze // fixed spectating so ref\'s can now use all the chasecam modes. // // Revision 1.8 2002/06/16 20:06:14 jbravo // Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap" // // Revision 1.7 2002/06/16 17:38:00 jbravo // Removed the MISSIONPACK ifdefs and missionpack only code. // // Revision 1.6 2002/01/11 19:48:30 jbravo // Formatted the source in non DOS format. // // Revision 1.5 2001/12/31 16:28:42 jbravo // I made a Booboo with the Log tag. // // //----------------------------------------------------------------------------- // Copyright (C) 1999-2000 Id Software, Inc. // // // g_arenas.c // #include "g_local.h" gentity_t *podium1; gentity_t *podium2; gentity_t *podium3; /* ================== UpdateTournamentInfo ================== */ void UpdateTournamentInfo(void) { int i; gentity_t *player; // int playerClientNum; //int n, accuracy, perfect, msglen; int n, msglen; char buf[32]; char msg[MAX_STRING_CHARS]; // find the real player player = NULL; for (i = 0; i < level.maxclients; i++) { //Blaze: Print out some debug info if (&g_entities[i] == NULL) G_Printf("Ln 0052\n"); player = &g_entities[i]; if (!player->inuse) { continue; } if (!(player->r.svFlags & SVF_BOT)) { break; } } // this should never happen! if (!player || i == level.maxclients) { return; } // playerClientNum = i; CalculateRanks(); /* if (level.clients[playerClientNum].sess.sessionTeam == TEAM_SPECTATOR) { Com_sprintf(msg, sizeof(msg), "postgame %i %i 0 0 0 0 0 0", level.numNonSpectatorClients, playerClientNum); } else { if (player->client->accuracy_shots) { accuracy = player->client->accuracy_hits * 100 / player->client->accuracy_shots; } else { accuracy = 0; } perfect = (level.clients[playerClientNum].ps.persistant[PERS_RANK] == 0 && player->client->ps.persistant[PERS_KILLED] == 0) ? 1 : 0; //Blaze: Removed because it uses the persistant stats stuff Com_sprintf( msg, sizeof(msg), "postgame %i %i %i %i %i %i %i %i", level.numNonSpectatorClients, playerClientNum, accuracy, player->client->ps.persistant[PERS_IMPRESSIVE_COUNT], player->client->ps.persistant[PERS_EXCELLENT_COUNT], player->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT], player->client->ps.persistant[PERS_SCORE], perfect ); } */ msglen = strlen(msg); for (i = 0; i < level.numNonSpectatorClients; i++) { n = level.sortedClients[i]; Com_sprintf(buf, sizeof(buf), " %i %i %i", n, level.clients[n].ps.persistant[PERS_RANK], level.clients[n].ps.persistant[PERS_SCORE]); msglen += strlen(buf); if (msglen >= sizeof(msg)) { break; } strcat(msg, buf); } trap_SendConsoleCommand(EXEC_APPEND, msg); } static gentity_t *SpawnModelOnVictoryPad(gentity_t * pad, vec3_t offset, gentity_t * ent, int place) { gentity_t *body; vec3_t vec; vec3_t f, r, u; body = G_Spawn(); if (!body) { G_Printf(S_COLOR_RED "ERROR: out of gentities\n"); return NULL; } body->classname = ent->client->pers.netname; body->client = ent->client; body->s = ent->s; body->s.eType = ET_PLAYER; // could be ET_INVISIBLE body->s.eFlags = 0; // clear EF_TALK, etc body->s.powerups = 0; // clear powerups body->s.loopSound = 0; // clear lava burning body->s.number = body - g_entities; body->timestamp = level.time; body->physicsObject = qtrue; body->physicsBounce = 0; // don't bounce body->s.event = 0; body->s.pos.trType = TR_STATIONARY; body->s.groundEntityNum = ENTITYNUM_WORLD; body->s.legsAnim = LEGS_IDLE; body->s.torsoAnim = TORSO_STAND; if (body->s.weapon == WP_NONE) { body->s.weapon = WP_PISTOL; } if (body->s.weapon == WP_KNIFE) { body->s.torsoAnim = TORSO_STAND2; } body->s.event = 0; body->r.svFlags = ent->r.svFlags; VectorCopy(ent->r.mins, body->r.mins); VectorCopy(ent->r.maxs, body->r.maxs); VectorCopy(ent->r.absmin, body->r.absmin); VectorCopy(ent->r.absmax, body->r.absmax); body->clipmask = CONTENTS_SOLID | CONTENTS_PLAYERCLIP; body->r.contents = CONTENTS_BODY; body->r.ownerNum = ent->r.ownerNum; body->takedamage = qfalse; VectorSubtract(level.intermission_origin, pad->r.currentOrigin, vec); vectoangles(vec, body->s.apos.trBase); body->s.apos.trBase[PITCH] = 0; body->s.apos.trBase[ROLL] = 0; AngleVectors(body->s.apos.trBase, f, r, u); VectorMA(pad->r.currentOrigin, offset[0], f, vec); VectorMA(vec, offset[1], r, vec); VectorMA(vec, offset[2], u, vec); G_SetOrigin(body, vec); trap_LinkEntity(body); body->count = place; return body; } static void CelebrateStop(gentity_t * player) { int anim; //Blaze: gah, dont need to change stance for using gauntlet // if( player->s.weapon == WP_GAUNTLET) { // anim = TORSO_STAND2; // } // else { anim = TORSO_STAND; // } player->s.torsoAnim = ((player->s.torsoAnim & ANIM_TOGGLEBIT) ^ ANIM_TOGGLEBIT) | anim; } #define TIMER_GESTURE (34*66+50) static void CelebrateStart(gentity_t * player) { player->s.torsoAnim = ((player->s.torsoAnim & ANIM_TOGGLEBIT) ^ ANIM_TOGGLEBIT) | TORSO_GESTURE; player->nextthink = level.time + TIMER_GESTURE; player->think = CelebrateStop; /* player->client->ps.events[player->client->ps.eventSequence & (MAX_PS_EVENTS-1)] = EV_TAUNT; player->client->ps.eventParms[player->client->ps.eventSequence & (MAX_PS_EVENTS-1)] = 0; player->client->ps.eventSequence++; */ G_AddEvent(player, EV_TAUNT, 0); } static vec3_t offsetFirst = { 0, 0, 74 }; static vec3_t offsetSecond = { -10, 60, 54 }; static vec3_t offsetThird = { -19, -60, 45 }; static void PodiumPlacementThink(gentity_t * podium) { vec3_t vec; vec3_t origin; vec3_t f, r, u; podium->nextthink = level.time + 100; AngleVectors(level.intermission_angle, vec, NULL, NULL); VectorMA(level.intermission_origin, trap_Cvar_VariableIntegerValue("g_podiumDist"), vec, origin); origin[2] -= trap_Cvar_VariableIntegerValue("g_podiumDrop"); G_SetOrigin(podium, origin); if (podium1) { VectorSubtract(level.intermission_origin, podium->r.currentOrigin, vec); vectoangles(vec, podium1->s.apos.trBase); podium1->s.apos.trBase[PITCH] = 0; podium1->s.apos.trBase[ROLL] = 0; AngleVectors(podium1->s.apos.trBase, f, r, u); VectorMA(podium->r.currentOrigin, offsetFirst[0], f, vec); VectorMA(vec, offsetFirst[1], r, vec); VectorMA(vec, offsetFirst[2], u, vec); G_SetOrigin(podium1, vec); } if (podium2) { VectorSubtract(level.intermission_origin, podium->r.currentOrigin, vec); vectoangles(vec, podium2->s.apos.trBase); podium2->s.apos.trBase[PITCH] = 0; podium2->s.apos.trBase[ROLL] = 0; AngleVectors(podium2->s.apos.trBase, f, r, u); VectorMA(podium->r.currentOrigin, offsetSecond[0], f, vec); VectorMA(vec, offsetSecond[1], r, vec); VectorMA(vec, offsetSecond[2], u, vec); G_SetOrigin(podium2, vec); } if (podium3) { VectorSubtract(level.intermission_origin, podium->r.currentOrigin, vec); vectoangles(vec, podium3->s.apos.trBase); podium3->s.apos.trBase[PITCH] = 0; podium3->s.apos.trBase[ROLL] = 0; AngleVectors(podium3->s.apos.trBase, f, r, u); VectorMA(podium->r.currentOrigin, offsetThird[0], f, vec); VectorMA(vec, offsetThird[1], r, vec); VectorMA(vec, offsetThird[2], u, vec); G_SetOrigin(podium3, vec); } } static gentity_t *SpawnPodium(void) { gentity_t *podium; vec3_t vec; vec3_t origin; podium = G_Spawn(); if (!podium) { return NULL; } podium->classname = "podium"; podium->s.eType = ET_GENERAL; podium->s.number = podium - g_entities; podium->clipmask = CONTENTS_SOLID; podium->r.contents = CONTENTS_SOLID; podium->s.modelindex = G_ModelIndex(SP_PODIUM_MODEL); AngleVectors(level.intermission_angle, vec, NULL, NULL); VectorMA(level.intermission_origin, trap_Cvar_VariableIntegerValue("g_podiumDist"), vec, origin); origin[2] -= trap_Cvar_VariableIntegerValue("g_podiumDrop"); G_SetOrigin(podium, origin); VectorSubtract(level.intermission_origin, podium->r.currentOrigin, vec); podium->s.apos.trBase[YAW] = vectoyaw(vec); trap_LinkEntity(podium); podium->think = PodiumPlacementThink; podium->nextthink = level.time + 100; return podium; } /* ================== SpawnModelsOnVictoryPads ================== */ void SpawnModelsOnVictoryPads(void) { gentity_t *player; gentity_t *podium; podium1 = NULL; podium2 = NULL; podium3 = NULL; podium = SpawnPodium(); player = SpawnModelOnVictoryPad(podium, offsetFirst, &g_entities[level.sortedClients[0]], level.clients[level.sortedClients[0]].ps. persistant[PERS_RANK] & ~RANK_TIED_FLAG); if (player) { player->nextthink = level.time + 2000; player->think = CelebrateStart; podium1 = player; } player = SpawnModelOnVictoryPad(podium, offsetSecond, &g_entities[level.sortedClients[1]], level.clients[level.sortedClients[1]].ps. persistant[PERS_RANK] & ~RANK_TIED_FLAG); if (player) { podium2 = player; } if (level.numNonSpectatorClients > 2) { player = SpawnModelOnVictoryPad(podium, offsetThird, &g_entities[level.sortedClients[2]], level.clients[level.sortedClients[2]].ps. persistant[PERS_RANK] & ~RANK_TIED_FLAG); if (player) { podium3 = player; } } } /* =============== Svcmd_AbortPodium_f =============== */ void Svcmd_AbortPodium_f(void) { if (g_gametype.integer != GT_SINGLE_PLAYER) { return; } if (podium1) { podium1->nextthink = level.time; podium1->think = CelebrateStop; } }