Prev: 42791 Up: Map Next: 43038
42809: 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 42809 LD A,(38544) Fetch the type of the robot.
42812 CP 16 Return if it is below 16.
42814 RET C
42815 CP 48 Return if it is 48 or above, as the robot is not in a walking state.
42817 RET NC
42818 LD HL,38608 Point HL at the first of the six entities that are used for enemies.
42821 LD DE,16 Each entity is 16 bytes long.
42824 LD B,6 There are six entities to check.
SpawnEnemies_Find 42826 LD A,(HL) Fetch the type of the entity.
42827 AND A Jump if it is not in use.
42828 JR Z,SpawnEnemies_UseFirstEntity
42830 ADD HL,DE Move on to the next entity.
42831 DJNZ SpawnEnemies_Find Loop back until all of them have been tried.
42833 JR SpawnEnemies_Destroyer Jump to try to start a destroyer.
SpawnEnemies_UseFirstEntity 42835 PUSH HL Copy the address of the entity into IX...
42836 POP IX Pop it into IX.
42838 LD B,16 There are 16 bytes to clear.
SpawnEnemies_Clear 42840 LD (HL),0 Clear a byte of the entity.
42842 INC HL Move on to the next byte.
42843 DJNZ SpawnEnemies_Clear Loop back until the entity has been cleared.
42845 LD A,(38546) Fetch the X cell of the camera...
42848 AND 48 ...and keep the sector (a multiple of 16).
42850 LD E,A Keep the sector column of the camera.
42851 LD A,(38423) Fetch the random number...
42854 AND 15 ...limited to 0-15...
42856 OR E ...and combine it with the sector to choose the X cell.
42857 CP 47 Jump if it is outside the map, which is 48 cells wide.
42859 JR NC,SpawnEnemies_Destroyer
42861 LD D,A Keep the X cell...
42862 LD E,0 ...and use zero for the fraction.
42864 LD A,(38548) Fetch the Y cell of the camera...
42867 AND 48 ...and keep the sector.
42869 LD L,A Keep the sector row of the camera.
42870 LD A,(38421) Fetch the frame counter...
42873 AND 15 ...limited to 0-15...
42875 OR L ...and combine it with the sector to choose the Y cell.
42876 CP 47 Jump if it is outside the map, which is 48 cells high.
42878 JR NC,SpawnEnemies_Destroyer
42880 LD H,A Keep the Y cell...
42881 LD L,0 ...and use zero for the fraction.
42883 CALL FindMapCell Find the cell using FindMapCell.
42886 JR NZ,SpawnEnemies_Destroyer Jump if it is not empty.
42888 LD (IX+0),64 Start the enemy with the first sprite of the sequence that shows it materialising.
42892 CALL SetPosition Store its position.
42895 CALL CheckEnemyOverlap Check whether another enemy is in the way using CheckEnemyOverlap.
42898 JR NC,SpawnEnemies_Random Jump if there is not.
42900 LD (IX+0),0 Otherwise cancel the new enemy...
42904 JR SpawnEnemies_Destroyer ...and jump to try to start a destroyer.
SpawnEnemies_Random 42906 LD A,R Fetch a number from the memory refresh register...
42908 AND 243 ...limit it to a time and a direction...
42910 LD (IX+7),A ...and store it.
42913 LD A,(38488) Fetch the number of sectors that have been activated.
42916 AND A Test whether there are any.
42917 LD A,(38423) Fetch the random number.
42920 JR NZ,SpawnEnemies_AnyKind Jump if some sectors have been activated, to use any of the kinds of enemy.
42922 AND 5 Otherwise limit the choice to the first two kinds of enemy...
SpawnEnemies_AnyKind 42924 AND 7 ...and limit the choice to the eight entries of the table.
42926 LD L,A Use it as an index...
42927 LD H,0
42929 LD BC,43038 Point BC at EnemyTypes.
42932 ADD HL,BC Add the index.
42933 LD A,(HL) Fetch the type that the enemy is going to have...
42934 LD (IX+5),A ...and store it.
Now try to start a destroyer. Destroyers are only started while a sector is under attack.
SpawnEnemies_Destroyer 42937 LD HL,38704 Point HL at the first of the four entities that are used for destroyers.
42940 LD DE,16 Each entity is 16 bytes long.
42943 LD B,4 There are four entities to check.
SpawnEnemies_FindDestroyer 42945 LD A,(HL) Fetch the type of the entity.
42946 AND A Jump if it is not in use.
42947 JR Z,SpawnEnemies_UseSecondEntity
42949 ADD HL,DE Move on to the next entity.
42950 DJNZ SpawnEnemies_FindDestroyer Loop back until all of them have been tried.
42952 RET Return.
SpawnEnemies_UseSecondEntity 42953 PUSH HL Copy the address of the entity into IX...
42954 POP IX Pop it into IX.
42956 LD B,16 There are 16 bytes to clear.
SpawnEnemies_ClearDestroyer 42958 LD (HL),0 Clear a byte of the entity.
42960 INC HL Move on to the next byte.
42961 DJNZ SpawnEnemies_ClearDestroyer Loop back until the entity has been cleared.
42963 LD A,(38471) Fetch the code of the sector that is under attack...
42966 LD C,A ...and keep it in C.
42967 RRA Move the bits for the row into place...
42968 RRA Shift the row one more place.
42969 AND 48 ...and keep them.
42971 CP 48 Return if there is no sector under attack.
42973 RET Z
42974 XOR 48 Turn the row upside down...
42976 SUB 16 ...and use it to find the Y cell of the sector.
42978 LD H,A Keep the Y cell.
42979 LD A,(38423) Fetch the random number...
42982 AND 15 ...limited to 0-15...
42984 OR H ...and combine it with the sector to choose the Y cell...
42985 LD H,A ...and keep it in H.
42986 LD A,C Fetch the code of the sector again.
42987 RLA Move the bits for the column into place...
42988 RLA
42989 RLA
42990 AND 48 ...and keep them.
42992 CP 48 Return if there is no sector under attack.
42994 RET Z
42995 LD D,A Keep the sector.
42996 LD A,R Fetch a number from the memory refresh register...
42998 AND 15 ...limited to 0-15...
43000 OR D ...combine it with the sector to choose the X cell...
43001 LD D,A ...and keep it in D.
43002 LD L,0 Use zero for the fraction of the Y position...
43004 LD E,L ...and of the X position.
43005 CALL FindMapCell Find the cell using FindMapCell.
43008 RET NZ Return if it is not empty.
43009 LD (IX+0),64 Start the destroyer with the first sprite of the sequence that shows it materialising.
43013 CALL SetPosition Store its position.
43016 CALL CheckEnemyOverlap Check whether another enemy is in the way using CheckEnemyOverlap.
43019 JR NC,SpawnEnemies_SetType Jump if there is not.
43021 LD (IX+0),0 Otherwise cancel the new destroyer...
43025 RET ...and return.
SpawnEnemies_SetType 43026 LD (IX+5),100 Set the type that the destroyer will have when it has materialised.
43030 LD A,R Choose a random direction and time...
43032 AND 243
43034 LD (IX+7),A ...and store it.
43037 RET Return.
Prev: 42791 Up: Map Next: 43038