/* * G_CheckArmor */ static float G_CheckArmor( edict_t *ent, float damage, int dflags ) { gclient_t *client = ent->r.client; float maxsave, save, armordamage; if( !client ) return 0.0f; if( dflags & DAMAGE_NO_ARMOR || dflags & DAMAGE_NO_PROTECTION ) return 0.0f; maxsave = min( damage, client->resp.armor / g_armor_degradation->value ); if( maxsave <= 0.0f ) return 0.0f; armordamage = maxsave * g_armor_degradation->value; save = maxsave * g_armor_protection->value; client->resp.armor -= armordamage; if( ARMOR_TO_INT( client->resp.armor ) <= 0 ) client->resp.armor = 0.0f; client->ps.stats[STAT_ARMOR] = ARMOR_TO_INT( client->resp.armor ); return save; }
static void Say_Team_Armor( edict_t *who, char *buf, int buflen, const char *current_color ) { if( GS_Armor_TagForCount( who->r.client->resp.armor ) != ARMOR_NONE ) { Q_snprintfz( buf, buflen, "%s%i%s", GS_FindItemByTag( GS_Armor_TagForCount( who->r.client->resp.armor ) )->color, ARMOR_TO_INT( who->r.client->resp.armor ), current_color ); } else { Q_snprintfz( buf, buflen, "%s0%s", S_COLOR_GREEN, current_color ); } }
int GS_Armor_TagForCount( float armorcount ) { int count = ARMOR_TO_INT( armorcount ); if( count > GS_FindItemByTag( ARMOR_YA )->inventory_max ) return ARMOR_RA; if( count > GS_FindItemByTag( ARMOR_GA )->inventory_max ) return ARMOR_YA; if( count ) return ARMOR_GA; return ARMOR_NONE; }
qboolean Add_Armor( edict_t *ent, edict_t *other, qboolean pick_it ) { gclient_t *client = other->r.client; float maxarmorcount = 0.0f, newarmorcount; float pickupitem_maxcount; if( !client ) return qfalse; if( !ent->item || !( ent->item->type & IT_ARMOR ) ) return qfalse; pickupitem_maxcount = GS_Armor_MaxCountForTag( ent->item->tag ); // can't pick if surpassed the max armor count of that type if( pickupitem_maxcount && ( client->resp.armor >= pickupitem_maxcount ) ) return qfalse; if( GS_Armor_TagForCount( client->resp.armor ) == ARMOR_NONE ) maxarmorcount = pickupitem_maxcount; else maxarmorcount = max( GS_Armor_MaxCountForTag( GS_Armor_TagForCount( client->resp.armor ) ), pickupitem_maxcount ); if( !pickupitem_maxcount ) newarmorcount = client->resp.armor + GS_Armor_PickupCountForTag( ent->item->tag ); else newarmorcount = min( client->resp.armor + GS_Armor_PickupCountForTag( ent->item->tag ), maxarmorcount ); // it can't be picked up if it doesn't add any armor if( newarmorcount <= client->resp.armor ) return qfalse; if( pick_it ) { client->resp.armor = newarmorcount; client->ps.stats[STAT_ARMOR] = ARMOR_TO_INT( client->resp.armor ); client->level.stats.armor_taken += ent->item->quantity; teamlist[other->s.team].stats.armor_taken += ent->item->quantity; } return qtrue; }
/* * G_Teams_TDM_UpdateTeamInfoMessages */ void G_Teams_UpdateTeamInfoMessages( void ) { static int nexttime = 0; static char teammessage[MAX_STRING_CHARS]; edict_t *ent, *e; size_t len; int i, j, team; char entry[MAX_TOKEN_CHARS]; int locationTag; nexttime -= game.snapFrameTime; if( nexttime > 0 ) return; while( nexttime <= 0 ) nexttime += 2000; // time for a new update for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ ) { *teammessage = 0; Q_snprintfz( teammessage, sizeof( teammessage ), "ti \"" ); len = strlen( teammessage ); // add our team info to the string for( i = 0; i < teamlist[team].numplayers; i++ ) { ent = game.edicts + teamlist[team].playerIndices[i]; if( G_IsDead( ent ) ) // don't show dead players continue; if( ent->r.client->teamstate.is_coach ) // don't show coachs continue; // get location name locationTag = G_MapLocationTAGForOrigin( ent->s.origin ); if( locationTag == -1 ) continue; *entry = 0; Q_snprintfz( entry, sizeof( entry ), "%i %i %i %i ", PLAYERNUM( ent ), locationTag, HEALTH_TO_INT( ent->health ), ARMOR_TO_INT( ent->r.client->resp.armor ) ); if( MAX_STRING_CHARS - len > strlen( entry ) ) { Q_strncatz( teammessage, entry, sizeof( teammessage ) ); len = strlen( teammessage ); } } // add closing quote *entry = 0; Q_snprintfz( entry, sizeof( entry ), "\"" ); if( MAX_STRING_CHARS - len > strlen( entry ) ) { Q_strncatz( teammessage, entry, sizeof( teammessage ) ); len = strlen( teammessage ); } for( i = 0; i < teamlist[team].numplayers; i++ ) { ent = game.edicts + teamlist[team].playerIndices[i]; if( !ent->r.inuse || !ent->r.client ) continue; trap_GameCmd( ent, teammessage ); // see if there are spectators chasing this player and send them the layout too for( j = 0; j < teamlist[TEAM_SPECTATOR].numplayers; j++ ) { e = game.edicts + teamlist[TEAM_SPECTATOR].playerIndices[j]; if( !e->r.inuse || !e->r.client ) continue; if( e->r.client->resp.chase.active && e->r.client->resp.chase.target == ENTNUM( ent ) ) trap_GameCmd( e, teammessage ); } } } }
/* * G_SetClientStats */ void G_SetClientStats( edict_t *ent ) { gclient_t *client = ent->r.client; int team, i; if( ent->r.client->resp.chase.active ) // in chasecam it copies the other player stats return; // // layouts // client->ps.stats[STAT_LAYOUTS] = 0; // don't force scoreboard when dead during timeout if( ent->r.client->level.showscores || GS_MatchState() >= MATCH_STATE_POSTMATCH ) client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_SCOREBOARD; if( GS_TeamBasedGametype() && !GS_InvidualGameType() ) client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_TEAMTAB; if( GS_HasChallengers() && ent->r.client->queueTimeStamp ) client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_CHALLENGER; if( GS_MatchState() <= MATCH_STATE_WARMUP && level.ready[PLAYERNUM( ent )] ) client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_READY; if( G_SpawnQueue_GetSystem( ent->s.team ) == SPAWNSYSTEM_INSTANT ) client->ps.stats[STAT_LAYOUTS] |= STAT_LAYOUT_INSTANTRESPAWN; // // team // client->ps.stats[STAT_TEAM] = client->ps.stats[STAT_REALTEAM] = ent->s.team; // // health // if( ent->s.team == TEAM_SPECTATOR ) client->ps.stats[STAT_HEALTH] = STAT_NOTSET; // no health for spectator else client->ps.stats[STAT_HEALTH] = HEALTH_TO_INT( ent->health ); client->r.frags = client->ps.stats[STAT_SCORE]; // // armor // if( GS_Instagib() ) { if( g_instashield->integer ) client->ps.stats[STAT_ARMOR] = ARMOR_TO_INT( 100.0f * ( client->resp.instashieldCharge / INSTA_SHIELD_MAX ) ); else client->ps.stats[STAT_ARMOR] = 0; } else client->ps.stats[STAT_ARMOR] = ARMOR_TO_INT( client->resp.armor ); // // pickup message // if( level.time > client->resp.pickup_msg_time ) { client->ps.stats[STAT_PICKUP_ITEM] = 0; } // // frags // if( ent->s.team == TEAM_SPECTATOR ) { client->ps.stats[STAT_SCORE] = STAT_NOTSET; // no frags for spectators } else { client->ps.stats[STAT_SCORE] = ent->r.client->level.stats.score; } // // Team scores // if( GS_TeamBasedGametype() ) { // team based i = 0; for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ ) { client->ps.stats[STAT_TEAM_ALPHA_SCORE+i] = teamlist[team].stats.score; i++; } // mark the rest as not set for(; team < GS_MAX_TEAMS; team++ ) { client->ps.stats[STAT_TEAM_ALPHA_SCORE+i] = STAT_NOTSET; i++; } } else { // not team based i = 0; for( team = TEAM_ALPHA; team < GS_MAX_TEAMS; team++ ) { client->ps.stats[STAT_TEAM_ALPHA_SCORE+i] = STAT_NOTSET; i++; } } // spawn system client->ps.stats[STAT_NEXT_RESPAWN] = ceil( G_SpawnQueue_NextRespawnTime( client->team ) * 0.001f ); // pointed player client->ps.stats[STAT_POINTED_TEAMPLAYER] = 0; client->ps.stats[STAT_POINTED_PLAYER] = G_FindPointedPlayer( ent ); if( client->ps.stats[STAT_POINTED_PLAYER] && GS_TeamBasedGametype() ) { edict_t *e = &game.edicts[client->ps.stats[STAT_POINTED_PLAYER]]; if( e->s.team == ent->s.team ) { int pointedhealth = HEALTH_TO_INT( e->health ); int pointedarmor = 0; int available_bits = 0; bool mega = false; if( pointedhealth < 0 ) pointedhealth = 0; if( pointedhealth > 100 ) { pointedhealth -= 100; mega = true; if( pointedhealth > 100 ) pointedhealth = 100; } pointedhealth /= 3.2; if( GS_Armor_TagForCount( e->r.client->resp.armor ) ) { pointedarmor = ARMOR_TO_INT( e->r.client->resp.armor ); } if( pointedarmor > 150 ) { pointedarmor = 150; } pointedarmor /= 5; client->ps.stats[STAT_POINTED_TEAMPLAYER] = ( ( pointedhealth &0x1F )|( pointedarmor&0x3F )<<6|( available_bits&0xF )<<12 ); if( mega ) { client->ps.stats[STAT_POINTED_TEAMPLAYER] |= 0x20; } } } // last killer. ignore world and team kills if( client->teamstate.last_killer ) { edict_t *targ = ent, *attacker = client->teamstate.last_killer; client->ps.stats[STAT_LAST_KILLER] = (attacker->r.client && !GS_IsTeamDamage( &targ->s, &attacker->s ) ? ENTNUM( attacker ) : 0); } else { client->ps.stats[STAT_LAST_KILLER] = 0; } }