As of now player shots can be one of:
– 1 shots
– 2 shots
– 3 shots
– 4 shots
– blaster shots
– laser shots
(perhaps later 1* shot, 2* shot and 3* shot – which are “old style” shots)
– all of the above can be combined with one or two scoopies
– all of the above can be combined with or without autofire
There are in general 3 different behaviours possible:
– full damage
– partial damage
– timed damage
Full damage shots
1 shots and blaster shots are full damage shots.
This means the complete damage the shot can make is done when the shot hits an enemy.
The shot is removed from the object list and is gone for good.
Partial damage shots
2,3,4 shots are partial damage shots.
This means, when the shot hits an enemy the enemy recieves as much damage as it can absorb till destroyed. If the shot strength (2,3,4) is more than the enemy needs to be killed, the shot is reduced in strength and continues.
The internal handling of these shots has changed from alpha 5 to alpha 6. Befor the reduction was always done in “1” steps. Now the strength is consumed by as much as the enemy strength in one go. This gives more efficient collision detection. For optimization purposes, partial damage shots only are considered with “normal” enemies (see below).
For bosses and bugs, these shots are treated as “full damage shots” – since the said enemies have “many” hitpoints and most of the time they would be consumed fully anyway.
Lasers do damage over time. If the player shoots, the laser is active for a short amount of time (10 rounds). Each round the laser does a small amount of damage.
Timed shots with autofire fire continously!
Scoopies in general always shoot the same kind of shot as the player. If the shot type is partial, each of the three shots (scoopy left, player, scoopy right) can have different partial shots – depending on how much shot power has been used to destroy enemies.
Scoopy shots in general
Programmatically the scoopy shot is an extention of the player shot – and not a distinct “shot object” of its own. Each player shot has two “flags” whether it also has a scoopy shot on the right and/or/left side. The flag consists of 4 bits. These four bits also encode the “partial” shot information. The collision detection of the scoopy shots is also done in relation to the player shot (add/subtract certain position information)
There are different kind of enemy objects. For each kind the collision detection might be handled differently.
– “normal” enemy
– shield enemy
– bug enemy
Collision detection – normal enemy
The collision detection is realized in a subroutine call from each enemy behaviour. The subroutine in general tests only TWO selected shots if they hit or not. The shot selection (which of all possible shots should be used) to be tested is located in different parts of the code – depending on the stage of the game. The selection itself is realized in two macros called INITIALZE_SHOT_TEST_MOVE_BLOCK_1 (and 2). Per default these are called in the background star “moveTo” wait loop.
The selection considers information about the general location (e.g. if the shot is below the lowest enemy – it is not (ever) tested) of the enemies, whether it has hit in the round “before” and the general object distance of the other to be tested shot.
The collision subroutine finaly leads to another macro call “COL_DETECT_ENEMY_SHOTS_ENEMY” which realizes the collision detection.
For easier y testing, all enemy objects have the lowest (vector-) position as a starting point, the starting point also is always x = 0 -> centered!
After initial y position testing – the “interesting” x position testing is done using positive only coordinates (+$80 to all positions). This relieves some of the hassels dealing with two-complement 8bit numbers and Z, C and V flags.
In general the enemy ship (x)position is taken as the base. If the x=0 position of the ship is within the radius of the bullet (within one radius to the left or one radius to the right) the shot hit the enemy.
The radius (due to internal comparissons) used to be unique to each shot – it is not anymore.
(This made more sense, when I used 1,2,3,4 horizontal shot design instead of the now used vertical design) Because of the result of the above comparisson – if not hit, the routine knows whether the shot is to the left or right of the enemy. If scoopies are present, than a further testing can be done.
It is assumed that the radius for the scoopy shot is always the same as the “main” shot. If the shot is within 3 radius of the x position of the enemy (and a scoopy on the correct side is present) than the scoopy scored a hit. Depending on the shot type, damage is reduced from the enemy hitpoints, the shot power is reduced or the shot is removed.
Due to the nature of the laser (and difficulty level – see below), the laser has to be shortened, when it hits an enemy (to the lowest enemy it can possibly hit). This makes it necessary to have a special treatment for the laser. The above logic is done for all enemies – but instead of removing hitpoints and destroying enemies – the location of the enmies is compared to a special laserEnemy position. After all enemies have been tested, the lowest enemy is known – and only that enemies is reduced (and maybe killed).
The location of the lowest enemy is given to the drawing routine of the laser, and it is only drawn up to that position. This logic is also done (if appropriate) for the left and right scoopy.
Collision detection – shield enemy
Same as above. But the shot is always fully consumed, and the shield does not take damage.
Collision detection – bug enemy
Nearly the same as above, but the final detection is made in another set of macros “COL_DETECT_ENEMY_SHOTS_ENEMY_BUG”. There some bug specialties are considered, like:
– bugs move differently – so the internal position is represented differently
– bugs can have up to 255 hitpoints (normal enemy max = 31), so the hitpoints are calculated differently
– due to optimization shots are not treated as partial shots
Collision detection – boss
Each boss has its own collision detection, since they are all “completly” different.
Due to optimization shots are not treated as partial shots
Collision detection – swarm
The Swarm of boss 1 is different in many aspects.
The sheer amount of enemies and the “near” position to the player, and the small size of the enemies makes it necessary to test each shot with each enemy. Chosing only “several” shots to test results in many shots just “going thru” the enemies. This strategy makes the swarm extremly sensitive to shots (more exact than any other collision detection used within VB).
It slows things down – but it has been balanced out, so that the refresh rate is within limits.
Collision detection – debris
Debris really is a special kind of enemy, which can not be hit by bullets.
No collision detection done here.
As of now there are four difficulty levels:
The difficulty has impact on the behaviour of player shots.
shot 1,2,3,4: damage per bullet = 3
blaster shot: damage = 10
laser: 2 damage per round, laser also is NOT inhibited by enemies, the ray goes thru all enemies above!
shot 1,2,3,4: damage per bullet = 2
blaster shot: damage = 7
laser: 1 damage per round
shot 1,2,3,4: damage per bullet = 1
blaster shot: damage = 6
laser: 1 damage per round
shot 1,2,3,4: damage per bullet = 1
blaster shot: damage = 5
laser: 1 damage every second round