From e64cd5b8a1dc38943cf71c5e6747fce0d5c7f1f7 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Fri, 31 Jan 2025 17:16:47 +0100 Subject: [PATCH] Start to make vehicle coordinates make sense --- src/activity_item_handling.cpp | 4 +- src/avatar.cpp | 6 +- src/cata_tiles.cpp | 2 +- src/creature.cpp | 16 +++++- src/creature.h | 1 + src/game.cpp | 6 +- src/handle_action.cpp | 1 - src/map.cpp | 28 ++++----- src/mapgen.cpp | 9 +-- src/veh_appliance.cpp | 13 ++--- src/veh_interact.cpp | 9 ++- src/vehicle.cpp | 37 ++++++++---- src/vehicle.h | 16 +++--- src/vehicle_move.cpp | 94 ++++++++++++++++--------------- tests/vehicle_efficiency_test.cpp | 4 +- tests/vehicle_ramp_test.cpp | 14 ++--- tests/vehicle_split_test.cpp | 14 ++--- 17 files changed, 152 insertions(+), 122 deletions(-) diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index 2b1ca60ed3665..db13b2c860059 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -589,8 +589,8 @@ static bool vehicle_activity( Character &you, const tripoint_bub_ms &src_loc, in // so , NPCs can remove the last part on a position, then there is no vehicle there anymore, // for someone else who stored that position at the start of their activity. // so we may need to go looking a bit further afield to find it , at activities end. - for( const tripoint_bub_ms &pt : veh->get_points( true ) ) { - you.activity.coord_set.insert( here.get_abs( pt ) ); + for( const tripoint_abs_ms &pt : veh->get_points( true ) ) { + you.activity.coord_set.insert( pt ); } // values[0] you.activity.values.push_back( here.get_abs( src_loc ).x() ); diff --git a/src/avatar.cpp b/src/avatar.cpp index 9a47e254425b9..fc420de545dd6 100644 --- a/src/avatar.cpp +++ b/src/avatar.cpp @@ -688,11 +688,11 @@ void avatar::grab( object_type grab_type_new, const tripoint_rel_ms &grab_point_ map &m = get_map(); if( gtype == object_type::VEHICLE ) { if( const optional_vpart_position ovp = m.veh_at( pos_bub() + gpoint ) ) { - for( const tripoint_bub_ms &target : ovp->vehicle().get_points() ) { + for( const tripoint_abs_ms &target : ovp->vehicle().get_points() ) { if( erase ) { - memorize_clear_decoration( m.get_abs( target ), /* prefix = */ "vp_" ); + memorize_clear_decoration( target, /* prefix = */ "vp_" ); } - m.memory_cache_dec_set_dirty( target, true ); + m.memory_cache_dec_set_dirty( m.get_bub( target ), true ); } } } else if( gtype != object_type::NONE ) { diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index 6c97af7c941e1..47fa2193e9771 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -3936,7 +3936,7 @@ bool cata_tiles::draw_vpart( const tripoint_bub_ms &p, lit_level ll, int &height avatar &you = get_avatar(); if( !veh.forward_velocity() && !veh.player_in_control( you ) && !( you.get_grab_type() == object_type::VEHICLE - && veh.get_points().count( ( you.pos_bub() + you.grab_point ) ) ) + && veh.get_points().count( ( you.pos_abs() + you.grab_point ) ) ) && here.memory_cache_dec_is_dirty( p ) ) { you.memorize_decoration( here.get_abs( p ), vd.get_tileset_id(), subtile, rotation ); } diff --git a/src/creature.cpp b/src/creature.cpp index f804e9c97b1b7..4e31ee6008a77 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -228,6 +228,16 @@ void Creature::setpos( map *here, const tripoint_bub_ms &p, bool check_gravity/* } } +void Creature::setpos( const tripoint_abs_ms &p, bool check_gravity/* = true*/ ) +{ + const tripoint_abs_ms old_loc = pos_abs(); + set_pos_abs_only( p ); + on_move( old_loc ); + if( check_gravity ) { + gravity_check(); + } +} + bool Creature::will_be_cramped_in_vehicle_tile( const tripoint_abs_ms &loc ) const { map &here = get_map(); @@ -668,10 +678,10 @@ bool Creature::sees( const tripoint_bub_ms &t, bool is_avatar, int range_mod ) c // Helper function to check if potential area of effect of a weapon overlaps vehicle // Maybe TODO: If this is too slow, precalculate a bounding box and clip the tested area to it -static bool overlaps_vehicle( const std::set &veh_area, const tripoint_bub_ms &pos, +static bool overlaps_vehicle( const std::set &veh_area, const tripoint_abs_ms &pos, const int area ) { - for( const tripoint_bub_ms &tmp : tripoint_range( pos - tripoint( area, area, 0 ), + for( const tripoint_abs_ms &tmp : tripoint_range( pos - tripoint( area, area, 0 ), pos + tripoint( area - 1, area - 1, 0 ) ) ) { if( veh_area.count( tmp ) > 0 ) { return true; @@ -813,7 +823,7 @@ Creature *Creature::auto_find_hostile_target( int range, int &boo_hoo, int area continue; // Handle this late so that boo_hoo++ can happen } // Expensive check for proximity to vehicle - if( self_area_iff && overlaps_vehicle( in_veh->get_points(), m->pos_bub(), area ) ) { + if( self_area_iff && overlaps_vehicle( in_veh->get_points(), m->pos_abs(), area ) ) { continue; } diff --git a/src/creature.h b/src/creature.h index ebe4862b7fe1e..92594fada361c 100644 --- a/src/creature.h +++ b/src/creature.h @@ -319,6 +319,7 @@ class Creature : public viewer virtual void gravity_check( map *here ); void setpos( const tripoint_bub_ms &p, bool check_gravity = true ); void setpos( map *here, const tripoint_bub_ms &p, bool check_gravity = true ); + void setpos( const tripoint_abs_ms &p, bool check_gravity = true ); /** Checks if the creature fits confortably into a given tile. */ bool will_be_cramped_in_vehicle_tile( const tripoint_abs_ms &loc ) const; diff --git a/src/game.cpp b/src/game.cpp index e038454794cb2..fca66979248c9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -5912,9 +5912,9 @@ void game::control_vehicle() if( veh ) { // If we reached here, we gained control of a vehicle. // Clear the map memory for the area covered by the vehicle to eliminate ghost vehicles. - for( const tripoint_bub_ms &target : veh->get_points() ) { - u.memorize_clear_decoration( m.get_abs( target ), "vp_" ); - m.memory_cache_dec_set_dirty( target, true ); + for( const tripoint_abs_ms &target : veh->get_points() ) { + u.memorize_clear_decoration( target, "vp_" ); + m.memory_cache_dec_set_dirty( m.get_bub( target ), true ); } veh->is_following = false; veh->is_patrolling = false; diff --git a/src/handle_action.cpp b/src/handle_action.cpp index fe2aa95c4f4c9..c01e40d83ac7b 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -760,7 +760,6 @@ static void grab() //solid vehicles can't be grabbed while boarded const optional_vpart_position vp_boarded = here.veh_at( you.pos_bub() ); if( vp_boarded ) { - const std::set grabbed_veh_points = vp->vehicle().get_points(); if( &vp_boarded->vehicle() == &vp->vehicle() && !empty( vp->vehicle().get_avail_parts( VPFLAG_OBSTACLE ) ) ) { add_msg( m_info, _( "You can't move the %s while you're boarding it." ), veh_name ); diff --git a/src/map.cpp b/src/map.cpp index 9f64c17136099..a12304bd2ff18 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -375,12 +375,12 @@ void map::memory_cache_ter_set_dirty( const tripoint_bub_ms &p, bool value ) con void map::memory_clear_vehicle_points( const vehicle &veh ) const { avatar &player_character = get_avatar(); - for( const tripoint_bub_ms &p : veh.get_points() ) { + for( const tripoint_abs_ms &p : veh.get_points() ) { if( !inbounds( p ) ) { continue; } - memory_cache_dec_set_dirty( p, true ); - player_character.memorize_clear_decoration( get_abs( p ), "vp_" ); + memory_cache_dec_set_dirty( get_bub( p ), true ); + player_character.memorize_clear_decoration( p, "vp_" ); } } @@ -602,11 +602,11 @@ std::unique_ptr map::detach_vehicle( vehicle *veh ) level_cache &ch = get_cache( z ); for( size_t i = 0; i < current_submap->vehicles.size(); i++ ) { if( current_submap->vehicles[i].get() == veh ) { - for( const tripoint_bub_ms &pt : veh->get_points() ) { + for( const tripoint_abs_ms &pt : veh->get_points() ) { if( inbounds( pt ) ) { - memory_cache_dec_set_dirty( pt, true ); + memory_cache_dec_set_dirty( get_bub( pt ), true ); } - get_avatar().memorize_clear_decoration( get_abs( pt ), "vp_" ); + get_avatar().memorize_clear_decoration( pt, "vp_" ); } ch.vehicle_list.erase( veh ); ch.zone_vehicles.erase( veh ); @@ -744,11 +744,12 @@ bool map::vehproceed( VehicleList &vehicle_list ) return true; } +// TODO: Make reality bubble independent. static bool sees_veh( const Creature &c, vehicle &veh, bool force_recalc ) { - const auto &veh_points = veh.get_points( force_recalc ); - return std::any_of( veh_points.begin(), veh_points.end(), [&c]( const tripoint_bub_ms & pt ) { - return c.sees( pt ); + const std::set &veh_points = veh.get_points( force_recalc ); + return std::any_of( veh_points.begin(), veh_points.end(), [&c]( const tripoint_abs_ms & pt ) { + return c.sees( get_map().get_bub( pt ) ); } ); } @@ -886,10 +887,11 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler if( !vertical && !veh.valid_wheel_config() && !( veh.is_watercraft() && veh.can_float() ) && !veh.is_flying_in_air() && dp.z() == 0 ) { veh.velocity -= std::clamp( veh.velocity, -2000, 2000 ); // extra drag - for( const tripoint_bub_ms &p : veh.get_points() ) { - const ter_id &pter = ter( p ); + for( const tripoint_abs_ms &p : veh.get_points() ) { + const tripoint_bub_ms pos = get_bub( p ); + const ter_id &pter = ter( pos ); if( pter == ter_t_dirt || pter == ter_t_grass ) { - ter_set( p, ter_t_dirtmound ); + ter_set( pos, ter_t_dirtmound ); } } } @@ -7136,7 +7138,7 @@ bool map::draw_maptile( const catacurses::window &w, const tripoint_bub_ms &p, if( !veh->forward_velocity() && !veh->player_in_control( player_character ) && !( player_character.get_grab_type() == object_type::VEHICLE - && veh->get_points().count( ( player_character.pos_bub() + + && veh->get_points().count( ( player_character.pos_abs() + player_character.grab_point ) ) ) ) { memory_sym = sym; } diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 426401b778653..35cd3bd8a52af 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -7002,13 +7002,14 @@ std::unique_ptr map::add_vehicle_to_map( */ std::unique_ptr handler_ptr; bool did_merge = false; - for( const tripoint_bub_ms &map_pos : first_veh->get_points( true ) ) { - std::vector parts_to_move = veh_to_add->get_parts_at( map_pos, "", + for( const tripoint_abs_ms &map_pos : first_veh->get_points( true ) ) { + const tripoint_bub_ms map_bub_pos = get_bub( map_pos ); // TODO: Make usages use this map. + std::vector parts_to_move = veh_to_add->get_parts_at( map_bub_pos, "", part_status_flag::any ); if( !parts_to_move.empty() ) { // Store target_point by value because first_veh->parts may reallocate // to a different address after install_part() - std::vector first_veh_parts = first_veh->get_parts_at( map_pos, "", + std::vector first_veh_parts = first_veh->get_parts_at( map_bub_pos, "", part_status_flag:: any ); // This happens if this location is occupied by a fake part. if( first_veh_parts.empty() || first_veh_parts.front()->is_fake ) { @@ -7024,7 +7025,7 @@ std::unique_ptr map::add_vehicle_to_map( veh_to_add->name, veh_to_add->type.str(), veh_to_add->pos_abs().to_string(), to_degrees( veh_to_add->turn_dir ), - map_pos.to_string() ); + map_bub_pos.to_string() ); } did_merge = true; const point_rel_ms target_point = first_veh_parts.front()->mount; diff --git a/src/veh_appliance.cpp b/src/veh_appliance.cpp index 0618bc967bbc4..79e595ae4a470 100644 --- a/src/veh_appliance.cpp +++ b/src/veh_appliance.cpp @@ -406,12 +406,11 @@ void veh_app_interact::refill() act.targets.push_back( target ); act.str_values.push_back( pt->info().id.str() ); const point_rel_ms q = veh->coord_translate( pt->mount ); - map &here = get_map(); - for( const tripoint_bub_ms &p : veh->get_points( true ) ) { - act.coord_set.insert( here.get_abs( p ) ); + for( const tripoint_abs_ms &p : veh->get_points( true ) ) { + act.coord_set.insert( p ); } - act.values.push_back( here.get_abs( veh->pos_bub() ).x() + q.x() ); - act.values.push_back( here.get_abs( veh->pos_bub() ).y() + q.y() ); + act.values.push_back( veh->pos_abs().x() + q.x() ); + act.values.push_back( veh->pos_abs().y() + q.y() ); act.values.push_back( a_point.x() ); act.values.push_back( a_point.y() ); act.values.push_back( -a_point.x() ); @@ -496,8 +495,8 @@ void veh_app_interact::remove() } else if( query_yn( _( "Are you sure you want to take down the %s?" ), veh->name ) ) { act = player_activity( ACT_VEHICLE, to_moves( time ), static_cast( 'O' ) ); act.str_values.push_back( vpinfo.id.str() ); - for( const tripoint_bub_ms &p : veh->get_points( true ) ) { - act.coord_set.insert( here.get_abs( p ) ); + for( const tripoint_abs_ms &p : veh->get_points( true ) ) { + act.coord_set.insert( p ); } const tripoint_abs_ms a_point_abs( here.get_abs( a_point_bub ) ); act.values.push_back( a_point_abs.x() ); diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index 9c7bf9f55cd71..949c94e9c2f44 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -176,12 +176,11 @@ player_activity veh_interact::serialize_activity() // otherwise (e.g. installing a new frame), just use part 0 const point_rel_ms q = veh->coord_translate( pt ? pt->mount : veh->part( 0 ).mount ); const vehicle_part *vpt = pt ? pt : &veh->part( 0 ); - map &here = get_map(); - for( const tripoint_bub_ms &p : veh->get_points( true ) ) { - res.coord_set.insert( here.get_abs( p ) ); + for( const tripoint_abs_ms &p : veh->get_points( true ) ) { + res.coord_set.insert( p ); } - res.values.push_back( here.get_abs( veh->pos_bub() ).x() + q.x() ); // values[0] - res.values.push_back( here.get_abs( veh->pos_bub() ).y() + q.y() ); // values[1] + res.values.push_back( veh->pos_abs().x() + q.x() ); // values[0] + res.values.push_back( veh->pos_abs().y() + q.y() ); // values[1] res.values.push_back( dd.x() ); // values[2] res.values.push_back( dd.y() ); // values[3] res.values.push_back( -dd.x() ); // values[4] diff --git a/src/vehicle.cpp b/src/vehicle.cpp index b931327f1778b..5d0b967376edb 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -3522,6 +3522,16 @@ tripoint_bub_ms vehicle::bub_part_pos( const vehicle_part &pt ) const return pos_bub() + pt.precalc[ 0 ]; } +tripoint_abs_ms vehicle::abs_part_pos( const int index ) const +{ + return abs_part_pos( parts[index] ); +} + +tripoint_abs_ms vehicle::abs_part_pos( const vehicle_part &pt ) const +{ + return pos_abs() + pt.precalc[0]; +} + void vehicle::set_submap_moved( const tripoint_bub_sm &p ) { const point_abs_ms old_msp = pos_abs().xy(); @@ -6613,7 +6623,7 @@ void vehicle::refresh( const bool remove_fakes ) zones_dirty = true; coeff_air_dirty = true; invalidate_mass(); - occupied_cache_pos = { -1, -1, -1 }; + occupied_cache_pos = tripoint_abs_ms::invalid; refresh_active_item_cache(); } @@ -7877,19 +7887,19 @@ bool vehicle::restore_folded_parts( const item &it ) return true; } -const std::set &vehicle::get_points( const bool force_refresh, +const std::set &vehicle::get_points( const bool force_refresh, const bool no_fake ) const { - if( force_refresh || occupied_cache_pos != pos_bub() || + if( force_refresh || occupied_cache_pos != pos_abs() || occupied_cache_direction != face.dir() ) { - occupied_cache_pos = pos_bub(); + occupied_cache_pos = pos_abs(); occupied_cache_direction = face.dir(); occupied_points.clear(); for( const std::pair> &part_location : relative_parts ) { if( no_fake && part( part_location.second.front() ).is_fake ) { continue; } - occupied_points.insert( bub_part_pos( part_location.second.front() ) ); + occupied_points.insert( abs_part_pos( part_location.second.front() ) ); } } @@ -7910,13 +7920,13 @@ void vehicle::part_project_points( const tripoint_rel_ms &dp ) } // Coordinates of where part will go due to movement (dx/dy/dz) // and turning (precalc[1]) - vp.next_pos = pos_bub() + dp + vp.precalc[1]; + vp.next_pos = pos_abs() + dp + vp.precalc[1]; } } -std::set vehicle::get_projected_part_points() const +std::set vehicle::get_projected_part_points() const { - std::set projected_points; + std::set projected_points; for( int p = 0; p < part_count(); p++ ) { const vehicle_part &vp = parts.at( p ); @@ -8242,18 +8252,21 @@ bounding_box vehicle::get_bounding_box( bool use_precalc, bool no_fake ) precalc_mounts( 0, turn_dir, point_rel_ms::zero ); - for( const tripoint_bub_ms &p : get_points( true, no_fake ) ) { + for( const tripoint_abs_ms &p : get_points( true, no_fake ) ) { point_rel_ms pt; if( use_precalc ) { const int i_use = 0; // TODO: Check if this is correct. part_at takes a vehicle relative position, not a bub one... - int part_idx = part_at( rebase_rel( p.xy() ) ); + // int part_idx = part_at((p - pos_abs()).xy()); // Suggested correction. + int part_idx = part_at( rebase_rel( get_map().get_bub( p ).xy() ) ); if( part_idx < 0 ) { continue; } pt = parts[part_idx].precalc[i_use].xy(); } else { - pt = rebase_rel( p.xy() ); + // TODO: Check if this is correct. part_at takes a vehicle relative position, not a bub one... + // pt = (p - pos_abs()).xy(); // Suggested correction. + pt = rebase_rel( get_map().get_bub( p ).xy() ); } if( pt.x() < min_x ) { min_x = pt.x(); @@ -8391,7 +8404,7 @@ std::set vehicle::advance_precalc_mounts( const point_sm_ms &new_pos, } pos = new_pos; } - occupied_cache_pos = { -1, -1, -1 }; + occupied_cache_pos = tripoint_abs_ms::invalid; return smzs; } diff --git a/src/vehicle.h b/src/vehicle.h index bfc3ab62f08f5..251ab2cbf8d2f 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -452,7 +452,7 @@ struct vehicle_part { std::array precalc = { { tripoint_rel_ms( -1, -1, 0 ), tripoint_rel_ms( -1, -1, 0 ) } }; /** temporarily held projected position */ - tripoint_bub_ms next_pos = tripoint_bub_ms( -1, -1, 0 ); // NOLINT(cata-serialize) + tripoint_abs_ms next_pos = tripoint_abs_ms( -1, -1, 0 ); // NOLINT(cata-serialize) /** current part health with range [0,durability] */ int hp() const; @@ -1439,6 +1439,8 @@ class vehicle */ tripoint_bub_ms bub_part_pos( int index ) const; tripoint_bub_ms bub_part_pos( const vehicle_part &pt ) const; + tripoint_abs_ms abs_part_pos( int index ) const; + tripoint_abs_ms abs_part_pos( const vehicle_part &pt ) const; /** * All the fuels that are in all the tanks in the vehicle, nicely summed up. * Note that empty tanks don't count at all. The value is the amount as it would be @@ -1794,7 +1796,7 @@ class vehicle // Handle given part collision with vehicle, monster/NPC/player or terrain obstacle // Returns collision, which has type, impulse, part, & target. - veh_collision part_collision( int part, const tripoint_bub_ms &p, + veh_collision part_collision( int part, const tripoint_abs_ms &p, bool just_detect, bool bash_floor ); // Process the trap beneath @@ -1994,14 +1996,14 @@ class vehicle bool assign_seat( vehicle_part &pt, const npc &who ); // Update the set of occupied points and return a reference to it - const std::set &get_points( bool force_refresh = false, + const std::set &get_points( bool force_refresh = false, bool no_fake = false ) const; // calculate the new projected points for all vehicle parts to move to void part_project_points( const tripoint_rel_ms &dp ); // get all vehicle parts' projected points - std::set get_projected_part_points() const; + std::set get_projected_part_points() const; /** * Consumes specified charges (or fewer) from the vehicle part @@ -2164,12 +2166,12 @@ class vehicle mutable double draft_m = 1; // NOLINT(cata-serialize) mutable double hull_height = 0.3; // NOLINT(cata-serialize) - // Bubble location when cache was last refreshed. - mutable tripoint_bub_ms occupied_cache_pos = { -1, -1, -1 }; // NOLINT(cata-serialize) + // Absolute location when cache was last refreshed. + mutable tripoint_abs_ms occupied_cache_pos = tripoint_abs_ms::invalid; // NOLINT(cata-serialize) // Vehicle facing when cache was last refreshed. mutable units::angle occupied_cache_direction = 0_degrees; // NOLINT(cata-serialize) // Cached points occupied by the vehicle - mutable std::set occupied_points; // NOLINT(cata-serialize) + mutable std::set occupied_points; // NOLINT(cata-serialize) // Master list of parts installed in the vehicle. std::vector parts; // NOLINT(cata-serialize) diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index 88f49666d8516..a03d351740574 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -687,9 +687,9 @@ void vehicle::stop() last_turn = 0_degrees; of_turn_carry = 0; map &here = get_map(); - for( const tripoint_bub_ms &p : get_points() ) { + for( const tripoint_abs_ms &p : get_points() ) { if( here.inbounds( p ) ) { - here.memory_cache_dec_set_dirty( p, true ); + here.memory_cache_dec_set_dirty( here.get_bub( p ), true ); } } } @@ -753,12 +753,12 @@ bool vehicle::collision( std::vector &colls, empty = false; // Coordinates of where part will go due to movement (dx/dy/dz) // and turning (precalc[1]) - const tripoint_bub_ms dsp = vp.next_pos; + const tripoint_abs_ms dsp = vp.next_pos; veh_collision coll = part_collision( p, dsp, just_detect, bash_floor ); if( coll.type == veh_coll_nothing && info.has_flag( VPFLAG_ROTOR ) ) { size_t radius = static_cast( std::round( info.rotor_info->rotor_diameter / 2.0f ) ); - for( const tripoint_bub_ms &rotor_point : here.points_in_radius( dsp, radius ) ) { - veh_collision rotor_coll = part_collision( p, rotor_point, just_detect, false ); + for( const tripoint_bub_ms &rotor_point : here.points_in_radius( here.get_bub( dsp ), radius ) ) { + veh_collision rotor_coll = part_collision( p, here.get_abs( rotor_point ), just_detect, false ); if( rotor_coll.type != veh_coll_nothing ) { coll = rotor_coll; if( just_detect ) { @@ -830,9 +830,11 @@ static void terrain_collision_data( const tripoint_bub_ms &p, bool bash_floor, density = bash_min; } -veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, +veh_collision vehicle::part_collision( int part, const tripoint_abs_ms &p, bool just_detect, bool bash_floor ) { + map &here = get_map(); + tripoint_bub_ms pos = here.get_bub( p ); // Vertical collisions need to be handled differently // All collisions have to be either fully vertical or fully horizontal for now const bool vert_coll = bash_floor || p.z() != sm_pos.z(); @@ -847,7 +849,6 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, ph = nullptr; } - map &here = get_map(); const optional_vpart_position ovp = here.veh_at( p ); // Disable vehicle/critter collisions when bashing floor // TODO: More elegant code @@ -886,13 +887,13 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, } // we just ran into a fish, so move it out of the way if( here.has_flag( ter_furn_flag::TFLAG_SWIMMABLE, critter->pos_bub() ) ) { - tripoint_bub_ms end_pos = critter->pos_bub(); - tripoint_bub_ms start_pos; - const std::set projected_points = get_projected_part_points(); + tripoint_abs_ms end_pos = critter->pos_abs(); + tripoint_abs_ms start_pos; + const std::set projected_points = get_projected_part_points(); const units::angle angle = move.dir() + ( coll_velocity > 0 ? 0_degrees : 180_degrees ) + 45_degrees * ( parts[part].mount.x() > pivot_point().x() ? -1 : 1 ); - const std::set &cur_points = get_points( true ); + const std::set &cur_points = get_points( true ); // push the animal out of way until it's no longer in our vehicle and not in // anyone else's position while( get_creature_tracker().creature_at( end_pos, true ) || @@ -922,7 +923,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, //part density float part_dens = 0.0f; - std::optional potential_impassable_field = here.get_impassable_field_at( p ); + std::optional potential_impassable_field = here.get_impassable_field_at( pos ); if( potential_impassable_field.has_value() ) { // impassable fields are not destructible ret.type = veh_coll_other; @@ -939,31 +940,31 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, part_dens = 15; mass2 = units::to_kilogram( critter->get_weight() ); ret.target_name = critter->disp_name(); - } else if( ( bash_floor && here.is_bashable_ter_furn( p, true ) ) || - ( here.is_bashable_ter_furn( p, false ) && here.move_cost_ter_furn( p ) != 2 && + } else if( ( bash_floor && here.is_bashable_ter_furn( pos, true ) ) || + ( here.is_bashable_ter_furn( pos, false ) && here.move_cost_ter_furn( pos ) != 2 && // Don't collide with tiny things, like flowers, unless we have a wheel in our space. ( part_with_feature( ret.part, VPFLAG_WHEEL, true ) >= 0 || - !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_TINY, p ) ) && + !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_TINY, pos ) ) && // Protrusions don't collide with short terrain. // Tiny also doesn't, but it's already excluded unless there's a wheel present. !( part_with_feature( vp.mount, "PROTRUSION", true ) >= 0 && - here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_SHORT, p ) ) && + here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_SHORT, pos ) ) && // These are bashable, but don't interact with vehicles. - !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_NOCOLLIDE, p ) && + !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_NOCOLLIDE, pos ) && // Do not collide with track tiles if we can use rails - !( here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_RAIL, p ) && this->can_use_rails() ) ) ) { + !( here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_RAIL, pos ) && this->can_use_rails() ) ) ) { // Movecost 2 indicates flat terrain like a floor, no collision there. ret.type = veh_coll_bashable; - terrain_collision_data( p, bash_floor, mass2, part_dens, e ); - ret.target_name = here.disp_name( p ); - } else if( here.impassable_ter_furn( p ) || - ( bash_floor && !here.has_flag( ter_furn_flag::TFLAG_NO_FLOOR, p ) ) ) { + terrain_collision_data( pos, bash_floor, mass2, part_dens, e ); + ret.target_name = here.disp_name( pos ); + } else if( here.impassable_ter_furn( pos ) || + ( bash_floor && !here.has_flag( ter_furn_flag::TFLAG_NO_FLOOR, pos ) ) ) { // not destructible ret.type = veh_coll_other; mass2 = 1000; e = 0.10f; part_dens = 80; - ret.target_name = here.disp_name( p ); + ret.target_name = here.disp_name( pos ); } if( ret.type == veh_coll_nothing || just_detect ) { @@ -1065,23 +1066,23 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, // Something bashable -- use map::bash to determine outcome // NOTE: Floor bashing disabled for balance reasons // Floor values are still used to set damage dealt to vehicle - smashed = here.is_bashable_ter_furn( p, false ) && - here.bash_resistance( p, bash_floor ) <= obj_dmg && - here.bash( p, obj_dmg, false, false, false, this ).success; + smashed = here.is_bashable_ter_furn( pos, false ) && + here.bash_resistance( pos, bash_floor ) <= obj_dmg && + here.bash( pos, obj_dmg, false, false, false, this ).success; if( smashed ) { - if( here.is_bashable_ter_furn( p, bash_floor ) ) { + if( here.is_bashable_ter_furn( pos, bash_floor ) ) { // There's new terrain there to smash smashed = false; - terrain_collision_data( p, bash_floor, mass2, part_dens, e ); - ret.target_name = here.disp_name( p ); - } else if( here.impassable_ter_furn( p ) ) { + terrain_collision_data( pos, bash_floor, mass2, part_dens, e ); + ret.target_name = here.disp_name( pos ); + } else if( here.impassable_ter_furn( pos ) ) { // There's new terrain there, but we can't smash it! smashed = false; ret.type = veh_coll_other; mass2 = 1000; e = 0.10f; part_dens = 80; - ret.target_name = here.disp_name( p ); + ret.target_name = here.disp_name( pos ); } } } else if( ret.type == veh_coll_body ) { @@ -1153,7 +1154,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, smashed = true; } else if( critter != nullptr ) { // Only count critter as pushed away if it actually changed position - smashed = critter->pos_bub() != p; + smashed = critter->pos_abs() != p; } } } @@ -1182,7 +1183,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, if( vpi.has_flag( "SHARP" ) ) { critter->bleed(); } else { - sounds::sound( p, 20, sounds::sound_t::combat, snd, false, "smash_success", "hit_vehicle" ); + sounds::sound( pos, 20, sounds::sound_t::combat, snd, false, "smash_success", "hit_vehicle" ); } } } else { @@ -1198,7 +1199,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_bub_ms &p, } } - sounds::sound( p, smashed ? 80 : 50, sounds::sound_t::combat, snd, false, "smash_success", + sounds::sound( pos, smashed ? 80 : 50, sounds::sound_t::combat, snd, false, "smash_success", "hit_vehicle" ); } @@ -1369,9 +1370,10 @@ bool vehicle::check_heli_descend( Character &p ) const int air_count = 0; map &here = get_map(); creature_tracker &creatures = get_creature_tracker(); - for( const tripoint_bub_ms &pt : get_points( true ) ) { - tripoint_bub_ms below( pt + tripoint::below ); - if( pt.z() < -OVERMAP_DEPTH || !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_NO_FLOOR, pt ) ) { + for( const tripoint_abs_ms &pt : get_points( true ) ) { + const tripoint_bub_ms pos = here.get_bub( pt ); + tripoint_bub_ms below( pos + tripoint::below ); + if( pt.z() < -OVERMAP_DEPTH || !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_NO_FLOOR, pos ) ) { p.add_msg_if_player( _( "You are already landed!" ) ); return false; } @@ -1409,10 +1411,11 @@ bool vehicle::check_heli_ascend( Character &p ) const } map &here = get_map(); creature_tracker &creatures = get_creature_tracker(); - for( const tripoint_bub_ms &pt : get_points( true ) ) { - tripoint_bub_ms above( pt + tripoint::above ); + for( const tripoint_abs_ms &pt : get_points( true ) ) { + const tripoint_bub_ms pos = here.get_bub( pt ); + tripoint_bub_ms above( pos + tripoint::above ); const optional_vpart_position ovp = here.veh_at( above ); - if( here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_INDOORS, pt ) || + if( here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_INDOORS, pos ) || here.impassable_ter_furn( above ) || ovp || creatures.creature_at( above ) ) { @@ -2102,7 +2105,7 @@ void vehicle::check_falling_or_floating() } // TODO: Make the vehicle "slide" towards its center of weight // when it's not properly supported - const std::set &pts = get_points(); + const std::set &pts = get_points(); if( pts.empty() ) { // Dirty vehicle with no parts is_falling = false; @@ -2114,13 +2117,14 @@ void vehicle::check_falling_or_floating() size_t deep_water_tiles = 0; size_t water_tiles = 0; - for( const tripoint_bub_ms &position : pts ) { - deep_water_tiles += here.has_flag( ter_furn_flag::TFLAG_DEEP_WATER, position ) ? 1 : 0; - water_tiles += here.has_flag( ter_furn_flag::TFLAG_SWIMMABLE, position ) ? 1 : 0; + for( const tripoint_abs_ms &position : pts ) { + const tripoint_bub_ms pos = here.get_bub( position ); + deep_water_tiles += here.has_flag( ter_furn_flag::TFLAG_DEEP_WATER, pos ) ? 1 : 0; + water_tiles += here.has_flag( ter_furn_flag::TFLAG_SWIMMABLE, pos ) ? 1 : 0; if( !is_falling ) { continue; } - is_falling = !has_support( position, true ); + is_falling = !has_support( pos, true ); } // in_deep_water if 2/3 of the vehicle is in deep water in_deep_water = 3 * deep_water_tiles >= 2 * pts.size(); diff --git a/tests/vehicle_efficiency_test.cpp b/tests/vehicle_efficiency_test.cpp index d25101cf19f74..2e0cd2f58aacb 100644 --- a/tests/vehicle_efficiency_test.cpp +++ b/tests/vehicle_efficiency_test.cpp @@ -231,8 +231,8 @@ static int test_efficiency( const vproto_id &veh_id, int &expected_mass, veh.idle( true ); // If the vehicle starts skidding, the effects become random and test is RUINED REQUIRE( !veh.skidding ); - for( const tripoint_bub_ms &pos : veh.get_points() ) { - REQUIRE( here.ter( pos ) ); + for( const tripoint_abs_ms &pos : veh.get_points() ) { + REQUIRE( here.ter( here.get_bub( pos ) ) ); } // How much it moved tiles_travelled += square_dist( starting_point, veh.pos_bub() ); diff --git a/tests/vehicle_ramp_test.cpp b/tests/vehicle_ramp_test.cpp index f442a8736e97b..09ee4854c7151 100644 --- a/tests/vehicle_ramp_test.cpp +++ b/tests/vehicle_ramp_test.cpp @@ -132,13 +132,13 @@ static void ramp_transition_angled( const vproto_id &veh_id, const units::angle int cycles = 0; const int target_z = use_ramp ? ( up ? 1 : -1 ) : 0; - std::set vpts = veh.get_points(); + std::set vpts = veh.get_points(); while( veh.engine_on && veh.safe_velocity() > 0 && cycles < 10 ) { clear_creatures(); CAPTURE( cycles ); - for( const tripoint_bub_ms &checkpt : vpts ) { + for( const tripoint_abs_ms &checkpt : vpts ) { int partnum = 0; - vehicle *check_veh = here.veh_at_internal( checkpt, partnum ); + vehicle *check_veh = here.veh_at_internal( here.get_bub( checkpt ), partnum ); CAPTURE( veh_ptr->pos_bub() ); CAPTURE( veh_ptr->face.dir() ); CAPTURE( checkpt ); @@ -149,8 +149,8 @@ static void ramp_transition_angled( const vproto_id &veh_id, const units::angle CHECK( veh.velocity == target_velocity ); // If the vehicle starts skidding, the effects become random and test is RUINED REQUIRE( !veh.skidding ); - for( const tripoint_bub_ms &pos : veh.get_points() ) { - REQUIRE( here.ter( pos ) ); + for( const tripoint_abs_ms &pos : veh.get_points() ) { + REQUIRE( here.ter( here.get_bub( pos ) ) ); } for( const vpart_reference &vp : veh.get_all_parts() ) { if( vp.info().location != "structure" ) { @@ -266,8 +266,8 @@ static void level_out( const vproto_id &veh_id, const bool drop_pos ) CHECK( veh.safe_velocity() > 0 ); std::vector all_parts; - for( const tripoint_bub_ms &pos : veh.get_points() ) { - for( vehicle_part *prt : veh.get_parts_at( pos, "", part_status_flag::any ) ) { + for( const tripoint_abs_ms &pos : veh.get_points() ) { + for( vehicle_part *prt : veh.get_parts_at( here.get_bub( pos ), "", part_status_flag::any ) ) { all_parts.push_back( prt ); if( drop_pos && prt->mount.x() < 0 ) { prt->precalc[0].z() = -1; diff --git a/tests/vehicle_split_test.cpp b/tests/vehicle_split_test.cpp index 805aace258f58..fa45cd04aff56 100644 --- a/tests/vehicle_split_test.cpp +++ b/tests/vehicle_split_test.cpp @@ -31,7 +31,7 @@ TEST_CASE( "vehicle_split_section", "[vehicle]" ) vehicle *veh_ptr = here.add_vehicle( vehicle_prototype_cross_split_test, vehicle_origin, dir, 0, 0 ); REQUIRE( veh_ptr != nullptr ); - std::set original_points = veh_ptr->get_points( true ); + std::set original_points = veh_ptr->get_points( true ); here.destroy_vehicle( vehicle_origin ); veh_ptr->part_removal_cleanup(); @@ -45,21 +45,21 @@ TEST_CASE( "vehicle_split_section", "[vehicle]" ) CHECK( vehs[1].v->part_count() == 12 ); CHECK( vehs[2].v->part_count() == 2 ); CHECK( vehs[3].v->part_count() == 3 ); - std::vector> all_points; + std::vector> all_points; for( int i = 0; i < 4; i++ ) { - const std::set &veh_points = vehs[i].v->get_points( true ); + const std::set &veh_points = vehs[i].v->get_points( true ); all_points.push_back( veh_points ); } for( int i = 0; i < 4; i++ ) { - std::set &veh_points = all_points[i]; + std::set &veh_points = all_points[i]; // every point in the new vehicle was in the old vehicle - for( const tripoint_bub_ms &vpos : veh_points ) { + for( const tripoint_abs_ms &vpos : veh_points ) { CHECK( original_points.find( vpos ) != original_points.end() ); } // no point in any new vehicle is in any other new vehicle for( int j = i + 1; j < 4; j++ ) { - std::set &other_points = all_points[j]; - for( const tripoint_bub_ms &vpos : veh_points ) { + std::set &other_points = all_points[j]; + for( const tripoint_abs_ms &vpos : veh_points ) { CHECK( other_points.find( vpos ) == other_points.end() ); } }