Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

g_active.c File Reference

#include "g_local.h"

Include dependency graph for g_active.c:

Include dependency graph

Go to the source code of this file.

Functions

void BotTestSolid (vec3_t origin)
void ClientEndFrame (gentity_t *ent)
void ClientEvents (gentity_t *ent, int oldEventSequence)
void ClientImpacts (gentity_t *ent, pmove_t *pm)
qboolean ClientInactivityTimer (gclient_t *client)
void ClientIntermissionThink (gclient_t *client)
void ClientThink (int clientNum)
void ClientThink_real (gentity_t *ent)
void ClientTimerActions (gentity_t *ent, int msec)
void G_RunClient (gentity_t *ent)
void G_SetClientSound (gentity_t *ent)
void G_TouchTriggers (gentity_t *ent)
void P_DamageFeedback (gentity_t *player)
void P_WorldEffects (gentity_t *ent)
void SendPendingPredictableEvents (playerState_t *ps)
void SpectatorClientEndFrame (gentity_t *ent)
void SpectatorThink (gentity_t *ent, usercmd_t *ucmd)


Function Documentation

void BotTestSolid vec3_t  origin  ) 
 

void ClientEndFrame gentity_t ent  ) 
 

Definition at line 1107 of file g_active.c.

References bg_itemlist, BG_PlayerStateToEntityState(), BG_PlayerStateToEntityStateExtraPolate(), gentity_s::client, playerState_s::commandTime, entityState_s::eFlags, G_SetClientSound(), g_smoothClients, g_synchronousClients, gentity_t, gitem_s::giTag, gentity_s::health, i, vmCvar_t::integer, level_locals_t::intermissiontime, gclient_s::lastCmdTime, level, P_DamageFeedback(), P_WorldEffects(), gclient_s::pers, playerState_s::pm_type, playerState_s::powerups, gclient_s::ps, qtrue, gentity_s::s, SendPendingPredictableEvents(), gclient_s::sess, clientSession_t::sessionTeam, SpectatorClientEndFrame(), playerState_s::stats, level_locals_t::time, VectorClear, and playerState_s::viewangles.

Referenced by ClientSpawn(), and G_RunFrame().

01107                                       {
01108     int         i;
01109     clientPersistant_t  *pers;
01110 
01111     if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
01112         SpectatorClientEndFrame( ent );
01113         return;
01114     }
01115 
01116     pers = &ent->client->pers;
01117 
01118     // turn off any expired powerups
01119     for ( i = 0 ; i < MAX_POWERUPS ; i++ ) {
01120         if ( ent->client->ps.powerups[ i ] < level.time ) {
01121             ent->client->ps.powerups[ i ] = 0;
01122         }
01123     }
01124 
01125 #ifdef MISSIONPACK
01126     // set powerup for player animation
01127     if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
01128         ent->client->ps.powerups[PW_GUARD] = level.time;
01129     }
01130     if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
01131         ent->client->ps.powerups[PW_SCOUT] = level.time;
01132     }
01133     if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_DOUBLER ) {
01134         ent->client->ps.powerups[PW_DOUBLER] = level.time;
01135     }
01136     if( bg_itemlist[ent->client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
01137         ent->client->ps.powerups[PW_AMMOREGEN] = level.time;
01138     }
01139     if ( ent->client->invulnerabilityTime > level.time ) {
01140         ent->client->ps.powerups[PW_INVULNERABILITY] = level.time;
01141     }
01142 #endif
01143 
01144     // save network bandwidth
01145 #if 0
01146     if ( !g_synchronousClients->integer && ent->client->ps.pm_type == PM_NORMAL ) {
01147         // FIXME: this must change eventually for non-sync demo recording
01148         VectorClear( ent->client->ps.viewangles );
01149     }
01150 #endif
01151 
01152     //
01153     // If the end of unit layout is displayed, don't give
01154     // the player any normal movement attributes
01155     //
01156     if ( level.intermissiontime ) {
01157         return;
01158     }
01159 
01160     // burn from lava, etc
01161     P_WorldEffects (ent);
01162 
01163     // apply all the damage taken this frame
01164     P_DamageFeedback (ent);
01165 
01166     // add the EF_CONNECTION flag if we haven't gotten commands recently
01167     if ( level.time - ent->client->lastCmdTime > 1000 ) {
01168         ent->s.eFlags |= EF_CONNECTION;
01169     } else {
01170         ent->s.eFlags &= ~EF_CONNECTION;
01171     }
01172 
01173     ent->client->ps.stats[STAT_HEALTH] = ent->health;   // FIXME: get rid of ent->health...
01174 
01175     G_SetClientSound (ent);
01176 
01177     // set the latest infor
01178     if (g_smoothClients.integer) {
01179         BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue );
01180     }
01181     else {
01182         BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue );
01183     }
01184     SendPendingPredictableEvents( &ent->client->ps );
01185 
01186     // set the bit for the reachability area the client is currently in
01187 //  i = trap_AAS_PointReachabilityAreaIndex( ent->client->ps.origin );
01188 //  ent->client->areabits[i >> 3] |= 1 << (i & 7);
01189 }

