Synchronized mips

This commit is contained in:
MysterD 2020-09-20 17:28:24 -07:00
parent bbe95efaa2
commit c5888aff50
5 changed files with 55 additions and 12 deletions

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(void) { static void cannon_on_received_pos(void) {
// 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; }
@ -179,7 +179,7 @@ void bhv_cannon_base_loop(void) {
if (!network_sync_object_initialized(o)) { if (!network_sync_object_initialized(o)) {
struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
so->ignore_if_true = cannon_ignore_remote_updates; so->ignore_if_true = cannon_ignore_remote_updates;
so->on_received = cannon_on_received; so->on_received_post = cannon_on_received_pos;
network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->oAction);
network_init_object_field(o, &o->oPrevAction); network_init_object_field(o, &o->oPrevAction);
network_init_object_field(o, &o->oTimer); network_init_object_field(o, &o->oTimer);

View file

@ -2,6 +2,18 @@
* Behavior for MIPS (everyone's favorite yellow rabbit). * Behavior for MIPS (everyone's favorite yellow rabbit).
*/ */
static u32 mipsPrevHeldState = 0;
static void bhv_mips_on_received_pre(void) {
mipsPrevHeldState = o->oHeldState;
}
static void bhv_mips_on_received_post(void) {
if (mipsPrevHeldState == HELD_HELD && o->oHeldState == HELD_FREE) {
cur_obj_init_animation(0);
}
}
/** /**
* Initializes MIPS' physics parameters and checks if he should be active, * Initializes MIPS' physics parameters and checks if he should be active,
* hiding him if necessary. * hiding him if necessary.
@ -41,6 +53,17 @@ void bhv_mips_init(void) {
o->oBuoyancy = 1.2f; o->oBuoyancy = 1.2f;
cur_obj_init_animation(0); cur_obj_init_animation(0);
struct SyncObject* so = network_init_object(o, 4000.0f);
network_init_object_field(o, &o->oMipsStartWaypointIndex);
network_init_object_field(o, &o->oForwardVel);
network_init_object_field(o, &o->oMipsStarStatus);
network_init_object_field(o, &o->oBehParams2ndByte);
network_init_object_field(o, &o->oHeldState);
network_init_object_field(o, &o->oFlags);
network_init_object_field(o, &o->oIntangibleTimer);
so->on_received_pre = bhv_mips_on_received_pre;
so->on_received_post = bhv_mips_on_received_post;
} }
/** /**
@ -58,6 +81,8 @@ s16 bhv_mips_find_furthest_waypoint_to_mario(void) {
pathBase = segmented_to_virtual(&inside_castle_seg7_trajectory_mips); pathBase = segmented_to_virtual(&inside_castle_seg7_trajectory_mips);
struct Object* player = nearest_player_to_object(o);
// For each waypoint in MIPS path... // For each waypoint in MIPS path...
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
waypoint = segmented_to_virtual(*(pathBase + i)); waypoint = segmented_to_virtual(*(pathBase + i));
@ -68,8 +93,7 @@ s16 bhv_mips_find_furthest_waypoint_to_mario(void) {
// Is the waypoint within 800 units of MIPS? // Is the waypoint within 800 units of MIPS?
if (is_point_close_to_object(o, x, y, z, 800)) { if (is_point_close_to_object(o, x, y, z, 800)) {
// Is this further from Mario than the last waypoint? // Is this further from Mario than the last waypoint?
distanceToMario = distanceToMario = sqr(x - player->header.gfx.pos[0]) + sqr(z - player->header.gfx.pos[2]);
sqr(x - gMarioObject->header.gfx.pos[0]) + sqr(z - gMarioObject->header.gfx.pos[2]);
if (furthestWaypointDistance < distanceToMario) { if (furthestWaypointDistance < distanceToMario) {
furthestWaypointIndex = i; furthestWaypointIndex = i;
furthestWaypointDistance = distanceToMario; furthestWaypointDistance = distanceToMario;
@ -221,7 +245,7 @@ void bhv_mips_free(void) {
} }
static u8 bhv_mips_held_continue_dialog(void) { static u8 bhv_mips_held_continue_dialog(void) {
return (o->oHeldState == HELD_HELD && o->oMipsStarStatus == MIPS_STAR_STATUS_HAVENT_SPAWNED_STAR); return (o->heldByPlayerIndex == 0 && o->oHeldState == HELD_HELD && o->oMipsStarStatus == MIPS_STAR_STATUS_HAVENT_SPAWNED_STAR);
} }
/** /**
@ -230,9 +254,11 @@ static u8 bhv_mips_held_continue_dialog(void) {
void bhv_mips_held(void) { void bhv_mips_held(void) {
s16 dialogID; s16 dialogID;
struct Object* player = gMarioStates[o->heldByPlayerIndex].marioObj;
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE; o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
cur_obj_init_animation(4); // Held animation. cur_obj_init_animation(4); // Held animation.
cur_obj_set_pos_relative(gMarioObject, 0, 60.0f, 100.0f); cur_obj_set_pos_relative(player, 0, 60.0f, 100.0f);
cur_obj_become_intangible(); cur_obj_become_intangible();
// If MIPS hasn't spawned his star yet... // If MIPS hasn't spawned his star yet...
@ -243,7 +269,7 @@ void bhv_mips_held(void) {
else else
dialogID = DIALOG_162; dialogID = DIALOG_162;
if (set_mario_npc_dialog(&gMarioStates[0], 1, bhv_mips_held_continue_dialog) == 2) { if (o->heldByPlayerIndex == 0 && set_mario_npc_dialog(&gMarioStates[0], 1, bhv_mips_held_continue_dialog) == 2) {
//o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP; //o->activeFlags |= ACTIVE_FLAG_INITIATED_TIME_STOP;
if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogID)) { if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogID)) {
o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY; o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY;
@ -266,6 +292,9 @@ void bhv_mips_dropped(void) {
cur_obj_become_tangible(); cur_obj_become_tangible();
o->oForwardVel = 3.0f; o->oForwardVel = 3.0f;
o->oAction = MIPS_ACT_IDLE; o->oAction = MIPS_ACT_IDLE;
if (network_owns_object(o)) {
network_send_object(o);
}
} }
/** /**
@ -281,6 +310,9 @@ void bhv_mips_thrown(void) {
o->oForwardVel = 25.0f; o->oForwardVel = 25.0f;
o->oVelY = 20.0f; o->oVelY = 20.0f;
o->oAction = MIPS_ACT_FALL_DOWN; o->oAction = MIPS_ACT_FALL_DOWN;
if (network_owns_object(o)) {
network_send_object(o);
}
} }
/** /**

View file

@ -1904,7 +1904,7 @@ s32 execute_mario_action(UNUSED struct Object *o) {
// two-player hack: drop held object if server is holding it // two-player hack: drop held object if server is holding it
if (gNetworkType == NT_CLIENT && gMarioState->playerIndex == 0 && gMarioState->heldObj != NULL) { if (gNetworkType == NT_CLIENT && gMarioState->playerIndex == 0 && gMarioState->heldObj != NULL) {
u8 inCutscene = ((gMarioState->action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE); u8 inCutscene = ((gMarioState->action & ACT_GROUP_MASK) != ACT_GROUP_CUTSCENE);
if (!inCutscene && gMarioState->heldObj == gMarioStates[0].heldObj) { if (!inCutscene && gMarioState->heldObj->heldByPlayerIndex != 0) {
drop_and_set_mario_action(gMarioState, ACT_IDLE, 0); drop_and_set_mario_action(gMarioState, ACT_IDLE, 0);
} }
} }

View file

@ -52,7 +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)(void); void (*on_received_pre)(void);
void (*on_received_post)(void);
void* extraFields[MAX_SYNC_OBJECT_FIELDS]; void* extraFields[MAX_SYNC_OBJECT_FIELDS];
}; };

View file

@ -55,7 +55,8 @@ struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance)
so->hasStandardFields = (maxSyncDistance >= 0); so->hasStandardFields = (maxSyncDistance >= 0);
so->maxUpdateRate = 0; so->maxUpdateRate = 0;
so->ignore_if_true = NULL; so->ignore_if_true = NULL;
so->on_received = NULL; so->on_received_pre = NULL;
so->on_received_post = NULL;
so->syncDeathEvent = true; so->syncDeathEvent = true;
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS); memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
@ -370,6 +371,15 @@ void network_receive_object(struct Packet* p) {
if (gMarioStates[0].heldObj == o) { return; } if (gMarioStates[0].heldObj == o) { return; }
} }
// trigger on-received callback
if (so->on_received_pre != NULL) {
extern struct Object* gCurrentObject;
struct Object* tmp = gCurrentObject;
gCurrentObject = so->o;
(*so->on_received_pre)();
gCurrentObject = tmp;
}
// read the rest of the packet data // read the rest of the packet data
packet_read_object_full_sync(p, o); packet_read_object_full_sync(p, o);
packet_read_object_standard_fields(p, o); packet_read_object_standard_fields(p, o);
@ -382,11 +392,11 @@ void network_receive_object(struct Packet* p) {
} }
// trigger on-received callback // trigger on-received callback
if (so->on_received != NULL) { if (so->on_received_post != NULL) {
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)(); (*so->on_received_post)();
gCurrentObject = tmp; gCurrentObject = tmp;
} }
} }