more movement stuff

This commit is contained in:
YamaArashi 2015-07-15 13:58:21 -07:00
parent 7b676f5851
commit ac78dda7d8
9 changed files with 192 additions and 137 deletions

View file

@ -188,7 +188,7 @@ UpdateNPCSprite: ; 4ed1 (1:4ed1)
call LoadDEPlusA ; a = [wNPCMovementDirections + $fe] (?)
jr .determineDirection
.randomMovement
call getTileSpriteStandsOn
call GetTileSpriteStandsOn
call Random
.determineDirection
ld b, a
@ -504,7 +504,7 @@ CheckSpriteAvailability: ; 50dc (1:50dc)
.skipXVisibilityTest
; make the sprite invisible if a text box is in front of it
; $5F is the maximum number for map tiles
call getTileSpriteStandsOn
call GetTileSpriteStandsOn
ld d, $60
ld a, [hli]
cp d
@ -685,7 +685,7 @@ CanWalkOntoTile: ; 516e (1:516e)
; calculates the tile pointer pointing to the tile the current sprite stancs on
; this is always the lower left tile of the 2x2 tile blocks all sprites are snapped to
; hl: output pointer
getTileSpriteStandsOn: ; 5207 (1:5207)
GetTileSpriteStandsOn: ; 5207 (1:5207)
ld h, $c1
ld a, [H_CURRENTSPRITEOFFSET]
add $4
@ -724,6 +724,10 @@ LoadDEPlusA: ; 522f (1:522f)
ret
DoScriptedNPCMovement: ; 5236 (1:5236)
; This is an alternative method of scripting an NPC's movement and is only used
; a few times in the game. It is used when the NPC and player must walk together
; in sync, such as when the player is following the NPC somewhere. An NPC can't
; be moved in sync with the player using the other method.
ld a, [wd730]
bit 7, a
ret z
@ -740,28 +744,28 @@ DoScriptedNPCMovement: ; 5236 (1:5236)
.noCarry
ld a, [hl]
; check if moving up
cp $40
cp NPC_MOVEMENT_UP
jr nz, .checkIfMovingDown
call GetSpriteScreenYPointer
ld c, SPRITE_FACING_UP
ld a, -2
jr .move
.checkIfMovingDown
cp $0
cp NPC_MOVEMENT_DOWN
jr nz, .checkIfMovingLeft
call GetSpriteScreenYPointer
ld c, SPRITE_FACING_DOWN
ld a, 2
jr .move
.checkIfMovingLeft
cp $80
cp NPC_MOVEMENT_LEFT
jr nz, .checkIfMovingRight
call GetSpriteScreenXPointer
ld c, SPRITE_FACING_LEFT
ld a, -2
jr .move
.checkIfMovingRight
cp $c0
cp NPC_MOVEMENT_RIGHT
jr nz, .noMatch
call GetSpriteScreenXPointer
ld c, SPRITE_FACING_RIGHT
@ -781,11 +785,11 @@ DoScriptedNPCMovement: ; 5236 (1:5236)
ld a, c
ld [hl], a ; facing direction
call AnimScriptedNPCMovement
ld hl, wcf18
ld hl, wScriptedNPCWalkCounter
dec [hl]
ret nz
ld a, $8
ld [wcf18], a
ld a, 8
ld [wScriptedNPCWalkCounter], a
ld hl, wNPCMovementDirections2Index
inc [hl]
ret
@ -793,8 +797,8 @@ DoScriptedNPCMovement: ; 5236 (1:5236)
InitScriptedNPCMovement: ; 52a6 (1:52a6)
xor a
ld [wNPCMovementDirections2Index], a
ld a, $8
ld [wcf18], a
ld a, 8
ld [wScriptedNPCWalkCounter], a
jp AnimScriptedNPCMovement
GetSpriteScreenYPointer: ; 52b2 (1:52b2)

View file

