/** * @brief Chose a team that should start the match * @param[in] player In singleplayer mode the team of this player will get the first turn * @sa SVCmd_StartGame_f */ static void G_GetStartingTeam (const player_t* player) { int teamCount; int playerCount; int knownTeams[MAX_TEAMS]; player_t *p; /* return with no action if activeTeam already assigned or if are in single-player mode */ if (G_MatchIsRunning()) return; if (sv_maxclients->integer == 1) { level.activeTeam = player->pers.team; level.teamOfs = MAX_TEAMS - level.activeTeam; return; } /* count number of currently connected unique teams and players (human controlled players only) */ p = NULL; teamCount = 0; playerCount = 0; while ((p = G_PlayerGetNextActiveHuman(p))) { int j; playerCount++; for (j = 0; j < teamCount; j++) { if (p->pers.team == knownTeams[j]) break; } if (j == teamCount) knownTeams[teamCount++] = p->pers.team; } if (teamCount) { const int teamIndex = (int) (frand() * (teamCount - 1) + 0.5); G_PrintStats("Starting new game: %s with %i teams", level.mapname, teamCount); level.activeTeam = knownTeams[teamIndex]; level.teamOfs = MAX_TEAMS - level.activeTeam; p = NULL; while ((p = G_PlayerGetNextActiveHuman(p))) if (p->pers.team != level.activeTeam) p->roundDone = true; } }
static void G_ActorRevitalise (Edict* ent) { if (G_IsStunned(ent)) { G_RemoveStunned(ent); /** @todo have a look at the morale value of * the ent and maybe get into rage or panic? */ G_ActorModifyCounters(ent->link, ent, 1, 0, -1); G_GetFloorItems(ent); } G_ActorSetMaxs(ent); /* check if the player appears/perishes, seen from other teams */ G_CheckVis(ent); /* calc new vis for this player */ G_CheckVisTeamAll(ent->team, 0, ent); G_PrintStats("%s is revitalized.", ent->chr.name); }
/** * @brief Checks whether a match is over. * @return @c true if this match is over, @c false otherwise */ bool G_MatchDoEnd (void) { /* check for intermission */ if (level.intermissionTime > 0.0 && level.time > level.intermissionTime) { G_PrintStats("End of game - Team %i is the winner", level.winningTeam); G_MatchSendResults(level.winningTeam, level.nextMapSwitch); /* now we cleanup the AI */ AIL_Cleanup(); if (level.mapEndCommand != NULL) { gi.AddCommandString(level.mapEndCommand); } level.intermissionTime = 0.0; level.winningTeam = 0; return true; } return false; }
/** * @brief Deal damage to each wounded team member. * @param[in] team The index of the team to deal damage to. */ void G_BleedWounds (const int team) { Actor* actor = nullptr; while ((actor = G_EdictsGetNextLivingActorOfTeam(actor, team))) { if (CHRSH_IsTeamDefRobot(actor->chr.teamDef)) continue; const teamDef_t* const teamDef = actor->chr.teamDef; const woundInfo_t& wounds = actor->chr.wounds; int damage = 0; for (int bodyPart = 0; bodyPart < teamDef->bodyTemplate->numBodyParts(); ++bodyPart) if (wounds.woundLevel[bodyPart] > actor->chr.maxHP * teamDef->bodyTemplate->woundThreshold(bodyPart)) damage += wounds.woundLevel[bodyPart] * teamDef->bodyTemplate->bleedingFactor(bodyPart); if (damage > 0) { G_PrintStats("%s is bleeding (damage: %i)", actor->chr.name, damage); G_TakeDamage(actor, damage); G_CheckDeathOrKnockout(actor, nullptr, nullptr, damage); } } /* Maybe the last team member bled to death */ G_MatchEndCheck(); }