# Scoring: CheckBridgeAndTown

```       Name: CheckBridgeAndTown                                      [Show more]
Type: Subroutine
Category: Scoring
Summary: Check whether we are safely flying under the bridge or down the
main street in Acornsville
Deep dive: Flying skills
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* CheckFlyingSkills (Part 2 of 2) calls CheckBridgeAndTown

This routine checks whether the plane is within a certain distance of a
specific coordinate from the (skillZoneHi skillZoneLo) table. If it is within
the correct distance, then it is within the skill zone.

The plane is said to be within a coordinate's skill zone if the following
checks are all true. They start with larger checks and whittle it down to more
fine-grained checks, as follows:

* The vector from the skill zone coordinate to the plane is in a positive
direction along each axis, i.e. the plane is somewhere inside a cuboid
that has the skill zone coordinate at its bottom-left corner, nearest the
origin (the origin is at ground level in the bottom-left corner of the
map).

* The length of this vector along each axis is < 1024, so the plane is close
enough to the skill zone coordinate for the next check to be done, i.e.
within the rectangular cuboid described above, so the plane is within a
cube of size 1024 in the skill zone coordinate's corner.

* The length of the vector along each axis divided by 4 is within the margin
for this skill zone (as defined in the skillZoneSize table), i.e. the
plane is within an even smaller rectangular cuboid, again in the skill
zone coordinate's corner, with dimensions given in the skillZoneSize
table.

In short, the plane is in the skill zone if it's inside a box whose dimensions
are given in the skillZoneSize table, and whose corner nearest the origin is
at the skill zone coordinate given in the skillZone table - in other words,
the cuboid at the skill zone coordinate, with the dimensions in skillZoneSize.

Or, even shorter, the plane is in a skill zone if this is true for all three
axes:

skill zone    <=      plane      <   skill zone  +  skill zone
coordinate         coordinate        coordinate      size * 4

Arguments:

A                    Determines which skill zone coordinate to check:

* 0, 3, 6 = under the suspension bridge

* 9, 12, 15, 18 = along main street in Acornsville

Returns:

C flag               The result:

* 0 = We are currently flying outside this skill zone

* 1 = We are currently flying inside this skill zone

.CheckBridgeAndTown

STA Q                  \ Set Q to the skill zone to check

LDY #2                 \ We now work through the three axes (z, y, x), so set
\ Y = 2 to act as an axis counter, going 2, 1, 0

.town1

TYA                    \ Set X = Q + Y
CLC                    \
ADC Q                  \ so X is an index into the skill zone coordinate tables
TAX                    \ for skill zone Q and axis Y

SEC                    \ Set (A P) = plane coordinate - skillZone coordinate
LDA xPlaneLo,Y         \
SBC skillZoneLo,X      \ starting with the high bytes
STA P

LDA xPlaneHi,Y         \ And then the low bytes, so (A P) contains the vector
SBC skillZoneHi,X      \ from the skill zone coordinate to the plane, along
\ axis Y

BMI town2              \ If (A P) is negative, jump to town2 to clear the C
\ flag

LSR A                  \ Set (A P) = (A P) / 4
ROR P                  \
LSR A                  \ If the high byte in A is non-zero, then the original A
BNE town2              \ must be less than %10000000000 (1024), so jump to
ROR P                  \ town2 to clear the C flag

LDA P                  \ If the low byte in P >= the margin for this skill zone
CMP skillZoneSize,X    \ in this axis, jump to town2 to clear the C flag
BCS town2

DEY                    \ Decrement the axis counter to point to the next axis

BPL town1              \ Loop back until we have checked all three axes

\ If we get here, then:
\
\   * The vector from the skill zone coordinate to the
\     plane is in a positive direction along each axis
\
\   * The length of the vector along each axis is < 1024
\
\   * The length of the vector along each axis divided
\     by 4 is within the margin for this skill zone
\
\ which means we are currently flying within this safe
\ zone

SEC                    \ Set the C flag to indicate we are currently flying
\ within this skill zone

RTS                    \ Return from the subroutine

.town2

CLC                    \ Clear the C flag to indicate we are currently flying
\ outside this skill zone

RTS                    \ Return from the subroutine
```