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++;
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue