Skip to navigation

Elite on the BBC Micro and NES

Main loop: Main game loop (Part 4 of 6)

[Elite-A, Flight]

Name: Main game loop (Part 4 of 6) [Show more] Type: Subroutine Category: Main loop Summary: Potentially spawn a lone bounty hunter or up to four pirates Deep dive: Program flow of the main game loop Ship data blocks Fixing ship positions
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * Main game loop (Part 1 of 6) calls via hordes * Main game loop (Part 3 of 6) calls via hordes

This section covers the following: * Potentially spawn (47% chance) either a pack of up to 8 bounty hunters, or a pack of up to 8 pirates * Also potentially spawn a Constrictor if this is the mission 1 endgame, or Thargoids if mission 2 is in progress
Other entry points: hordes Spawn a pack of ships, made up of ships from type A to type A + X, with the pack size normally being one to four ships, but rarely being up to eight ships
DEC EV \ Decrement EV, the extra vessels spawning delay, and if BPL MLOOPS \ it is still positive, jump to MLOOPS to stop spawning, \ so we only do the following when the EV counter runs \ down INC EV \ EV is negative, so bump it up again, setting it back \ to 0 LDA TP \ Fetch bits 2 and 3 of TP, which contain the status of AND #%00001100 \ mission 2 CMP #%00001000 \ If bit 3 is set and bit 2 is clear, keep going to BNE nopl \ spawn a Thargoid as we are transporting the plans in \ mission 2 and the Thargoids are trying to stop us, \ otherwise jump to nopl to skip spawning a Thargoid JSR DORND \ Set A and X to random numbers CMP #200 \ If the random number in A < 200 (78% chance), jump to BCC nopl \ nopl to skip spawning a Thargoid .fothg2 JSR GTHG \ Call GTHG to spawn a Thargoid ship and a Thargon \ companion .nopl JSR DORND \ Set A and X to random numbers LDY gov \ If the government of this system is 0 (anarchy), jump BEQ LABEL_2 \ straight to LABEL_2 to start spawning pirates or \ bounty hunters CMP #120 \ If the random number in A >= 120 (53% chance), jump to BCS MLOOPS \ MLOOPS to stop spawning (so there's a 47% chance of \ spawning pirates or bounty hunters) AND #7 \ Reduce the random number in A to the range 0-7, and CMP gov \ if A is less than government of this system, jump BCC MLOOPS \ to MLOOPS to stop spawning (so safer governments with \ larger gov numbers have a greater chance of jumping \ out, which is another way of saying that more \ dangerous systems spawn pirates and bounty hunters \ more often) .LABEL_2 \ --- Mod: Code removed for Elite-A: ------------------> \ \ Now to spawn a lone bounty hunter or a group of \ \ pirates \ \ JSR Ze \ Call Ze to initialise INWK to a potentially hostile \ \ ship, and set A and X to random values \ \ \ \ Note that because Ze uses the value of X returned by \ \ DORND, and X contains the value of A returned by the \ \ previous call to DORND, this does not set the new ship \ \ to a totally random location. See the deep dive on \ \ "Fixing ship positions" for details \ \ CMP #100 \ If the random number in A >= 100 (61% chance), jump \ BCS mt1 \ to mt1 to spawn pirates, otherwise keep going to \ \ spawn a lone bounty hunter \ --- And replaced by: --------------------------------> \ Now to spawn a group of bounty hunters, a Thargoid or \ a pack of pirates CPX #100 \ If the random number in X >= 100 (61% chance), jump BCS mt1 \ to mt1 to spawn pirates, otherwise keep going to \ spawn bounty hunters or a Thargoid \ --- End of replacement ------------------------------> INC EV \ Increase the extra vessels spawning counter, to \ prevent the next attempt to spawn extra vessels AND #3 \ Set A = random number in the range 0-3, which we \ will now use to determine the type of ship \ --- Mod: Code removed for Elite-A: ------------------> \ ADC #CYL2 \ Add A to #CYL2 (we know the C flag is clear as we \ \ passed through the BCS above), so A is now one of the \ \ lone bounty hunter ships, i.e. Cobra Mk III (pirate), \ \ Asp Mk II, Python (pirate) or Fer-de-lance \ \ \ \ Interestingly, this logic means that the Moray, which \ \ is the ship after the Fer-de-lance in the XX21 table, \ \ never spawns, as the above logic chooses a blueprint \ \ number in the range CYL2 to CYL2+3 (i.e. 24 to 27), \ \ and the Moray is blueprint 28 \ \ \ \ No other code spawns the ship with blueprint 28, so \ \ this means the Moray is never seen in Elite \ \ \ \ This is presumably a bug, which could be very easily \ \ fixed by inserting one of the following instructions \ \ before the ADC #CYL2 instruction above: \ \ \ \ * SEC would change the range to 25 to 28, which \ \ would cover the Asp Mk II, Python (pirate), \ \ Fer-de-lance and Moray \ \ \ \ * LSR A would set the C flag to a random number to \ \ give a range of 24 to 28, which would cover the \ \ Cobra Mk III (pirate), Asp Mk II, Python (pirate), \ \ Fer-de-lance and Moray \ \ \ \ It's hard to know what the authors' original intent \ \ was, but the second approach makes the Moray and Cobra \ \ Mk III the rarest choices, with the Asp Mk II, Python \ \ and Fer-de-Lance being more likely, and as the Moray \ \ is described in the literature as a rare ship, and the \ \ Cobra can already be spawned as part of a group of \ \ pirates (see mt1 below), I tend to favour the LSR A \ \ solution over the SEC approach \ --- And replaced by: --------------------------------> ADC #25 \ Add A to 25 (we know the C flag is clear as we passed \ through the BCS above), so A is now a ship blueprint \ position in the range 25-28, which is where the bounty \ hunter ships live in the ship files \ --- End of replacement ------------------------------> TAY \ Copy the new ship type to Y JSR THERE \ Call THERE to see if we are in the Constrictor's \ system in mission 1 BCC NOCON \ If the C flag is clear then we are not in the \ Constrictor's system, so skip to NOCON LDA #%11111001 \ Set the AI flag of this ship so that it has E.C.M., STA INWK+32 \ has a very high aggression level of 28 out of 31, is \ hostile, and has AI enabled - nasty stuff! LDA TP \ Fetch bits 0 and 1 of TP, which contain the status of AND #%00000011 \ mission 1 LSR A \ Shift bit 0 into the C flag BCC NOCON \ If bit 0 is clear, skip to NOCON as mission 1 is not \ in progress ORA MANY+CON \ Bit 0 of A now contains bit 1 of TP, so this will be \ set if we have already completed mission 1, so this OR \ will be non-zero if we have either completed mission \ 1, or there is already a Constrictor in our local \ bubble of universe (in which case MANY+CON will be \ non-zero) BEQ YESCON \ If A = 0 then mission 1 is in progress, we haven't \ completed it yet, and there is no Constrictor in the \ vicinity, so jump to YESCON to spawn the Constrictor .NOCON TYA \ Set A to the new ship type in Y EQUB &2C \ Skip the next instruction by turning it into \ &2C &A9 &1F, or BIT &1FA9, which does nothing apart \ from affect the flags .YESCON LDA #CON \ If we jump straight here, we are in the mission 1 \ endgame and it's time to spawn the Constrictor, so \ set A to the Constrictor's type .focoug JSR NWSHP \ Spawn the new ship, whether it's a pirate or \ Constrictor .mj1 JMP MLOOP \ Jump down to MLOOP, as we are done spawning ships .mt1 \ --- Mod: Code removed for Elite-A: ------------------> \ AND #3 \ It's time to spawn a group of pirates, so set A to a \ \ random number in the range 0-3, which will be the \ \ loop counter for spawning pirates below (so we will \ \ spawn 1-4 pirates) \ \ STA EV \ Delay further spawnings by this number \ \ STA XX13 \ Store the number in XX13, the pirate counter \ \.mt3 \ \ JSR DORND \ Set A and X to random numbers \ \ STA T \ Set T to a random number \ \ JSR DORND \ Set A and X to random numbers \ \ AND T \ Set A to the AND of two random numbers, so each bit \ \ has 25% chance of being set which makes the chances \ \ of a smaller number higher \ \ AND #7 \ Reduce A to a random number in the range 0-7, though \ \ with a bigger chance of a smaller number in this range \ \ STA CPIR \ Set CPIR to this random number in the range 0-7 \ \.more \ \ LDA CPIR \ Set A to the ship type in CPIR \ \ ADC #PACK \ #PACK is set to #SH3, the ship type for a Sidewinder, \ \ so this sets our new ship type to one of the pack \ \ hunters, namely a Sidewinder, Mamba, Krait, Adder, \ \ Gecko, Cobra Mk I, Worm or Cobra Mk III (pirate) \ --- And replaced by: --------------------------------> LDA #17 \ Fall through into hordes to spawn a pack of ships from LDX #7 \ ship blueprint positions 17 to 24, which is where the \ pirate ships live in the ship blueprint files .hordes \ This routine spawns a pack of ships, made up of ships \ from type A to type A + X, with the pack size normally \ being one to four ships, but rarely being up to eight \ ships \ \ Let's call A the "base ship type", and X the "ship \ type range" STA horde_base+1 \ Modify the ADC instruction at horde_base so that it \ adds the base ship type given in A STX horde_mask+1 \ Modify the ADC instruction at horde_mask so that it \ ANDs the ship type range given in X JSR DORND \ Set A and X to random numbers CMP #248 \ If A >= 248 (3.1% chance), jump to horde_large so we BCS horde_large \ potentially spawn a larger pack (i.e. up to 8 ships) STA XX13 \ We are going to spawn a smaller pack (i.e. up to 4 TXA \ ships), so set: AND XX13 \ AND #3 \ A = A AND X AND 3 \ \ to give a random pack size of 0-3, with a greater \ chance of the smaller numbers than the larger ones \ (due to the AND). This will be our pack size, which \ won't be affected further by the following AND \ instruction .horde_large AND #7 \ If we are going to spawn a larger pack, reduce the \ random number in A to the range 0-7, with an equal \ chance of each of the numbers. This will be our pack \ size \ By this point our pack size is in A, and is either \ 0-3 or 0-7 STA EV \ Delay further spawnings by this number STA XX13 \ Store the number in XX13, the pack size counter .mt3 JSR DORND \ Set A and X to random numbers STA T \ Set A = A AND X TXA \ AND T \ which is in the range 0-255, but with a greater chance \ of being a smaller number (due to the AND) .horde_mask AND #&FF \ This instruction gets modified so that it ANDs the \ ship type range given in the argument X to the \ hordes routine, i.e. it turns into AND #type_range, \ which reduces our random number to be between 0 and \ the ship type range (so if we add this number to the \ base ship type, it will pick a random ship type from \ within the range A to A + X, where A and X are the \ arguments to the original call to hordes STA CPIR \ Set CPIR to our random number in the range 0 to \ the ship type .more LDA CPIR \ Set A to the ship type in CPIR CLC \ Clear the C flag for the addition below .horde_base ADC #0 \ This instruction gets modified so that it adds the \ ship type given in the argument A to the hordes \ routine, i.e. it turns into ADC #ship_type, so this \ sets A to a ship type in the range we want INC INWK+27 \ Increment the speed of the ship we are about to spawn, \ so later ships in the pack go faster INC INWK+1 \ Increment the x_hi coordinate of the ship we are about \ to spawn, so later ships in the pack are spread out to \ the sides INC INWK+4 \ Increment the y_hi coordinate of the ship we are about \ to spawn, so later ships in the pack are spread out \ to the top and bottom \ --- End of replacement ------------------------------> JSR NWSHP \ Try adding a new ship of type A to the local bubble \ --- Mod: Code removed for Elite-A: ------------------> \ BCS P%+7 \ If the ship was successfully added, skip the following \ \ two instructions \ \ DEC CPIR \ The ship wasn't added, which might be because the ship \ \ blueprint for this ship type isn't in the currently \ \ loaded ship blueprints file, so decrement CPIR to \ \ point to the previous ship type, so we can try \ \ spawning that type of pirate instead \ \ BPL more \ Loop back to more to have another go at spawning this \ \ pirate, until we have tried spawning a Sidewinder when \ \ CPIR is 0, in which case give up and move on to the \ \ next pirate to spawn \ \ DEC XX13 \ Decrement the pirate counter \ \ BPL mt3 \ If we need more pirates, loop back up to mt3, \ \ otherwise we are done spawning, so fall through into \ \ the end of the main loop at MLOOP \ --- And replaced by: --------------------------------> CMP #24 \ This compares the value of A (which is set to the \ x_sign value of the spawned ship by NWSHP), but the \ result isn't used anywhere, as CMP affects the Z and N \ flags (not the C flag), and these same flags will be \ overwritten by the two DEC instructions below... so \ this instruction has no effect BCS P%+7 \ If the ship was successfully added, skip the following \ two instructions DEC CPIR \ The ship wasn't added, which might be because the ship \ blueprint for this ship type isn't in the currently \ loaded ship blueprints file, so decrement CPIR to \ point to the previous ship type, so we can try \ spawning that type of ship instead BPL more \ Loop back to more to have another go at spawning this \ ship, until CPIR is 0, in which case we have tried \ spawning all the ship types in the range, so give up \ and move on to the next pirate to spawn DEC XX13 \ Decrement the pack size counter BPL mt3 \ If we need more ships, loop back up to mt3, \ otherwise we are done spawning, so fall through into \ the end of the main loop at MLOOP \ --- End of replacement ------------------------------>