Here is the call graph for this function:

void ClientEvents gentity_t ent,
int  oldEventSequence
 

Definition at line 537 of file g_active.c.

References BG_FindItem(), BG_FindItemForPowerup(), gentity_s::client, gentity_s::count, Drop_Item(), entityState_s::eType, EV_FALL_FAR, EV_FALL_MEDIUM, EV_FIRE_WEAPON, EV_USE_ITEM1, EV_USE_ITEM2, EV_USE_ITEM3, EV_USE_ITEM4, EV_USE_ITEM5, playerState_s::events, playerState_s::eventSequence, FireWeapon(), G_Damage(), g_dmflags, g_gametype, gclient_t, playerState_s::generic1, gentity_t, gitem_t, gentity_s::health, i, vmCvar_t::integer, j, level, MAX_PS_EVENTS, MOD_FALLING, NULL, playerState_s::origin, gentity_s::pain_debounce_time, playerState_s::powerups, gclient_s::ps, PW_BLUEFLAG, PW_NEUTRALFLAG, PW_REDFLAG, gentity_s::s, SelectSpawnPoint(), gclient_s::sess, clientSession_t::sessionTeam, gentity_s::spawnflags, playerState_s::stats, TeleportPlayer(), level_locals_t::time, vec3_t, and VectorSet.

Referenced by ClientThink_real().

00537                                                           {
00538     int     i, j;
00539     int     event;
00540     gclient_t *client;
00541     int     damage;
00542     vec3_t  dir;
00543     vec3_t  origin, angles;
00544 //  qboolean    fired;
00545     gitem_t *item;
00546     gentity_t *drop;
00547 
00548     client = ent->client;
00549 
00550     if ( oldEventSequence < client->ps.eventSequence - MAX_PS_EVENTS ) {
00551         oldEventSequence = client->ps.eventSequence - MAX_PS_EVENTS;
00552     }
00553     for ( i = oldEventSequence ; i < client->ps.eventSequence ; i++ ) {
00554         event = client->ps.events[ i & (MAX_PS_EVENTS-1) ];
00555 
00556         switch ( event ) {
00557         case EV_FALL_MEDIUM:
00558         case EV_FALL_FAR:
00559             if ( ent->s.eType != ET_PLAYER ) {
00560                 break;      // not in the player model
00561             }
00562             if ( g_dmflags.integer & DF_NO_FALLING ) {
00563                 break;
00564             }
00565             if ( event == EV_FALL_FAR ) {
00566                 damage = 10;
00567             } else {
00568                 damage = 5;
00569             }
00570             VectorSet (dir, 0, 0, 1);
00571             ent->pain_debounce_time = level.time + 200; // no normal pain sound
00572             G_Damage (ent, NULL, NULL, NULL, NULL, damage, 0, MOD_FALLING);
00573             break;
00574 
00575         case EV_FIRE_WEAPON:
00576             FireWeapon( ent );
00577             break;
00578 
00579         case EV_USE_ITEM1:      // teleporter
00580             // drop flags in CTF
00581             item = NULL;
00582             j = 0;
00583 
00584             if ( ent->client->ps.powerups[ PW_REDFLAG ] ) {
00585                 item = BG_FindItemForPowerup( PW_REDFLAG );
00586                 j = PW_REDFLAG;
00587             } else if ( ent->client->ps.powerups[ PW_BLUEFLAG ] ) {
00588                 item = BG_FindItemForPowerup( PW_BLUEFLAG );
00589                 j = PW_BLUEFLAG;
00590             } else if ( ent->client->ps.powerups[ PW_NEUTRALFLAG ] ) {
00591                 item = BG_FindItemForPowerup( PW_NEUTRALFLAG );
00592                 j = PW_NEUTRALFLAG;
00593             }
00594 
00595             if ( item ) {
00596                 drop = Drop_Item( ent, item, 0 );
00597                 // decide how many seconds it has left
00598                 drop->count = ( ent->client->ps.powerups[ j ] - level.time ) / 1000;
00599                 if ( drop->count < 1 ) {
00600                     drop->count = 1;
00601                 }
00602 
00603                 ent->client->ps.powerups[ j ] = 0;
00604             }
00605 
00606 #ifdef MISSIONPACK
00607             if ( g_gametype.integer == GT_HARVESTER ) {
00608                 if ( ent->client->ps.generic1 > 0 ) {
00609                     if ( ent->client->sess.sessionTeam == TEAM_RED ) {
00610                         item = BG_FindItem( "Blue Cube" );
00611                     } else {
00612                         item = BG_FindItem( "Red Cube" );
00613                     }
00614                     if ( item ) {
00615                         for ( j = 0; j < ent->client->ps.generic1; j++ ) {
00616                             drop = Drop_Item( ent, item, 0 );
00617                             if ( ent->client->sess.sessionTeam == TEAM_RED ) {
00618                                 drop->spawnflags = TEAM_BLUE;
00619                             } else {
00620                                 drop->spawnflags = TEAM_RED;
00621                             }
00622                         }
00623                     }
00624                     ent->client->ps.generic1 = 0;
00625                 }
00626             }
00627 #endif
00628             SelectSpawnPoint( ent->client->ps.origin, origin, angles );
00629             TeleportPlayer( ent, origin, angles );
00630             break;
00631 
00632         case EV_USE_ITEM2:      // medkit
00633             ent->health = ent->client->ps.stats[STAT_MAX_HEALTH] + 25;
00634 
00635             break;
00636 
00637 #ifdef MISSIONPACK
00638         case EV_USE_ITEM3:      // kamikaze
00639             // make sure the invulnerability is off
00640             ent->client->invulnerabilityTime = 0;
00641             // start the kamikze
00642             G_StartKamikaze( ent );
00643             break;
00644 
00645         case EV_USE_ITEM4:      // portal
00646             if( ent->client->portalID ) {
00647                 DropPortalSource( ent );
00648             }
00649             else {
00650                 DropPortalDestination( ent );
00651             }
00652             break;
00653         case EV_USE_ITEM5:      // invulnerability
00654             ent->client->invulnerabilityTime = level.time + 10000;
00655             break;
00656 #endif
00657 
00658         default:
00659             break;
00660         }
00661     }
00662 
00663 }

