You've already forked pokecrystal-board
mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2025-12-11 05:02:16 -08:00
Multiplayer engine: player objects (re)positioning logic [Commit 6] (#40)
This commit is contained in:
@@ -57,4 +57,5 @@ MapSetupCommands:
|
||||
add_mapsetup BackupMapObjects ; 32
|
||||
add_mapsetup LoadDisabledSpaces ; 33
|
||||
add_mapsetup MapCallbackAtEndMapSetup ; 34
|
||||
add_mapsetup RepositionMockedPlayerObject ; 35
|
||||
add_mapsetup RepositionMockedPlayerObjects_Connection ; 35
|
||||
add_mapsetup RepositionMockedPlayerObjects_NextPlayer ; 36
|
||||
|
||||
@@ -93,7 +93,7 @@ MapSetupScript_Connection:
|
||||
mapsetup RefreshPlayerCoords
|
||||
mapsetup LoadBlockData
|
||||
mapsetup LoadDisabledSpaces
|
||||
mapsetup RepositionMockedPlayerObject
|
||||
mapsetup RepositionMockedPlayerObjects_Connection
|
||||
mapsetup LoadMapTileset
|
||||
mapsetup SaveScreen
|
||||
mapsetup LoadMapObjects
|
||||
@@ -149,6 +149,7 @@ MapSetupScript_NextPlayer:
|
||||
mapsetup GetMapScreenCoords
|
||||
mapsetup LoadBlockData
|
||||
mapsetup LoadDisabledSpaces
|
||||
mapsetup RepositionMockedPlayerObjects_NextPlayer
|
||||
mapsetup BufferScreen
|
||||
mapsetup LoadMapGraphics
|
||||
mapsetup LoadMapTimeOfDay
|
||||
|
||||
@@ -248,7 +248,7 @@ The backing up of disabled spaces to WRAM is done individually per space the mom
|
||||
|
||||
When a map is entered during a level, if the map has been visited before during the current level, there will be backup disabled space and map object data for it. Its existence is looked up in *wDisabledSpacesBackups* and *wMapObjectsBackups* by searching for an entry matching the map group and map id of the map being entered (*LoadDisabledSpaces* map setup command and an extension to *CopyMapObjectEvents* all the way from the *LoadMapAttributes* map setup command).
|
||||
|
||||
Regarding map connections, note that, while a mocked player sprite during view map mode remains visible when crossing a connection by "respawning" it in the destination map (see *RepositionMockedPlayerObject*), the "respawning" of other map objects across map connections isn't supported. If you for example put an NPC too close to a map connection, it will disappear from the screen when crossing the connection, just like in Pokemon Crystal.
|
||||
Regarding map connections, note that, while a mocked player sprite during view map mode remains visible when crossing a connection by "respawning" it in the destination map (see *RepositionMockedPlayerObjects_Connection*), the "respawning" of other map objects across map connections isn't supported. If you for example put an NPC too close to a map connection, it will disappear from the screen when crossing the connection, just like in Pokemon Crystal.
|
||||
|
||||
# Game navigation and progression
|
||||
|
||||
|
||||
@@ -854,26 +854,60 @@ QueueFollowerFirstStep:
|
||||
scf
|
||||
ret
|
||||
|
||||
PositionAllPlayerObjectsExceptCurrent:
|
||||
; called by MAPSETUP_NEXTPLAYER
|
||||
; calls RepositionMockedPlayerObject for each player according to wNumLevelPlayers,
|
||||
; except for the player at wCurTurnPlayer.
|
||||
ret
|
||||
RepositionMockedPlayerObjects_NextPlayer:
|
||||
; map setup command called by MAPSETUP_NEXTPLAYER after LoadBlockData,
|
||||
; once the new map blocks have been loaded to wOverworldMapBlocks.
|
||||
; position all players according to wNumLevelPlayers, except for the player at wCurTurnPlayer (which isn't being mocked).
|
||||
ld a, [wNumLevelPlayers]
|
||||
maskbits MAX_PLAYERS
|
||||
cp 1
|
||||
ret z ; return if single player mode
|
||||
.loop
|
||||
dec a
|
||||
cp -1
|
||||
ret z
|
||||
ld hl, wCurTurnPlayer
|
||||
cp [hl]
|
||||
jr z, .loop
|
||||
ld [wMockingWhichPlayer], a
|
||||
push af
|
||||
call RepositionMockedPlayerObject
|
||||
pop af
|
||||
jr .loop
|
||||
|
||||
RepositionMockedPlayerObject::
|
||||
RepositionMockedPlayerObjects_Connection::
|
||||
; map setup command called by map setup script MAPSETUP_CONNECTION after LoadBlockData,
|
||||
; once the new map blocks have been loaded to wOverworldMapBlocks.
|
||||
; Only applies during BOARDEVENT_VIEW_MAP_MODE
|
||||
; During BOARDEVENT_VIEW_MAP_MODE:
|
||||
; position all players according to wNumLevelPlayers.
|
||||
; Otherwise:
|
||||
; position all players according to wNumLevelPlayers, except for the player at wCurTurnPlayer (which isn't being mocked).
|
||||
; this mode is the same as RepositionMockedPlayerObjects_NextPlayer
|
||||
ldh a, [hCurBoardEvent]
|
||||
cp BOARDEVENT_VIEW_MAP_MODE
|
||||
ret nz
|
||||
jr nz, RepositionMockedPlayerObjects_NextPlayer
|
||||
ld a, [wNumLevelPlayers]
|
||||
maskbits MAX_PLAYERS
|
||||
.loop
|
||||
dec a
|
||||
cp -1
|
||||
ret z
|
||||
ld [wMockingWhichPlayer], a
|
||||
push af
|
||||
call RepositionMockedPlayerObject
|
||||
pop af
|
||||
jr .loop
|
||||
|
||||
; if map at wPlayer1MapGroup, wPlayer1MapNumber is not the current map,
|
||||
; or a map connected to the current map, we are done.
|
||||
ld hl, wPlayer1MapGroup
|
||||
ld a, [hli]
|
||||
RepositionMockedPlayerObject:
|
||||
; if map at wPlayer*MapGroup, wPlayer*MapNumber is not the current map, do nothing.
|
||||
; otherwise mock this player object.
|
||||
ld a, [wMockingWhichPlayer]
|
||||
ld hl, wPlayer1Location
|
||||
ld bc, wPlayer2Location - wPlayer1Location
|
||||
call AddNTimes
|
||||
ld a, [hli] ; wPlayer*MapGroup
|
||||
ld b, a
|
||||
ld c, [hl] ; wPlayer1MapNumber
|
||||
ld c, [hl] ; wPlayer*MapNumber
|
||||
ld a, [wMapGroup]
|
||||
cp b
|
||||
jr nz, .next_map_1
|
||||
@@ -917,10 +951,14 @@ RepositionMockedPlayerObject::
|
||||
ld [wTempByteValue], a
|
||||
ld hl, .got_sprite_coords
|
||||
push hl
|
||||
ld a, [wPlayer1XCoord]
|
||||
ld d, a
|
||||
ld a, [wPlayer1YCoord]
|
||||
ld a, [wMockingWhichPlayer]
|
||||
ld hl, wPlayer1YCoord
|
||||
ld bc, wPlayer2YCoord - wPlayer1YCoord
|
||||
call AddNTimes
|
||||
ld a, [hli] ; wPlayer*YCoord
|
||||
ld e, a
|
||||
ld a, [hl] ; wPlayer*XCoord
|
||||
ld d, a
|
||||
jumptable_bc .Jumptable, wTempByteValue
|
||||
|
||||
.Jumptable:
|
||||
@@ -931,27 +969,21 @@ RepositionMockedPlayerObject::
|
||||
|
||||
.got_sprite_coords
|
||||
ret nc ; return if sprite is not in visible part of connected map
|
||||
xor a ; PLAYER_1
|
||||
ld [wMockingWhichPlayer], a
|
||||
jr MockPlayerObject.loaded_player_mock_coords
|
||||
|
||||
MockPlayerObject_Multiplayer::
|
||||
; input: a: value to write into wMockingWhichPlayer
|
||||
maskbits MAX_PLAYERS
|
||||
ld [wMockingWhichPlayer], a
|
||||
; ld a, [wMockingWhichPlayer]
|
||||
; hl is y,x coordinates: load them into wPlayer*MockYCoord and wPlayer*MockXCoord
|
||||
push hl
|
||||
ld a, [wMockingWhichPlayer]
|
||||
ld hl, wPlayer1MockYCoord
|
||||
ld bc, wPlayer2MockYCoord - wPlayer1MockYCoord
|
||||
call AddNTimes
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld a, [wMockingWhichPlayer]
|
||||
ld hl, wPlayer1YCoord
|
||||
ld bc, wPlayer2YCoord - wPlayer1YCoord
|
||||
call AddNTimes
|
||||
jr MockPlayerObject
|
||||
pop de
|
||||
ld [hl], d
|
||||
inc hl
|
||||
ld [hl], e
|
||||
jr MockPlayerObject.loaded_player_mock_coords
|
||||
|
||||
MockPlayerObject_ViewMapMode::
|
||||
; called from .EnterViewMapMode either in board menu or branch space.
|
||||
; mocks just PLAYER_1 to wMapObject{d:PLAYER_1_MOCK_OBJECT}.
|
||||
farcall RefreshPlayerCoords ; refresh wPlayerObjectYCoord and wPlayerObjectXCoord (not strictly necessary)
|
||||
xor a ; PLAYER_1
|
||||
ld [wMockingWhichPlayer], a
|
||||
@@ -1226,8 +1258,8 @@ GetWestConnectedSpriteCoords:
|
||||
xor a
|
||||
ret ; nc
|
||||
|
||||
; load into wPlayer1MockYCoord and wPlayer1MockXCoord the coordinates
|
||||
; that correspond to wOverworldMapBlocks address at hl.
|
||||
; load into h and l the y and x coordinates that correspond to wOverworldMapBlocks address at hl.
|
||||
; return nc if either X or Y coord is too negative to be visible in the screen.
|
||||
ConvertConnectedOverworldMapBlockAddressToXYCoords:
|
||||
ld bc, -wOverworldMapBlocks + $10000
|
||||
add hl, bc
|
||||
@@ -1254,20 +1286,20 @@ ConvertConnectedOverworldMapBlockAddressToXYCoords:
|
||||
; substract 6 tiles from y, substract 6 tiles from x.
|
||||
; the '6's correspond to the 3 extra blocks in each margin of wOverworldMapBlocks.
|
||||
sub 6
|
||||
ld [wPlayer1MockXCoord], a
|
||||
ld l, a
|
||||
ld a, d
|
||||
sub 6
|
||||
ld [wPlayer1MockYCoord], a
|
||||
call CheckPlayerMockSpriteOutOfScreen
|
||||
ld h, a
|
||||
call .CheckPlayerMockSpriteOutOfScreen
|
||||
ret ; c or nc
|
||||
|
||||
; return nc if either X or Y coord is too negative to be visible in the screen.
|
||||
; this corresponds to half-block coords -5 and -6, which are visible by wOverworldMapBlocks,
|
||||
; but not by the map sprite engine when it adds 4 to X and to Y to obtain wPlayerObject coords.
|
||||
CheckPlayerMockSpriteOutOfScreen:
|
||||
ld a, [wPlayer1MockXCoord]
|
||||
.CheckPlayerMockSpriteOutOfScreen:
|
||||
ld a, l ; x coord
|
||||
ld b, a
|
||||
ld a, [wPlayer1MockYCoord]
|
||||
ld a, h ; y coord
|
||||
ld c, a
|
||||
ld a, -5
|
||||
cp b
|
||||
|
||||
@@ -2164,10 +2164,11 @@ wBreedingCompatibility::
|
||||
wMoveGrammar::
|
||||
wApplyStatLevelMultipliersToEnemy::
|
||||
wUsePPUp::
|
||||
wMockingWhichPlayer::
|
||||
db
|
||||
|
||||
wFailedToFlee:: db
|
||||
wFailedToFlee::
|
||||
wMockingWhichPlayer::
|
||||
db
|
||||
wNumFleeAttempts:: db
|
||||
wMonTriedToEvolve:: db
|
||||
|
||||
@@ -2520,7 +2521,7 @@ wBikeStep:: dw
|
||||
wKurtApricornQuantity:: db
|
||||
|
||||
wCurLevel:: db
|
||||
wNumLevelPlayers:: db
|
||||
wNumLevelPlayers:: db ; 1-4
|
||||
wPlayer1Id:: db
|
||||
wPlayer2Id:: db
|
||||
wPlayer3Id:: db
|
||||
@@ -2579,7 +2580,7 @@ wPlayer2Location:: player_location wPlayer2
|
||||
wPlayer3Location:: player_location wPlayer3
|
||||
wPlayer4Location:: player_location wPlayer4
|
||||
|
||||
; used in MockPlayerObject_* and RepositionMockedPlayerObject
|
||||
; used in MockPlayerObject_* and RepositionMockedPlayerObjects_Connection
|
||||
; player 1: used during a View Map mode session or in multiplayer
|
||||
; player 2-4: used in multiplayer
|
||||
wPlayer1MockYCoord:: db
|
||||
|
||||
Reference in New Issue
Block a user