@ -44,22 +44,25 @@ _EndNPCMovementScript: ; 1a41d (6:641d)
ld [wSimulatedJoypadStatesEnd], a
ret
ProfOakMovementScriptPointerTable: ; 1a442 (6:6442)
dw Func_1a44c
dw Func_1a485
dw Func_1a4a1
dw Func_1a4a6
dw Func_1a4f4
PalletMovementScriptPointerTable: ; 1a442 (6:6442)
dw PalletMovementScript_OakMoveLeft
dw PalletMovementScript_PlayerMoveLeft
dw PalletMovementScript_WaitAndWalkToLab
dw PalletMovementScript_WalkToLab
dw PalletMovementScript_Done
Func_1a44c: ; 1a44c (6:644c)
PalletMovementScript_OakMoveLeft: ; 1a44c (6:644c)
ld a, [W_XCOORD]
sub $a
ld [wcca1], a
jr z, .asm_1a475
ld b, $0
ld [wNumStepsToTake], a
jr z, .playerOnLeftTile
; The player is on the right tile of the northern path out of Pallet Town and
; Prof. Oak is below.
; Make Prof. Oak step to the left.
ld b, 0
ld c, a
ld hl, wNPCMovementDirections2
ld a, $80
ld a, NPC_MOVEMENT_LEFT
call FillMemory
ld [hl], $ff
ld a, [wSpriteIndex]
@ -68,36 +71,39 @@ Func_1a44c: ; 1a44c (6:644c)
call MoveSprite
ld a, $1
ld [wNPCMovementScriptFunctionNum], a
jr .asm_1a47a
.asm_1a475
jr .done
; The player is on the left tile of the northern path out of Pallet Town and
; Prof. Oak is below.
; Prof. Oak is already on the right tile.
.playerOnLeftTile
ld a, $3
ld [wNPCMovementScriptFunctionNum], a
.asm_1a47a
.done
ld hl, W_FLAGS_D733
set 1, [hl]
ld a, $fc
ld [wJoyIgnore], a
ret
Func_1a485: ; 1a485 (6:6485)
PalletMovementScript_PlayerMoveLeft: ; 1a485 (6:6485)
ld a, [wd730]
bit 0, a
ret nz
ld a, [wcca1]
bit 0, a ; is an NPC being moved by a script?
ret nz ; return if Oak is still moving
ld a, [wNumStepsToTake]
ld [wSimulatedJoypadStatesIndex], a
ld [$ff95], a
ld [hNPCMovementDirections2Index], a
predef ConvertNPCMovementDirectionsToJoypadMasks
call StartSimulatingJoypadStates
ld a, $2
ld [wNPCMovementScriptFunctionNum], a
ret
Func_1a4a1: ; 1a4a1 (6:64a1)
PalletMovementScript_WaitAndWalkToLab: ; 1a4a1 (6:64a1)
ld a, [wSimulatedJoypadStatesIndex]
and a
and a ; is the player done moving left yet?
ret nz
Func_1a4a6: ; 1a4a6 (6:64a6)
PalletMovementScript_WalkToLab: ; 1a4a6 (6:64a6)
xor a
ld [wOverrideSimulatedJoypadStatesMask], a
ld a, [wSpriteIndex]
@ -122,12 +128,12 @@ Func_1a4a6: ; 1a4a6 (6:64a6)
ret
RLEList_ProfOakWalkToLab: ; 1a4dc (6:64dc)
db $00, $05
db $80, $01
db $00, $05
db $C0, $03
db $40, $01
db $E0, $01
db NPC_MOVEMENT_DOWN, $05
db NPC_MOVEMENT_LEFT, $01
db NPC_MOVEMENT_DOWN, $05
db NPC_MOVEMENT_RIGHT, $03
db NPC_MOVEMENT_UP, $01
db $E0, $01 ; stand still
db $FF
RLEList_PlayerWalkToLab: ; 1a4e9 (6:64e9)
@ -138,7 +144,7 @@ RLEList_PlayerWalkToLab: ; 1a4e9 (6:64e9)
db D_DOWN, $06
db $FF
Func_1a4f4: ; 1a4f4 (6:64f4)
PalletMovementScript_Done: ; 1a4f4 (6:64f4)
ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
@ -152,10 +158,10 @@ Func_1a4f4: ; 1a4f4 (6:64f4)
jp EndNPCMovementScript
PewterMuseumGuyMovementScriptPointerTable: ; 1a510 (6:6510)
dw Func_1a514
dw PewterMovementScriptDone
dw PewterMovementScript_WalkToMuseum
dw PewterMovementScript_Done
Func_1a514: ; 1a514 (6:6514)
PewterMovementScript_WalkToMuseum: ; 1a514 (6:6514)
ld a, BANK(Music_MuseumGuy)
ld [wc0ef], a
ld [wc0f0], a
@ -191,13 +197,13 @@ RLEList_PewterMuseumPlayer: ; 1a559 (6:6559)
db $FF
RLEList_PewterMuseumGuy: ; 1a562 (6:6562)
db $40, $06
db $80, $0D
db $40, $03
db $80, $01
db NPC_MOVEMENT_UP, $06
db NPC_MOVEMENT_LEFT, $0D
db NPC_MOVEMENT_UP, $03
db NPC_MOVEMENT_LEFT, $01
db $FF
PewterMovementScriptDone: ; 1a56b (6:656b)
PewterMovementScript_Done: ; 1a56b (6:656b)
ld a, [wSimulatedJoypadStatesIndex]
and a
ret nz
@ -208,10 +214,10 @@ PewterMovementScriptDone: ; 1a56b (6:656b)
jp EndNPCMovementScript
PewterGymGuyMovementScriptPointerTable: ; 1a57d (6:657d)
dw Func_1a581
dw PewterMovementScriptDone
dw PewterMovementScript_WalkToGym
dw PewterMovementScript_Done
Func_1a581: ; 1a581 (6:6581)
PewterMovementScript_WalkToGym: ; 1a581 (6:6581)
ld a, BANK(Music_MuseumGuy)
ld [wc0ef], a
ld [wc0f0], a
@ -252,12 +258,12 @@ RLEList_PewterGymPlayer: ; 1a5cd (6:65cd)
db $FF
RLEList_PewterGymGuy: ; 1a5da (6:65da)
db $00, $02
db $80, $0F
db $40, $05
db $80, $0B
db $00, $05
db $C0, $03
db NPC_MOVEMENT_DOWN, $02
db NPC_MOVEMENT_LEFT, $0F
db NPC_MOVEMENT_UP, $05
db NPC_MOVEMENT_LEFT, $0B
db NPC_MOVEMENT_DOWN, $05
db NPC_MOVEMENT_RIGHT, $03
db $FF
FreezeEnemyTrainerSprite: ; 1a5e7 (6:65e7)

