Changeset 68:9d65d8683e8d
- Timestamp:
- 11/21/07 00:48:04 (3 years ago)
- Branch:
- tjw-1.2
- convert_revision:
- svn:7c786126-522e-0410-a822-d6d8feae56ca/branches/tjw-1.2@89
- Location:
- src/game
- Files:
-
- 9 modified
-
g_active.c (modified) (6 diffs)
-
g_buildable.c (modified) (4 diffs)
-
g_client.c (modified) (27 diffs)
-
g_cmds.c (modified) (15 diffs)
-
g_combat.c (modified) (1 diff)
-
g_local.h (modified) (5 diffs)
-
g_main.c (modified) (5 diffs)
-
g_misc.c (modified) (1 diff)
-
g_ptr.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/game/g_active.c
r66 r68 376 376 pmove_t pm; 377 377 gclient_t *client; 378 qboolean attack1, attack3; 378 379 qboolean doPmove = qtrue; 379 380 … … 382 383 client->oldbuttons = client->buttons; 383 384 client->buttons = ucmd->buttons; 385 386 attack1 = ( ( client->buttons & BUTTON_ATTACK ) && 387 !( client->oldbuttons & BUTTON_ATTACK ) ); 388 attack3 = ( ( client->buttons & BUTTON_USE_HOLDABLE ) && 389 !( client->oldbuttons & BUTTON_USE_HOLDABLE ) ); 384 390 385 391 if( client->sess.spectatorState == SPECTATOR_LOCKED || client->sess.spectatorState == SPECTATOR_FOLLOW ) … … 401 407 if (doPmove) 402 408 { 409 // in case the client entered the queue while following a teammate 410 if( ( client->pers.teamSelection == PTE_ALIENS && 411 G_SearchSpawnQueue( &level.alienSpawnQueue, ent-g_entities ) ) || 412 ( client->pers.teamSelection == PTE_HUMANS && 413 G_SearchSpawnQueue( &level.humanSpawnQueue, ent-g_entities ) ) ) 414 { 415 client->ps.pm_flags |= PMF_QUEUED; 416 } 417 403 418 client->ps.speed = BG_FindSpeedForClass( client->ps.stats[ STAT_PCLASS ] ); 404 419 … … 426 441 trap_UnlinkEntity( ent ); 427 442 428 if( ( client->buttons & BUTTON_ATTACK ) && !( client->oldbuttons & BUTTON_ATTACK ) ) 429 { 430 //if waiting in a queue remove from the queue 431 if( client->ps.pm_flags & PMF_QUEUED ) 432 { 433 if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) 434 G_RemoveFromSpawnQueue( &level.alienSpawnQueue, client->ps.clientNum ); 435 else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) 436 G_RemoveFromSpawnQueue( &level.humanSpawnQueue, client->ps.clientNum ); 437 438 client->pers.classSelection = PCL_NONE; 439 client->ps.stats[ STAT_PCLASS ] = PCL_NONE; 440 } 441 else if( client->pers.classSelection == PCL_NONE ) 442 { 443 if( client->pers.teamSelection == PTE_NONE ) 444 G_TriggerMenu( client->ps.clientNum, MN_TEAM ); 445 else if( client->pers.teamSelection == PTE_ALIENS ) 446 G_TriggerMenu( client->ps.clientNum, MN_A_CLASS ); 447 else if( client->pers.teamSelection == PTE_HUMANS ) 448 G_TriggerMenu( client->ps.clientNum, MN_H_SPAWN ); 449 } 443 if( ( attack1 || attack3 ) && ( client->ps.pm_flags & PMF_QUEUED ) ) 444 { 445 if( client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS ) 446 G_RemoveFromSpawnQueue( &level.alienSpawnQueue, client->ps.clientNum ); 447 else if( client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) 448 G_RemoveFromSpawnQueue( &level.humanSpawnQueue, client->ps.clientNum ); 449 450 client->pers.classSelection = PCL_NONE; 451 client->ps.stats[ STAT_PCLASS ] = PCL_NONE; 452 } 453 454 if( attack1 && client->pers.classSelection == PCL_NONE ) 455 { 456 if( client->pers.teamSelection == PTE_NONE ) 457 G_TriggerMenu( client->ps.clientNum, MN_TEAM ); 458 else if( client->pers.teamSelection == PTE_ALIENS ) 459 G_TriggerMenu( client->ps.clientNum, MN_A_CLASS ); 460 else if( client->pers.teamSelection == PTE_HUMANS ) 461 G_TriggerMenu( client->ps.clientNum, MN_H_SPAWN ); 450 462 } 451 463 … … 466 478 } 467 479 468 if( ( client->buttons & BUTTON_USE_HOLDABLE ) && !( client->oldbuttons & BUTTON_USE_HOLDABLE ) ) 480 else if( attack1 && ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) 481 { 482 G_StopFollowing( ent ); 483 client->pers.classSelection = PCL_NONE; 484 if( client->pers.teamSelection == PTE_NONE ) 485 G_TriggerMenu( ent-g_entities, MN_TEAM ); 486 else if( client->pers.teamSelection == PTE_ALIENS ) 487 G_TriggerMenu( ent-g_entities, MN_A_CLASS ); 488 else if( client->pers.teamSelection == PTE_HUMANS ) 489 G_TriggerMenu( ent-g_entities, MN_H_SPAWN ); 490 } 491 492 if( attack3 ) 493 { 469 494 G_ToggleFollow( ent ); 495 } 470 496 } 471 497 … … 1905 1931 pers = &ent->client->pers; 1906 1932 1933 // save a copy of things from playerState in case of SPECTATOR_FOLLOW 1934 pers->score = ent->client->ps.persistant[ PERS_SCORE ]; 1935 pers->credit = ent->client->ps.persistant[ PERS_CREDIT ]; 1936 1907 1937 // 1908 1938 // If the end of unit layout is displayed, don't give -
src/game/g_buildable.c
r65 r68 1240 1240 VectorCopy( origin, player->client->ps.origin ); 1241 1241 VectorCopy( vec3_origin, player->client->ps.velocity ); 1242 SetClientViewAngle( player, angles );1242 G_SetClientViewAngle( player, angles ); 1243 1243 } 1244 1244 … … 1320 1320 G_SetOrigin( activator, hovelOrigin ); 1321 1321 VectorCopy( hovelOrigin, activator->client->ps.origin ); 1322 SetClientViewAngle( activator, hovelAngles );1322 G_SetClientViewAngle( activator, hovelAngles ); 1323 1323 } 1324 1324 } … … 1395 1395 G_SetOrigin( builder, newOrigin ); 1396 1396 VectorCopy( newOrigin, builder->client->ps.origin ); 1397 SetClientViewAngle( builder, newAngles );1397 G_SetClientViewAngle( builder, newAngles ); 1398 1398 1399 1399 //client leaves hovel … … 1837 1837 G_SetOrigin(activator,spawn_origin); 1838 1838 VectorCopy(spawn_origin,activator->client->ps.origin); 1839 SetClientViewAngle(activator,spawn_angles);1839 G_SetClientViewAngle(activator,spawn_angles); 1840 1840 1841 1841 // Play the spawn sound effect -
src/game/g_client.c
r65 r68 140 140 if( client->ps.persistant[ PERS_CREDIT ] < 0 ) 141 141 client->ps.persistant[ PERS_CREDIT ] = 0; 142 // keep PERS_CREDIT in sync if not following 143 if( client->sess.spectatorState != SPECTATOR_FOLLOW ) 144 client->ps.persistant[ PERS_CREDIT ] = client->pers.credit; 142 145 } 143 146 … … 146 149 ======================================================================= 147 150 148 SelectSpawnPoint151 G_SelectSpawnPoint 149 152 150 153 ======================================================================= … … 181 184 /* 182 185 ================ 183 SelectNearestDeathmatchSpawnPoint186 G_SelectNearestDeathmatchSpawnPoint 184 187 185 188 Find the spot that we DON'T want to use … … 187 190 */ 188 191 #define MAX_SPAWN_POINTS 128 189 gentity_t * SelectNearestDeathmatchSpawnPoint( vec3_t from )192 gentity_t *G_SelectNearestDeathmatchSpawnPoint( vec3_t from ) 190 193 { 191 194 gentity_t *spot; … … 216 219 /* 217 220 ================ 218 SelectRandomDeathmatchSpawnPoint221 G_SelectRandomDeathmatchSpawnPoint 219 222 220 223 go to a random point that doesn't telefrag … … 222 225 */ 223 226 #define MAX_SPAWN_POINTS 128 224 gentity_t * SelectRandomDeathmatchSpawnPoint( void )227 gentity_t *G_SelectRandomDeathmatchSpawnPoint( void ) 225 228 { 226 229 gentity_t *spot; … … 251 254 /* 252 255 =========== 253 SelectRandomFurthestSpawnPoint256 G_SelectRandomFurthestSpawnPoint 254 257 255 258 Chooses a player start, deathmatch start, etc 256 259 ============ 257 260 */ 258 gentity_t * SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles )261 gentity_t *G_SelectRandomFurthestSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) 259 262 { 260 263 gentity_t *spot; … … 334 337 /* 335 338 ================ 336 SelectAlienSpawnPoint339 G_SelectAlienSpawnPoint 337 340 338 341 go to a random point that doesn't telefrag 339 342 ================ 340 343 */ 341 gentity_t * SelectAlienSpawnPoint( vec3_t preference )344 gentity_t *G_SelectAlienSpawnPoint( vec3_t preference ) 342 345 { 343 346 gentity_t *spot; … … 383 386 /* 384 387 ================ 385 SelectHumanSpawnPoint388 G_SelectHumanSpawnPoint 386 389 387 390 go to a random point that doesn't telefrag 388 391 ================ 389 392 */ 390 gentity_t * SelectHumanSpawnPoint( vec3_t preference )393 gentity_t *G_SelectHumanSpawnPoint( vec3_t preference ) 391 394 { 392 395 gentity_t *spot; … … 432 435 /* 433 436 =========== 434 SelectSpawnPoint437 G_SelectSpawnPoint 435 438 436 439 Chooses a player start, deathmatch start, etc 437 440 ============ 438 441 */ 439 gentity_t * SelectSpawnPoint( vec3_t avoidPoint, vec3_t origin, vec3_t angles )440 { 441 return SelectRandomFurthestSpawnPoint( avoidPoint, origin, angles );442 gentity_t *G_SelectSpawnPoint( vec3_t avoidPoint, vec3_t origin, vec3_t angles ) 443 { 444 return G_SelectRandomFurthestSpawnPoint( avoidPoint, origin, angles ); 442 445 } 443 446 … … 445 448 /* 446 449 =========== 447 SelectTremulousSpawnPoint450 G_SelectTremulousSpawnPoint 448 451 449 452 Chooses a player start, deathmatch start, etc 450 453 ============ 451 454 */ 452 gentity_t * SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t origin, vec3_t angles )455 gentity_t *G_SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t origin, vec3_t angles ) 453 456 { 454 457 gentity_t *spot = NULL; 455 458 456 459 if( team == PTE_ALIENS ) 457 spot = SelectAlienSpawnPoint( preference );460 spot = G_SelectAlienSpawnPoint( preference ); 458 461 else if( team == PTE_HUMANS ) 459 spot = SelectHumanSpawnPoint( preference );462 spot = G_SelectHumanSpawnPoint( preference ); 460 463 461 464 //no available spots … … 478 481 /* 479 482 =========== 480 SelectInitialSpawnPoint483 G_SelectInitialSpawnPoint 481 484 482 485 Try to find a spawn point marked 'initial', otherwise … … 484 487 ============ 485 488 */ 486 gentity_t * SelectInitialSpawnPoint( vec3_t origin, vec3_t angles )489 gentity_t *G_SelectInitialSpawnPoint( vec3_t origin, vec3_t angles ) 487 490 { 488 491 gentity_t *spot; … … 497 500 if( !spot || SpotWouldTelefrag( spot ) ) 498 501 { 499 return SelectSpawnPoint( vec3_origin, origin, angles );502 return G_SelectSpawnPoint( vec3_origin, origin, angles ); 500 503 } 501 504 … … 509 512 /* 510 513 =========== 511 SelectSpectatorSpawnPoint514 G_SelectSpectatorSpawnPoint 512 515 513 516 ============ 514 517 */ 515 gentity_t * SelectSpectatorSpawnPoint( vec3_t origin, vec3_t angles )518 gentity_t *G_SelectSpectatorSpawnPoint( vec3_t origin, vec3_t angles ) 516 519 { 517 520 FindIntermissionPoint( ); … … 526 529 /* 527 530 =========== 528 SelectAlienLockSpawnPoint531 G_SelectAlienLockSpawnPoint 529 532 530 533 Try to find a spawn point for alien intermission otherwise … … 532 535 ============ 533 536 */ 534 gentity_t * SelectAlienLockSpawnPoint( vec3_t origin, vec3_t angles )537 gentity_t *G_SelectAlienLockSpawnPoint( vec3_t origin, vec3_t angles ) 535 538 { 536 539 gentity_t *spot; … … 540 543 541 544 if( !spot ) 542 return SelectSpectatorSpawnPoint( origin, angles );545 return G_SelectSpectatorSpawnPoint( origin, angles ); 543 546 544 547 VectorCopy( spot->s.origin, origin ); … … 551 554 /* 552 555 =========== 553 SelectHumanLockSpawnPoint556 G_SelectHumanLockSpawnPoint 554 557 555 558 Try to find a spawn point for human intermission otherwise … … 557 560 ============ 558 561 */ 559 gentity_t * SelectHumanLockSpawnPoint( vec3_t origin, vec3_t angles )562 gentity_t *G_SelectHumanLockSpawnPoint( vec3_t origin, vec3_t angles ) 560 563 { 561 564 gentity_t *spot; … … 565 568 566 569 if( !spot ) 567 return SelectSpectatorSpawnPoint( origin, angles );570 return G_SelectSpectatorSpawnPoint( origin, angles ); 568 571 569 572 VectorCopy( spot->s.origin, origin ); … … 747 750 /* 748 751 ================== 749 SetClientViewAngle752 G_SetClientViewAngle 750 753 751 754 ================== 752 755 */ 753 void SetClientViewAngle( gentity_t *ent, vec3_t angle )756 void G_SetClientViewAngle( gentity_t *ent, vec3_t angle ) 754 757 { 755 758 int i; … … 1156 1159 strcpy( c2, Info_ValueForKey( userinfo, "color2" ) ); 1157 1160 1158 if( client->ps.pm_flags & PMF_FOLLOW ) 1159 team = PTE_NONE; 1160 else 1161 team = client->ps.stats[ STAT_PTEAM ]; 1161 team = client->pers.teamSelection; 1162 1162 1163 1163 // send over a subset of the userinfo keys so other clients can … … 1341 1341 client->pers.enterTime = level.time; 1342 1342 client->pers.teamState.state = TEAM_BEGIN; 1343 client->pers.classSelection = PCL_NONE; 1343 1344 1344 1345 // save eflags around this, because changing teams will … … 1463 1464 { 1464 1465 if( teamLocal == PTE_NONE ) 1465 spawnPoint = SelectSpectatorSpawnPoint( spawn_origin, spawn_angles );1466 spawnPoint = G_SelectSpectatorSpawnPoint( spawn_origin, spawn_angles ); 1466 1467 else if( teamLocal == PTE_ALIENS ) 1467 spawnPoint = SelectAlienLockSpawnPoint( spawn_origin, spawn_angles );1468 spawnPoint = G_SelectAlienLockSpawnPoint( spawn_origin, spawn_angles ); 1468 1469 else if( teamLocal == PTE_HUMANS ) 1469 spawnPoint = SelectHumanLockSpawnPoint( spawn_origin, spawn_angles );1470 spawnPoint = G_SelectHumanLockSpawnPoint( spawn_origin, spawn_angles ); 1470 1471 } 1471 1472 else … … 1522 1523 client->ps.persistant[ PERS_SPAWN_COUNT ]++; 1523 1524 client->ps.persistant[ PERS_TEAM ] = client->sess.sessionTeam; 1525 1526 // restore really persistant things 1527 client->ps.persistant[ PERS_SCORE ] = client->pers.score; 1528 client->ps.persistant[ PERS_CREDIT ] = client->pers.credit; 1524 1529 1525 1530 client->airOutTime = level.time + 12000; … … 1648 1653 1649 1654 trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd ); 1650 SetClientViewAngle( ent, spawn_angles );1655 G_SetClientViewAngle( ent, spawn_angles ); 1651 1656 1652 1657 if( !( client->sess.sessionTeam == TEAM_SPECTATOR ) ) -
src/game/g_cmds.c
r67 r68 264 264 if( cl->pers.connected == CON_CONNECTING ) 265 265 ping = -1; 266 else if( cl->sess.spectatorState == SPECTATOR_FOLLOW ) 267 ping = cl->pers.ping < 999 ? cl->pers.ping : 999; 266 268 else 267 269 ping = cl->ps.ping < 999 ? cl->ps.ping : 999; 268 270 269 if( cl-> ps.stats[ STAT_HEALTH ] > 0)271 if( cl->sess.sessionTeam != TEAM_SPECTATOR ) 270 272 { 271 273 weapon = cl->ps.weapon; … … 556 558 if( ent->client && ent->client->pers.connected == CON_CONNECTED ) 557 559 { 558 // stop following clients559 if( ent->client->sess.sessionTeam == TEAM_SPECTATOR &&560 ent->client->sess.spectatorState == SPECTATOR_FOLLOW &&561 ent->client->sess.spectatorClient == self->client->ps.clientNum )562 {563 if( !G_FollowNewClient( ent, 1 ) )564 G_StopFollowing( ent );565 }566 560 // cure poison 567 561 if( ent->client->ps.stats[ STAT_STATE ] & SS_POISONCLOUDED && … … 596 590 && ( level.time - ent->client->pers.teamChangeTime ) > 60000 ) ) 597 591 { 598 if( oldTeam == PTE_NONE ) 599 { 600 // ps.persistant[] from a spectator cannot be trusted 601 ent->client->ps.persistant[ PERS_SCORE ] = ent->client->pers.savedScore; 602 ent->client->ps.persistant[ PERS_CREDIT ] = ent->client->pers.savedCredit; 603 } 604 else if( oldTeam == PTE_ALIENS ) 605 { 606 // always save in human credtis 607 ent->client->ps.persistant[ PERS_CREDIT ] *= 608 (float)FREEKILL_HUMAN / FREEKILL_ALIEN; 609 } 610 611 if( newTeam == PTE_NONE ) 612 { 613 // save values before the client enters the spectator team and their 614 // ps.persistant[] values become trashed 615 ent->client->pers.savedScore = ent->client->ps.persistant[ PERS_SCORE ]; 616 ent->client->pers.savedCredit = ent->client->ps.persistant[ PERS_CREDIT ]; 617 } 592 if( oldTeam == PTE_ALIENS ) 593 ent->client->pers.credit *= (float)FREEKILL_HUMAN / FREEKILL_ALIEN; 618 594 else if( newTeam == PTE_ALIENS ) 619 { 620 // convert to alien currency 621 ent->client->ps.persistant[ PERS_CREDIT ] *= 622 (float)FREEKILL_ALIEN / FREEKILL_HUMAN; 623 } 595 ent->client->pers.credit *= (float)FREEKILL_ALIEN / FREEKILL_HUMAN; 624 596 } 625 597 else 626 598 { 627 ent->client->ps.persistant[ PERS_CREDIT ] = 0; 628 ent->client->ps.persistant[ PERS_SCORE ] = 0; 629 ent->client->pers.savedScore = 0; 630 ent->client->pers.savedCredit = 0; 599 ent->client->pers.credit = 0; 600 ent->client->pers.score = 0; 631 601 } 632 602 … … 698 668 //guard against build timer exploit 699 669 if( ent->client->pers.teamSelection != PTE_NONE && 670 ent->client->sess.sessionTeam != TEAM_SPECTATOR && 700 671 ( ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0 || 701 672 ent->client->ps.stats[ STAT_PCLASS ] == PCL_ALIEN_BUILDER0_UPG || … … 1622 1593 trace_t tr, tr2; 1623 1594 vec3_t infestOrigin; 1624 int allowedClasses[ PCL_NUM_CLASSES ];1625 int numClasses = 0;1626 1595 pClass_t currentClass = ent->client->ps.stats[ STAT_PCLASS ]; 1627 1596 pClass_t newClass; … … 1638 1607 qboolean humanNear = qfalse; 1639 1608 1640 if( ent->client->ps.stats[ STAT_HEALTH ] <= 0 )1641 return;1642 1643 1609 clientNum = ent->client - level.clients; 1644 1610 trap_Argv( 1, s, sizeof( s ) ); 1645 1646 if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) ) 1647 allowedClasses[ numClasses++ ] = PCL_ALIEN_BUILDER0; 1648 1649 if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0_UPG ) && 1650 BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, g_alienStage.integer ) ) 1651 allowedClasses[ numClasses++ ] = PCL_ALIEN_BUILDER0_UPG; 1652 1653 if( BG_ClassIsAllowed( PCL_ALIEN_LEVEL0 ) ) 1654 allowedClasses[ numClasses++ ] = PCL_ALIEN_LEVEL0; 1611 newClass = BG_FindClassNumForName( s ); 1612 1613 if( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) 1614 { 1615 if( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) 1616 G_StopFollowing( ent ); 1617 if( ent->client->pers.teamSelection == PTE_ALIENS ) 1618 { 1619 if( newClass != PCL_ALIEN_BUILDER0 && 1620 newClass != PCL_ALIEN_BUILDER0_UPG && 1621 newClass != PCL_ALIEN_LEVEL0 ) 1622 { 1623 trap_SendServerCommand( ent-g_entities, 1624 va( "print \"You cannot spawn with class %s\n\"", s ) ); 1625 return; 1626 } 1627 1628 if( !BG_ClassIsAllowed( newClass ) ) 1629 { 1630 trap_SendServerCommand( ent-g_entities, 1631 va( "print \"Class %s is not allowed\n\"", s ) ); 1632 return; 1633 } 1634 if( !BG_FindStagesForClass( newClass, g_alienStage.integer ) ) 1635 { 1636 trap_SendServerCommand( ent-g_entities, 1637 va( "print \"Class %s not allowed at stage %d\n\"", 1638 s, g_alienStage.integer ) ); 1639 return; 1640 } 1641 1642 // spawn from an egg 1643 if( G_PushSpawnQueue( &level.alienSpawnQueue, clientNum ) ) 1644 { 1645 ent->client->pers.classSelection = newClass; 1646 ent->client->ps.stats[ STAT_PCLASS ] = newClass; 1647 } 1648 } 1649 else if( ent->client->pers.teamSelection == PTE_HUMANS ) 1650 { 1651 //set the item to spawn with 1652 if( !Q_stricmp( s, BG_FindNameForWeapon( WP_MACHINEGUN ) ) && 1653 BG_WeaponIsAllowed( WP_MACHINEGUN ) ) 1654 { 1655 ent->client->pers.humanItemSelection = WP_MACHINEGUN; 1656 } 1657 else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD ) ) && 1658 BG_WeaponIsAllowed( WP_HBUILD ) ) 1659 { 1660 ent->client->pers.humanItemSelection = WP_HBUILD; 1661 } 1662 else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD2 ) ) && 1663 BG_WeaponIsAllowed( WP_HBUILD2 ) && 1664 BG_FindStagesForWeapon( WP_HBUILD2, g_humanStage.integer ) ) 1665 { 1666 ent->client->pers.humanItemSelection = WP_HBUILD2; 1667 } 1668 else 1669 { 1670 trap_SendServerCommand( ent-g_entities, 1671 "print \"Unknown starting item\n\"" ); 1672 return; 1673 } 1674 // spawn from a telenode 1675 if( G_PushSpawnQueue( &level.humanSpawnQueue, clientNum ) ) 1676 { 1677 ent->client->pers.classSelection = PCL_HUMAN; 1678 ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN; 1679 } 1680 } 1681 return; 1682 } 1683 1684 if( ent->health <= 0 ) 1685 return; 1655 1686 1656 1687 if( ent->client->pers.teamSelection == PTE_ALIENS && … … 1658 1689 !( ent->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) ) 1659 1690 { 1660 newClass = BG_FindClassNumForName( s );1661 1691 if( newClass == PCL_NONE ) 1662 1692 { 1663 trap_SendServerCommand( ent-g_entities, va( "print \"Unknown class\n\"" ));1693 trap_SendServerCommand( ent-g_entities, "print \"Unknown class\n\"" ); 1664 1694 return; 1665 1695 } … … 1716 1746 1717 1747 //guard against selling the HBUILD weapons exploit 1718 if( ( currentClass == PCL_ALIEN_BUILDER0 || 1748 if( ent->client->sess.sessionTeam != TEAM_SPECTATOR && 1749 ( currentClass == PCL_ALIEN_BUILDER0 || 1719 1750 currentClass == PCL_ALIEN_BUILDER0_UPG ) && 1720 1751 ent->client->ps.stats[ STAT_MISC ] > 0 ) … … 1792 1823 } 1793 1824 } 1794 else1795 {1796 //spawning from an egg1797 for( i = 0; i < numClasses; i++ )1798 {1799 if( allowedClasses[ i ] == newClass &&1800 BG_FindStagesForClass( newClass, g_alienStage.integer ) &&1801 BG_ClassIsAllowed( newClass ) )1802 {1803 G_LogOnlyPrintf("ClientTeamClass: %i alien %s\n", clientNum, s);1804 1805 ent->client->pers.classSelection =1806 ent->client->ps.stats[ STAT_PCLASS ] = newClass;1807 G_PushSpawnQueue( &level.alienSpawnQueue, clientNum );1808 return;1809 }1810 }1811 trap_SendServerCommand( ent-g_entities, va( "print \"You cannot spawn as this class\n\"" ) );1812 return;1813 }1814 1825 } 1815 1826 else if( ent->client->pers.teamSelection == PTE_HUMANS ) 1816 1827 { 1817 1828 //humans cannot use this command whilst alive 1818 if( ent->client->pers.classSelection != PCL_NONE ) 1819 { 1820 trap_SendServerCommand( ent-g_entities, va( "print \"You must be dead to use the class command\n\"" ) ); 1821 return; 1822 } 1823 1824 ent->client->pers.classSelection = 1825 ent->client->ps.stats[ STAT_PCLASS ] = PCL_HUMAN; 1826 1827 //set the item to spawn with 1828 if( !Q_stricmp( s, BG_FindNameForWeapon( WP_MACHINEGUN ) ) && BG_WeaponIsAllowed( WP_MACHINEGUN ) ) 1829 ent->client->pers.humanItemSelection = WP_MACHINEGUN; 1830 else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD ) ) && BG_WeaponIsAllowed( WP_HBUILD ) ) 1831 ent->client->pers.humanItemSelection = WP_HBUILD; 1832 else if( !Q_stricmp( s, BG_FindNameForWeapon( WP_HBUILD2 ) ) && BG_WeaponIsAllowed( WP_HBUILD2 ) && 1833 BG_FindStagesForWeapon( WP_HBUILD2, g_humanStage.integer ) ) 1834 ent->client->pers.humanItemSelection = WP_HBUILD2; 1835 else 1836 { 1837 ent->client->pers.classSelection = PCL_NONE; 1838 trap_SendServerCommand( ent-g_entities, va( "print \"Unknown starting item\n\"" ) ); 1839 return; 1840 } 1841 1842 G_LogOnlyPrintf("ClientTeamClass: %i human %s\n", clientNum, s); 1843 1844 G_PushSpawnQueue( &level.humanSpawnQueue, clientNum ); 1829 trap_SendServerCommand( ent-g_entities, 1830 "print \"You must be dead to use the class command\n\"" ); 1831 return; 1845 1832 } 1846 1833 } … … 2786 2773 /* 2787 2774 ================= 2775 G_StopFromFollowing 2776 2777 stops any other clients from following this one 2778 called when a player leaves a team or dies 2779 ================= 2780 */ 2781 void G_StopFromFollowing( gentity_t *ent ) 2782 { 2783 int i; 2784 2785 for( i = 0; i < level.maxclients; i++ ) 2786 { 2787 if( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR && 2788 level.clients[ i ].sess.spectatorState == SPECTATOR_FOLLOW && 2789 level.clients[ i ].sess.spectatorClient == ent->client->ps.clientNum ) 2790 { 2791 if( !G_FollowNewClient( &g_entities[ i ], 1 ) ) 2792 G_StopFollowing( &g_entities[ i ] ); 2793 } 2794 } 2795 } 2796 2797 /* 2798 ================= 2788 2799 G_StopFollowing 2789 2800 … … 2796 2807 ent->client->ps.persistant[ PERS_TEAM ] = TEAM_SPECTATOR; 2797 2808 ent->client->sess.sessionTeam = TEAM_SPECTATOR; 2798 ent->client->sess.spectatorState = SPECTATOR_FREE; 2809 ent->client->ps.stats[ STAT_PTEAM ] = ent->client->pers.teamSelection; 2810 2811 if( ent->client->pers.teamSelection == PTE_NONE ) 2812 { 2813 ent->client->sess.spectatorState = SPECTATOR_FREE; 2814 } 2815 else 2816 { 2817 vec3_t spawn_origin, spawn_angles; 2818 2819 ent->client->sess.spectatorState = SPECTATOR_LOCKED; 2820 if( ent->client->pers.teamSelection == PTE_ALIENS ) 2821 G_SelectAlienLockSpawnPoint( spawn_origin, spawn_angles ); 2822 else if( ent->client->pers.teamSelection == PTE_HUMANS ) 2823 G_SelectHumanLockSpawnPoint( spawn_origin, spawn_angles ); 2824 G_SetOrigin( ent, spawn_origin ); 2825 VectorCopy( spawn_origin, ent->client->ps.origin ); 2826 G_SetClientViewAngle( ent, spawn_angles ); 2827 } 2799 2828 ent->client->sess.spectatorClient = -1; 2800 2829 ent->client->ps.pm_flags &= ~PMF_FOLLOW; 2801 ent->client->ps.stats[ STAT_PTEAM ] = PTE_NONE;2802 2830 2803 2831 ent->client->ps.stats[ STAT_STATE ] &= ~SS_WALLCLIMBING; … … 2864 2892 2865 2893 // can't follow another spectator 2866 if( level.clients[ clientnum ].pers.teamSelection == PTE_NONE ) 2894 if( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) 2895 continue; 2896 2897 // can only follow teammates when dead and on a team 2898 if( ent->client->pers.teamSelection != PTE_NONE && 2899 ( level.clients[ clientnum ].pers.teamSelection != 2900 ent->client->pers.teamSelection ) ) 2867 2901 continue; 2868 2902 … … 3007 3041 3008 3042 // won't work unless spectating 3043 if( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) 3044 return; 3009 3045 if( ent->client->sess.spectatorState == SPECTATOR_NOT ) 3010 3046 return; … … 3211 3247 { "donate", CMD_TEAM, Cmd_Donate_f }, 3212 3248 3213 { "follow", CMD_ NOTEAM, Cmd_Follow_f },3214 { "follownext", CMD_ NOTEAM, Cmd_FollowCycle_f },3215 { "followprev", CMD_ NOTEAM, Cmd_FollowCycle_f },3249 { "follow", CMD_SPEC, Cmd_Follow_f }, 3250 { "follownext", CMD_SPEC, Cmd_FollowCycle_f }, 3251 { "followprev", CMD_SPEC, Cmd_FollowCycle_f }, 3216 3252 3217 3253 { "where", CMD_TEAM, Cmd_Where_f }, … … 3285 3321 } 3286 3322 3287 if( cmds[ i ].cmdFlags & CMD_ NOTEAM&&3288 ent->client-> pers.teamSelection != PTE_NONE)3323 if( cmds[ i ].cmdFlags & CMD_SPEC && 3324 ent->client->sess.sessionTeam != TEAM_SPECTATOR ) 3289 3325 { 3290 3326 trap_SendServerCommand( clientNum, 3291 "print \" Cannot use this command when on a team\n\"" );3327 "print \"You can only use this command when spectating\n\"" ); 3292 3328 return; 3293 3329 } -
src/game/g_combat.c
r1 r68 148 148 // stop any following clients 149 149 // r1: removed, annoying. 150 // G_StopFromFollowing( self ); 150 151 151 152 self->client->ps.pm_type = PM_DEAD; -
src/game/g_local.h
r66 r68 346 346 int nameChanges; 347 347 348 // used to save p ersistant[]values while in SPECTATOR_FOLLOW mode349 int s avedScore;350 int savedCredit;348 // used to save playerState_t values while in SPECTATOR_FOLLOW mode 349 int score; 350 int credit; 351 351 int ping; 352 352 … … 484 484 int G_PopSpawnQueue( spawnQueue_t *sq ); 485 485 int G_PeekSpawnQueue( spawnQueue_t *sq ); 486 void G_PushSpawnQueue( spawnQueue_t *sq, int clientNum ); 486 qboolean G_SearchSpawnQueue( spawnQueue_t *sq, int clientNum ); 487 qboolean G_PushSpawnQueue( spawnQueue_t *sq, int clientNum ); 487 488 qboolean G_RemoveFromSpawnQueue( spawnQueue_t *sq, int clientNum ); 488 489 int G_GetPosInSpawnQueue( spawnQueue_t *sq, int clientNum ); … … 670 671 #define CMD_MESSAGE 0x02 // sends message to others (skip when muted) 671 672 #define CMD_TEAM 0x04 // must be on a team 672 #define CMD_ NOTEAM 0x08 // must not be on a team673 #define CMD_SPEC 0x08 // must be in spectator mode 673 674 #define CMD_ALIEN 0x10 674 675 #define CMD_HUMAN 0x20 … … 698 699 // 699 700 void Cmd_Score_f( gentity_t *ent ); 701 void G_StopFromFollowing( gentity_t *ent ); 700 702 void G_StopFollowing( gentity_t *ent ); 701 703 qboolean G_FollowNewClient( gentity_t *ent, int dir ); … … 917 919 void G_AddCreditToClient( gclient_t *client, short credit, qboolean cap ); 918 920 team_t TeamCount( int ignoreClientNum, int team ); 919 void SetClientViewAngle( gentity_t *ent, vec3_t angle ); 920 gentity_t *SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t origin, vec3_t angles ); 921 gentity_t *SelectSpawnPoint( vec3_t avoidPoint, vec3_t origin, vec3_t angles ); 921 void G_SetClientViewAngle( gentity_t *ent, vec3_t angle ); 922 gentity_t *G_SelectTremulousSpawnPoint( pTeam_t team, vec3_t preference, vec3_t origin, vec3_t angles ); 923 gentity_t *G_SelectSpawnPoint( vec3_t avoidPoint, vec3_t origin, vec3_t angles ); 924 gentity_t *G_SelectAlienLockSpawnPoint( vec3_t origin, vec3_t angles ); 925 gentity_t *G_SelectHumanLockSpawnPoint( vec3_t origin, vec3_t angles ); 922 926 void SpawnCorpse( gentity_t *ent ); 923 927 void respawn( gentity_t *ent ); -
src/game/g_main.c
r66 r68 821 821 822 822 // then sort by score 823 if( ca->p s.persistant[ PERS_SCORE ] > cb->ps.persistant[ PERS_SCORE ])823 if( ca->pers.score > cb->pers.score ) 824 824 return -1; 825 else if( ca->p s.persistant[ PERS_SCORE ] < cb->ps.persistant[ PERS_SCORE ])825 else if( ca->pers.score < cb->pers.score ) 826 826 return 1; 827 827 else … … 905 905 /* 906 906 ============ 907 G_SearchSpawnQueue 908 909 Look to see if clientNum is already in the spawnQueue 910 ============ 911 */ 912 qboolean G_SearchSpawnQueue( spawnQueue_t *sq, int clientNum ) 913 { 914 int i; 915 916 for( i = 0; i < MAX_CLIENTS; i++ ) 917 if( sq->clients[ i ] == clientNum ) 918 return qtrue; 919 return qfalse; 920 } 921 922 /* 923 ============ 907 924 G_PushSpawnQueue 908 925 … … 910 927 ============ 911 928 */ 912 void G_PushSpawnQueue( spawnQueue_t *sq, int clientNum ) 913 { 929 qboolean G_PushSpawnQueue( spawnQueue_t *sq, int clientNum ) 930 { 931 // don't add the same client more than once 932 if( G_SearchSpawnQueue( sq, clientNum ) ) 933 return qfalse; 934 914 935 sq->back = QUEUE_PLUS1( sq->back ); 915 936 sq->clients[ sq->back ] = clientNum; 916 937 917 938 g_entities[ clientNum ].client->ps.pm_flags |= PMF_QUEUED; 939 return qtrue; 918 940 } 919 941 … … 1049 1071 ent = &g_entities[ clientNum ]; 1050 1072 1051 if( ( spawn = SelectTremulousSpawnPoint( team,1073 if( ( spawn = G_SelectTremulousSpawnPoint( team, 1052 1074 ent->client->pers.lastDeathLocation, 1053 1075 spawn_origin, spawn_angles ) ) ) … … 1585 1607 if( !ent ) 1586 1608 { // the map creator forgot to put in an intermission point... 1587 SelectSpawnPoint( vec3_origin, level.intermission_origin, level.intermission_angle );1609 G_SelectSpawnPoint( vec3_origin, level.intermission_origin, level.intermission_angle ); 1588 1610 } 1589 1611 else -
src/game/g_misc.c
r0 r68 90 90 91 91 // set angles 92 SetClientViewAngle( player, angles );92 G_SetClientViewAngle( player, angles ); 93 93 94 94 // kill anything at the destination -
src/game/g_ptr.c
r0 r68 64 64 client->pers.connection->clientTeam = client->pers.teamSelection; 65 65 if( client->pers.teamSelection == PTE_NONE ) 66 client->pers.connection->clientCredit = client->pers. savedCredit;66 client->pers.connection->clientCredit = client->pers.credit; 67 67 else 68 68 client->pers.connection->clientCredit = client->ps.persistant[ PERS_CREDIT ];