Here is the call graph for this function:

void ClientImpacts gentity_t ent,
pmove_t pm
 

Definition at line 207 of file g_active.c.

References g_entities, gentity_t, i, j, memset(), pmove_t::numtouch, pm, gentity_s::r, entityShared_t::svFlags, gentity_s::touch, and pmove_t::touchents.

Referenced by ClientThink_real().

00207                                                   {
00208     int     i, j;
00209     trace_t trace;
00210     gentity_t   *other;
00211 
00212     memset( &trace, 0, sizeof( trace ) );
00213     for (i=0 ; i<pm->numtouch ; i++) {
00214         for (j=0 ; j<i ; j++) {
00215             if (pm->touchents[j] == pm->touchents[i] ) {
00216                 break;
00217             }
00218         }
00219         if (j != i) {
00220             continue;   // duplicated
00221         }
00222         other = &g_entities[ pm->touchents[i] ];
00223 
00224         if ( ( ent->r.svFlags & SVF_BOT ) && ( ent->touch ) ) {
00225             ent->touch( ent, other, &trace );
00226         }
00227 
00228         if ( !other->touch ) {
00229             continue;
00230         }
00231 
00232         other->touch( other, ent, &trace );
00233     }
00234 
00235 }

Here is the call graph for this function:

qboolean ClientInactivityTimer gclient_t client  ) 
 

Definition at line 371 of file g_active.c.

References usercmd_s::buttons, level_locals_t::clients, clientPersistant_t::cmd, usercmd_s::forwardmove, g_inactivity, gclient_t, gclient_s::inactivityTime, gclient_s::inactivityWarning, vmCvar_t::integer, level, clientPersistant_t::localClient, gclient_s::pers, qboolean, usercmd_s::rightmove, level_locals_t::time, trap_DropClient(), trap_SendServerCommand(), and usercmd_s::upmove.

Referenced by ClientThink_real().

