Synchronized LLL puzzle

This commit is contained in:
MysterD 2020-09-22 18:25:17 -07:00
parent c515ccd427
commit 47f5e2315e
8 changed files with 93 additions and 10 deletions

View file

@ -114,19 +114,87 @@ void bhv_lll_bowser_puzzle_spawn_pieces(f32 pieceWidth) {
o->oAction++; 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. * Does the initial spawn of the puzzle pieces and then waits to spawn 5 coins.
*/ */
void bhv_lll_bowser_puzzle_loop(void) { void bhv_lll_bowser_puzzle_loop(void) {
s32 i; s32 i;
UNUSED struct Object *sp28; UNUSED struct Object *sp28;
struct Object* player = nearest_player_to_object(o);
int distanceToPlayer = dist_between_objects(o, player);
bhv_lll_bowser_puzzle_networking();
switch (o->oAction) { switch (o->oAction) {
case BOWSER_PUZZLE_ACT_SPAWN_PIECES: case BOWSER_PUZZLE_ACT_SPAWN_PIECES:
bhv_lll_bowser_puzzle_spawn_pieces(480.0f); bhv_lll_bowser_puzzle_spawn_pieces(480.0f);
break; break;
case BOWSER_PUZZLE_ACT_WAIT_FOR_COMPLETE: case BOWSER_PUZZLE_ACT_WAIT_FOR_COMPLETE:
// If both completion flags are set and Mario is within 1000 units... // If both completion flags are set and Mario is within 1000 units...
if (o->oBowserPuzzleCompletionFlags == 3 && o->oDistanceToMario < 1000.0f) { if (o->oBowserPuzzleCompletionFlags == 3 && distanceToPlayer < 1000.0f) {
// Spawn 5 coins. // Spawn 5 coins.
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
sp28 = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned); sp28 = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned);
@ -164,11 +232,17 @@ 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 Mario is standing on this puzzle piece, set a flag in the parent.
if (gMarioObject->platform == o) if (cur_obj_is_any_player_on_platform())
o->parentObj->oBowserPuzzleCompletionFlags = 1; o->parentObj->oBowserPuzzleCompletionFlags = 1;
// If we should advance to the next action... // If we should advance to the next action...
if (o->oBowserPuzzlePieceContinuePerformingAction == 0) { 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. // Start doing the next action.
cur_obj_change_action(*nextAction); cur_obj_change_action(*nextAction);

View file

@ -151,7 +151,7 @@ u8 cannon_ignore_remote_updates(void) {
return ((gNetworkType == NT_SERVER) && o->oCannonIsLocal); return ((gNetworkType == NT_SERVER) && o->oCannonIsLocal);
} }
static void cannon_on_received_pos(void) { static void cannon_on_received_pos(u8 fromLocalIndex) {
// check if we're on in the cannon too // check if we're on in the cannon too
struct MarioState* m = &gMarioStates[0]; struct MarioState* m = &gMarioStates[0];
if (m->action != ACT_IN_CANNON) { return; } if (m->action != ACT_IN_CANNON) { return; }

View file

@ -4,11 +4,11 @@
static u32 mipsPrevHeldState = 0; static u32 mipsPrevHeldState = 0;
static void bhv_mips_on_received_pre(void) { static void bhv_mips_on_received_pre(u8 fromLocalIndex) {
mipsPrevHeldState = o->oHeldState; mipsPrevHeldState = o->oHeldState;
} }
static void bhv_mips_on_received_post(void) { static void bhv_mips_on_received_post(u8 fromLocalIndex) {
if (mipsPrevHeldState == HELD_HELD && o->oHeldState == HELD_FREE) { if (mipsPrevHeldState == HELD_HELD && o->oHeldState == HELD_FREE) {
cur_obj_init_animation(0); cur_obj_init_animation(0);
} }

View file

@ -5,7 +5,7 @@
#ifdef DEBUG #ifdef DEBUG
static u8 warpToLevel = LEVEL_BOB; static u8 warpToLevel = LEVEL_LLL;
#define SCANCODE_0 0x0B #define SCANCODE_0 0x0B
#define SCANCODE_3 0x04 #define SCANCODE_3 0x04

View file

@ -52,8 +52,8 @@ struct SyncObject {
bool hasStandardFields; bool hasStandardFields;
float maxUpdateRate; float maxUpdateRate;
u8 (*ignore_if_true)(void); u8 (*ignore_if_true)(void);
void (*on_received_pre)(void); void (*on_received_pre)(u8 fromLocalIndex);
void (*on_received_post)(void); void (*on_received_post)(u8 fromLocalIndex);
void* extraFields[MAX_SYNC_OBJECT_FIELDS]; void* extraFields[MAX_SYNC_OBJECT_FIELDS];
}; };

View file

@ -14,6 +14,14 @@ bool network_player_any_connected(void) {
return false; return false;
} }
u8 network_player_connected_count(void) {
u8 count = 0;
for (int i = 1; i < MAX_PLAYERS; i++) {
if (gNetworkPlayers[i].connected) { count++; }
}
return count;
}
void network_player_update(void) { void network_player_update(void) {
float elapsed = (clock() - gLastNetworkSend) / (float)CLOCKS_PER_SEC; float elapsed = (clock() - gLastNetworkSend) / (float)CLOCKS_PER_SEC;
if (elapsed > NETWORK_PLAYER_TIMEOUT / 3.0f) { if (elapsed > NETWORK_PLAYER_TIMEOUT / 3.0f) {

View file

@ -29,6 +29,7 @@ extern struct NetworkPlayer* gNetworkPlayerLocal;
extern struct NetworkPlayer* gNetworkPlayerServer; extern struct NetworkPlayer* gNetworkPlayerServer;
bool network_player_any_connected(void); bool network_player_any_connected(void);
u8 network_player_connected_count(void);
void network_player_update(void); void network_player_update(void);
u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex); u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex);
u8 network_player_disconnected(u8 globalIndex); u8 network_player_disconnected(u8 globalIndex);

View file

@ -378,7 +378,7 @@ void network_receive_object(struct Packet* p) {
extern struct Object* gCurrentObject; extern struct Object* gCurrentObject;
struct Object* tmp = gCurrentObject; struct Object* tmp = gCurrentObject;
gCurrentObject = so->o; gCurrentObject = so->o;
(*so->on_received_pre)(); (*so->on_received_pre)(p->localIndex);
gCurrentObject = tmp; gCurrentObject = tmp;
} }
@ -398,7 +398,7 @@ void network_receive_object(struct Packet* p) {
extern struct Object* gCurrentObject; extern struct Object* gCurrentObject;
struct Object* tmp = gCurrentObject; struct Object* tmp = gCurrentObject;
gCurrentObject = so->o; gCurrentObject = so->o;
(*so->on_received_post)(); (*so->on_received_post)(p->localIndex);
gCurrentObject = tmp; gCurrentObject = tmp;
} }
} }