4.5.9 [SOLVED] Timer End Scripts Won't Trigger Anymore (formerly titled Monsters Won't Shoot)

puppydrum64

Active member
So I re-built my shooter game, most of the scripts are tweaked slightly but other than overhauling the draw sprites subroutine using the RTS trick and the method in the advanced tutorial, not too much has changed. I did remove the draw hud portions of the subroutines since this game uses a sprite hud and those sections seemed to do nothing anyway. But now my monsters won't shoot. They are programmed exactly as they are in the intermediate tutorial but they never fire any bullets. I set a break point for when the "Shoot At Player" action is triggered but it never reaches that part of the code. Both player characters can shoot no problem so it doesn't have anything to do with the change in the draw sprite routine. What's going on? I know asking a question like this will probably get me nowhere so I'll just include my demo.txt as a pastebin. Since it's so large I'll leave out anything that doesn't have to do with the game logic (such as sound, text, and other things that don't matter.)

EDIT: See the post below. This seems to affect all my games and not just the one I'm working on right now, which suggests a problem with the original scripts that I must have inadvertently created.

EDIT 2: I figured out what I did wrong. In the reply to this post I had said the following:
I would like to point out that at some point I had actually removed one of the .include statements for one of these in bank 1C but I have since changed it back, and I think after that I had the problem of them not loading. Even though they should by now.

In my attempt to fix this, I had followed the error messages when compiling to the Update Action Timer script. I saw the following code:

Code:
LDA EndAnimAndActions_Lo,y
            STA temp16
            LDA EndAnimAndActions_Hi,y
            STA temp16+1
        
            JSR doEndActionTrampoline
                 JMP pastEndActionTrampoline
                 doEndActionTrampoline:
                     JMP (temp16)
                    ; ;;; make sure that the behavior ends in an RTS, and then it will 
                    ; ;;; slide right back to this part of the code.
                 pastEndActionTrampoline:

Not knowing what EndAnimAndActions were, I had added them as variables into my project just to get the code to run. Which caused the game to compile correctly but it crashed immediately. I went back and commented out everything in the section starting with "JSR doEndActionTrampoline" and it worked. I thought "Well my game doesn't use trampolines for the player to jump on so I don't need this" when it was actually referring to the JMP statement being a "trampoline" to the next part of code.

Moral of the story: Don't modify the scripts that come with NESmaker (unless it's for fixing a bug that came with them). Always save a copy and edit the copy!

demo.txt - Pastebin.com
 
Last edited:

puppydrum64

Active member
Just to raise this back up to the top and update with some new findings. I think I've almost found the source of my predicament. The error appears to be these scripts that do not get called anymore for some reason: doObjectAction and TimerEndScripts. Here are my versions of them for reference. I don't recall changing them in any way. I would like to point out that at some point I had actually removed one of the .include statements for one of these in bank 1C but I have since changed it back, and I think after that I had the problem of them not loading. Even though they should by now.

