Easily opened with the latest version of Polished Map (4.5.4 as of writing).
object_event
data is a little misleading -- movement constant has wrong context (e.g. SLOW_STEP_LEFT
is inaccurate)
Hex ID | Movement |
---|---|
$00 | Invisible but interactible object |
$01 | Wander around |
$02 | Look around |
$03 | Wander north and south |
$04 | Wander east and west |
$05 | Facing down |
$06 | Facing up |
$07 | Facing left |
$08 | Facing right |
> $09
, game locks up. SPRITEMOVEDATA_STILL
is missing.
(equivalent constants in pokegold's map_object_constants.asm
)
Sample map for XXX Town
:
INCLUDE "constants.asm"
SECTION "data/maps/objects/XXX.asm", ROMX
map_attributes XXX, XXX, NORTH | WEST | EAST
connection north, PrinceRoute, PRINCE_ROUTE, 0
connection west, Route1P1, ROUTE_1_P1, 0
connection east, RouteSilentEast, ROUTE_SILENT_EAST, 0
XXX_MapEvents::
dw $4000 ; unknown
def_warp_events
warp_event 5, 3, PLAYER_HOUSE_1F, 1, 51
; bg_events are used for signs??
def_bg_events
bg_event 6, 4, 1
def_object_events
object_event 6, 6, SPRITE_SILVER, $03, 6, 6, -1, -1, 0, 0, 0, 0, 0, 0
object_event 13, 13, SPRITE_BLUE, SLOW_STEP_LEFT, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0
XXX_Blocks::
INCBIN "maps/XXX.blk"
Scripting is still done with ASM. It's set up much more like Red/Blue's, only with the addition of which NPCs should be displayed.
Map scripts are usually:
XXX_ScriptLoader:: ; required
ld hl, XXX_Scenes
call RunMapScript
call WriteBackMapScriptNumber
ret
; call then ret's can be replaced with jp
With XXX_Scenes
being:
XXX_Scenes:
; 00
dw XXX_Scene00
dw XXX_Scene00_NPCs
; 01
dw XXX_Scene01
dw XXX_Scene01_NPCs
; 02
dw XXX_Scene02
dw XXX_Scene02_NPCs
; and so on...
XXX_Scene##
contains the ASM script run at every frame for a given script number.
XXX_Scene##_NPCs
contains a $FF
-terminated list of which NPCs to display when a script number is active, which seems to follow the object data order in data/maps/objects/XXX.asm
:
; XXX NPC ID's
const_def
const XXX_OBJECT_SILVER
const XXX_OBJECT_BLUE
XXX_Scene##_NPCs:
db XXX_OBJECT_SILVER
db XXX_OBJECT_BLUE
db -1 ; terminator
Background events like signs can be assigned to XXX_BGEventRoutines
, which GF calls at the end of every individual script:
ld de, XXX_BGEventRoutines
call CallMapTextSubroutine
ret
You may want to do that inside the script loader itself. As for the routines themselves:
XXX_BGEventRoutines:
dw XXX_TheOnlySign
dw XXX_BlankRoutine
; ----- start BG event routines -----
XXX_TheOnlySign:
ld hl, .Text
jp OpenTextbox
.Text:
text "123"
done
XXX_BlankRoutine:
ret
Object events are hooked to XXX_TextPointers
, which are really just miniscripts:
XXX_TextPointers:: ; required
dw XXX_Talk1
dw XXX_Talk2
; ----- start object event routines -----
XXX_Talk1:
ld hl, .Text
jp OpenTextbox
.Text:
text "123"
done
XXX_Talk2:
ld hl, .Text
jp OpenTextbox
.Text:
text "888"
done
Instead of documenting a bunch of ASM I decided to make a bunch of macros. ¯\(ツ)/¯
; check_location <X>, <Y>
; Check if the player is in some specific map location
check_location: macro
ld a, [wYCoord]
cp \2
ret nz
ld a, [wXCoord]
cp \1
ret nz
endm
lock_controls: macro
ld hl, wJoypadFlags
set 7, [hl]
endm
unlock_controls: macro
ld hl, wJoypadFlags
res 7, [hl]
endm
; move_npc <npc_id>, <movement data pointer>
;
; Refer to constants/movement_constants.asm.
;
; $32 = end movement
; $33 = end movement and disappear
;
; NPC ID 0 is the player
move_npc: macro
ld a, \1
ld hl, \2
call LoadMovementDataPointer
endm
; lock_screen_on <npc_id>
;
; After assigning an NPC some movement data,
; this locks script advancement until the
; NPC stops moving.
;
; This command does not actually wait inside
; the script, but is defined at the end of a
; script to tell the game to wait first before
; loading the next script.
;
; As a consequence, unlock_screen *MUST* be the
; first thing in the next script, otherwise the
; game will soft lock!
lock_screen_on: macro
assert \1 > 0, "Player object ($00) cannot be locked"
ld a, \1
call Function17f9
ld hl, wc5ed
set 7, [hl]
ld a, 1
call WriteIntod637
endm
unlock_screen: macro
call Function1848
endm
; set_scene <script number>
set_scene: macro
ld a, \1
ld [wMapScriptNumber], a
endm
; dialog <textbox ptr>
dialog: macro
ld hl, \1
call OpenTextbox
endm
; jump_dialog <textbox ptr>
jump_dialog: macro
ld hl, \1
jp OpenTextbox
endm