diff --git a/code/network/multi_interpolate.cpp b/code/network/multi_interpolate.cpp index fd9cd2949aa..537dd43e9ab 100644 --- a/code/network/multi_interpolate.cpp +++ b/code/network/multi_interpolate.cpp @@ -165,8 +165,10 @@ void interpolation_manager::interpolate_main(vec3d* pos, matrix* ori, physics_in // correct the ship record for player ships when an up to date packet comes in. void interpolation_manager::reinterpolate_previous(TIMESTAMP stamp, int prev_packet_index, int next_packet_index, vec3d& position, matrix& orientation, vec3d& velocity, vec3d& rotational_velocity) { - // calc what the timing was previously. - float numerator = static_cast(stamp.value()) - static_cast(_packets[prev_packet_index].remote_missiontime); + // calc what the timing was previously. The caller hands us an absolute timestamp, + // but remote_missiontime is relative to mission start, so drop the start time before comparing. + float local_time = static_cast(stamp.value() - Multi_Timing_Info.get_mission_start_time()); + float numerator = local_time - static_cast(_packets[prev_packet_index].remote_missiontime); float denominator = static_cast(_packets[next_packet_index].remote_missiontime) - static_cast(_packets[prev_packet_index].remote_missiontime); denominator = (denominator > 0.05f) ? denominator : 0.05f; diff --git a/code/network/multi_obj.cpp b/code/network/multi_obj.cpp index 760b31af85b..10306310f83 100644 --- a/code/network/multi_obj.cpp +++ b/code/network/multi_obj.cpp @@ -1223,6 +1223,17 @@ int multi_oo_pack_client_data(ubyte *data, ship* shipp) return packet_size; } +// vm_extract_angles_matrix_alternate returns angles in the range -PI..PI, but the subsystem list packer +// encodes them as an unsigned fraction of a full rotation, so wrap negatives around before sending. +static float multi_oo_normalized_angle(float angle) +{ + if (angle < 0.0f) { + angle += PI2; + } + + return angle / PI2; +} + // pack the appropriate info into the data #define PACK_PERCENT(v) { std::uint8_t upercent; if(v < 0.0f){v = 0.0f;} upercent = (v * 255.0f) <= 255.0f ? (std::uint8_t)(v * 255.0f) : (std::uint8_t)255; memcpy(data + packet_size + header_bytes, &upercent, sizeof(std::uint8_t)); packet_size++; } #define PACK_BYTE(v) { memcpy( data + packet_size + header_bytes, &v, 1 ); packet_size += 1; } @@ -1411,32 +1422,32 @@ int multi_oo_pack_data(net_player *pl, object *objp, ushort oo_flags, ubyte *dat // here we're checking to see if the subsystems rotated enough to send. if (angs_1 != nullptr && angs_1->b != Oo_info.player_frame_info[pl->player_id].last_sent[objp->net_signature].subsystem_1b[i]) { flags[i] |= OO_SUBSYS_ROTATION_1b; - subsys_data.push_back(angs_1->b / PI2); + subsys_data.push_back(multi_oo_normalized_angle(angs_1->b)); } if (angs_1 != nullptr && angs_1->h != Oo_info.player_frame_info[pl->player_id].last_sent[objp->net_signature].subsystem_1h[i]) { flags[i] |= OO_SUBSYS_ROTATION_1h; - subsys_data.push_back(angs_1->h / PI2); + subsys_data.push_back(multi_oo_normalized_angle(angs_1->h)); } if (angs_1 != nullptr && angs_1->p != Oo_info.player_frame_info[pl->player_id].last_sent[objp->net_signature].subsystem_1p[i]) { flags[i] |= OO_SUBSYS_ROTATION_1p; - subsys_data.push_back(angs_1->p / PI2); + subsys_data.push_back(multi_oo_normalized_angle(angs_1->p)); } if (angs_2 != nullptr && angs_2->b != Oo_info.player_frame_info[pl->player_id].last_sent[objp->net_signature].subsystem_2b[i]) { flags[i] |= OO_SUBSYS_ROTATION_2b; - subsys_data.push_back(angs_2->b / PI2); + subsys_data.push_back(multi_oo_normalized_angle(angs_2->b)); } if (angs_2 != nullptr && angs_2->h != Oo_info.player_frame_info[pl->player_id].last_sent[objp->net_signature].subsystem_2h[i]) { flags[i] |= OO_SUBSYS_ROTATION_2h; - subsys_data.push_back(angs_2->h / PI2); + subsys_data.push_back(multi_oo_normalized_angle(angs_2->h)); } if (angs_2 != nullptr && angs_2->p != Oo_info.player_frame_info[pl->player_id].last_sent[objp->net_signature].subsystem_2p[i]) { flags[i] |= OO_SUBSYS_ROTATION_2p; - subsys_data.push_back(angs_2->p / PI2); + subsys_data.push_back(multi_oo_normalized_angle(angs_2->p)); } // clang says deleting null pointer has no effect @@ -1600,8 +1611,8 @@ int multi_oo_unpack_client_data(net_player* pl, ubyte* data, bool keep_data) int offset = 0; - // read flag info - ushort in_flags; + // read flag info -- this is packed as a single byte, so it must be read back as one + ubyte in_flags; memcpy(&in_flags, data, sizeof(ubyte)); offset++; @@ -1895,7 +1906,7 @@ int multi_oo_unpack_data(net_player* pl, ubyte* data, int seq_num, int time_delt full_physics = true; } - int r5 = multi_pack_unpack_desired_vel_and_desired_rotvel(0, full_physics, data + offset, &pobjp->phys_info, &local_desired_vel); + int r5 = multi_pack_unpack_desired_vel_and_desired_rotvel(0, full_physics, data + offset, &new_phys_info, &local_desired_vel); offset += r5; // change it back to global coordinates. vm_vec_unrotate(&new_phys_info.desired_vel, &local_desired_vel, &new_orient); diff --git a/code/network/multimsgs.cpp b/code/network/multimsgs.cpp index e7b5d9a677d..dafeb087ea3 100644 --- a/code/network/multimsgs.cpp +++ b/code/network/multimsgs.cpp @@ -2646,7 +2646,7 @@ void process_ship_kill_packet( ubyte *data, header *hinfo ) } // maybe set wash_killed - if (extra_death_info & EXTRA_DEATH_VAPORIZED) { + if (extra_death_info & EXTRA_DEATH_WASHED) { Ships[sobjp->instance].wash_killed = 1; } @@ -7633,7 +7633,8 @@ void process_homing_weapon_info( ubyte *data, header *hinfo ) } if (flags & HWIF_BIG_UPDATE) { - wp->creation_time = Missiontime + missile_lifetime; + // the sender packed the missile's age, so walk creation_time back from now to recover it + wp->creation_time = Missiontime - missile_lifetime; weapon_objp->pos = missile_pos; weapon_objp->orient = orient_in; wp->launch_speed = launch_speed; diff --git a/code/network/multiutil.cpp b/code/network/multiutil.cpp index d9deec24046..47f6a014913 100644 --- a/code/network/multiutil.cpp +++ b/code/network/multiutil.cpp @@ -3625,9 +3625,9 @@ int multi_pack_unpack_desired_vel_and_desired_rotvel( int write, bool full_physi a = bitbuffer_get_signed(&buf,5); b = bitbuffer_get_signed(&buf,5); c = bitbuffer_get_signed(&buf,5); - pi->rotvel.xyz.x = pi->max_rotvel.xyz.x * i2fl(a)/15.0f; - pi->rotvel.xyz.y = pi->max_rotvel.xyz.y * i2fl(b)/15.0f; - pi->rotvel.xyz.z = pi->max_rotvel.xyz.z * i2fl(c)/15.0f; + pi->desired_rotvel.xyz.x = pi->max_rotvel.xyz.x * i2fl(a)/15.0f; + pi->desired_rotvel.xyz.y = pi->max_rotvel.xyz.y * i2fl(b)/15.0f; + pi->desired_rotvel.xyz.z = pi->max_rotvel.xyz.z * i2fl(c)/15.0f; }