# Overview Enemy logic is controlled by enemy routines, every enemy has a set of routines that it can execute. The list of routines per enemy is specified in the `*_routine_ptr_tbl` tables all in bank 7. Which enemies are in which screen of a level are specified in the `enemy_routine_ptr_tbl` (for shared enemies) or one of the 7 `enemy_routine_level_x` tables. Level 2 and level 4 share the same enemy routine `enemy_routine_level_2_4` table. Upon execution of `level_routine_04` and `level_routine_0a`, every enemy is given the opportunity to execute logic specific to that enemy type. This is done by looping down #$f to #$0 through the `ENEMY_ROUTINE` memory addresses in the `exe_all_enemy_routine` method. Enemies are added to the end going down, i.e. they start at #$f and go down. # Generation Enemies can be generated in the level in one of two ways: random generation, and level-specific hard-coded locations. # Level Enemies Each level defines hard-coded locations on each screen where an enemy will be generated. These enemies are always at that location in the level. This is defined in the `level_enemy_screen_ptr_ptr_tbl` in bank 2. There are #$08 2-byte entries in this table, one for each level, e.g. `level_1_enemy_screen_ptr_tbl`. Each 2-byte entry is a memory address to another table of addresses, e.g. `level_1_enemy_screen_02`. Each entry here defines the enemies within a single screen of a level. Screen 0 does never has enemies, so the first entry in this table is associated to the second screen of the level. There is always one more entry for a level than there are screens. ## Data Structure ### Outdoor levels For a given screen, each enemy is defined with at least #$03 bytes. For example, the first enemy defined on `level_1_enemy_screen_00` is `.byte $10,$05,$60`. These three bytes define a soldier who runs left, but doesn't shoot. These bytes need to be broken up into bits to further understand their meaning. ``` 0001 0000 0000 0101 0110 0000 XXXX XXXX RRTT TTTT YYYY YAAA ``` * `X` - X offset * `R` - Repeat * `T` - Enemy Type * `Y` - Y Offset * `A` - Enemy Attribute ### Byte 1 - XX byte The first byte, #$10, from the example above specifies the x position of the enemy. ### Byte 2 - Repeat and Enemy Type The second byte, #$05, from the example above defines two things: repeat, and enemy type. The most significant 2 bits define the number of times to repeat an enemy, the least significant 6 bits define the enemy type. To see a list of all enemy types and what they are, see `Enemy Glossary.md`. For example, #$05 has a repeat of 0 and a enemy type of #$05. #$05 is the soldier. If the repeat value is 0, then the enemy is not repeated and will take a total of #$3 bytes. However, if there is a repeat, for each repetition, one more byte is added and has the same structure as the `Y Offset and Attribute` byte. This means an enemy with a repeated enemy will have the same XX position and the same type, but have its own Y position and attributes. Here is an example of a screen enemy definition with a repeat ``` level_1_enemy_screen_09: .byte $10,$43,$40,$b4 ; flying capsule (enemy type #$03), attribute: 000 (R), location: (#$10, #$40) ; repeat: 1 [(y = #$b0, attr = 100)] .byte $e0,$07,$81 ; red turret (enemy type #$07), attribute: 001, location: (#$e0, #$80) .byte $ff ``` ### Byte 3 - Y Offset and Attribute The third byte, #$60, from the example above defines the vertical position of the enemy as well as that enemy's attributes. The #$05 most significant bits specify the vertical offset and the least significant 3 bits are for the attributes. Each enemy can use the 3 attribute bits however they see fit. For example, a soldier uses the attributes to know which way to start running, and whether or not the soldier fires bullets from their gun. For a detailed list of each enemy type and their attributes, see `Enemy Glossary.md`. ### Indoor/Base Levels ``` XXXX YYYY CDTT TTTT AAAA AAAA ``` * `X` - X offset * `Y` - Y Offset * `C` - Whether or not to add #$08 to Y position * `D` - Whether or not to add #$08 to X position * `T` - Enemy Type * `A` - Enemy Attribute # Enemy Destroyed When an enemy is determined to be destroyed, e.g. their `ENEMY_HP` has gone to 0 after collision with a bullet, then the enemy routine for the active enemy is immediately adjusted to a routine index specified by `enemy_destroyed_routine_xx`. These are grouped in the `enemy_destroyed_routine_ptr_tbl`. For example, when a soldier is destroyed, `enemy_destroyed_routine_01` specifies byte #$05 for the soldier. This corresponds to `soldier_routine_04` # Soldier Generation In addition to the hard-coded screen-specific enemies that appear in the same location every play through (specified in the `level_x_enemy_screen_xx` data structures). _Contra_ generates soldiers at regular intervals with slightly random enemy logic so that each play through has a different experience. When playing a level, the game state is in `game_routine_05`, and specifically in `level_routine_04`. `level_routine_04` is run every frame. One part of `level_routine_04` is to run the logic to determine if an enemy soldier (enemy type #$05) should be created. This logic is in bank 2's `exe_soldier_generation` method. `exe_soldier_generation` runs one of three soldier generation routines depending on the current value of `SOLDIER_GENERATION_ROUTINE`. Initially, this value is #$00 and `soldier_generation_00` is executed. ## soldier_generation_00 `soldier_generation_00` initializes a level-specific timer that controls the speed of soldier generation. This timer is subsequently adjusted based on the number of times the game has been completed, and the player's current weapon strength. Every time the game has been completed (max of 3 times), #$28 is subtracted from the initial level-specific soldier generation timer. Additionally, the player weapon strength multiplied by #$05 is subtracted from the soldier generation timer. For example, level 3 (waterfall) has an initial level-specific timer value of #$d8 (specified in the `level_soldier_generation_timer` table). If the player has beaten the game once and has a `PLAYER_WEAPON_STRENGTH` of #$03 (S weapon), then the computed soldier generation timer would be #$a1. ``` #$a1 = #$d8 - (#$01 * #$28) - (#$05 * #$03) ``` Soldier generation is disabled on the indoor/base levels (level 2 and level 4) along with level 8 (alien's lair). They are disabled by a value of #$00 being specified in the `level_soldier_generation_timer` table. For these levels, no other soldier generation routine will be run, only `soldier_generation_00`. Once the soldier generation timer has been initialized and adjusted, the `SOLDIER_GENERATION_ROUTINE` is incremented so that the next game loop's `exe_soldier_generation` causes `soldier_generation_01` to execute. ## soldier_generation_01 `soldier_generation_01` is responsible for decrementing the soldier generation timer until it elapses. Then it is responsible for creating the soldier, if certain conditions are met. This includes randomizing the soldier's location and enemy attributes. `soldier_generation_01` will first look at the current soldier generation timer, if the timer is not yet less than #$00, then the timer is decremented by #$02, unless the frame is scrolling on an odd frame number. Then the timer is only decremented by #$01. Once the soldier generation timer has elapsed, the routine looks for an appropriate location to generate the soldier on the screen. Soldiers are always generated from the left or right edge of the screen. First the starting horizontal position is determined. This is essentially determined randomly by the current frame number and values in the `gen_soldier_initial_x_pos` table. The result will be either the left edge (#$0a) or the right edge (#$fa or #$fc). There is an exception for level one. Until a larger number of soldiers have already been generated, soldiers will only appear from the right, probably to make the beginning of the game slightly easier. Once the x position is decided, the routine will start looking for a vertical location that has a ground for the soldier to stand on. It does this in one of 3 ways randomly to ensure soldiers are generated from multiple locations if possible. The 3 methods are from top of the screen to the bottom, from the bottom of the screen to the top, and from the player vertical position up to the top. If a horizontal and vertical position is found where a soldier can be placed on the ground, then some memory is updated to specify the location and the soldier generation routine is incremented to `soldier_generation_02`. ## soldier_generation_02 At this point, a location is found for the soldier to generate. `soldier_generation_02` is responsible for actually initializing and creating the soldier. Some checks are performed to make sure it's appropriate to generate a soldier, for example, when `ENEMY_ATTACK_FLAG` is set to #$00 (off), then a soldier will not be generated. Other checks include that there are no solid blocks (collision code #$80) right in front of the soldier to generate, and that there is no player right next to the edge of the screen where the soldier would be generated from (this check doesn't happen after beating the game at least once). If any checks determine that the soldier should not be generated, then the routine resets the `SOLDIER_GENERATION_ROUTINE` back to #$00 and stops. To randomize the various behaviors of the generated soldiers, this routine will look up initial behavior from one of the `soldier_level_attributes_xx` tables based on the level. This will randomize the soldier direction, whether or not the soldier will shoot and how frequently, and a value specifying the probability of ultimately not generating the soldier. Finally, the soldier is generated and the values are moved into the standard enemy memory location addresses, creating the soldier.