|
|
1.1 ! root 1: #include "g_local.h" ! 2: ! 3: ! 4: ! 5: /* ! 6: ====================================================================== ! 7: ! 8: INTERMISSION ! 9: ! 10: ====================================================================== ! 11: */ ! 12: ! 13: void MoveClientToIntermission (edict_t *ent) ! 14: { ! 15: if (deathmatch->value || coop->value) ! 16: ent->client->showscores = true; ! 17: VectorCopy (level.intermission_origin, ent->s.origin); ! 18: ent->client->ps.pmove.origin[0] = level.intermission_origin[0]*8; ! 19: ent->client->ps.pmove.origin[1] = level.intermission_origin[1]*8; ! 20: ent->client->ps.pmove.origin[2] = level.intermission_origin[2]*8; ! 21: VectorCopy (level.intermission_angle, ent->client->ps.viewangles); ! 22: ent->client->ps.pmove.pm_type = PM_FREEZE; ! 23: ent->client->ps.gunindex = 0; ! 24: ent->client->ps.blend[3] = 0; ! 25: ent->client->ps.rdflags &= ~RDF_UNDERWATER; ! 26: ! 27: // clean up powerup info ! 28: ent->client->quad_framenum = 0; ! 29: ent->client->invincible_framenum = 0; ! 30: ent->client->breather_framenum = 0; ! 31: ent->client->enviro_framenum = 0; ! 32: ent->client->grenade_blew_up = false; ! 33: ent->client->grenade_time = 0; ! 34: ! 35: ent->viewheight = 0; ! 36: ent->s.modelindex = 0; ! 37: ent->s.modelindex2 = 0; ! 38: ent->s.modelindex3 = 0; ! 39: ent->s.modelindex = 0; ! 40: ent->s.effects = 0; ! 41: ent->s.sound = 0; ! 42: ent->solid = SOLID_NOT; ! 43: ! 44: // add the layout ! 45: ! 46: if (deathmatch->value || coop->value) ! 47: { ! 48: DeathmatchScoreboardMessage (ent, NULL); ! 49: gi.unicast (ent, true); ! 50: } ! 51: ! 52: } ! 53: ! 54: void BeginIntermission (edict_t *targ) ! 55: { ! 56: int i, n; ! 57: edict_t *ent, *client; ! 58: ! 59: if (level.intermissiontime) ! 60: return; // allready activated ! 61: ! 62: //ZOID ! 63: if (deathmatch->value && ctf->value) ! 64: CTFCalcScores(); ! 65: //ZOID ! 66: ! 67: game.autosaved = false; ! 68: ! 69: // respawn any dead clients ! 70: for (i=0 ; i<maxclients->value ; i++) ! 71: { ! 72: client = g_edicts + 1 + i; ! 73: if (!client->inuse) ! 74: continue; ! 75: if (client->health <= 0) ! 76: respawn(client); ! 77: } ! 78: ! 79: level.intermissiontime = level.time; ! 80: level.changemap = targ->map; ! 81: ! 82: if (strstr(level.changemap, "*")) ! 83: { ! 84: if (coop->value) ! 85: { ! 86: for (i=0 ; i<maxclients->value ; i++) ! 87: { ! 88: client = g_edicts + 1 + i; ! 89: if (!client->inuse) ! 90: continue; ! 91: // strip players of all keys between units ! 92: for (n = 0; n < MAX_ITEMS; n++) ! 93: { ! 94: if (itemlist[n].flags & IT_KEY) ! 95: client->client->pers.inventory[n] = 0; ! 96: } ! 97: } ! 98: } ! 99: } ! 100: else ! 101: { ! 102: if (!deathmatch->value) ! 103: { ! 104: level.exitintermission = 1; // go immediately to the next level ! 105: return; ! 106: } ! 107: } ! 108: ! 109: level.exitintermission = 0; ! 110: ! 111: // find an intermission spot ! 112: ent = G_Find (NULL, FOFS(classname), "info_player_intermission"); ! 113: if (!ent) ! 114: { // the map creator forgot to put in an intermission point... ! 115: ent = G_Find (NULL, FOFS(classname), "info_player_start"); ! 116: if (!ent) ! 117: ent = G_Find (NULL, FOFS(classname), "info_player_deathmatch"); ! 118: } ! 119: else ! 120: { // chose one of four spots ! 121: i = rand() & 3; ! 122: while (i--) ! 123: { ! 124: ent = G_Find (ent, FOFS(classname), "info_player_intermission"); ! 125: if (!ent) // wrap around the list ! 126: ent = G_Find (ent, FOFS(classname), "info_player_intermission"); ! 127: } ! 128: } ! 129: ! 130: VectorCopy (ent->s.origin, level.intermission_origin); ! 131: VectorCopy (ent->s.angles, level.intermission_angle); ! 132: ! 133: // move all clients to the intermission point ! 134: for (i=0 ; i<maxclients->value ; i++) ! 135: { ! 136: client = g_edicts + 1 + i; ! 137: if (!client->inuse) ! 138: continue; ! 139: MoveClientToIntermission (client); ! 140: } ! 141: } ! 142: ! 143: ! 144: /* ! 145: ================== ! 146: DeathmatchScoreboardMessage ! 147: ! 148: ================== ! 149: */ ! 150: void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer) ! 151: { ! 152: char entry[1024]; ! 153: char string[1400]; ! 154: int stringlength; ! 155: int i, j, k; ! 156: int sorted[MAX_CLIENTS]; ! 157: int sortedscores[MAX_CLIENTS]; ! 158: int score, total; ! 159: int picnum; ! 160: int x, y; ! 161: gclient_t *cl; ! 162: edict_t *cl_ent; ! 163: char *tag; ! 164: ! 165: //ZOID ! 166: if (ctf->value) { ! 167: CTFScoreboardMessage (ent, killer); ! 168: return; ! 169: } ! 170: //ZOID ! 171: ! 172: // sort the clients by score ! 173: total = 0; ! 174: for (i=0 ; i<game.maxclients ; i++) ! 175: { ! 176: cl_ent = g_edicts + 1 + i; ! 177: if (!cl_ent->inuse) ! 178: continue; ! 179: score = game.clients[i].resp.score; ! 180: for (j=0 ; j<total ; j++) ! 181: { ! 182: if (score > sortedscores[j]) ! 183: break; ! 184: } ! 185: for (k=total ; k>j ; k--) ! 186: { ! 187: sorted[k] = sorted[k-1]; ! 188: sortedscores[k] = sortedscores[k-1]; ! 189: } ! 190: sorted[j] = i; ! 191: sortedscores[j] = score; ! 192: total++; ! 193: } ! 194: ! 195: // print level name and exit rules ! 196: string[0] = 0; ! 197: ! 198: stringlength = strlen(string); ! 199: ! 200: // add the clients in sorted order ! 201: if (total > 12) ! 202: total = 12; ! 203: ! 204: for (i=0 ; i<total ; i++) ! 205: { ! 206: cl = &game.clients[sorted[i]]; ! 207: cl_ent = g_edicts + 1 + sorted[i]; ! 208: ! 209: picnum = gi.imageindex ("i_fixme"); ! 210: x = (i>=6) ? 160 : 0; ! 211: y = 32 + 32 * (i%6); ! 212: ! 213: // add a dogtag ! 214: if (cl_ent == ent) ! 215: tag = "tag1"; ! 216: else if (cl_ent == killer) ! 217: tag = "tag2"; ! 218: else ! 219: tag = NULL; ! 220: if (tag) ! 221: { ! 222: Com_sprintf (entry, sizeof(entry), ! 223: "xv %i yv %i picn %s ",x+32, y, tag); ! 224: j = strlen(entry); ! 225: if (stringlength + j > 1024) ! 226: break; ! 227: strcpy (string + stringlength, entry); ! 228: stringlength += j; ! 229: } ! 230: ! 231: // send the layout ! 232: Com_sprintf (entry, sizeof(entry), ! 233: "client %i %i %i %i %i %i ", ! 234: x, y, sorted[i], cl->resp.score, cl->ping, (level.framenum - cl->resp.enterframe)/600); ! 235: j = strlen(entry); ! 236: if (stringlength + j > 1024) ! 237: break; ! 238: strcpy (string + stringlength, entry); ! 239: stringlength += j; ! 240: } ! 241: ! 242: gi.WriteByte (svc_layout); ! 243: gi.WriteString (string); ! 244: } ! 245: ! 246: ! 247: /* ! 248: ================== ! 249: DeathmatchScoreboard ! 250: ! 251: Draw instead of help message. ! 252: Note that it isn't that hard to overflow the 1400 byte message limit! ! 253: ================== ! 254: */ ! 255: void DeathmatchScoreboard (edict_t *ent) ! 256: { ! 257: DeathmatchScoreboardMessage (ent, ent->enemy); ! 258: gi.unicast (ent, true); ! 259: } ! 260: ! 261: ! 262: /* ! 263: ================== ! 264: Cmd_Score_f ! 265: ! 266: Display the scoreboard ! 267: ================== ! 268: */ ! 269: void Cmd_Score_f (edict_t *ent) ! 270: { ! 271: ent->client->showinventory = false; ! 272: ent->client->showhelp = false; ! 273: //ZOID ! 274: if (ent->client->menu) ! 275: PMenu_Close(ent); ! 276: //ZOID ! 277: ! 278: if (!deathmatch->value && !coop->value) ! 279: return; ! 280: ! 281: if (ent->client->showscores) ! 282: { ! 283: ent->client->showscores = false; ! 284: ent->client->update_chase = true; ! 285: return; ! 286: } ! 287: ! 288: ent->client->showscores = true; ! 289: ! 290: DeathmatchScoreboard (ent); ! 291: } ! 292: ! 293: ! 294: /* ! 295: ================== ! 296: HelpComputer ! 297: ! 298: Draw help computer. ! 299: ================== ! 300: */ ! 301: void HelpComputer (edict_t *ent) ! 302: { ! 303: char string[1024]; ! 304: char *sk; ! 305: ! 306: if (skill->value == 0) ! 307: sk = "easy"; ! 308: else if (skill->value == 1) ! 309: sk = "medium"; ! 310: else if (skill->value == 2) ! 311: sk = "hard"; ! 312: else ! 313: sk = "hard+"; ! 314: ! 315: // send the layout ! 316: Com_sprintf (string, sizeof(string), ! 317: "xv 32 yv 8 picn help " // background ! 318: "xv 202 yv 12 string2 \"%s\" " // skill ! 319: "xv 0 yv 24 cstring2 \"%s\" " // level name ! 320: "xv 0 yv 54 cstring2 \"%s\" " // help 1 ! 321: "xv 0 yv 110 cstring2 \"%s\" " // help 2 ! 322: "xv 50 yv 164 string2 \" kills goals secrets\" " ! 323: "xv 50 yv 172 string2 \"%3i/%3i %i/%i %i/%i\" ", ! 324: sk, ! 325: level.level_name, ! 326: game.helpmessage1, ! 327: game.helpmessage2, ! 328: level.killed_monsters, level.total_monsters, ! 329: level.found_goals, level.total_goals, ! 330: level.found_secrets, level.total_secrets); ! 331: ! 332: gi.WriteByte (svc_layout); ! 333: gi.WriteString (string); ! 334: gi.unicast (ent, true); ! 335: } ! 336: ! 337: ! 338: /* ! 339: ================== ! 340: Cmd_Help_f ! 341: ! 342: Display the current help message ! 343: ================== ! 344: */ ! 345: void Cmd_Help_f (edict_t *ent) ! 346: { ! 347: // this is for backwards compatability ! 348: if (deathmatch->value) ! 349: { ! 350: Cmd_Score_f (ent); ! 351: return; ! 352: } ! 353: ! 354: ent->client->showinventory = false; ! 355: ent->client->showscores = false; ! 356: ! 357: if (ent->client->showhelp && (ent->client->resp.game_helpchanged == game.helpchanged)) ! 358: { ! 359: ent->client->showhelp = false; ! 360: return; ! 361: } ! 362: ! 363: ent->client->showhelp = true; ! 364: ent->client->resp.helpchanged = 0; ! 365: HelpComputer (ent); ! 366: } ! 367: ! 368: ! 369: //======================================================================= ! 370: ! 371: /* ! 372: =============== ! 373: G_SetStats ! 374: =============== ! 375: */ ! 376: void G_SetStats (edict_t *ent) ! 377: { ! 378: gitem_t *item; ! 379: int index, cells; ! 380: int power_armor_type; ! 381: ! 382: // ! 383: // health ! 384: // ! 385: ent->client->ps.stats[STAT_HEALTH_ICON] = level.pic_health; ! 386: ent->client->ps.stats[STAT_HEALTH] = ent->health; ! 387: ! 388: // ! 389: // ammo ! 390: // ! 391: if (!ent->client->ammo_index /* || !ent->client->pers.inventory[ent->client->ammo_index] */) ! 392: { ! 393: ent->client->ps.stats[STAT_AMMO_ICON] = 0; ! 394: ent->client->ps.stats[STAT_AMMO] = 0; ! 395: } ! 396: else ! 397: { ! 398: item = &itemlist[ent->client->ammo_index]; ! 399: ent->client->ps.stats[STAT_AMMO_ICON] = gi.imageindex (item->icon); ! 400: ent->client->ps.stats[STAT_AMMO] = ent->client->pers.inventory[ent->client->ammo_index]; ! 401: } ! 402: ! 403: // ! 404: // armor ! 405: // ! 406: power_armor_type = PowerArmorType (ent); ! 407: if (power_armor_type) ! 408: { ! 409: cells = ent->client->pers.inventory[ITEM_INDEX(FindItem ("cells"))]; ! 410: if (cells == 0) ! 411: { // ran out of cells for power armor ! 412: ent->flags &= ~FL_POWER_ARMOR; ! 413: gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/power2.wav"), 1, ATTN_NORM, 0); ! 414: power_armor_type = 0;; ! 415: } ! 416: } ! 417: ! 418: index = ArmorIndex (ent); ! 419: if (power_armor_type && (!index || (level.framenum & 8) ) ) ! 420: { // flash between power armor and other armor icon ! 421: ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex ("i_powershield"); ! 422: ent->client->ps.stats[STAT_ARMOR] = cells; ! 423: } ! 424: else if (index) ! 425: { ! 426: item = GetItemByIndex (index); ! 427: ent->client->ps.stats[STAT_ARMOR_ICON] = gi.imageindex (item->icon); ! 428: ent->client->ps.stats[STAT_ARMOR] = ent->client->pers.inventory[index]; ! 429: } ! 430: else ! 431: { ! 432: ent->client->ps.stats[STAT_ARMOR_ICON] = 0; ! 433: ent->client->ps.stats[STAT_ARMOR] = 0; ! 434: } ! 435: ! 436: // ! 437: // pickup message ! 438: // ! 439: if (level.time > ent->client->pickup_msg_time) ! 440: { ! 441: ent->client->ps.stats[STAT_PICKUP_ICON] = 0; ! 442: ent->client->ps.stats[STAT_PICKUP_STRING] = 0; ! 443: } ! 444: ! 445: // ! 446: // timers ! 447: // ! 448: if (ent->client->quad_framenum > level.framenum) ! 449: { ! 450: ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_quad"); ! 451: ent->client->ps.stats[STAT_TIMER] = (ent->client->quad_framenum - level.framenum)/10; ! 452: } ! 453: else if (ent->client->invincible_framenum > level.framenum) ! 454: { ! 455: ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_invulnerability"); ! 456: ent->client->ps.stats[STAT_TIMER] = (ent->client->invincible_framenum - level.framenum)/10; ! 457: } ! 458: else if (ent->client->enviro_framenum > level.framenum) ! 459: { ! 460: ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_envirosuit"); ! 461: ent->client->ps.stats[STAT_TIMER] = (ent->client->enviro_framenum - level.framenum)/10; ! 462: } ! 463: else if (ent->client->breather_framenum > level.framenum) ! 464: { ! 465: ent->client->ps.stats[STAT_TIMER_ICON] = gi.imageindex ("p_rebreather"); ! 466: ent->client->ps.stats[STAT_TIMER] = (ent->client->breather_framenum - level.framenum)/10; ! 467: } ! 468: else ! 469: { ! 470: ent->client->ps.stats[STAT_TIMER_ICON] = 0; ! 471: ent->client->ps.stats[STAT_TIMER] = 0; ! 472: } ! 473: ! 474: // ! 475: // selected item ! 476: // ! 477: if (ent->client->pers.selected_item == -1) ! 478: ent->client->ps.stats[STAT_SELECTED_ICON] = 0; ! 479: else ! 480: ent->client->ps.stats[STAT_SELECTED_ICON] = gi.imageindex (itemlist[ent->client->pers.selected_item].icon); ! 481: ! 482: ent->client->ps.stats[STAT_SELECTED_ITEM] = ent->client->pers.selected_item; ! 483: ! 484: // ! 485: // layouts ! 486: // ! 487: ent->client->ps.stats[STAT_LAYOUTS] = 0; ! 488: ! 489: if (deathmatch->value) ! 490: { ! 491: if (ent->client->pers.health <= 0 || level.intermissiontime ! 492: || ent->client->showscores) ! 493: ent->client->ps.stats[STAT_LAYOUTS] |= 1; ! 494: if (ent->client->showinventory && ent->client->pers.health > 0) ! 495: ent->client->ps.stats[STAT_LAYOUTS] |= 2; ! 496: } ! 497: else ! 498: { ! 499: if (ent->client->showscores || ent->client->showhelp) ! 500: ent->client->ps.stats[STAT_LAYOUTS] |= 1; ! 501: if (ent->client->showinventory && ent->client->pers.health > 0) ! 502: ent->client->ps.stats[STAT_LAYOUTS] |= 2; ! 503: } ! 504: ! 505: // ! 506: // frags ! 507: // ! 508: ent->client->ps.stats[STAT_FRAGS] = ent->client->resp.score; ! 509: ! 510: // ! 511: // help icon / current weapon if not shown ! 512: // ! 513: if (ent->client->resp.helpchanged && (level.framenum&8) ) ! 514: ent->client->ps.stats[STAT_HELPICON] = gi.imageindex ("i_help"); ! 515: else if ( (ent->client->pers.hand == CENTER_HANDED || ent->client->ps.fov > 91) ! 516: && ent->client->pers.weapon) ! 517: ent->client->ps.stats[STAT_HELPICON] = gi.imageindex (ent->client->pers.weapon->icon); ! 518: else ! 519: ent->client->ps.stats[STAT_HELPICON] = 0; ! 520: ! 521: //ZOID ! 522: SetCTFStats(ent); ! 523: //ZOID ! 524: } ! 525:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.