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);
}
static void cannon_on_received(void) {
static void cannon_on_received_pos(void) {
// check if we're on in the cannon too
struct MarioState* m = &gMarioStates[0];
if (m->action != ACT_IN_CANNON) { return; }
@ -179,7 +179,7 @@ void bhv_cannon_base_loop(void) {
if (!network_sync_object_initialized(o)) {
struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
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->oPrevAction);
network_init_object_field(o, &o->oTimer);

View file

@ -2,6 +2,18 @@
* 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,
* hiding him if necessary.
@ -41,6 +53,17 @@ void bhv_mips_init(void) {
o->oBuoyancy = 1.2f;
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);
struct Object* player = nearest_player_to_object(o);
// For each waypoint in MIPS path...
for (i = 0; i < 10; 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?
if (is_point_close_to_object(o, x, y, z, 800)) {
// Is this further from Mario than the last waypoint?
distanceToMario =
sqr(x - gMarioObject->header.gfx.pos[0]) + sqr(z - gMarioObject->header.gfx.pos[2]);
distanceToMario = sqr(x - player->header.gfx.pos[0]) + sqr(z - player->header.gfx.pos[2]);
if (furthestWaypointDistance < distanceToMario) {
furthestWaypointIndex = i;
furthestWaypointDistance = distanceToMario;
@ -221,7 +245,7 @@ void bhv_mips_free(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) {
s16 dialogID;
struct Object* player = gMarioStates[o->heldByPlayerIndex].marioObj;
o->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
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();
// If MIPS hasn't spawned his star yet...
@ -243,7 +269,7 @@ void bhv_mips_held(void) {
else
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;
if (cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogID)) {
o->oInteractionSubtype |= INT_SUBTYPE_DROP_IMMEDIATELY;
@ -266,6 +292,9 @@ void bhv_mips_dropped(void) {
cur_obj_become_tangible();
o->oForwardVel = 3.0f;
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->oVelY = 20.0f;
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
if (gNetworkType == NT_CLIENT && gMarioState->playerIndex == 0 && gMarioState->heldObj != NULL) {
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);
}
}

View file

@ -52,7 +52,8 @@ struct SyncObject {
bool hasStandardFields;
float maxUpdateRate;
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];
};

View file

@ -55,7 +55,8 @@ struct SyncObject* network_init_object(struct Object *o, float maxSyncDistance)
so->hasStandardFields = (maxSyncDistance >= 0);
so->maxUpdateRate = 0;
so->ignore_if_true = NULL;
so->on_received = NULL;
so->on_received_pre = NULL;
so->on_received_post = NULL;
so->syncDeathEvent = true;
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; }
}
// 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
packet_read_object_full_sync(p, o);
packet_read_object_standard_fields(p, o);
@ -382,11 +392,11 @@ void network_receive_object(struct Packet* p) {
}
// trigger on-received callback
if (so->on_received != NULL) {
if (so->on_received_post != NULL) {
extern struct Object* gCurrentObject;
struct Object* tmp = gCurrentObject;
gCurrentObject = so->o;
(*so->on_received)();
(*so->on_received_post)();
gCurrentObject = tmp;
}
}