View file

@ -16,10 +16,10 @@ PrepareOAMData:
ld [hOAMBufferOffset], a
.spriteLoop
ld [hSpriteDataOffset2], a
ld [hSpriteOffset2], a
ld d, wSpriteStateData1 / $100
ld a, [hSpriteDataOffset2]
ld a, [hSpriteOffset2]
ld e, a
ld a, [de] ; c1x0
and a
@ -139,7 +139,7 @@ PrepareOAMData:
ld [hOAMBufferOffset], a
.nextSprite
ld a, [hSpriteDataOffset2]
ld a, [hSpriteOffset2]
add $10
cp $100 % $100
jp nz, .spriteLoop

View file

@ -2195,7 +2195,7 @@ RunNPCMovementScript:: ; 310e (0:310e)
ld [MBC1RomBank], a
ret
.NPCMovementScriptPointerTables
dw ProfOakMovementScriptPointerTable
dw PalletMovementScriptPointerTable
dw PewterMuseumGuyMovementScriptPointerTable
dw PewterGymGuyMovementScriptPointerTable
.playerStepOutFromDoor
@ -3078,7 +3078,7 @@ MoveSprite_:: ; 363d (0:363d)
ld [wWastedByteCD3A],a
ret
; divides [$ffe5] by [$ffe6] and stores the quotient in [$ffe7]
; divides [hDividend2] by [hDivisor2] and stores the quotient in [hQuotient2]
DivideBytes:: ; 366b (0:366b)
push hl
ld hl, $ffe7

View file