00371                                                     {
00372     if ( ! g_inactivity.integer ) {
00373         // give everyone some time, so if the operator sets g_inactivity during
00374         // gameplay, everyone isn't kicked
00375         client->inactivityTime = level.time + 60 * 1000;
00376         client->inactivityWarning = qfalse;
00377     } else if ( client->pers.cmd.forwardmove || 
00378         client->pers.cmd.rightmove || 
00379         client->pers.cmd.upmove ||
00380         (client->pers.cmd.buttons & BUTTON_ATTACK) ) {
00381         client->inactivityTime = level.time + g_inactivity.integer * 1000;
00382         client->inactivityWarning = qfalse;
00383     } else if ( !client->pers.localClient ) {
00384         if ( level.time > client->inactivityTime ) {
00385             trap_DropClient( client - level.clients, "Dropped due to inactivity" );
00386             return qfalse;
00387         }
00388         if ( level.time > client->inactivityTime - 10000 && !client->inactivityWarning ) {
00389             client->inactivityWarning = qtrue;
00390             trap_SendServerCommand( client - level.clients, "cp \"Ten seconds until inactivity drop!\n\"" );
00391         }
00392     }
00393     return qtrue;
00394 }

Here is the call graph for this function:

void ClientIntermissionThink gclient_t client  ) 
 

Definition at line 513 of file g_active.c.

References BUTTON_ATTACK, usercmd_s::buttons, gclient_s::buttons, clientPersistant_t::cmd, playerState_s::eFlags, gclient_t, gclient_s::oldbuttons, gclient_s::pers, gclient_s::ps, and gclient_s::readyToExit.

Referenced by ClientThink_real().

00513                                                   {
00514     client->ps.eFlags &= ~EF_TALK;
00515     client->ps.eFlags &= ~EF_FIRING;
00516 
00517     // the level will exit when everyone wants to or after timeouts
00518 
00519     // swap and latch button actions
00520     client->oldbuttons = client->buttons;
00521     client->buttons = client->pers.cmd.buttons;
00522     if ( client->buttons & ( BUTTON_ATTACK | BUTTON_USE_HOLDABLE ) & ( client->oldbuttons ^ client->buttons ) ) {
00523         // this used to be an ^1 but once a player says ready, it should stick
00524         client->readyToExit = 1;
00525     }
00526 }

void ClientThink int  clientNum  ) 
 

Definition at line 1027 of file g_active.c.

References gentity_s::client, ClientThink_real(), clientPersistant_t::cmd, g_entities, g_synchronousClients, gentity_t, vmCvar_t::integer, gclient_s::lastCmdTime, level, gclient_s::pers, gentity_s::r, entityShared_t::svFlags, level_locals_t::time, and trap_GetUsercmd().

Referenced by ClientSpawn(), and vmMain().

01027                                   {
01028     gentity_t *ent;
01029 
01030     ent = g_entities + clientNum;
01031     trap_GetUsercmd( clientNum, &ent->client->pers.cmd );
01032 
01033     // mark the time we got info, so we can display the
01034     // phone jack if they don't get any for a while
01035     ent->client->lastCmdTime = level.time;
01036 
01037     if ( !(ent->r.svFlags & SVF_BOT) && !g_synchronousClients.integer ) {
01038         ClientThink_real( ent );
01039     }
01040 }

Here is the call graph for this function:

void ClientThink_real gentity_t ent  ) 
 

Definition at line 756 of file g_active.c.

