diff --git a/include/object_fields.h b/include/object_fields.h index e01c87fe4..f4ad21734 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -829,6 +829,7 @@ #define /*0x0F4*/ oDDDPoleVel OBJECT_FIELD_F32(0x1B) #define /*0x0F8*/ oDDDPoleMaxOffset OBJECT_FIELD_F32(0x1C) #define /*0x0FC*/ oDDDPoleOffset OBJECT_FIELD_F32(0x1D) +#define /*0x100*/ oDDDPoleTimer OBJECT_FIELD_U32(0x1E) /* Pyramid Top */ #define /*0x0F4*/ oPyramidTopPillarsTouched OBJECT_FIELD_S32(0x1B) diff --git a/src/game/behaviors/ddd_pole.inc.c b/src/game/behaviors/ddd_pole.inc.c index 752b6e607..d8cf32fe7 100644 --- a/src/game/behaviors/ddd_pole.inc.c +++ b/src/game/behaviors/ddd_pole.inc.c @@ -1,41 +1,44 @@ -void bhv_ddd_pole_override_ownership(u8* shouldOverride, u8* shouldOwn) { - *shouldOverride = TRUE; - *shouldOwn = (gNetworkType == NT_SERVER); -} - void bhv_ddd_pole_init(void) { if (!(save_file_get_flags() & (SAVE_FLAG_HAVE_KEY_2 | SAVE_FLAG_UNLOCKED_UPSTAIRS_DOOR))) { obj_mark_for_deletion(o); } else { o->hitboxDownOffset = 100.0f; o->oDDDPoleMaxOffset = 100.0f * o->oBehParams2ndByte; - - struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); - so->override_ownership = bhv_ddd_pole_override_ownership; - network_init_object_field(o, &o->oPosX); - network_init_object_field(o, &o->oPosY); - network_init_object_field(o, &o->oPosZ); - network_init_object_field(o, &o->oDDDPoleVel); - network_init_object_field(o, &o->oDDDPoleOffset); - network_init_object_field(o, &o->oAction); - network_init_object_field(o, &o->oPrevAction); - network_init_object_field(o, &o->oTimer); } } -void bhv_ddd_pole_update(void) { - if (o->oTimer > 20) { - o->oDDDPoleOffset += o->oDDDPoleVel; - if (clamp_f32(&o->oDDDPoleOffset, 0.0f, o->oDDDPoleMaxOffset)) { - o->oDDDPoleVel = -o->oDDDPoleVel; +void bhv_ddd_pole_update(void) { + // make sure we're loaded and synchronized + if (!gNetworkAreaLoaded) { + o->oTimer = 0; + o->oDDDPoleTimer = 0; + return; + } else { + // catch up, jumping full loop cycles at a time + u16 loopTime = (((u16)o->oDDDPoleMaxOffset / 10) + 20) * 2; + if (o->oDDDPoleTimer == 0 && (gNetworkAreaTimer - o->oDDDPoleTimer) >= loopTime) { + o->oDDDPoleTimer = ((gNetworkAreaTimer - o->oDDDPoleTimer) / loopTime) * loopTime; o->oTimer = 0; - if (network_owns_object(o)) { - network_send_object(o); - } } } - obj_set_dist_from_home(o->oDDDPoleOffset); + while (o->oDDDPoleTimer < gNetworkAreaTimer) { + if (o->oTimer > 20) { + o->oDDDPoleOffset += o->oDDDPoleVel; + + if (clamp_f32(&o->oDDDPoleOffset, 0.0f, o->oDDDPoleMaxOffset)) { + o->oDDDPoleVel = -o->oDDDPoleVel; + o->oTimer = 0; + } + } + + obj_set_dist_from_home(o->oDDDPoleOffset); + + o->oDDDPoleTimer++; + if (o->oDDDPoleTimer < gNetworkAreaTimer) { + cur_obj_fake_update(); + } + } }