#include "g_local.h" /* ====================================================================== INTERMISSION ====================================================================== */ void MoveClientToIntermission (edict_t *ent) { //ERASER START gclient_t *client; client = ent->client; //ERASER END if (deathmatch->value || coop->value) ent->client->showscores = true; VectorCopy (level.intermission_origin, ent->s.origin); ent->client->ps.pmove.origin[0] = level.intermission_origin[0]*8; ent->client->ps.pmove.origin[1] = level.intermission_origin[1]*8; ent->client->ps.pmove.origin[2] = level.intermission_origin[2]*8; VectorCopy (level.intermission_angle, ent->client->ps.viewangles); ent->client->ps.pmove.pm_type = PM_FREEZE; ent->client->ps.gunindex = 0; ent->client->ps.blend[3] = 0; ent->client->ps.rdflags &= ~RDF_UNDERWATER; // clean up powerup info ent->client->quad_framenum = 0; ent->client->invincible_framenum = 0; ent->client->breather_framenum = 0; ent->client->enviro_framenum = 0; ent->client->grenade_blew_up = false; ent->client->grenade_time = 0; ent->viewheight = 0; ent->s.modelindex = 0; ent->s.modelindex2 = 0; ent->s.modelindex3 = 0; ent->s.modelindex = 0; ent->s.effects = 0; ent->s.sound = 0; ent->solid = SOLID_NOT; // add the layout if (!ent->bot_client && (deathmatch->value || coop->value))//ERASER ADDED (!ent->bot_client && { DeathmatchScoreboardMessage (ent, NULL); gi.unicast (ent, true); } } void BeginIntermission (edict_t *targ) { int i, n; edict_t *ent, *client; if (level.intermissiontime) return; // allready activated //ZOID if (deathmatch->value && ctf->value) CTFCalcScores(); //ZOID game.autosaved = false; // respawn any dead clients for (i=0 ; ivalue ; i++) { client = g_edicts + 1 + i; if (!client->inuse) continue; if (client->health <= 0) respawn(client); } level.intermissiontime = level.time; level.changemap = targ->map; if (strstr(level.changemap, "*")) { if (coop->value) { for (i=0 ; ivalue ; i++) { client = g_edicts + 1 + i; if (!client->inuse) continue; // strip players of all keys between units for (n = 0; n < MAX_ITEMS; n++) { if (itemlist[n].flags & IT_KEY) client->client->pers.inventory[n] = 0; } } } } else { if (!deathmatch->value) { level.exitintermission = 1; // go immediately to the next level return; } } level.exitintermission = 0; // find an intermission spot ent = G_Find (NULL, FOFS(classname), "info_player_intermission"); if (!ent) { // the map creator forgot to put in an intermission point... ent = G_Find (NULL, FOFS(classname), "info_player_start"); if (!ent) ent = G_Find (NULL, FOFS(classname), "info_player_deathmatch"); } else { // chose one of four spots i = rand() & 3; while (i--) { ent = G_Find (ent, FOFS(classname), "info_player_intermission"); if (!ent) // wrap around the list ent = G_Find (ent, FOFS(classname), "info_player_intermission"); } } VectorCopy (ent->s.origin, level.intermission_origin); VectorCopy (ent->s.angles, level.intermission_angle); // move all clients to the intermission point for (i=0 ; ivalue ; i++) { client = g_edicts + 1 + i; if (!client->inuse) continue; MoveClientToIntermission (client); } } //ERASER START FOR CUSTOM TEAMS PLAY void TeamplayScoreboardMessage (edict_t *ent, edict_t *killer) { char entry[1024]; char string[1400]; int stringlength; int i, j, k, t; int sorted[MAX_CLIENTS]; int sortedscores[MAX_CLIENTS]; bot_team_t *sortedteams[MAX_TEAMS]; int doneteam[MAX_TEAMS]; int numteams, best, bestscore; int score, total; int x, y; gclient_t *cl; edict_t *cl_ent; // clear the doneteam flags memset(doneteam, 0, sizeof(int) * MAX_TEAMS); numteams = 0; // incremented each time we add a team to the list // sort the teams for (i=0; iingame) continue; bestscore = -999999; best = -1; // find the highest scoring team for (j=0; jingame) continue; if (bot_teams[j]->score > bestscore) { best = j; bestscore = bot_teams[j]->score; } } if (best > -1) { doneteam[best] = true; sortedteams[numteams] = bot_teams[best]; numteams++; } else // must be done { break; } } string[0] = 0; stringlength = strlen(string); for (t=0; t 3) // only print the top 4 teams break; // sort the clients by score total = 0; for (i=0 ; iinuse) continue; if (cl_ent->client->team != sortedteams[t]) continue; score = game.clients[i].resp.score; for (j=0 ; j sortedscores[j]) break; } for (k=total ; k>j ; k--) { sorted[k] = sorted[k-1]; sortedscores[k] = sortedscores[k-1]; } sorted[j] = i; sortedscores[j] = score; total++; } if (total > 4) total = 4; x = 160; y = (t * 48); if (ent->client->team == sortedteams[t]) { Com_sprintf (entry, sizeof(entry), "xv %i yv %i picn tag1 ", 32, y); j = strlen(entry); if (stringlength + j > 1024) break; strcpy (string + stringlength, entry); stringlength += j; } // Send team info Com_sprintf (entry, sizeof(entry), "xv %i yv %i string \"%s\" ", 70, y+6, sortedteams[t]->teamname); j = strlen(entry); if (stringlength + j > 1024) break; strcpy (string + stringlength, entry); stringlength += j; // Send team score info Com_sprintf (entry, sizeof(entry), "xv %i yv %i string \"%i\" ", 80, y + 20, sortedteams[t]->score); j = strlen(entry); if (stringlength + j > 1024) break; strcpy (string + stringlength, entry); stringlength += j; for (i=0 ; iresp.score, cl->pers.netname); } else { Com_sprintf (entry, sizeof(entry), "xv %i yv %i string2 \"%3i %s\" ", x, y, cl->resp.score, cl->pers.netname); } j = strlen(entry); if (stringlength + j > 1024) break; strcpy (string + stringlength, entry); stringlength += j; } } gi.WriteByte (svc_layout); gi.WriteString (string); } //ERASER END /* ================== DeathmatchScoreboardMessage ================== */ void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer) { char entry[1024]; char string[1400]; int stringlength; int i, j, k; int sorted[MAX_CLIENTS]; int sortedscores[MAX_CLIENTS]; int score, total; int picnum; int x, y; gclient_t *cl; edict_t *cl_ent; char *tag; //WF - Scanner // if (ent->client->showscores || ent->client->showinventory) // if (ent->client->pers.scanner_active) // ent->client->pers.scanner_active=2; //WF //WF - added following 2 lines if (ent->client->showscores) { //ZOID if (ctf->value) { CTFScoreboardMessage (ent, killer); return; } //ZOID //ERASER START if (teamplay->value && ent->client->team) { TeamplayScoreboardMessage(ent, killer); return; } //ERASER END // sort the clients by score total = 0; for (i=0 ; iinuse) continue; score = game.clients[i].resp.score; for (j=0 ; j sortedscores[j]) break; } for (k=total ; k>j ; k--) { sorted[k] = sorted[k-1]; sortedscores[k] = sortedscores[k-1]; } sorted[j] = i; sortedscores[j] = score; total++; } // print level name and exit rules string[0] = 0; stringlength = strlen(string); // add the clients in sorted order if (total > 12) total = 12; for (i=0 ; i=6) ? 160 : 0; y = 32 + 32 * (i%6); // add a dogtag if (cl_ent == ent) tag = "tag1"; else if (cl_ent == killer) tag = "tag2"; else tag = NULL; if (tag) { Com_sprintf (entry, sizeof(entry), "xv %i yv %i picn %s ",x+32, y, tag); j = strlen(entry); if (stringlength + j > 1024) break; strcpy (string + stringlength, entry); stringlength += j; } //ERASER START if (cl_ent->bot_client) { cl->ping = (int) cl_ent->bot_stats->avg_ping + ((random() * 2) - 1) * 80; if (cl->ping < 0) cl->ping = 0; } //ERASER END // send the layout Com_sprintf (entry, sizeof(entry), "client %i %i %i %i %i %i ", x, y, sorted[i], cl->resp.score, cl->ping, (level.framenum - cl->resp.enterframe)/600); j = strlen(entry); if (stringlength + j > 1024) break; strcpy (string + stringlength, entry); stringlength += j; } }//WF - added rest of stuff here including this line else *string=0; //WF Scanner active ? //if (ent->client->pers.scanner_active) // ShowScanner(ent,string); //WF END gi.WriteByte (svc_layout); gi.WriteString (string); } /* ================== DeathmatchScoreboard Draw instead of help message. Note that it isn't that hard to overflow the 1400 byte message limit! ================== */ void DeathmatchScoreboard (edict_t *ent) { DeathmatchScoreboardMessage (ent, ent->enemy); gi.unicast (ent, true); } /* ================== Cmd_Score_f Display the scoreboard ================== */ void Cmd_Score_f (edict_t *ent) { ent->client->showinventory = false; ent->client->showhelp = false; //ZOID if (ent->client->menu) PMenu_Close(ent); //ZOID if (!deathmatch->value && !coop->value) return; if (ent->client->showscores) { ent->client->showscores = false; ent->client->update_chase = true; return; } ent->client->showscores = true; DeathmatchScoreboard (ent); } /* ================== HelpComputer Draw help computer. ================== */ void HelpComputer (edict_t *ent) { char string[1024]; /* char *sk; if (skill->value == 0) sk = "easy"; else if (skill->value == 1) sk = "medium"; else if (skill->value == 2) sk = "hard"; else sk = "hard+"; */ // send the layout Com_sprintf (string, sizeof(string), "xv 32 yv 8 picn help " // background "xv 0 yv 24 cstring2 \"%s\" " // level name "xv 0 yv 54 cstring2 \"%s\" " // help 1 "xv 0 yv 110 cstring2 \"%s\" ", // help 2 level.level_name, game.helpmessage1, game.helpmessage2); gi.WriteByte (svc_layout); gi.WriteString (string); // gi.unicast (ent, true); } /* ================== Cmd_Help_f Display the current help message ================== */ void Cmd_Help_f (edict_t *ent) { // this is for backwards compatability if (deathmatch->value) { Cmd_Score_f (ent); return; } ent->client->showinventory = false; ent->client->showscores = false; if (ent->client->showhelp && (ent->client->resp.game_helpchanged == game.helpchanged)) { ent->client->showhelp = false; return; } ent->client->showhelp = true; ent->client->resp.helpchanged = 0; HelpComputer (ent); } // TeT Using a menu to display map help - see g_ctf.c //void Cmd_MapHelp_f (edict_t *ent) //{ // ent->client->showinventory = false; // ent->client->showscores = false; // if (ent->client->showhelp && (ent->client->resp.game_helpchanged == game.helpchanged)) // { // ent->client->showhelp = false; // return; // } // ent->client->showhelp = true; // ent->client->resp.helpchanged = 0; // HelpComputer (ent); //} //======================================================================= /* =============== G_SetStats =============== */ void G_SetStats (edict_t *ent) { gitem_t *item; int index; int power_armor_type; int cells = 0; // // health // ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health; ent->client->ps.stats[STAT_HEALTH] = ent->health; // // weapon damage // ent->client->ps.stats[STAT_DAMAGE_ICON] = level.pic_damage; ent->client->ps.stats[STAT_DAMAGE] = ent->client->weapon_damage; // // ref called timeout? // if (wf_game.game_halted) ent->client->ps.stats[STAT_TIMEOUT_ICON] = level.pic_timeout; else ent->client->ps.stats[STAT_TIMEOUT_ICON] = 0; // // ammo // if (!ent->client->ammo_index /* ||!ent->client->pers.inventory[ent->client->ammo_index] */) { ent->client->ps.stats[STAT_AMMO_ICON] = 0; ent->client->ps.stats[STAT_AMMO] = 0; } else { item = &itemlist[ent->client->ammo_index]; ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex(item->icon); ent->client->ps.stats[STAT_AMMO] = ent->client->pers.inventory[ent->client->ammo_index]; } // // armor // power_armor_type = PowerArmorType (ent); if (power_armor_type) { cells = ent->client->pers.inventory[ITEM_INDEX(FindItem ("cells"))]; if (cells == 0) { // ran out of cells for power armor ent->flags &= ~FL_POWER_ARMOR; gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0); power_armor_type = 0;; } } index = ArmorIndex (ent); if (power_armor_type && (!index || (level.framenum & 8) ) ) { // flash between power armor and other armor icon ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex ("i_powershield"); ent->client->ps.stats[STAT_ARMOR] = cells; } else if (index) { item = GetItemByIndex (index); ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex (item->icon); ent->client->ps.stats[STAT_ARMOR] = ent->client->pers.inventory[index]; } else { ent->client->ps.stats[STAT_ARMOR_ICON] = 0; ent->client->ps.stats[STAT_ARMOR] = 0; } // // pickup message // if (level.time > ent->client->pickup_msg_time) { ent->client->ps.stats[STAT_PICKUP_ICON] = 0; ent->client->ps.stats[STAT_PICKUP_STRING] = 0; } // // timers // if (ent->client->quad_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad"); ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum)/10; } else if (ent->client->invincible_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_invulnerability"); ent->client->ps.stats[STAT_TIMER] = (ent->client->invincible_framenum - level.framenum)/10; } else if (ent->client->enviro_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_envirosuit"); ent->client->ps.stats[STAT_TIMER] = (ent->client->enviro_framenum - level.framenum)/10; } else if (ent->client->breather_framenum > level.framenum) { ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_rebreather"); ent->client->ps.stats[STAT_TIMER] = (ent->client->breather_framenum - level.framenum)/10; } else { ent->client->ps.stats[STAT_TIMER_ICON] = 0; ent->client->ps.stats[STAT_TIMER] = 0; } // // selected item // if (ent->client->pers.selected_item == -1) ent->client->ps.stats[STAT_SELECTED_ICON] = 0; else ent->client->ps.stats[STAT_SELECTED_ICON] = gi.imageindex (itemlist[ent->client->pers.selected_item].icon); ent->client->ps.stats[STAT_SELECTED_ITEM] = ent->client->pers.selected_item; // // layouts // ent->client->ps.stats[STAT_LAYOUTS] = 0; if (deathmatch->value) { //WF - scanner if (ent->client->pers.health <= 0 || level.intermissiontime || ent->client->showscores || ent->client->pers.scanner_active || ent->client->showhelp) // TeT, added showhelp, needed for maphelp ent->client->ps.stats[STAT_LAYOUTS] |= 1; //WF if (ent->client->showinventory && ent->client->pers.health > 0) ent->client->ps.stats[STAT_LAYOUTS] |= 2; } else { if (ent->client->showscores || ent->client->showhelp) ent->client->ps.stats[STAT_LAYOUTS] |= 1; if (ent->client->showinventory && ent->client->pers.health > 0) ent->client->ps.stats[STAT_LAYOUTS] |= 2; } // // frags // ent->client->ps.stats[STAT_FRAGS] = ent->client->resp.score; // // help icon / current weapon if not shown // if (ent->client->resp.helpchanged && (level.framenum&8) ) ent->client->ps.stats[STAT_HELPICON] = gi.imageindex ("i_help"); else if ( (ent->client->pers.hand == CENTER_HANDED || ent->client->ps.fov > 91) && ent->client->pers.weapon) ent->client->ps.stats[STAT_HELPICON] = gi.imageindex (ent->client->pers.weapon->icon); else ent->client->ps.stats[STAT_HELPICON] = 0; //ZOID SetCTFStats(ent); //ZOID }