References bg_itemlist, BG_PlayerStateToEntityState(), BG_PlayerStateToEntityStateExtraPolate(), BotTestAAS(), BUTTON_ATTACK, gclient_s::buttons, usercmd_s::buttons, CheckGauntletAttack(), gentity_s::client, ClientEvents(), ClientImpacts(), ClientInactivityTimer(), ClientIntermissionThink(), ClientTimerActions(), pmove_t::cmd, clientPersistant_t::cmd, playerState_s::commandTime, clientPersistant_t::connected, entityShared_t::currentOrigin, pmove_t::debugLevel, EF_AWARD_ASSIST, EF_AWARD_DEFEND, EF_AWARD_EXCELLENT, EF_AWARD_GAUNTLET, EF_AWARD_IMPRESSIVE, playerState_s::eFlags, playerState_s::eventSequence, gentity_s::eventTime, EXEC_APPEND, gclient_s::fireHeld, gentity_s::flags, usercmd_s::forwardmove, g_debugMove, g_dmflags, g_forcerespawn, g_gravity, g_singlePlayer, g_smoothClients, g_speed, G_TouchTriggers(), pmove_t::gauntletHit, gclient_t, gentity_t, gitem_s::giTag, playerState_s::gravity, gclient_s::hook, vmCvar_t::integer, level_locals_t::intermissionQueued, level_locals_t::intermissiontime, gclient_s::latched_buttons, level, MASK_PLAYERSOLID, pmove_t::maxs, entityShared_t::maxs, memset(), pmove_t::mins, entityShared_t::mins, gclient_s::noclip, pmove_t::noFootsteps, gclient_s::oldbuttons, gclient_s::oldOrigin, playerState_s::origin, gclient_s::pers, pm, playerState_s::pm_flags, playerState_s::pm_type, Pmove(), pmove_t::pmove_fixed, pmove_fixed, pmove_t::pmove_msec, pmove_msec, clientPersistant_t::pmoveFixed, pmove_t::pointcontents, entityState_s::pos, playerState_s::powerups, pmove_t::ps, gclient_s::ps, qtrue, gentity_s::r, respawn(), gclient_s::respawnTime, gclient_s::rewardTime, usercmd_s::rightmove, gentity_s::s, SendPendingPredictableEvents(), usercmd_s::serverTime, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::spectatorState, SpectatorThink(), playerState_s::speed, playerState_s::stats, entityShared_t::svFlags, level_locals_t::time, pmove_t::trace, pmove_t::tracemask, trap_Cvar_Set(), trap_LinkEntity(), trap_SendConsoleCommand(), trajectory_t::trBase, usercmd_s::upmove, usercmd_t, vmCvar_t::value, vec3_t, VectorCopy, pmove_t::waterlevel, gentity_s::waterlevel, pmove_t::watertype, gentity_s::watertype, playerState_s::weapon, Weapon_HookFree(), playerState_s::weaponTime, WP_GAUNTLET, and WP_GRAPPLING_HOOK.

Referenced by ClientThink(), and G_RunClient().

