JamesNES
Well-known member
This is a pretty simple one I just had to write. I wanted to make a town but most of the collisions that you'd need in a dungeon just don't apply, so those are wasted. I figured if you swap out all your normal collision scripts for town-specific collisions, it'd be easier to make multiple warps on a single screen. Eg one goes to an inn, one goes to a house, etc. There are other ways to do that but this is by far the simplest. I've tested this in the adventure module, but I don't see why it wouldn't work for anything else (famous last words).
This uses a screen flag to tell when you're on a town screen, and then just redirects the tile collision script to use different scripts.
I'm using the third screen flag to tell the game to use the different collision set:
The only file we need to change in this is Bank18.asm.
By default, at line 52 (66 in adventure module) you'll see:
This gets changed to:
Then at the very bottom of the file you can add the references to your new tile scripts:
Each include will have to point to where you've put your new scripts. If you don't need to use all 16 you can just delete the .include line.
You can also mix and match with your normal tile types, like:
To have #$01 still be the same solid tile script you'd normally use.
Downsides are that there's an extra LDA, AND and BEQ for every object on screen. I did do a workaround so it's only once per frame, but you'd need to use 4 zero page bytes that aren't affected by the object subroutine. So I went for simplicity.
This uses a screen flag to tell when you're on a town screen, and then just redirects the tile collision script to use different scripts.
I'm using the third screen flag to tell the game to use the different collision set:
The only file we need to change in this is Bank18.asm.
By default, at line 52 (66 in adventure module) you'll see:
Code:
LDY temp
LDA TileTableLo,y
STA temp16
LDA TileTableHi,y
STA temp16+1
This gets changed to:
Code:
LDY temp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Multiple Tile Script Starts Here ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LDA ScreenFlags00
AND #%00100000
BEQ +notTownTiles
LDA TownTileTableLo,y
STA temp16
LDA TownTileTableHi,y
STA temp16+1
JMP +gotTileAddress
+notTownTiles
;;Use default tile types
LDA TileTableLo,y
STA temp16
LDA TileTableHi,y
STA temp16+1
+gotTileAddress
;;Ends here
Then at the very bottom of the file you can add the references to your new tile scripts:
Code:
TownTileTableLo:
.db <TownTile_00, <TownTile_01, <TownTile_02, <TownTile_03, <TownTile_04, <TownTile_05, <TownTile_06, <TownTile_07
.db <TownTile_08, <TownTile_09, <TownTile_10, <TownTile_11, <TownTile_12, <TownTile_13, <TownTile_14, <TownTile_15
TownTileTableHi:
.db >TownTile_00, >TownTile_01, >TownTile_02, >TownTile_03, >TownTile_04, >TownTile_05, >TownTile_06, >TownTile_07
.db >TownTile_08, >TownTile_09, >TownTile_10, >TownTile_11, >TownTile_12, >TownTile_13, >TownTile_14, >TownTile_15
TownTile_00:
RTS
TownTile_01:
.include ROOT\Game\TownTiles\TownTile01.asm
RTS
TownTile_02:
.include ROOT\Game\TownTiles\TownTile02.asm
RTS
TownTile_03:
.include ROOT\Game\TownTiles\TownTile03.asm
RTS
TownTile_04:
.include ROOT\Game\TownTiles\TownTile04.asm
RTS
TownTile_05:
.include ROOT\Game\TownTiles\TownTile05.asm
RTS
TownTile_06:
.include ROOT\Game\TownTiles\TownTile06.asm
RTS
TownTile_07:
.include ROOT\Game\TownTiles\TownTile07.asm
RTS
TownTile_08:
.include ROOT\Game\TownTiles\TownTile08.asm
RTS
TownTile_09:
.include ROOT\Game\TownTiles\TownTile09.asm
RTS
TownTile_10:
.include ROOT\Game\TownTiles\TownTile10.asm
RTS
TownTile_11:
.include ROOT\Game\TownTiles\TownTile11.asm
RTS
TownTile_12:
.include ROOT\Game\TownTiles\TownTile12.asm
RTS
TownTile_13:
.include ROOT\Game\TownTiles\TownTile13.asm
RTS
TownTile_14:
.include ROOT\Game\TownTiles\TownTile14.asm
RTS
TownTile_15:
.include ROOT\Game\TownTiles\TownTile15.asm
RTS
Each include will have to point to where you've put your new scripts. If you don't need to use all 16 you can just delete the .include line.
You can also mix and match with your normal tile types, like:
Code:
TownTileTableLo:
.db <TownTile_00, <Tile_01, <TownTile_02, <TownTile_03, <TownTile_04, <TownTile_05, <TownTile_06, <TownTile_07
.db <TownTile_08, <TownTile_09, <TownTile_10, <TownTile_11, <TownTile_12, <TownTile_13, <TownTile_14, <TownTile_15
TownTileTableHi:
.db >TownTile_00, >Tile_01, >TownTile_02, >TownTile_03, >TownTile_04, >TownTile_05, >TownTile_06, >TownTile_07
.db >TownTile_08, >TownTile_09, >TownTile_10, >TownTile_11, >TownTile_12, >TownTile_13, >TownTile_14, >TownTile_15
To have #$01 still be the same solid tile script you'd normally use.
Downsides are that there's an extra LDA, AND and BEQ for every object on screen. I did do a workaround so it's only once per frame, but you'd need to use 4 zero page bytes that aren't affected by the object subroutine. So I went for simplicity.