.tact1 STA viewingObject \ If we get here then the enemy has turned a tree into a \ meanie and A contains the meanie's object number \ (which we fetched from enemyMeanieTree in part 1), so \ this sets the viewing object to the meanie so the gaze \ checks below are performed from the point of view of \ the meanie LDY enemyTarget,X \ Set Y to the object number in enemyTarget, so when we \ refer to object #Y, it's the meanie's target object LDA objectFlags,Y \ If bit 7 of the object flags for the meanie's target BMI tact4 \ is set then the target doesn't have an associated \ object, so the player must have transferred and \ reabsorbed the original robot that the meanie was \ targeting, so jump to tact4 to restart the enemy's \ drain counter and turn the meanie back into a tree LDA #0 \ Set A = 0 to pass to CheckEnemyGaze as the object type \ of the target (object type 0 being a robot), so we \ only run the gaze calculations when object #Y is a \ robot JSR CheckEnemyGaze \ Call CheckEnemyGaze to check the gaze of the meanie \ towards the robot, returning the following if the \ the object is a robot (an object of type 0): \ \ * objectViewYaw(Hi Lo) = the yaw angle of the robot \ relative to the view (i.e. relative to the \ meanie's view of the world) \ \ * targetVisibility = bit 7 set if the robot's tile \ is visible, bit 6 set if the robot is visible \ \ * treeVisibility = bit 7 set if there is a tree in \ the way of the robot's tile, bit 6 set if there is \ a tree in the way of the robot LDA objectViewYawHi \ If objectViewYawHi >= 20 then the robot is outside of CMP #20 \ the meanie's viewing arc of 20 yaw angles, so jump to BCS tact2 \ tact2 to rotate the meanie in the direction of the \ robot CPY playerObject \ If the robot is not the player object, then the player BNE tact4 \ must have transferred to a different robot, so jump to \ tact4 to restart the enemy's drain counter and turn \ the meanie back into a tree LDA targetVisibility \ If the meanie can't see the robot or the robot's tile BEQ tact5 \ then targetVisibility will be zero, so jump to tact5 \ to turn the meanie back into a tree \ If we get here then the meanie is looking at a robot, \ the robot is within the meanie's viewing arc, the \ robot is the player object and the meanie can either \ see the robot's tile or the robot itself \ \ This means the meanie can see the player, so it can \ force the player into hyperspace JSR PerformHyperspace \ Hyperspace the player to a brand new tile LDA #4 \ Set titleObjectToDraw to the object type for a meanie, STA titleObjectToDraw \ so if the hyperspace fails because the player doesn't \ have enough energy, then the game over screen will \ show a meanie to indicate that it was responsible for \ the player's demise JMP MoveOnToNextEnemy \ Jump to MoveOnToNextEnemy to stop applying tactics to \ this enemy and set things up so we move on to the next \ enemy in the next iteration of the gameplay loop .tact2 LDA #8 \ Set A = 8 to use as the value of meanieYawStep when \ the meanie needs to rotate clockwise towards the \ player BIT objectViewYawHi \ If objectViewYawHi is positive then the player is to BPL tact3 \ the right of the meanie's viewing arc, so jump to \ tact3 to set the yaw step to +8 so the meanie rotates \ right (clockwise( towards the player to the right LDA #&F8 \ Otherwise objectViewYawHi is negative and the player \ is to the left of the meanie's viewing arc, so set A \ to -8 for the yaw step so the meanie rotates left \ (anticlockwise) towards the player to the left .tact3 STA meanieYawStep \ Store the value of A in meanieYawStep, so we can add \ it to the meanie's yaw angle below to make it rotate \ towards the player LDY enemyObject \ Set X to the object number of the meanie that we are LDX enemyMeanieTree,Y \ processing TXA \ Check to see whether it is safe to redraw the meanie 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 objectYawAngle,X \ Add meanieYawStep to the yaw angle for the meanie so CLC \ it rotates towards the player ADC meanieYawStep STA objectYawAngle,X LDA #10 \ Set enemyTacticTimer for the meanie to 10 so we wait STA enemyTacticTimer,Y \ for 10 * 0.06 = 0.6 seconds before applying tactics to \ the meanie again TXA \ Store the enemy object number on the stack so we can PHA \ retrieve it below LDX #3 \ Set X = 3 to pass to MakeSound-6 as the pitch of the \ first part of the rotating meanie sound LDY #70 \ Set Y = 70 to pass to MakeSound-6 as the pitch of the \ second part of the rotating meanie sound LDA #1 \ Make sound #1 (rotating meanie) with the pitches in X JSR MakeSound-6 \ and Y PLA \ Retrieve the enemy object number from the stack into X TAX JMP tact26 \ Jump to tact26 to draw the updated object #X without a \ dithered effect, so the meanie rotates instantly if it \ is on the screen .tact4 LDA #0 \ Set enemyDrainTimer = 0 to restart the drain counter STA enemyDrainTimer,X \ for the enemy in part 5 of ApplyTactics, so it doesn't \ drain energy for another 120 timer ticks (120 * 0.06 = \ 7.2 seconds) .tact5 \ If we get here then we need to turn the meanie back \ into a tree LDY enemyObject \ Set X to the object number of the meanie that we are LDX enemyMeanieTree,Y \ processing TXA \ Check to see whether it is safe to redraw the meanie 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 #%10000000 \ Set bit 7 of enemyMeanieTree so the enemy that turned STA enemyMeanieTree,Y \ a tree into the meanie is no longer flagged as such LDA #2 \ Turn the meanie object back into a tree (an object of STA objectTypes,X \ type 2) JMP tact25 \ Jump to tact25 with X set to the object number of \ the tree to update it on-screen with a dithered effect \ and return from the subroutine using a tail callName: ApplyTactics (Part 2 of 8) [Show more] Type: Subroutine Category: Gameplay Summary: Process the tactics for a meanieContext: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
[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 CheckEnemyGaze (Part 1 of 2) (category: Gameplay)
Check to see whether the current enemy can see a specific target object of a specific type
[X]
Entry point MakeSound-6 in subroutine MakeSound (category: Sound)
Make a two-part sound at the pitches defined in X and Y, where X is the pitch for sound data block #0 and Y is the pitch for sound data block #1
[X]
Subroutine MoveOnToNextEnemy (category: Gameplay)
Update enemyObject so the next time we consider applying enemy tactics, we apply them to the next enemy, looping from 7 to 0
[X]
Subroutine PerformHyperspace (category: Gameplay)
Hyperspace the player to a brand new tile, ideally at the same altitude as the current tile
[X]
Variable enemyDrainTimer in workspace Main variable workspace
A timer for each enemy that counts down every 0.06
[X]
Variable enemyMeanieTree in workspace Main variable workspace
Enemy has turned a tree into a meanie (one byte per
[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 enemyTacticTimer in workspace Main variable workspace
A timer for each enemy that counts down every 0.06
[X]
Variable enemyTarget in workspace Main variable workspace
The object number of the enemy's target (one byte per
[X]
Variable meanieYawStep in workspace Main variable workspace
The yaw angle through which we rotate a meanie as it searches for the player in the ApplyTactics routine
[X]
Variable objectFlags in workspace Stack variables
Object flags for up to 64 objects
[X]
Variable objectTypes (category: 3D objects)
The object types table for up to 64 objects
[X]
Variable objectViewYawHi in workspace Main variable workspace
The yaw angle of the object being analysed, relative to the current viewer (high byte)
[X]
Variable objectYawAngle (category: 3D objects)
The yaw angle for each object (i.e. the horizontal direction in which they are facing)
[X]
Variable playerObject in workspace Zero page
The number of the player object
[X]
Label tact2 is local to this routine
[X]
Entry point tact25 in subroutine ApplyTactics (Part 8 of 8) (category: Gameplay)
Dither the updated object #X onto the screen, with bit 7 of drawLandscape determining whether the object is drawn on its own (bit 7 set) or with the surrounding landscape (bit 7 clear)
[X]
Label tact26 in subroutine ApplyTactics (Part 8 of 8)
[X]
Label tact3 is local to this routine
[X]
Label tact4 is local to this routine
[X]
Label tact5 is local to this routine
[X]
Variable targetVisibility in workspace Zero page
Reports whether a target object is visible from an enemy in the CheckEnemyGaze routine
[X]
Variable titleObjectToDraw in workspace Main variable workspace
The object we are drawing in the DrawTitleView routine
[X]
Variable viewingObject in workspace Zero page
The number of the viewing object