;; Boss Behavior Script
;; By Chronicler Of Legends
;; This script is a control script for all bosses in the game.
;; NOTE: THIS IS A VERY LARGE SCRIPT, IT WILL TAKE UP A LOT OF SPACE.
;;
;; Because they have complex behavior that would take up multiple scripts on its own, we give the bosses
;; their own programming not controlled by the NESMaker GUI.
;; We just do not have enough room for boss behaviors in our 16 ai scripts.
;; This script is designed to be a start to control all of your games bosses. Some modification for specifics
;; will be necessary, but this framework should help.
;; Same script for all the bosses but different behaviors? How do we differentiate between them?
;; Well we need to define boss rooms. Each boss room will have a unique ID.
;; We will check the ID first and jump to the correct label depending on that.
;; Extra info:
;; If we are here, then monster is in x
;; How to trigger a screen: TriggerScreen screenType
bossBehaviorStart:
;; Is the screen triggered? If so the boss is already defeated. Make sure it is gone.
bossScreenNotTriggered:
;; The screen is not triggered, so this is the first time encountering the boss. We need to set it up.
;; Which boss is it? Check the screen type.
bossIsBossOne:
;; First Boss
;; Do we need to setup the boss?
;LDA bossSetup
;CMP #$00
;BEQ bossIsBossOneSetup
;JMP bossIsBossOneBehavior
;bossIsBossOneSetup:
;; Setup variables for this boss.
;LDA #$00
;STA monstersSpawned
bossIsBossOneBehavior:
;; Boss Behaviors
;; Check the bosses action state, and do an action accordingly.
LDA Object_action_step,x ;; Get and store the enemies action state
AND #%00000111
STA temp
;; Point to the correct behaviors
LDA temp
CMP #$0
BEQ bossIsBossOneBehaviorZero
LDA temp
CMP #$1
BEQ bossIsBossOneBehaviorOne
LDA temp
CMP #$2
BEQ bossIsBossOneBehaviorTwo
JMP BossIsBossOneBehaviorUndefined
bossIsBossOneBehaviorZero:
;; Wait a few seconds
JSR bossSRNull
JMP bossCleanup
bossIsBossOneBehaviorOne:
;; Spawn slimes in this state, or shoot if too many slimes created.
JSR bossSRSpawnSlimes
JMP bossCleanup
bossIsBossOneBehaviorTwo:
;; Spawn a slime
JSR bossSRNull
JMP bossCleanup
BossIsBossOneBehaviorUndefined:
;; We shouldn't get here, but if we do, fix it by setting the action state to 0
LDA #$00
STA Object_action_step,x
JMP bossCleanup
bossCleanup:
;; The screen is triggered, make sure to destroy the boss and remove any tiles related to them.
;; Boss Subroutines:
;; We have separated different actions down here to help keep the code clean.
bossSRNull:
;; Dont do anything
RTS
bossSRSpawnSlimes:
;; BASED ON JSHERMAN's SPAWNING CODE! THANKS!
;; Spawns slimes in random positions up to a maximum limit.
LDA monstersSpawned
CMP #ENEMY_MAXSPAWN
BCS bossSRSpawnSlimes_DoNotSpawn
bossSRSpawnSlimes_Spawn:
;; Put our monster in a temp var for safekeeping
TXA
STA tempx
;; Get offset
LDA Object_x_hi,x
CLC
ADC #$04 ;; arbitrary...would put an 8x8 proj in the center of a 16x16 object
STA temp1
CLC
ADC #$04 ;; arbitrary...would put a 8x8 proj in the center of a 16x16 object
LDA Object_y_hi,x
STA temp2
;; Spawn a new monster
INC monstersSpawned
CreateObject temp1, temp2, #ENEMY_SPAWNID_SLIME, #$00, currentNametable
RTS
bossSRSpawnSlimes_DoNotSpawn:
;; Force the boss into the next action state.
;LDA #$02
;STA Object_action_step,x
JSR bossSRShootTowardPlayer
;; Dont spawn any new enemies
LDX tempx
RTS
bossSRSpawnSlimeBarriers:
;; Check if we should spawn the barriers
LDA monstersSpawned
CMP #$03
BEQ bossSRSpawnSlimeBarriers_spawn
RTS
bossSRSpawnSlimeBarriers_spawn:
;CreateObject #$91, #$151, #ENEMY_SPAWNID_BAR1, #$00, currentNametable
;CreateObject #$81, #$91, #ENEMY_SPAWNID_BAR2, #$00, currentNametable
;CreateObject #$151, #$91, #ENEMY_SPAWNID_BAR2, #$00, currentNametable
RTS
bossSRShootTowardPlayer:
;; Boss version of shoot towards player
TXA
STA tempx
;; get offset
LDA Object_x_hi,x
;CLC
;ADC #$04 ;; arbitrary...would put an 8x8 proj in the center of a 16x16 object
STA temp1
LDA Object_y_hi,x
CLC
ADC #$10
STA temp2
LDA Object_scroll,x
STA temp
CreateObject temp1, temp2, #OBJ_MONSTER_PROJECTILE, #$00, temp ;; maybe use a different state for ignore physics?
LDA #$00
STA Object_movement,x
;; we will skip traditional movement
;; and use direct speed instead.
;; will this cause deacceleration?
;; what we need is a bit to "ignore physics engine" which will ignore acc/dec
LDA Object_x_hi,x
sec
sbc xScroll
STA temp
LDA Object_y_hi,x
STA temp2
TXA
STA tempz ;; store the newly created object's x
;; shoot at player one - if there are two players, will we randomize somhow?
LDX player1_object
LDA Object_x_hi,x
sec
sbc xScroll
CLC
ADC #PLR_HCENTEROFFSET
STA temp1
LDA Object_y_hi,x
CLC
ADC #PLR_VCENTEROFFSET
STA temp3
LDX tempz ;; restore newly created projectile object.
JSR MoveTowardsPlayer
LDX tempz
LDA myHvel
STA Object_h_speed_lo,x
LDA #$00
STA Object_h_speed_hi,x
LDA myVvel
STA Object_v_speed_lo,x
LDA #$00
STA Object_v_speed_hi,x
bossSRShootTowardPlayer_gotVAimSpeeds:
LDX tempx
RTS