Do Object Action
Code:
doObjectAction:
    TXA
    PHA
    TYA
    PHA

        LDX arg0_hold
        LDY Object_type,x
        LDA ObjectBehaviorTableLo,y
        STA temp16
        LDA ObjectBehaviorTableHi,y
        STA temp16+1
        LDY arg1_hold
        LDA (temp16),y

            ;;; this now holds the action type id and the action timer.
            ;;; xxxxxyyy: x=action timer, y=action type, 0-7.
            STA temp
            AND #%00001111
            STA tempA ;; use this to "do" the action.
            
            
            LDA temp
            ;;; RIGHT HERE, assing the timer.
            LSR
            LSR
            LSR
            LSR
            BNE notZeroForActionTimer ;;    
                ;; set to a random number if zero
                JSR doGetRandomNumber
                AND #%00111111 ; 0-127 for a timer.
                ASL
                JMP gotNewActionTimer
            notZeroForActionTimer:
                ASL
                ASL
                ASL
                ASL
            gotNewActionTimer:
                STA Object_action_timer,x
                
            ;;;;;;;;;;;;;;;;;;;;;;; 
            ;;; RESET ANIMATION TIMER
            ;;;;;;;;;;;;;;;;;;;;;;;;;
            LDY Object_type,x
            LDA ObjectAnimationSpeedTableLo,y
            STA temp16
            LDA ObjectAnimationSpeedTableHi,y
            STA temp16+1
            
            LDA Object_frame,x
            LSR
            LSR
            LSR
            AND #%00000111
            TAY
            
            LDA (temp16),y ;; this now points to the proper spot on the anim speed table.
                            ;; we need to capture that number.
                            ;; Its high nibble is the "animation type"
            AND #%00001111
            ;;                Now we have a value 0-16.
            ;;                 This correlates to animation speed, but it probably shouldn't be a one-to-one comparision.
            ASL
            ASL
            STA Object_animation_timer,x
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                
            LDA Object_frame,x
            AND #%11111000
            STA Object_frame,x ;; reset animation frame.
            
        
            LDY tempA
    
            LDA AI_table_lo,y
            STA temp16
            LDA AI_table_hi,y
            STA temp16+1
        
            JSR doObjectActionTrampoline
                 JMP pastObjectActionTrampoline
                 doObjectActionTrampoline:
                    JMP (temp16)
                    ; ;;; make sure that the behavior ends in an RTS, and then it will 
                    ; ;;; slide right back to this part of the code.
                 pastObjectActionTrampoline:
        ;;; Set this step's vulnerabilities.
            LDY Object_type,x
            LDA VulnerabilityTableLo,y
            STA temp16
            LDA VulnerabilityTableHi,y
            STA temp16+1
            LDA Object_frame,x
            LSR
            LSR
            LSR
            AND #%00000111
            TAY
            LDA (temp16),y
            STA Object_vulnerability,x
              
    
    PLA
    TAY
    PLA
    TAX
    RTS


Timer End Scripts


Code:
;;; 00 = Loop
end_loop_action:

    RTS
;;; 01 = Advance
advance_action:
        LDA Object_frame,x
        LSR
        LSR
        LSR
        AND #%00000111
        CLC
        ADC #$01
        AND #%00000111
        STA tempB
        ;STA tempD ;; the action frame that was assigned during create macro.
        ;;;; object behavior tables are with the lut table.
        ;;;; the lut table is in bank 1C.
        ; SwitchBank #$1C
            ; ;;; Then, get the behavior for that object on that frame number.
            ; LDY Object_type,x
            ; LDA ObjectBehaviorTableLo,y
            ; STA pointer
            ; LDA ObjectBehaviorTableHi,y
            ; STA pointer+1
            ; LDY tempD
            ; LDA (pointer),y
            ; AND #%00001111
            ; STA tempB
        ; ReturnBank
        LDA tempB
        ASL
        ASL
        ASL
        STA tempC
        LDA Object_frame,x
        AND #%11000111
        ORA tempC
        STA Object_frame,x

        TXA 
        STA tempA
        
        DoObjectAction tempA, tempB
    ;    ;arg0 = what object?
        ;arg1 = what step behavior?
    RTS
;;; 02 = Repeat
repeat_action:
    LDA Object_frame,x
        LSR
        LSR
        LSR
        AND #%00000111
        STA tempB
    
        TXA 
        STA tempA

        DoObjectAction tempA, tempB
    ;    ;arg0 = what object?
        ;arg1 = what step behavior?
    RTS
