Resynchronized LLL puzzle pieces
Created a timer based on area that is shared. The puzzle pieces will execute rapidly to catch up to the timer on level join. This keeps them in sync without constantly needing to acknowledge that a puzzle piece had moved before continuing.
This commit is contained in:
parent
6aded174e9
commit
e7d0f8ec8b
|
@ -310,6 +310,7 @@
|
|||
#define /*0x108*/ oBowserPuzzlePieceContinuePerformingAction OBJECT_FIELD_S32(0x20)
|
||||
#define /*0x10C*/ oBowserPuzzlePieceActionList OBJECT_FIELD_VPTR(0x21)
|
||||
#define /*0x110*/ oBowserPuzzlePieceNextAction OBJECT_FIELD_VPTR(0x22)
|
||||
#define /*0x0F4*/ oBowserPuzzlePieceTimer OBJECT_FIELD_U32(0x1B)
|
||||
|
||||
/* Bubba */
|
||||
#define /*0x0F4*/ oBubbaUnkF4 OBJECT_FIELD_F32(0x1B)
|
||||
|
|
|
@ -94,6 +94,8 @@ void bhv_lll_bowser_puzzle_spawn_piece(s16 model, const BehaviorScript *behavior
|
|||
puzzlePiece->oAction = initialAction; // This action never gets executed.
|
||||
puzzlePiece->oBowserPuzzlePieceActionList = actionList;
|
||||
puzzlePiece->oBowserPuzzlePieceNextAction = actionList;
|
||||
puzzlePiece->oBowserPuzzlePieceTimer = 0;
|
||||
puzzlePiece->oTimer = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,69 +116,6 @@ void bhv_lll_bowser_puzzle_spawn_pieces(f32 pieceWidth) {
|
|||
o->oAction++;
|
||||
}
|
||||
|
||||
static u8 bowserPuzzleTimer = 0;
|
||||
static u8 bowserPuzzleOnAction = 0;
|
||||
static u8 bowserPuzzleServerAction = 0;
|
||||
static u32 bowserPuzzleTxRxAction = 0;
|
||||
static u8 bowserPuzzleRx[MAX_PLAYERS] = { 0 };
|
||||
|
||||
static void bhv_lll_bowser_puzzle_networking_received(u8 fromLocalIndex) {
|
||||
if (gNetworkType == NT_CLIENT) {
|
||||
if (bowserPuzzleTxRxAction != (u8)(bowserPuzzleOnAction + 1)) { return; }
|
||||
bowserPuzzleServerAction = bowserPuzzleTxRxAction;
|
||||
return;
|
||||
}
|
||||
if (bowserPuzzleTxRxAction != bowserPuzzleOnAction) { return; }
|
||||
bowserPuzzleRx[fromLocalIndex] = bowserPuzzleTxRxAction;
|
||||
}
|
||||
|
||||
static void bhv_lll_bowser_puzzle_networking(void) {
|
||||
if (!network_sync_object_initialized(o)) {
|
||||
bowserPuzzleTimer = 0;
|
||||
bowserPuzzleOnAction = 0;
|
||||
bowserPuzzleServerAction = 0;
|
||||
bowserPuzzleTxRxAction = 0;
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) { bowserPuzzleRx[i] = 0; }
|
||||
|
||||
struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
|
||||
network_init_object_field(o, &bowserPuzzleTxRxAction);
|
||||
so->on_received_post = bhv_lll_bowser_puzzle_networking_received;
|
||||
}
|
||||
|
||||
if (bowserPuzzleTimer < 24) {
|
||||
bowserPuzzleTimer++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
if (bowserPuzzleTimer == 24) {
|
||||
bowserPuzzleTimer++;
|
||||
bowserPuzzleOnAction++;
|
||||
bowserPuzzleTxRxAction = bowserPuzzleOnAction;
|
||||
network_send_object(o);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 1; i < MAX_PLAYERS; i++) {
|
||||
if (gNetworkPlayers[i].connected && bowserPuzzleRx[i] != bowserPuzzleOnAction) { return; }
|
||||
}
|
||||
|
||||
// received from all, continue
|
||||
bowserPuzzleTimer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gNetworkType == NT_CLIENT) {
|
||||
if (bowserPuzzleServerAction == (u8)(bowserPuzzleOnAction + 1)) {
|
||||
bowserPuzzleOnAction++;
|
||||
bowserPuzzleTimer = 0;
|
||||
bowserPuzzleTxRxAction = bowserPuzzleServerAction;
|
||||
network_send_object(o);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Does the initial spawn of the puzzle pieces and then waits to spawn 5 coins.
|
||||
*/
|
||||
|
@ -186,8 +125,6 @@ void bhv_lll_bowser_puzzle_loop(void) {
|
|||
struct Object* player = nearest_player_to_object(o);
|
||||
int distanceToPlayer = dist_between_objects(o, player);
|
||||
|
||||
bhv_lll_bowser_puzzle_networking();
|
||||
|
||||
switch (o->oAction) {
|
||||
case BOWSER_PUZZLE_ACT_SPAWN_PIECES:
|
||||
bhv_lll_bowser_puzzle_spawn_pieces(480.0f);
|
||||
|
@ -229,7 +166,7 @@ void bhv_lll_bowser_puzzle_piece_action_1(void) {
|
|||
* Update the puzzle piece.
|
||||
*/
|
||||
void bhv_lll_bowser_puzzle_piece_update(void) {
|
||||
s8 *nextAction = o->oBowserPuzzlePieceNextAction;
|
||||
s8* nextAction = o->oBowserPuzzlePieceNextAction;
|
||||
|
||||
// If Mario is standing on this puzzle piece, set a flag in the parent.
|
||||
if (cur_obj_is_any_player_on_platform())
|
||||
|
@ -237,11 +174,6 @@ void bhv_lll_bowser_puzzle_piece_update(void) {
|
|||
|
||||
// If we should advance to the next action...
|
||||
if (o->oBowserPuzzlePieceContinuePerformingAction == 0) {
|
||||
// if we haven't received an event from everyone, do not continue execution
|
||||
if (bowserPuzzleTimer >= 24) {
|
||||
cur_obj_change_action(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Start doing the next action.
|
||||
cur_obj_change_action(*nextAction);
|
||||
|
@ -327,11 +259,27 @@ void (*sBowserPuzzlePieceActions[])(void) = {
|
|||
};
|
||||
|
||||
void bhv_lll_bowser_puzzle_piece_loop(void) {
|
||||
bhv_lll_bowser_puzzle_piece_update();
|
||||
// make sure we're loaded and synchronized
|
||||
if (!gNetworkLevelLoaded) {
|
||||
o->oTimer = 0;
|
||||
return;
|
||||
} else if (o->oBowserPuzzlePieceTimer == 0 && (gNetworkLevelTimer - o->oBowserPuzzlePieceTimer) >= 650) {
|
||||
o->oBowserPuzzlePieceTimer = ((gNetworkLevelTimer - o->oBowserPuzzlePieceTimer) / 650) * 650;
|
||||
o->oTimer = 0;
|
||||
}
|
||||
|
||||
cur_obj_call_action_function(sBowserPuzzlePieceActions);
|
||||
while (o->oBowserPuzzlePieceTimer < gNetworkLevelTimer) {
|
||||
bhv_lll_bowser_puzzle_piece_update();
|
||||
|
||||
o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX;
|
||||
o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY;
|
||||
o->oPosZ = o->oBowserPuzzlePieceOffsetZ + o->oHomeZ;
|
||||
cur_obj_call_action_function(sBowserPuzzlePieceActions);
|
||||
|
||||
o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX;
|
||||
o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY;
|
||||
o->oPosZ = o->oBowserPuzzlePieceOffsetZ + o->oHomeZ;
|
||||
|
||||
o->oBowserPuzzlePieceTimer++;
|
||||
if (o->oBowserPuzzlePieceTimer < gNetworkLevelTimer) {
|
||||
o->oTimer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
static u8 warpToLevel = LEVEL_BOB;
|
||||
static u8 warpToLevel = LEVEL_LLL;
|
||||
|
||||
#define SCANCODE_0 0x0B
|
||||
#define SCANCODE_1 0x02
|
||||
|
|
|
@ -27,6 +27,7 @@ struct NetworkSystem* gNetworkSystem = &gNetworkSystemSocket;
|
|||
u16 networkLoadingLevel = 0;
|
||||
bool gNetworkLevelLoaded = false;
|
||||
bool gNetworkLevelSyncing = true;
|
||||
u32 gNetworkLevelTimer = 0;
|
||||
|
||||
clock_t gLastNetworkSend = 0;
|
||||
struct StringLinkedList gRegisteredMods = { 0 };
|
||||
|
@ -91,6 +92,7 @@ void network_on_init_level(void) {
|
|||
networkLoadingLevel = 0;
|
||||
gNetworkLevelLoaded = false;
|
||||
gNetworkLevelSyncing = true;
|
||||
gNetworkLevelTimer = 0;
|
||||
}
|
||||
|
||||
void network_on_loaded_level(void) {
|
||||
|
@ -228,8 +230,11 @@ void network_update(void) {
|
|||
networkLoadingLevel++;
|
||||
if (!gNetworkLevelLoaded && networkLoadingLevel >= LOADING_LEVEL_THRESHOLD) {
|
||||
gNetworkLevelLoaded = true;
|
||||
gNetworkLevelTimer = 0;
|
||||
network_on_loaded_level();
|
||||
}
|
||||
} else if (gNetworkLevelLoaded) {
|
||||
gNetworkLevelTimer++;
|
||||
}
|
||||
|
||||
// send out update packets
|
||||
|
|
|
@ -82,6 +82,7 @@ extern struct NetworkSystem* gNetworkSystem;
|
|||
extern enum NetworkType gNetworkType;
|
||||
extern bool gNetworkLevelLoaded;
|
||||
extern bool gNetworkLevelSyncing;
|
||||
extern u32 gNetworkLevelTimer;
|
||||
extern struct SyncObject gSyncObjects[];
|
||||
extern struct ServerSettings gServerSettings;
|
||||
extern clock_t gLastNetworkSend;
|
||||
|
|
|
@ -43,6 +43,9 @@ void network_send_area(struct NetworkPlayer* toNp) {
|
|||
packet_write(&p, &gCurrLevelNum, sizeof(s16));
|
||||
packet_write(&p, &gCurrAreaIndex, sizeof(s16));
|
||||
|
||||
// area variables
|
||||
packet_write(&p, &gNetworkLevelTimer, sizeof(u32));
|
||||
|
||||
// write sync id removals
|
||||
packet_write(&p, &sRemoveSyncIdsIndex, sizeof(u8));
|
||||
for (int i = 0; i < sRemoveSyncIdsIndex; i++) {
|
||||
|
@ -129,6 +132,10 @@ void network_receive_area(struct Packet* p) {
|
|||
packet_read(p, &levelNum, sizeof(s16));
|
||||
packet_read(p, &areaIndex, sizeof(s16));
|
||||
|
||||
// read area variables
|
||||
packet_read(p, &gNetworkLevelTimer, sizeof(u32));
|
||||
|
||||
|
||||
extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum;
|
||||
if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) {
|
||||
LOG_ERROR("rx area: received an improper location");
|
||||
|
|
Loading…
Reference in New Issue