mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	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
					
				
					 6 changed files with 39 additions and 77 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		
		Reference in a new issue