void simulation_receiver::drag_mispredictions_into_past(interpolation_system& interp, past_infection_system& past, const cosmos& predicted_cosmos, const std::vector<misprediction_candidate_entry>& mispredictions) const { for (const auto e : mispredictions) { const const_entity_handle reconciliated_entity = predicted_cosmos[e.id]; const bool identity_matches = reconciliated_entity.alive() && reconciliated_entity.has_logic_transform(); if (!identity_matches) continue; const auto& reconciliated_transform = reconciliated_entity.logic_transform(); const bool is_contagious_agent = reconciliated_entity.get_flag(entity_flag::IS_PAST_CONTAGIOUS); const bool should_smooth_rotation = !is_contagious_agent || predicted_cosmos[reconciliated_entity.get<components::driver>().owned_vehicle].alive(); auto& interp_data = interp.get_data(reconciliated_entity); const bool shouldnt_smooth = reconciliated_entity.has<components::crosshair>(); bool misprediction_detected = false; const float num_predicted_steps = static_cast<float>(predicted_steps.size()); if (!shouldnt_smooth && (reconciliated_transform.pos - e.transform.pos).length_sq() > 1.f) { interp_data.positional_slowdown_multiplier = std::max(1.f, misprediction_smoothing_multiplier * num_predicted_steps); misprediction_detected = true; } if (should_smooth_rotation && std::abs(reconciliated_transform.rotation - e.transform.rotation) > 1.f) { interp_data.rotational_slowdown_multiplier = std::max(1.f, misprediction_smoothing_multiplier * num_predicted_steps); misprediction_detected = true; } if (identity_matches || (!misprediction_detected && !is_contagious_agent)) { past.uninfect(reconciliated_entity); } } }
bool physics_system::is_constructed_colliders(const const_entity_handle handle) const { return handle.alive() // && is_constructed_rigid_body(handle.get<components::fixtures>().get_owner_body()) && get_colliders_cache(handle).fixtures_per_collider.size()> 0 && get_colliders_cache(handle).fixtures_per_collider[0].size() > 0; }
entity_id get_closest_hostile( const const_entity_handle subject, const const_entity_handle subject_attitude, const real32 radius, const b2Filter filter ) { const auto& cosm = subject.get_cosmos(); const auto si = cosm.get_si(); const auto& physics = cosm.get_solvable_inferred().physics; const auto transform = subject.get_logic_transform(); entity_id closest_hostile; auto min_distance = std::numeric_limits<real32>::max(); if (subject_attitude.alive()) { const auto subject_attitude_transform = subject_attitude.get_logic_transform(); physics.for_each_in_aabb( si, transform.pos - vec2(radius, radius), transform.pos + vec2(radius, radius), filter, [&](const b2Fixture& fix) { const const_entity_handle s = cosm[get_body_entity_that_owns(fix)]; if (s != subject && s.has<components::attitude>() && !sentient_and_unconscious(s)) { const auto calculated_attitude = calc_attitude(s, subject_attitude); if (is_hostile(calculated_attitude)) { const auto dist = (s.get_logic_transform().pos - subject_attitude_transform.pos).length_sq(); if (dist < min_distance) { closest_hostile = s; min_distance = dist; } } } return callback_result::CONTINUE; } ); } return closest_hostile; }
std::vector<entity_id> get_closest_hostiles( const const_entity_handle subject, const const_entity_handle subject_attitude, const real32 radius, const b2Filter filter ) { const auto& cosm = subject.get_cosmos(); const auto si = cosm.get_si(); const auto& physics = cosm.get_solvable_inferred().physics; const auto transform = subject.get_logic_transform(); struct hostile_entry { entity_id s; real32 dist = 0.f; bool operator<(const hostile_entry& b) const { return dist < b.dist; } bool operator==(const hostile_entry& b) const { return s == b.s; } operator entity_id() const { return s; } }; std::vector<hostile_entry> hostiles; if (subject_attitude.alive()) { const auto subject_attitude_transform = subject_attitude.get_logic_transform(); physics.for_each_in_aabb( si, transform.pos - vec2(radius, radius), transform.pos + vec2(radius, radius), filter, [&](const b2Fixture& fix) { const const_entity_handle s = cosm[get_body_entity_that_owns(fix)]; if (s != subject && s.has<components::attitude>()) { const auto calculated_attitude = calc_attitude(s, subject_attitude); if (is_hostile(calculated_attitude)) { const auto dist = (s.get_logic_transform().pos - subject_attitude_transform.pos).length_sq(); hostile_entry new_entry; new_entry.s = s; new_entry.dist = dist; hostiles.push_back(new_entry); } } return callback_result::CONTINUE; } ); } sort_range(hostiles); remove_duplicates_from_sorted(hostiles); return { hostiles.begin(), hostiles.end() }; }
bool physics_system::is_constructed_rigid_body(const const_entity_handle handle) const { return handle.alive() && get_rigid_body_cache(handle).body != nullptr; }
void draw_crosshair_lines( std::function<void(vec2, vec2, rgba)> callback, std::function<void(vec2, vec2)> dashed_line_callback, const interpolation_system& interp, const const_entity_handle crosshair, const const_entity_handle character) { if (crosshair.alive()) { const auto& cosmos = crosshair.get_cosmos(); const auto& physics = cosmos.systems_temporary.get<physics_system>(); vec2 line_from[2]; vec2 line_to[2]; const auto crosshair_pos = crosshair.viewing_transform(interp).pos; const auto guns = character.guns_wielded(); auto calculate_color = [&](const const_entity_handle target) { const auto att = calculate_attitude(character, target); if (att == attitude_type::WANTS_TO_KILL || att == attitude_type::WANTS_TO_KNOCK_UNCONSCIOUS) { return red; } else if (att == attitude_type::WANTS_TO_HEAL) { return green; } else { return cyan; } }; if (guns.size() >= 1) { const auto subject_item = guns[0]; const auto& gun = subject_item.get<components::gun>(); const auto rifle_transform = subject_item.viewing_transform(interp); const auto barrel_center = gun.calculate_barrel_center(rifle_transform); const auto muzzle = gun.calculate_muzzle_position(rifle_transform); line_from[0] = muzzle; const auto proj = crosshair_pos.get_projection_multiplier(barrel_center, muzzle); if (proj > 1.f) { line_to[0] = barrel_center + (muzzle - barrel_center) * proj; const auto raycast = physics.ray_cast_px(line_from[0], line_to[0], filters::bullet(), subject_item); auto col = cyan; if (raycast.hit) { dashed_line_callback(raycast.intersection, line_to[0]); line_to[0] = raycast.intersection; col = calculate_color(cosmos[raycast.what_entity]); } callback(line_from[0], line_to[0], col); } } if (guns.size() >= 2) { const auto subject_item = guns[1]; const auto& gun = subject_item.get<components::gun>(); const auto rifle_transform = subject_item.viewing_transform(interp); const auto barrel_center = gun.calculate_barrel_center(rifle_transform); const auto muzzle = gun.calculate_muzzle_position(rifle_transform); line_from[1] = muzzle; const auto proj = crosshair_pos.get_projection_multiplier(barrel_center, muzzle); if (proj > 1.f) { line_to[1] = barrel_center + (muzzle - barrel_center) * proj; const auto raycast = physics.ray_cast_px(line_from[1], line_to[1], filters::bullet(), subject_item); auto col = cyan; if (raycast.hit) { dashed_line_callback(raycast.intersection, line_to[1]); line_to[1] = raycast.intersection; col = calculate_color(cosmos[raycast.what_entity]); } callback(line_from[1], line_to[1], col); } } } }