.dobj1 \ If we jump here from below here then the player has \ run out of energy LDA #%10000000 \ Set bit 7 of sentinelHasWon to indicate that the STA sentinelHasWon \ player has run out of energy and the Sentinel has won JMP FinishEnemyTactics \ Jump to FinishEnemyTactics to stop applying tactics to \ the current enemy and return to the ProcessGameplay \ routine to continue with the gameplay loop .DrainObjectEnergy LDX targetObject \ Set X to the object number that is being drained of \ energy CPX playerObject \ If this is not the player object, jump to dobj2 to BNE dobj2 \ drain energy from object #X rather than the player \ If we get here then this is the player object, so we \ now drain energy from the player LDA playerEnergy \ If the player has no energy then draining more energy BEQ dobj1 \ will kill them, so jump to dobj1 to process this SEC \ Subtract 1 from the player's energy SBC #1 STA playerEnergy JSR UpdateIconsScanner \ Update the icons in the top-left corner of the screen \ to show the player's current energy level and redraw \ the scanner box LDA #5 \ Make sound #5 (ping) JSR MakeSound SEC \ Set the C flag to indicate that the player still has a \ non-zero energy level JMP dobj7 \ Jump to dobj7 to finish up and return from the \ subroutine .dobj2 \ If we get here then we need to drain energy from \ object #X TXA \ Check to see whether it is safe to redraw object #X JSR AbortWhenVisible \ without risk of corrupting a screen pan (if there is \ a risk and it can't be updated, then the call to \ AbortWhenVisible will not return here and will instead \ abort tactics for this iteration of the gameplay loop) LDA objectTypes,X \ Set A to the type of object #X BNE dobj3 \ If object #X is not a robot (i.e. not an object of \ type 0), jump to dobj3 \ If we get here then we are draining energy from a \ robot in object #X LDY enemyObject \ Set enemyDrainTimer = 0 to restart the drain counter LDA #0 \ for the enemy in part 5 of ApplyTactics, so it doesn't STA enemyDrainTimer,Y \ drain energy for another 120 timer ticks (120 * 0.06 = \ 7.2 seconds) LDA #3 \ Set A = 3 so the robot loses one energy unit and \ changes into a boulder (i.e. an object of type 3) BNE dobj5 \ Jump to dobj5 to set the new object type of object #X \ to the value in A, so the robot turns into a boulder .dobj3 CMP #2 \ If object #X is not a tree (i.e. not an object of BNE dobj4 \ type 2), jump to dobj4 \ If we get here then we are draining energy from a \ tree in object #X JSR DeleteObject \ Delete object #X and remove it from the landscape, \ as trees only have one energy unit, so draining one \ unit from a tree removes it altogether JMP dobj6 \ Jump to dobj6 to skip updating the energy for object \ #X, as we just deleted it .dobj4 \ If we get here then we must be draining energy from a \ boulder in object #X, so now we change it into a tree LDA #116 \ Set minObjWidth = 116 so we use the width of the wider STA minObjWidth \ object, the boulder, when we calculate the object's \ visibility when updating the object on-screen LDA #2 \ Set A = 2 so the boulder loses one energy unit and \ changes into a tree (i.e. an object of type 2) .dobj5 STA objectTypes,X \ Set the object type of object #X to the new type in A .dobj6 CLC \ Clear the C flag to return from the subroutine .dobj7 PHP \ Store the C flag on the stack so we can retrieve it \ below to return from the subroutine LDY enemyObject \ Increment the energy level for the enemy object by one LDA enemyEnergy,Y \ unit, as the enemy just absorbed one unit from the CLC \ target object ADC #1 STA enemyEnergy,Y PLP \ Retrieve the C flag from the stack to return from the \ subroutine RTS \ Return from the subroutineName: DrainObjectEnergy [Show more] Type: Subroutine Category: Gameplay Summary: Drain energy from an object into an enemy, transforming it into an object with an energy level of one unit less (if applicable)Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ApplyTactics (Part 5 of 8) calls DrainObjectEnergy * ApplyTactics (Part 7 of 8) calls DrainObjectEnergy
Arguments: targetObject The number of the object being drained of energy enemyObject The number of the object doing the draining
Returns: C flag Result flag: * Set if the player object is being drained and they still have a positive energy level after the draining * Clear if one of the following is true: * The player object is being drained and they now have a negative energy level, so the Sentinel has won * The player object is not being drained X The object number of the target that has been drained of energy (and which has therefore been transformed into a different object type)
[X]
Subroutine AbortWhenVisible (category: Gameplay)
Abort applying the tactics for this gameplay loop if updating the object on-screen will corrupt a screen pan
[X]
Subroutine DeleteObject (category: 3D objects)
Delete an object, removing it from the landscape and vacating its object number
[X]
Subroutine FinishEnemyTactics (category: Gameplay)
Stop applying tactics to the current enemy and return to the ProcessGameplay routine to continue with the gameplay loop
[X]
Subroutine MakeSound (category: Sound)
Make a sound
[X]
Subroutine UpdateIconsScanner (category: Scanner/energy row)
Update the icons in the top-left corner of the screen to show the player's current energy level and redraw the scanner box
[X]
Label dobj1 is local to this routine
[X]
Label dobj2 is local to this routine
[X]
Label dobj3 is local to this routine
[X]
Label dobj4 is local to this routine
[X]
Label dobj5 is local to this routine
[X]
Label dobj6 is local to this routine
[X]
Label dobj7 is local to this routine
[X]
Variable enemyDrainTimer in workspace Main variable workspace
A timer for each enemy that counts down every 0.06
[X]
Variable enemyEnergy in workspace Main variable workspace
Enemy energy levels (one byte per enemy)
[X]
Variable enemyObject in workspace Zero page
The object number of the enemy to which we are applying tactics in this iteration around the main loop (0-7)
[X]
Variable minObjWidth in workspace Main variable workspace
The on-screen width to use when updating objects
[X]
Variable objectTypes (category: 3D objects)
The object types table for up to 64 objects
[X]
Variable playerEnergy in workspace Main variable workspace
The player's energy level (in the range 0 to 63)
[X]
Variable playerObject in workspace Zero page
The number of the player object
[X]
Variable sentinelHasWon in workspace Main variable workspace
A flag to record when the player runs out of energy (i.e. the energy level goes negative), at which point the Sentinel wins
[X]
Variable targetObject in workspace Main variable workspace
The number of the object that is being targeted in the DrainObjectEnergy routine