REJECT table is a resource lump attached to maps which is used to speed up line-of-sight calculations. It is a lookup table that indicates for every pair of sectors in the map whether a direct line of sight between them is possible.
In SRB2, most enemies need to be able to "see" a player before they can chase or attack them. To search for possible players to target, they call an action such as
A_Look in their current state. For each player that this action identifies as a possible target, it calls the
P_CheckSight function, passing the enemy Object and the player Object as parameters.
P_CheckSight then uses the
REJECT table to determine quickly when it is impossible for the enemy to see the player.
REJECT table works by precalculating whether direct line of sight between sectors is possible. A
REJECT builder (which is included in most nodebuilders, including ZenNode) is used to generate the table, which may take a substantial amount of time to calculate. When completed, a table of boolean values is generated, one for each combination of possible pairs of sectors. A value of
true indicates that no line of sight is possible between the sectors; a value of
false indicates that a line of sight may be possible, depending on the positions of the Objects in the sectors. These boolean values are then packed into bytes, each of which stores up to eight values at once. The size of a
REJECT lump in bytes can therefore be calculated as
(number of sectors)2/8 rounded up to the next full integer.
In order to determine whether an enemy can see a player,
P_CheckSight looks up the value in the
REJECT table, using the number of the sector the player is in and the number of the sector the enemy is in. If the value is found to be true, it is immediately known that no line of sight is possible between the two sectors, and it is therefore impossible for the enemy to see the player. If the value is false, line of sight between the sectors may be possible: A more complicated calculation is performed to determine whether the player is visible to the enemy.
REJECT lump is optional. If it is missing, the game will skip the
REJECT lookup and always perform the full calculation to determine if a line of sight exists. The game will also skip the lookup if a
REJECT lump does exist but is empty (i.e. it has a length of zero). This may cause the game to slow down, especially in maps that are large or have many enemies.
REJECT lump is smaller than expected, then the line-of-sight information for some pairs of sectors will be missing. The game performs no bounds checking before looking up values in the
REJECT table, so if the pair of sectors that is looked up is not in the table, whatever happens to be in memory after the end of the table will be used as a
REJECT value. This may cause enemies not to detect players which they would normally be able to see.