mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-23 20:45:11 +00:00
Synchronized LLL puzzle
This commit is contained in:
parent
c515ccd427
commit
47f5e2315e
8 changed files with 93 additions and 10 deletions
|
@ -114,19 +114,87 @@ 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.
|
||||
*/
|
||||
void bhv_lll_bowser_puzzle_loop(void) {
|
||||
s32 i;
|
||||
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) {
|
||||
case BOWSER_PUZZLE_ACT_SPAWN_PIECES:
|
||||
bhv_lll_bowser_puzzle_spawn_pieces(480.0f);
|
||||
break;
|
||||
case BOWSER_PUZZLE_ACT_WAIT_FOR_COMPLETE:
|
||||
// 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.
|
||||
for (i = 0; i < 5; i++)
|
||||
sp28 = spawn_object(o, MODEL_YELLOW_COIN, bhvSingleCoinGetsSpawned);
|
||||
|
@ -164,11 +232,17 @@ void bhv_lll_bowser_puzzle_piece_update(void) {
|
|||
s8 *nextAction = o->oBowserPuzzlePieceNextAction;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ u8 cannon_ignore_remote_updates(void) {
|
|||
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
|
||||
struct MarioState* m = &gMarioStates[0];
|
||||
if (m->action != ACT_IN_CANNON) { return; }
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
static u32 mipsPrevHeldState = 0;
|
||||
|
||||
static void bhv_mips_on_received_pre(void) {
|
||||
static void bhv_mips_on_received_pre(u8 fromLocalIndex) {
|
||||
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) {
|
||||
cur_obj_init_animation(0);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#ifdef DEBUG
|
||||
|
||||
static u8 warpToLevel = LEVEL_BOB;
|
||||
static u8 warpToLevel = LEVEL_LLL;
|
||||
|
||||
#define SCANCODE_0 0x0B
|
||||
#define SCANCODE_3 0x04
|
||||
|
|
|
@ -52,8 +52,8 @@ struct SyncObject {
|
|||
bool hasStandardFields;
|
||||
float maxUpdateRate;
|
||||
u8 (*ignore_if_true)(void);
|
||||
void (*on_received_pre)(void);
|
||||
void (*on_received_post)(void);
|
||||
void (*on_received_pre)(u8 fromLocalIndex);
|
||||
void (*on_received_post)(u8 fromLocalIndex);
|
||||
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,14 @@ bool network_player_any_connected(void) {
|
|||
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) {
|
||||
float elapsed = (clock() - gLastNetworkSend) / (float)CLOCKS_PER_SEC;
|
||||
if (elapsed > NETWORK_PLAYER_TIMEOUT / 3.0f) {
|
||||
|
|
|
@ -29,6 +29,7 @@ extern struct NetworkPlayer* gNetworkPlayerLocal;
|
|||
extern struct NetworkPlayer* gNetworkPlayerServer;
|
||||
|
||||
bool network_player_any_connected(void);
|
||||
u8 network_player_connected_count(void);
|
||||
void network_player_update(void);
|
||||
u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex);
|
||||
u8 network_player_disconnected(u8 globalIndex);
|
||||
|
|
|
@ -378,7 +378,7 @@ void network_receive_object(struct Packet* p) {
|
|||
extern struct Object* gCurrentObject;
|
||||
struct Object* tmp = gCurrentObject;
|
||||
gCurrentObject = so->o;
|
||||
(*so->on_received_pre)();
|
||||
(*so->on_received_pre)(p->localIndex);
|
||||
gCurrentObject = tmp;
|
||||
}
|
||||
|
||||
|
@ -398,7 +398,7 @@ void network_receive_object(struct Packet* p) {
|
|||
extern struct Object* gCurrentObject;
|
||||
struct Object* tmp = gCurrentObject;
|
||||
gCurrentObject = so->o;
|
||||
(*so->on_received_post)();
|
||||
(*so->on_received_post)(p->localIndex);
|
||||
gCurrentObject = tmp;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue