Prev: A727 Up: Map Next: A81E
A739: Spawn Enemies
Used by the routine at MainLoop.
Called every frame while the robot is alive. It tries to start a new enemy at a random position in the sector that the robot is in, and tries to start a new destroyer in the sector that is under attack. A new enemy starts as the sprites that show it materialising. The enemy is only started if there is a free entity, and if the cell that is chosen at random is empty.
SpawnEnemies A739 LD A,($9690) Fetch the type of the robot.
A73C CP $10 Return if it is below 10.
A73E RET C
A73F CP $30 Return if it is 30 or above, as the robot is not in a walking state.
A741 RET NC
A742 LD HL,$96D0 Point HL at the first of the six entities that are used for enemies.
A745 LD DE,$0010 Each entity is 10 bytes long.
A748 LD B,$06 There are six entities to check.
SpawnEnemies_Find A74A LD A,(HL) Fetch the type of the entity.
A74B AND A Jump if it is not in use.
A74C JR Z,SpawnEnemies_UseFirstEntity
A74E ADD HL,DE Move on to the next entity.
A74F DJNZ SpawnEnemies_Find Loop back until all of them have been tried.
A751 JR SpawnEnemies_Destroyer Jump to try to start a destroyer.
SpawnEnemies_UseFirstEntity A753 PUSH HL Copy the address of the entity into IX...
A754 POP IX Pop it into IX.
A756 LD B,$10 There are 10 bytes to clear.
SpawnEnemies_Clear A758 LD (HL),$00 Clear a byte of the entity.
A75A INC HL Move on to the next byte.
A75B DJNZ SpawnEnemies_Clear Loop back until the entity has been cleared.
A75D LD A,($9692) Fetch the X cell of the camera...
A760 AND $30 ...and keep the sector (a multiple of 10).
A762 LD E,A Keep the sector column of the camera.
A763 LD A,($9617) Fetch the random number...
A766 AND $0F ...limited to 00-0F...
A768 OR E ...and combine it with the sector to choose the X cell.
A769 CP $2F Jump if it is outside the map, which is 30 cells wide.
A76B JR NC,SpawnEnemies_Destroyer
A76D LD D,A Keep the X cell...
A76E LD E,$00 ...and use zero for the fraction.
A770 LD A,($9694) Fetch the Y cell of the camera...
A773 AND $30 ...and keep the sector.
A775 LD L,A Keep the sector row of the camera.
A776 LD A,($9615) Fetch the frame counter...
A779 AND $0F ...limited to 00-0F...
A77B OR L ...and combine it with the sector to choose the Y cell.
A77C CP $2F Jump if it is outside the map, which is 30 cells high.
A77E JR NC,SpawnEnemies_Destroyer
A780 LD H,A Keep the Y cell...
A781 LD L,$00 ...and use zero for the fraction.
A783 CALL FindMapCell Find the cell using FindMapCell.
A786 JR NZ,SpawnEnemies_Destroyer Jump if it is not empty.
A788 LD (IX+$00),$40 Start the enemy with the first sprite of the sequence that shows it materialising.
A78C CALL SetPosition Store its position.
A78F CALL CheckEnemyOverlap Check whether another enemy is in the way using CheckEnemyOverlap.
A792 JR NC,SpawnEnemies_Random Jump if there is not.
A794 LD (IX+$00),$00 Otherwise cancel the new enemy...
A798 JR SpawnEnemies_Destroyer ...and jump to try to start a destroyer.
SpawnEnemies_Random A79A LD A,R Fetch a number from the memory refresh register...
A79C AND $F3 ...limit it to a time and a direction...
A79E LD (IX+$07),A ...and store it.
A7A1 LD A,($9658) Fetch the number of sectors that have been activated.
A7A4 AND A Test whether there are any.
A7A5 LD A,($9617) Fetch the random number.
A7A8 JR NZ,SpawnEnemies_AnyKind Jump if some sectors have been activated, to use any of the kinds of enemy.
A7AA AND $05 Otherwise limit the choice to the first two kinds of enemy...
SpawnEnemies_AnyKind A7AC AND $07 ...and limit the choice to the eight entries of the table.
A7AE LD L,A Use it as an index...
A7AF LD H,$00
A7B1 LD BC,$A81E Point BC at EnemyTypes.
A7B4 ADD HL,BC Add the index.
A7B5 LD A,(HL) Fetch the type that the enemy is going to have...
A7B6 LD (IX+$05),A ...and store it.
Now try to start a destroyer. Destroyers are only started while a sector is under attack.
SpawnEnemies_Destroyer A7B9 LD HL,$9730 Point HL at the first of the four entities that are used for destroyers.
A7BC LD DE,$0010 Each entity is 10 bytes long.
A7BF LD B,$04 There are four entities to check.
SpawnEnemies_FindDestroyer A7C1 LD A,(HL) Fetch the type of the entity.
A7C2 AND A Jump if it is not in use.
A7C3 JR Z,SpawnEnemies_UseSecondEntity
A7C5 ADD HL,DE Move on to the next entity.
A7C6 DJNZ SpawnEnemies_FindDestroyer Loop back until all of them have been tried.
A7C8 RET Return.
SpawnEnemies_UseSecondEntity A7C9 PUSH HL Copy the address of the entity into IX...
A7CA POP IX Pop it into IX.
A7CC LD B,$10 There are 10 bytes to clear.
SpawnEnemies_ClearDestroyer A7CE LD (HL),$00 Clear a byte of the entity.
A7D0 INC HL Move on to the next byte.
A7D1 DJNZ SpawnEnemies_ClearDestroyer Loop back until the entity has been cleared.
A7D3 LD A,($9647) Fetch the code of the sector that is under attack...
A7D6 LD C,A ...and keep it in C.
A7D7 RRA Move the bits for the row into place...
A7D8 RRA Shift the row one more place.
A7D9 AND $30 ...and keep them.
A7DB CP $30 Return if there is no sector under attack.
A7DD RET Z
A7DE XOR $30 Turn the row upside down...
A7E0 SUB $10 ...and use it to find the Y cell of the sector.
A7E2 LD H,A Keep the Y cell.
A7E3 LD A,($9617) Fetch the random number...
A7E6 AND $0F ...limited to 00-0F...
A7E8 OR H ...and combine it with the sector to choose the Y cell...
A7E9 LD H,A ...and keep it in H.
A7EA LD A,C Fetch the code of the sector again.
A7EB RLA Move the bits for the column into place...
A7EC RLA
A7ED RLA
A7EE AND $30 ...and keep them.
A7F0 CP $30 Return if there is no sector under attack.
A7F2 RET Z
A7F3 LD D,A Keep the sector.
A7F4 LD A,R Fetch a number from the memory refresh register...
A7F6 AND $0F ...limited to 00-0F...
A7F8 OR D ...combine it with the sector to choose the X cell...
A7F9 LD D,A ...and keep it in D.
A7FA LD L,$00 Use zero for the fraction of the Y position...
A7FC LD E,L ...and of the X position.
A7FD CALL FindMapCell Find the cell using FindMapCell.
A800 RET NZ Return if it is not empty.
A801 LD (IX+$00),$40 Start the destroyer with the first sprite of the sequence that shows it materialising.
A805 CALL SetPosition Store its position.
A808 CALL CheckEnemyOverlap Check whether another enemy is in the way using CheckEnemyOverlap.
A80B JR NC,SpawnEnemies_SetType Jump if there is not.
A80D LD (IX+$00),$00 Otherwise cancel the new destroyer...
A811 RET ...and return.
SpawnEnemies_SetType A812 LD (IX+$05),$64 Set the type that the destroyer will have when it has materialised.
A816 LD A,R Choose a random direction and time...
A818 AND $F3
A81A LD (IX+$07),A ...and store it.
A81D RET Return.
Prev: A727 Up: Map Next: A81E