@ -28,7 +28,7 @@ hPartyMonIndex EQU $FF8C
hHalveItemPrices EQU $FF8E
hSpriteDataOffset2 EQU $FF8F
hSpriteOffset2 EQU $FF8F
hOAMBufferOffset EQU $FF90
@ -39,6 +39,11 @@ hTilePlayerStandingOn EQU $FF93
hSpritePriority EQU $FF94
hNPCMovementDirections2Index EQU $FF95
; CalcPositionOfPlayerRelativeToNPC
hNPCSpriteOffset EQU $FF95
; Multiplcation and division variables are meant
; to overlap for back-to-back usage. Big endian.
@ -57,6 +62,33 @@ H_NUMTOPRINT EQU $FF96 ; 3 bytes
H_POWEROFTEN EQU $FF99 ; 3 bytes
H_SAVEDNUMTOPRINT EQU $FF9C ; 3 bytes
; distance in steps between NPC and player
hNPCPlayerYDistance EQU $FF95
hNPCPlayerXDistance EQU $FF96
hFindPathNumSteps EQU $FF97
; bit 0: set when the end of the path's Y coordinate matches the target's
; bit 1: set when the end of the path's X coordinate matches the target's
; When both bits are set, the end of the path is at the target's position
; (i.e. the path has been found).
hFindPathFlags EQU $FF98
hFindPathYProgress EQU $FF99
hFindPathXProgress EQU $FF9A
; 0 = from player to NPC
; 1 = from NPC to player
hNPCPlayerRelativePosPerspective EQU $FF9B
; bit 0:
; 0 = target is to the south or aligned
; 1 = target is to the north
; bit 1:
; 0 = target is to the east or aligned
; 1 = target is to the west
hNPCPlayerRelativePosFlags EQU $FF9D
hSerialReceivedNewData EQU $FFA9
; $01 = using external clock
@ -166,6 +198,10 @@ hTilesetType EQU $FFD7
H_CURRENTSPRITEOFFSET EQU $FFDA ; multiple of $10
hDividend2 EQU $FFE5
hDivisor2 EQU $FFE6
hQuotient2 EQU $FFE7
hSpriteVRAMSlotAndFacing EQU $FFE9
hSpriteAnimFrameCounter EQU $FFEA

117
main.asm
View file

