Synchronize Bobomb buddies and cannons

This commit is contained in:
MysterD 2020-08-09 07:42:44 -07:00
parent a49b8f3b1e
commit 41647d95c4
14 changed files with 245 additions and 136 deletions

View file

@ -349,9 +349,10 @@
#define /*0x1AC*/ oTripletButterflyScalePhase OBJECT_FIELD_S32(0x49)
/* Cannon */
#define /*0x0F4*/ oCannonUnkF4 OBJECT_FIELD_S32(0x1B)
#define /*0x0F8*/ oCannonUnkF8 OBJECT_FIELD_S32(0x1C)
#define /*0x10C*/ oCannonUnk10C OBJECT_FIELD_S32(0x21)
#define /*0x0F4*/ oCannonUnkF4 OBJECT_FIELD_S32(0x1B)
#define /*0x0F8*/ oCannonUnkF8 OBJECT_FIELD_S32(0x1C)
#define /*0x10C*/ oCannonUnk10C OBJECT_FIELD_S32(0x21)
#define /*0x110*/ oCannonIsLocal OBJECT_FIELD_S32(0x22)
/* Cap */
#define /*0x0F4*/ oCapUnkF4 OBJECT_FIELD_S32(0x1B)

View file

@ -12,6 +12,8 @@ static struct ObjectHitbox sBobombHitbox = {
/* hurtboxHeight: */ 0,
};
static u32 forceCannonOpen = FALSE;
void bhv_bobomb_init(void) {
o->oGravity = 2.5;
o->oFriction = 0.8;
@ -287,6 +289,13 @@ void bhv_bobomb_buddy_init(void) {
o->oFriction = 0.8;
o->oBuoyancy = 1.3;
o->oInteractionSubtype = INT_SUBTYPE_NPC;
if (o->oBobombBuddyRole == BOBOMB_BUDDY_ROLE_CANNON) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_init_object_field(o, &o->oBobombBuddyHasTalkedToMario);
network_init_object_field(o, &o->oBobombBuddyCannonStatus);
network_init_object_field(o, &forceCannonOpen);
}
}
void bobomb_buddy_act_idle(void) {
@ -328,6 +337,11 @@ void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText) {
buddyText = cutscene_object_with_dialog(CUTSCENE_DIALOG, o, dialogFirstText);
if (buddyText != 0) {
save_file_set_cannon_unlocked();
forceCannonOpen = TRUE;
network_send_object(o);
forceCannonOpen = FALSE;
cannonClosed = cur_obj_nearest_object_with_behavior(bhvCannonClosed);
if (cannonClosed != 0)
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENING;
@ -357,6 +371,7 @@ void bobomb_buddy_cannon_dialog(s16 dialogFirstText, s16 dialogSecondText) {
o->oInteractStatus = 0;
o->oAction = BOBOMB_BUDDY_ACT_IDLE;
o->oBobombBuddyCannonStatus = BOBOMB_BUDDY_CANNON_OPENED;
network_send_object(o);
break;
}
}
@ -421,6 +436,11 @@ void bobomb_buddy_actions(void) {
}
void bhv_bobomb_buddy_loop(void) {
if (forceCannonOpen) {
save_file_set_cannon_unlocked();
forceCannonOpen = FALSE;
}
bobomb_buddy_actions();
curr_obj_random_blink(&o->oBobombBuddyBlinkTimer);

View file

@ -182,7 +182,7 @@ void bhv_generic_bowling_ball_spawner_init(void) {
void bhv_generic_bowling_ball_spawner_loop(void) {
if (o->oSyncID == 0) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_object_settings(o, FALSE, 0, TRUE);
network_object_settings(o, FALSE, 0, TRUE, NULL);
}
struct Object *bowlingBall;
@ -219,7 +219,7 @@ void bhv_generic_bowling_ball_spawner_loop(void) {
void bhv_thi_bowling_ball_spawner_loop(void) {
if (o->oSyncID == 0) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_object_settings(o, FALSE, 0, TRUE);
network_object_settings(o, FALSE, 0, TRUE, NULL);
}
struct Object *bowlingBall;
@ -254,7 +254,7 @@ void bhv_bob_pit_bowling_ball_init(void) {
o->oBuoyancy = 2.0f;
network_init_object(o, 5000.0f);
network_object_settings(o, FALSE, 5.0f, TRUE);
network_object_settings(o, FALSE, 5.0f, TRUE, NULL);
}
void bhv_bob_pit_bowling_ball_loop(void) {

View file

@ -19,18 +19,24 @@ void opened_cannon_act_0(void) {
}
cur_obj_become_tangible();
cur_obj_enable_rendering();
if (o->oDistanceToMario < 500.0f) {
struct Object* player = nearest_player_to_object(o);
int distanceToPlayer = dist_between_objects(o, player);
if (distanceToPlayer < 500.0f) {
//cur_obj_become_tangible();
//cur_obj_enable_rendering();
if (o->oInteractStatus & INT_STATUS_INTERACTED
&& (!(o->oInteractStatus
& INT_STATUS_TOUCHED_BOB_OMB))) // bob-omb explodes when it gets into a cannon
{
o->oAction = 4;
o->oCannonUnk10C = 1;
o->oCannonUnkF8 = 1;
} else
o->oInteractStatus = 0;
if (player == gMarioState[0].marioObj) {
if (o->oInteractStatus & INT_STATUS_INTERACTED && (!(o->oInteractStatus & INT_STATUS_TOUCHED_BOB_OMB))) { // bob-omb explodes when it gets into a cannon
o->oAction = 4;
o->oCannonUnk10C = 1;
o->oCannonUnkF8 = 1;
o->oCannonIsLocal = TRUE;
network_send_object(o);
} else {
o->oInteractStatus = 0;
}
}
} else {
//cur_obj_become_intangible();
//cur_obj_disable_rendering();
@ -49,6 +55,11 @@ void opened_cannon_act_4(void) {
o->oPosZ += (f32)((o->oTimer / 2 & 1) - 0.5) * 4;
o->oAction = 6;
}
if (!o->oCannonIsLocal) {
// two-player hack
gMarioStates[1].marioObj->oMarioCannonObjectYaw = o->oMoveAngleYaw;
gMarioStates[1].marioObj->oMarioCannonInputYaw = 0;
}
}
void opened_cannon_act_6(void) {
@ -61,11 +72,21 @@ void opened_cannon_act_6(void) {
if (o->oTimer < 6) {
} else {
if (o->oTimer < 22) {
o->oMoveAngleYaw =
sins(o->oCannonUnkF4) * 0x4000 + ((s16)(o->oBehParams2ndByte << 8));
o->oMoveAngleYaw = sins(o->oCannonUnkF4) * 0x4000 + ((s16)(o->oBehParams2ndByte << 8));
o->oCannonUnkF4 += 0x400;
} else if (o->oTimer < 26) {
} else {
if (o->oCannonIsLocal) {
gMarioStates[0].marioObj->oMarioCannonObjectYaw = o->oMoveAngleYaw;
gMarioStates[0].marioObj->oMarioCannonInputYaw = 0;
gMarioStates[0].faceAngle[0] = 8192;
} else {
// two-player hack
gMarioStates[1].marioObj->oMarioCannonObjectYaw = o->oMoveAngleYaw;
gMarioStates[1].marioObj->oMarioCannonInputYaw = 0;
gMarioStates[1].faceAngle[0] = 8192;
}
o->oCannonUnkF4 = 0;
o->oAction = 5;
}
@ -82,15 +103,22 @@ void opened_cannon_act_5(void) {
o->oCannonUnkF4 += 0x400;
o->oMoveAnglePitch = sins(o->oCannonUnkF4) * 0x2000;
} else if (o->oTimer < 25) {
} else
} else {
o->oAction = 1;
}
}
}
void opened_cannon_act_1(void) {
UNUSED s32 unused;
cur_obj_become_intangible();
cur_obj_disable_rendering();
if (o->oCannonIsLocal) { // two-player hack
cur_obj_become_intangible();
cur_obj_disable_rendering();
} else {
struct MarioState* marioState = &gMarioStates[1]; // two-player hack
o->oMoveAnglePitch = 14563 + marioState->faceAngle[0] * -0.5f;
o->oMoveAngleYaw = marioState->marioObj->oMarioCannonObjectYaw + marioState->marioObj->oMarioCannonInputYaw;
}
o->oCannonUnk10C = 0;
gMarioShotFromCannon = 1;
}
@ -101,8 +129,11 @@ void opened_cannon_act_2(void) {
void opened_cannon_act_3(void) {
UNUSED s32 unused;
if (o->oTimer > 3)
if (o->oTimer > 3) {
o->oAction = 0;
o->oCannonIsLocal = FALSE;
if (o->heldByPlayerIndex == 0) { network_send_object(o); }
}
}
void (*sOpenedCannonActions[])(void) = { opened_cannon_act_0, opened_cannon_act_1, opened_cannon_act_2,
@ -113,7 +144,23 @@ u8 unused0EA1FC[] = { 2, 0, 0, 0, 0, 0, 0, 0, 63, 128, 0, 0, 2, 0, 0, 0
63, 128, 0, 0, 2, 0, 0, 0, 65, 160, 0, 0, 63, 128, 0, 0, 2, 0, 0, 0,
65, 160, 0, 0, 63, 128, 0, 0, 8, 0, 0, 0, 65, 32, 0, 0, 63, 128, 0, 0 };
u8 cannon_ignore_remote_updates(struct Object* object) { return object->oCannonIsLocal; }
void bhv_cannon_base_loop(void) {
if (o->oSyncID == 0) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_object_settings(o, FALSE, 0, FALSE, &cannon_ignore_remote_updates);
network_init_object_field(o, &o->oAction);
network_init_object_field(o, &o->oTimer);
network_init_object_field(o, &o->oCannonUnk10C);
network_init_object_field(o, &o->oCannonUnkF8);
network_init_object_field(o, &o->oCannonUnkF4);
}
if (o->oAction != 0 && !o->oCannonIsLocal) {
cur_obj_push_mario_away_from_cylinder(220, 300);
}
cur_obj_call_action_function(sOpenedCannonActions);
if (o->oCannonUnkF8)
o->oCannonUnkF8++;

View file

@ -528,7 +528,7 @@ void bhv_wooden_post_update(void) {
if ((o->oWoodenPostMarioPounding = cur_obj_is_mario_ground_pounding_platform())) {
cur_obj_play_sound_2(SOUND_GENERAL_POUND_WOOD_POST);
o->oWoodenPostSpeedY = -70.0f;
if (network_owns_object(o)) { network_send_object(o); }
network_send_object(o);
}
} else if (approach_f32_ptr(&o->oWoodenPostSpeedY, 0.0f, 25.0f)) {
// Stay still until mario is done ground pounding
@ -559,7 +559,7 @@ void bhv_wooden_post_update(void) {
// coins
o->oWoodenPostTotalMarioAngle += (s16)(angleToPlayer - o->oWoodenPostPrevAngleToMario);
if (absi(o->oWoodenPostTotalMarioAngle) > 0x30000 && o->oTimer < 200) {
if (network_owns_object(o)) { network_send_object(o); }
network_send_object(o);
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
set_object_respawn_info_bits(o, 1);
}

View file

@ -46,7 +46,7 @@ void checkerboard_plat_act_rotate(s32 a0, s16 a1) {
void bhv_checkerboard_platform_init(void) {
o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte;
network_init_object(o, 1000.0f);
network_object_settings(o, TRUE, 5.0f, TRUE);
network_object_settings(o, TRUE, 5.0f, TRUE, NULL);
}
void bhv_checkerboard_platform_loop(void) {

View file

@ -9,6 +9,8 @@
void bhv_purple_switch_loop(void) {
if (o->oSyncID == 0) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_init_object_field(o, &o->oAction);
network_init_object_field(o, &o->oTimer);
}
u8 anyPlayerOnPlatform = FALSE;
@ -76,6 +78,7 @@ void bhv_purple_switch_loop(void) {
cur_obj_scale_over_time(2, 3, 0.2f, 1.5f);
if (o->oTimer == 3) {
o->oAction = PURPLE_SWITCH_IDLE;
network_send_object(o);
}
break;
/**

View file

@ -33,7 +33,7 @@ void bhv_water_bomb_spawner_update(void) {
network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS);
network_init_object_field(o, &o->oWaterBombSpawnerBombActive);
network_init_object_field(o, &o->oWaterBombSpawnerTimeToSpawn);
network_object_settings(o, FALSE, 0, TRUE);
network_object_settings(o, FALSE, 0, TRUE, NULL);
}
f32 latDistToMario = 9999;

View file

@ -1092,6 +1092,8 @@ u32 interact_door(struct MarioState *m, UNUSED u32 interactType, struct Object *
}
u32 interact_cannon_base(struct MarioState *m, UNUSED u32 interactType, struct Object *o) {
if (o->oAction != 0) { return; }
if (m->action != ACT_IN_CANNON) {
mario_stop_riding_and_holding(m);
o->oInteractStatus = INT_STATUS_INTERACTED;

View file

@ -1648,7 +1648,10 @@ s32 act_jump_kick(struct MarioState *m) {
}
s32 act_shot_from_cannon(struct MarioState *m) {
if (m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
// only allow for local player
u8 allowCameraChange = (m == &gMarioStates[0]);
if (allowCameraChange && m->area->camera->mode != CAMERA_MODE_BEHIND_MARIO) {
m->statusForCamera->cameraEvent = CAM_EVENT_SHOT_FROM_CANNON;
}
@ -1667,14 +1670,16 @@ s32 act_shot_from_cannon(struct MarioState *m) {
set_mario_action(m, ACT_DIVE_SLIDE, 0);
m->faceAngle[0] = 0;
#ifndef BETTERCAMERA
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
if (allowCameraChange) { set_camera_mode(m->area->camera, m->area->camera->defMode, 1); }
#else
if (newcam_active == 0)
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
else
{
m->area->camera->mode = CAMERA_MODE_NEWCAM;
gLakituState.mode = CAMERA_MODE_NEWCAM;
if (allowCameraChange) {
if (newcam_active == 0)
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
else
{
m->area->camera->mode = CAMERA_MODE_NEWCAM;
gLakituState.mode = CAMERA_MODE_NEWCAM;
}
}
#endif
queue_rumble_data(5, 80);
@ -1691,14 +1696,16 @@ s32 act_shot_from_cannon(struct MarioState *m) {
m->particleFlags |= PARTICLE_VERTICAL_STAR;
set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
#ifndef BETTERCAMERA
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
if (allowCameraChange) { set_camera_mode(m->area->camera, m->area->camera->defMode, 1); }
#else
if (newcam_active == 0)
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
else
{
m->area->camera->mode = CAMERA_MODE_NEWCAM;
gLakituState.mode = CAMERA_MODE_NEWCAM;
if (allowCameraChange) {
if (newcam_active == 0)
set_camera_mode(m->area->camera, m->area->camera->defMode, 1);
else
{
m->area->camera->mode = CAMERA_MODE_NEWCAM;
gLakituState.mode = CAMERA_MODE_NEWCAM;
}
}
#endif
break;

View file

@ -673,80 +673,84 @@ s32 act_in_cannon(struct MarioState *m) {
s16 startFacePitch = m->faceAngle[0];
s16 startFaceYaw = m->faceAngle[1];
switch (m->actionState) {
case 0:
m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
m->usedObj->oInteractStatus = INT_STATUS_INTERACTED;
if (m->usedObj != NULL) {
switch (m->actionState) {
case 0:
m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
m->usedObj->oInteractStatus = INT_STATUS_INTERACTED;
m->statusForCamera->cameraEvent = CAM_EVENT_CANNON;
m->statusForCamera->usedObj = m->usedObj;
m->statusForCamera->cameraEvent = CAM_EVENT_CANNON;
m->statusForCamera->usedObj = m->usedObj;
vec3f_set(m->vel, 0.0f, 0.0f, 0.0f);
vec3f_set(m->vel, 0.0f, 0.0f, 0.0f);
m->pos[0] = m->usedObj->oPosX;
m->pos[1] = m->usedObj->oPosY + 350.0f;
m->pos[2] = m->usedObj->oPosZ;
m->pos[0] = m->usedObj->oPosX;
m->pos[1] = m->usedObj->oPosY + 350.0f;
m->pos[2] = m->usedObj->oPosZ;
m->forwardVel = 0.0f;
m->forwardVel = 0.0f;
m->actionState = 1;
break;
m->actionState = 1;
break;
case 1:
if (m->usedObj->oAction == 1) {
m->faceAngle[0] = m->usedObj->oMoveAnglePitch;
m->faceAngle[1] = m->usedObj->oMoveAngleYaw;
case 1:
if (m->usedObj->oAction == 1) {
m->faceAngle[0] = m->usedObj->oMoveAnglePitch;
m->faceAngle[1] = m->usedObj->oMoveAngleYaw;
marioObj->oMarioCannonObjectYaw = m->usedObj->oMoveAngleYaw;
marioObj->oMarioCannonInputYaw = 0;
marioObj->oMarioCannonObjectYaw = m->usedObj->oMoveAngleYaw;
marioObj->oMarioCannonInputYaw = 0;
m->actionState = 2;
}
break;
case 2:
m->faceAngle[0] -= (s16)(m->controller->stickY * 10.0f);
marioObj->oMarioCannonInputYaw -= (s16)(m->controller->stickX * 10.0f);
if (m->faceAngle[0] > 0x38E3) {
m->faceAngle[0] = 0x38E3;
}
if (m->faceAngle[0] < 0) {
m->faceAngle[0] = 0;
}
if (marioObj->oMarioCannonInputYaw > 0x4000) {
marioObj->oMarioCannonInputYaw = 0x4000;
}
if (marioObj->oMarioCannonInputYaw < -0x4000) {
marioObj->oMarioCannonInputYaw = -0x4000;
}
m->faceAngle[1] = marioObj->oMarioCannonObjectYaw + marioObj->oMarioCannonInputYaw;
if (m->input & INPUT_A_PRESSED) {
m->forwardVel = 100.0f * coss(m->faceAngle[0]);
m->vel[1] = 100.0f * sins(m->faceAngle[0]);
m->pos[0] += 120.0f * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
m->pos[1] += 120.0f * sins(m->faceAngle[0]);
m->pos[2] += 120.0f * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
play_sound(SOUND_ACTION_FLYING_FAST, m->marioObj->header.gfx.cameraToObject);
play_sound(SOUND_OBJ_POUNDING_CANNON, m->marioObj->header.gfx.cameraToObject);
m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
set_mario_action(m, ACT_SHOT_FROM_CANNON, 0);
queue_rumble_data(60, 70);
m->usedObj->oAction = 2;
return FALSE;
} else {
if (m->faceAngle[0] != startFacePitch || m->faceAngle[1] != startFaceYaw) {
play_sound(SOUND_MOVING_AIM_CANNON, m->marioObj->header.gfx.cameraToObject);
reset_rumble_timers_2(0);
m->actionState = 2;
}
}
break;
case 2:
m->faceAngle[0] -= (s16)(m->controller->stickY * 10.0f);
marioObj->oMarioCannonInputYaw -= (s16)(m->controller->stickX * 10.0f);
if (m->faceAngle[0] > 0x38E3) {
m->faceAngle[0] = 0x38E3;
}
if (m->faceAngle[0] < 0) {
m->faceAngle[0] = 0;
}
if (marioObj->oMarioCannonInputYaw > 0x4000) {
marioObj->oMarioCannonInputYaw = 0x4000;
}
if (marioObj->oMarioCannonInputYaw < -0x4000) {
marioObj->oMarioCannonInputYaw = -0x4000;
}
m->faceAngle[1] = marioObj->oMarioCannonObjectYaw + marioObj->oMarioCannonInputYaw;
extern struct MarioState gMarioStates[];
if (m->input & INPUT_A_PRESSED && m == &gMarioStates[0]) {
m->forwardVel = 100.0f * coss(m->faceAngle[0]);
m->vel[1] = 100.0f * sins(m->faceAngle[0]);
m->pos[0] += 120.0f * coss(m->faceAngle[0]) * sins(m->faceAngle[1]);
m->pos[1] += 120.0f * sins(m->faceAngle[0]);
m->pos[2] += 120.0f * coss(m->faceAngle[0]) * coss(m->faceAngle[1]);
play_sound(SOUND_ACTION_FLYING_FAST, m->marioObj->header.gfx.cameraToObject);
play_sound(SOUND_OBJ_POUNDING_CANNON, m->marioObj->header.gfx.cameraToObject);
m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_ACTIVE;
set_mario_action(m, ACT_SHOT_FROM_CANNON, 0);
queue_rumble_data(60, 70);
m->usedObj->oAction = 2;
return FALSE;
} else {
if (m->faceAngle[0] != startFacePitch || m->faceAngle[1] != startFaceYaw) {
play_sound(SOUND_MOVING_AIM_CANNON, m->marioObj->header.gfx.cameraToObject);
reset_rumble_timers_2(0);
}
}
}
}
vec3f_copy(m->marioObj->header.gfx.pos, m->pos);

View file

@ -2257,8 +2257,17 @@ void cur_obj_push_mario_away_from_cylinder(f32 radius, f32 extentY) {
marioRelY = -marioRelY;
}
if (marioRelY < extentY) {
cur_obj_push_mario_away(radius);
if (marioRelY >= extentY) { continue; }
f32 marioRelX = player->oPosX - o->oPosX;
f32 marioRelZ = player->oPosZ - o->oPosZ;
f32 marioDist = sqrtf(sqr(marioRelX) + sqr(marioRelZ));
if (marioDist < radius) {
//! If this function pushes Mario out of bounds, it will trigger Mario's
// oob failsafe
gMarioStates[i].pos[0] += (radius - marioDist) / radius * marioRelX;
gMarioStates[i].pos[2] += (radius - marioDist) / radius * marioRelZ;
}
}
}

View file

@ -46,6 +46,7 @@ struct SyncObject {
bool fullObjectSync;
bool keepRandomSeed;
float maxUpdateRate;
u8 (*ignore_if_true)(struct Object*);
void* extraFields[MAX_SYNC_OBJECT_FIELDS];
};
@ -57,7 +58,7 @@ extern struct SyncObject syncObjects[];
void network_init(enum NetworkType networkType);
void network_init_object(struct Object *object, float maxSyncDistance);
void network_object_settings(struct Object *object, bool fullObjectSync, float maxUpdateRate, bool keepRandomSeed);
void network_object_settings(struct Object *object, bool fullObjectSync, float maxUpdateRate, bool keepRandomSeed, u8 ignore_if_true(struct Object*));
void network_send(struct Packet* p);
void network_update(void);
void network_shutdown(void);

View file

@ -29,15 +29,17 @@ void network_init_object(struct Object *o, float maxSyncDistance) {
so->fullObjectSync = false;
so->keepRandomSeed = false;
so->maxUpdateRate = 0;
so->ignore_if_true = NULL;
memset(so->extraFields, 0, sizeof(void*) * MAX_SYNC_OBJECT_FIELDS);
}
void network_object_settings(struct Object *o, bool fullObjectSync, float maxUpdateRate, bool keepRandomSeed) {
void network_object_settings(struct Object *o, bool fullObjectSync, float maxUpdateRate, bool keepRandomSeed, u8 ignore_if_true(struct Object*)) {
assert(o->oSyncID != 0);
struct SyncObject* so = &syncObjects[o->oSyncID];
so->fullObjectSync = fullObjectSync;
so->maxUpdateRate = maxUpdateRate;
so->keepRandomSeed = keepRandomSeed;
so->ignore_if_true = ignore_if_true;
}
void network_init_object_field(struct Object *o, void* field) {
@ -65,19 +67,25 @@ void network_send_object(struct Object* o) {
packet_write(&p, &o->oSyncID, 4);
packet_write(&p, &so->onEventId, sizeof(u16));
packet_write(&p, &so->behavior, sizeof(void*));
packet_write(&p, &o->activeFlags, sizeof(s16));
packet_write(&p, &o->header.gfx.node.flags, sizeof(s16));
if (so->maxSyncDistance != SYNC_DISTANCE_ONLY_EVENTS) {
packet_write(&p, &o->activeFlags, sizeof(s16));
packet_write(&p, &o->header.gfx.node.flags, sizeof(s16));
}
if (so->fullObjectSync) {
packet_write(&p, o->rawData.asU32, sizeof(u32) * 80);
} else {
packet_write(&p, &o->oPosX, sizeof(u32) * 7);
packet_write(&p, &o->oAction, sizeof(u32));
packet_write(&p, &o->oSubAction, sizeof(u32));
packet_write(&p, &o->oInteractStatus, sizeof(u32));
packet_write(&p, &o->oHeldState, sizeof(u32));
packet_write(&p, &o->oMoveAngleYaw, sizeof(u32));
packet_write(&p, &o->oTimer, sizeof(u32));
if (so->maxSyncDistance != SYNC_DISTANCE_ONLY_EVENTS) {
packet_write(&p, &o->oPosX, sizeof(u32) * 7);
packet_write(&p, &o->oAction, sizeof(u32));
packet_write(&p, &o->oSubAction, sizeof(u32));
packet_write(&p, &o->oInteractStatus, sizeof(u32));
packet_write(&p, &o->oHeldState, sizeof(u32));
packet_write(&p, &o->oMoveAngleYaw, sizeof(u32));
packet_write(&p, &o->oTimer, sizeof(u32));
}
packet_write(&p, &so->extraFieldCount, sizeof(u8));
for (int i = 0; i < so->extraFieldCount; i++) {
@ -108,6 +116,7 @@ void network_receive_object(struct Packet* p) {
// retrieve SyncObject
struct SyncObject* so = &syncObjects[syncId];
so->clockSinceUpdate = clock();
if (so->ignore_if_true != NULL && (*so->ignore_if_true)(so->o)) { return; }
// extract Object
struct Object* o = syncObjects[syncId].o;
@ -148,28 +157,34 @@ void network_receive_object(struct Packet* p) {
}
// write object flags
packet_read(p, &o->activeFlags, sizeof(u16));
packet_read(p, &o->header.gfx.node.flags, sizeof(s16));
if (so->maxSyncDistance != SYNC_DISTANCE_ONLY_EVENTS) {
packet_read(p, &o->activeFlags, sizeof(u16));
packet_read(p, &o->header.gfx.node.flags, sizeof(s16));
}
if (so->fullObjectSync) {
packet_read(p, o->rawData.asU32, sizeof(u32) * 80);
} else {
packet_read(p, &o->oPosX, sizeof(u32) * 7);
packet_read(p, &o->oAction, sizeof(u32));
packet_read(p, &o->oSubAction, sizeof(u32));
packet_read(p, &o->oInteractStatus, sizeof(u32));
packet_read(p, &o->oHeldState, sizeof(u32));
packet_read(p, &o->oMoveAngleYaw, sizeof(u32));
packet_read(p, &o->oTimer, sizeof(u32));
}
// write extra fields
u8 extraFields = 0;
packet_read(p, &extraFields, sizeof(u8));
assert(extraFields == so->extraFieldCount);
for (int i = 0; i < extraFields; i++) {
assert(so->extraFields[i] != NULL);
packet_read(p, so->extraFields[i], sizeof(u32));
if (so->maxSyncDistance != SYNC_DISTANCE_ONLY_EVENTS) {
packet_read(p, &o->oPosX, sizeof(u32) * 7);
packet_read(p, &o->oAction, sizeof(u32));
packet_read(p, &o->oSubAction, sizeof(u32));
packet_read(p, &o->oInteractStatus, sizeof(u32));
packet_read(p, &o->oHeldState, sizeof(u32));
packet_read(p, &o->oMoveAngleYaw, sizeof(u32));
packet_read(p, &o->oTimer, sizeof(u32));
}
// write extra fields
u8 extraFields = 0;
packet_read(p, &extraFields, sizeof(u8));
assert(extraFields == so->extraFieldCount);
for (int i = 0; i < extraFields; i++) {
assert(so->extraFields[i] != NULL);
packet_read(p, so->extraFields[i], sizeof(u32));
}
}
// deactivated