00756                                         {
00757     gclient_t   *client;
00758     pmove_t     pm;
00759     int         oldEventSequence;
00760     int         msec;
00761     usercmd_t   *ucmd;
00762 
00763     client = ent->client;
00764 
00765     // don't think if the client is not yet connected (and thus not yet spawned in)
00766     if (client->pers.connected != CON_CONNECTED) {
00767         return;
00768     }
00769     // mark the time, so the connection sprite can be removed
00770     ucmd = &ent->client->pers.cmd;
00771 
00772     // sanity check the command time to prevent speedup cheating
00773     if ( ucmd->serverTime > level.time + 200 ) {
00774         ucmd->serverTime = level.time + 200;
00775 //      G_Printf("serverTime <<<<<\n" );
00776     }
00777     if ( ucmd->serverTime < level.time - 1000 ) {
00778         ucmd->serverTime = level.time - 1000;
00779 //      G_Printf("serverTime >>>>>\n" );
00780     } 
00781 
00782     msec = ucmd->serverTime - client->ps.commandTime;
00783     // following others may result in bad times, but we still want
00784     // to check for follow toggles
00785     if ( msec < 1 && client->sess.spectatorState != SPECTATOR_FOLLOW ) {
00786         return;
00787     }
00788     if ( msec > 200 ) {
00789         msec = 200;
00790     }
00791 
00792     if ( pmove_msec.integer < 8 ) {
00793         trap_Cvar_Set("pmove_msec", "8");
00794     }
00795     else if (pmove_msec.integer > 33) {
00796         trap_Cvar_Set("pmove_msec", "33");
00797     }
00798 
00799     if ( pmove_fixed.integer || client->pers.pmoveFixed ) {
00800         ucmd->serverTime = ((ucmd->serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
00801         //if (ucmd->serverTime - client->ps.commandTime <= 0)
00802         //  return;
00803     }
00804 
00805     //
00806     // check for exiting intermission
00807     //
00808     if ( level.intermissiontime ) {
00809         ClientIntermissionThink( client );
00810         return;
00811     }
00812 
00813     // spectators don't do much
00814     if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
00815         if ( client->sess.spectatorState == SPECTATOR_SCOREBOARD ) {
00816             return;
00817         }
00818         SpectatorThink( ent, ucmd );
00819         return;
00820     }
00821 
00822     // check for inactivity timer, but never drop the local client of a non-dedicated server
00823     if ( !ClientInactivityTimer( client ) ) {
00824         return;
00825     }
00826 
00827     // clear the rewards if time
00828     if ( level.time > client->rewardTime ) {
00829         client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
00830     }
00831 
00832     if ( client->noclip ) {
00833         client->ps.pm_type = PM_NOCLIP;
00834     } else if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
00835         client->ps.pm_type = PM_DEAD;
00836     } else {
00837         client->ps.pm_type = PM_NORMAL;
00838     }
00839 
00840     client->ps.gravity = g_gravity.value;
00841 
00842     // set speed
00843     client->ps.speed = g_speed.value;
00844 
00845 #ifdef MISSIONPACK
00846     if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
00847         client->ps.speed *= 1.5;
00848     }
00849     else
00850 #endif
00851     if ( client->ps.powerups[PW_HASTE] ) {
00852         client->ps.speed *= 1.3;
00853     }
00854 
00855     // Let go of the hook if we aren't firing
00856     if ( client->ps.weapon == WP_GRAPPLING_HOOK &&
00857         client->hook && !( ucmd->buttons & BUTTON_ATTACK ) ) {
00858         Weapon_HookFree(client->hook);
00859     }
00860 
00861     // set up for pmove
00862     oldEventSequence = client->ps.eventSequence;
00863 
00864     memset (&pm, 0, sizeof(pm));
00865 
00866     // check for the hit-scan gauntlet, don't let the action
00867     // go through as an attack unless it actually hits something
00868     if ( client->ps.weapon == WP_GAUNTLET && !( ucmd->buttons & BUTTON_TALK ) &&
00869         ( ucmd->buttons & BUTTON_ATTACK ) && client->ps.weaponTime <= 0 ) {
00870         pm.gauntletHit = CheckGauntletAttack( ent );
00871     }
00872 
00873     if ( ent->flags & FL_FORCE_GESTURE ) {
00874         ent->flags &= ~FL_FORCE_GESTURE;
00875         ent->client->pers.cmd.buttons |= BUTTON_GESTURE;
00876     }
00877 
00878 #ifdef MISSIONPACK
00879     // check for invulnerability expansion before doing the Pmove
00880     if (client->ps.powerups[PW_INVULNERABILITY] ) {
00881         if ( !(client->ps.pm_flags & PMF_INVULEXPAND) ) {
00882             vec3_t mins = { -42, -42, -42 };
00883             vec3_t maxs = { 42, 42, 42 };
00884             vec3_t oldmins, oldmaxs;
00885 
00886             VectorCopy (ent->r.mins, oldmins);
00887             VectorCopy (ent->r.maxs, oldmaxs);
00888             // expand
00889             VectorCopy (mins, ent->r.mins);
00890             VectorCopy (maxs, ent->r.maxs);
00891             trap_LinkEntity(ent);
00892             // check if this would get anyone stuck in this player
00893             if ( !StuckInOtherClient(ent) ) {
00894                 // set flag so the expanded size will be set in PM_CheckDuck
00895                 client->ps.pm_flags |= PMF_INVULEXPAND;
00896             }
00897             // set back
00898             VectorCopy (oldmins, ent->r.mins);
00899             VectorCopy (oldmaxs, ent->r.maxs);
00900             trap_LinkEntity(ent);
00901         }
00902     }
00903 #endif
00904 
00905     pm.ps = &client->ps;
00906     pm.cmd = *ucmd;
00907     if ( pm.ps->pm_type == PM_DEAD ) {
00908         pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
00909     }
00910     else if ( ent->r.svFlags & SVF_BOT ) {
00911         pm.tracemask = MASK_PLAYERSOLID | CONTENTS_BOTCLIP;
00912     }
00913     else {
00914         pm.tracemask = MASK_PLAYERSOLID;
00915     }
00916     pm.trace = trap_Trace;
00917     pm.pointcontents = trap_PointContents;
00918     pm.debugLevel = g_debugMove.integer;
00919     pm.noFootsteps = ( g_dmflags.integer & DF_NO_FOOTSTEPS ) > 0;
00920 
00921     pm.pmove_fixed = pmove_fixed.integer | client->pers.pmoveFixed;
00922     pm.pmove_msec = pmove_msec.integer;
00923 
00924     VectorCopy( client->ps.origin, client->oldOrigin );
00925 
00926 #ifdef MISSIONPACK
00927         if (level.intermissionQueued != 0 && g_singlePlayer.integer) {
00928             if ( level.time - level.intermissionQueued >= 1000  ) {
00929                 pm.cmd.buttons = 0;
00930                 pm.cmd.forwardmove = 0;
00931                 pm.cmd.rightmove = 0;
00932                 pm.cmd.upmove = 0;
00933                 if ( level.time - level.intermissionQueued >= 2000 && level.time - level.intermissionQueued <= 2500 ) {
00934                     trap_SendConsoleCommand( EXEC_APPEND, "centerview\n");
00935                 }
00936                 ent->client->ps.pm_type = PM_SPINTERMISSION;
00937             }
00938         }
00939         Pmove (&pm);
00940 #else
00941         Pmove (&pm);
00942 #endif
00943 
00944     // save results of pmove
00945     if ( ent->client->ps.eventSequence != oldEventSequence ) {
00946         ent->eventTime = level.time;
00947     }
00948     if (g_smoothClients.integer) {
00949         BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue );
00950     }
00951     else {
00952         BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue );
00953     }
00954     SendPendingPredictableEvents( &ent->client->ps );
00955 
00956     if ( !( ent->client->ps.eFlags & EF_FIRING ) ) {
00957         client->fireHeld = qfalse;      // for grapple
00958     }
00959 
00960     // use the snapped origin for linking so it matches client predicted versions
00961     VectorCopy( ent->s.pos.trBase, ent->r.currentOrigin );
00962 
00963     VectorCopy (pm.mins, ent->r.mins);
00964     VectorCopy (pm.maxs, ent->r.maxs);
00965 
00966     ent->waterlevel = pm.waterlevel;
00967     ent->watertype = pm.watertype;
00968 
00969     // execute client events
00970     ClientEvents( ent, oldEventSequence );
00971 
00972     // link entity now, after any personal teleporters have been used
00973     trap_LinkEntity (ent);
00974     if ( !ent->client->noclip ) {
00975         G_TouchTriggers( ent );
00976     }
00977 
00978     // NOTE: now copy the exact origin over otherwise clients can be snapped into solid
00979     VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
00980 
00981     //test for solid areas in the AAS file
00982     BotTestAAS(ent->r.currentOrigin);
00983 
00984     // touch other objects
00985     ClientImpacts( ent, &pm );
00986 
00987     // save results of triggers and client events
00988     if (ent->client->ps.eventSequence != oldEventSequence) {
00989         ent->eventTime = level.time;
00990     }
00991 
00992     // swap and latch button actions
00993     client->oldbuttons = client->buttons;
00994     client->buttons = ucmd->buttons;
00995     client->latched_buttons |= client->buttons & ~client->oldbuttons;
00996 
00997     // check for respawning
00998     if ( client->ps.stats[STAT_HEALTH] <= 0 ) {
00999         // wait for the attack button to be pressed
01000         if ( level.time > client->respawnTime ) {
01001             // forcerespawn is to prevent users from waiting out powerups
01002             if ( g_forcerespawn.integer > 0 && 
01003                 ( level.time - client->respawnTime ) > g_forcerespawn.integer * 1000 ) {
01004                 respawn( ent );
01005                 return;
01006             }
01007         
01008             // pressing attack or use is the normal respawn method
01009             if ( ucmd->buttons & ( BUTTON_ATTACK | BUTTON_USE_HOLDABLE ) ) {
01010                 respawn( ent );
01011             }
01012         }
01013         return;
01014     }
01015 
01016     // perform once-a-second actions
01017     ClientTimerActions( ent, msec );
01018 }

