[SOLVED] [4.5.9] Is there a way to bring back ChangeAllTiles?

pigeonaut

Member
Hello!

In 4.1.x there was a macro script called: "ChangeAllTiles" where it would find all tiles of a certain type and then change all those tiles to a different type of tile. It would also let you change the tile graphic as well.

I was wondering if any of you were able to adapt this script to work in version 4.5.x?

I would like my player to press a button and have all of the solid tiles turn to null.

(I have attached the old 4.1 ChangeAllTiles script)

Thanks!
 

Attachments

  • ChangeAllTiles.txt
    1.4 KB · Views: 14
Last edited:

kastar

New member
ChangeTileAtCollision is somewhat similar. I've been working on something similar and it looks pretty do-able to retrofit the old ChangeAllTiles macro using the ChangeTileAtCollision macro.
 

kastar

New member
FYI, I tried that and you'd need to adjust some of the labels to make it match up with some of the changes between 4.1.5 and 4.5.*. That's where you could use ChangeTileAtCollision for inspiration.
 

pigeonaut

Member
ChangeTileAtCollision is somewhat similar. I've been working on something similar and it looks pretty do-able to retrofit the old ChangeAllTiles macro using the ChangeTileAtCollision macro.
Couldn't you just add the ChangeAllTiles macro to the game and it will work?
FYI, I tried that and you'd need to adjust some of the labels to make it match up with some of the changes between 4.1.5 and 4.5.*. That's where you could use ChangeTileAtCollision for inspiration.
Thanks for looking into this! Do you think it just needs a simple label change? I'll try that today and see if it works.
 

pigeonaut

Member
Alright figured it out!!! I essentially copied the code from the "doHandleObjectCollisions_AdventureBase" script where it handles removing the "monster blocks".

Here is the macro that will let you replace all tiles of a certain type depending on what parameters you put in:
Code:
MACRO change_all_tiles arg0, arg1, arg2

    ; arg0 = the tile type that you want to replace
    ; arg1 = metatile to change into (graphic)
    ; arg2 = collision to change into (tile type)
    
    
    TILE_TO_REPLACE = arg0 ; the number collision type of your monster block.
                LDX #$00
                doReplaceTile:
                    LDA currentNametable
                        AND #%00000001
                        BEQ +isEvenCt
                            LDA #$24
                            STA temp1 ;; high byte of thing
                            ;;; is odd col table.
                            LDA collisionTable2,x
                            CMP #TILE_TO_REPLACE
                            BEQ +isTileToReplace
                                JMP +notTileToReplace
                            +isTileToReplace
                                ;; is tile_to_replace table.
                                LDA arg2
                                STA collisionTable2,x
                                
                                JSR getTileToChange_forTileToReplace

                                JMP +doneWithTileUpdate
                        +isEvenCt
                            LDA #$20
                            STA temp1 ;; high byte of thing.
                            ;;; is odd col table.
                            LDA collisionTable,x
                            CMP #TILE_TO_REPLACE
                            BEQ +isTileToReplace
                                JMP +notTileToReplace
                            +isTileToReplace
                                ;; is tile_to_replace table.
                                LDA arg2
                                STA collisionTable,x
                                JSR getTileToChange_forTileToReplace
        
                                JMP +doneWithTileUpdate
                                
                                
                                
                            getTileToChange_forTileToReplace:

                                TXA
                                STA temp
                                LSR
                                LSR
                                LSR
                                LSR
                                LSR
                                LSR
                                clc
                                ADC temp1
                                STA temp2 ;;;temp16+1
                                TXA
                                AND #%11110000
                                ASL
                                ASL
                                STA tempz
                                TXA
                                AND #%00001111
                                ASL
                                ORA tempz
                                STA temp3 ;temp16
                                
                                
                                ;;; SET THE TILE NUMBER TO CHANGE TO.   
                                LDA arg1 ;;arg1 ;; the tile to change.
                                        ;;; this is in tiles, so if you wanted the second "metatile",
                                        ;;; use 2, not 1.  If you wanted the tile in the next row,
                                        ;;; use #$20, not #$10.  Etc.
                                STA tempA
                                CLC
                                ADC #$01
                                STA tempB
                                CLC
                                ADC #$0F
                                STA tempC
                                CLC
                                ADC #$01
                                STA tempD
                                
                                
                                LDY #$00
                                    LDA temp2
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA temp3
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA tempA
                                    STA scrollUpdateRam,y
                                    INY
                                    
                                    LDA temp2
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA temp3
                                    CLC
                                    ADC #$01
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA tempB
                                    STA scrollUpdateRam,y
                                    INY
                                    
                                        LDA temp3
                                        CLC
                                        ADC #$20
                                        STA temp3
                                        LDA temp2
                                        ADC #$00
                                        STA temp2
                                    
                                    LDA temp2
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA temp3
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA tempC
                                    STA scrollUpdateRam,y
                                    INY
                                    
                                    LDA temp2
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA temp3
                                    CLC
                                    ADC #$01
                                    STA scrollUpdateRam,y
                                    INY
                                    LDA tempD
                                    STA scrollUpdateRam,y
                                    INY
                                
                                TYA
                                STA maxScrollOffsetCounter
    
            
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Turn on update screen on next frame.
        LDA updateScreenData
        ORA #%0000100
        STA updateScreenData
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RTS
+doneWithTileUpdate
    
                        
                        JSR doWaitFrame
                        