;;; 03 = Go To First
goToFirst_action:

            LDA #$00
            STA tempB
        ;;;; HURT END
        LDA Object_frame,x
        AND #%00111000
        CMP #%00111000
        BNE +notHurtFrame
            LDA #$00
            STA Object_h_speed_hi,x
            STA Object_h_speed_lo,x
            STA Object_v_speed_hi,x
            STA Object_v_speed_lo,x
            LDA Object_direction,x
            AND #%00001111
            STA Object_direction,x
        ;;;;;;;;;;;;;;;;;;;;
        +notHurtFrame
        
        LDA Object_frame,x
        AND #%11000111
        STA Object_frame,x
        
    
        TXA 
        STA tempA
        
        DoObjectAction tempA, tempB
    ;    ;arg0 = what object?
        ;arg1 = what step behavior?
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
         ;; turn off move towards point if current action is 7.
        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    RTS
;;; 04 = Go To Last
goToLast_action:
            LDA #$07
            STA tempB
    
        
        LDA Object_frame,x
        ora #%00111000
        STA Object_frame,x
        
        TXA 
        STA tempA
        
        DoObjectAction tempA, tempB
    ;    ;arg0 = what object?
        ;arg1 = what step behavior?
    RTS
;;; 05 = Go To Previous
goToPrev_action:
        LDA Object_frame,x
    LDA Object_frame,x
        LSR
        LSR
        LSR
        AND #%00000111
        SEC
        SBC #$01
        AND #%00000111
        STA tempB ;; the action frame that was assigned during create macro.
        ;;;; object behavior tables are with the lut table.
        ;;;; the lut table is in bank 1C.
        ASL
        ASL
        ASL
        STA tempC
        LDA Object_frame,x
        AND #%11000111
        ORA tempC
        STA Object_frame,x
        
        TXA 
        STA tempA
        
        DoObjectAction tempA, tempB
    ;    ;arg0 = what object?
        ;arg1 = what step behavior?
    RTS
;;; 06 = Destroy Me
destroyMe_action:
    DestroyObject
    RTS
;;; 07 = Go To Warp
goToWarp_action:
    WarpToScreen warpToMap, warpToScreen, #$01
    RTS
;;; 08 = Show Message (1)
show_message_action

    RTS
;;; 09 = Go To Continue
goToContinue_action:
    LDA continueMap
    STA warpMap
    
    LDA continueScreen
    STA currentNametable
    
    LDX player1_object
    STA Object_screen,x
    
    LDA #$02 ;; this is continue type warp.
    STA screenTransitionType ;; is of warp type

    
    LDA gameHandler
    ORA #%10000000
    STA gameHandler ;; this will set the next game loop to update the screen.
    ChangeActionStep player1_object, #$00
    LDX player1_object
    LDA #$00000000
    STA Object_direction,x
    RTS
;;; 10 = Restart Screen
restartScreen_action:
    LDA #$02
    STA screenTransitionType
    LDA gameHandler
    ORA #%10000000
    STA gameHandler ;; this will set the next game loop to update the screen.
    ChangeActionStep player1_object, #$00
    LDX player1_object
    LDA #$00000000
    STA Object_direction,x
    RTS
;;; 11 = Restart Game
restartGame_action:
    JMP RESET
    RTS
;;; 12 = User 0
userEnd0_action:
    RTS
;;; 13 = User 1
userEnd1_action:
    RTS

    
EndAnimAndActions_Lo:
    .db #<end_loop_action, #<advance_action, #<repeat_action, #<goToFirst_action, #<goToLast_action, #<goToPrev_action, #<destroyMe_action, #<goToWarp_action
    .db #<show_message_action, #<goToContinue_action, #<restartScreen_action, #<restartGame_action, #<userEnd0_action, #<userEnd1_action
    
EndAnimAndActions_Hi:
    .db #>end_loop_action, #>advance_action, #>repeat_action, #>goToFirst_action, #>goToLast_action, #>goToPrev_action, #>destroyMe_action, #>goToWarp_action
    .db #>show_message_action, #>goToContinue_action, #>restartScreen_action, #>restartGame_action, #>userEnd0_action, #>userEnd1_action
 
Top Bottom