Here is the call graph for this function:

void ClientTimerActions gentity_t ent,
int  msec
 

Definition at line 403 of file g_active.c.

References playerState_s::ammo, bg_itemlist, gentity_s::client, EV_POWERUP_REGEN, G_AddEvent(), gclient_t, gentity_t, gitem_s::giTag, gentity_s::health, i, max, playerState_s::powerups, gclient_s::ps, playerState_s::stats, t, gclient_s::timeResidual, w, WP_BFG, WP_GRENADE_LAUNCHER, WP_LIGHTNING, WP_MACHINEGUN, WP_PLASMAGUN, WP_RAILGUN, WP_ROCKET_LAUNCHER, and WP_SHOTGUN.

Referenced by ClientThink_real().

00403                                                     {
00404     gclient_t   *client;
00405 #ifdef MISSIONPACK
00406     int         maxHealth;
00407 #endif
00408 
00409     client = ent->client;
00410     client->timeResidual += msec;
00411 
00412     while ( client->timeResidual >= 1000 ) {
00413         client->timeResidual -= 1000;
00414 
00415         // regenerate
00416 #ifdef MISSIONPACK
00417         if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) {
00418             maxHealth = client->ps.stats[STAT_MAX_HEALTH] / 2;
00419         }
00420         else if ( client->ps.powerups[PW_REGEN] ) {
00421             maxHealth = client->ps.stats[STAT_MAX_HEALTH];
00422         }
00423         else {
00424             maxHealth = 0;
00425         }
00426         if( maxHealth ) {
00427             if ( ent->health < maxHealth ) {
00428                 ent->health += 15;
00429                 if ( ent->health > maxHealth * 1.1 ) {
00430                     ent->health = maxHealth * 1.1;
00431                 }
00432                 G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
00433             } else if ( ent->health < maxHealth * 2) {
00434                 ent->health += 5;
00435                 if ( ent->health > maxHealth * 2 ) {
00436                     ent->health = maxHealth * 2;
00437                 }
00438                 G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
00439             }
00440 #else
00441         if ( client->ps.powerups[PW_REGEN] ) {
00442             if ( ent->health < client->ps.stats[STAT_MAX_HEALTH]) {
00443                 ent->health += 15;
00444                 if ( ent->health > client->ps.stats[STAT_MAX_HEALTH] * 1.1 ) {
00445                     ent->health = client->ps.stats[STAT_MAX_HEALTH] * 1.1;
00446                 }
00447                 G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
00448             } else if ( ent->health < client->ps.stats[STAT_MAX_HEALTH] * 2) {
00449                 ent->health += 5;
00450                 if ( ent->health > client->ps.stats[STAT_MAX_HEALTH] * 2 ) {
00451                     ent->health = client->ps.stats[STAT_MAX_HEALTH] * 2;
00452                 }
00453                 G_AddEvent( ent, EV_POWERUP_REGEN, 0 );
00454             }
00455 #endif
00456         } else {
00457             // count down health when over max
00458             if ( ent->health > client->ps.stats[STAT_MAX_HEALTH] ) {
00459                 ent->health--;
00460             }
00461         }
00462 
00463         // count down armor when over max
00464         if ( client->ps.stats[STAT_ARMOR] > client->ps.stats[STAT_MAX_HEALTH] ) {
00465             client->ps.stats[STAT_ARMOR]--;
00466         }
00467     }
00468 #ifdef MISSIONPACK
00469     if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
00470         int w, max, inc, t, i;
00471     int weapList[]={WP_MACHINEGUN,WP_SHOTGUN,WP_GRENADE_LAUNCHER,WP_ROCKET_LAUNCHER,WP_LIGHTNING,WP_RAILGUN,WP_PLASMAGUN,WP_BFG,WP_NAILGUN,WP_PROX_LAUNCHER,WP_CHAINGUN};
00472     int weapCount = sizeof(weapList) / sizeof(int);
00473         //
00474     for (i = 0; i < weapCount; i++) {
00475           w = weapList[i];
00476 
00477           switch(w) {
00478               case WP_MACHINEGUN: max = 50; inc = 4; t = 1000; break;
00479               case WP_SHOTGUN: max = 10; inc = 1; t = 1500; break;
00480               case WP_GRENADE_LAUNCHER: max = 10; inc = 1; t = 2000; break;
00481               case WP_ROCKET_LAUNCHER: max = 10; inc = 1; t = 1750; break;
00482               case WP_LIGHTNING: max = 50; inc = 5; t = 1500; break;
00483               case WP_RAILGUN: max = 10; inc = 1; t = 1750; break;
00484               case WP_PLASMAGUN: max = 50; inc = 5; t = 1500; break;
00485               case WP_BFG: max = 10; inc = 1; t = 4000; break;
00486               case WP_NAILGUN: max = 10; inc = 1; t = 1250; break;
00487               case WP_PROX_LAUNCHER: max = 5; inc = 1; t = 2000; break;
00488               case WP_CHAINGUN: max = 100; inc = 5; t = 1000; break;
00489               default: max = 0; inc = 0; t = 1000; break;
00490           }
00491           client->ammoTimes[w] += msec;
00492           if ( client->ps.ammo[w] >= max ) {
00493               client->ammoTimes[w] = 0;
00494           }
00495           if ( client->ammoTimes[w] >= t ) {
00496               while ( client->ammoTimes[w] >= t )
00497                   client->ammoTimes[w] -= t;
00498               client->ps.ammo[w] += inc;
00499               if ( client->ps.ammo[w] > max ) {
00500                   client->ps.ammo[w] = max;
00501               }
00502           }
00503     }
00504     }
00505 #endif
00506 }

Here is the call graph for this function:

void G_RunClient gentity_t ent  ) 
 

Definition at line 1043 of file g_active.c.

References gentity_s::client, ClientThink_real(), clientPersistant_t::cmd, g_synchronousClients, gentity_t, vmCvar_t::integer, level, gclient_s::pers, gentity_s::r, usercmd_s::serverTime, entityShared_t::svFlags, and level_locals_t::time.

Referenced by G_RunFrame().