@ -4521,72 +4521,75 @@ IsItemInBag_: ; f8a5 (3:78a5)
FindPathToPlayer: ; f8ba (3:78ba)
xor a
ld hl, $ff97
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
ld hl, hFindPathNumSteps
ld [hli], a ; hFindPathNumSteps
ld [hli], a ; hFindPathFlags
ld [hli], a ; hFindPathYProgress
ld [hl], a ; hFindPathXProgress
ld hl, wNPCMovementDirections2
ld de, $0
.loop
ld a, [$ff99]
ld a, [hFindPathYProgress]
ld b, a
ld a, [$ff95] ; Y distance in steps
ld a, [hNPCPlayerYDistance] ; Y distance in steps
call CalcDifference
ld d, a
and a
jr nz, .asm_f8da
ld a, [$ff98]
set 0, a
ld [$ff98], a
ld a, [hFindPathFlags]
set 0, a ; current end of path matches the player's Y coordinate
ld [hFindPathFlags], a
.asm_f8da
ld a, [$ff9a]
ld a, [hFindPathXProgress]
ld b, a
ld a, [$ff96] ; X distance in steps
ld a, [hNPCPlayerXDistance] ; X distance in steps
call CalcDifference
ld e, a
and a
jr nz, .asm_f8ec
ld a, [$ff98]
set 1, a
ld [$ff98], a
ld a, [hFindPathFlags]
set 1, a ; current end of path matches the player's X coordinate
ld [hFindPathFlags], a
.asm_f8ec
ld a, [$ff98]
cp $3
ld a, [hFindPathFlags]
cp $3 ; has the end of the path reached the player's position?
jr z, .done
; Compare whether the X distance between the player and the current of the path
; is greater or if the Y distance is. Then, try to reduce whichever is greater.
ld a, e
cp d
jr c, .asm_f90a
ld a, [$ff9d]
jr c, .yDistanceGreater
; x distance is greater
ld a, [hNPCPlayerRelativePosFlags]
bit 1, a
jr nz, .asm_f900
jr nz, .playerIsLeftOfNPC
ld d, NPC_MOVEMENT_RIGHT
jr .asm_f902
.asm_f900
jr .next1
.playerIsLeftOfNPC
ld d, NPC_MOVEMENT_LEFT
.asm_f902
ld a, [$ff9a]
add $1
ld [$ff9a], a
jr .asm_f91c
.asm_f90a
ld a, [$ff9d]
.next1
ld a, [hFindPathXProgress]
add 1
ld [hFindPathXProgress], a
jr .storeDirection
.yDistanceGreater
ld a, [hNPCPlayerRelativePosFlags]
bit 0, a
jr nz, .asm_f914
jr nz, .playerIsAboveNPC
ld d, NPC_MOVEMENT_DOWN
jr .asm_f916
.asm_f914
jr .next2
.playerIsAboveNPC
ld d, NPC_MOVEMENT_UP
.asm_f916
ld a, [$ff99]
add $1
ld [$ff99], a
.asm_f91c
.next2
ld a, [hFindPathYProgress]
add 1
ld [hFindPathYProgress], a
.storeDirection
ld a, d
ld [hli], a
ld a, [$ff97]
ld a, [hFindPathNumSteps]
inc a
ld [$ff97], a
ld [hFindPathNumSteps], a
jp .loop
.done
ld [hl], $ff
@ -4594,13 +4597,13 @@ FindPathToPlayer: ; f8ba (3:78ba)
CalcPositionOfPlayerRelativeToNPC: ; f929 (3:7929)
xor a
ld [$ff9d], a
ld [hNPCPlayerRelativePosFlags], a
ld a, [wSpriteStateData1 + 4] ; player's sprite screen Y position in pixels
ld d, a
ld a, [wSpriteStateData1 + 6] ; player's sprite screen X position in pixels
ld e, a
ld hl, wSpriteStateData1
ld a, [$ff95] ; sprite offset
ld a, [hNPCSpriteOffset]
add l
add $4
ld l, a
@ -4614,26 +4617,26 @@ CalcPositionOfPlayerRelativeToNPC: ; f929 (3:7929)
jr nc, .NPCSouthOfOrAlignedWithPlayer
.NPCNorthOfPlayer
push hl
ld hl, $ff9d
ld hl, hNPCPlayerRelativePosFlags
bit 0, [hl]
set 0, [hl]
pop hl
jr .divideYDistance
.NPCSouthOfOrAlignedWithPlayer
push hl
ld hl, $ff9d
ld hl, hNPCPlayerRelativePosFlags
bit 0, [hl]
res 0, [hl]
pop hl
.divideYDistance
push hl
ld hl, $ffe5
ld hl, hDividend2
ld [hli], a
ld a, 16
ld [hli], a
call DivideBytes ; divide Y absolute distance by 16
ld a, [hl] ; quotient
ld [$ff95], a
ld [hNPCPlayerYDistance], a
pop hl
inc hl
ld b, e
@ -4642,35 +4645,35 @@ CalcPositionOfPlayerRelativeToNPC: ; f929 (3:7929)
jr nc, .NPCEastOfOrAlignedWithPlayer
.NPCWestOfPlayer
push hl
ld hl, $ff9d
ld hl, hNPCPlayerRelativePosFlags
bit 1, [hl]
set 1, [hl]
pop hl
jr .divideXDistance
.NPCEastOfOrAlignedWithPlayer
push hl
ld hl, $ff9d
ld hl, hNPCPlayerRelativePosFlags
bit 1, [hl]
res 1, [hl]
pop hl
.divideXDistance
ld [$ffe5], a
ld [hDividend2], a
ld a, 16
ld [$ffe6], a
ld [hDivisor2], a
call DivideBytes ; divide X absolute distance by 16
ld a, [$ffe7] ; quotient
ld [$ff96], a
ld a, [$ff9b]
ld a, [hQuotient2]
ld [hNPCPlayerXDistance], a
ld a, [hNPCPlayerRelativePosPerspective]
and a
ret z
ld a, [$ff9d]
ld a, [hNPCPlayerRelativePosFlags]
cpl
and $3
ld [$ff9d], a
ld [hNPCPlayerRelativePosFlags], a
ret
ConvertNPCMovementDirectionsToJoypadMasks: ; f9a0 (3:79a0)
ld a, [$ff95]
ld a, [hNPCMovementDirections2Index]
ld [wNPCMovementDirections2Index], a
dec a
ld de, wSimulatedJoypadStatesEnd
@ -4684,9 +4687,9 @@ ConvertNPCMovementDirectionsToJoypadMasks: ; f9a0 (3:79a0)
call ConvertNPCMovementDirectionToJoypadMask
ld [de], a
inc de
ld a, [$ff95]
ld a, [hNPCMovementDirections2Index]
dec a
ld [$ff95], a
ld [hNPCMovementDirections2Index], a
jr nz, .loop
ret