+notTileToReplace
                    INX
                    CPX #240
                    BEQ +skip ;; done
                        PlaySound #sfx_powerup
                        ;;loop back !
                        JMP doReplaceTile ;; last tile_to_replace.
    
    +skip
    
    ENDM

To test:
- Add this new macro into your \GameEngineData\Routines\BASE_4_5\System\Macros\ folder (make sure the file name matches the macro name)
- Then make a new input script and assign it to your A button:

Code:
change_all_tiles #$02, #$00, #$01

- On your screen add some tiles of type #$02 , give those tiles a nice graphic
- Then when you run your game and hit A button, every tile on the screen, of type #$02 should turn into graphic #$00 (the first tile in your tile-sheet) and will turn into a solid tile.

Let me know if there are any issues or questions. Hope this helps!
 

Bucket Mouse

Active member
@pigeonaut
The ChangeAllTiles macro doesn't work as a tile.

It makes the lock tile disappear, but the entire screen freezes afterward.

It looks like the conflict is between the tile and the sprite. To get around it I have to create a new variable, add 1 to it when the sprite touches the tile, and then put a check before it to look at the variable. Otherwise it will keep changing the tile infinitely.
 
Last edited:

pigeonaut

Member
@pigeonaut
The ChangeAllTiles macro doesn't work as a tile.

It makes the lock tile disappear, but the entire screen freezes afterward.

It looks like the conflict is between the tile and the sprite. To get around it I have to create a new variable, add 1 to it when the sprite touches the tile, and then put a check before it to look at the variable. Otherwise it will keep changing the tile infinitely.
Thanks for the tip!!! That makes a lot of sense.
 

chains

Member
Here's my contribution to this thread if you want to change a particular set of tiles and don't want to loop through the whole nametable:

Code:
;;; door tile

    LDA updateScreenData
    AND #%00000100
    BEQ +doScript
        RTS
    +doScript
    LDA scrollOffsetCounter
    BEQ +doIt
        RTS
    +doIt   
CPX player1_object
BEQ +isPlayer
    JMP +notPlayer
    +isPlayer

    LDA myKeys
    CMP #$01
    BEQ +hasKeys
        ;; drop the keys
        LDA #$00
        STA myKeys
        JMP +notPlayer
    ;; this is how ChangeTileAtCollision reads these vars
    ;; temp1 -> tile
    ;; temp2 -> nametable
    +hasKeys:
        ;; save the current tile
        LDA temp1
        STA tempx
        ;; removes this tile, we don't need to check this tile anymore
        ChangeTileAtCollision #$00, #$00

        JSR doWaitFrame ;; update the nametable

        ;; open the door
        DOOR_OPEN_TILE1 = #$AA
        DOOR_OPEN_TILE2 = #$AC

        LDA tempx
        SEC
        SBC #$02
        STA temp1
        STA tempx

        ChangeTileAtCollision #DOOR_OPEN_TILE1, #$00

        JSR doWaitFrame

        LDA tempx
        CLC
        ADC #$01
        STA temp1

        ChangeTileAtCollision #DOOR_OPEN_TILE2, #$00


    +notPlayer

Add this script to a specific tile, then when you collide with it, it will change the two adjacent tiles to something else. In my case, I'm erasing the current tile to avoid the engine making the check again. Since I've already opened the door, there's no reason to keep checking it all the time.
 

nesker

New member
for anyone using the change_all_tiles marco and noticing sudden crashes, at the start of the macro add:

Code:
TXA 
PHA 
TYA 
PHA

and at the very end of the macro add

Code:
PLA 
TAY 
PLA 
TAX

The reason for this is if you are calling this macro when you are already running a loop using the x or y registry, this macro overrides it. by temporarily storing the x and y registry, you can call it back again at the end of the macro and continue on your way

edit: updated thanks to a suggestion by ClutterCross
 
Last edited:
Top Bottom