/** * @brief Find valid actor spawn fields for this player. * @note Already used spawn-point are not found because ent->type is changed in G_ClientTeamInfo. * @param[in] player The player to spawn the actors for. * @param[in] spawnType The type of spawn-point so search for (ET_ACTORSPAWN or ET_ACTOR2x2SPAWN) * @return A pointer to a found spawn point or NULL if nothing was found or on error. */ static edict_t *G_ClientGetFreeSpawnPoint (const player_t * player, int spawnType) { edict_t *ent = NULL; /* Abort for non-spawnpoints */ assert(spawnType == ET_ACTORSPAWN || spawnType == ET_ACTOR2x2SPAWN); if (level.randomSpawn) { edict_t *list[MAX_EDICTS]; int count = 0; while ((ent = G_EdictsGetNext(ent))) if (ent->type == spawnType && player->pers.team == ent->team) { if (G_GetLivingActorFromPos(ent->pos)) continue; list[count++] = ent; } if (count) return list[rand() % count]; } else { while ((ent = G_EdictsGetNext(ent))) if (ent->type == spawnType && player->pers.team == ent->team) { if (G_GetLivingActorFromPos(ent->pos)) continue; return ent; } } return NULL; }
/** * @brief Checks whether the actor should stop movement * @param ent The actors edict * @param visState The visibility check state @c VIS_PERISH, @c VIS_APPEAR * @return @c true if the actor should stop movement, @c false otherwise */ static bool G_ActorShouldStopInMidMove (const edict_t *ent, int visState, dvec_t* dvtab, int max) { if (visState & VIS_STOP) return true; /* check that the appearing unit is not on a grid position the actor wanted to walk to. * this might be the case if the edict got visible in mid mode */ if (visState & VIS_APPEAR) { pos3_t pos; VectorCopy(ent->pos, pos); while (max >= 0) { int tmp = 0; const edict_t *blockEdict; PosAddDV(pos, tmp, dvtab[max]); max--; blockEdict = G_GetLivingActorFromPos(pos); if (blockEdict && G_IsBlockingMovementActor(blockEdict)) { const bool visible = G_IsVisibleForTeam(blockEdict, ent->team); if (visible) return true; } } } return false; }