View file

@ -333,14 +333,14 @@ OaksLabScript10: ; 1cd6d (7:4d6d)
ld [$ff8c], a
call DisplayTextID
ld a, $1
ld [$ff9b], a
ld [hNPCPlayerRelativePosPerspective], a
ld a, $1
swap a
ld [$ff95], a
ld [hNPCSpriteOffset], a
predef CalcPositionOfPlayerRelativeToNPC
ld a, [$ff95]
ld a, [hNPCPlayerYDistance]
dec a
ld [$ff95], a
ld [hNPCPlayerYDistance], a
predef FindPathToPlayer
ld de, wNPCMovementDirections2
ld a, $1

View file

@ -33,7 +33,7 @@ PalletTownScript0: ; 18e81 (6:4e81)
ld a,$FF
call PlaySound ; stop music
ld a, BANK(Music_MeetProfOak)
ld c,a ; song bank
ld c,a
ld a, MUSIC_MEET_PROF_OAK ; “oak appears” music
call PlayMusic
ld a,$FC
@ -50,7 +50,7 @@ PalletTownScript1: ; 18eb2 (6:4eb2)
xor a
ld [wcf0d],a
ld a,1
ld [$FF8C],a
ld [hSpriteIndexOrTextID],a
call DisplayTextID
ld a,$FF
ld [wJoyIgnore],a
@ -65,25 +65,25 @@ PalletTownScript1: ; 18eb2 (6:4eb2)
PalletTownScript2: ; 18ed2 (6:4ed2)
ld a,1
ld [$FF8C],a
ld a,4
ld [H_SPRITEINDEX],a
ld a,SPRITE_FACING_UP
ld [$FF8D],a
call SetSpriteFacingDirectionAndDelay
call Delay3
ld a,1
ld [W_YCOORD],a
ld a,1
ld [$FF9B],a
ld [hNPCPlayerRelativePosPerspective],a
ld a,1
swap a
ld [$FF95],a
ld [hNPCSpriteOffset],a
predef CalcPositionOfPlayerRelativeToNPC
ld hl,$FF95
ld hl,hNPCPlayerYDistance
dec [hl]
predef FindPathToPlayer ; load Oaks movement into wNPCMovementDirections2
ld de,wNPCMovementDirections2
ld a,1 ; oak
ld [$FF8C],a
ld [H_SPRITEINDEX],a
call MoveSprite
ld a,$FF
ld [wJoyIgnore],a
@ -104,8 +104,9 @@ PalletTownScript3: ; 18f12 (6:4f12)
ld a,$FC
ld [wJoyIgnore],a
ld a,1
ld [$FF8C],a
ld [hSpriteIndexOrTextID],a
call DisplayTextID
; set up movement script that causes the player to follow Oak to his lab
ld a,$FF
ld [wJoyIgnore],a
ld a,1
@ -124,7 +125,7 @@ PalletTownScript3: ; 18f12 (6:4f12)
PalletTownScript4: ; 18f4b (6:4f4b)
ld a,[wNPCMovementScriptPointerTableNum]
and a
and a ; is the movement script over?
ret nz
; trigger the next script

View file

@ -390,7 +390,9 @@ wSwitchPartyMonTempBuffer:: ; cc97
; temporary buffer when swapping party mon data
ds 10
wcca1:: ds 49 ; used in overworld npc movement
wNumStepsToTake:: ; cca1
; used in Pallet Town scripted movement
ds 49
wRLEByteCount:: ; ccd2
ds 1
@ -988,7 +990,10 @@ wNPCMovementScriptSpriteOffset:: ; cf17
; sprite offset of sprite being controlled by NPC movement script
ds 1
wcf18:: ds 2 ; used with overworld movement
wScriptedNPCWalkCounter:: ; cf18
ds 1
ds 1
wGBC:: ; cf1a
ds 1