00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "g_local.h"
00025
00026
00027 typedef struct teamgame_s {
00028 float last_flag_capture;
00029 int last_capture_team;
00030 flagStatus_t redStatus;
00031 flagStatus_t blueStatus;
00032 flagStatus_t flagStatus;
00033 int redTakenTime;
00034 int blueTakenTime;
00035 int redObeliskAttackedTime;
00036 int blueObeliskAttackedTime;
00037 } teamgame_t;
00038
00039 teamgame_t teamgame;
00040
00041 gentity_t *neutralObelisk;
00042
00043 void Team_SetFlagStatus( int team, flagStatus_t status );
00044
00045 void Team_InitGame( void ) {
00046 memset(&teamgame, 0, sizeof teamgame);
00047
00048 switch( g_gametype.integer ) {
00049 case GT_CTF:
00050 teamgame.redStatus = teamgame.blueStatus = -1;
00051 Team_SetFlagStatus( TEAM_RED, FLAG_ATBASE );
00052 Team_SetFlagStatus( TEAM_BLUE, FLAG_ATBASE );
00053 break;
00054 #ifdef MISSIONPACK
00055 case GT_1FCTF:
00056 teamgame.flagStatus = -1;
00057 Team_SetFlagStatus( TEAM_FREE, FLAG_ATBASE );
00058 break;
00059 #endif
00060 default:
00061 break;
00062 }
00063 }
00064
00065 int OtherTeam(int team) {
00066 if (team==TEAM_RED)
00067 return TEAM_BLUE;
00068 else if (team==TEAM_BLUE)
00069 return TEAM_RED;
00070 return team;
00071 }
00072
00073 const char *TeamName(int team) {
00074 if (team==TEAM_RED)
00075 return "RED";
00076 else if (team==TEAM_BLUE)
00077 return "BLUE";
00078 else if (team==TEAM_SPECTATOR)
00079 return "SPECTATOR";
00080 return "FREE";
00081 }
00082
00083 const char *OtherTeamName(int team) {
00084 if (team==TEAM_RED)
00085 return "BLUE";
00086 else if (team==TEAM_BLUE)
00087 return "RED";
00088 else if (team==TEAM_SPECTATOR)
00089 return "SPECTATOR";
00090 return "FREE";
00091 }
00092
00093 const char *TeamColorString(int team) {
00094 if (team==TEAM_RED)
00095 return S_COLOR_RED;
00096 else if (team==TEAM_BLUE)
00097 return S_COLOR_BLUE;
00098 else if (team==TEAM_SPECTATOR)
00099 return S_COLOR_YELLOW;
00100 return S_COLOR_WHITE;
00101 }
00102
00103
00104 void QDECL PrintMsg( gentity_t *ent, const char *fmt, ... ) {
00105 char msg[1024];
00106 va_list argptr;
00107 char *p;
00108
00109 va_start (argptr,fmt);
00110 if (vsprintf (msg, fmt, argptr) > sizeof(msg)) {
00111 G_Error ( "PrintMsg overrun" );
00112 }
00113 va_end (argptr);
00114
00115
00116 while ((p = strchr(msg, '"')) != NULL)
00117 *p = '\'';
00118
00119 trap_SendServerCommand ( ( (ent == NULL) ? -1 : ent-g_entities ), va("print \"%s\"", msg ));
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 void AddTeamScore(vec3_t origin, int team, int score) {
00131 gentity_t *te;
00132
00133 te = G_TempEntity(origin, EV_GLOBAL_TEAM_SOUND );
00134 te->r.svFlags |= SVF_BROADCAST;
00135
00136 if ( team == TEAM_RED ) {
00137 if ( level.teamScores[ TEAM_RED ] + score == level.teamScores[ TEAM_BLUE ] ) {
00138
00139 te->s.eventParm = GTS_TEAMS_ARE_TIED;
00140 }
00141 else if ( level.teamScores[ TEAM_RED ] <= level.teamScores[ TEAM_BLUE ] &&
00142 level.teamScores[ TEAM_RED ] + score > level.teamScores[ TEAM_BLUE ]) {
00143
00144 te->s.eventParm = GTS_REDTEAM_TOOK_LEAD;
00145 }
00146 else {
00147
00148 te->s.eventParm = GTS_REDTEAM_SCORED;
00149 }
00150 }
00151 else {
00152 if ( level.teamScores[ TEAM_BLUE ] + score == level.teamScores[ TEAM_RED ] ) {
00153
00154 te->s.eventParm = GTS_TEAMS_ARE_TIED;
00155 }
00156 else if ( level.teamScores[ TEAM_BLUE ] <= level.teamScores[ TEAM_RED ] &&
00157 level.teamScores[ TEAM_BLUE ] + score > level.teamScores[ TEAM_RED ]) {
00158
00159 te->s.eventParm = GTS_BLUETEAM_TOOK_LEAD;
00160 }
00161 else {
00162
00163 te->s.eventParm = GTS_BLUETEAM_SCORED;
00164 }
00165 }
00166 level.teamScores[ team ] += score;
00167 }
00168
00169
00170
00171
00172
00173
00174 qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 ) {
00175 if ( !ent1->client || !ent2->client ) {
00176 return qfalse;
00177 }
00178
00179 if ( g_gametype.integer < GT_TEAM ) {
00180 return qfalse;
00181 }
00182
00183 if ( ent1->client->sess.sessionTeam == ent2->client->sess.sessionTeam ) {
00184 return qtrue;
00185 }
00186
00187 return qfalse;
00188 }
00189
00190
00191 static char ctfFlagStatusRemap[] = { '0', '1', '*', '*', '2' };
00192 static char oneFlagStatusRemap[] = { '0', '1', '2', '3', '4' };
00193
00194 void Team_SetFlagStatus( int team, flagStatus_t status ) {
00195 qboolean modified = qfalse;
00196
00197 switch( team ) {
00198 case TEAM_RED:
00199 if( teamgame.redStatus != status ) {
00200 teamgame.redStatus = status;
00201 modified = qtrue;
00202 }
00203 break;
00204
00205 case TEAM_BLUE:
00206 if( teamgame.blueStatus != status ) {
00207 teamgame.blueStatus = status;
00208 modified = qtrue;
00209 }
00210 break;
00211
00212 case TEAM_FREE:
00213 if( teamgame.flagStatus != status ) {
00214 teamgame.flagStatus = status;
00215 modified = qtrue;
00216 }
00217 break;
00218 }
00219
00220 if( modified ) {
00221 char st[4];
00222
00223 if( g_gametype.integer == GT_CTF ) {
00224 st[0] = ctfFlagStatusRemap[teamgame.redStatus];
00225 st[1] = ctfFlagStatusRemap[teamgame.blueStatus];
00226 st[2] = 0;
00227 }
00228 else {
00229 st[0] = oneFlagStatusRemap[teamgame.flagStatus];
00230 st[1] = 0;
00231 }
00232
00233 trap_SetConfigstring( CS_FLAGSTATUS, st );
00234 }
00235 }
00236
00237 void Team_CheckDroppedItem( gentity_t *dropped ) {
00238 if( dropped->item->giTag == PW_REDFLAG ) {
00239 Team_SetFlagStatus( TEAM_RED, FLAG_DROPPED );
00240 }
00241 else if( dropped->item->giTag == PW_BLUEFLAG ) {
00242 Team_SetFlagStatus( TEAM_BLUE, FLAG_DROPPED );
00243 }
00244 else if( dropped->item->giTag == PW_NEUTRALFLAG ) {
00245 Team_SetFlagStatus( TEAM_FREE, FLAG_DROPPED );
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254 void Team_ForceGesture(int team) {
00255 int i;
00256 gentity_t *ent;
00257
00258 for (i = 0; i < MAX_CLIENTS; i++) {
00259 ent = &g_entities[i];
00260 if (!ent->inuse)
00261 continue;
00262 if (!ent->client)
00263 continue;
00264 if (ent->client->sess.sessionTeam != team)
00265 continue;
00266
00267 ent->flags |= FL_FORCE_GESTURE;
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 void Team_FragBonuses(gentity_t *targ, gentity_t *inflictor, gentity_t *attacker)
00281 {
00282 int i;
00283 gentity_t *ent;
00284 int flag_pw, enemy_flag_pw;
00285 int otherteam;
00286 int tokens;
00287 gentity_t *flag, *carrier = NULL;
00288 char *c;
00289 vec3_t v1, v2;
00290 int team;
00291
00292
00293 if (!targ->client || !attacker->client || targ == attacker || OnSameTeam(targ, attacker))
00294 return;
00295
00296 team = targ->client->sess.sessionTeam;
00297 otherteam = OtherTeam(targ->client->sess.sessionTeam);
00298 if (otherteam < 0)
00299 return;
00300
00301
00302 if (team == TEAM_RED) {
00303 flag_pw = PW_REDFLAG;
00304 enemy_flag_pw = PW_BLUEFLAG;
00305 } else {
00306 flag_pw = PW_BLUEFLAG;
00307 enemy_flag_pw = PW_REDFLAG;
00308 }
00309
00310 if (g_gametype.integer == GT_1FCTF) {
00311 enemy_flag_pw = PW_NEUTRALFLAG;
00312 }
00313
00314
00315 tokens = 0;
00316 #ifdef MISSIONPACK
00317 if( g_gametype.integer == GT_HARVESTER ) {
00318 tokens = targ->client->ps.generic1;
00319 }
00320 #endif
00321 if (targ->client->ps.powerups[enemy_flag_pw]) {
00322 attacker->client->pers.teamState.lastfraggedcarrier = level.time;
00323 AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS);
00324 attacker->client->pers.teamState.fragcarrier++;
00325 PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's flag carrier!\n",
00326 attacker->client->pers.netname, TeamName(team));
00327
00328
00329
00330 for (i = 0; i < g_maxclients.integer; i++) {
00331 ent = g_entities + i;
00332 if (ent->inuse && ent->client->sess.sessionTeam == otherteam)
00333 ent->client->pers.teamState.lasthurtcarrier = 0;
00334 }
00335 return;
00336 }
00337
00338
00339 if (tokens) {
00340 attacker->client->pers.teamState.lastfraggedcarrier = level.time;
00341 AddScore(attacker, targ->r.currentOrigin, CTF_FRAG_CARRIER_BONUS * tokens * tokens);
00342 attacker->client->pers.teamState.fragcarrier++;
00343 PrintMsg(NULL, "%s" S_COLOR_WHITE " fragged %s's skull carrier!\n",
00344 attacker->client->pers.netname, TeamName(team));
00345
00346
00347
00348 for (i = 0; i < g_maxclients.integer; i++) {
00349 ent = g_entities + i;
00350 if (ent->inuse && ent->client->sess.sessionTeam == otherteam)
00351 ent->client->pers.teamState.lasthurtcarrier = 0;
00352 }
00353 return;
00354 }
00355
00356 if (targ->client->pers.teamState.lasthurtcarrier &&
00357 level.time - targ->client->pers.teamState.lasthurtcarrier < CTF_CARRIER_DANGER_PROTECT_TIMEOUT &&
00358 !attacker->client->ps.powerups[flag_pw]) {
00359
00360
00361 AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_DANGER_PROTECT_BONUS);
00362
00363 attacker->client->pers.teamState.carrierdefense++;
00364 targ->client->pers.teamState.lasthurtcarrier = 0;
00365
00366 attacker->client->ps.persistant[PERS_DEFEND_COUNT]++;
00367 team = attacker->client->sess.sessionTeam;
00368
00369 attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00370 attacker->client->ps.eFlags |= EF_AWARD_DEFEND;
00371 attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
00372
00373 return;
00374 }
00375
00376 if (targ->client->pers.teamState.lasthurtcarrier &&
00377 level.time - targ->client->pers.teamState.lasthurtcarrier < CTF_CARRIER_DANGER_PROTECT_TIMEOUT) {
00378
00379 AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_DANGER_PROTECT_BONUS);
00380
00381 attacker->client->pers.teamState.carrierdefense++;
00382 targ->client->pers.teamState.lasthurtcarrier = 0;
00383
00384 attacker->client->ps.persistant[PERS_DEFEND_COUNT]++;
00385 team = attacker->client->sess.sessionTeam;
00386
00387 attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00388 attacker->client->ps.eFlags |= EF_AWARD_DEFEND;
00389 attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
00390
00391 return;
00392 }
00393
00394
00395
00396
00397
00398 #ifdef MISSIONPACK
00399 if( g_gametype.integer == GT_OBELISK ) {
00400
00401 switch (attacker->client->sess.sessionTeam) {
00402 case TEAM_RED:
00403 c = "team_redobelisk";
00404 break;
00405 case TEAM_BLUE:
00406 c = "team_blueobelisk";
00407 break;
00408 default:
00409 return;
00410 }
00411
00412 } else if (g_gametype.integer == GT_HARVESTER ) {
00413
00414 c = "team_neutralobelisk";
00415 } else {
00416 #endif
00417
00418 switch (attacker->client->sess.sessionTeam) {
00419 case TEAM_RED:
00420 c = "team_CTF_redflag";
00421 break;
00422 case TEAM_BLUE:
00423 c = "team_CTF_blueflag";
00424 break;
00425 default:
00426 return;
00427 }
00428
00429 for (i = 0; i < g_maxclients.integer; i++) {
00430 carrier = g_entities + i;
00431 if (carrier->inuse && carrier->client->ps.powerups[flag_pw])
00432 break;
00433 carrier = NULL;
00434 }
00435 #ifdef MISSIONPACK
00436 }
00437 #endif
00438 flag = NULL;
00439 while ((flag = G_Find (flag, FOFS(classname), c)) != NULL) {
00440 if (!(flag->flags & FL_DROPPED_ITEM))
00441 break;
00442 }
00443
00444 if (!flag)
00445 return;
00446
00447
00448
00449
00450 VectorSubtract(targ->r.currentOrigin, flag->r.currentOrigin, v1);
00451 VectorSubtract(attacker->r.currentOrigin, flag->r.currentOrigin, v2);
00452
00453 if ( ( ( VectorLength(v1) < CTF_TARGET_PROTECT_RADIUS &&
00454 trap_InPVS(flag->r.currentOrigin, targ->r.currentOrigin ) ) ||
00455 ( VectorLength(v2) < CTF_TARGET_PROTECT_RADIUS &&
00456 trap_InPVS(flag->r.currentOrigin, attacker->r.currentOrigin ) ) ) &&
00457 attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) {
00458
00459
00460 AddScore(attacker, targ->r.currentOrigin, CTF_FLAG_DEFENSE_BONUS);
00461 attacker->client->pers.teamState.basedefense++;
00462
00463 attacker->client->ps.persistant[PERS_DEFEND_COUNT]++;
00464
00465 attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00466 attacker->client->ps.eFlags |= EF_AWARD_DEFEND;
00467 attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
00468
00469 return;
00470 }
00471
00472 if (carrier && carrier != attacker) {
00473 VectorSubtract(targ->r.currentOrigin, carrier->r.currentOrigin, v1);
00474 VectorSubtract(attacker->r.currentOrigin, carrier->r.currentOrigin, v1);
00475
00476 if ( ( ( VectorLength(v1) < CTF_ATTACKER_PROTECT_RADIUS &&
00477 trap_InPVS(carrier->r.currentOrigin, targ->r.currentOrigin ) ) ||
00478 ( VectorLength(v2) < CTF_ATTACKER_PROTECT_RADIUS &&
00479 trap_InPVS(carrier->r.currentOrigin, attacker->r.currentOrigin ) ) ) &&
00480 attacker->client->sess.sessionTeam != targ->client->sess.sessionTeam) {
00481 AddScore(attacker, targ->r.currentOrigin, CTF_CARRIER_PROTECT_BONUS);
00482 attacker->client->pers.teamState.carrierdefense++;
00483
00484 attacker->client->ps.persistant[PERS_DEFEND_COUNT]++;
00485
00486 attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00487 attacker->client->ps.eFlags |= EF_AWARD_DEFEND;
00488 attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
00489
00490 return;
00491 }
00492 }
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 void Team_CheckHurtCarrier(gentity_t *targ, gentity_t *attacker)
00504 {
00505 int flag_pw;
00506
00507 if (!targ->client || !attacker->client)
00508 return;
00509
00510 if (targ->client->sess.sessionTeam == TEAM_RED)
00511 flag_pw = PW_BLUEFLAG;
00512 else
00513 flag_pw = PW_REDFLAG;
00514
00515
00516 if (targ->client->ps.powerups[flag_pw] &&
00517 targ->client->sess.sessionTeam != attacker->client->sess.sessionTeam)
00518 attacker->client->pers.teamState.lasthurtcarrier = level.time;
00519
00520
00521 if (targ->client->ps.generic1 &&
00522 targ->client->sess.sessionTeam != attacker->client->sess.sessionTeam)
00523 attacker->client->pers.teamState.lasthurtcarrier = level.time;
00524 }
00525
00526
00527 gentity_t *Team_ResetFlag( int team ) {
00528 char *c;
00529 gentity_t *ent, *rent = NULL;
00530
00531 switch (team) {
00532 case TEAM_RED:
00533 c = "team_CTF_redflag";
00534 break;
00535 case TEAM_BLUE:
00536 c = "team_CTF_blueflag";
00537 break;
00538 case TEAM_FREE:
00539 c = "team_CTF_neutralflag";
00540 break;
00541 default:
00542 return NULL;
00543 }
00544
00545 ent = NULL;
00546 while ((ent = G_Find (ent, FOFS(classname), c)) != NULL) {
00547 if (ent->flags & FL_DROPPED_ITEM)
00548 G_FreeEntity(ent);
00549 else {
00550 rent = ent;
00551 RespawnItem(ent);
00552 }
00553 }
00554
00555 Team_SetFlagStatus( team, FLAG_ATBASE );
00556
00557 return rent;
00558 }
00559
00560 void Team_ResetFlags( void ) {
00561 if( g_gametype.integer == GT_CTF ) {
00562 Team_ResetFlag( TEAM_RED );
00563 Team_ResetFlag( TEAM_BLUE );
00564 }
00565 #ifdef MISSIONPACK
00566 else if( g_gametype.integer == GT_1FCTF ) {
00567 Team_ResetFlag( TEAM_FREE );
00568 }
00569 #endif
00570 }
00571
00572 void Team_ReturnFlagSound( gentity_t *ent, int team ) {
00573 gentity_t *te;
00574
00575 if (ent == NULL) {
00576 G_Printf ("Warning: NULL passed to Team_ReturnFlagSound\n");
00577 return;
00578 }
00579
00580 te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
00581 if( team == TEAM_BLUE ) {
00582 te->s.eventParm = GTS_RED_RETURN;
00583 }
00584 else {
00585 te->s.eventParm = GTS_BLUE_RETURN;
00586 }
00587 te->r.svFlags |= SVF_BROADCAST;
00588 }
00589
00590 void Team_TakeFlagSound( gentity_t *ent, int team ) {
00591 gentity_t *te;
00592
00593 if (ent == NULL) {
00594 G_Printf ("Warning: NULL passed to Team_TakeFlagSound\n");
00595 return;
00596 }
00597
00598
00599
00600 switch(team) {
00601 case TEAM_RED:
00602 if( teamgame.blueStatus != FLAG_ATBASE ) {
00603 if (teamgame.blueTakenTime > level.time - 10000)
00604 return;
00605 }
00606 teamgame.blueTakenTime = level.time;
00607 break;
00608
00609 case TEAM_BLUE:
00610 if( teamgame.redStatus != FLAG_ATBASE ) {
00611 if (teamgame.redTakenTime > level.time - 10000)
00612 return;
00613 }
00614 teamgame.redTakenTime = level.time;
00615 break;
00616 }
00617
00618 te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
00619 if( team == TEAM_BLUE ) {
00620 te->s.eventParm = GTS_RED_TAKEN;
00621 }
00622 else {
00623 te->s.eventParm = GTS_BLUE_TAKEN;
00624 }
00625 te->r.svFlags |= SVF_BROADCAST;
00626 }
00627
00628 void Team_CaptureFlagSound( gentity_t *ent, int team ) {
00629 gentity_t *te;
00630
00631 if (ent == NULL) {
00632 G_Printf ("Warning: NULL passed to Team_CaptureFlagSound\n");
00633 return;
00634 }
00635
00636 te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
00637 if( team == TEAM_BLUE ) {
00638 te->s.eventParm = GTS_BLUE_CAPTURE;
00639 }
00640 else {
00641 te->s.eventParm = GTS_RED_CAPTURE;
00642 }
00643 te->r.svFlags |= SVF_BROADCAST;
00644 }
00645
00646 void Team_ReturnFlag( int team ) {
00647 Team_ReturnFlagSound(Team_ResetFlag(team), team);
00648 if( team == TEAM_FREE ) {
00649 PrintMsg(NULL, "The flag has returned!\n" );
00650 }
00651 else {
00652 PrintMsg(NULL, "The %s flag has returned!\n", TeamName(team));
00653 }
00654 }
00655
00656 void Team_FreeEntity( gentity_t *ent ) {
00657 if( ent->item->giTag == PW_REDFLAG ) {
00658 Team_ReturnFlag( TEAM_RED );
00659 }
00660 else if( ent->item->giTag == PW_BLUEFLAG ) {
00661 Team_ReturnFlag( TEAM_BLUE );
00662 }
00663 else if( ent->item->giTag == PW_NEUTRALFLAG ) {
00664 Team_ReturnFlag( TEAM_FREE );
00665 }
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 void Team_DroppedFlagThink(gentity_t *ent) {
00678 int team = TEAM_FREE;
00679
00680 if( ent->item->giTag == PW_REDFLAG ) {
00681 team = TEAM_RED;
00682 }
00683 else if( ent->item->giTag == PW_BLUEFLAG ) {
00684 team = TEAM_BLUE;
00685 }
00686 else if( ent->item->giTag == PW_NEUTRALFLAG ) {
00687 team = TEAM_FREE;
00688 }
00689
00690 Team_ReturnFlagSound( Team_ResetFlag( team ), team );
00691
00692 }
00693
00694
00695
00696
00697
00698
00699
00700 int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
00701 int i;
00702 gentity_t *player;
00703 gclient_t *cl = other->client;
00704 int enemy_flag;
00705
00706 #ifdef MISSIONPACK
00707 if( g_gametype.integer == GT_1FCTF ) {
00708 enemy_flag = PW_NEUTRALFLAG;
00709 }
00710 else {
00711 #endif
00712 if (cl->sess.sessionTeam == TEAM_RED) {
00713 enemy_flag = PW_BLUEFLAG;
00714 } else {
00715 enemy_flag = PW_REDFLAG;
00716 }
00717
00718 if ( ent->flags & FL_DROPPED_ITEM ) {
00719
00720 PrintMsg( NULL, "%s" S_COLOR_WHITE " returned the %s flag!\n",
00721 cl->pers.netname, TeamName(team));
00722 AddScore(other, ent->r.currentOrigin, CTF_RECOVERY_BONUS);
00723 other->client->pers.teamState.flagrecovery++;
00724 other->client->pers.teamState.lastreturnedflag = level.time;
00725
00726 Team_ReturnFlagSound(Team_ResetFlag(team), team);
00727 return 0;
00728 }
00729 #ifdef MISSIONPACK
00730 }
00731 #endif
00732
00733
00734
00735 if (!cl->ps.powerups[enemy_flag])
00736 return 0;
00737 #ifdef MISSIONPACK
00738 if( g_gametype.integer == GT_1FCTF ) {
00739 PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the flag!\n", cl->pers.netname );
00740 }
00741 else {
00742 #endif
00743 PrintMsg( NULL, "%s" S_COLOR_WHITE " captured the %s flag!\n", cl->pers.netname, TeamName(OtherTeam(team)));
00744 #ifdef MISSIONPACK
00745 }
00746 #endif
00747
00748 cl->ps.powerups[enemy_flag] = 0;
00749
00750 teamgame.last_flag_capture = level.time;
00751 teamgame.last_capture_team = team;
00752
00753
00754 AddTeamScore(ent->s.pos.trBase, other->client->sess.sessionTeam, 1);
00755 Team_ForceGesture(other->client->sess.sessionTeam);
00756
00757 other->client->pers.teamState.captures++;
00758
00759 other->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00760 other->client->ps.eFlags |= EF_AWARD_CAP;
00761 other->client->rewardTime = level.time + REWARD_SPRITE_TIME;
00762 other->client->ps.persistant[PERS_CAPTURES]++;
00763
00764
00765 AddScore(other, ent->r.currentOrigin, CTF_CAPTURE_BONUS);
00766
00767 Team_CaptureFlagSound( ent, team );
00768
00769
00770 for (i = 0; i < g_maxclients.integer; i++) {
00771 player = &g_entities[i];
00772 if (!player->inuse)
00773 continue;
00774
00775 if (player->client->sess.sessionTeam !=
00776 cl->sess.sessionTeam) {
00777 player->client->pers.teamState.lasthurtcarrier = -5;
00778 } else if (player->client->sess.sessionTeam ==
00779 cl->sess.sessionTeam) {
00780 if (player != other)
00781 AddScore(player, ent->r.currentOrigin, CTF_TEAM_BONUS);
00782
00783 if (player->client->pers.teamState.lastreturnedflag +
00784 CTF_RETURN_FLAG_ASSIST_TIMEOUT > level.time) {
00785 AddScore (player, ent->r.currentOrigin, CTF_RETURN_FLAG_ASSIST_BONUS);
00786 other->client->pers.teamState.assists++;
00787
00788 player->client->ps.persistant[PERS_ASSIST_COUNT]++;
00789
00790 player->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00791 player->client->ps.eFlags |= EF_AWARD_ASSIST;
00792 player->client->rewardTime = level.time + REWARD_SPRITE_TIME;
00793
00794 } else if (player->client->pers.teamState.lastfraggedcarrier +
00795 CTF_FRAG_CARRIER_ASSIST_TIMEOUT > level.time) {
00796 AddScore(player, ent->r.currentOrigin, CTF_FRAG_CARRIER_ASSIST_BONUS);
00797 other->client->pers.teamState.assists++;
00798 player->client->ps.persistant[PERS_ASSIST_COUNT]++;
00799
00800 player->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00801 player->client->ps.eFlags |= EF_AWARD_ASSIST;
00802 player->client->rewardTime = level.time + REWARD_SPRITE_TIME;
00803 }
00804 }
00805 }
00806 Team_ResetFlags();
00807
00808 CalculateRanks();
00809
00810 return 0;
00811 }
00812
00813 int Team_TouchEnemyFlag( gentity_t *ent, gentity_t *other, int team ) {
00814 gclient_t *cl = other->client;
00815
00816 #ifdef MISSIONPACK
00817 if( g_gametype.integer == GT_1FCTF ) {
00818 PrintMsg (NULL, "%s" S_COLOR_WHITE " got the flag!\n", other->client->pers.netname );
00819
00820 cl->ps.powerups[PW_NEUTRALFLAG] = INT_MAX;
00821
00822 if( team == TEAM_RED ) {
00823 Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_RED );
00824 }
00825 else {
00826 Team_SetFlagStatus( TEAM_FREE, FLAG_TAKEN_BLUE );
00827 }
00828 }
00829 else{
00830 #endif
00831 PrintMsg (NULL, "%s" S_COLOR_WHITE " got the %s flag!\n",
00832 other->client->pers.netname, TeamName(team));
00833
00834 if (team == TEAM_RED)
00835 cl->ps.powerups[PW_REDFLAG] = INT_MAX;
00836 else
00837 cl->ps.powerups[PW_BLUEFLAG] = INT_MAX;
00838
00839 Team_SetFlagStatus( team, FLAG_TAKEN );
00840 #ifdef MISSIONPACK
00841 }
00842 #endif
00843
00844 AddScore(other, ent->r.currentOrigin, CTF_FLAG_BONUS);
00845 cl->pers.teamState.flagsince = level.time;
00846 Team_TakeFlagSound( ent, team );
00847
00848 return -1;
00849 }
00850
00851 int Pickup_Team( gentity_t *ent, gentity_t *other ) {
00852 int team;
00853 gclient_t *cl = other->client;
00854
00855 #ifdef MISSIONPACK
00856 if( g_gametype.integer == GT_OBELISK ) {
00857
00858 G_FreeEntity( ent );
00859 return 0;
00860 }
00861
00862 if( g_gametype.integer == GT_HARVESTER ) {
00863
00864 if( ent->spawnflags != cl->sess.sessionTeam ) {
00865 cl->ps.generic1 += 1;
00866 }
00867 G_FreeEntity( ent );
00868 return 0;
00869 }
00870 #endif
00871
00872 if( strcmp(ent->classname, "team_CTF_redflag") == 0 ) {
00873 team = TEAM_RED;
00874 }
00875 else if( strcmp(ent->classname, "team_CTF_blueflag") == 0 ) {
00876 team = TEAM_BLUE;
00877 }
00878 #ifdef MISSIONPACK
00879 else if( strcmp(ent->classname, "team_CTF_neutralflag") == 0 ) {
00880 team = TEAM_FREE;
00881 }
00882 #endif
00883 else {
00884 PrintMsg ( other, "Don't know what team the flag is on.\n");
00885 return 0;
00886 }
00887 #ifdef MISSIONPACK
00888 if( g_gametype.integer == GT_1FCTF ) {
00889 if( team == TEAM_FREE ) {
00890 return Team_TouchEnemyFlag( ent, other, cl->sess.sessionTeam );
00891 }
00892 if( team != cl->sess.sessionTeam) {
00893 return Team_TouchOurFlag( ent, other, cl->sess.sessionTeam );
00894 }
00895 return 0;
00896 }
00897 #endif
00898
00899 if( team == cl->sess.sessionTeam) {
00900 return Team_TouchOurFlag( ent, other, team );
00901 }
00902 return Team_TouchEnemyFlag( ent, other, team );
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912 gentity_t *Team_GetLocation(gentity_t *ent)
00913 {
00914 gentity_t *eloc, *best;
00915 float bestlen, len;
00916 vec3_t origin;
00917
00918 best = NULL;
00919 bestlen = 3*8192.0*8192.0;
00920
00921 VectorCopy( ent->r.currentOrigin, origin );
00922
00923 for (eloc = level.locationHead; eloc; eloc = eloc->nextTrain) {
00924 len = ( origin[0] - eloc->r.currentOrigin[0] ) * ( origin[0] - eloc->r.currentOrigin[0] )
00925 + ( origin[1] - eloc->r.currentOrigin[1] ) * ( origin[1] - eloc->r.currentOrigin[1] )
00926 + ( origin[2] - eloc->r.currentOrigin[2] ) * ( origin[2] - eloc->r.currentOrigin[2] );
00927
00928 if ( len > bestlen ) {
00929 continue;
00930 }
00931
00932 if ( !trap_InPVS( origin, eloc->r.currentOrigin ) ) {
00933 continue;
00934 }
00935
00936 bestlen = len;
00937 best = eloc;
00938 }
00939
00940 return best;
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 qboolean Team_GetLocationMsg(gentity_t *ent, char *loc, int loclen)
00952 {
00953 gentity_t *best;
00954
00955 best = Team_GetLocation( ent );
00956
00957 if (!best)
00958 return qfalse;
00959
00960 if (best->count) {
00961 if (best->count < 0)
00962 best->count = 0;
00963 if (best->count > 7)
00964 best->count = 7;
00965 Com_sprintf(loc, loclen, "%c%c%s" S_COLOR_WHITE, Q_COLOR_ESCAPE, best->count + '0', best->message );
00966 } else
00967 Com_sprintf(loc, loclen, "%s", best->message);
00968
00969 return qtrue;
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982 #define MAX_TEAM_SPAWN_POINTS 32
00983 gentity_t *SelectRandomTeamSpawnPoint( int teamstate, team_t team ) {
00984 gentity_t *spot;
00985 int count;
00986 int selection;
00987 gentity_t *spots[MAX_TEAM_SPAWN_POINTS];
00988 char *classname;
00989
00990 if (teamstate == TEAM_BEGIN) {
00991 if (team == TEAM_RED)
00992 classname = "team_CTF_redplayer";
00993 else if (team == TEAM_BLUE)
00994 classname = "team_CTF_blueplayer";
00995 else
00996 return NULL;
00997 } else {
00998 if (team == TEAM_RED)
00999 classname = "team_CTF_redspawn";
01000 else if (team == TEAM_BLUE)
01001 classname = "team_CTF_bluespawn";
01002 else
01003 return NULL;
01004 }
01005 count = 0;
01006
01007 spot = NULL;
01008
01009 while ((spot = G_Find (spot, FOFS(classname), classname)) != NULL) {
01010 if ( SpotWouldTelefrag( spot ) ) {
01011 continue;
01012 }
01013 spots[ count ] = spot;
01014 if (++count == MAX_TEAM_SPAWN_POINTS)
01015 break;
01016 }
01017
01018 if ( !count ) {
01019 return G_Find( NULL, FOFS(classname), classname);
01020 }
01021
01022 selection = rand() % count;
01023 return spots[ selection ];
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033 gentity_t *SelectCTFSpawnPoint ( team_t team, int teamstate, vec3_t origin, vec3_t angles ) {
01034 gentity_t *spot;
01035
01036 spot = SelectRandomTeamSpawnPoint ( teamstate, team );
01037
01038 if (!spot) {
01039 return SelectSpawnPoint( vec3_origin, origin, angles );
01040 }
01041
01042 VectorCopy (spot->s.origin, origin);
01043 origin[2] += 9;
01044 VectorCopy (spot->s.angles, angles);
01045
01046 return spot;
01047 }
01048
01049
01050
01051 static int QDECL SortClients( const void *a, const void *b ) {
01052 return *(int *)a - *(int *)b;
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065 void TeamplayInfoMessage( gentity_t *ent ) {
01066 char entry[1024];
01067 char string[8192];
01068 int stringlength;
01069 int i, j;
01070 gentity_t *player;
01071 int cnt;
01072 int h, a;
01073 int clients[TEAM_MAXOVERLAY];
01074
01075 if ( ! ent->client->pers.teamInfo )
01076 return;
01077
01078
01079
01080
01081 for (i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) {
01082 player = g_entities + level.sortedClients[i];
01083 if (player->inuse && player->client->sess.sessionTeam ==
01084 ent->client->sess.sessionTeam ) {
01085 clients[cnt++] = level.sortedClients[i];
01086 }
01087 }
01088
01089
01090 qsort( clients, cnt, sizeof( clients[0] ), SortClients );
01091
01092
01093 string[0] = 0;
01094 stringlength = 0;
01095
01096 for (i = 0, cnt = 0; i < g_maxclients.integer && cnt < TEAM_MAXOVERLAY; i++) {
01097 player = g_entities + i;
01098 if (player->inuse && player->client->sess.sessionTeam ==
01099 ent->client->sess.sessionTeam ) {
01100
01101 h = player->client->ps.stats[STAT_HEALTH];
01102 a = player->client->ps.stats[STAT_ARMOR];
01103 if (h < 0) h = 0;
01104 if (a < 0) a = 0;
01105
01106 Com_sprintf (entry, sizeof(entry),
01107 " %i %i %i %i %i %i",
01108
01109 i, player->client->pers.teamState.location, h, a,
01110 player->client->ps.weapon, player->s.powerups);
01111 j = strlen(entry);
01112 if (stringlength + j > sizeof(string))
01113 break;
01114 strcpy (string + stringlength, entry);
01115 stringlength += j;
01116 cnt++;
01117 }
01118 }
01119
01120 trap_SendServerCommand( ent-g_entities, va("tinfo %i %s", cnt, string) );
01121 }
01122
01123 void CheckTeamStatus(void) {
01124 int i;
01125 gentity_t *loc, *ent;
01126
01127 if (level.time - level.lastTeamLocationTime > TEAM_LOCATION_UPDATE_TIME) {
01128
01129 level.lastTeamLocationTime = level.time;
01130
01131 for (i = 0; i < g_maxclients.integer; i++) {
01132 ent = g_entities + i;
01133
01134 if ( ent->client->pers.connected != CON_CONNECTED ) {
01135 continue;
01136 }
01137
01138 if (ent->inuse && (ent->client->sess.sessionTeam == TEAM_RED || ent->client->sess.sessionTeam == TEAM_BLUE)) {
01139 loc = Team_GetLocation( ent );
01140 if (loc)
01141 ent->client->pers.teamState.location = loc->health;
01142 else
01143 ent->client->pers.teamState.location = 0;
01144 }
01145 }
01146
01147 for (i = 0; i < g_maxclients.integer; i++) {
01148 ent = g_entities + i;
01149
01150 if ( ent->client->pers.connected != CON_CONNECTED ) {
01151 continue;
01152 }
01153
01154 if (ent->inuse && (ent->client->sess.sessionTeam == TEAM_RED || ent->client->sess.sessionTeam == TEAM_BLUE)) {
01155 TeamplayInfoMessage( ent );
01156 }
01157 }
01158 }
01159 }
01160
01161
01162
01163
01164
01165
01166 void SP_team_CTF_redplayer( gentity_t *ent ) {
01167 }
01168
01169
01170
01171
01172
01173 void SP_team_CTF_blueplayer( gentity_t *ent ) {
01174 }
01175
01176
01177
01178
01179
01180
01181 void SP_team_CTF_redspawn(gentity_t *ent) {
01182 }
01183
01184
01185
01186
01187
01188 void SP_team_CTF_bluespawn(gentity_t *ent) {
01189 }
01190
01191
01192 #ifdef MISSIONPACK
01193
01194
01195
01196
01197
01198
01199 static void ObeliskRegen( gentity_t *self ) {
01200 self->nextthink = level.time + g_obeliskRegenPeriod.integer * 1000;
01201 if( self->health >= g_obeliskHealth.integer ) {
01202 return;
01203 }
01204
01205 G_AddEvent( self, EV_POWERUP_REGEN, 0 );
01206 self->health += g_obeliskRegenAmount.integer;
01207 if ( self->health > g_obeliskHealth.integer ) {
01208 self->health = g_obeliskHealth.integer;
01209 }
01210
01211 self->activator->s.modelindex2 = self->health * 0xff / g_obeliskHealth.integer;
01212 self->activator->s.frame = 0;
01213 }
01214
01215
01216 static void ObeliskRespawn( gentity_t *self ) {
01217 self->takedamage = qtrue;
01218 self->health = g_obeliskHealth.integer;
01219
01220 self->think = ObeliskRegen;
01221 self->nextthink = level.time + g_obeliskRegenPeriod.integer * 1000;
01222
01223 self->activator->s.frame = 0;
01224 }
01225
01226
01227 static void ObeliskDie( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod ) {
01228 int otherTeam;
01229
01230 otherTeam = OtherTeam( self->spawnflags );
01231 AddTeamScore(self->s.pos.trBase, otherTeam, 1);
01232 Team_ForceGesture(otherTeam);
01233
01234 CalculateRanks();
01235
01236 self->takedamage = qfalse;
01237 self->think = ObeliskRespawn;
01238 self->nextthink = level.time + g_obeliskRespawnDelay.integer * 1000;
01239
01240 self->activator->s.modelindex2 = 0xff;
01241 self->activator->s.frame = 2;
01242
01243 G_AddEvent( self->activator, EV_OBELISKEXPLODE, 0 );
01244
01245 AddScore(attacker, self->r.currentOrigin, CTF_CAPTURE_BONUS);
01246
01247
01248 attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
01249 attacker->client->ps.eFlags |= EF_AWARD_CAP;
01250 attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME;
01251 attacker->client->ps.persistant[PERS_CAPTURES]++;
01252
01253 teamgame.redObeliskAttackedTime = 0;
01254 teamgame.blueObeliskAttackedTime = 0;
01255 }
01256
01257
01258 static void ObeliskTouch( gentity_t *self, gentity_t *other, trace_t *trace ) {
01259 int tokens;
01260
01261 if ( !other->client ) {
01262 return;
01263 }
01264
01265 if ( OtherTeam(other->client->sess.sessionTeam) != self->spawnflags ) {
01266 return;
01267 }
01268
01269 tokens = other->client->ps.generic1;
01270 if( tokens <= 0 ) {
01271 return;
01272 }
01273
01274 PrintMsg(NULL, "%s" S_COLOR_WHITE " brought in %i skull%s.\n",
01275 other->client->pers.netname, tokens, tokens ? "s" : "" );
01276
01277 AddTeamScore(self->s.pos.trBase, other->client->sess.sessionTeam, tokens);
01278 Team_ForceGesture(other->client->sess.sessionTeam);
01279
01280 AddScore(other, self->r.currentOrigin, CTF_CAPTURE_BONUS*tokens);
01281
01282
01283 other->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
01284 other->client->ps.eFlags |= EF_AWARD_CAP;
01285 other->client->rewardTime = level.time + REWARD_SPRITE_TIME;
01286 other->client->ps.persistant[PERS_CAPTURES] += tokens;
01287
01288 other->client->ps.generic1 = 0;
01289 CalculateRanks();
01290
01291 Team_CaptureFlagSound( self, self->spawnflags );
01292 }
01293
01294 static void ObeliskPain( gentity_t *self, gentity_t *attacker, int damage ) {
01295 int actualDamage = damage / 10;
01296 if (actualDamage <= 0) {
01297 actualDamage = 1;
01298 }
01299 self->activator->s.modelindex2 = self->health * 0xff / g_obeliskHealth.integer;
01300 if (!self->activator->s.frame) {
01301 G_AddEvent(self, EV_OBELISKPAIN, 0);
01302 }
01303 self->activator->s.frame = 1;
01304 AddScore(attacker, self->r.currentOrigin, actualDamage);
01305 }
01306
01307 gentity_t *SpawnObelisk( vec3_t origin, int team, int spawnflags) {
01308 trace_t tr;
01309 vec3_t dest;
01310 gentity_t *ent;
01311
01312 ent = G_Spawn();
01313
01314 VectorCopy( origin, ent->s.origin );
01315 VectorCopy( origin, ent->s.pos.trBase );
01316 VectorCopy( origin, ent->r.currentOrigin );
01317
01318 VectorSet( ent->r.mins, -15, -15, 0 );
01319 VectorSet( ent->r.maxs, 15, 15, 87 );
01320
01321 ent->s.eType = ET_GENERAL;
01322 ent->flags = FL_NO_KNOCKBACK;
01323
01324 if( g_gametype.integer == GT_OBELISK ) {
01325 ent->r.contents = CONTENTS_SOLID;
01326 ent->takedamage = qtrue;
01327 ent->health = g_obeliskHealth.integer;
01328 ent->die = ObeliskDie;
01329 ent->pain = ObeliskPain;
01330 ent->think = ObeliskRegen;
01331 ent->nextthink = level.time + g_obeliskRegenPeriod.integer * 1000;
01332 }
01333 if( g_gametype.integer == GT_HARVESTER ) {
01334 ent->r.contents = CONTENTS_TRIGGER;
01335 ent->touch = ObeliskTouch;
01336 }
01337
01338 if ( spawnflags & 1 ) {
01339
01340 G_SetOrigin( ent, ent->s.origin );
01341 } else {
01342
01343
01344 ent->s.origin[2] += 1;
01345
01346
01347 VectorSet( dest, ent->s.origin[0], ent->s.origin[1], ent->s.origin[2] - 4096 );
01348 trap_Trace( &tr, ent->s.origin, ent->r.mins, ent->r.maxs, dest, ent->s.number, MASK_SOLID );
01349 if ( tr.startsolid ) {
01350 ent->s.origin[2] -= 1;
01351 G_Printf( "SpawnObelisk: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin) );
01352
01353 ent->s.groundEntityNum = ENTITYNUM_NONE;
01354 G_SetOrigin( ent, ent->s.origin );
01355 }
01356 else {
01357
01358 ent->s.groundEntityNum = tr.entityNum;
01359 G_SetOrigin( ent, tr.endpos );
01360 }
01361 }
01362
01363 ent->spawnflags = team;
01364
01365 trap_LinkEntity( ent );
01366
01367 return ent;
01368 }
01369
01370
01371
01372 void SP_team_redobelisk( gentity_t *ent ) {
01373 gentity_t *obelisk;
01374
01375 if ( g_gametype.integer <= GT_TEAM ) {
01376 G_FreeEntity(ent);
01377 return;
01378 }
01379 ent->s.eType = ET_TEAM;
01380 if ( g_gametype.integer == GT_OBELISK ) {
01381 obelisk = SpawnObelisk( ent->s.origin, TEAM_RED, ent->spawnflags );
01382 obelisk->activator = ent;
01383
01384 ent->s.modelindex2 = 0xff;
01385 ent->s.frame = 0;
01386 }
01387 if ( g_gametype.integer == GT_HARVESTER ) {
01388 obelisk = SpawnObelisk( ent->s.origin, TEAM_RED, ent->spawnflags );
01389 obelisk->activator = ent;
01390 }
01391 ent->s.modelindex = TEAM_RED;
01392 trap_LinkEntity(ent);
01393 }
01394
01395
01396
01397 void SP_team_blueobelisk( gentity_t *ent ) {
01398 gentity_t *obelisk;
01399
01400 if ( g_gametype.integer <= GT_TEAM ) {
01401 G_FreeEntity(ent);
01402 return;
01403 }
01404 ent->s.eType = ET_TEAM;
01405 if ( g_gametype.integer == GT_OBELISK ) {
01406 obelisk = SpawnObelisk( ent->s.origin, TEAM_BLUE, ent->spawnflags );
01407 obelisk->activator = ent;
01408
01409 ent->s.modelindex2 = 0xff;
01410 ent->s.frame = 0;
01411 }
01412 if ( g_gametype.integer == GT_HARVESTER ) {
01413 obelisk = SpawnObelisk( ent->s.origin, TEAM_BLUE, ent->spawnflags );
01414 obelisk->activator = ent;
01415 }
01416 ent->s.modelindex = TEAM_BLUE;
01417 trap_LinkEntity(ent);
01418 }
01419
01420
01421
01422 void SP_team_neutralobelisk( gentity_t *ent ) {
01423 if ( g_gametype.integer != GT_1FCTF && g_gametype.integer != GT_HARVESTER ) {
01424 G_FreeEntity(ent);
01425 return;
01426 }
01427 ent->s.eType = ET_TEAM;
01428 if ( g_gametype.integer == GT_HARVESTER) {
01429 neutralObelisk = SpawnObelisk( ent->s.origin, TEAM_FREE, ent->spawnflags);
01430 neutralObelisk->spawnflags = TEAM_FREE;
01431 }
01432 ent->s.modelindex = TEAM_FREE;
01433 trap_LinkEntity(ent);
01434 }
01435
01436
01437
01438
01439
01440
01441
01442 qboolean CheckObeliskAttack( gentity_t *obelisk, gentity_t *attacker ) {
01443 gentity_t *te;
01444
01445
01446 if( obelisk->die != ObeliskDie ) {
01447 return qfalse;
01448 }
01449
01450
01451 if( !attacker->client ) {
01452 return qfalse;
01453 }
01454
01455
01456 if( obelisk->spawnflags == attacker->client->sess.sessionTeam ) {
01457 return qtrue;
01458 }
01459
01460
01461
01462
01463 if ((obelisk->spawnflags == TEAM_RED &&
01464 teamgame.redObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME) ||
01465 (obelisk->spawnflags == TEAM_BLUE &&
01466 teamgame.blueObeliskAttackedTime < level.time - OVERLOAD_ATTACK_BASE_SOUND_TIME) ) {
01467
01468
01469 te = G_TempEntity( obelisk->s.pos.trBase, EV_GLOBAL_TEAM_SOUND );
01470 if( obelisk->spawnflags == TEAM_RED ) {
01471 te->s.eventParm = GTS_REDOBELISK_ATTACKED;
01472 teamgame.redObeliskAttackedTime = level.time;
01473 }
01474 else {
01475 te->s.eventParm = GTS_BLUEOBELISK_ATTACKED;
01476 teamgame.blueObeliskAttackedTime = level.time;
01477 }
01478 te->r.svFlags |= SVF_BROADCAST;
01479 }
01480
01481 return qfalse;
01482 }
01483 #endif