diff --git a/src/activity_actor.cpp b/src/activity_actor.cpp index e471c1e55e566..50bdc4978d985 100644 --- a/src/activity_actor.cpp +++ b/src/activity_actor.cpp @@ -629,13 +629,15 @@ void autodrive_activity_actor::start( player_activity &, Character &who ) void autodrive_activity_actor::do_turn( player_activity &act, Character &who ) { + map &here = get_map(); + if( who.in_vehicle && who.controlling_vehicle && player_vehicle ) { if( who.get_moves() <= 0 ) { // out of moves? the driver's not doing anything this turn // (but the vehicle will continue moving) return; } - switch( player_vehicle->do_autodrive( who ) ) { + switch( player_vehicle->do_autodrive( here, who ) ) { case autodrive_result::ok: if( who.get_moves() > 0 ) { // if do_autodrive() didn't eat up all our moves, end the turn @@ -1357,8 +1359,8 @@ bikerack_racking_activity_actor::bikerack_racking_activity_actor( const vehicle : racks( racks ) { map &here = get_map(); - parent_vehicle_pos = parent_vehicle.bub_part_pos( &here, 0 ); - racked_vehicle_pos = racked_vehicle.bub_part_pos( &here, 0 ); + parent_vehicle_pos = parent_vehicle.bub_part_pos( here, 0 ); + racked_vehicle_pos = racked_vehicle.bub_part_pos( here, 0 ); } void bikerack_racking_activity_actor::start( player_activity &act, Character & ) @@ -1584,7 +1586,7 @@ bikerack_unracking_activity_actor::bikerack_unracking_activity_actor( const vehi : parts( parts ), racks( racks ) { map &here = get_map(); - parent_vehicle_pos = parent_vehicle.bub_part_pos( &here, 0 ); + parent_vehicle_pos = parent_vehicle.bub_part_pos( here, 0 ); } void bikerack_unracking_activity_actor::start( player_activity &act, Character & ) @@ -8031,14 +8033,14 @@ bool vehicle_folding_activity_actor::fold_vehicle( Character &p, bool check_only for( const vpart_reference &vpr : veh.get_any_parts( VPFLAG_CARGO ) ) { vehicle_stack cargo = vpr.items(); for( const item &elem : cargo ) { - here.add_item_or_charges( veh.pos_bub( &here ), elem ); + here.add_item_or_charges( veh.pos_bub( here ), elem ); } cargo.clear(); } - veh.unboard_all(); + veh.unboard_all( here ); p.add_msg_if_player( _( "You fold the %s." ), veh.name ); - here.add_item_or_charges( veh.pos_bub( &here ), veh.get_folded_item() ); + here.add_item_or_charges( veh.pos_bub( here ), veh.get_folded_item( here ) ); here.destroy_vehicle( &veh ); return true; @@ -8048,7 +8050,7 @@ vehicle_folding_activity_actor::vehicle_folding_activity_actor( const vehicle &t { map &here = get_map(); folding_time = target.folding_time(); - target_pos = target.bub_part_pos( &here, 0 ); + target_pos = target.bub_part_pos( here, 0 ); } void vehicle_folding_activity_actor::start( player_activity &act, Character &p ) @@ -8121,7 +8123,7 @@ bool vehicle_unfolding_activity_actor::unfold_vehicle( Character &p, bool check_ here.destroy_vehicle( veh ); return false; } - const bool cant_float = !veh->can_float(); + const bool cant_float = !veh->can_float( here ); const auto invalid_pos = [&here, &cant_float]( const tripoint_bub_ms & p ) { return ( cant_float && here.has_flag_ter( ter_furn_flag::TFLAG_DEEP_WATER, p ) ) || here.veh_at( p ) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 1f6ed87c9a8a7..514bcf92393a3 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2145,7 +2145,7 @@ void activity_handlers::vehicle_finish( player_activity *act, Character *you ) const optional_vpart_position vp = here.veh_at( here.get_bub( tripoint_abs_ms( act->values[0], act->values[1], you->posz() ) ) ); - veh_interact::complete_vehicle( *you ); + veh_interact::complete_vehicle( here, *you ); // complete_vehicle set activity type to NULL if the vehicle // was completely dismantled, otherwise the vehicle still exist and // is to be examined again. diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index a1820dadeea08..9ea8fc7f87a93 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -226,7 +226,7 @@ static void put_into_vehicle( Character &c, item_drop_reason reason, const std:: c.invalidate_weight_carried_cache(); vehicle_part &vp = vpr.part(); vehicle &veh = vpr.vehicle(); - const tripoint_bub_ms where = veh.bub_part_pos( &here, vp ); + const tripoint_bub_ms where = veh.bub_part_pos( here, vp ); int items_did_not_fit_count = 0; int into_vehicle_count = 0; const std::string part_name = vp.info().name(); diff --git a/src/cata_tiles.cpp b/src/cata_tiles.cpp index 875c06b7f59b3..235bb972ff534 100644 --- a/src/cata_tiles.cpp +++ b/src/cata_tiles.cpp @@ -1473,7 +1473,7 @@ void cata_tiles::draw( const point &dest, const tripoint_bub_ms ¢er, int wid if( g->display_overlay_state( ACTION_DISPLAY_VEHICLE_AI ) ) { for( const wrapped_vehicle &elem : here.get_vehicles() ) { const vehicle &veh = *elem.v; - const point_bub_ms veh_pos = veh.pos_bub( &here ).xy(); + const point_bub_ms veh_pos = veh.pos_bub( here ).xy(); for( const auto &overlay_data : veh.get_debug_overlay_data() ) { const point_bub_ms pt = veh_pos + std::get<0>( overlay_data ); const int color = std::get<1>( overlay_data ); diff --git a/src/character.cpp b/src/character.cpp index eb1e164f7cc98..8a84a56cd2972 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -3072,6 +3072,7 @@ int Character::get_standard_stamina_cost( const item *thrown_item ) const std::vector Character::nearby( const std::function &func, int radius ) const { + map &here = get_map(); std::vector res; visit_items( [&]( const item * e, const item * parent ) { @@ -3081,7 +3082,7 @@ std::vector Character::nearby( const return VisitResponse::NEXT; } ); - for( const map_cursor &cur : map_selector( pos_bub(), radius ) ) { + for( const map_cursor &cur : map_selector( pos_bub( &here ), radius ) ) { cur.visit_items( [&]( const item * e, const item * parent ) { if( func( e, parent ) ) { res.emplace_back( cur, const_cast( e ) ); @@ -3090,7 +3091,7 @@ std::vector Character::nearby( const } ); } - for( const vehicle_cursor &cur : vehicle_selector( pos_bub(), radius ) ) { + for( const vehicle_cursor &cur : vehicle_selector( here, pos_bub( &here ), radius ) ) { cur.visit_items( [&]( const item * e, const item * parent ) { if( func( e, parent ) ) { res.emplace_back( cur, const_cast( e ) ); @@ -3210,6 +3211,7 @@ units::mass Character::best_nearby_lifting_assist() const units::mass Character::best_nearby_lifting_assist( const tripoint_bub_ms &world_pos ) const { + map &here = get_map(); int mech_lift = 0; if( is_mounted() ) { auto *mons = mounted_creature.get(); @@ -3219,7 +3221,7 @@ units::mass Character::best_nearby_lifting_assist( const tripoint_bub_ms &world_ } int lift_quality = std::max( { this->max_quality( qual_LIFT ), mech_lift, map_selector( this->pos_bub(), PICKUP_RANGE ).max_quality( qual_LIFT ), - vehicle_selector( world_pos, 4, true, true ).max_quality( qual_LIFT ) + vehicle_selector( here, world_pos, 4, true, true ).max_quality( qual_LIFT ) } ); return lifting_quality_to_mass( lift_quality ); } @@ -6925,6 +6927,7 @@ void Character::mod_stamina( int mod ) void Character::burn_move_stamina( int moves ) { + map &here = get_map(); int overburden_percentage = 0; //add half the difference between current stored kcal weight and healthy stored kcal weight to weight of carried gear units::mass fat_penalty = units::from_kilogram( 0.5f * std::max( 0.0f, @@ -6946,12 +6949,12 @@ void Character::burn_move_stamina( int moves ) ///\EFFECT_SWIMMING decreases stamina burn when swimming //Appropriate traits let you walk along the bottom without getting as tired - if( get_map().has_flag( ter_furn_flag::TFLAG_DEEP_WATER, pos_bub() ) && + if( here.has_flag( ter_furn_flag::TFLAG_DEEP_WATER, pos_bub( &here ) ) && !has_flag( json_flag_WATERWALKING ) && ( !has_flag( json_flag_WALK_UNDERWATER ) || - get_map().has_flag( ter_furn_flag::TFLAG_GOES_DOWN, pos_bub() ) ) && - !get_map().has_flag_furn( "BRIDGE", pos_bub() ) && - !( in_vehicle && get_map().veh_at( pos_bub() )->vehicle().can_float() ) ) { + here.has_flag( ter_furn_flag::TFLAG_GOES_DOWN, pos_bub( &here ) ) ) && + !here.has_flag_furn( "BRIDGE", pos_bub( &here ) ) && + !( in_vehicle && here.veh_at( pos_bub( &here ) )->vehicle().can_float( here ) ) ) { burn_ratio += 100 / std::pow( 1.1, get_skill_level( skill_swimming ) ); } @@ -13351,7 +13354,7 @@ void Character::pause() for( wrapped_vehicle &v : vehs ) { veh = v.v; if( veh && veh->is_moving() && veh->player_in_control( here, *this ) ) { - double exp_temp = 1 + veh->total_mass() / 400.0_kilogram + + double exp_temp = 1 + veh->total_mass( here ) / 400.0_kilogram + std::abs( veh->velocity / 3200.0 ); int experience = static_cast( exp_temp ); if( exp_temp - experience > 0 && x_in_y( exp_temp - experience, 1.0 ) ) { @@ -13367,8 +13370,7 @@ void Character::pause() wait_effects(); } -template -bool Character::can_lift( const T &obj ) const +bool Character::can_lift( item &obj ) const { // avoid comparing by weight as different objects use differing scales (grams vs kilograms etc) int str = get_lift_str(); @@ -13379,8 +13381,18 @@ bool Character::can_lift( const T &obj ) const const int npc_str = get_lift_assist(); return str + npc_str >= obj.lift_strength(); } -template bool Character::can_lift( const item &obj ) const; -template bool Character::can_lift( const vehicle &obj ) const; + +bool Character::can_lift( vehicle &veh, map &here ) const +{ + // avoid comparing by weight as different objects use differing scales (grams vs kilograms etc) + int str = get_lift_str(); + if( mounted_creature ) { + auto *const mons = mounted_creature.get(); + str = mons->mech_str_addition() == 0 ? str : mons->mech_str_addition(); + } + const int npc_str = get_lift_assist(); + return str + npc_str >= veh.lift_strength( here ); +} static std::string wrap60( const std::string &text ) { diff --git a/src/character.h b/src/character.h index f61d8eb79c852..3cf697cf1b9b4 100644 --- a/src/character.h +++ b/src/character.h @@ -2727,7 +2727,8 @@ class Character : public Creature, public visitable void pause(); // '.' command; pauses & resets recoil /** Check player strong enough to lift an object unaided by equipment (jacks, levers etc) */ - template bool can_lift( const T &obj ) const; + bool can_lift( item &obj ) const; + bool can_lift( vehicle &veh, map &here ) const; // --------------- Values --------------- std::string name; // Pre-cataclysm name, invariable // In-game name which you give to npcs or whoever asks, variable @@ -4206,7 +4207,4 @@ struct enum_traits { }; /// Get translated name of a stat std::string get_stat_name( character_stat Stat ); - -extern template bool Character::can_lift( const item &obj ) const; -extern template bool Character::can_lift( const vehicle &obj ) const; #endif // CATA_SRC_CHARACTER_H diff --git a/src/character_guns.cpp b/src/character_guns.cpp index b55a52cfb1fb3..c4626e12b1bc0 100644 --- a/src/character_guns.cpp +++ b/src/character_guns.cpp @@ -110,6 +110,8 @@ std::vector Character::get_ammo( const ammotype &at ) const std::vector Character::find_ammo( const item &obj, bool empty, int radius ) const { + map &here = get_map(); + std::vector res; find_ammo_helper( const_cast( *this ), obj, empty, std::back_inserter( res ), true ); @@ -118,7 +120,7 @@ std::vector Character::find_ammo( const item &obj, bool empty, in for( map_cursor &cursor : map_selector( pos_bub(), radius ) ) { find_ammo_helper( cursor, obj, empty, std::back_inserter( res ), false ); } - for( vehicle_cursor &cursor : vehicle_selector( pos_bub(), radius ) ) { + for( vehicle_cursor &cursor : vehicle_selector( here, pos_bub( &here ), radius ) ) { find_ammo_helper( cursor, obj, empty, std::back_inserter( res ), false ); } } diff --git a/src/construction.cpp b/src/construction.cpp index 615e950f432de..b2ff42160120d 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -1719,7 +1719,7 @@ void construct::done_vehicle( const tripoint_bub_ms &p, Character & ) const item &base = components.front(); veh->name = name; - const int partnum = veh->install_part( point_rel_ms::zero, vpart_from_item( base.typeId() ), + const int partnum = veh->install_part( here, point_rel_ms::zero, vpart_from_item( base.typeId() ), item( base ) ); veh->part( partnum ).set_flag( vp_flag::unsalvageable_flag ); @@ -1730,9 +1730,10 @@ void construct::done_vehicle( const tripoint_bub_ms &p, Character & ) void construct::done_wiring( const tripoint_bub_ms &p, Character &who ) { - get_map().partial_con_remove( p ); + map &here = get_map(); + here.partial_con_remove( p ); - place_appliance( p, vpart_from_item( itype_wall_wiring ), who ); + place_appliance( here, p, vpart_from_item( itype_wall_wiring ), who ); } void construct::done_appliance( const tripoint_bub_ms &p, Character &who ) @@ -1756,7 +1757,7 @@ void construct::done_appliance( const tripoint_bub_ms &p, Character &who ) const item &base = components.front(); const vpart_id &vpart = vpart_appliance_from_item( base.typeId() ); - place_appliance( p, vpart, who, base ); + place_appliance( here, p, vpart, who, base ); } void construct::done_deconstruct( const tripoint_bub_ms &p, Character &player_character ) diff --git a/src/game.cpp b/src/game.cpp index b4ed5de15c74a..330cb56ad8bba 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1192,7 +1192,7 @@ vehicle *game::place_vehicle_nearby( std::vector search_types = omt_search_types; if( search_types.empty() ) { const vehicle &veh = *id->blueprint; - if( veh.max_ground_velocity( here ) == 0 && veh.can_float() ) { + if( veh.max_ground_velocity( here ) == 0 && veh.can_float( here ) ) { search_types.emplace_back( "river" ); search_types.emplace_back( "lake" ); search_types.emplace_back( "ocean" ); @@ -2853,7 +2853,7 @@ void game::setremoteveh( vehicle *veh ) } std::stringstream remote_veh_string; - const tripoint_bub_ms vehpos = veh->pos_bub( &here ); + const tripoint_bub_ms vehpos = veh->pos_bub( here ); remote_veh_string << vehpos.x() << ' ' << vehpos.y() << ' ' << vehpos.z(); u.set_value( "remote_controlling_vehicle", remote_veh_string.str() ); } @@ -5772,7 +5772,9 @@ void game::save_cyborg( item *cyborg, const tripoint_bub_ms &couch_pos, Characte void game::exam_appliance( vehicle &veh, const point_rel_ms &c ) { - player_activity act = veh_app_interact::run( veh, c ); + map &here = get_map(); + + player_activity act = veh_app_interact::run( here, veh, c ); if( act ) { u.set_moves( 0 ); u.assign_activity( act ); @@ -5781,11 +5783,13 @@ void game::exam_appliance( vehicle &veh, const point_rel_ms &c ) void game::exam_vehicle( vehicle &veh, const point_rel_ms &c ) { + map &here = get_map(); + if( veh.magic ) { add_msg( m_info, _( "This is your %s" ), veh.name ); return; } - player_activity act = veh_interact::run( veh, c ); + player_activity act = veh_interact::run( here, veh, c ); if( act ) { u.set_moves( 0 ); u.assign_activity( act ); @@ -5846,7 +5850,7 @@ void game::control_vehicle() const bool controls_ok = controls_idx >= 0; // controls available to "drive" const bool reins_ok = reins_idx >= 0 // reins + animal available to "drive" && veh->has_engine_type( fuel_type_animal, false ) - && veh->get_harnessed_animal(); + && veh->get_harnessed_animal( here ); if( veh->player_in_control( here, u ) ) { // player already "driving" - offer ways to leave if( controls_ok ) { @@ -11202,6 +11206,7 @@ bool game::walk_move( const tripoint_bub_ms &dest_loc, const bool via_ramp, point_rel_sm game::place_player( const tripoint_bub_ms &dest_loc, bool quick ) { + map &here = get_map(); const optional_vpart_position vp1 = m.veh_at( dest_loc ); if( const std::optional label = vp1.get_label() ) { add_msg( m_info, _( "Label here: %s" ), *label ); @@ -11485,7 +11490,7 @@ point_rel_sm game::place_player( const tripoint_bub_ms &dest_loc, bool quick ) // Drench the player if swimmable if( m.has_flag( ter_furn_flag::TFLAG_SWIMMABLE, u.pos_bub() ) && !m.has_flag_furn( "BRIDGE", u.pos_bub() ) && - !( u.is_mounted() || ( u.in_vehicle && vp1->vehicle().can_float() ) ) && + !( u.is_mounted() || ( u.in_vehicle && vp1->vehicle().can_float( here ) ) ) && !u.has_flag( json_flag_WATERWALKING ) ) { u.drench( 80, u.get_drenching_body_parts( false, false ), false ); diff --git a/src/grab.cpp b/src/grab.cpp index a3e51eb38b57b..387efeaacca6b 100644 --- a/src/grab.cpp +++ b/src/grab.cpp @@ -33,7 +33,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) return false; } const int grabbed_part = grabbed_vehicle_vp->part_index(); - if( monster *mon = grabbed_vehicle->get_harnessed_animal() ) { + if( monster *mon = grabbed_vehicle->get_harnessed_animal( here ) ) { add_msg( m_info, _( "You cannot move this vehicle whilst your %s is harnessed!" ), mon->get_name() ); u.grab( object_type::NONE ); @@ -85,7 +85,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) //vehicle movement: strength check. very strong humans can move about 2,000 kg in a wheelbarrow. int mc = 0; // worst case scenario strength required to move vehicle. - const int max_str_req = grabbed_vehicle->total_mass() / 10_kilogram; + const int max_str_req = grabbed_vehicle->total_mass( here ) / 10_kilogram; // actual strength required to move vehicle. int str_req = 0; // ARM_STR governs dragging heavy things @@ -99,7 +99,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) //if vehicle is rollable we modify str_req based on a function of movecost per wheel. const auto &wheel_indices = grabbed_vehicle->wheelcache; - valid_wheels = grabbed_vehicle->valid_wheel_config(); + valid_wheels = grabbed_vehicle->valid_wheel_config( here ); if( valid_wheels ) { //check for bad push/pull angle if( veh_has_solid && !veh_single_tile && grabbed_vehicle->steering_effectiveness( here ) > 0 ) { @@ -108,7 +108,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) units::angle face_delta = angle_delta( grabbed_vehicle->face.dir(), my_dir.dir() ); tileray my_pos_dir; - tripoint_rel_ms my_angle = u.pos_bub( &here ) - grabbed_vehicle->pos_bub( &here ); + tripoint_rel_ms my_angle = u.pos_bub( &here ) - grabbed_vehicle->pos_bub( here ); my_pos_dir.init( my_angle.xy() ); back_of_vehicle = ( angle_delta( grabbed_vehicle->face.dir(), my_pos_dir.dir() ) > 90_degrees ); invalid_veh_face = ( face_delta > vehicles::steer_increment * 2 - 1_degrees && @@ -122,7 +122,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) } else { str_req = max_str_req / 10; //determine movecost for terrain touching wheels - const tripoint_bub_ms vehpos = grabbed_vehicle->pos_bub( &here ); + const tripoint_bub_ms vehpos = grabbed_vehicle->pos_bub( here ); for( int p : wheel_indices ) { const tripoint_bub_ms wheel_pos = vehpos + grabbed_vehicle->part( p ).precalc[0]; const int mapcost = m.move_cost( wheel_pos, grabbed_vehicle ); @@ -149,7 +149,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) if( str_req <= str ) { if( str_req == max_str_req ) { //if vehicle has no wheels, make a noise. - sounds::sound( grabbed_vehicle->pos_bub( &here ), str_req * 2, sounds::sound_t::movement, + sounds::sound( grabbed_vehicle->pos_bub( here ), str_req * 2, sounds::sound_t::movement, _( "a scraping noise." ), true, "misc", "scraping" ); } //calculate exertion factor and movement penalty @@ -217,12 +217,12 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) grabbed_vehicle->face = tileray( grabbed_vehicle->turn_dir ); precalc_dir = mdir.dir(); } - grabbed_vehicle->precalc_mounts( 1, precalc_dir, grabbed_vehicle->pivot_point() ); + grabbed_vehicle->precalc_mounts( 1, precalc_dir, grabbed_vehicle->pivot_point( here ) ); grabbed_vehicle->pos -= grabbed_vehicle->pivot_displacement().raw(); // Grabbed part has to stay at distance 1 to the player // and in roughly the same direction. - const tripoint_bub_ms new_part_pos = grabbed_vehicle->pos_bub( &here ) + + const tripoint_bub_ms new_part_pos = grabbed_vehicle->pos_bub( here ) + grabbed_vehicle->part( grabbed_part ).precalc[1]; const tripoint_bub_ms expected_pos = u.pos_bub( &here ) + dp + md_next_grab; tripoint_rel_ms actual_dir = tripoint_rel_ms( ( expected_pos - new_part_pos ).xy(), 0 ); @@ -236,7 +236,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) while( !no_player_collision ) { no_player_collision = true; for( const vpart_reference &vp : grabbed_vehicle->get_all_parts() ) { - if( grabbed_vehicle->pos_bub( &here ) + + if( grabbed_vehicle->pos_bub( here ) + vp.part().precalc[1] + actual_dir == u.pos_bub( &here ) + skip ) { no_player_collision = false; break; @@ -258,7 +258,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) const tripoint_bub_ms player_prev = u.pos_bub( &here ); u.setpos( tripoint_bub_ms::zero, false ); std::vector colls; - failed = grabbed_vehicle->collision( colls, actual_dir, true ); + failed = grabbed_vehicle->collision( here, colls, actual_dir, true ); u.setpos( player_prev ); if( !colls.empty() ) { blocker_name = colls.front().target_name; @@ -298,7 +298,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) add_msg( _( "You let go of the %1$s as it starts to fall." ), grabbed_vehicle->disp_name() ); u.grab( object_type::NONE ); u.grab_point = tripoint_rel_ms::zero; - m.set_seen_cache_dirty( grabbed_vehicle->pos_bub( &here ) ); + m.set_seen_cache_dirty( grabbed_vehicle->pos_bub( here ) ); return true; } } else { @@ -309,7 +309,7 @@ bool game::grabbed_veh_move( const tripoint_rel_ms &dp ) for( int p : wheel_indices ) { if( one_in( 2 ) ) { vehicle_part &vp_wheel = grabbed_vehicle->part( p ); - tripoint_bub_ms wheel_p = grabbed_vehicle->bub_part_pos( &here, vp_wheel ); + tripoint_bub_ms wheel_p = grabbed_vehicle->bub_part_pos( here, vp_wheel ); grabbed_vehicle->handle_trap( &m, wheel_p, vp_wheel ); } } diff --git a/src/handle_action.cpp b/src/handle_action.cpp index fc027fee34bbe..532571b5d542b 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -519,7 +519,7 @@ static void pldrive( const tripoint_rel_ms &p ) const bool has_animal_controls = veh->part_with_feature( vp.mount, "CONTROL_ANIMAL", true ) >= 0; const bool has_controls = veh->part_with_feature( vp.mount, "CONTROLS", true ) >= 0; const bool has_animal = veh->has_engine_type( fuel_type_animal, false ) && - veh->get_harnessed_animal(); + veh->get_harnessed_animal( here ); if( !has_controls && !has_animal_controls ) { add_msg( m_info, _( "You can't drive the vehicle from here. You need controls!" ) ); player_character.controlling_vehicle = false; @@ -546,13 +546,13 @@ static void pldrive( const tripoint_rel_ms &p ) } } if( p.z() == -1 ) { - if( veh->check_heli_descend( player_character ) ) { + if( veh->check_heli_descend( here, player_character ) ) { player_character.add_msg_if_player( m_info, _( "You steer the vehicle into a descent." ) ); } else { return; } } else if( p.z() == 1 ) { - if( veh->check_heli_ascend( player_character ) ) { + if( veh->check_heli_ascend( here, player_character ) ) { player_character.add_msg_if_player( m_info, _( "You steer the vehicle into an ascent." ) ); } else { return; @@ -564,7 +564,7 @@ static void pldrive( const tripoint_rel_ms &p ) return; } } - veh->pldrive( get_avatar(), p.x(), p.y(), p.z() ); + veh->pldrive( here, get_avatar(), p.x(), p.y(), p.z() ); } static void pldrive( point_rel_ms d ) @@ -1172,10 +1172,10 @@ static void wait() veh.is_falling || // *not* vertical_velocity, which is only used for collisions veh.velocity || // is moving ( veh.cruise_velocity && ( // would move if it could - ( veh.is_watercraft() && veh.can_float() ) || // is viable watercraft floating on water + ( veh.is_watercraft() && veh.can_float( here ) ) || // is viable watercraft floating on water veh.sufficient_wheel_config() // is viable land vehicle on ground or fording shallow water ) ) || - ( veh.is_in_water( true ) && !veh.can_float() ) // is sinking in deep water + ( veh.is_in_water( true ) && !veh.can_float( here ) ) // is sinking in deep water ) ) { popup( _( "You can't pass time while controlling a moving vehicle." ) ); return; diff --git a/src/handle_liquid.cpp b/src/handle_liquid.cpp index 062c3ccb9241b..d9590741877ad 100644 --- a/src/handle_liquid.cpp +++ b/src/handle_liquid.cpp @@ -56,7 +56,7 @@ static void serialize_liquid_source( player_activity &act, const vehicle &veh, c act.values.push_back( static_cast( liquid_source_type::VEHICLE ) ); act.values.push_back( part_num ); if( part_num != -1 ) { - act.coords.push_back( here.get_abs( veh.bub_part_pos( &here, part_num ) ) ); + act.coords.push_back( here.get_abs( veh.bub_part_pos( here, part_num ) ) ); } else { act.coords.push_back( veh.pos_abs() ); } @@ -88,7 +88,7 @@ static void serialize_liquid_target( player_activity &act, const vpart_reference map &here = get_map(); act.values.push_back( static_cast( liquid_target_type::VEHICLE ) ); act.values.push_back( 0 ); // dummy - act.coords.push_back( here.get_abs( vp.vehicle().bub_part_pos( &here, 0 ) ) ); + act.coords.push_back( here.get_abs( vp.vehicle().bub_part_pos( here, 0 ) ) ); act.values.push_back( vp.part_index() ); // tank part index } @@ -385,6 +385,7 @@ static bool handle_item_target( Character &player_character, item &liquid, liqui static bool handle_vehicle_target( Character &player_character, item &liquid, liquid_dest_opt &target, const std::function &create_activity ) { + map &here = get_map(); if( target.veh == nullptr ) { return false; } @@ -398,7 +399,8 @@ static bool handle_vehicle_target( Character &player_character, item &liquid, round_up( to_liter( liquid.charges * stack ), 1 ), liquid.tname() ); - const std::optional vpr = veh_interact::select_part( *target.veh, sel, title ); + const std::optional vpr = veh_interact::select_part( here, *target.veh, sel, + title ); if( !vpr ) { return false; } diff --git a/src/iexamine.cpp b/src/iexamine.cpp index 112fed9a54516..8f7ca46b82c0b 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1565,10 +1565,10 @@ void iexamine::elevator( Character &you, const tripoint_bub_ms &examp ) } for( vehicle *v : vehs.v ) { - tripoint_bub_ms const p = _rotate_point_sm( { v->pos_bub( &here ).xy(), movez}, + tripoint_bub_ms const p = _rotate_point_sm( { v->pos_bub( here ).xy(), movez}, erot, sm_orig ); - here.displace_vehicle( *v, p - v->pos_bub( &here ) ); + here.displace_vehicle( *v, p - v->pos_bub( here ) ); v->turn( erot * 90_degrees ); v->face = tileray( v->turn_dir ); v->precalc_mounts( 0, v->turn_dir, v->pivot_anchor[0] ); diff --git a/src/iexamine_actors.cpp b/src/iexamine_actors.cpp index 9550d3c0b44c8..00bffa56c510d 100644 --- a/src/iexamine_actors.cpp +++ b/src/iexamine_actors.cpp @@ -37,7 +37,7 @@ void appliance_convert_examine_actor::call( Character &you, const tripoint_bub_m here.ter_set( examp, *ter_set ); } - place_appliance( examp, vpart_appliance_from_item( appliance_item ), you ); + place_appliance( here, examp, vpart_appliance_from_item( appliance_item ), you ); } void appliance_convert_examine_actor::finalize() const diff --git a/src/item.cpp b/src/item.cpp index ac530ce8ab7e0..bf5f9776a66e1 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -14212,13 +14212,13 @@ ret_val item::link_to( vehicle &veh, const point_rel_ms &mount, link_state vehicle_part prev_veh_part( vpid, item( *this ) ); prev_veh_part.target.first = prev_part_target.first; prev_veh_part.target.second = prev_part_target.second; - prev_veh->install_part( prev_mount, std::move( prev_veh_part ) ); + prev_veh->install_part( here, prev_mount, std::move( prev_veh_part ) ); prev_veh->precalc_mounts( 1, prev_veh->pivot_rotation[1], prev_veh->pivot_anchor[1] ); vehicle_part sel_veh_part( vpid, item( *this ) ); sel_veh_part.target.first = sel_part_target.first; sel_veh_part.target.second = sel_part_target.second; - veh.install_part( mount, std::move( sel_veh_part ) ); + veh.install_part( here, mount, std::move( sel_veh_part ) ); veh.precalc_mounts( 1, veh.pivot_rotation[1], veh.pivot_anchor[1] ); if( link_type == link_state::vehicle_tow ) { diff --git a/src/item_location.cpp b/src/item_location.cpp index 49bc18e237f4c..c136bf81be39b 100644 --- a/src/item_location.cpp +++ b/src/item_location.cpp @@ -486,7 +486,7 @@ class item_location::impl::item_on_vehicle : public item_location::impl tripoint_bub_ms pos_bub() const override { map &here = get_map(); - return cur.veh.bub_part_pos( &here, cur.part ); + return cur.veh.bub_part_pos( here, cur.part ); } Character *carrier() const override { @@ -536,7 +536,7 @@ class item_location::impl::item_on_vehicle : public item_location::impl map &here = get_map(); item *obj = target(); int mv = ch.item_handling_cost( *obj, true, VEHICLE_HANDLING_PENALTY, qty ); - mv += 100 * rl_dist( ch.pos_bub( &here ), cur.veh.bub_part_pos( &here, cur.part ) ); + mv += 100 * rl_dist( ch.pos_bub( &here ), cur.veh.bub_part_pos( here, cur.part ) ); // TODO: handle unpacking costs diff --git a/src/item_stack.h b/src/item_stack.h index 0c39cbfb6b926..9c4256efc90f8 100644 --- a/src/item_stack.h +++ b/src/item_stack.h @@ -37,7 +37,7 @@ class item_stack size_t size() const; bool empty() const; - virtual void insert( const item &newitem ) = 0; + virtual void insert( map &here, const item &newitem ) = 0; virtual iterator erase( const_iterator it ) = 0; virtual void clear(); // Will cause a debugmsg if there is not exactly one item at the location diff --git a/src/iuse.cpp b/src/iuse.cpp index 9ff7924e60998..56b79a9ad108d 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -3050,7 +3050,7 @@ std::optional iuse::siphon( Character *p, item *, const tripoint_bub_ms & ) p->add_msg_if_player( m_info, _( "There's no vehicle there." ) ); return std::nullopt; } - act_vehicle_siphon( v ); + act_vehicle_siphon( here, v ); return 1; } @@ -7318,7 +7318,7 @@ static vehicle *pickveh( const tripoint_bub_ms ¢er, bool advanced ) for( wrapped_vehicle &veh : here.get_vehicles() ) { vehicle *&v = veh.v; - if( rl_dist( center, v->pos_bub( &here ) ) < 40 && + if( rl_dist( center, v->pos_bub( here ) ) < 40 && v->fuel_left( here, itype_battery ) > 0 && ( !empty( v->get_avail_parts( advctrl ) ) || ( !advanced && !empty( v->get_avail_parts( ctrl ) ) ) ) ) { @@ -7328,7 +7328,7 @@ static vehicle *pickveh( const tripoint_bub_ms ¢er, bool advanced ) std::vector locations; for( int i = 0; i < static_cast( vehs.size() ); i++ ) { vehicle *veh = vehs[i]; - locations.push_back( veh->pos_bub( &here ) ); + locations.push_back( veh->pos_bub( here ) ); pmenu.addentry( i, true, MENU_AUTOASSIGN, veh->name ); } diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 1bb105c5242a4..bbacd8685c8e8 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -1328,7 +1328,7 @@ std::optional deploy_appliance_actor::use( Character *p, item &it, // TODO: Use map aware operation when available it.spill_contents( suitable.value() ); // TODO: Use map aware operation when available - if( !place_appliance( suitable.value(), + if( !place_appliance( *here, suitable.value(), vpart_appliance_from_item( appliance_base ), *p, it ) ) { // failed to place somehow, cancel!! return 0; diff --git a/src/lightmap.cpp b/src/lightmap.cpp index ae3a16218daf4..c0a832b1dff89 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -589,7 +589,7 @@ void map::generate_lightmap( const int zlev ) for( const vehicle_part *pt : lights ) { const vpart_info &vp = pt->info(); - tripoint_bub_ms src = v->bub_part_pos( this, *pt ); + tripoint_bub_ms src = v->bub_part_pos( *this, *pt ); if( !inbounds( src ) ) { continue; @@ -1123,7 +1123,7 @@ void map::build_seen_cache( const tripoint_bub_ms &origin, const int target_z, i continue; // Player not at camera control, so cameras don't work } - const tripoint_bub_ms mirror_pos = veh->bub_part_pos( this, vp_mirror ); + const tripoint_bub_ms mirror_pos = veh->bub_part_pos( *this, vp_mirror ); // Determine how far the light has already traveled so mirrors // don't cheat the light distance falloff. diff --git a/src/map.cpp b/src/map.cpp index a92a79130dcef..5641887ccc691 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -233,6 +233,11 @@ map_stack::iterator map_stack::erase( map_stack::const_iterator it ) return myorigin->i_rem( location, it ); } +void map_stack::insert( map &, const item &newitem ) +{ + myorigin->add_item_or_charges( location, newitem ); +} + void map_stack::insert( const item &newitem ) { myorigin->add_item_or_charges( location, newitem ); @@ -470,7 +475,7 @@ void map::add_vehicle_to_cache( vehicle *veh ) if( vpr.part().removed ) { continue; } - const tripoint_bub_ms p = veh->bub_part_pos( this, vpr.part() ); + const tripoint_bub_ms p = veh->bub_part_pos( *this, vpr.part() ); level_cache &ch = get_cache( p.z() ); ch.set_veh_cached_parts( p, *veh, static_cast( vpr.part_index() ) ); if( inbounds( p ) ) { @@ -592,7 +597,7 @@ std::unique_ptr map::detach_vehicle( vehicle *veh ) unboard_vehicle( part, passenger ); } } - veh->invalidate_towing( true ); + veh->invalidate_towing( *this, true ); submap *const current_submap = get_submap_at_grid( veh->sm_pos - abs_sub.xy() ); if( current_submap == nullptr ) { debugmsg( "Tried to detach vehicle at %s but the submap is not loaded", @@ -660,7 +665,7 @@ void map::vehmove() } else if( veh->is_patrolling ) { veh->autopilot_patrol( this ); } - veh->gain_moves(); + veh->gain_moves( *this ); veh->slow_leak( *this ); wrapped_vehicle w; w.v = veh; @@ -738,7 +743,7 @@ bool map::vehproceed( VehicleList &vehicle_list ) return false; } - cur_veh->v = cur_veh->v->act_on_map(); + cur_veh->v = cur_veh->v->act_on_map( *this ); if( cur_veh->v == nullptr ) { vehicle_list = get_vehicles(); } @@ -790,7 +795,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler return &veh; } - veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() ); + veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point( *this ) ); // cancel out any movement of the vehicle due only to a change in pivot tripoint_rel_ms dp1 = dp - veh.pivot_displacement(); @@ -815,7 +820,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler size_t collision_attempts = 10; do { collisions.clear(); - veh.collision( collisions, dp1, false ); + veh.collision( *this, collisions, dp1, false ); // Vehicle collisions std::map > veh_collisions; @@ -851,7 +856,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler } else { impulse += coll_dmg; veh.damage( *this, part_num, coll_dmg, damage_bash ); - veh.damage_all( coll_dmg / 2, coll_dmg, damage_bash, collision_point ); + veh.damage_all( *this, coll_dmg / 2, coll_dmg, damage_bash, collision_point ); } } } @@ -876,7 +881,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler veh.stop_autodriving(); const int volume = std::min( 100, std::sqrt( impulse ) ); // TODO: Center the sound at weighted (by impulse) average of collisions - sounds::sound( veh.pos_bub( this ), volume, sounds::sound_t::combat, _( "crash!" ), + sounds::sound( veh.pos_bub( *this ), volume, sounds::sound_t::combat, _( "crash!" ), false, "smash_success", "hit_vehicle" ); } @@ -886,7 +891,8 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler } // If not enough wheels, mess up the ground a bit. - if( !vertical && !veh.valid_wheel_config() && !( veh.is_watercraft() && veh.can_float() ) && + if( !vertical && !veh.valid_wheel_config( *this ) && !( veh.is_watercraft() && + veh.can_float( *this ) ) && !veh.is_flying_in_air() && dp.z() == 0 ) { veh.velocity -= std::clamp( veh.velocity, -2000, 2000 ); // extra drag for( const tripoint_abs_ms &p : veh.get_points() ) { @@ -932,7 +938,7 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler displace_vehicle( veh, dp1 ); level_vehicle( veh ); } else if( !vertical ) { - veh.stop(); + veh.stop( *this ); } veh.check_falling_or_floating(); // If the PC is in the currently moved vehicle, adjust the @@ -953,12 +959,12 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler // The math needs to be floating-point to work, so the values might as well be. const float vehicle_grounded_wheel_area = static_cast( vehicle_wheel_traction( veh, true ) ); const float weight_to_damage_factor = 0.05f; // Nobody likes a magic number. - const float vehicle_mass_kg = to_kilogram( veh.total_mass() ); + const float vehicle_mass_kg = to_kilogram( veh.total_mass( *this ) ); for( const int vp_wheel_idx : wheel_indices ) { vehicle_part &vp_wheel = veh.part( vp_wheel_idx ); const vpart_info &vpi_wheel = vp_wheel.info(); - const tripoint_bub_ms wheel_p = veh.bub_part_pos( this, vp_wheel ); + const tripoint_bub_ms wheel_p = veh.bub_part_pos( *this, vp_wheel ); if( one_in( 2 ) && displace_water( wheel_p ) ) { sounds::sound( wheel_p, 4, sounds::sound_t::movement, _( "splash!" ), false, "environment", "splash" ); @@ -980,12 +986,12 @@ vehicle *map::move_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const tiler } } if( veh.is_towing() ) { - veh.do_towing_move(); + veh.do_towing_move( *this ); // veh.do_towing_move() may cancel towing, so we need to recheck is_towing here if( veh.is_towing() && veh.tow_data.get_towed()->tow_cable_too_far() ) { add_msg( m_info, _( "A towing cable snaps off of %s." ), veh.tow_data.get_towed()->disp_name() ); - veh.tow_data.get_towed()->invalidate_towing( true ); + veh.tow_data.get_towed()->invalidate_towing( *this, true ); } } // Redraw scene, but only if the player is not engaged in an activity and @@ -1027,8 +1033,8 @@ float map::vehicle_vehicle_collision( vehicle &veh, vehicle &veh2, // Check whether avatar sees the collision, and log a message if so const avatar &you = get_avatar(); - const tripoint_bub_ms part1_pos = veh.bub_part_pos( this, vp1 ); - const tripoint_bub_ms part2_pos = veh2.bub_part_pos( this, vp2 ); + const tripoint_bub_ms part1_pos = veh.bub_part_pos( *this, vp1 ); + const tripoint_bub_ms part2_pos = veh2.bub_part_pos( *this, vp2 ); if( you.sees( part1_pos ) || you.sees( part2_pos ) ) { //~ %1$s: first vehicle name (without "the") //~ %2$s: first part name @@ -1050,23 +1056,23 @@ float map::vehicle_vehicle_collision( vehicle &veh, vehicle &veh2, // and 38mph is 3800 'velocity' rl_vec2d velo_veh1 = veh.velo_vec(); rl_vec2d velo_veh2 = veh2.velo_vec(); - const float m1 = to_kilogram( veh.total_mass() ); - const float m2 = to_kilogram( veh2.total_mass() ); + const float m1 = to_kilogram( veh.total_mass( *this ) ); + const float m2 = to_kilogram( veh2.total_mass( *this ) ); //Energy of vehicle1 and vehicle2 before collision float E = 0.5 * m1 * velo_veh1.magnitude() * velo_veh1.magnitude() + 0.5 * m2 * velo_veh2.magnitude() * velo_veh2.magnitude(); // Collision_axis - point_rel_ms cof1 = veh .rotated_center_of_mass(); - point_rel_ms cof2 = veh2.rotated_center_of_mass(); + point_rel_ms cof1 = veh .rotated_center_of_mass( *this ); + point_rel_ms cof2 = veh2.rotated_center_of_mass( *this ); int &x_cof1 = cof1.x(); int &y_cof1 = cof1.y(); int &x_cof2 = cof2.x(); int &y_cof2 = cof2.y(); rl_vec2d collision_axis_y; - const tripoint_bub_ms veh_pos = veh.pos_bub( this ); - const tripoint_bub_ms veh2_pos = veh2.pos_bub( this ); + const tripoint_bub_ms veh_pos = veh.pos_bub( *this ); + const tripoint_bub_ms veh2_pos = veh2.pos_bub( *this ); collision_axis_y.x = ( veh_pos.x() + x_cof1 ) - ( veh2_pos.x() + x_cof2 ); collision_axis_y.y = ( veh_pos.y() + y_cof1 ) - ( veh2_pos.y() + y_cof2 ); collision_axis_y = collision_axis_y.normalized(); @@ -1127,7 +1133,7 @@ float map::vehicle_vehicle_collision( vehicle &veh, vehicle &veh2, float d_E = E - E_a; //Lost energy at collision -> deformation energy dmg = std::abs( d_E / 1000 / 2000 ); //adjust to balance damage } else { - const float m1 = to_kilogram( veh.total_mass() ); + const float m1 = to_kilogram( veh.total_mass( *this ) ); // Collision is perfectly inelastic for simplicity // Assume veh2 is standing still dmg = std::abs( veh.vertical_velocity / 100.0f ) * m1 / 10; @@ -1182,7 +1188,7 @@ float map::vehicle_vehicle_collision( vehicle &veh, vehicle &veh2, if( dmg2_part > 100 ) { // Shake vehicle because of collision - veh2.damage_all( dmg2_part / 2, dmg2_part, damage_bash, epicenter2 ); + veh2.damage_all( *this, dmg2_part / 2, dmg2_part, damage_bash, epicenter2 ); } if( dmg_veh1 > 800 ) { @@ -1307,7 +1313,7 @@ VehicleList map::get_vehicles( const tripoint_bub_ms &start, const tripoint_bub_ elem->sm_pos.z() = cz; wrapped_vehicle w; w.v = elem.get(); - w.pos = w.v->pos_bub( this ); + w.pos = w.v->pos_bub( *this ); vehs.push_back( w ); } } @@ -1439,7 +1445,7 @@ void map::unboard_vehicle( const tripoint_bub_ms &p, bool dead_passenger ) bool map::displace_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const bool adjust_pos, const std::set &parts_to_move ) { - const tripoint_bub_ms src = veh.pos_bub( this ); + const tripoint_bub_ms src = veh.pos_bub( *this ); // handle vehicle ramps int ramp_offset = 0; if( adjust_pos ) { @@ -1498,7 +1504,7 @@ bool map::displace_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const bool // move the vehicle // don't let it go off grid if( !inbounds( dst ) ) { - veh.stop(); + veh.stop( *this ); // Silent debug dbg( D_ERROR ) << "map:displace_vehicle: Stopping vehicle, displaced dp=(" << dp.x() << ", " << dp.y() << ", " << dp.z() << ")"; @@ -1532,7 +1538,7 @@ bool map::displace_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const bool continue; } Creature *psg = r.psg; - const tripoint_bub_ms part_pos = veh.bub_part_pos( this, prt ); + const tripoint_bub_ms part_pos = veh.bub_part_pos( *this, prt ); if( psg == nullptr ) { debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?", prt, part_pos.x(), part_pos.y(), part_pos.z(), @@ -1616,7 +1622,7 @@ bool map::displace_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const bool } } } - veh.check_is_heli_landed(); + veh.check_is_heli_landed( *this ); } if( remote ) { @@ -1635,7 +1641,7 @@ bool map::displace_vehicle( vehicle &veh, const tripoint_rel_ms &dp, const bool void map::level_vehicle( vehicle &veh ) { int cnt = 0; - while( !veh.level_vehicle() && cnt < ( 2 * OVERMAP_DEPTH ) ) { + while( !veh.level_vehicle( *this ) && cnt < ( 2 * OVERMAP_DEPTH ) ) { cnt++; } } @@ -5552,7 +5558,7 @@ void map::process_items() level_cache &cache = access_cache( gz ); std::set submaps_with_vehicles; for( vehicle *this_vehicle : cache.vehicle_list ) { - tripoint_bub_ms pos = this_vehicle->pos_bub( this ); + tripoint_bub_ms pos = this_vehicle->pos_bub( *this ); submaps_with_vehicles.emplace( pos.x() / SEEX, pos.y() / SEEY, pos.z() ); } for( const tripoint &pos : submaps_with_vehicles ) { @@ -6036,7 +6042,7 @@ std::list map::use_charges( const std::vector &reachable_ const optional_vpart_position vp = veh_at( p ); if( vp ) { - std::list tmp = vp->vehicle().use_charges( *vp, type, quantity, filter, in_tools ); + std::list tmp = vp->vehicle().use_charges( *this, *vp, type, quantity, filter, in_tools ); ret.splice( ret.end(), tmp ); if( quantity <= 0 ) { return ret; @@ -9435,7 +9441,7 @@ static void vehicle_caching_internal( level_cache &zch, const vpart_reference &v auto &floor_cache = zch.floor_cache; const size_t part = vp.part_index(); - const tripoint_bub_ms part_pos = v->bub_part_pos( &here, vp.part() ); + const tripoint_bub_ms part_pos = v->bub_part_pos( here, vp.part() ); bool vehicle_is_opaque = vp.has_feature( VPFLAG_OPAQUE ) && !vp.part().is_broken(); @@ -9463,7 +9469,7 @@ static void vehicle_caching_internal_above( level_cache &zch_above, const vpart_ map &here = get_map(); // TODO: Check is this is actually reasonable. Probably need to feed the map in. if( vp.has_feature( VPFLAG_ROOF ) || vp.has_feature( VPFLAG_OPAQUE ) ) { - const tripoint_bub_ms part_pos = v->bub_part_pos( &here, vp.part() ); + const tripoint_bub_ms part_pos = v->bub_part_pos( here, vp.part() ); zch_above.floor_cache[part_pos.x()][part_pos.y()] = true; } } @@ -9476,7 +9482,7 @@ void map::do_vehicle_caching( int z ) } for( vehicle *v : ch->vehicle_list ) { for( const vpart_reference &vp : v->get_all_parts_with_fakes() ) { - const tripoint_bub_ms part_pos = v->bub_part_pos( this, vp.part() ); + const tripoint_bub_ms part_pos = v->bub_part_pos( *this, vp.part() ); if( !inbounds( part_pos.xy() ) ) { continue; } diff --git a/src/map.h b/src/map.h index 6dbe8d5801461..0bed532f08ef5 100644 --- a/src/map.h +++ b/src/map.h @@ -112,7 +112,8 @@ class map_stack : public item_stack public: map_stack( cata::colony *newstack, tripoint_bub_ms newloc, map *neworigin ) : item_stack( newstack ), location( newloc ), myorigin( neworigin ) {} - void insert( const item &newitem ) override; + void insert( map &, const item &newitem ) override; + void insert( const item &newitem ); iterator erase( const_iterator it ) override; int count_limit() const override { return MAX_ITEM_IN_SQUARE; diff --git a/src/mapgen.cpp b/src/mapgen.cpp index b309a3c4f5323..801731fbeb060 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -7159,7 +7159,7 @@ vehicle *map::add_vehicle( const vproto_id &type, const tripoint_bub_ms &p, cons veh->sm_pos = abs_sub.xy() + rebase_rel( quotient ); veh->pos = remainder; veh->init_state( *this, veh_fuel, veh_status, force_status ); - veh->place_spawn_items(); + veh->place_spawn_items( *this ); veh->face.init( dir ); veh->turn_dir = dir; // for backwards compatibility, we always spawn with a pivot point of (0,0) so @@ -7215,7 +7215,7 @@ std::unique_ptr map::add_vehicle_to_map( for( std::vector::const_iterator part = frame_indices.begin(); part != frame_indices.end(); part++ ) { - const tripoint_bub_ms p = veh_to_add->bub_part_pos( this, *part ); + const tripoint_bub_ms p = veh_to_add->bub_part_pos( *this, *part ); if( veh_to_add->part( *part ).is_fake ) { continue; @@ -7290,7 +7290,7 @@ std::unique_ptr map::add_vehicle_to_map( const ret_val valid_mount = first_veh->can_mount( target_point, vpi ); if( valid_mount.success() ) { // make a copy so we don't interfere with veh_to_add->remove_part below - first_veh->install_part( target_point, vehicle_part( *vp ) ); + first_veh->install_part( *this, target_point, vehicle_part( *vp ) ); } // ignore parts that would make invalid vehicle configuration } diff --git a/src/monmove.cpp b/src/monmove.cpp index 9455dd497dc97..5f5e9b35e9217 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -2404,7 +2404,7 @@ void monster::shove_vehicle( const tripoint_bub_ms &remote_destination, optional_vpart_position vp = here.veh_at( nearby_destination ); if( vp ) { vehicle &veh = vp->vehicle(); - const units::mass veh_mass = veh.total_mass(); + const units::mass veh_mass = veh.total_mass( here ); int shove_moves_minimal = 0; int shove_veh_mass_moves_factor = 0; int shove_velocity = 0; diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 0740722766b5a..8b2b1e3458fef 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -1810,7 +1810,7 @@ void npc::execute_action( npc_action action ) } // A seat is available if we can move there and it's either unassigned or assigned to us auto available_seat = [&]( const vehicle_part & pt ) { - tripoint_bub_ms target = veh->bub_part_pos( &here, pt ); + tripoint_bub_ms target = veh->bub_part_pos( here, pt ); if( !pt.is_seat() ) { return false; } @@ -1875,7 +1875,7 @@ void npc::execute_action( npc_action action ) const int cur_part = seats[i].second; - tripoint_bub_ms pp = veh->bub_part_pos( &here, cur_part ); + tripoint_bub_ms pp = veh->bub_part_pos( here, cur_part ); update_path( pp, true ); if( !path.empty() ) { // All is fine diff --git a/src/overmap_ui.cpp b/src/overmap_ui.cpp index 1ad90f5396480..11ff2b428e7c1 100644 --- a/src/overmap_ui.cpp +++ b/src/overmap_ui.cpp @@ -1793,8 +1793,8 @@ static std::vector get_overmap_path_to( const tripoint_abs_omt player_veh = &vp->vehicle(); // for now we can only handle flyers if already in the air const bool can_fly = player_veh->is_rotorcraft( here ) && player_veh->is_flying_in_air(); - const bool can_float = player_veh->can_float(); - const bool can_drive = player_veh->valid_wheel_config(); + const bool can_float = player_veh->can_float( here ); + const bool can_drive = player_veh->valid_wheel_config( here ); // TODO: check engines/fuel if( can_fly ) { params = overmap_path_params::for_aircraft(); diff --git a/src/ranged.cpp b/src/ranged.cpp index 9335e81ef969c..1ffa06a3b803d 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -521,7 +521,7 @@ target_handler::trajectory target_handler::mode_turrets( avatar &you, vehicle &v int range_total = 0; for( vehicle_part *t : turrets ) { int range = veh.turret_query( *t ).range(); - tripoint_bub_ms pos = veh.bub_part_pos( &here, *t ); + tripoint_bub_ms pos = veh.bub_part_pos( here, *t ); int res = 0; res = std::max( res, rl_dist( you.pos_bub(), pos + point( range, 0 ) ) ); @@ -2282,7 +2282,7 @@ static void cycle_action( item &weap, const itype_id &ammo, map *here, const tri if( !( brass_catcher && brass_catcher->put_in( linkage, pocket_type::CONTAINER ).success() ) ) { if( ovp_cargo ) { - ovp_cargo->items().insert( linkage ); + ovp_cargo->items().insert( *here, linkage ); } else { here->add_item_or_charges( eject, linkage ); } @@ -3389,7 +3389,7 @@ void target_ui::update_turrets_in_range() for( vehicle_part *t : *vturrets ) { turret_data td = veh->turret_query( *t ); if( td.in_range( here.get_abs( dst ) ) ) { - tripoint_bub_ms src = veh->bub_part_pos( &here, *t ); + tripoint_bub_ms src = veh->bub_part_pos( here, *t ); turrets_in_range.push_back( {t, line_to( src, dst )} ); } } diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 6bd05d36fdc2f..cacfc97675086 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -3584,7 +3584,7 @@ void vehicle::serialize( JsonOut &json ) const if( is_towed() ) { vehicle *tower = tow_data.get_towed_by(); if( tower ) { - other_tow_temp_point = tower->bub_part_pos( &here, tower->get_tow_part() ); + other_tow_temp_point = tower->bub_part_pos( here, tower->get_tow_part() ); } } json.member( "other_tow_point", other_tow_temp_point ); diff --git a/src/sounds.cpp b/src/sounds.cpp index 355dd52a5e254..cc4f7c115873a 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -1049,10 +1049,10 @@ void sfx::do_vehicle_exterior_engine_sfx() for( wrapped_vehicle vehicle : vehs ) { if( vehicle.v->vehicle_noise > 0 && vehicle.v->vehicle_noise - - sound_distance( player_character.pos_bub( &here ), vehicle.v->pos_bub( &here ) ) > noise_factor ) { + sound_distance( player_character.pos_bub( &here ), vehicle.v->pos_bub( here ) ) > noise_factor ) { noise_factor = vehicle.v->vehicle_noise - sound_distance( player_character.pos_bub( &here ), - vehicle.v->pos_bub( &here ) ); + vehicle.v->pos_bub( here ) ); veh = vehicle.v; } } @@ -1091,7 +1091,7 @@ void sfx::do_vehicle_exterior_engine_sfx() if( is_channel_playing( ch ) ) { if( engine_external_id_and_variant == id_and_variant ) { - Mix_SetPosition( ch_int, to_degrees( get_heard_angle( veh->pos_bub( &here ) ) ), 0 ); + Mix_SetPosition( ch_int, to_degrees( get_heard_angle( veh->pos_bub( here ) ) ), 0 ); set_channel_volume( ch, vol ); add_msg_debug( debugmode::DF_SOUND, "PLAYING exterior_engine_sound, vol: ex:%d true:%d", vol, Mix_Volume( ch_int, -1 ) ); @@ -1101,7 +1101,7 @@ void sfx::do_vehicle_exterior_engine_sfx() add_msg_debug( debugmode::DF_SOUND, "STOP exterior_engine_sound, change id/var" ); play_ambient_variant_sound( id_and_variant.first, id_and_variant.second, seas_str, indoors, night, 128, ch, 0 ); - Mix_SetPosition( ch_int, to_degrees( get_heard_angle( veh->pos_bub( &here ) ) ), 0 ); + Mix_SetPosition( ch_int, to_degrees( get_heard_angle( veh->pos_bub( here ) ) ), 0 ); set_channel_volume( ch, vol ); add_msg_debug( debugmode::DF_SOUND, "START exterior_engine_sound %s %s vol: %d", id_and_variant.first, @@ -1112,7 +1112,7 @@ void sfx::do_vehicle_exterior_engine_sfx() play_ambient_variant_sound( id_and_variant.first, id_and_variant.second, seas_str, indoors, night, 128, ch, 0 ); add_msg_debug( debugmode::DF_SOUND, "Vol: %d %d", vol, Mix_Volume( ch_int, -1 ) ); - Mix_SetPosition( ch_int, to_degrees( get_heard_angle( veh->pos_bub( &here ) ) ), 0 ); + Mix_SetPosition( ch_int, to_degrees( get_heard_angle( veh->pos_bub( here ) ) ), 0 ); add_msg_debug( debugmode::DF_SOUND, "Vol: %d %d", vol, Mix_Volume( ch_int, -1 ) ); set_channel_volume( ch, vol ); add_msg_debug( debugmode::DF_SOUND, "START exterior_engine_sound NEW %s %s vol: ex:%d true:%d", diff --git a/src/turret.cpp b/src/turret.cpp index 114cddb3fec36..56666201f8f0f 100644 --- a/src/turret.cpp +++ b/src/turret.cpp @@ -473,7 +473,7 @@ void vehicle::turrets_set_targeting() for( vehicle_part &p : parts ) { if( p.is_turret() ) { turrets.push_back( &p ); - locations.push_back( bub_part_pos( &here, p ) ); + locations.push_back( bub_part_pos( here, p ) ); } } @@ -529,7 +529,7 @@ void vehicle::turrets_set_mode() for( vehicle_part &p : parts ) { if( p.base.is_gun() ) { turrets.push_back( &p ); - locations.push_back( bub_part_pos( &here, p ) ); + locations.push_back( bub_part_pos( here, p ) ); } } @@ -581,7 +581,7 @@ npc &vehicle_part::get_targeting_npc( vehicle &veh ) brain.name = string_format( _( "The %s turret" ), get_base().tname( 1 ) ); brain.set_skill_level( get_base().gun_skill(), 8 ); } - cpu.brain->setpos( veh.bub_part_pos( &here, *this ) ); + cpu.brain->setpos( veh.bub_part_pos( here, *this ) ); cpu.brain->recalc_sight_limits(); return *cpu.brain; } @@ -615,7 +615,7 @@ int vehicle::automatic_fire_turret( vehicle_part &pt ) } // The position of the vehicle part. - tripoint_bub_ms pos = bub_part_pos( &here, pt ); + tripoint_bub_ms pos = bub_part_pos( here, pt ); // Create the targeting computer's npc npc &cpu = pt.get_targeting_npc( *this ); diff --git a/src/veh_appliance.cpp b/src/veh_appliance.cpp index 72c41c72f6147..554cc7fb8847f 100644 --- a/src/veh_appliance.cpp +++ b/src/veh_appliance.cpp @@ -56,12 +56,11 @@ vpart_id vpart_appliance_from_item( const itype_id &item_id ) return vpart_ap_standing_lamp; } -bool place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, +bool place_appliance( map &here, const tripoint_bub_ms &p, const vpart_id &vpart, const Character &owner, const std::optional &base ) { const vpart_info &vpinfo = vpart.obj(); - map &here = get_map(); vehicle *veh = here.add_vehicle( vehicle_prototype_none, p, 0_degrees, 0, 0 ); if( !veh ) { @@ -78,9 +77,9 @@ bool place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, // transform the deploying item into what it *should* be before storing it copied.convert( vpinfo.base_item ); } - partnum = veh->install_part( point_rel_ms::zero, vpart, std::move( copied ) ); + partnum = veh->install_part( here, point_rel_ms::zero, vpart, std::move( copied ) ); } else { - partnum = veh->install_part( point_rel_ms::zero, vpart ); + partnum = veh->install_part( here, point_rel_ms::zero, vpart ); } if( partnum == -1 ) { // unrecoverable, failed to be installed somehow @@ -123,16 +122,16 @@ bool place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, // Make some lighting appliances directed if( vpinfo.has_flag( flag_HALF_CIRCLE_LIGHT ) && partnum != -1 ) { - orient_part( veh, vpinfo, partnum ); + orient_part( here, veh, vpinfo, partnum ); } veh->set_owner( owner ); return true; } -player_activity veh_app_interact::run( vehicle &veh, const point_rel_ms &p ) +player_activity veh_app_interact::run( map &here, vehicle &veh, const point_rel_ms &p ) { veh_app_interact ap( veh, p ); - ap.app_loop(); + ap.app_loop( here ); return ap.act; } @@ -150,21 +149,19 @@ veh_app_interact::veh_app_interact( vehicle &veh, const point_rel_ms &p ) } // @returns true if a battery part exists on any vehicle connected to veh -static bool has_battery_in_grid( vehicle *veh ) +static bool has_battery_in_grid( map &here, vehicle *veh ) { - map &here = get_map(); - return !veh->search_connected_batteries( here ).empty(); } -void veh_app_interact::init_ui_windows() +void veh_app_interact::init_ui_windows( map &here ) { imenu.reset(); - populate_app_actions(); + populate_app_actions( here ); - int height_info = veh->get_printable_fuel_types().size() + 2; + int height_info = veh->get_printable_fuel_types( here ).size() + 2; - if( !has_battery_in_grid( veh ) ) { + if( !has_battery_in_grid( here, veh ) ) { height_info++; } if( !veh->batteries.empty() ) { @@ -215,16 +212,14 @@ void veh_app_interact::init_ui_windows() imenu.setup(); } -void veh_app_interact::draw_info() +void veh_app_interact::draw_info( map &here ) { - map &here = get_map(); - werase( w_info ); int row = 0; // Fuel indicators - veh->print_fuel_indicators( w_info, point( 0, row ), 0, true, true, true, true ); - row += veh->get_printable_fuel_types().size(); + veh->print_fuel_indicators( here, w_info, point( 0, row ), 0, true, true, true, true ); + row += veh->get_printable_fuel_types( here ).size(); // Onboard battery power if( !veh->batteries.empty() ) { @@ -254,7 +249,7 @@ void veh_app_interact::draw_info() wprintz( w_info, rcol, rstr ); }; - if( !has_battery_in_grid( veh ) ) { + if( !has_battery_in_grid( here, veh ) ) { mvwprintz( w_info, point( 0, row ), c_light_red, _( "Appliance has no connection to a battery." ) ); row++; } @@ -423,10 +418,8 @@ void veh_app_interact::refill() } } -void veh_app_interact::siphon() +void veh_app_interact::siphon( map &here ) { - map &here = get_map(); - std::vector ptlist; for( const vpart_reference &vpr : veh->get_any_parts( VPFLAG_FLUIDTANK ) ) { if( vpr.part().get_base().has_item_with( []( const item & it ) { @@ -466,9 +459,8 @@ void veh_app_interact::rename() } } -void veh_app_interact::remove() +void veh_app_interact::remove( map &here ) { - map &here = get_map(); const tripoint_abs_ms a_point_abs( veh->mount_to_tripoint_abs( a_point ) ); vehicle_part *vp; @@ -525,19 +517,16 @@ bool veh_app_interact::can_disconnect() return true; } -void veh_app_interact::disconnect() +void veh_app_interact::disconnect( map &here ) { - map &here = get_map(); - veh->separate_from_grid( &here, a_point ); get_player_character().pause(); } -void veh_app_interact::plug() +void veh_app_interact::plug( map &here ) { - map &here = get_map(); const int part = veh->part_at( veh->coord_translate( a_point ) ); - const tripoint_bub_ms pos = veh->bub_part_pos( &here, part ); + const tripoint_bub_ms pos = veh->bub_part_pos( here, part ); item cord( itype_power_cord ); cord.link_to( *veh, a_point, link_state::automatic ); if( cord.get_use( "link_up" ) ) { @@ -552,9 +541,8 @@ void veh_app_interact::hide() vp.hidden = !vp.hidden; } -void veh_app_interact::populate_app_actions() +void veh_app_interact::populate_app_actions( map &here ) { - map &here = get_map(); vehicle_part *vp; const tripoint_abs_ms a_point_abs( veh->mount_to_tripoint_abs( a_point ) ); if( auto sel_part = here.veh_at( a_point_abs ).part_with_feature( VPFLAG_APPLIANCE, false ) ) { @@ -576,8 +564,8 @@ void veh_app_interact::populate_app_actions() imenu.addentry( -1, can_refill(), ctxt.keys_bound_to( "REFILL" ).front(), ctxt.get_action_name( "REFILL" ) ); // Siphon - app_actions.emplace_back( [this]() { - siphon(); + app_actions.emplace_back( [&here, this]() { + siphon( here ); } ); imenu.addentry( -1, can_siphon(), ctxt.keys_bound_to( "SIPHON" ).front(), ctxt.get_action_name( "SIPHON" ) ); @@ -588,14 +576,14 @@ void veh_app_interact::populate_app_actions() imenu.addentry( -1, true, ctxt.keys_bound_to( "RENAME" ).front(), ctxt.get_action_name( "RENAME" ) ); // Remove - app_actions.emplace_back( [this]() { - remove(); + app_actions.emplace_back( [&here, this]() { + remove( here ); } ); imenu.addentry( -1, veh->can_unmount( *vp, true ).success(), ctxt.keys_bound_to( "REMOVE" ).front(), ctxt.get_action_name( "REMOVE" ) ); // Plug - app_actions.emplace_back( [this]() { - plug(); + app_actions.emplace_back( [&here, this]() { + plug( here ); } ); imenu.addentry( -1, true, ctxt.keys_bound_to( "PLUG" ).front(), string_format( "%s%s", ctxt.get_action_name( "PLUG" ), @@ -613,8 +601,8 @@ void veh_app_interact::populate_app_actions() if( veh->is_powergrid() && veh->part_count() > 1 && !vp->info().has_flag( VPFLAG_WALL_MOUNTED ) ) { // Disconnect from power grid - app_actions.emplace_back( [this]() { - disconnect(); + app_actions.emplace_back( [&here, this]() { + disconnect( here ); veh = nullptr; } ); const bool can_disc = can_disconnect(); @@ -634,33 +622,33 @@ void veh_app_interact::populate_app_actions() } } -shared_ptr_fast veh_app_interact::create_or_get_ui_adaptor() +shared_ptr_fast veh_app_interact::create_or_get_ui_adaptor( map &here ) { shared_ptr_fast current_ui = ui.lock(); if( !current_ui ) { ui = current_ui = make_shared_fast(); - current_ui->on_screen_resize( [this]( ui_adaptor & cui ) { - init_ui_windows(); + current_ui->on_screen_resize( [&here, this]( ui_adaptor & cui ) { + init_ui_windows( here ); cui.position_from_window( catacurses::stdscr ); } ); current_ui->mark_resize(); - current_ui->on_redraw( [this]( const ui_adaptor & ) { + current_ui->on_redraw( [&here, this]( const ui_adaptor & ) { draw_border( w_border, c_white, veh->name, c_white ); wnoutrefresh( w_border ); - draw_info(); + draw_info( here ); } ); } return current_ui; } -void veh_app_interact::app_loop() +void veh_app_interact::app_loop( map &here ) { bool done = false; while( !done ) { // scope this tighter so that this ui is hidden when app_actions[ret]() triggers { ui.reset(); - shared_ptr_fast current_ui = create_or_get_ui_adaptor(); + shared_ptr_fast current_ui = create_or_get_ui_adaptor( here ); ui_manager::redraw(); shared_ptr_fast input_ui = imenu.create_or_get_ui(); imenu.query(); diff --git a/src/veh_appliance.h b/src/veh_appliance.h index e456ade5aac90..395f31ad4eaec 100644 --- a/src/veh_appliance.h +++ b/src/veh_appliance.h @@ -10,7 +10,7 @@ class vehicle; class ui_adaptor; vpart_id vpart_appliance_from_item( const itype_id &item_id ); -bool place_appliance( const tripoint_bub_ms &p, const vpart_id &vpart, +bool place_appliance( map &here, const tripoint_bub_ms &p, const vpart_id &vpart, const Character &owner, const std::optional &base = std::nullopt ); /** @@ -38,7 +38,7 @@ class veh_app_interact * @returns An activity to assign to the player (ACT_VEHICLE), * or a null activity if no further action is required. */ - static player_activity run( vehicle &veh, const point_rel_ms &p = point_rel_ms::zero ); + static player_activity run( map &here, vehicle &veh, const point_rel_ms &p = point_rel_ms::zero ); private: explicit veh_app_interact( vehicle &veh, const point_rel_ms &p ); @@ -72,21 +72,21 @@ class veh_app_interact * Sets up the window parameters to fit the amount of text to be displayed. * The setup calls populate_app_actions() to initialize the content. */ - void init_ui_windows(); + void init_ui_windows( map &here ); /** * Draws the upper portion, representing the appliance's usage info. */ - void draw_info(); + void draw_info( map &here ); /** * Populates the list of available actions for this appliance. The action display * names are stored as uilist entries in imenu, and the associated functions * are stored in app_actions. */ - void populate_app_actions(); + void populate_app_actions( map &here ); /** * Initializes the ui_adaptor and callbacks responsible for drawing w_border and w_info. */ - shared_ptr_fast create_or_get_ui_adaptor(); + shared_ptr_fast create_or_get_ui_adaptor( map &here ); /** * Checks whether the current appliance can be refilled (excludes batteries). * @returns True if the appliance contains a part that can be refilled. @@ -111,7 +111,7 @@ class veh_app_interact * If multiple parts are eligible, the player is prompted to select one. * A liquid handling activity is assigned to the player to process the transfer. */ - void siphon(); + void siphon( map &here ); /** * Function associated with the "RENAME" action. * Prompts the player to choose a new name for this appliance. The name is @@ -122,7 +122,7 @@ class veh_app_interact * Function associated with the "REMOVE" action. * Turns the installed appliance into its base item. */ - void remove(); + void remove( map &here ); /** * Checks whether the part has any items linked to it so it can tell the player * to disconnect those first. This prevents players from doing this by accident. @@ -133,12 +133,12 @@ class veh_app_interact * Function associated with the "DISCONNECT_GRID" action. * Removes appliance from a power grid, allowing it to be moved individually. */ - void disconnect(); + void disconnect( map &here ); /** * Function associated with the "PLUG" action. * Connects the power cable to selected tile. */ - void plug(); + void plug( map &here ); /** * Function associated with the "HIDE" action. * Hides the selected tiles sprite. @@ -149,7 +149,7 @@ class veh_app_interact * performs selected actions. The loop exits once an activity is assigned * (either directly to the player or to 'act'), or when QUIT input is received. */ - void app_loop(); + void app_loop( map &here ); }; #endif // CATA_SRC_VEH_APPLIANCE_H diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index c24d691c61d42..7fa2d4c7b0c0c 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -113,9 +113,9 @@ static std::string health_color( bool status ) static constexpr units::mass JACK_LIMIT = 8500_kilogram; // 8500kg ( 8.5 metric tonnes ) // cap JACK requirements to support arbitrarily large vehicles -static double jack_quality( const vehicle &veh ) +static double jack_quality( map &here, const vehicle &veh ) { - const units::quantity mass = std::min( veh.total_mass(), + const units::quantity mass = std::min( veh.total_mass( here ), JACK_LIMIT ); return std::ceil( mass / lifting_quality_to_mass( 1 ) ); } @@ -126,12 +126,10 @@ static auto can_refill = []( const vehicle_part &pt ) return pt.can_reload(); }; -static void act_vehicle_unload_fuel( vehicle *veh ); +static void act_vehicle_unload_fuel( map &here, vehicle *veh ); -player_activity veh_interact::serialize_activity() +player_activity veh_interact::serialize_activity( map &here ) { - map &here = get_map(); - const vehicle_part *pt = sel_vehicle_part; const vpart_info *vp = sel_vpart_info; @@ -139,7 +137,7 @@ player_activity veh_interact::serialize_activity() if( !parts_here.empty() ) { const vpart_reference part_here( *veh, parts_here[0] ); const vpart_reference displayed_part( *veh, veh->part_displayed_at( part_here.mount_pos() ) ); - return veh_shape( *veh ).start( displayed_part.pos_bub( &here ) ); + return veh_shape( here, *veh ).start( displayed_part.pos_bub( &here ) ); } return player_activity(); } @@ -195,22 +193,20 @@ player_activity veh_interact::serialize_activity() return res; } -void orient_part( vehicle *veh, const vpart_info &vpinfo, int partnum, +void orient_part( map &here, vehicle *veh, const vpart_info &vpinfo, int partnum, const std::optional &part_placement ) { - map &here = get_map(); - avatar &player_character = get_avatar(); // Stash offset and set it to the location of the part so look_around will // start there. const tripoint_rel_ms old_view_offset = player_character.view_offset; - tripoint_bub_ms offset = veh->pos_bub( &here ); + tripoint_bub_ms offset = veh->pos_bub( here ); // Appliances are one tile so the part placement there is always point::zero if( part_placement ) { point_rel_ms copied_placement = *part_placement; offset = offset + copied_placement; } - player_character.view_offset = offset - player_character.pos_bub(); + player_character.view_offset = offset - player_character.pos_bub( &here ); point_rel_ms delta; do { @@ -234,14 +230,14 @@ void orient_part( vehicle *veh, const vpart_info &vpinfo, int partnum, veh->part( partnum ).direction = dir; } -player_activity veh_interact::run( vehicle &veh, const point_rel_ms &p ) +player_activity veh_interact::run( map &here, vehicle &veh, const point_rel_ms &p ) { - veh_interact vehint( veh, p ); - vehint.do_main_loop(); - return vehint.serialize_activity(); + veh_interact vehint( here, veh, p ); + vehint.do_main_loop( here ); + return vehint.serialize_activity( here ); } -std::optional veh_interact::select_part( const vehicle &veh, +std::optional veh_interact::select_part( map &here, const vehicle &veh, const part_selector &sel, const std::string &title ) { std::optional res = std::nullopt; @@ -259,9 +255,9 @@ std::optional veh_interact::select_part( const vehicle &veh, act( std::find_if( vpr.begin(), vpr.end(), sel_wrapper )->part() ); } else if( opts != 0 ) { - veh_interact vehint( const_cast( veh ) ); + veh_interact vehint( here, const_cast( veh ) ); vehint.title = title.empty() ? _( "Select part" ) : title; - vehint.overview( sel, act ); + vehint.overview( here, sel, act ); } return res; @@ -270,7 +266,7 @@ std::optional veh_interact::select_part( const vehicle &veh, /** * Creates a blank veh_interact window. */ -veh_interact::veh_interact( vehicle &veh, const point_rel_ms &p ) +veh_interact::veh_interact( map &here, vehicle &veh, const point_rel_ms &p ) : dd( p ), veh( &veh ), main_context( "VEH_INTERACT", keyboard_mode::keycode ) { main_context.register_directions(); @@ -304,7 +300,7 @@ veh_interact::veh_interact( vehicle &veh, const point_rel_ms &p ) count_durability(); cache_tool_availability(); // Initialize info of selected parts - move_cursor( point_rel_ms::zero ); + move_cursor( here, point_rel_ms::zero ); } veh_interact::~veh_interact() = default; @@ -408,7 +404,7 @@ struct veh_interact::remove_info_t { size_t tab = 0; }; -shared_ptr_fast veh_interact::create_or_get_ui_adaptor() +shared_ptr_fast veh_interact::create_or_get_ui_adaptor( map &here ) { shared_ptr_fast current_ui = ui.lock(); if( !current_ui ) { @@ -422,14 +418,14 @@ shared_ptr_fast veh_interact::create_or_get_ui_adaptor() current_ui.position_from_window( catacurses::stdscr ); } ); current_ui->mark_resize(); - current_ui->on_redraw( [this]( const ui_adaptor & ) { + current_ui->on_redraw( [&here, this]( const ui_adaptor & ) { if( ui_hidden ) { return; } display_grid(); display_name(); - display_stats(); - display_veh(); + display_stats( here ); + display_veh( here ); werase( w_parts ); veh->print_part_list( w_parts, 0, getmaxy( w_parts ) - 1, getmaxx( w_parts ), cpart, highlight_part, @@ -486,15 +482,15 @@ shared_ptr_fast veh_interact::create_or_get_ui_adaptor() return current_ui; } -void veh_interact::hide_ui( const bool hide ) +void veh_interact::hide_ui( map &here, const bool hide ) { if( hide != ui_hidden ) { ui_hidden = hide; - create_or_get_ui_adaptor()->mark_resize(); + create_or_get_ui_adaptor( here )->mark_resize(); } } -void veh_interact::do_main_loop() +void veh_interact::do_main_loop( map &here ) { bool finish = false; Character &player_character = get_player_character(); @@ -506,37 +502,37 @@ void veh_interact::do_main_loop() owner_fac = g->faction_manager_ptr->get( faction_no_faction ); } - shared_ptr_fast current_ui = create_or_get_ui_adaptor(); + shared_ptr_fast current_ui = create_or_get_ui_adaptor( here ); while( !finish ) { - calc_overview(); + calc_overview( here ); ui_manager::redraw(); const int description_scroll_lines = catacurses::getmaxy( w_parts ) - 4; const std::string action = main_context.handle_input(); msg.reset(); if( const std::optional vec = main_context.get_direction_rel_ms( action ) ) { - move_cursor( vec->xy() ); + move_cursor( here, vec->xy() ); } else if( action == "QUIT" ) { finish = true; } else if( action == "INSTALL" ) { if( veh->handle_potential_theft( player_character ) ) { - do_install(); + do_install( here ); } } else if( action == "REPAIR" ) { if( veh->handle_potential_theft( player_character ) ) { - do_repair(); + do_repair( here ); } } else if( action == "MEND" ) { if( veh->handle_potential_theft( player_character ) ) { - do_mend(); + do_mend( here ); } } else if( action == "REFILL" ) { if( veh->handle_potential_theft( player_character ) ) { - do_refill(); + do_refill( here ); } } else if( action == "REMOVE" ) { if( veh->handle_potential_theft( player_character ) ) { - do_remove(); + do_remove( here ); } } else if( action == "RENAME" ) { if( owned_by_player ) { @@ -548,7 +544,7 @@ void veh_interact::do_main_loop() } } else if( action == "SIPHON" ) { if( veh->handle_potential_theft( player_character ) ) { - do_siphon(); + do_siphon( here ); // Siphoning may have started a player activity. If so, we should close the // vehicle dialog and continue with the activity. finish = !player_character.activity.is_null(); @@ -559,13 +555,13 @@ void veh_interact::do_main_loop() } } else if( action == "UNLOAD" ) { if( veh->handle_potential_theft( player_character ) ) { - finish = do_unload(); + finish = do_unload( here ); } } else if( action == "CHANGE_SHAPE" ) { sel_cmd = 'p'; } else if( action == "ASSIGN_CREW" ) { if( owned_by_player ) { - do_assign_crew(); + do_assign_crew( here ); } else { if( owner_fac ) { popup( _( "You cannot assign crew on this vehicle as it is owned by: %s." ), @@ -581,21 +577,21 @@ void veh_interact::do_main_loop() } } } else if( action == "FUEL_LIST_DOWN" ) { - move_fuel_cursor( 1 ); + move_fuel_cursor( here, 1 ); } else if( action == "FUEL_LIST_UP" ) { - move_fuel_cursor( -1 ); + move_fuel_cursor( here, -1 ); } else if( action == "OVERVIEW_DOWN" ) { move_overview_line( 1 ); } else if( action == "OVERVIEW_UP" ) { move_overview_line( -1 ); } else if( action == "DESC_LIST_DOWN" ) { - move_cursor( point_rel_ms::zero, 1 ); + move_cursor( here, point_rel_ms::zero, 1 ); } else if( action == "DESC_LIST_UP" ) { - move_cursor( point_rel_ms::zero, -1 ); + move_cursor( here, point_rel_ms::zero, -1 ); } else if( action == "PAGE_DOWN" ) { - move_cursor( point_rel_ms::zero, description_scroll_lines ); + move_cursor( here, point_rel_ms::zero, description_scroll_lines ); } else if( action == "PAGE_UP" ) { - move_cursor( point_rel_ms::zero, -description_scroll_lines ); + move_cursor( here, point_rel_ms::zero, -description_scroll_lines ); } if( sel_cmd != ' ' ) { finish = true; @@ -605,6 +601,8 @@ void veh_interact::do_main_loop() void veh_interact::cache_tool_availability() { + map &here = get_map(); + Character &player_character = get_player_character(); crafting_inv = &player_character.crafting_inventory(); @@ -615,7 +613,7 @@ void veh_interact::cache_tool_availability() } int max_quality = std::max( { player_character.max_quality( qual_JACK ), mech_jack, map_selector( player_character.pos_bub(), PICKUP_RANGE ).max_quality( qual_JACK ), - vehicle_selector( player_character.pos_bub(), 2, true, *veh ).max_quality( qual_JACK ) + vehicle_selector( here, player_character.pos_bub(), 2, true, *veh ).max_quality( qual_JACK ) } ); max_jack = lifting_quality_to_mass( max_quality ); } @@ -776,9 +774,9 @@ task_reason veh_interact::cant_do( char mode ) return task_reason::CAN_DO; } -bool veh_interact::can_self_jack() +bool veh_interact::can_self_jack( map &here ) { - int lvl = jack_quality( *veh ); + int lvl = jack_quality( here, *veh ); for( const vpart_reference &vp : veh->get_avail_parts( "SELF_JACK" ) ) { if( vp.part().base.has_quality( qual_SELF_JACK, lvl ) ) { @@ -788,7 +786,7 @@ bool veh_interact::can_self_jack() return false; } -bool veh_interact::update_part_requirements() +bool veh_interact::update_part_requirements( map &here ) { if( sel_vpart_info == nullptr ) { return false; @@ -899,7 +897,7 @@ bool veh_interact::update_part_requirements() skill_mechanics.obj().name(), dif_steering ) + "\n"; } - std::pair res = calc_lift_requirements( *sel_vpart_info ); + std::pair res = calc_lift_requirements( here, *sel_vpart_info ); if( !res.first ) { ok = res.first; } @@ -923,9 +921,9 @@ bool veh_interact::update_part_requirements() * @param delta -1 if moving up, * 1 if moving down */ -void veh_interact::move_fuel_cursor( int delta ) +void veh_interact::move_fuel_cursor( map &here, int delta ) { - int max_fuel_indicators = static_cast( veh->get_printable_fuel_types().size() ); + int max_fuel_indicators = static_cast( veh->get_printable_fuel_types( here ).size() ); int height = 5; fuel_index += delta; @@ -965,7 +963,7 @@ static void sort_uilist_entries_by_line_drawing( std::vector &shap } ); } -void veh_interact::do_install() +void veh_interact::do_install( map &here ) { task_reason reason = cant_do( 'i' ); @@ -1002,7 +1000,7 @@ void veh_interact::do_install() } } - shared_ptr_fast current_ui = create_or_get_ui_adaptor(); + shared_ptr_fast current_ui = create_or_get_ui_adaptor( here ); int &pos = install_info->pos = 0; size_t &tab = install_info->tab = 0; @@ -1019,7 +1017,7 @@ void veh_interact::do_install() sel_vpart_info = pos >= 0 && pos < static_cast( tab_vparts.size() ) ? tab_vparts[pos] : nullptr; - const bool can_install = update_part_requirements(); + const bool can_install = update_part_requirements( here ); ui_manager::redraw(); const std::string action = main_context.handle_input(); @@ -1118,14 +1116,14 @@ bool veh_interact::move_in_list( int &pos, const std::string &action, const int return true; } -void veh_interact::do_repair() +void veh_interact::do_repair( map &here ) { task_reason reason = cant_do( 'r' ); if( reason == task_reason::INVALID_TARGET ) { vehicle_part *most_repairable = get_most_repairable_part(); if( most_repairable && most_repairable->is_repairable() ) { - move_cursor( ( most_repairable->mount.raw() + dd ).rotate( 3 ) ); + move_cursor( here, ( most_repairable->mount.raw() + dd ).rotate( 3 ) ); return; } } @@ -1157,7 +1155,7 @@ void veh_interact::do_repair() restore_on_out_of_scope prev_title( title ); title = _( "Choose a part here to repair:" ); - shared_ptr_fast current_ui = create_or_get_ui_adaptor(); + shared_ptr_fast current_ui = create_or_get_ui_adaptor( here ); int pos = 0; @@ -1179,7 +1177,7 @@ void veh_interact::do_repair() if( pt.info().has_flag( "NEEDS_JACKING" ) ) { nmsg += _( "Additional requirements:\n" ); - std::pair res = calc_lift_requirements( pt.info() ); + std::pair res = calc_lift_requirements( here, pt.info() ); if( !res.first ) { ok = false; } @@ -1258,7 +1256,7 @@ void veh_interact::do_repair() } } -void veh_interact::do_mend() +void veh_interact::do_mend( map &here ) { switch( cant_do( 'm' ) ) { case task_reason::LOW_MORALE: @@ -1295,10 +1293,10 @@ void veh_interact::do_mend() sel_cmd = 'q'; }; - overview( sel, act ); + overview( here, sel, act ); } -void veh_interact::do_refill() +void veh_interact::do_refill( map &here ) { switch( cant_do( 'f' ) ) { case task_reason::MOVING_VEHICLE: @@ -1342,13 +1340,11 @@ void veh_interact::do_refill() } }; - overview( can_refill, act ); + overview( here, can_refill, act ); } -void veh_interact::calc_overview() +void veh_interact::calc_overview( map &here ) { - map &here = get_map(); - const hotkey_queue &hotkeys = hotkey_queue::alphabets(); const auto next_hotkey = [&]( input_event & evt ) { @@ -1629,7 +1625,8 @@ void veh_interact::display_overview() wnoutrefresh( w_list ); } -void veh_interact::overview( const overview_enable_t &enable, +void veh_interact::overview( map &here, + const overview_enable_t &enable, const overview_action_t &action ) { restore_on_out_of_scope prev_overview_enable( overview_enable ); @@ -1639,10 +1636,10 @@ void veh_interact::overview( const overview_enable_t &enable, restore_on_out_of_scope prev_overview_pos( overview_pos ); - shared_ptr_fast current_ui = create_or_get_ui_adaptor(); + shared_ptr_fast current_ui = create_or_get_ui_adaptor( here ); while( true ) { - calc_overview(); + calc_overview( here ); if( overview_pos < 0 || static_cast( overview_pos ) >= overview_opts.size() ) { overview_pos = -1; @@ -1663,7 +1660,7 @@ void veh_interact::overview( const overview_enable_t &enable, } if( overview_pos >= 0 && static_cast( overview_pos ) < overview_opts.size() ) { - move_cursor( ( overview_opts[overview_pos].part->mount.raw() + dd ).rotate( 3 ) ); + move_cursor( here, ( overview_opts[overview_pos].part->mount.raw() + dd ).rotate( 3 ) ); } if( overview_pos >= 0 && static_cast( overview_pos ) < overview_opts.size() && @@ -1744,7 +1741,7 @@ vehicle_part *veh_interact::get_most_repairable_part() const return veh_utils::most_repairable_part( *veh, get_player_character() ); } -bool veh_interact::can_remove_part( int idx, const Character &you ) +bool veh_interact::can_remove_part( map &here, int idx, const Character &you ) { sel_vehicle_part = &veh->part( idx ); sel_vpart_info = &sel_vehicle_part->info(); @@ -1772,7 +1769,7 @@ bool veh_interact::can_remove_part( int idx, const Character &you ) nmsg += string_format( _( "Removing the %1$s may yield:\n> %2$s\n" ), sel_vehicle_part->name(), enumerate_as_string( removed_names ) ); } else { - item result_of_removal = veh->part_to_item( *sel_vehicle_part ); + item result_of_removal = veh->part_to_item( here, *sel_vehicle_part ); nmsg += string_format( _( "Removing the %1$s will yield:\n> %2$s\n" ), sel_vehicle_part->name(), result_of_removal.display_name() ); @@ -1787,7 +1784,7 @@ bool veh_interact::can_remove_part( int idx, const Character &you ) nmsg += _( "Additional requirements:\n" ); - std::pair res = calc_lift_requirements( *sel_vpart_info ); + std::pair res = calc_lift_requirements( here, *sel_vpart_info ); if( !res.first ) { ok = res.first; } @@ -1806,7 +1803,7 @@ bool veh_interact::can_remove_part( int idx, const Character &you ) return ok || get_avatar().has_trait( trait_DEBUG_HS ); } -void veh_interact::do_remove() +void veh_interact::do_remove( map &here ) { task_reason reason = cant_do( 'o' ); @@ -1825,14 +1822,14 @@ void veh_interact::do_remove() avatar &player_character = get_avatar(); int pos = 0; for( size_t i = 0; i < parts_here.size(); i++ ) { - if( can_remove_part( parts_here[ i ], player_character ) ) { + if( can_remove_part( here, parts_here[ i ], player_character ) ) { pos = i; break; } } msg.reset(); - shared_ptr_fast current_ui = create_or_get_ui_adaptor(); + shared_ptr_fast current_ui = create_or_get_ui_adaptor( here ); restore_on_out_of_scope prev_overview_enable( overview_enable ); @@ -1841,7 +1838,7 @@ void veh_interact::do_remove() while( true ) { int part = parts_here[ pos ]; - bool can_remove = can_remove_part( part, player_character ); + bool can_remove = can_remove_part( here, part, player_character ); overview_enable = [this, part]( const vehicle_part & pt ) { return &pt == &veh->part( part ); @@ -1849,7 +1846,7 @@ void veh_interact::do_remove() highlight_part = pos; - calc_overview(); + calc_overview( here ); ui_manager::redraw(); //read input @@ -1896,10 +1893,8 @@ void veh_interact::do_remove() } } -void veh_interact::do_siphon() +void veh_interact::do_siphon( map &here ) { - map &here = get_map(); - switch( cant_do( 's' ) ) { case task_reason::INVALID_TARGET: msg = _( "The vehicle has no liquid fuel left to siphon." ); @@ -1927,9 +1922,9 @@ void veh_interact::do_siphon() auto act = [&]( const vehicle_part & pt ) { on_out_of_scope restore_ui( [&]() { - hide_ui( false ); + hide_ui( here, false ); } ); - hide_ui( true ); + hide_ui( here, true ); const item &base = pt.get_base(); const int idx = veh->index_of_part( &pt ); item liquid( base.legacy_front() ); @@ -1939,10 +1934,10 @@ void veh_interact::do_siphon() } }; - overview( sel, act ); + overview( here, sel, act ); } -bool veh_interact::do_unload() +bool veh_interact::do_unload( map &here ) { switch( cant_do( 'd' ) ) { case task_reason::INVALID_TARGET: @@ -1957,7 +1952,7 @@ bool veh_interact::do_unload() break; } - act_vehicle_unload_fuel( veh ); + act_vehicle_unload_fuel( here, veh ); return true; } @@ -1999,7 +1994,7 @@ static void do_change_shape_menu( vehicle_part &vp ) } } -void veh_interact::do_assign_crew() +void veh_interact::do_assign_crew( map &here ) { if( cant_do( 'w' ) != task_reason::CAN_DO ) { msg = _( "Need at least one seat and an ally to assign crew members." ); @@ -2034,7 +2029,7 @@ void veh_interact::do_assign_crew() } }; - overview( sel, act ); + overview( here, sel, act ); } void veh_interact::do_rename() @@ -2072,7 +2067,7 @@ void veh_interact::do_relabel() } } -std::pair veh_interact::calc_lift_requirements( const vpart_info +std::pair veh_interact::calc_lift_requirements( map &here, const vpart_info &sel_vpart_info ) { int lvl = 0; @@ -2096,10 +2091,10 @@ std::pair veh_interact::calc_lift_requirements( const vpart_i return std::pair ( false, nmsg ); } qual = qual_JACK; - lvl = jack_quality( *veh ); - str = veh->lift_strength(); - use_aid = ( max_jack >= lifting_quality_to_mass( lvl ) ) || can_self_jack(); - use_str = player_character.can_lift( *veh ); + lvl = jack_quality( here, *veh ); + str = veh->lift_strength( here ); + use_aid = ( max_jack >= lifting_quality_to_mass( lvl ) ) || can_self_jack( here ); + use_str = player_character.can_lift( *veh, here ); } else { item base( sel_vpart_info.base_item ); qual = qual_LIFT; @@ -2196,10 +2191,8 @@ bool veh_interact::can_potentially_install( const vpart_info &vpart ) * @param d How far to move the cursor. * @param dstart_at How far to change the start position for vehicle part descriptions */ -void veh_interact::move_cursor( const point_rel_ms &d, int dstart_at ) +void veh_interact::move_cursor( map &here, const point_rel_ms &d, int dstart_at ) { - map &here = get_map(); - dd += d.rotate( 3 ); if( d != point_rel_ms::zero ) { start_limit = 0; @@ -2211,7 +2204,7 @@ void veh_interact::move_cursor( const point_rel_ms &d, int dstart_at ) cpart = part_at( point_rel_ms::zero ); const point_rel_ms vd = -dd; const point_rel_ms q = veh->coord_translate( vd ); - const tripoint_bub_ms vehp = veh->pos_bub( &here ) + q; + const tripoint_bub_ms vehp = veh->pos_bub( here ) + q; const bool has_critter = get_creature_tracker().creature_at( vehp ); terrain_here = here.ter( vehp ).obj(); bool obstruct = here.impassable_ter_furn( vehp ); @@ -2310,7 +2303,7 @@ void veh_interact::display_grid() /** * Draws the viewport with the vehicle. */ -void veh_interact::display_veh() +void veh_interact::display_veh( map &here ) { werase( w_disp ); const point h_size = point( getmaxx( w_disp ), getmaxy( w_disp ) ) / 2; @@ -2318,8 +2311,8 @@ void veh_interact::display_veh() if( debug_mode ) { // show CoM, pivot in debug mode - const point_rel_ms &pivot = veh->pivot_point(); - const point_rel_ms &com = veh->local_center_of_mass(); + const point_rel_ms &pivot = veh->pivot_point( here ); + const point_rel_ms &com = veh->local_center_of_mass( here ); mvwprintz( w_disp, point::zero, c_green, "CoM %d,%d", com.x(), com.y() ); // NOLINTNEXTLINE(cata-use-named-point-constants) @@ -2343,7 +2336,6 @@ void veh_interact::display_veh() mvwvline( w_disp, point( h_size.x, 0 ), c_dark_gray, LINE_XOXO, getmaxy( w_disp ) ); mvwhline( w_disp, point( 0, h_size.y ), c_dark_gray, LINE_OXOX, getmaxx( w_disp ) ); - map &here = get_map(); nc_color col_at_cursor = c_black; int sym_at_cursor = ' '; //Iterate over structural parts so we only hit each square once @@ -2362,7 +2354,7 @@ void veh_interact::display_veh() } const point pt_disp( getmaxx( w_disp ) / 2, getmaxy( w_disp ) / 2 ); - const tripoint_bub_ms pos_at_cursor = veh->pos_bub( &here ) + veh->coord_translate( -dd ); + const tripoint_bub_ms pos_at_cursor = veh->pos_bub( here ) + veh->coord_translate( -dd ); const optional_vpart_position ovp = here.veh_at( pos_at_cursor ); col_at_cursor = hilite( col_at_cursor ); if( here.impassable_ter_furn( pos_at_cursor ) || ( ovp && &ovp->vehicle() != veh ) ) { @@ -2372,17 +2364,15 @@ void veh_interact::display_veh() wnoutrefresh( w_disp ); } -static std::string wheel_state_description( const vehicle &veh ) +static std::string wheel_state_description( map &here, const vehicle &veh ) { - map &here = get_map(); - bool is_boat = !veh.floating.empty(); bool is_land = !veh.wheelcache.empty() || !is_boat; bool suf_land = veh.sufficient_wheel_config(); - bool bal_land = veh.balanced_wheel_config(); + bool bal_land = veh.balanced_wheel_config( here ); - bool suf_boat = veh.can_float(); + bool suf_boat = veh.can_float( here ); float steer = veh.steering_effectiveness( here ); @@ -2424,10 +2414,8 @@ static std::string wheel_state_description( const vehicle &veh ) /** * Displays the vehicle's stats at the bottom of the window. */ -void veh_interact::display_stats() const +void veh_interact::display_stats( map &here ) const { - map &here = get_map(); - werase( w_stats_1 ); werase( w_stats_2 ); werase( w_stats_3 ); @@ -2526,7 +2514,7 @@ void veh_interact::display_stats() const } fold_and_print( *win[i], point( 0, row[i] ), getmaxx( *win[i] ), c_light_gray, _( "Mass: %5.0f %s" ), - convert_weight( veh->total_mass() ), weight_units() ); + convert_weight( veh->total_mass( here ) ), weight_units() ); i += 1; fold_and_print( *win[i], point( 0, row[i] ), getmaxx( *win[i] ), c_light_gray, disp_w > 35 ? _( "Cargo volume: %s / %s %s" ) : @@ -2541,7 +2529,7 @@ void veh_interact::display_stats() const i += 1; fold_and_print( *win[i], point( 0, row[i] ), getmaxx( *win[i] ), c_light_gray, - wheel_state_description( *veh ) ); + wheel_state_description( here, *veh ) ); i += 1; if( install_info || remove_info ) { @@ -2590,14 +2578,14 @@ void veh_interact::display_stats() const if( is_boat ) { fold_and_print( *win[i], point( 0, row[i] ), getmaxx( *win[i] ), c_light_gray, _( "Water drag: %5.2f" ), - veh->coeff_water_drag() ); + veh->coeff_water_drag( here ) ); } i += 1; if( is_ground ) { fold_and_print( *win[i], point( 0, row[i] ), getmaxx( *win[i] ), c_light_gray, _( "Rolling drag: %5.2f" ), - veh->coeff_rolling_drag() ); + veh->coeff_rolling_drag( here ) ); } i += 1; @@ -2614,14 +2602,14 @@ void veh_interact::display_stats() const if( is_boat ) { - const double water_clearance = veh->water_hull_height() - veh->water_draft(); + const double water_clearance = veh->water_hull_height( here ) - veh->water_draft( here ); const char *draft_string = water_clearance > 0 ? _( "Draft/Clearance:%4.2fm/%4.2fm" ) : _( "Draft/Clearance:%4.2fm/%4.2fm" ) ; fold_and_print( *win[i], point( 0, row[i] ), getmaxx( *win[i] ), c_light_gray, draft_string, - veh->water_draft(), water_clearance ); + veh->water_draft( here ), water_clearance ); i += 1; } @@ -2629,7 +2617,7 @@ void veh_interact::display_stats() const i = std::max( i, 2 * stats_h ); // Print fuel percentage & type name only if it fits in the window, 10 is width of "E...F 100%" - veh->print_fuel_indicators( *win[i], point( 0, row[i] ), fuel_index, true, + veh->print_fuel_indicators( here, *win[i], point( 0, row[i] ), fuel_index, true, ( getmaxx( *win[i] ) > 10 ), ( getmaxx( *win[i] ) > 10 ) ); @@ -2959,10 +2947,8 @@ void veh_interact::count_durability() } } -void act_vehicle_siphon( vehicle *veh ) +void act_vehicle_siphon( map &here, vehicle *veh ) { - map &here = get_map(); - std::vector fuels; bool has_liquid = false; // Check all tanks on this vehicle to see if they contain any liquid @@ -2981,7 +2967,8 @@ void act_vehicle_siphon( vehicle *veh ) auto sel = []( const vehicle_part & pt ) { return pt.contains_liquid(); }; - if( const std::optional tank = veh_interact::select_part( *veh, sel, title ) ) { + if( const std::optional tank = veh_interact::select_part( here, *veh, sel, + title ) ) { item liquid( tank->part().get_base().only_item() ); const int liq_charges = liquid.charges; if( liquid_handler::handle_liquid( liquid, nullptr, 1, nullptr, veh, tank->part_index() ) ) { @@ -2991,10 +2978,8 @@ void act_vehicle_siphon( vehicle *veh ) } } -void act_vehicle_unload_fuel( vehicle *veh ) +void act_vehicle_unload_fuel( map &here, vehicle *veh ) { - map &here = get_map(); - std::vector fuels; for( auto &e : veh->fuels_left() ) { const itype *type = item::find_type( e.first ); @@ -3051,7 +3036,7 @@ void act_vehicle_unload_fuel( vehicle *veh ) * Called when the activity timer for installing parts, repairing, etc times * out and the action is complete. */ -void veh_interact::complete_vehicle( Character &you ) +void veh_interact::complete_vehicle( map &here, Character &you ) { if( you.activity.values.size() < 7 ) { debugmsg( "ACT_VEHICLE values.size() is %d", you.activity.values.size() ); @@ -3061,7 +3046,6 @@ void veh_interact::complete_vehicle( Character &you ) debugmsg( "ACT_VEHICLE str_values is empty" ); return; } - map &here = get_map(); const tripoint_abs_ms act_pos( you.activity.values[0], you.activity.values[1], you.posz() ); optional_vpart_position ovp = here.veh_at( act_pos ); if( !ovp ) { @@ -3127,7 +3111,7 @@ void veh_interact::complete_vehicle( Character &you ) } you.invalidate_crafting_inventory(); - const int partnum = veh.install_part( d, part_id, std::move( base ), installed_with ); + const int partnum = veh.install_part( here, d, part_id, std::move( base ), installed_with ); if( partnum < 0 ) { debugmsg( "complete_vehicle install part fails dx=%d dy=%d id=%s", d.x(), d.y(), part_id.c_str() ); @@ -3145,10 +3129,10 @@ void veh_interact::complete_vehicle( Character &you ) if( vpinfo.has_flag( VPFLAG_CONE_LIGHT ) || vpinfo.has_flag( VPFLAG_WIDE_CONE_LIGHT ) || vpinfo.has_flag( VPFLAG_HALF_CIRCLE_LIGHT ) ) { - orient_part( &veh, vpinfo, partnum, q ); + orient_part( here, &veh, vpinfo, partnum, q ); } - const tripoint_bub_ms vehp = veh.pos_bub( &here ) + tripoint_rel_ms( q, 0 ); + const tripoint_bub_ms vehp = veh.pos_bub( here ) + tripoint_rel_ms( q, 0 ); // TODO: allow boarding for non-players as well. Character *const pl = get_creature_tracker().creature_at( vehp ); if( vpinfo.has_flag( VPFLAG_BOARDABLE ) && pl ) { @@ -3166,7 +3150,7 @@ void veh_interact::complete_vehicle( Character &you ) case 'r': { vehicle_part &vp = veh.part( you.activity.values[6] ); - veh_utils::repair_part( veh, vp, you ); + veh_utils::repair_part( here, veh, vp, you ); break; } @@ -3276,9 +3260,9 @@ void veh_interact::complete_vehicle( Character &you ) } if( wall_wire_removal ) { - veh.part_to_item( *vp ); // what's going on here? this line isn't doing anything... + veh.part_to_item( here, *vp ); // what's going on here? this line isn't doing anything... } else if( vpi.has_flag( "TOW_CABLE" ) ) { - veh.invalidate_towing( true, &you ); + veh.invalidate_towing( here, true, &you ); } else if( broken ) { item_group::ItemList pieces = vp->pieces_for_broken_part(); resulting_items.insert( resulting_items.end(), pieces.begin(), pieces.end() ); @@ -3287,7 +3271,7 @@ void veh_interact::complete_vehicle( Character &you ) item_group::ItemList pieces = vp->pieces_for_broken_part(); resulting_items.insert( resulting_items.end(), pieces.begin(), pieces.end() ); } else { - resulting_items.push_back( veh.removed_part( *vp ) ); + resulting_items.push_back( veh.removed_part( here, *vp ) ); // damage reduces chance of success (0.8^damage_level) const double component_success_chance = std::pow( 0.8, vp->damage_level() ); @@ -3326,7 +3310,7 @@ void veh_interact::complete_vehicle( Character &you ) // Power cables must remove parts from the target vehicle, too. if( vpi.has_flag( VPFLAG_POWER_TRANSFER ) ) { - veh.remove_remote_part( *vp ); + veh.remove_remote_part( here, *vp ); } if( appliance_removal && veh.part_count() > 1 ) { @@ -3350,9 +3334,9 @@ void veh_interact::complete_vehicle( Character &you ) // Save these values now so they aren't lost when parts or vehicles are destroyed. const point_rel_ms part_mount = vp->mount; - const tripoint_bub_ms part_pos = veh.bub_part_pos( &here, *vp ); + const tripoint_bub_ms part_pos = veh.bub_part_pos( here, *vp ); - veh.unlink_cables( part_mount, you, + veh.unlink_cables( here, part_mount, you, false, /* unneeded as items will be unlinked if the connected part is removed */ appliance_removal || vpi.location == "structure", appliance_removal || vpi.has_flag( VPFLAG_CABLE_PORTS ) || vpi.has_flag( VPFLAG_BATTERY ) ); @@ -3367,7 +3351,7 @@ void veh_interact::complete_vehicle( Character &you ) // part_removal_cleanup calls refresh, so parts_at_relative is valid veh.part_removal_cleanup( here ); if( veh.parts_at_relative( part_mount, true ).empty() ) { - get_map().clear_vehicle_point_from_cache( &veh, part_pos ); + here.clear_vehicle_point_from_cache( &veh, part_pos ); } } // This will be part of an NPC "job" where they need to clean up the activity diff --git a/src/veh_interact.h b/src/veh_interact.h index 1ab0200241774..468d0773646ad 100644 --- a/src/veh_interact.h +++ b/src/veh_interact.h @@ -23,6 +23,7 @@ class Character; class inventory; +class map; class vpart_info; struct requirement_data; @@ -51,16 +52,17 @@ class veh_interact using part_selector = std::function; public: - static player_activity run( vehicle &veh, const point_rel_ms &p ); + static player_activity run( map &here, vehicle &veh, const point_rel_ms &p ); /** Prompt for a part matching the selector function */ - static std::optional select_part( const vehicle &veh, const part_selector &sel, + static std::optional select_part( map &here, const vehicle &veh, + const part_selector &sel, const std::string &title = std::string() ); - static void complete_vehicle( Character &you ); + static void complete_vehicle( map &here, Character &you ); private: - explicit veh_interact( vehicle &veh, const point_rel_ms &p = point_rel_ms::zero ); + explicit veh_interact( map &here, vehicle &veh, const point_rel_ms &p = point_rel_ms::zero ); ~veh_interact(); point_rel_ms dd = point_rel_ms::zero; @@ -130,17 +132,17 @@ class veh_interact // maximum weight_capacity of available jacking equipment (if any) units::mass max_jack; - shared_ptr_fast create_or_get_ui_adaptor(); - void hide_ui( bool hide ); + shared_ptr_fast create_or_get_ui_adaptor( map &here ); + void hide_ui( map &here, bool hide ); - player_activity serialize_activity(); + player_activity serialize_activity( map &here ); /** Format list of requirements returning true if all are met */ bool format_reqs( std::string &msg, const requirement_data &reqs, const std::map &skills, time_duration time ) const; int part_at( const point_rel_ms &d ); - void move_cursor( const point_rel_ms &d, int dstart_at = 0 ); + void move_cursor( map &here, const point_rel_ms &d, int dstart_at = 0 ); task_reason cant_do( char mode ); bool can_potentially_install( const vpart_info &vpart ); /** Move index (parameter pos) according to input action: @@ -153,7 +155,7 @@ class veh_interact */ bool move_in_list( int &pos, const std::string &action, int size, int header = 0 ) const; - void move_fuel_cursor( int delta ); + void move_fuel_cursor( map &here, int delta ); /** * @name Task handlers @@ -163,16 +165,16 @@ class veh_interact * @param msg failure message to display (if any) */ /*@{*/ - void do_install(); - void do_repair(); - void do_mend(); - void do_refill(); - void do_remove(); + void do_install( map &here ); + void do_repair( map &here ); + void do_mend( map &here ); + void do_refill( map &here ); + void do_remove( map &here ); void do_rename(); - void do_siphon(); + void do_siphon( map &here ); // Returns true if exiting the screen - bool do_unload(); - void do_assign_crew(); + bool do_unload( map &here ); + void do_assign_crew( map &here ); void do_relabel(); /*@}*/ @@ -181,11 +183,11 @@ class veh_interact * @return bool true if lift requirements are fulfilled * @return string msg for the ui to show the lift requirements */ - std::pair calc_lift_requirements( const vpart_info &sel_vpart_info ); + std::pair calc_lift_requirements( map &here, const vpart_info &sel_vpart_info ); void display_grid(); - void display_veh(); - void display_stats() const; + void display_veh( map &here ); + void display_stats( map &here ) const; void display_name(); void display_mode(); void display_list( size_t pos, const std::vector &list, int header = 0 ); @@ -227,7 +229,7 @@ class veh_interact overview_action_t overview_action; int overview_pos = -1; - void calc_overview(); + void calc_overview( map &here ); void display_overview(); /** * Display overview of parts, optionally with interactive selection of one part @@ -237,7 +239,7 @@ class veh_interact that will be highlighted * @param action callback when part is selected. */ - void overview( const overview_enable_t &enable = {}, + void overview( map &here, const overview_enable_t &enable = {}, const overview_action_t &action = {} ); void move_overview_line( int ); @@ -255,9 +257,9 @@ class veh_interact vehicle_part *get_most_repairable_part() const; //do_remove supporting operation, writes requirements to ui - bool can_remove_part( int idx, const Character &you ); + bool can_remove_part( map &here, int idx, const Character &you ); //do install support, writes requirements to ui - bool update_part_requirements(); + bool update_part_requirements( map &here ); /* Vector of all vpart TYPES that can be mounted in the current square. * Can be converted to a vector. @@ -282,17 +284,17 @@ class veh_interact void cache_tool_availability(); void allocate_windows(); - void do_main_loop(); + void do_main_loop( map &here ); void cache_tool_availability_update_lifting( const tripoint_bub_ms &world_cursor_pos ); /** Returns true if the vehicle has a jack powerful enough to lift itself installed */ - bool can_self_jack(); + bool can_self_jack( map &here ); }; -void act_vehicle_siphon( vehicle *veh ); +void act_vehicle_siphon( map &here, vehicle *veh ); -void orient_part( vehicle *veh, const vpart_info &vpinfo, int partnum, +void orient_part( map &here, vehicle *veh, const vpart_info &vpinfo, int partnum, const std::optional &part_placement = std::nullopt ); #endif // CATA_SRC_VEH_INTERACT_H diff --git a/src/veh_shape.cpp b/src/veh_shape.cpp index da38cece8d40a..3f60004c88469 100644 --- a/src/veh_shape.cpp +++ b/src/veh_shape.cpp @@ -11,14 +11,14 @@ #include "veh_utils.h" #include "ui_manager.h" -veh_shape::veh_shape( vehicle &vehicle ): veh( vehicle ) { } +veh_shape::veh_shape( map &here, vehicle &vehicle ): veh( vehicle ), here( here ) { } player_activity veh_shape::start( const tripoint_bub_ms &pos ) { - map &here = get_map(); + map &temp = here; // Work around to get 'here' to be accepted into the lambda list avatar &you = get_avatar(); - on_out_of_scope cleanup( [&here]() { - here.invalidate_map_cache( get_avatar().view_offset.z() ); + on_out_of_scope cleanup( [&temp]() { + temp.invalidate_map_cache( get_avatar().view_offset.z() ); } ); restore_on_out_of_scope view_offset_prev( you.view_offset ); @@ -29,7 +29,7 @@ player_activity veh_shape::start( const tripoint_bub_ms &pos ) if( !set_cursor_pos( pos ) ) { debugmsg( "failed to set cursor at given part" ); - set_cursor_pos( veh.bub_part_pos( &here, 0 ) ); + set_cursor_pos( veh.bub_part_pos( here, 0 ) ); } const auto target_ui_cb = make_shared_fast( @@ -84,13 +84,11 @@ player_activity veh_shape::start( const tripoint_bub_ms &pos ) std::vector veh_shape::parts_under_cursor() const { - map &here = get_map(); - std::vector res; // TODO: tons of methods getting parts from vehicle but all of them seem inadequate? for( int part_idx = 0; part_idx < veh.part_count_real(); part_idx++ ) { const vehicle_part &p = veh.part( part_idx ); - if( veh.bub_part_pos( &here, p ) == get_cursor_pos() && !p.is_fake ) { + if( veh.bub_part_pos( here, p ) == get_cursor_pos() && !p.is_fake ) { res.emplace_back( veh, part_idx ); } } @@ -130,7 +128,6 @@ std::optional veh_shape::select_part_at_cursor( void veh_shape::change_part_shape( vpart_reference vpr ) const { - map &here = get_map(); vehicle_part &part = vpr.part(); const vpart_info &vpi = part.info(); veh_menu menu( this->veh, _( "Choose cosmetic variant:" ) ); @@ -145,7 +142,7 @@ void veh_shape::change_part_shape( vpart_reference vpr ) const .keep_menu_open() .skip_locked_check() .skip_theft_check() - .location( veh.bub_part_pos( &here, part ).raw() ) + .location( veh.bub_part_pos( here, part ).raw() ) .select( part.variant == vvid ) .desc( _( "Confirm to save or exit to revert" ) ) .symbol( vv.get_symbol_curses( 0_degrees, false ) ) @@ -200,7 +197,7 @@ bool veh_shape::set_cursor_pos( const tripoint_bub_ms &new_pos ) } if( z != cursor_pos.z() ) { - get_map().invalidate_map_cache( z ); + here.invalidate_map_cache( z ); } cursor_pos = target_pos; you.view_offset = cursor_pos - you.pos_bub(); diff --git a/src/veh_shape.h b/src/veh_shape.h index fb59115f1eb8b..3b05f1d9b9281 100644 --- a/src/veh_shape.h +++ b/src/veh_shape.h @@ -4,12 +4,13 @@ #include "vehicle.h" +class map; class player_activity; class veh_shape { public: - explicit veh_shape( vehicle &vehicle ); + explicit veh_shape( map &here, vehicle &vehicle ); /// Starts vehicle ui loop, runs until canceled or activity is selected and returned /// @param vehicle Vehicle to handle @@ -23,6 +24,7 @@ class veh_shape vehicle &veh; // cursor handling + map &here; std::set cursor_allowed; // all points the cursor is allowed to be on tripoint_bub_ms cursor_pos; tripoint_bub_ms get_cursor_pos() const; diff --git a/src/veh_type.cpp b/src/veh_type.cpp index 50121f18578c2..037cfec5a7c09 100644 --- a/src/veh_type.cpp +++ b/src/veh_type.cpp @@ -1535,6 +1535,7 @@ void vehicle_prototype::save_vehicle_as_prototype( const vehicle &veh, JsonOut & */ void vehicles::finalize_prototypes() { + map &here = get_map(); // TODO: Determine if this is good enough. vehicle_prototype_factory.finalize(); for( const vehicle_prototype &const_proto : vehicles::get_all_prototypes() ) { vehicle_prototype &proto = const_cast( const_proto ); @@ -1560,7 +1561,7 @@ void vehicles::finalize_prototypes() continue; } - const int part_idx = blueprint.install_part( pt.pos, pt.part ); + const int part_idx = blueprint.install_part( here, pt.pos, pt.part ); if( part_idx < 0 ) { debugmsg( "init_vehicles: '%s' part '%s'(%d) can't be installed to %d,%d", blueprint.name, pt.part.c_str(), diff --git a/src/veh_utils.cpp b/src/veh_utils.cpp index ab01d89dd514f..3d71ed0b5ec01 100644 --- a/src/veh_utils.cpp +++ b/src/veh_utils.cpp @@ -91,10 +91,8 @@ vehicle_part *most_repairable_part( vehicle &veh, Character &who ) return vp_most_damaged != nullptr ? vp_most_damaged : vp_broken; } -bool repair_part( vehicle &veh, vehicle_part &pt, Character &who ) +bool repair_part( map &here, vehicle &veh, vehicle_part &pt, Character &who ) { - map &here = get_map(); - const vpart_info &vp = pt.info(); const requirement_data reqs = pt.is_broken() @@ -144,7 +142,7 @@ bool repair_part( vehicle &veh, vehicle_part &pt, Character &who ) const std::string variant = pt.variant; here.spawn_items( who.pos_bub( &here ), pt.pieces_for_broken_part() ); veh.remove_part( pt ); - const int partnum = veh.install_part( mount, vpid, std::move( base ) ); + const int partnum = veh.install_part( here, mount, vpid, std::move( base ) ); if( partnum >= 0 ) { vehicle_part &vp = veh.part( partnum ); vp.direction = direction; @@ -410,14 +408,16 @@ class veh_menu_cb : public uilist_callback g->invalidate_main_ui_adaptor(); if( on_select ) { on_select(); - map &m = get_map(); - m.invalidate_map_cache( m.get_abs_sub().z() ); + map &here = get_map(); // TODO: Handle getting the correct map. + here.invalidate_map_cache( here.get_abs_sub().z() ); } } }; bool veh_menu::query() { + map &here = get_map(); // TODO: Handle getting the correct map. + if( items.empty() ) { debugmsg( "veh_menu::query() called with empty items" ); return false; @@ -485,10 +485,9 @@ bool veh_menu::query() chosen._on_submit(); - map &m = get_map(); veh.refresh( ); - m.invalidate_visibility_cache(); - m.invalidate_map_cache( m.get_abs_sub().z() ); + here.invalidate_visibility_cache(); + here.invalidate_map_cache( here.get_abs_sub().z() ); return chosen._keep_menu_open; } diff --git a/src/veh_utils.h b/src/veh_utils.h index b83500643261f..0966a4f3d3f1e 100644 --- a/src/veh_utils.h +++ b/src/veh_utils.h @@ -10,6 +10,7 @@ #include "type_id.h" class Character; +class map; class vehicle; class vpart_info; struct uilist_entry; @@ -29,7 +30,7 @@ vehicle_part *most_repairable_part( vehicle &veh, Character &who_arg ); * Repairs a given part on a given vehicle by given character. * Awards xp and consumes components. */ -bool repair_part( vehicle &veh, vehicle_part &pt, Character &who ); +bool repair_part( map &here, vehicle &veh, vehicle_part &pt, Character &who ); } // namespace veh_utils struct veh_menu_item { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 76e88cb3d7787..bbd2baf8348ec 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -152,7 +152,7 @@ void DefaultRemovePartHandler::removed( map *here, vehicle &veh, const int part { avatar &player_character = get_avatar(); const vehicle_part &vp = veh.part( part ); - const tripoint_bub_ms part_pos = veh.bub_part_pos( here, vp ); + const tripoint_bub_ms part_pos = veh.bub_part_pos( *here, vp ); // If the player is currently working on the removed part, stop them as it's futile now. const player_activity &act = player_character.activity; @@ -191,10 +191,8 @@ vehicle_stack::iterator vehicle_stack::erase( vehicle_stack::const_iterator it ) return veh.remove_item( vp, it ); } -void vehicle_stack::insert( const item &newitem ) +void vehicle_stack::insert( map &here, const item &newitem ) { - map &here = get_map(); - veh.add_item( here, vp, newitem ); } @@ -266,7 +264,7 @@ bool vehicle::player_in_control( const map &here, const Character &p ) const if( vp && &vp->vehicle() == this && p.controlling_vehicle && ( ( part_with_feature( vp->mount_pos(), "CONTROL_ANIMAL", true ) >= 0 && - has_engine_type( fuel_type_animal, false ) && get_harnessed_animal() ) || + has_engine_type( fuel_type_animal, false ) && get_harnessed_animal( here ) ) || ( part_with_feature( vp->part_index(), VPFLAG_CONTROLS, false ) >= 0 ) ) ) { return true; @@ -581,7 +579,7 @@ void vehicle::init_state( map &placed_on, int init_veh_fuel, int init_veh_status // destroy tires until the vehicle is not drivable if( destroyTires && !wheelcache.empty() ) { int tries = 0; - while( valid_wheel_config() && tries < 100 ) { + while( valid_wheel_config( placed_on ) && tries < 100 ) { // wheel config is still valid, destroy the tire. set_hp( parts[random_entry( wheelcache )], 0, false ); tries++; @@ -705,8 +703,8 @@ std::set vehicle::immediate_path( map *here, const units::angle &r adjusted_angle = round_to_multiple_of( adjusted_angle, vehicles::steer_increment ); tileray collision_vector; collision_vector.init( adjusted_angle ); - point_bub_ms top_left_actual = pos_bub( here ).xy() + coord_translate( front_left ); - point_bub_ms top_right_actual = pos_bub( here ).xy() + coord_translate( front_right ); + point_bub_ms top_left_actual = pos_bub( *here ).xy() + coord_translate( front_left ); + point_bub_ms top_right_actual = pos_bub( *here ).xy() + coord_translate( front_right ); std::vector front_row = line_to( here->get_abs( tripoint_bub_ms{top_left_actual.x(), top_left_actual.y(), here->get_abs_sub().z()} ).xy(), here->get_abs( tripoint_bub_ms{ top_right_actual.x(), top_right_actual.y(), here->get_abs_sub().z()} ).xy() ); for( const point_abs_ms &elem : front_row ) { @@ -749,7 +747,7 @@ void vehicle::drive_to_local_target( map *here, const tripoint_abs_ms &target, Character &player_character = get_player_character(); if( follow_protocol && player_character.in_vehicle ) { if( here == &get_map() ) { // TODO: Make sound handling map aware - sounds::sound( pos_bub( here ), 30, sounds::sound_t::alert, + sounds::sound( pos_bub( *here ), 30, sounds::sound_t::alert, string_format( _( "the %s emitting a beep and saying \"Autonomous driving protocols suspended!\"" ), name ) ); } @@ -764,7 +762,7 @@ void vehicle::drive_to_local_target( map *here, const tripoint_abs_ms &target, if( stop ) { if( autopilot_on ) { if( here == &get_map() ) { // TODO: Make sound handling map aware - sounds::sound( pos_bub( here ), 30, sounds::sound_t::alert, + sounds::sound( pos_bub( *here ), 30, sounds::sound_t::alert, string_format( _( "the %s emitting a beep and saying \"Obstacle detected!\"" ), name ) ); } @@ -806,7 +804,7 @@ void vehicle::drive_to_local_target( map *here, const tripoint_abs_ms &target, accel_y = 1; } } - selfdrive( turn_x, accel_y ); + selfdrive( *here, turn_x, accel_y ); } bool vehicle::precollision_check( units::angle &angle, map &here, bool follow_protocol ) @@ -966,9 +964,9 @@ void vehicle::smash( map &m, float hp_percent_loss_min, float hp_percent_loss_ma } } -int vehicle::lift_strength() const +int vehicle::lift_strength( map &here ) const { - units::mass mass = total_mass(); + units::mass mass = total_mass( here ); return std::max( mass / 10000_gram, 1 ); } @@ -1089,7 +1087,7 @@ void vehicle::backfire( map *here, const vehicle_part &vp ) const // single space after the exclamation mark because it does not end the sentence //~ backfire sound const std::string text = _( "a loud BANG! from the %s" ); // NOLINT(cata-text-style); - const tripoint_bub_ms pos = bub_part_pos( here, vp ); + const tripoint_bub_ms pos = bub_part_pos( *here, vp ); const int volume = 40 + units::to_watt( part_vpower_w( *here, vp, true ) ) / 10000; if( here == &get_map() ) { // TODO: Make sound handling map aware. sounds::sound( pos, volume, sounds::sound_t::movement, @@ -1474,23 +1472,23 @@ bool vehicle::is_appliance() const return has_tag( flag_APPLIANCE ); } -int vehicle::install_part( const point_rel_ms &dp, const vpart_id &type ) +int vehicle::install_part( map &here, const point_rel_ms &dp, const vpart_id &type ) { - return install_part( dp, type, item( type.obj().base_item ) ); + return install_part( here, dp, type, item( type.obj().base_item ) ); } -int vehicle::install_part( const point_rel_ms &dp, const vpart_id &type, item &&base ) +int vehicle::install_part( map &here, const point_rel_ms &dp, const vpart_id &type, item &&base ) { - return install_part( dp, vehicle_part( type, std::move( base ) ) ); + return install_part( here, dp, vehicle_part( type, std::move( base ) ) ); } -int vehicle::install_part( const point_rel_ms &dp, const vpart_id &type, item &&base, +int vehicle::install_part( map &here, const point_rel_ms &dp, const vpart_id &type, item &&base, std::vector &installed_with ) { - return install_part( dp, vehicle_part( type, std::move( base ), installed_with ) ); + return install_part( here, dp, vehicle_part( type, std::move( base ), installed_with ) ); } -int vehicle::install_part( const point_rel_ms &dp, vehicle_part &&vp ) +int vehicle::install_part( map &here, const point_rel_ms &dp, vehicle_part &&vp ) { const vpart_info &vpi = vp.info(); const ret_val valid_mount = can_mount( dp, vpi ); @@ -1542,7 +1540,7 @@ int vehicle::install_part( const point_rel_ms &dp, vehicle_part &&vp ) } } // refresh will add them back if needed - remove_fake_parts( true ); + remove_fake_parts( here, true ); vehicle_part &vp_installed = parts.emplace_back( std::move( vp ) ); vp_installed.enabled = enable; vp_installed.mount = dp; @@ -1566,7 +1564,7 @@ std::vector vehicle::find_vehicles_to_rack( map *here vehicle *veh_matched = nullptr; std::set parts_matched; for( const int &rack_part : filtered_rack ) { - const tripoint_bub_ms search_pos = bub_part_pos( here, rack_part ) + offset; + const tripoint_bub_ms search_pos = bub_part_pos( *here, rack_part ) + offset; const optional_vpart_position ovp = here->veh_at( search_pos ); if( !ovp || &ovp->vehicle() == this || ovp->vehicle().is_appliance() ) { continue; @@ -1711,8 +1709,8 @@ bool vehicle::merge_rackable_vehicle( map *here, vehicle *carry_veh, // the mount point on the old vehicle (carry_veh) that will be destroyed point_rel_ms old_mount; }; - remove_fake_parts( /* cleanup = */ false ); - invalidate_towing( true ); + remove_fake_parts( *here, /* cleanup = */ false ); + invalidate_towing( *here, true ); // By structs, we mean all the parts of the carry vehicle that are at the structure location // of the vehicle (i.e. frames) std::vector carry_veh_structs = carry_veh->all_parts_at_location( part_location_structure ); @@ -1828,7 +1826,7 @@ bool vehicle::merge_rackable_vehicle( map *here, vehicle *carry_veh, // Now that we've added zones to this vehicle, we need to make sure their positions // update when we next interact with them zones_dirty = true; - remove_fake_parts( /* cleanup = */ true ); + remove_fake_parts( *here, /* cleanup = */ true ); refresh( ); //~ %1$s is the vehicle being loaded onto the bicycle rack @@ -1855,20 +1853,20 @@ bool vehicle::merge_vehicle_parts( map *here, vehicle *veh ) if( part.info().has_flag( VPFLAG_POWER_TRANSFER ) ) { // Disconnect cables that are attached between the merging vehicles. // Delete power cords, drop extension cords on the ground. - item drop = veh->part_to_item( part ); + item drop = veh->part_to_item( *here, part ); if( drop.link().t_veh.get() == this ) { if( !veh->magic && part.info().id != vpart_power_cord ) { - const tripoint_bub_ms drop_pos = veh->bub_part_pos( here, part ); + const tripoint_bub_ms drop_pos = veh->bub_part_pos( *here, part ); drop.reset_link( false, nullptr, -1, true, drop_pos ); here->add_item_or_charges( drop_pos, drop ); } - veh->remove_remote_part( part ); + veh->remove_remote_part( *here, part ); continue; } } point_abs_ms part_loc = veh->mount_to_tripoint_abs( part.mount ).xy(); - remove_fake_parts(); + remove_fake_parts( *here ); parts.push_back( part ); vehicle_part &copied_part = parts.back(); copied_part.mount = part_loc - pos_abs().xy(); @@ -1907,8 +1905,8 @@ bool vehicle::merge_appliance_into_grid( map *here, vehicle &veh_target ) bounding_box vehicle_box = get_bounding_box( false, true ); bounding_box target_vehicle_box = veh_target.get_bounding_box( false, true ); - const tripoint_bub_ms veh_pos = pos_bub( here ); - const tripoint_bub_ms target_pos = veh_target.pos_bub( here ); + const tripoint_bub_ms veh_pos = pos_bub( *here ); + const tripoint_bub_ms target_pos = veh_target.pos_bub( *here ); const point_bub_ms min = { std::min( veh_pos.x() + vehicle_box.p1.x(), target_pos.x() + target_vehicle_box.p1.x() ), std::min( veh_pos.y() + vehicle_box.p1.y(), target_pos.y() + target_vehicle_box.p1.y() ) }; @@ -1923,13 +1921,13 @@ bool vehicle::merge_appliance_into_grid( map *here, vehicle &veh_target ) if( size.x() <= MAX_WIRE_VEHICLE_SIZE && size.y() <= MAX_WIRE_VEHICLE_SIZE ) { // Find all item connections to the merging network so they can be updated after merge. std::vector network_connections = here->item_network_connections( &veh_target ); - tripoint_bub_ms old_grid_reference{veh_target.pos_bub( here )}; + tripoint_bub_ms old_grid_reference{veh_target.pos_bub( *here )}; if( !merge_vehicle_parts( here, &veh_target ) ) { debugmsg( "failed to merge vehicle parts" ); } else { // Adjust the connections after the change of the power_grid origo. for( const item_reference &item_ref : network_connections ) { - item_ref.item_ref->link().t_mount += ( old_grid_reference - this->pos_bub( here ) ).xy(); + item_ref.item_ref->link().t_mount += ( old_grid_reference - this->pos_bub( *here ) ).xy(); } //Keep wall wiring sections from losing their flag @@ -1948,7 +1946,7 @@ bool vehicle::merge_appliance_into_grid( map *here, vehicle &veh_target ) void vehicle::separate_from_grid( map *here, const point_rel_ms mount ) { // Disconnect items and power cords - unlink_cables( mount, get_player_character(), true, true, true ); + unlink_cables( *here, mount, get_player_character(), true, true, true ); part_removal_cleanup( *here ); if( part_count() <= 1 ) { // No need to split the power grid up. @@ -2020,7 +2018,7 @@ bool vehicle::remove_part( vehicle_part &vp, RemovePartHandler &handler ) return false; } - const tripoint_bub_ms part_loc = bub_part_pos( &handler.get_map_ref(), vp ); + const tripoint_bub_ms part_loc = bub_part_pos( handler.get_map_ref(), vp ); if( !handler.get_map_ref().inbounds( part_loc ) ) { debugmsg( "vehicle::remove_part part '%s' at mount %s bub pos %s is out of map " @@ -2047,7 +2045,8 @@ bool vehicle::remove_part( vehicle_part &vp, RemovePartHandler &handler ) return false; } vehicle_part &vp_dep = parts[dep]; - handler.add_item_or_charges( &handler.get_map_ref(), part_loc, part_to_item( vp_dep ), false ); + handler.add_item_or_charges( &handler.get_map_ref(), part_loc, part_to_item( handler.get_map_ref(), + vp_dep ), false ); remove_part( vp_dep, handler ); return true; }; @@ -2155,7 +2154,7 @@ bool vehicle::do_remove_part_actual( map *here ) get_items( vp ).clear(); } if( vp.is_real_or_active_fake() ) { - const tripoint_bub_ms pt = bub_part_pos( here, vp ); + const tripoint_bub_ms pt = bub_part_pos( *here, vp ); here->clear_vehicle_point_from_cache( this, pt ); } it = parts.erase( it ); @@ -2166,7 +2165,7 @@ bool vehicle::do_remove_part_actual( map *here ) } void vehicle::part_removal_cleanup( map &here ) { - remove_fake_parts( false ); + remove_fake_parts( here, false ); const bool changed = do_remove_part_actual( &here ); if( changed || parts.empty() ) { refresh( ); @@ -2200,7 +2199,7 @@ bool vehicle::remove_carried_vehicle( map &here, const std::vector &carried // pivot is the stack that has zeroed mount point, only it has valid axis set if( !carried_stack.empty() && carried_stack.top().mount == tripoint_rel_ms::zero ) { carried_pivot = carried_stack.top(); - pivot_pos = bub_part_pos( &here, carried_part ); + pivot_pos = bub_part_pos( here, carried_part ); break; } } @@ -2447,7 +2446,7 @@ bool vehicle::split_vehicles( map &here, } } } - new_v_pos3 = bub_part_pos( &here, parts[ split_part0 ] ); + new_v_pos3 = bub_part_pos( here, parts[ split_part0 ] ); mnt_offset = parts[ split_part0 ].mount; new_vehicle = here.add_vehicle( vehicle_prototype_none, new_v_pos3, face.dir() ); if( new_vehicle == nullptr ) { @@ -2576,7 +2575,7 @@ bool vehicle::split_vehicles( map &here, new_vehicle->precalc_mounts( 0, new_vehicle->turn_dir, point_rel_ms::zero ); new_vehicle->precalc_mounts( 1, new_vehicle->skidding ? new_vehicle->turn_dir : new_vehicle->face.dir(), - new_vehicle->pivot_point() ); + new_vehicle->pivot_point( here ) ); if( !passengers.empty() ) { new_vehicle->relocate_passengers( passengers ); } @@ -3397,7 +3396,7 @@ tripoint_bub_ms vehicle::mount_to_tripoint( map *here, const point_rel_ms &mount { tripoint_rel_ms mnt_translated; coord_translate( pivot_rotation[0], pivot_anchor[0], mount + offset, mnt_translated ); - return pos_bub( here ) + mnt_translated; + return pos_bub( *here ) + mnt_translated; } tripoint_abs_ms vehicle::mount_to_tripoint_abs( const point_rel_ms &mount, @@ -3498,11 +3497,11 @@ Character *vehicle::get_driver( map &here ) const return nullptr; } -monster *vehicle::get_monster( map &here, int p ) const +monster *vehicle::get_monster( const map &here, int p ) const { p = part_with_feature( p, VPFLAG_BOARDABLE, false ); if( p >= 0 ) { - return get_creature_tracker().creature_at( bub_part_pos( &here, p ), true ); + return get_creature_tracker().creature_at( bub_part_pos( here, p ), true ); } return nullptr; } @@ -3517,17 +3516,17 @@ tripoint_abs_omt vehicle::pos_abs_omt() const return project_to( pos_abs() ); } -tripoint_bub_ms vehicle::pos_bub( map *here ) const +tripoint_bub_ms vehicle::pos_bub( const map &here ) const { - return here->get_bub( pos_abs() ); + return here.get_bub( pos_abs() ); } -tripoint_bub_ms vehicle::bub_part_pos( map *here, const int index ) const +tripoint_bub_ms vehicle::bub_part_pos( const map &here, const int index ) const { return bub_part_pos( here, parts[index] ); } -tripoint_bub_ms vehicle::bub_part_pos( map *here, const vehicle_part &pt ) const +tripoint_bub_ms vehicle::bub_part_pos( const map &here, const vehicle_part &pt ) const { return pos_bub( here ) + pt.precalc[0]; } @@ -3552,13 +3551,13 @@ void vehicle::set_submap_moved( map *here, const tripoint_bub_sm &p ) overmap_buffer.move_vehicle( this, old_msp ); } -units::mass vehicle::total_mass() const +units::mass vehicle::total_mass( map &here ) const { // local_center_of_mass() is more frequently called // than rotated_center_of_mass(). // To improve performance, refresh mass_center_no_precalc. if( mass_dirty ) { - calc_mass_center( false ); + calc_mass_center( here, false ); } return mass_cache; @@ -3566,7 +3565,7 @@ units::mass vehicle::total_mass() const units::mass vehicle::weight_on_wheels( map &here ) const { - const units::mass vehicle_mass = total_mass(); + const units::mass vehicle_mass = total_mass( here ); units::mass animal_mass = 0_gram; for( const int e : engines ) { const vehicle_part &vp = parts[e]; @@ -3580,18 +3579,18 @@ units::mass vehicle::weight_on_wheels( map &here ) const return vehicle_mass - animal_mass; } -const point_rel_ms &vehicle::rotated_center_of_mass() const +const point_rel_ms &vehicle::rotated_center_of_mass( map &here ) const { // TODO: Bring back caching of this point - calc_mass_center( true ); + calc_mass_center( here, true ); return mass_center_precalc; } -const point_rel_ms &vehicle::local_center_of_mass() const +const point_rel_ms &vehicle::local_center_of_mass( map &here ) const { if( mass_center_no_precalc_dirty ) { - calc_mass_center( false ); + calc_mass_center( here, false ); } return mass_center_no_precalc; @@ -3765,7 +3764,7 @@ int vehicle::drain( map &here, const int index, int amount, bool apply_loss ) return 0; } - const int drained = pt.ammo_consume( amount, &here, bub_part_pos( &here, pt ) ); + const int drained = pt.ammo_consume( amount, &here, bub_part_pos( here, pt ) ); invalidate_mass(); return drained; } @@ -3849,7 +3848,7 @@ bool vehicle::can_use_rails( map &here ) const bool is_wheel_on_rail = false; for( int part_index : rail_wheelcache ) { // at least one wheel should be on track - if( here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_RAIL, bub_part_pos( &here, part_index ) ) ) { + if( here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_RAIL, bub_part_pos( here, part_index ) ) ) { is_wheel_on_rail = true; break; } @@ -3864,11 +3863,11 @@ int vehicle::ground_acceleration( map &here, const bool fueled, int at_vel_in_vm } int target_vmiph = std::max( at_vel_in_vmi, std::max( 1000, max_velocity( here, fueled ) / 4 ) ); int cmps = vmiph_to_cmps( target_vmiph ); - double weight = to_kilogram( total_mass() ); + double weight = to_kilogram( total_mass( here ) ); if( is_towing() ) { vehicle *other_veh = tow_data.get_towed(); if( other_veh ) { - weight = weight + to_kilogram( other_veh->total_mass() ); + weight = weight + to_kilogram( other_veh->total_mass( here ) ); } } int engine_power_ratio = units::to_watt( total_power( here, fueled ) ) / weight; @@ -3885,7 +3884,7 @@ int vehicle::rotor_acceleration( map &here, const bool fueled, int at_vel_in_vmi return 0; } const int accel_at_vel = 100 * lift_thrust_of_rotorcraft( here, - fueled ) / to_kilogram( total_mass() ); + fueled ) / to_kilogram( total_mass( here ) ); return cmps_to_vmiph( accel_at_vel ); } @@ -3897,11 +3896,11 @@ int vehicle::water_acceleration( map &here, const bool fueled, int at_vel_in_vmi int target_vmiph = std::max( at_vel_in_vmi, std::max( 1000, max_water_velocity( here, fueled ) / 4 ) ); int cmps = vmiph_to_cmps( target_vmiph ); - double weight = to_kilogram( total_mass() ); + double weight = to_kilogram( total_mass( here ) ); if( is_towing() ) { vehicle *other_veh = tow_data.get_towed(); if( other_veh ) { - weight = weight + to_kilogram( other_veh->total_mass() ); + weight = weight + to_kilogram( other_veh->total_mass( here ) ); } } int engine_power_ratio = units::to_watt( total_power( here, fueled ) ) / weight; @@ -3988,7 +3987,7 @@ int vehicle::current_acceleration( map &here, const bool fueled ) const int vehicle::max_ground_velocity( map &here, const bool fueled ) const { int total_engine_w = units::to_watt( total_power( here, fueled ) ); - double c_rolling_drag = coeff_rolling_drag(); + double c_rolling_drag = coeff_rolling_drag( here ); double max_in_mps = simple_cubic_solution( coeff_air_drag(), c_rolling_drag, c_rolling_drag * vehicles::rolling_constant_to_variable, -total_engine_w ); @@ -4011,11 +4010,11 @@ int vehicle::max_ground_velocity( map &here, const bool fueled ) const int vehicle::max_water_velocity( map &here, const bool fueled ) const { int total_engine_w = units::to_watt( total_power( here, fueled ) ); - double total_drag = coeff_water_drag() + coeff_air_drag(); + double total_drag = coeff_water_drag( here ) + coeff_air_drag(); double max_in_mps = std::cbrt( total_engine_w / total_drag ); add_msg_debug( debugmode::DF_VEHICLE, "%s: power %d, c_air %3.2f, c_water %3.2f, water max_in_mps %3.2f", - name, total_engine_w, coeff_air_drag(), coeff_water_drag(), max_in_mps ); + name, total_engine_w, coeff_air_drag(), coeff_water_drag( here ), max_in_mps ); return mps_to_vmiph( max_in_mps ); } @@ -4056,7 +4055,7 @@ int vehicle::max_reverse_velocity( map &here, const bool fueled ) const int vehicle::safe_ground_velocity( map &here, const bool fueled ) const { int effective_engine_w = units::to_watt( total_power( here, fueled, true ) ); - double c_rolling_drag = coeff_rolling_drag(); + double c_rolling_drag = coeff_rolling_drag( here ); double safe_in_mps = simple_cubic_solution( coeff_air_drag(), c_rolling_drag, c_rolling_drag * vehicles::rolling_constant_to_variable, -effective_engine_w ); @@ -4074,7 +4073,7 @@ int vehicle::safe_rotor_velocity( map &here, const bool fueled ) const int vehicle::safe_water_velocity( map &here, const bool fueled ) const { int total_engine_w = units::to_watt( total_power( here, fueled, true ) ); - double total_drag = coeff_water_drag() + coeff_air_drag(); + double total_drag = coeff_water_drag( here ) + coeff_air_drag(); double safe_in_mps = std::cbrt( total_engine_w / total_drag ); return mps_to_vmiph( safe_in_mps ); } @@ -4208,7 +4207,7 @@ void vehicle::noise_and_smoke( map &here, int load, time_duration time ) } add_msg_debug( debugmode::DF_VEHICLE, "VEH NOISE final: %d", static_cast( noise ) ); vehicle_noise = static_cast( noise ); - sounds::sound( pos_bub( &here ), noise, sounds::sound_t::movement, + sounds::sound( pos_bub( here ), noise, sounds::sound_t::movement, _( is_rotorcraft( here ) ? heli_noise : sounds[lvl].first ), true ); } @@ -4410,7 +4409,7 @@ double vehicle::coeff_air_drag() const return coefficient_air_resistance; } -double vehicle::coeff_rolling_drag() const +double vehicle::coeff_rolling_drag( map &here ) const { if( !coeff_rolling_dirty ) { return coefficient_rolling_resistance; @@ -4435,31 +4434,31 @@ double vehicle::coeff_rolling_drag() const wheel_factor *= wheel_ratio / ( base_wheels * wheel_ratio - base_wheels + wheelcache.size() ); } - coefficient_rolling_resistance = newton_ratio * wheel_factor * to_kilogram( total_mass() ); + coefficient_rolling_resistance = newton_ratio * wheel_factor * to_kilogram( total_mass( here ) ); coeff_rolling_dirty = false; return coefficient_rolling_resistance; } -double vehicle::water_hull_height() const +double vehicle::water_hull_height( map &here ) const { if( coeff_water_dirty ) { - coeff_water_drag(); + coeff_water_drag( here ); } return hull_height; } -double vehicle::water_draft() const +double vehicle::water_draft( map &here ) const { if( coeff_water_dirty ) { - coeff_water_drag(); + coeff_water_drag( here ); } return draft_m; } -bool vehicle::can_float() const +bool vehicle::can_float( map &here ) const { if( coeff_water_dirty ) { - coeff_water_drag(); + coeff_water_drag( here ); } // Someday I'll deal with submarines, but now, you can only float if you have freeboard return draft_m < hull_height; @@ -4496,7 +4495,7 @@ double vehicle::lift_thrust_of_rotorcraft( map &here, const bool fuelled, const bool vehicle::has_sufficient_rotorlift( map &here ) const { // comparison of newton to newton - convert kg to newton. - return lift_thrust_of_rotorcraft( here, true ) > to_kilogram( total_mass() ) * 9.8; + return lift_thrust_of_rotorcraft( here, true ) > to_kilogram( total_mass( here ) ) * 9.8; } bool vehicle::is_rotorcraft( map &here ) const @@ -4607,7 +4606,7 @@ bool vehicle::can_control_on_land( const Character &pc ) const return true; } -double vehicle::coeff_water_drag() const +double vehicle::coeff_water_drag( map &here ) const { if( !coeff_water_dirty ) { return coefficient_water_resistance; @@ -4654,7 +4653,7 @@ double vehicle::coeff_water_drag() const // area * depth = vehicle_mass / water_density // depth = vehicle_mass / water_density / area constexpr double water_density = 1000.0; // kg/m^3 - draft_m = to_kilogram( total_mass() ) / water_density / hull_area_m; + draft_m = to_kilogram( total_mass( here ) ) / water_density / hull_area_m; // increase the streamlining as more of the boat is covered in boat boards double c_water_drag = 1.25 - hull_coverage; // hull height starts at 0.3m and goes up as you add more boat boards @@ -4669,12 +4668,12 @@ double vehicle::coeff_water_drag() const float vehicle::k_traction( map &here, float wheel_traction_area ) const { if( in_deep_water ) { - return can_float() ? 1.0f : -1.0f; + return can_float( here ) ? 1.0f : -1.0f; } if( is_flying ) { return is_rotorcraft( here ) ? 1.0f : -1.0f; } - if( is_watercraft() && can_float() ) { + if( is_watercraft() && can_float( here ) ) { return 1.0f; } @@ -4851,7 +4850,7 @@ bool vehicle::handle_potential_theft( Character const &you, bool check_only, boo return true; } -bool vehicle::balanced_wheel_config() const +bool vehicle::balanced_wheel_config( map &here ) const { point_rel_ms min = point_rel_ms::max; point_rel_ms max = point_rel_ms::min; @@ -4865,28 +4864,28 @@ bool vehicle::balanced_wheel_config() const } // Check center of mass inside support of wheels (roughly) - const point_rel_ms &com = local_center_of_mass(); + const point_rel_ms &com = local_center_of_mass( here ); const inclusive_rectangle support( min, max ); return support.contains( com ); } -bool vehicle::valid_wheel_config() const +bool vehicle::valid_wheel_config( map &here ) const { - return sufficient_wheel_config() && balanced_wheel_config(); + return sufficient_wheel_config() && balanced_wheel_config( here ); } float vehicle::steering_effectiveness( map &here ) const { if( in_deep_water ) { // I'M ON A BOAT - return can_float() ? 1.0f : 0.0f; + return can_float( here ) ? 1.0f : 0.0f; } if( is_flying ) { // I'M IN THE AIR return is_rotorcraft( here ) ? 1.0f : 0.0f; } // irksome special case for boats in shallow water - if( is_watercraft() && can_float() ) { + if( is_watercraft() && can_float( here ) ) { return 1.0f; } @@ -4895,7 +4894,8 @@ float vehicle::steering_effectiveness( map &here ) const } // no steering if only steering part is animal harness without animal in it const vehicle_part &vp = parts[steering[0]]; - if( steering.size() == 1 && vp.info().fuel_type == fuel_type_animal && !get_harnessed_animal() ) { + if( steering.size() == 1 && vp.info().fuel_type == fuel_type_animal && + !get_harnessed_animal( here ) ) { return -2.0f; } // For now, you just need one wheel working for 100% effective steering. @@ -5015,7 +5015,7 @@ void vehicle::consume_fuel( map &here, int load, bool idling ) driver->has_effect( effect_winded ) ) { cruise_velocity = 0; if( velocity == 0 ) { - stop(); + stop( here ); } } // we want this to update the activity level whenever we're using muscle power to move @@ -5215,7 +5215,7 @@ units::power vehicle::total_solar_epower( map &here ) const units::power epower = 0_W; for( const int p : solar_panels ) { const vehicle_part &vp = parts[p]; - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); if( vp.is_unavailable() || !is_sm_tile_outside( here.get_abs( pos ) ) ) { continue; } @@ -5237,7 +5237,7 @@ units::power vehicle::total_wind_epower( map &here ) const units::power epower = 0_W; for( const int p : wind_turbines ) { const vehicle_part &vp = parts[p]; - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); if( vp.is_unavailable() || !is_sm_tile_outside( here.get_abs( pos ) ) ) { continue; } @@ -5257,7 +5257,7 @@ units::power vehicle::total_water_wheel_epower( map &here ) const units::power epower = 0_W; for( const int p : water_wheels ) { const vehicle_part &vp = parts[p]; - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); if( vp.is_unavailable() || !is_sm_tile_over_water( here.get_abs( pos ) ) ) { continue; } @@ -5397,7 +5397,7 @@ void vehicle::power_parts( map &here ) int fuel_consumed = reactors_output_bat / efficiency; // Remainder has a chance of resulting in more fuel consumption fuel_consumed += x_in_y( reactors_output_bat % efficiency, efficiency ) ? 1 : 0; - vp.ammo_consume( fuel_consumed, &here, bub_part_pos( &here, vp ) ); + vp.ammo_consume( fuel_consumed, &here, bub_part_pos( here, vp ) ); reactor_working = true; delta_energy_bat += reactors_output_bat; } @@ -5408,7 +5408,7 @@ void vehicle::power_parts( map &here ) for( int elem : reactors ) { parts[ elem ].enabled = false; } - if( player_is_driving_this_veh( &here ) || player_character.sees( pos_bub( &here ) ) ) { + if( player_is_driving_this_veh( &here ) || player_character.sees( pos_bub( here ) ) ) { add_msg( _( "The %s's reactor dies!" ), name ); } } @@ -5443,13 +5443,13 @@ void vehicle::power_parts( map &here ) is_alarm_on = false; camera_on = false; - if( player_is_driving_this_veh( &here ) || player_character.sees( pos_bub( &here ) ) ) { + if( player_is_driving_this_veh( &here ) || player_character.sees( pos_bub( here ) ) ) { add_msg( _( "The %s's battery dies!" ), name ); } if( engine_epower < 0_W ) { // Not enough epower to run gas engine ignition system engine_on = false; - if( player_is_driving_this_veh( &here ) || player_character.sees( pos_bub( &here ) ) ) { + if( player_is_driving_this_veh( &here ) || player_character.sees( pos_bub( here ) ) ) { add_msg( _( "The %s's engine dies!" ), name ); } } @@ -5804,7 +5804,7 @@ void vehicle::idle( map &here, bool on_map ) if( engine_on && ( has_engine_type_not( fuel_type_muscle, true ) && has_engine_type_not( fuel_type_animal, true ) && has_engine_type_not( fuel_type_wind, true ) && has_engine_type_not( fuel_type_mana, true ) ) ) { - add_msg_if_player_sees( pos_bub( &here ), _( "The %s's engine dies!" ), name ); + add_msg_if_player_sees( pos_bub( here ), _( "The %s's engine dies!" ), name ); } engine_on = false; } @@ -5813,7 +5813,7 @@ void vehicle::idle( map &here, bool on_map ) for( int i : planters ) { vehicle_part &vp = parts[ i ]; if( vp.enabled ) { - add_msg_if_player_sees( pos_bub( &here ), _( "The %s's planter turns off due to low temperature." ), + add_msg_if_player_sees( pos_bub( here ), _( "The %s's planter turns off due to low temperature." ), name ); vp.enabled = false; } @@ -5822,12 +5822,12 @@ void vehicle::idle( map &here, bool on_map ) linked_item_epower_this_turn = 0_W; recharge_epower_this_turn = 0_W; - smart_controller_handle_turn(); + smart_controller_handle_turn( here ); if( !on_map ) { return; } else { - update_time( calendar::turn ); + update_time( here, calendar::turn ); } // Parts emitting fields @@ -5838,11 +5838,11 @@ void vehicle::idle( map &here, bool on_map ) continue; } for( const emit_id &e : pt.info().emissions ) { - here.emit_field( bub_part_pos( &here, pt ), e ); + here.emit_field( bub_part_pos( here, pt ), e ); } for( const emit_id &e : pt.info().exhaust ) { if( exhaust_and_muffle.first == -1 ) { - here.emit_field( bub_part_pos( &here, pt ), e ); + here.emit_field( bub_part_pos( here, pt ), e ); } else { here.emit_field( exhaust_dest( &here, exhaust_and_muffle.first ), e ); } @@ -5902,8 +5902,8 @@ void vehicle::on_move( map &here ) // TODO: Send ID of driver get_event_bus().send( is_passenger( pc ), player_is_driving_this_veh( &here ), remote_controlled( pc ), - is_flying_in_air(), is_watercraft() && can_float(), can_use_rails( here ), - is_falling, is_in_water( true ) && !can_float(), + is_flying_in_air(), is_watercraft() && can_float( here ), can_use_rails( here ), + is_falling, is_in_water( true ) && !can_float( here ), skidding, velocity, sm_pos.z() ); } @@ -5921,23 +5921,23 @@ void vehicle::slow_leak( map &here ) itype_id fuel = p.ammo_current(); int qty = std::max( ( 0.5 - health ) * ( 0.5 - health ) * p.ammo_remaining() / 10, 1.0 ); point_rel_ms q = coord_translate( p.mount ); - const tripoint_bub_ms dest = pos_bub( &here ) + tripoint_rel_ms( q, 0 ); + const tripoint_bub_ms dest = pos_bub( here ) + tripoint_rel_ms( q, 0 ); // damaged batteries self-discharge without leaking, plutonium leaks slurry if( fuel != fuel_type_battery && fuel != fuel_type_plutonium_cell ) { item leak( fuel, calendar::turn, qty ); here.add_item_or_charges( dest, leak ); - p.ammo_consume( qty, &here, bub_part_pos( &here, p ) ); + p.ammo_consume( qty, &here, bub_part_pos( here, p ) ); } else if( fuel == fuel_type_plutonium_cell ) { if( p.ammo_remaining() >= PLUTONIUM_CHARGES / 10 ) { item leak( itype_plut_slurry_dense, calendar::turn, qty ); here.add_item_or_charges( dest, leak ); - p.ammo_consume( qty * PLUTONIUM_CHARGES / 10, &here, bub_part_pos( &here, p ) ); + p.ammo_consume( qty * PLUTONIUM_CHARGES / 10, &here, bub_part_pos( here, p ) ); } else { - p.ammo_consume( p.ammo_remaining(), &here, bub_part_pos( &here, p ) ); + p.ammo_consume( p.ammo_remaining(), &here, bub_part_pos( here, p ) ); } } else { - p.ammo_consume( qty, &here, bub_part_pos( &here, p ) ); + p.ammo_consume( qty, &here, bub_part_pos( here, p ) ); } } } @@ -6047,7 +6047,7 @@ std::optional vehicle::add_item( map &here, vehicle_par if( itm_copy.is_bucket_nonempty() ) { // this is a vehicle, so there is only one pocket. // so if it will spill, spill all of it - itm_copy.spill_contents( bub_part_pos( &here, vp ) ); + itm_copy.spill_contents( bub_part_pos( here, vp ) ); } const vehicle_stack::iterator new_pos = vp.items.insert( itm_copy ); @@ -6111,10 +6111,8 @@ std::map vehicle::prepare_tools( const vehicle_part &vp ) const return res; } -void vehicle::place_spawn_items() +void vehicle::place_spawn_items( map &here ) { - map &here = get_map(); - if( !type.is_valid() ) { return; } @@ -6212,10 +6210,8 @@ void vehicle::place_zones( map &pmap ) const } } -void vehicle::gain_moves() +void vehicle::gain_moves( map &here ) { - map &here = get_map(); - fuel_used_last_turn.clear(); check_falling_or_floating(); const bool pl_control = player_is_driving_this_veh( &here ); @@ -6224,12 +6220,12 @@ void vehicle::gain_moves() shed_loose_parts(); } of_turn = 1 + of_turn_carry; - const int vslowdown = slowdown( velocity ); + const int vslowdown = slowdown( here, velocity ); if( vslowdown > std::abs( velocity ) ) { if( cruise_velocity && pl_control ) { velocity = velocity > 0 ? 1 : -1; } else { - stop(); + stop( here ); } } else if( velocity < 0 ) { velocity += vslowdown; @@ -6243,11 +6239,11 @@ void vehicle::gain_moves() of_turn_carry = 0; // cruise control TODO: enable for NPC? if( ( pl_control || is_following || is_patrolling ) && cruise_velocity != velocity ) { - thrust( cruise_velocity > velocity ? 1 : -1 ); + thrust( here, cruise_velocity > velocity ? 1 : -1 ); } else if( is_rotorcraft( here ) && velocity == 0 ) { // rotorcraft uses fuel for hover // whether it's flying or not is checked inside thrust function - thrust( 0 ); + thrust( here, 0 ); } // Force off-map connected vehicles to load by visiting them every time we gain moves. @@ -6274,23 +6270,22 @@ void vehicle::gain_moves() } } -bool vehicle::decrement_summon_timer() +bool vehicle::decrement_summon_timer( map &here ) { if( !summon_time_limit ) { return false; } if( *summon_time_limit <= 0_turns ) { - map &here = get_map(); for( const vpart_reference &vpr : get_all_parts() ) { vehicle_part &vp = vpr.part(); - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); for( item &it : vp.items ) { here.add_item_or_charges( pos, it ); } vp.items.clear(); } - add_msg_if_player_sees( pos_bub( &here ), m_info, _( "Your %s winks out of existence." ), name ); - get_map().destroy_vehicle( this ); + add_msg_if_player_sees( pos_bub( here ), m_info, _( "Your %s winks out of existence." ), name ); + here.destroy_vehicle( this ); return true; } else { *summon_time_limit -= 1_turns; @@ -6679,10 +6674,8 @@ vpart_edge_info vehicle::get_edge_info( const point_rel_ms &mount ) const return vpart_edge_info( f_index, a_index, l_index, r_index, left_side, right_side ); } -void vehicle::remove_fake_parts( const bool cleanup ) +void vehicle::remove_fake_parts( map &here, const bool cleanup ) { - map &here = get_map(); - if( fake_parts.empty() ) { edges.clear(); return; @@ -6712,23 +6705,23 @@ void vehicle::remove_fake_parts( const bool cleanup ) } } -const point_rel_ms &vehicle::pivot_point() const +const point_rel_ms &vehicle::pivot_point( map &here ) const { if( pivot_dirty ) { - refresh_pivot(); + refresh_pivot( here ); } return pivot_cache; } -void vehicle::refresh_pivot() const +void vehicle::refresh_pivot( map &here ) const { // Const method, but messes with mutable fields pivot_dirty = false; - if( wheelcache.empty() || !valid_wheel_config() ) { + if( wheelcache.empty() || !valid_wheel_config( here ) ) { // No usable wheels, use CoM (dragging) - pivot_cache = local_center_of_mass(); + pivot_cache = local_center_of_mass( here ); return; } @@ -6814,14 +6807,14 @@ void vehicle::refresh_pivot() const if( xc_denominator < 0.1 || yc_denominator < 0.1 ) { debugmsg( "vehicle::refresh_pivot had a bad weight: xc=%.3f/%.3f yc=%.3f/%.3f", xc_numerator, xc_denominator, yc_numerator, yc_denominator ); - pivot_cache = local_center_of_mass(); + pivot_cache = local_center_of_mass( here ); } else { pivot_cache.x() = std::round( xc_numerator / xc_denominator ); pivot_cache.y() = std::round( yc_numerator / yc_denominator ); } } -void vehicle::do_towing_move() +void vehicle::do_towing_move( map &here ) { if( !no_towing_slack() || velocity <= 0 ) { return; @@ -6835,7 +6828,7 @@ void vehicle::do_towing_move() vehicle *towed_veh = tow_data.get_towed(); if( !towed_veh ) { debugmsg( "tried to do towing move, but towed vehicle doesn't exist." ); - invalidate_towing(); + invalidate_towing( here ); return; } const int other_tow_index = towed_veh->get_tow_part(); @@ -6844,13 +6837,12 @@ void vehicle::do_towing_move() invalidate = true; } if( invalidate ) { - invalidate_towing( true ); + invalidate_towing( here, true ); return; } - map &here = get_map(); - const tripoint_abs_ms tower_tow_point = here.get_abs( bub_part_pos( &here, tow_index ) ); - const tripoint_abs_ms towed_tow_point = here.get_abs( towed_veh->bub_part_pos( - &here, other_tow_index ) ); + const tripoint_abs_ms tower_tow_point = abs_part_pos( tow_index ); + const tripoint_abs_ms towed_tow_point = towed_veh->abs_part_pos( + other_tow_index ); // same as above, but where the pulling vehicle is pulling from units::angle towing_veh_angle = towed_veh->get_angle_from_targ( tower_tow_point ); const bool reverse = towed_veh->tow_data.tow_direction == TOW_BACK; @@ -6875,7 +6867,7 @@ void vehicle::do_towing_move() switch( towed_veh->tow_data.tow_direction ) { case TOW_FRONT: case TOW_BACK: - towed_veh->selfdrive( turn_x, accel_y ); + towed_veh->selfdrive( here, turn_x, accel_y ); break; default: @@ -7003,9 +6995,8 @@ bool towing_data::set_towing( vehicle *tower_veh, vehicle *towed_veh ) return true; } -void vehicle::invalidate_towing( bool first_vehicle, Character *remover ) +void vehicle::invalidate_towing( map &here, bool first_vehicle, Character *remover ) { - map &here = get_map(); if( !is_towing() && !is_towed() ) { return; } @@ -7018,13 +7009,13 @@ void vehicle::invalidate_towing( bool first_vehicle, Character *remover ) const point_rel_ms other_tow_cable_mount = other_veh && other_tow_cable_idx > -1 ? other_veh->part( other_tow_cable_idx ).mount : point_rel_ms::zero; if( other_veh ) { - other_veh->invalidate_towing(); + other_veh->invalidate_towing( here ); } if( tow_cable_idx > -1 ) { vehicle_part &vp = parts[tow_cable_idx]; - item drop = part_to_item( vp ); + item drop = part_to_item( here, vp ); drop.set_damage( 0 ); - tripoint_bub_ms drop_pos = bub_part_pos( &here, vp ); + tripoint_bub_ms drop_pos = bub_part_pos( here, vp ); remove_part( vp ); if( other_tow_cable_idx > -1 ) { drop.reset_link( false ); @@ -7125,10 +7116,9 @@ bool vehicle::no_towing_slack() const } -std::optional vehicle::get_remote_part( const vehicle_part &vp_local ) const +std::optional vehicle::get_remote_part( map &here, + const vehicle_part &vp_local ) const { - map &here = get_map(); - vehicle *veh = find_vehicle( here, vp_local.target.second ); // If the target vehicle is still there, ask it to remove its part if( veh != nullptr ) { @@ -7143,13 +7133,13 @@ std::optional vehicle::get_remote_part( const vehicle_part &vp_ return std::nullopt; } -void vehicle::remove_remote_part( const vehicle_part &vp_local ) const +void vehicle::remove_remote_part( map &here, const vehicle_part &vp_local ) const { - const auto part = get_remote_part( vp_local ); + const auto part = get_remote_part( here, vp_local ); if( part ) { part->vehicle().remove_part( part->part() ); // Rebuild vehicle cache to avoid creating an illusion of the remote car. - get_map().rebuild_vehicle_level_caches(); + here.rebuild_vehicle_level_caches(); } } @@ -7182,12 +7172,12 @@ void vehicle::shed_loose_parts( const trinary shed_cables, map *here, const trip const int max_dist = vp_loose.get_base().max_link_length(); if( distance > max_dist || shed_cables == trinary::ALL ) { - add_msg_if_player_sees( bub_part_pos( here, vp_loose ), m_warning, + add_msg_if_player_sees( bub_part_pos( *here, vp_loose ), m_warning, _( "The %s's %s was detached!" ), name, vp_loose.name( false ) ); remove_remote = true; } else { // cable still has some slack to it, so update the remote part's target and continue. - const auto remote = get_remote_part( vp_loose ); + const auto remote = get_remote_part( *here, vp_loose ); if( remote ) { remote->part().target.first = vp_loose_dst; remote->part().target.second = dst ? here->get_abs( *dst ) : pos_abs(); @@ -7195,19 +7185,19 @@ void vehicle::shed_loose_parts( const trinary shed_cables, map *here, const trip continue; } } - const item drop = part_to_item( vp_loose ); + const item drop = part_to_item( *here, vp_loose ); if( !magic ) { - here->add_item_or_charges( bub_part_pos( here, vp_loose ), drop ); + here->add_item_or_charges( bub_part_pos( *here, vp_loose ), drop ); } if( remove_remote ) { - remove_remote_part( vp_loose ); + remove_remote_part( *here, vp_loose ); } remove_part( vp_loose ); } } -void vehicle::unlink_cables( const point_rel_ms &mount, Character &remover, +void vehicle::unlink_cables( map &here, const point_rel_ms &mount, Character &remover, bool unlink_items, bool unlink_tow_cables, bool unlink_power_cords ) { if( !unlink_items && !unlink_tow_cables && !unlink_power_cords ) { @@ -7224,7 +7214,7 @@ void vehicle::unlink_cables( const point_rel_ms &mount, Character &remover, } if( unlink_tow_cables && part.info().has_flag( "TOW_CABLE" ) ) { bool u_can_stash_tow = remover.can_stash( part.get_base() ); - invalidate_towing( true, &remover ); + invalidate_towing( here, true, &remover ); if( u_can_stash_tow ) { remover.add_msg_if_player( _( "You detach the %s and take it." ), part.name( false ) ); } else { @@ -7232,7 +7222,7 @@ void vehicle::unlink_cables( const point_rel_ms &mount, Character &remover, } } if( unlink_power_cords && part.info().has_flag( VPFLAG_POWER_TRANSFER ) ) { - item drop = part_to_item( part ); + item drop = part_to_item( here, part ); bool u_can_stash = remover.can_stash( drop ); if( !magic && !drop.has_flag( flag_NO_DROP ) && remover.i_add_or_drop( drop ) ) { if( u_can_stash ) { @@ -7243,7 +7233,7 @@ void vehicle::unlink_cables( const point_rel_ms &mount, Character &remover, } else { remover.add_msg_if_player( _( "You detached the %s." ), drop.type_name() ); } - remove_remote_part( part ); + remove_remote_part( here, part ); remove_part( part ); } } @@ -7321,12 +7311,11 @@ bool vpart_position::is_inside() const return vehicle().part( part_index() ).inside; } -void vehicle::unboard_all() const +void vehicle::unboard_all( map &here ) const { - map &here = get_map(); std::vector bp = boarded_parts(); for( const int &i : bp ) { - here.unboard_vehicle( bub_part_pos( &here, i ) ); + here.unboard_vehicle( bub_part_pos( here, i ) ); } } @@ -7404,7 +7393,7 @@ int vehicle::damage( map &here, int p, int dmg, const damage_type_id &type, bool } } -void vehicle::damage_all( int dmg1, int dmg2, const damage_type_id &type, +void vehicle::damage_all( map &here, int dmg1, int dmg2, const damage_type_id &type, const point_rel_ms &impact ) { if( dmg2 < dmg1 ) { @@ -7428,7 +7417,7 @@ void vehicle::damage_all( int dmg1, int dmg2, const damage_type_id &type, net_dmg = std::max( 0, net_dmg - vp_shock_absorber.info().bonus ); } } - damage_direct( get_map(), vp, net_dmg, type ); + damage_direct( here, vp, net_dmg, type ); } } } @@ -7508,7 +7497,7 @@ int vehicle::break_off( map &here, vehicle_part &vp, int dmg ) if( rng( 0, vpi.durability / 10 ) >= dmg ) { return dmg; } - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); const auto scatter_parts = [&]( const vehicle_part & pt ) { for( const item &piece : pt.pieces_for_broken_part() ) { // inside the loop, so each piece goes to a different place @@ -7523,7 +7512,8 @@ int vehicle::break_off( map &here, vehicle_part &vp, int dmg ) } }; std::unique_ptr handler_ptr; - if( g && &get_map() == &here ) { + if( g && &get_map() == + &here ) { // TODO: Refine logic to determine whether it's mapgen or game play. handler_ptr = std::make_unique(); } else { handler_ptr = std::make_unique( here ); @@ -7540,13 +7530,13 @@ int vehicle::break_off( map &here, vehicle_part &vp, int dmg ) // Tow cables - remove it in one piece, remove remote part, and remove towing data add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is disconnected!" ), name, vp_here.name() ); - invalidate_towing( true ); + invalidate_towing( here, true ); } else if( vpi_here.has_flag( VPFLAG_POWER_TRANSFER ) ) { // Electrical cables - remove it in one piece and remove remote part add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is disconnected!" ), name, vp_here.name() ); - here.add_item_or_charges( pos, part_to_item( vp_here ) ); - remove_remote_part( vp_here ); + here.add_item_or_charges( pos, part_to_item( here, vp_here ) ); + remove_remote_part( here, vp_here ); } else if( vp_here.is_broken() ) { // Tearing off a broken part - break it up add_msg_if_player_sees( pos, m_bad, _( "The %s's %s breaks into pieces!" ), name, @@ -7557,7 +7547,7 @@ int vehicle::break_off( map &here, vehicle_part &vp, int dmg ) add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is torn off!" ), name, vp_here.name() ); if( !magic ) { - here.add_item_or_charges( pos, part_to_item( vp_here ) ); + here.add_item_or_charges( pos, part_to_item( here, vp_here ) ); } } remove_part( vp_here, *handler_ptr ); @@ -7572,13 +7562,13 @@ int vehicle::break_off( map &here, vehicle_part &vp, int dmg ) // Tow cables - remove it in one piece, remove remote part, and remove towing data add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is disconnected!" ), name, vp.name() ); - invalidate_towing( true ); + invalidate_towing( here, true ); } else if( vpi.has_flag( VPFLAG_POWER_TRANSFER ) ) { // Electrical cables - remove it in one piece and remove remote part add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is disconnected!" ), name, vp.name() ); - here.add_item_or_charges( pos, part_to_item( vp ) ); - remove_remote_part( vp ); + here.add_item_or_charges( pos, part_to_item( here, vp ) ); + remove_remote_part( here, vp ); } else { //Just break it off add_msg_if_player_sees( pos, m_bad, _( "The %1$s's %2$s is destroyed!" ), name, vp.name() ); @@ -7608,12 +7598,12 @@ int vehicle::break_off( map &here, vehicle_part &vp, int dmg ) } if( remove ) { if( vpi_here.has_flag( "TOW_CABLE" ) ) { - invalidate_towing( true ); + invalidate_towing( here, true ); } else { if( vpi_here.has_flag( VPFLAG_POWER_TRANSFER ) ) { - remove_remote_part( vp_here ); + remove_remote_part( here, vp_here ); } - here.add_item_or_charges( pos, part_to_item( vp_here ) ); + here.add_item_or_charges( pos, part_to_item( here, vp_here ) ); remove_part( vp_here, *handler_ptr ); } } @@ -7624,9 +7614,8 @@ int vehicle::break_off( map &here, vehicle_part &vp, int dmg ) return dmg; } -bool vehicle::explode_fuel( vehicle_part &vp, const damage_type_id &type ) +bool vehicle::explode_fuel( map &here, vehicle_part &vp, const damage_type_id &type ) { - map &here = get_map(); const itype_id &ft = vp.info().fuel_type; item fuel = item( ft ); if( !fuel.has_explosion_data() ) { @@ -7635,7 +7624,7 @@ bool vehicle::explode_fuel( vehicle_part &vp, const damage_type_id &type ) const fuel_explosion_data &data = fuel.get_explosion_data(); if( vp.is_broken() ) { - leak_fuel( vp ); + leak_fuel( here, vp ); } int explosion_chance = type == damage_heat ? data.explosion_chance_hot : @@ -7644,7 +7633,7 @@ bool vehicle::explode_fuel( vehicle_part &vp, const damage_type_id &type ) get_event_bus().send( name ); const int pow = 120 * ( 1 - std::exp( data.explosion_factor / -5000 * ( vp.ammo_remaining() * data.fuel_size_factor ) ) ); - explosion_handler::explosion( nullptr, bub_part_pos( &here, vp ), pow, 0.7, data.fiery_explosion ); + explosion_handler::explosion( nullptr, bub_part_pos( here, vp ), pow, 0.7, data.fiery_explosion ); mod_hp( vp, -vp.hp() ); vp.ammo_unset(); } @@ -7658,7 +7647,7 @@ int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_t return dmg; // part is already dead } const vpart_info &vpi = vp.info(); - const tripoint_bub_ms vppos = bub_part_pos( &here, vp ); + const tripoint_bub_ms vppos = bub_part_pos( here, vp ); // If auto-driving and damage happens, bail out if( is_autodriving ) { stop_autodriving(); @@ -7671,7 +7660,7 @@ int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_t int tsh = std::min( 20, vpi.durability / 10 ); if( dmg < tsh && type != damage_pure ) { if( type == damage_heat && vp.is_fuel_store() ) { - explode_fuel( vp, type ); + explode_fuel( here, vp, type ); } return dmg; @@ -7691,7 +7680,7 @@ int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_t pivot_dirty = true; // destroyed parts lose any contained fuels, battery charges or ammo - leak_fuel( vp ); + leak_fuel( here, vp ); for( const item &e : vp.items ) { here.add_item_or_charges( vppos, e ); @@ -7711,7 +7700,7 @@ int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_t } if( vp.is_fuel_store() ) { - explode_fuel( vp, type ); + explode_fuel( here, vp, type ); } else if( vp.is_broken() && vpi.has_flag( "UNMOUNT_ON_DAMAGE" ) ) { const int vp_idx = index_of_part( &vp, /* include_removed = */ true ); monster *mon = get_monster( here, vp_idx ); @@ -7719,13 +7708,13 @@ int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_t mon->remove_effect( effect_harnessed ); } if( vpi.has_flag( "TOW_CABLE" ) ) { - invalidate_towing( true ); + invalidate_towing( here, true ); } else { - item part_as_item = part_to_item( vp ); + item part_as_item = part_to_item( here, vp ); add_msg_if_player_sees( vppos, m_bad, _( "The %1$s's %2$s is disconnected!" ), name, vp.name() ); if( vpi.has_flag( VPFLAG_POWER_TRANSFER ) ) { - remove_remote_part( vp ); + remove_remote_part( here, vp ); part_as_item.set_damage( 0 ); } else { part_as_item.set_damage( vpi.base_item.obj().damage_max() - 1 ); @@ -7733,7 +7722,7 @@ int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_t if( !magic ) { here.add_item_or_charges( vppos, part_as_item ); } - if( !g || &get_map() != &here ) { + if( !g || &get_map() != &here ) { // TODO: Refine logic to determine if this is mapgen or gameplay. MapgenRemovePartHandler handler( here ); remove_part( vp, handler ); } else { @@ -7745,16 +7734,15 @@ int vehicle::damage_direct( map &here, vehicle_part &vp, int dmg, const damage_t return std::max( dres, 0 ); } -void vehicle::leak_fuel( vehicle_part &pt ) const +void vehicle::leak_fuel( map &here, vehicle_part &pt ) const { // only liquid fuels from non-empty tanks can leak out onto map tiles if( !pt.is_tank() || pt.ammo_remaining() <= 0 ) { return; } - map &here = get_map(); // leak in random directions but prefer closest tiles and avoid walls or other obstacles - std::vector tiles = closest_points_first( bub_part_pos( &here, pt ), 1 ); + std::vector tiles = closest_points_first( bub_part_pos( here, pt ), 1 ); tiles.erase( std::remove_if( tiles.begin(), tiles.end(), [&here]( const tripoint_bub_ms & e ) { return !here.passable( e ); } ), tiles.end() ); @@ -7763,7 +7751,7 @@ void vehicle::leak_fuel( vehicle_part &pt ) const const itype *fuel = item::find_type( pt.ammo_current() ); while( !tiles.empty() && pt.ammo_remaining() ) { int qty = pt.ammo_consume( rng( 0, std::max( pt.ammo_remaining() / 3, 1 ) ), - &here, bub_part_pos( &here, pt ) ); + &here, bub_part_pos( here, pt ) ); if( qty > 0 ) { here.add_item_or_charges( random_entry( tiles ), item( fuel, calendar::turn, qty ) ); } @@ -7827,7 +7815,7 @@ time_duration vehicle::unfolding_time() const } ); } -item vehicle::get_folded_item() const +item vehicle::get_folded_item( map &here ) const { item folded( itype_generic_folded_vehicle, calendar::turn ); const std::vector> &parts = real_parts(); @@ -7859,7 +7847,7 @@ item vehicle::get_folded_item() const const int avg_part_damage = static_cast( sum_of_damage / num_of_parts ); folded.set_var( "tracking", tracking_on ? 1 : 0 ); - folded.set_var( "weight", to_milligram( total_mass() ) ); + folded.set_var( "weight", to_milligram( total_mass( here ) ) ); folded.set_var( "volume", folded_volume / 250_ml ); folded.set_var( "name", string_format( _( "folded %s" ), name ) ); folded.set_var( "vehicle_name", name ); @@ -7975,11 +7963,9 @@ std::set vehicle::get_projected_part_points() const return projected_points; } -std::list vehicle::use_charges( const vpart_position &vp, const itype_id &type, +std::list vehicle::use_charges( map &here, const vpart_position &vp, const itype_id &type, int &quantity, const std::function &filter, bool in_tools ) { - map &here = get_map(); - std::list ret; // HACK: water_faucet pseudo tool gives access to liquids in tanks const itype_id veh_tool_type = type.obj().phase > phase_id::SOLID @@ -8050,7 +8036,7 @@ point_rel_ms vpart_position::mount_pos() const tripoint_bub_ms vpart_position::pos_bub( map *here ) const { - return vehicle().bub_part_pos( here, part_index() ); + return vehicle().bub_part_pos( *here, part_index() ); } tripoint_abs_ms vpart_position::pos_abs() const @@ -8108,7 +8094,7 @@ static bool is_sm_tile_outside( const tripoint_abs_ms &real_global_pos ) sm->get_furn( p ).obj().has_flag( ter_furn_flag::TFLAG_INDOORS ) ); } -void vehicle::update_time( const time_point &update_to ) +void vehicle::update_time( map &here, const time_point &update_to ) { const time_point update_from = last_update; if( update_to < update_from || update_from == time_point( 0 ) ) { @@ -8117,8 +8103,6 @@ void vehicle::update_time( const time_point &update_to ) return; } - map &here = get_map(); - if( sm_pos.z() < 0 ) { last_update = update_to; return; @@ -8184,7 +8168,7 @@ void vehicle::update_time( const time_point &update_to ) units::power epower = 0_W; for( const int p : solar_panels ) { const vehicle_part &vp = parts[p]; - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); if( vp.is_unavailable() || !is_sm_tile_outside( here.get_abs( pos ) ) ) { continue; } @@ -8229,10 +8213,8 @@ void vehicle::invalidate_mass() coeff_water_dirty = true; } -void vehicle::calc_mass_center( bool use_precalc ) const +void vehicle::calc_mass_center( map &here, bool use_precalc ) const { - map &here = get_map(); - units::quantity xf; units::quantity yf; units::mass m_total = 0_gram; @@ -8457,7 +8439,7 @@ vehicle_part_with_fakes_range vehicle::get_all_parts_with_fakes( bool with_inact return vehicle_part_with_fakes_range( const_cast( *this ), with_inactive ); } -item vehicle::part_to_item( const vehicle_part &vp ) const +item vehicle::part_to_item( map &here, const vehicle_part &vp ) const { item tmp = vp.base; tmp.unset_flag( flag_VEHICLE ); @@ -8467,7 +8449,7 @@ item vehicle::part_to_item( const vehicle_part &vp ) const // Tow cables are handled inside of invalidate_towing instead. if( tmp.has_flag( flag_CABLE_SPOOL ) && !tmp.has_flag( flag_TOW_CABLE ) ) { tmp.reset_link( false ); - const std::optional remote = get_remote_part( vp ); + const std::optional remote = get_remote_part( here, vp ); if( remote && tmp.link_to( remote->vehicle(), remote->part().mount, link_state::automatic ).success() ) { tmp.link().t_abs_pos = vp.target.second; @@ -8484,9 +8466,9 @@ item vehicle::part_to_item( const vehicle_part &vp ) const return tmp; } -item vehicle::removed_part( const vehicle_part &vp ) const +item vehicle::removed_part( map &here, const vehicle_part &vp ) const { - item ret = part_to_item( vp ); + item ret = part_to_item( here, vp ); if( vp.info().removed_item ) { ret.convert( *vp.info().removed_item ); } @@ -8548,7 +8530,7 @@ tripoint_bub_ms vehicle::exhaust_dest( map *here, int part ) const p.x() += ( velocity < 0 ? 1 : -1 ); } point_rel_ms q = coord_translate( p ); - return pos_bub( here ) + tripoint_rel_ms( q, 0 ); + return pos_bub( *here ) + tripoint_rel_ms( q, 0 ); } void vehicle::add_tag( const std::string &tag ) diff --git a/src/vehicle.h b/src/vehicle.h index ea62ce4cb00a9..e16200e206925 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -179,7 +179,7 @@ class vehicle_stack : public item_stack public: vehicle_stack( vehicle &veh, vehicle_part &vp ); item_stack::iterator erase( item_stack::const_iterator it ) override; - void insert( const item &newitem ) override; + void insert( map &here, const item &newitem ) override; int count_limit() const override; units::volume max_volume() const override; }; @@ -823,7 +823,7 @@ class vehicle // Removes the part, breaks it into pieces and possibly removes parts attached to it int break_off( map &here, vehicle_part &vp, int dmg ); // Returns if it did actually explode - bool explode_fuel( vehicle_part &vp, const damage_type_id &type ); + bool explode_fuel( map &here, vehicle_part &vp, const damage_type_id &type ); //damages vehicle controls and security system void smash_security_system(); // get vpart powerinfo for part number, accounting for variable-sized parts and hps. @@ -840,11 +840,11 @@ class vehicle // Vehicle fuel indicator (by fuel) // TODO: Figure out what coordinate system "point" is in and type it. - void print_fuel_indicator( const catacurses::window &w, const point &p, + void print_fuel_indicator( map &here, const catacurses::window &w, const point &p, const itype_id &fuel_type, bool verbose = false, bool desc = false ); // TODO: Figure out what coordinate system "point" is in and type it. - void print_fuel_indicator( const catacurses::window &w, const point &p, + void print_fuel_indicator( map &here, const catacurses::window &w, const point &p, const itype_id &fuel_type, std::map fuel_usages, bool verbose = false, bool desc = false ); @@ -856,12 +856,12 @@ class vehicle double engine_cold_factor( const vehicle_part &vp ) const; // refresh pivot_cache, clear pivot_dirty - void refresh_pivot() const; + void refresh_pivot( map &here ) const; - void calc_mass_center( bool precalc ) const; + void calc_mass_center( map &here, bool precalc ) const; /** empty the contents of a tank, battery or turret spilling liquids randomly on the ground */ - void leak_fuel( vehicle_part &pt ) const; + void leak_fuel( map &here, vehicle_part &pt ) const; /// Returns a map of connected vehicle pointers to power loss factor: /// Keys are vehicles connected by POWER_TRANSFER parts, includes self @@ -963,8 +963,8 @@ class vehicle void print_vparts_descs( const catacurses::window &win, int max_y, int width, int p, int &start_at, int &start_limit ) const; // towing functions - void invalidate_towing( bool first_vehicle = false, Character *remover = nullptr ); - void do_towing_move(); + void invalidate_towing( map &here, bool first_vehicle = false, Character *remover = nullptr ); + void do_towing_move( map &here ); bool tow_cable_too_far() const; bool no_towing_slack() const; bool is_towing() const; @@ -1012,7 +1012,7 @@ class vehicle units::angle get_angle_from_targ( const tripoint_abs_ms &targ ) const; void drive_to_local_target( map *here, const tripoint_abs_ms &target, bool follow_protocol ); // Drive automatically towards some destination for one turn. - autodrive_result do_autodrive( Character &driver ); + autodrive_result do_autodrive( map &here, Character &driver ); // Stop any kind of automatic vehicle control and apply the brakes. void stop_autodriving( bool apply_brakes = true ); @@ -1044,18 +1044,18 @@ class vehicle // install a part of type \p type at mount \p dp // @return installed part index or -1 if can_mount(...) failed - int install_part( const point_rel_ms &dp, const vpart_id &type ); + int install_part( map &here, const point_rel_ms &dp, const vpart_id &type ); // install a part of type \p type at mount \p dp with \p base (std::move -ing it) // @return installed part index or -1 if can_mount(...) failed - int install_part( const point_rel_ms &dp, const vpart_id &type, item &&base ); + int install_part( map &here, const point_rel_ms &dp, const vpart_id &type, item &&base ); - int install_part( const point_rel_ms &dp, const vpart_id &type, item &&base, + int install_part( map &here, const point_rel_ms &dp, const vpart_id &type, item &&base, std::vector &installed_with ); // install the given part \p vp (std::move -ing it) // @return installed part index or -1 if can_mount(...) failed - int install_part( const point_rel_ms &dp, vehicle_part &&vp ); + int install_part( map &here, const point_rel_ms &dp, vehicle_part &&vp ); struct rackable_vehicle { std::string name; @@ -1137,11 +1137,11 @@ class vehicle * Useful for, e.g. power cables that have a vehicle part on both sides. * @param vp_local Vehicle part that is connected to the remote part. */ - std::optional get_remote_part( const vehicle_part &vp_local ) const; + std::optional get_remote_part( map &here, const vehicle_part &vp_local ) const; /** * Remove the part on a targeted remote vehicle that a part is targeting. */ - void remove_remote_part( const vehicle_part &vp_local ) const; + void remove_remote_part( map &here, const vehicle_part &vp_local ) const; /** * Yields a range containing all parts (including broken ones) that can be * iterated over. @@ -1300,7 +1300,7 @@ class vehicle part_status_flag condition ); /** Test if part can be enabled (unbroken, sufficient fuel etc), optionally displaying failures to user */ - bool can_enable( const vehicle_part &pt, bool alert = false ) const; + bool can_enable( map &here, const vehicle_part &pt, bool alert = false ) const; /** * Return the index of the next part to open at `p`'s location @@ -1397,14 +1397,14 @@ class vehicle bool below_roof = true, bool roof = true ) const; // Get all printable fuel types - std::vector get_printable_fuel_types() const; + std::vector get_printable_fuel_types( map &here ) const; // Vehicle fuel indicators (all of them) // TODO: Figure out what coordinate system this uses and convert to it. - void print_fuel_indicators( - const catacurses::window &win, const point &, int start_index = 0, - bool fullsize = false, bool verbose = false, bool desc = false, - bool isHorizontal = false ); + void print_fuel_indicators( map &here, + const catacurses::window &win, const point &, int start_index = 0, + bool fullsize = false, bool verbose = false, bool desc = false, + bool isHorizontal = false ); /** * Vehicle speed gauge @@ -1413,8 +1413,9 @@ class vehicle * @param spacing Sets size of space between components * @warning if spacing is negative it is changed to 0 */ - // TODO: Figure out what coordinate system this uses and convert to it. - void print_speed_gauge( const catacurses::window &win, const point &, int spacing = 0 ) const; + // TODO: Figure out what coordinate system this uses and convert to it, or remove it, as it's not used. + void print_speed_gauge( map &here, const catacurses::window &win, const point &, + int spacing = 0 ) const; // Pre-calculate mount points for (idir=0) - current direction or // (idir=1) - next turn direction @@ -1434,7 +1435,7 @@ class vehicle // get character that is currently controlling the vehicle's motion Character *get_driver( map &here ) const; // get monster on a boardable part at p - monster *get_monster( map &here, int p ) const; + monster *get_monster( const map &here, int p ) const; bool enclosed_at( map *here, const tripoint_bub_ms &pos ); // not const because it calls refresh_insides @@ -1445,12 +1446,12 @@ class vehicle tripoint_abs_omt pos_abs_omt() const; // Returns the coordinates (in map squares) of the vehicle relative to the local map. // Warning: Don't assume this position contains a vehicle part - tripoint_bub_ms pos_bub( map *here ) const; + tripoint_bub_ms pos_bub( const map &here ) const; /** * Get the coordinates of the studied part of the vehicle */ - tripoint_bub_ms bub_part_pos( map *here, int index ) const; - tripoint_bub_ms bub_part_pos( map *here, const vehicle_part &pt ) const; + tripoint_bub_ms bub_part_pos( const map &here, int index ) const; + tripoint_bub_ms bub_part_pos( const map &here, 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; /** @@ -1579,19 +1580,19 @@ class vehicle void invalidate_mass(); // get the total mass of vehicle, including cargo and passengers - units::mass total_mass() const; + units::mass total_mass( map &here ) const; // Get the total mass of the vehicle minus the weight of any creatures that are // powering it; ie, the mass of the vehicle that the wheels are supporting units::mass weight_on_wheels( map &here ) const; // Gets the center of mass calculated for precalc[0] coordinates - const point_rel_ms &rotated_center_of_mass() const; + const point_rel_ms &rotated_center_of_mass( map &here ) const; // Gets the center of mass calculated for mount point coordinates - const point_rel_ms &local_center_of_mass() const; + const point_rel_ms &local_center_of_mass( map &here ) const; // Get the pivot point of vehicle; coordinates are unrotated mount coordinates. // This may result in refreshing the pivot point if it is currently stale. - const point_rel_ms &pivot_point() const; + const point_rel_ms &pivot_point( map &here ) const; // Get the (artificial) displacement of the vehicle due to the pivot point changing // between precalc[0] and precalc[1]. This needs to be subtracted from any actual @@ -1680,7 +1681,7 @@ class vehicle * multiplied by a constant to get the constant part of rolling resistance drag in N * depends on wheel design, wheel number, and vehicle weight */ - double coeff_rolling_drag() const; + double coeff_rolling_drag( map &here ) const; /** * coefficient of water drag in kg/m @@ -1688,26 +1689,26 @@ class vehicle * proportional to cross sectional area of the vehicle, times the density of water, * times a dimensional constant based on the vehicle's shape */ - double coeff_water_drag() const; + double coeff_water_drag( map &here ) const; /** * watertight hull height in meters measures distance from bottom of vehicle * to the point where the vehicle will start taking on water */ - double water_hull_height() const; + double water_hull_height( map &here ) const; /** * water draft in meters - how much of the vehicle's body is under water * must be less than the hull height or the boat will sink * at some point, also add boats with deep draft running around */ - double water_draft() const; + double water_draft( map &here ) const; /** * can_float * does the vehicle have freeboard or does it overflow with water? */ - bool can_float() const; + bool can_float( map &here ) const; /** * is the vehicle mostly in water or mostly on fairly dry land? */ @@ -1757,8 +1758,8 @@ class vehicle // Calculate if it can move using its wheels bool sufficient_wheel_config() const; - bool balanced_wheel_config() const; - bool valid_wheel_config() const; + bool balanced_wheel_config( map &here ) const; + bool valid_wheel_config( map &here ) const; // return the relative effectiveness of the steering (1.0 is normal) // <0 means there is no steering installed at all. @@ -1777,20 +1778,21 @@ class vehicle // thrust (1) or brake (-1) vehicle // @param z = z thrust for helicopters etc - void thrust( int thd, int z = 0 ); + void thrust( map &here, int thd, int z = 0 ); /** * if smart controller is enabled, turns on and off engines depending on load and battery level * @param thrusting must be true when called from vehicle::thrust and vehicle is thrusting * @param k_traction_cache cached value of vehicle::k_traction, if empty, will be computed */ - void smart_controller_handle_turn( const std::optional &k_traction_cache = std::nullopt ); + void smart_controller_handle_turn( map &here, + const std::optional &k_traction_cache = std::nullopt ); bool has_available_electric_engine(); void disable_smart_controller_if_needed(); //deceleration due to ground friction and air resistance - int slowdown( int velocity ) const; + int slowdown( map &here, int velocity ) const; // depending on skid vectors, chance to recover. void possibly_recover_from_skid(); @@ -1799,19 +1801,19 @@ class vehicle float forward_velocity() const; // cruise control - void cruise_thrust( int amount ); + void cruise_thrust( map &here, int amount ); // turn vehicle left (negative) or right (positive), degrees void turn( units::angle deg ); // Returns if any collision occurred - bool collision( std::vector &colls, + bool collision( map &here, std::vector &colls, const tripoint_rel_ms &dp, bool just_detect, bool bash_floor = false ); // 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_abs_ms &p, + veh_collision part_collision( map &here, int part, const tripoint_abs_ms &p, bool just_detect, bool bash_floor ); // Process the trap beneath @@ -1821,20 +1823,20 @@ class vehicle /** * vehicle is driving itself */ - void selfdrive( int trn, int acceleration ); + void selfdrive( map &here, int trn, int acceleration ); /** * can the helicopter descend/ascend here? */ - bool check_heli_descend( Character &p ) const; - bool check_heli_ascend( Character &p ) const; - bool check_is_heli_landed(); + bool check_heli_descend( map &here, Character &p ) const; + bool check_heli_ascend( map &here, Character &p ) const; + bool check_is_heli_landed( map &here ); /** * Player is driving the vehicle * @param trn is turn direction * @param acceleration is acceleration * @param z for vertical movement - e.g helicopters */ - void pldrive( Character &driver, int trn, int acceleration, int z = 0 ); + void pldrive( map &here, Character &driver, int trn, int acceleration, int z = 0 ); /** * Flags item \p tool with PSEUDO, if it has MOD pocket then a `pseudo_magazine_mod` is @@ -1891,21 +1893,21 @@ class vehicle const std::vector &get_tools( const vehicle_part &vp ) const; // Generates starting items in the car, should only be called when placed on the map - void place_spawn_items(); + void place_spawn_items( map &here ); void place_zones( map &pmap ) const; - void gain_moves(); + void gain_moves( map &here ); // if its a summoned vehicle - its gotta disappear at some point, return true if destroyed - bool decrement_summon_timer(); + bool decrement_summon_timer( map &here ); // reduces velocity to 0 - void stop(); + void stop( map &here ); void refresh_insides(); - void unboard_all() const; + void unboard_all( map &here ) const; // Damage individual part. bash means damage // must exceed certain threshold to be subtracted from hp @@ -1915,7 +1917,8 @@ class vehicle bool aimed = true ); // damage all parts (like shake from strong collision), range from dmg1 to dmg2 - void damage_all( int dmg1, int dmg2, const damage_type_id &type, const point_rel_ms &impact ); + void damage_all( map &here, int dmg1, int dmg2, const damage_type_id &type, + const point_rel_ms &impact ); //Shifts the coordinates of all parts and moves the vehicle in the opposite direction. void shift_parts( map &here, const point_rel_ms &delta ); @@ -1941,7 +1944,8 @@ class vehicle * @param unlink_tow_cables If tow cables should be unlinked. * @param unlink_power_cords If power grid cables (power_cord) should be unlinked. */ - void unlink_cables( const point_rel_ms &mount, Character &remover, bool unlink_items = false, + void unlink_cables( map &here, const point_rel_ms &mount, Character &remover, + bool unlink_items = false, bool unlink_tow_cables = false, bool unlink_power_cords = false ); /** @@ -2028,7 +2032,8 @@ class vehicle * @param filter Must return true for use to occur. * @return items that provide consumed charges */ - std::list use_charges( const vpart_position &vp, const itype_id &type, int &quantity, + std::list use_charges( map &here, const vpart_position &vp, const itype_id &type, + int &quantity, const std::function &filter, bool in_tools = false ); // opens/closes/locks doors or multipart doors @@ -2047,7 +2052,7 @@ class vehicle // @returns how long should unfolding activity take time_duration unfolding_time() const; // @returns item of this vehicle folded - item get_folded_item() const; + item get_folded_item( map &here ) const; // restores vehicle parts from a folded item // @returns true if succeeded bool restore_folded_parts( const item &it ); @@ -2097,7 +2102,7 @@ class vehicle //true if an engine exists with specified type //If enabled true, this engine must be enabled to return true bool has_engine_type( const itype_id &ft, bool enabled ) const; - monster *get_harnessed_animal() const; + monster *get_harnessed_animal( const map &here ) const; //true if an engine exists without the specified type //If enabled true, this engine must be enabled to return true bool has_engine_type_not( const itype_id &ft, bool enabled ) const; @@ -2119,7 +2124,7 @@ class vehicle // update vehicle parts as the vehicle moves void on_move( map &here ); // move the vehicle on the map. Returns updated pointer to self. - vehicle *act_on_map(); + vehicle *act_on_map( map &here ); // check if the vehicle should be falling or is in water void check_falling_or_floating(); @@ -2132,11 +2137,11 @@ class vehicle * &wheels_on_rail - resulting wheels that land on ter_flag_to_check * &turning_wheels_that_are_one_axis_counter - number of wheels that are on one axis and will land on rail */ - void precalculate_vehicle_turning( units::angle new_turn_dir, bool check_rail_direction, + void precalculate_vehicle_turning( map &here, units::angle new_turn_dir, bool check_rail_direction, ter_furn_flag ter_flag_to_check, int &wheels_on_rail, int &turning_wheels_that_are_one_axis_counter ) const; - bool allow_auto_turn_on_rails( units::angle &corrected_turn_dir ) const; - bool allow_manual_turn_on_rails( units::angle &corrected_turn_dir ) const; + bool allow_auto_turn_on_rails( map &here, units::angle &corrected_turn_dir ) const; + bool allow_manual_turn_on_rails( map &here, units::angle &corrected_turn_dir ) const; bool is_wheel_state_correct_to_turn_on_rails( int wheels_on_rail, int wheel_count, int turning_wheels_that_are_one_axis ) const; /** @@ -2160,7 +2165,7 @@ class vehicle std::string disp_name() const; /** Required strength to be able to successfully lift the vehicle unaided by equipment */ - int lift_strength() const; + int lift_strength( map &here ) const; // Called by map.cpp to make sure the real position of each zone_data is accurate bool refresh_zones(); @@ -2168,7 +2173,7 @@ class vehicle bounding_box get_bounding_box( bool use_precalc = true, bool no_fake = false ); // Retroactively pass time spent outside bubble // Funnels, solar panels - void update_time( const time_point &update_to ); + void update_time( map &here, const time_point &update_to ); // The faction that owns this vehicle. faction_id owner = faction_id::NULL_ID(); @@ -2199,7 +2204,7 @@ class vehicle vpart_edge_info get_edge_info( const point_rel_ms &mount ) const; // Removes fake parts from the parts vector - void remove_fake_parts( bool cleanup = true ); + void remove_fake_parts( map &here, bool cleanup = true ); bool should_enable_fake( const tripoint_rel_ms &fake_precalc, const tripoint_rel_ms &parent_precalc, const tripoint_rel_ms &neighbor_precalc ) const; public: @@ -2223,13 +2228,13 @@ class vehicle * Generate the corresponding item from this vehicle part. It includes * the hp (item damage), fuel charges (battery or liquids), aspect, ... */ - item part_to_item( const vehicle_part &vp ) const; + item part_to_item( map &here, const vehicle_part &vp ) const; /** * If the vehicle part has an item it is removed as, transform the item * to the item it is removed_as */ - item removed_part( const vehicle_part &vp ) const; + item removed_part( map &here, const vehicle_part &vp ) const; // Updates the internal precalculated mount offsets after the vehicle has been displaced // used in map::displace_vehicle() @@ -2238,7 +2243,7 @@ class vehicle const tripoint_rel_ms &dp, int ramp_offset, bool adjust_pos, std::set parts_to_move ); // make sure the vehicle is supported across z-levels or on the same z-level - bool level_vehicle(); + bool level_vehicle( map &here ); // These are lists of part numbers used for quick lookup of various kinds of vehicle parts. // They are rebuilt in vehicle::refresh() diff --git a/src/vehicle_autodrive.cpp b/src/vehicle_autodrive.cpp index ffec614620fae..e925d6956b8f5 100644 --- a/src/vehicle_autodrive.cpp +++ b/src/vehicle_autodrive.cpp @@ -352,12 +352,12 @@ struct auto_navigation_data { return view_to_map.inverse().transform( p.raw().xy() ); } // transforms a point from map bub coords into view map coords - point to_view( const tripoint_bub_ms &p ) const { - return to_view( get_map().get_abs( p ) ); + point to_view( const map &here, const tripoint_bub_ms &p ) const { + return to_view( here.get_abs( p ) ); } // returns `p` adjusted so that the z-level is placed on the ground - template - Tripoint adjust_z( const Tripoint &p ) const; + tripoint_bub_ms adjust_z( map &here, const tripoint_bub_ms &p ) const; + tripoint_abs_ms adjust_z( const tripoint_abs_ms &p ) const; }; enum class collision_check_result : int { @@ -377,9 +377,9 @@ class vehicle::autodrive_controller const auto_navigation_data &get_data() { return data; } - void check_safe_speed(); - std::optional compute_next_step(); - collision_check_result check_collision_zone( orientation turn_dir ); + void check_safe_speed( map &here ); + std::optional compute_next_step( map &here ); + collision_check_result check_collision_zone( map &here, orientation turn_dir ); void reduce_speed(); private: @@ -388,14 +388,14 @@ class vehicle::autodrive_controller auto_navigation_data data; void compute_coordinates(); - bool check_drivable( const tripoint_bub_ms &pt ) const; - void compute_obstacles(); + bool check_drivable( map &here, const tripoint_bub_ms &pt ) const; + void compute_obstacles( map &here ); void enqueue_if_ramp( point_queue &ramp_points, const map &here, const tripoint_bub_ms &p ) const; - void compute_obstacles_from_enqueued_ramp_points( point_queue &ramp_points, const map &here ); - vehicle_profile compute_profile( orientation facing ) const; + void compute_obstacles_from_enqueued_ramp_points( point_queue &ramp_points, map &here ); + vehicle_profile compute_profile( map &here, orientation facing ) const; void compute_valid_positions(); void compute_goal_zone(); - void precompute_data(); + void precompute_data( map &here ); scored_address compute_node_score( const node_address &addr, const navigation_node &node ) const; void compute_next_nodes( const node_address &addr, const navigation_node &node, int target_speed_tps, @@ -603,8 +603,20 @@ static int signum( int val ) return ( 0 < val ) - ( val < 0 ); } -template -Tripoint auto_navigation_data::adjust_z( const Tripoint &p ) const +tripoint_bub_ms auto_navigation_data::adjust_z( map &here, const tripoint_bub_ms &p ) const +{ + if( !land_ok ) { + return p; + } + const point pt_view = to_view( here, p ); + if( !view_bounds.contains( pt_view ) ) { + debugmsg( "Autodrive tried to adjust zlevel on out-of-bounds point p=%s", p.to_string() ); + return p; // shouldn't happen, but who knows. + } + return { p.xy(), ground_z[pt_view] }; +} + +tripoint_abs_ms auto_navigation_data::adjust_z( const tripoint_abs_ms &p ) const { if( !land_ok ) { return p; @@ -634,13 +646,14 @@ void vehicle::autodrive_controller::compute_coordinates() data.view_to_map.pre_offset += data.nav_to_view.post_offset; } -vehicle_profile vehicle::autodrive_controller::compute_profile( orientation facing ) const +vehicle_profile vehicle::autodrive_controller::compute_profile( map &here, + orientation facing ) const { vehicle_profile ret; tileray tdir( to_angle( facing ) ); ret.tdir = tdir; std::map> extent_map; - const point_rel_ms pivot = driven_veh.pivot_point(); + const point_rel_ms pivot = driven_veh.pivot_point( here ); for( const vehicle_part &part : driven_veh.parts ) { if( part.removed ) { continue; @@ -697,10 +710,8 @@ vehicle_profile vehicle::autodrive_controller::compute_profile( orientation faci // Return true if the map tile at the given position (in map coordinates) // can be driven on (not an obstacle). // The logic should match what is in vehicle::part_collision(). -bool vehicle::autodrive_controller::check_drivable( const tripoint_bub_ms &pt ) const +bool vehicle::autodrive_controller::check_drivable( map &here, const tripoint_bub_ms &pt ) const { - const map &here = get_map(); - // check if another vehicle is there; tiles occupied by the current // vehicle are evidently drivable const optional_vpart_position ovp = here.veh_at( pt ); @@ -792,16 +803,15 @@ bool vehicle::autodrive_controller::check_drivable( const tripoint_bub_ms &pt ) return true; } -void vehicle::autodrive_controller::compute_obstacles() +void vehicle::autodrive_controller::compute_obstacles( map &here ) { - const map &here = get_map(); const int z = data.current_omt.z(); point_queue ramp_points; for( int dx = 0; dx < NAV_VIEW_SIZE_X; dx++ ) { for( int dy = 0; dy < NAV_VIEW_SIZE_Y; dy++ ) { const tripoint_abs_ms abs_map_pt( data.view_to_map.transform( point( dx, dy ), z ) ); const tripoint_bub_ms p = here.get_bub( abs_map_pt ); - data.is_obstacle[dx][dy] = !check_drivable( p ); + data.is_obstacle[dx][dy] = !check_drivable( here, p ); data.ground_z[dx][dy] = z; enqueue_if_ramp( ramp_points, here, p ); } @@ -830,17 +840,17 @@ void vehicle::autodrive_controller::enqueue_if_ramp( point_queue &ramp_points, // set `is_obstacle` and `ground_z` again, based on whether they are an obstacle or not on // this zlevel. void vehicle::autodrive_controller::compute_obstacles_from_enqueued_ramp_points( - point_queue &ramp_points, const map &here ) + point_queue &ramp_points, map &here ) { auto is_drivable = [this, &here]( const tripoint_bub_ms & p ) { - return here.inbounds( p ) && check_drivable( p ); + return here.inbounds( p ) && check_drivable( here, p ); }; while( !ramp_points.to_check.empty() ) { const tripoint_bub_ms ramp_point = ramp_points.to_check.front(); ramp_points.to_check.pop(); for( const tripoint_bub_ms &p : ff::point_flood_fill_4_connected( ramp_point, ramp_points.visited, is_drivable ) ) { - const point pt_view = data.to_view( p ); + const point pt_view = data.to_view( here, p ); if( !data.view_bounds.contains( pt_view ) ) { continue; } @@ -916,10 +926,8 @@ void vehicle::autodrive_controller::compute_goal_zone() data.goal_points[1] = goal_transform.transform( point( x, OMT_SIZE / 2 - 1 ) ); } -void vehicle::autodrive_controller::precompute_data() +void vehicle::autodrive_controller::precompute_data( map &here ) { - map &here = get_map(); - const tripoint_abs_omt current_omt = driven_veh.pos_abs_omt(); const tripoint_abs_omt next_omt = driver.omt_path.back(); const tripoint_abs_omt next_next_omt = driver.omt_path.size() >= 2 ? @@ -931,8 +939,8 @@ void vehicle::autodrive_controller::precompute_data() data.next_next_omt = next_next_omt; // initialize car and driver properties - data.land_ok = driven_veh.valid_wheel_config(); - data.water_ok = driven_veh.can_float(); + data.land_ok = driven_veh.valid_wheel_config( here ); + data.water_ok = driven_veh.can_float( here ); data.air_ok = driven_veh.has_sufficient_rotorlift( here ); data.is_flying = driven_veh.is_rotorcraft( here ) && driven_veh.is_flying_in_air(); data.max_speed_tps = std::min( @@ -948,12 +956,12 @@ void vehicle::autodrive_controller::precompute_data() // or maybe just keep track of player moves? data.max_steer = 1; for( orientation dir : all_orientations() ) { - data.profile( dir ) = compute_profile( dir ); + data.profile( dir ) = compute_profile( here, dir ); } // initialize navigation data compute_coordinates(); - compute_obstacles(); + compute_obstacles( here ); compute_valid_positions(); compute_goal_zone(); data.path.clear(); @@ -1139,10 +1147,8 @@ vehicle::autodrive_controller::autodrive_controller( const vehicle &driven_veh, data.clear(); } -void vehicle::autodrive_controller::check_safe_speed() +void vehicle::autodrive_controller::check_safe_speed( map &here ) { - map &here = get_map(); - // We normally drive at or below the vehicle's "safe speed" (beyond which the engine starts // taking damage). We normally determine this at the beginning of path planning and cache it. // However, sometimes the vehicle's safe speed may drop (e.g. amphibious vehicle entering @@ -1153,11 +1159,10 @@ void vehicle::autodrive_controller::check_safe_speed() } } -collision_check_result vehicle::autodrive_controller::check_collision_zone( orientation turn_dir ) +collision_check_result vehicle::autodrive_controller::check_collision_zone( map &here, + orientation turn_dir ) { - map &here = get_map(); - - const tripoint_bub_ms veh_pos = driven_veh.pos_bub( &here ); + const tripoint_bub_ms veh_pos = driven_veh.pos_bub( here ); // first check if we have any visibility in front, to prevent blind driving tileray face_dir = driven_veh.face; @@ -1166,7 +1171,7 @@ collision_check_result vehicle::autodrive_controller::check_collision_zone( orie bool changed_zlevel = false; bool blind = true; for( const point_rel_ms &p : data.profile( to_orientation( face_dir.dir() ) ).collision_points ) { - const tripoint_bub_ms next = data.adjust_z( veh_pos + forward_offset + p ); + const tripoint_bub_ms next = data.adjust_z( here, veh_pos + forward_offset + p ); if( driver.sees( next ) ) { blind = false; } @@ -1197,7 +1202,7 @@ collision_check_result vehicle::autodrive_controller::check_collision_zone( orie collision_zone.insert( p + offset ); } for( const point_rel_ms &p : collision_zone ) { - if( !check_drivable( data.adjust_z( veh_pos + p ) ) ) { + if( !check_drivable( here, data.adjust_z( here, veh_pos + p ) ) ) { return collision_check_result::close_obstacle; } } @@ -1212,11 +1217,11 @@ collision_check_result vehicle::autodrive_controller::check_collision_zone( orie } } for( const point_rel_ms &p : collision_zone ) { - const tripoint_bub_ms next = data.adjust_z( veh_pos + p ); + const tripoint_bub_ms next = data.adjust_z( here, veh_pos + p ); if( !data.is_flying && !driver.sees( next ) ) { return collision_check_result::slow_down; } - if( !check_drivable( next ) ) { + if( !check_drivable( here, next ) ) { return collision_check_result::slow_down; } } @@ -1228,9 +1233,9 @@ void vehicle::autodrive_controller::reduce_speed() data.max_speed_tps = MIN_SPEED_TPS; } -std::optional vehicle::autodrive_controller::compute_next_step() +std::optional vehicle::autodrive_controller::compute_next_step( map &here ) { - precompute_data(); + precompute_data( here ); const tripoint_abs_ms veh_pos = driven_veh.pos_abs(); const bool had_cached_path = !data.path.empty(); const bool two_steps = data.path.size() > 2; @@ -1360,10 +1365,8 @@ std::vector> vehicle::get_debug_overl return ret; } -autodrive_result vehicle::do_autodrive( Character &driver ) +autodrive_result vehicle::do_autodrive( map &here, Character &driver ) { - map &here = get_map(); - if( !is_autodriving ) { return autodrive_result::abort; } @@ -1390,8 +1393,8 @@ autodrive_result vehicle::do_autodrive( Character &driver ) stop_autodriving(); return autodrive_result::abort; } - active_autodrive_controller->check_safe_speed(); - std::optional next_step = active_autodrive_controller->compute_next_step(); + active_autodrive_controller->check_safe_speed( here ); + std::optional next_step = active_autodrive_controller->compute_next_step( here ); if( !next_step ) { // message handles pathfinding failure either due to obstacles or inability to see driver.add_msg_if_player( m_warning, _( "Can't see a path forward." ) ); @@ -1411,7 +1414,7 @@ autodrive_result vehicle::do_autodrive( Character &driver ) // check for collisions before we steer, since steering may end our turn // which would cause the vehicle to move and maybe crash - switch( active_autodrive_controller->check_collision_zone( next_step->steering_dir ) ) { + switch( active_autodrive_controller->check_collision_zone( here, next_step->steering_dir ) ) { case collision_check_result::no_visibility: driver.add_msg_if_player( m_warning, _( "You can't see anything in front of your vehicle!" ) ); stop_autodriving(); @@ -1439,7 +1442,7 @@ autodrive_result vehicle::do_autodrive( Character &driver ) // nothing we can do about it now, hope we don't crash! break; } - pldrive( driver, signum( turn_delta ), 0 ); + pldrive( here, driver, signum( turn_delta ), 0 ); } // Don't do anything else below; the driver's turn may be over (moves <= 0) so // any extra actions would be "cheating". diff --git a/src/vehicle_display.cpp b/src/vehicle_display.cpp index d63d9294025be..d05da86fc7ad9 100644 --- a/src/vehicle_display.cpp +++ b/src/vehicle_display.cpp @@ -313,10 +313,8 @@ void vehicle::print_vparts_descs( const catacurses::window &win, int max_y, int * Returns an array of fuel types that can be printed * @return An array of printable fuel type ids */ -std::vector vehicle::get_printable_fuel_types() const +std::vector vehicle::get_printable_fuel_types( map &here ) const { - map &here = get_map(); - std::set opts; for( const vpart_reference &vpr : get_all_parts() ) { const vehicle_part &pt = vpr.part(); @@ -345,10 +343,11 @@ std::vector vehicle::get_printable_fuel_types() const * @param desc true if the name of the fuel should be at the end * @param isHorizontal true if the menu is not vertical */ -void vehicle::print_fuel_indicators( const catacurses::window &win, const point &p, int start_index, +void vehicle::print_fuel_indicators( map &here, const catacurses::window &win, const point &p, + int start_index, bool fullsize, bool verbose, bool desc, bool isHorizontal ) { - auto fuels = get_printable_fuel_types(); + auto fuels = get_printable_fuel_types( here ); if( fuels.empty() ) { return; } @@ -357,12 +356,12 @@ void vehicle::print_fuel_indicators( const catacurses::window &win, const point const vehicle_part &vp = parts[part_idx]; // if only one display, print the first engine that's on and consumes power if( is_engine_on( vp ) && !is_perpetual_type( vp ) && !is_engine_type( vp, fuel_type_muscle ) ) { - print_fuel_indicator( win, p, vp.fuel_current(), verbose, desc ); + print_fuel_indicator( here, win, p, vp.fuel_current(), verbose, desc ); return; } } // or print the first fuel if no engines - print_fuel_indicator( win, p, fuels.front(), verbose, desc ); + print_fuel_indicator( here, win, p, fuels.front(), verbose, desc ); return; } @@ -372,7 +371,7 @@ void vehicle::print_fuel_indicators( const catacurses::window &win, const point for( int i = start_index; i < max_size; i++ ) { const itype_id &f = fuels[i]; - print_fuel_indicator( win, p + point( 0, yofs ), f, fuel_used_last_turn, verbose, desc ); + print_fuel_indicator( here, win, p + point( 0, yofs ), f, fuel_used_last_turn, verbose, desc ); yofs++; } @@ -392,20 +391,18 @@ void vehicle::print_fuel_indicators( const catacurses::window &win, const point * @param desc true if the name of the fuel should be at the end * @param fuel_usages map of fuel types to consumption for verbose */ -void vehicle::print_fuel_indicator( const catacurses::window &win, const point &p, +void vehicle::print_fuel_indicator( map &here, const catacurses::window &win, const point &p, const itype_id &fuel_type, bool verbose, bool desc ) { std::map fuel_usages; - print_fuel_indicator( win, p, fuel_type, fuel_usages, verbose, desc ); + print_fuel_indicator( here, win, p, fuel_type, fuel_usages, verbose, desc ); } -void vehicle::print_fuel_indicator( const catacurses::window &win, const point &p, +void vehicle::print_fuel_indicator( map &here, const catacurses::window &win, const point &p, const itype_id &fuel_type, std::map fuel_usages, bool verbose, bool desc ) { - map &here = get_map(); - static constexpr std::array fsyms = { 'E', '\\', '|', '/', 'F' }; nc_color col_indf1 = c_light_gray; int cap = fuel_capacity( here, fuel_type ); @@ -474,10 +471,9 @@ void vehicle::print_fuel_indicator( const catacurses::window &win, const point & } } -void vehicle::print_speed_gauge( const catacurses::window &win, const point &p, int spacing ) const +void vehicle::print_speed_gauge( map &here, const catacurses::window &win, const point &p, + int spacing ) const { - map &here = get_map(); - if( spacing < 0 ) { spacing = 0; } diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index 14b0b89c14fa4..3008a42c72b0e 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -107,7 +107,7 @@ int vmiph_to_cmps( int vmiph ) return vmiph / mps_to_miph; } -int vehicle::slowdown( int at_velocity ) const +int vehicle::slowdown( map &here, int at_velocity ) const { double mps = vmiph_to_mps( std::abs( at_velocity ) ); @@ -115,21 +115,23 @@ int vehicle::slowdown( int at_velocity ) const double f_total_drag = coeff_air_drag() * mps * mps; if( is_watercraft() ) { // same with water resistance - f_total_drag += coeff_water_drag() * mps * mps; + f_total_drag += coeff_water_drag( here ) * mps * mps; } else if( !is_falling && !is_flying ) { - double f_rolling_drag = coeff_rolling_drag() * ( vehicles::rolling_constant_to_variable + mps ); + double f_rolling_drag = coeff_rolling_drag( here ) * ( vehicles::rolling_constant_to_variable + + mps ); // increase rolling resistance by up to 25x if the vehicle is skidding at right angle to facing const double skid_factor = 1 + 24 * std::abs( units::sin( face.dir() - move.dir() ) ); f_total_drag += f_rolling_drag * skid_factor; } // check mass to make sure it's not 0 which happens for some reason - double accel_slowdown = total_mass().value() > 0 ? f_total_drag / to_kilogram( total_mass() ) : 0; + double accel_slowdown = total_mass( here ).value() > 0 ? f_total_drag / to_kilogram( total_mass( + here ) ) : 0; // converting m/s^2 to vmiph/s int slowdown = mps_to_vmiph( accel_slowdown ); if( is_towing() ) { vehicle *other_veh = tow_data.get_towed(); if( other_veh ) { - slowdown += other_veh->slowdown( at_velocity ); + slowdown += other_veh->slowdown( here, at_velocity ); } } if( slowdown < 0 ) { @@ -139,17 +141,16 @@ int vehicle::slowdown( int at_velocity ) const "%s at %d vimph, f_drag %3.2f, drag accel %d vmiph - extra drag %d", name, at_velocity, f_total_drag, slowdown, units::to_watt( static_drag() ) ); // plows slow rolling vehicles, but not falling or floating vehicles - if( !( is_falling || ( is_watercraft() && can_float() ) || is_flying ) ) { + if( !( is_falling || ( is_watercraft() && can_float( here ) ) || is_flying ) ) { slowdown -= units::to_watt( static_drag() ); } return std::max( 1, slowdown ); } -void vehicle::smart_controller_handle_turn( const std::optional &k_traction_cache ) +void vehicle::smart_controller_handle_turn( map &here, + const std::optional &k_traction_cache ) { - map &here = get_map(); - // get settings or defaults smart_controller_config cfg = smart_controller_cfg.value_or( smart_controller_config() ); @@ -447,29 +448,28 @@ void vehicle::smart_controller_handle_turn( const std::optional &k_tracti update_alternator_load( here ); } -void vehicle::thrust( int thd, int z ) +void vehicle::thrust( map &here, int thd, int z ) { - map &here = get_map(); - //if vehicle is stopped, set target direction to forward. //ensure it is not skidding. Set turns used to 0. if( !is_moving() && z == 0 ) { turn_dir = face.dir(); - stop(); + stop( here ); } bool pl_ctrl = player_is_driving_this_veh( &here ); // No need to change velocity if there are no wheels - if( ( is_watercraft() && can_float() ) || ( is_rotorcraft( here ) && ( z != 0 || is_flying ) ) ) { + if( ( is_watercraft() && can_float( here ) ) || ( is_rotorcraft( here ) && ( z != 0 || + is_flying ) ) ) { // we're good - } else if( in_deep_water && !can_float() ) { - stop(); + } else if( in_deep_water && !can_float( here ) ) { + stop( here ); if( pl_ctrl ) { add_msg( _( "The %s is too leaky!" ), name ); } return; - } else if( !valid_wheel_config() && z == 0 ) { - stop(); + } else if( !valid_wheel_config( here ) && z == 0 ) { + stop( here ); if( pl_ctrl ) { add_msg( _( "The %s doesn't have enough wheels to move!" ), name ); } @@ -486,7 +486,7 @@ void vehicle::thrust( int thd, int z ) float traction = k_traction( here, here.vehicle_wheel_traction( *this ) ); if( thrusting ) { - smart_controller_handle_turn( traction ); + smart_controller_handle_turn( here, traction ); } int accel = current_acceleration( here ) * traction; @@ -602,7 +602,7 @@ void vehicle::thrust( int thd, int z ) //change vehicles velocity if( ( velocity > 0 && velocity + vel_inc < 0 ) || ( velocity < 0 && velocity + vel_inc > 0 ) ) { //velocity within braking distance of 0 - stop(); + stop( here ); } else { // Increase velocity up to max_vel or min_vel, but not above. const int min_vel = max_reverse_velocity( here ); @@ -630,10 +630,8 @@ void vehicle::thrust( int thd, int z ) } } -void vehicle::cruise_thrust( int amount ) +void vehicle::cruise_thrust( map &here, int amount ) { - map &here = get_map(); - if( amount == 0 ) { return; } @@ -685,14 +683,13 @@ void vehicle::turn( units::angle deg ) turn_dir = round_to_multiple_of( turn_dir, vehicles::steer_increment ); } -void vehicle::stop() +void vehicle::stop( map &here ) { velocity = 0; skidding = false; move = face; last_turn = 0_degrees; of_turn_carry = 0; - map &here = get_map(); for( const tripoint_abs_ms &p : get_points() ) { if( here.inbounds( p ) ) { here.memory_cache_dec_set_dirty( here.get_bub( p ), true ); @@ -700,11 +697,10 @@ void vehicle::stop() } } -bool vehicle::collision( std::vector &colls, +bool vehicle::collision( map &here, std::vector &colls, const tripoint_rel_ms &dp, bool just_detect, bool bash_floor ) { - map &here = get_map(); /* * Big TODO: * Rewrite this function so that it has "pre-collision" phase (detection) @@ -721,14 +717,14 @@ bool vehicle::collision( std::vector &colls, if( dp.z() != 0 && ( dp.x() != 0 || dp.y() != 0 ) ) { // Split into horizontal + vertical - return collision( colls, tripoint_rel_ms( dp.xy(), 0 ), just_detect, bash_floor ) || - collision( colls, tripoint_rel_ms( 0, 0, dp.z() ), just_detect, bash_floor ); + return collision( here, colls, tripoint_rel_ms( dp.xy(), 0 ), just_detect, bash_floor ) || + collision( here, colls, tripoint_rel_ms( 0, 0, dp.z() ), just_detect, bash_floor ); } if( dp.z() == -1 && !bash_floor ) { // First check current level, then the one below if current had no collisions // Bash floors on the current one, but not on the one below. - if( collision( colls, tripoint_rel_ms::zero, just_detect, true ) ) { + if( collision( here, colls, tripoint_rel_ms::zero, just_detect, true ) ) { return true; } } @@ -759,11 +755,12 @@ bool vehicle::collision( std::vector &colls, // Coordinates of where part will go due to movement (dx/dy/dz) // and turning (precalc[1]) const tripoint_abs_ms dsp = vp.next_pos; - veh_collision coll = part_collision( p, dsp, just_detect, bash_floor ); + veh_collision coll = part_collision( here, 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( here.get_bub( dsp ), radius ) ) { - veh_collision rotor_coll = part_collision( p, here.get_abs( rotor_point ), just_detect, false ); + veh_collision rotor_coll = part_collision( here, p, here.get_abs( rotor_point ), just_detect, + false ); if( rotor_coll.type != veh_coll_nothing ) { coll = rotor_coll; if( just_detect ) { @@ -823,11 +820,10 @@ bool vehicle::collision( std::vector &colls, } // A helper to make sure mass and density is always calculated the same way -static void terrain_collision_data( const tripoint_bub_ms &p, bool bash_floor, +static void terrain_collision_data( map &here, const tripoint_bub_ms &p, bool bash_floor, float &mass, float &density, float &elastic ) { elastic = 0.30; - map &here = get_map(); // Just a rough rescale for now to obtain approximately equal numbers const int bash_min = here.bash_resistance( p, bash_floor ); const int bash_max = here.bash_strength( p, bash_floor ); @@ -835,10 +831,9 @@ 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_abs_ms &p, +veh_collision vehicle::part_collision( map &here, 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 @@ -897,7 +892,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_abs_ms &p, 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 ); + ( parts[part].mount.x() > pivot_point( here ).x() ? -1 : 1 ); 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 @@ -961,7 +956,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_abs_ms &p, this->can_use_rails( here ) ) ) ) { // Movecost 2 indicates flat terrain like a floor, no collision there. ret.type = veh_coll_bashable; - terrain_collision_data( pos, bash_floor, mass2, part_dens, e ); + terrain_collision_data( here, 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 ) ) ) { @@ -983,7 +978,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_abs_ms &p, // Rotors only use rotor mass in calculation. const float mass = vpi.has_flag( VPFLAG_ROTOR ) ? to_kilogram( vp.base.weight() ) - : to_kilogram( total_mass() ); + : to_kilogram( total_mass( here ) ); //Calculate damage resulting from d_E const itype *type = item::find_type( vpi.base_item ); @@ -1079,7 +1074,7 @@ veh_collision vehicle::part_collision( int part, const tripoint_abs_ms &p, if( here.is_bashable_ter_furn( pos, bash_floor ) ) { // There's new terrain there to smash smashed = false; - terrain_collision_data( pos, bash_floor, mass2, part_dens, e ); + terrain_collision_data( here, 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! @@ -1308,10 +1303,8 @@ void vehicle::handle_trap( map *here, const tripoint_bub_ms &p, vehicle_part &vp } } -monster *vehicle::get_harnessed_animal() const +monster *vehicle::get_harnessed_animal( const map &here ) const { - map &here = get_map(); - for( size_t e = 0; e < parts.size(); e++ ) { const vehicle_part &vp = parts[ e ]; if( vp.info().fuel_type == fuel_type_animal ) { @@ -1324,11 +1317,9 @@ monster *vehicle::get_harnessed_animal() const return nullptr; } -void vehicle::selfdrive( const int trn, const int acceleration ) +void vehicle::selfdrive( map &here, const int trn, const int acceleration ) { - map &here = get_map(); - - if( !is_towed() && !magic && !get_harnessed_animal() && !has_part( "AUTOPILOT" ) ) { + if( !is_towed() && !magic && !get_harnessed_animal( here ) && !has_part( "AUTOPILOT" ) ) { is_following = false; return; } @@ -1341,13 +1332,13 @@ void vehicle::selfdrive( const int trn, const int acceleration ) if( acceleration != 0 ) { if( !is_towed() ) { const int thr_amount = std::abs( velocity ) < 2000 ? 400 : 500; - cruise_thrust( -acceleration * thr_amount ); + cruise_thrust( here, -acceleration * thr_amount ); } else { - thrust( -acceleration ); + thrust( here, -acceleration ); } } // TODO: Actually check if we're on land on water (or disable water-skidding) - if( skidding && valid_wheel_config() ) { + if( skidding && valid_wheel_config( here ) ) { const float handling_diff = handling_difficulty( here ); if( handling_diff * rng( 1, 10 ) < 15 ) { velocity = static_cast( forward_velocity() ); @@ -1357,24 +1348,20 @@ void vehicle::selfdrive( const int trn, const int acceleration ) } } -bool vehicle::check_is_heli_landed() +bool vehicle::check_is_heli_landed( map &here ) { - map &here = get_map(); - // @TODO - when there are chasms that extend below z-level 0 - perhaps the heli // will be able to descend into them but for now, assume z-level-0 == the ground. if( pos_abs().z() == 0 || - !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_NO_FLOOR, pos_bub( &here ) ) ) { + !here.has_flag_ter_or_furn( ter_furn_flag::TFLAG_NO_FLOOR, pos_bub( here ) ) ) { is_flying = false; return true; } return false; } -bool vehicle::check_heli_descend( Character &p ) const +bool vehicle::check_heli_descend( map &here, Character &p ) const { - map &here = get_map(); - if( !is_rotorcraft( here ) ) { debugmsg( "A vehicle is somehow flying without being an aircraft" ); return true; @@ -1408,10 +1395,8 @@ bool vehicle::check_heli_descend( Character &p ) const } -bool vehicle::check_heli_ascend( Character &p ) const +bool vehicle::check_heli_ascend( map &here, Character &p ) const { - map &here = get_map(); - if( !is_rotorcraft( here ) ) { debugmsg( "A vehicle is somehow flying without being an aircraft" ); return true; @@ -1440,10 +1425,9 @@ bool vehicle::check_heli_ascend( Character &p ) const return true; } -void vehicle::pldrive( Character &driver, const int trn, const int acceleration, const int z ) +void vehicle::pldrive( map &here, Character &driver, const int trn, const int acceleration, + const int z ) { - map &here = get_map(); - bool is_non_proficient = false; float effective_driver_skill = driver.get_skill_level( skill_driving ); float vehicle_proficiency; @@ -1476,7 +1460,7 @@ void vehicle::pldrive( Character &driver, const int trn, const int acceleration, } if( z != 0 && is_rotorcraft( here ) ) { driver.set_moves( std::min( driver.get_moves(), 0 ) ); - thrust( 0, z ); + thrust( here, 0, z ); } units::angle turn_delta = vehicles::steer_increment * trn; const float handling_diff = handling_difficulty( here ) + non_prof_penalty; @@ -1558,11 +1542,11 @@ void vehicle::pldrive( Character &driver, const int trn, const int acceleration, } if( acceleration != 0 ) { - cruise_thrust( -acceleration * 400 ); + cruise_thrust( here, -acceleration * 400 ); } // TODO: Actually check if we're on land on water (or disable water-skidding) - if( skidding && trn != 0 && valid_wheel_config() ) { + if( skidding && trn != 0 && valid_wheel_config( here ) ) { ///\EFFECT_DEX increases chance of regaining control of a vehicle ///\EFFECT_DRIVING increases chance of regaining control of a vehicle @@ -1659,7 +1643,8 @@ float get_collision_factor( const float delta_v ) } } -void vehicle::precalculate_vehicle_turning( units::angle new_turn_dir, bool check_rail_direction, +void vehicle::precalculate_vehicle_turning( map &here, units::angle new_turn_dir, + bool check_rail_direction, const ter_furn_flag ter_flag_to_check, int &wheels_on_rail, int &turning_wheels_that_are_one_axis ) const { @@ -1688,15 +1673,14 @@ void vehicle::precalculate_vehicle_turning( units::angle new_turn_dir, bool chec */ turning_wheels_that_are_one_axis = 0; - map &here = get_map(); for( int part_index : wheelcache ) { const auto &wheel = parts[ part_index ]; bool rails_ahead = true; tripoint_rel_ms wheel_point; - coord_translate( mdir.dir(), this->pivot_point(), wheel.mount, + coord_translate( mdir.dir(), this->pivot_point( here ), wheel.mount, wheel_point ); - tripoint_bub_ms wheel_tripoint = pos_bub( &here ) + wheel_point; + tripoint_bub_ms wheel_tripoint = pos_bub( here ) + wheel_point; // maximum number of incorrect tiles for this type of turn(diagonal or not) const int allowed_incorrect_tiles_diagonal = 1; @@ -1765,7 +1749,7 @@ static units::angle get_corrected_turn_dir( const units::angle &turn_dir, return normalize( corrected_turn_dir ); } -bool vehicle::allow_manual_turn_on_rails( units::angle &corrected_turn_dir ) const +bool vehicle::allow_manual_turn_on_rails( map &here, units::angle &corrected_turn_dir ) const { bool allow_turn_on_rail = false; // driver tried to turn rails vehicle @@ -1774,7 +1758,8 @@ bool vehicle::allow_manual_turn_on_rails( units::angle &corrected_turn_dir ) con int wheels_on_rail; int turning_wheels_that_are_one_axis; - precalculate_vehicle_turning( corrected_turn_dir, true, ter_furn_flag::TFLAG_RAIL, wheels_on_rail, + precalculate_vehicle_turning( here, corrected_turn_dir, true, ter_furn_flag::TFLAG_RAIL, + wheels_on_rail, turning_wheels_that_are_one_axis ); if( is_wheel_state_correct_to_turn_on_rails( wheels_on_rail, rail_wheelcache.size(), turning_wheels_that_are_one_axis ) ) { @@ -1784,7 +1769,7 @@ bool vehicle::allow_manual_turn_on_rails( units::angle &corrected_turn_dir ) con return allow_turn_on_rail; } -bool vehicle::allow_auto_turn_on_rails( units::angle &corrected_turn_dir ) const +bool vehicle::allow_auto_turn_on_rails( map &here, units::angle &corrected_turn_dir ) const { bool allow_turn_on_rail = false; // check if autoturn is possible @@ -1792,14 +1777,15 @@ bool vehicle::allow_auto_turn_on_rails( units::angle &corrected_turn_dir ) const // precalculate wheels for every direction int straight_wheels_on_rail; int straight_turning_wheels_that_are_one_axis; - precalculate_vehicle_turning( face.dir(), true, ter_furn_flag::TFLAG_RAIL, straight_wheels_on_rail, + precalculate_vehicle_turning( here, face.dir(), true, ter_furn_flag::TFLAG_RAIL, + straight_wheels_on_rail, straight_turning_wheels_that_are_one_axis ); units::angle left_turn_dir = get_corrected_turn_dir( face.dir() - 45_degrees, face.dir() ); int leftturn_wheels_on_rail; int leftturn_turning_wheels_that_are_one_axis; - precalculate_vehicle_turning( left_turn_dir, true, ter_furn_flag::TFLAG_RAIL, + precalculate_vehicle_turning( here, left_turn_dir, true, ter_furn_flag::TFLAG_RAIL, leftturn_wheels_on_rail, leftturn_turning_wheels_that_are_one_axis ); @@ -1807,7 +1793,7 @@ bool vehicle::allow_auto_turn_on_rails( units::angle &corrected_turn_dir ) const get_corrected_turn_dir( face.dir() + 45_degrees, face.dir() ); int rightturn_wheels_on_rail; int rightturn_turning_wheels_that_are_one_axis; - precalculate_vehicle_turning( right_turn_dir, true, ter_furn_flag::TFLAG_RAIL, + precalculate_vehicle_turning( here, right_turn_dir, true, ter_furn_flag::TFLAG_RAIL, rightturn_wheels_on_rail, rightturn_turning_wheels_that_are_one_axis ); @@ -1841,29 +1827,27 @@ bool vehicle::is_wheel_state_correct_to_turn_on_rails( int wheels_on_rail, int w // allow turn for vehicles with wheel distance < 4 when moving backwards } -vehicle *vehicle::act_on_map() +vehicle *vehicle::act_on_map( map &here ) { - map &here = get_map(); - - const tripoint_bub_ms pt = pos_bub( &here ); + const tripoint_bub_ms pt = pos_bub( here ); if( !here.inbounds( pt ) ) { dbg( D_INFO ) << "stopping out-of-map vehicle. (x,y,z)=(" << pt.x() << "," << pt.y() << "," << pt.z() << ")"; - stop(); + stop( here ); of_turn = 0; is_falling = false; return this; } - if( decrement_summon_timer() ) { + if( decrement_summon_timer( here ) ) { return nullptr; } const bool pl_ctrl = player_is_driving_this_veh( &here ); // TODO: Remove this hack, have vehicle sink a z-level - if( in_deep_water && !can_float() ) { + if( in_deep_water && !can_float( here ) ) { add_msg( m_bad, _( "Your %s sank." ), name ); if( pl_ctrl ) { - unboard_all(); + unboard_all( here ); } if( g->remoteveh() == this ) { g->setremoteveh( nullptr ); @@ -1900,7 +1884,7 @@ vehicle *vehicle::act_on_map() // Low enough for bicycles to go in reverse. // If the movement is due to a change in z-level, i.e a helicopter then the lateral movement will often be zero. if( !should_fall && std::abs( velocity ) < 20 && requested_z_change == 0 ) { - stop(); + stop( here ); of_turn -= .321f; return this; } @@ -1910,7 +1894,7 @@ vehicle *vehicle::act_on_map() if( traction < 0.001f ) { of_turn = 0; if( !should_fall ) { - stop(); + stop( here ); if( floating.empty() ) { add_msg( m_info, _( "Your %s can't move on this terrain." ), name ); } else { @@ -1955,7 +1939,7 @@ vehicle *vehicle::act_on_map() // Eventually send it skidding if no control // But not if it's remotely controlled, is in water or can use rails - if( !controlled && !pl_ctrl && !( is_watercraft() && can_float() ) && !can_use_rails && + if( !controlled && !pl_ctrl && !( is_watercraft() && can_float( here ) ) && !can_use_rails && !is_flying && requested_z_change == 0 ) { skidding = true; } @@ -1974,9 +1958,9 @@ vehicle *vehicle::act_on_map() bool allow_turn_on_rail = false; if( can_use_rails && !falling_only ) { units::angle corrected_turn_dir; - allow_turn_on_rail = allow_manual_turn_on_rails( corrected_turn_dir ); + allow_turn_on_rail = allow_manual_turn_on_rails( here, corrected_turn_dir ); if( !allow_turn_on_rail ) { - allow_turn_on_rail = allow_auto_turn_on_rails( corrected_turn_dir ); + allow_turn_on_rail = allow_auto_turn_on_rails( here, corrected_turn_dir ); } if( allow_turn_on_rail ) { turn_dir = corrected_turn_dir; @@ -2018,9 +2002,8 @@ vehicle *vehicle::act_on_map() return here.move_vehicle( *this, dp, mdir ); } -bool vehicle::level_vehicle() +bool vehicle::level_vehicle( map &here ) { - map &here = get_map(); if( is_flying && is_rotorcraft( here ) ) { return true; } @@ -2031,7 +2014,7 @@ bool vehicle::level_vehicle() if( prt.info().location != part_location_structure ) { continue; } - const tripoint_bub_ms part_pos = bub_part_pos( &here, prt ); + const tripoint_bub_ms part_pos = bub_part_pos( here, prt ); if( no_support.find( part_pos.z() ) == no_support.end() ) { no_support[part_pos.z()] = part_pos.z() > -OVERMAP_DEPTH; } @@ -2108,7 +2091,7 @@ void vehicle::check_falling_or_floating() // Check under the wheels, if they're supported nothing else matters. int supported_wheels = 0; for( int wheel_index : wheelcache ) { - const tripoint_bub_ms position = bub_part_pos( &here, wheel_index ); + const tripoint_bub_ms position = bub_part_pos( here, wheel_index ); if( has_support( position, false ) ) { ++supported_wheels; } @@ -2153,9 +2136,9 @@ void vehicle::check_falling_or_floating() float map::vehicle_wheel_traction( const vehicle &veh, bool ignore_movement_modifiers ) { if( veh.is_in_water( /* deep_water = */ true ) ) { - return veh.can_float() ? 1.0f : -1.0f; + return veh.can_float( *this ) ? 1.0f : -1.0f; } - if( veh.is_watercraft() && veh.can_float() ) { + if( veh.is_watercraft() && veh.can_float( *this ) ) { return 1.0f; } @@ -2169,7 +2152,7 @@ float map::vehicle_wheel_traction( const vehicle &veh, bool ignore_movement_modi for( const int wheel_idx : veh.wheelcache ) { const vehicle_part &vp = veh.part( wheel_idx ); const vpart_info &vpi = vp.info(); - const tripoint_bub_ms pp = veh.bub_part_pos( this, vp ); + const tripoint_bub_ms pp = veh.bub_part_pos( *this, vp ); const ter_t &tr = ter( pp ).obj(); if( tr.has_flag( ter_furn_flag::TFLAG_DEEP_WATER ) || tr.has_flag( ter_furn_flag::TFLAG_NO_FLOOR ) ) { @@ -2225,7 +2208,7 @@ units::angle map::shake_vehicle( vehicle &veh, const int velocity_before, continue; } - const tripoint_bub_ms part_pos = veh.bub_part_pos( &here, ps ); + const tripoint_bub_ms part_pos = veh.bub_part_pos( here, ps ); if( rider->pos_bub() != part_pos ) { debugmsg( "throw passenger: passenger at %d,%d,%d, part at %d,%d,%d", rider->posx(), rider->posy(), rider->posz(), diff --git a/src/vehicle_part.cpp b/src/vehicle_part.cpp index e72e88ea9112d..0d469b4bcd2c7 100644 --- a/src/vehicle_part.cpp +++ b/src/vehicle_part.cpp @@ -660,10 +660,8 @@ bool vehicle::mod_hp( vehicle_part &pt, int qty ) return pt.base.mod_damage( -qty * pt.base.max_damage() / dur ); } -bool vehicle::can_enable( const vehicle_part &pt, bool alert ) const +bool vehicle::can_enable( map &here, const vehicle_part &pt, bool alert ) const { - map &here = get_map(); - if( std::none_of( parts.begin(), parts.end(), [&pt]( const vehicle_part & e ) { return &e == &pt; } ) || pt.removed ) { diff --git a/src/vehicle_selector.cpp b/src/vehicle_selector.cpp index 16bbda88a6cc1..9b747e2ac39a8 100644 --- a/src/vehicle_selector.cpp +++ b/src/vehicle_selector.cpp @@ -6,10 +6,10 @@ #include "point.h" #include "vpart_position.h" -vehicle_selector::vehicle_selector( const tripoint_bub_ms &pos, int radius, bool accessible, +vehicle_selector::vehicle_selector( map &here, const tripoint_bub_ms &pos, int radius, + bool accessible, bool visibility_only ) { - map &here = get_map(); for( const tripoint_bub_ms &e : closest_points_first( pos, radius ) ) { if( !accessible || ( visibility_only ? here.sees( pos, e, radius ) : here.clear_path( pos, e, radius, 1, 100 ) ) ) { @@ -20,10 +20,10 @@ vehicle_selector::vehicle_selector( const tripoint_bub_ms &pos, int radius, bool } } -vehicle_selector::vehicle_selector( const tripoint_bub_ms &pos, int radius, bool accessible, +vehicle_selector::vehicle_selector( map &here, const tripoint_bub_ms &pos, int radius, + bool accessible, const vehicle &ignore ) { - map &here = get_map(); for( const tripoint_bub_ms &e : closest_points_first( pos, radius ) ) { if( !accessible || here.clear_path( pos, e, radius, 1, 100 ) ) { if( const optional_vpart_position vp = here.veh_at( e ) ) { diff --git a/src/vehicle_selector.h b/src/vehicle_selector.h index 49cf3f7c59728..ea539ee6ff9e4 100644 --- a/src/vehicle_selector.h +++ b/src/vehicle_selector.h @@ -13,6 +13,7 @@ #include "visitable.h" class item; +class map; class vehicle; struct tripoint; @@ -51,7 +52,8 @@ class vehicle_selector : public visitable * @param accessible whether found items must be accessible from pos to be considered * @param visibility_only accessibility based on line of sight, not walkability */ - explicit vehicle_selector( const tripoint_bub_ms &pos, int radius = 0, bool accessible = true, + explicit vehicle_selector( map &here, const tripoint_bub_ms &pos, int radius = 0, + bool accessible = true, bool visibility_only = false ); /** @@ -61,7 +63,8 @@ class vehicle_selector : public visitable * @param accessible whether found items must be accessible from pos to be considered * @param ignore don't include this vehicle as part of the selection */ - vehicle_selector( const tripoint_bub_ms &pos, int radius, bool accessible, const vehicle &ignore ); + vehicle_selector( map &here, const tripoint_bub_ms &pos, int radius, bool accessible, + const vehicle &ignore ); // similar to item_location you are not supposed to store this class between turns vehicle_selector( const vehicle_selector &that ) = delete; diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 845053c777f64..2eeade6c5be7b 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -111,6 +111,7 @@ static const zone_type_id zone_type_VEHICLE_PATROL( "VEHICLE_PATROL" ); void handbrake() { + map &here = get_map(); Character &player_character = get_player_character(); const optional_vpart_position vp = get_map().veh_at( player_character.pos_bub() ); if( !vp ) { @@ -126,7 +127,7 @@ void handbrake() } else { int braking_power = std::abs( veh->velocity ) / 2 + 10 * 100; if( std::abs( veh->velocity ) < braking_power ) { - veh->stop(); + veh->stop( here ); } else { int sgn = veh->velocity > 0 ? 1 : -1; veh->velocity = sgn * ( std::abs( veh->velocity ) - braking_power ); @@ -181,7 +182,7 @@ void vehicle::control_doors() const bool open = !vp.open; menu.add( string_format( "%s %s", actname, vp.name() ) ) .hotkey_auto() - .location( bub_part_pos( &here, vp ).raw() ) + .location( bub_part_pos( here, vp ).raw() ) .keep_menu_open() .on_submit( [this, vp_idx, open] { if( can_close( vp_idx, get_player_character() ) ) @@ -200,7 +201,7 @@ void vehicle::control_doors() const bool lock = !vp.locked; menu.add( string_format( "%s %s", actname, vp.name() ) ) .hotkey_auto() - .location( bub_part_pos( &here, vp ).raw() ) + .location( bub_part_pos( here, vp ).raw() ) .keep_menu_open() .on_submit( [this, vp_idx, lock] { lock_or_unlock( vp_idx, lock ); @@ -248,7 +249,7 @@ void vehicle::control_doors() } while( menu.query() ); } -static void add_electronic_toggle( vehicle &veh, veh_menu &menu, const std::string &name, +static void add_electronic_toggle( map &here, vehicle &veh, veh_menu &menu, const std::string &name, const std::string &action, const std::string &flag ) { // fetch matching parts and abort early if none found @@ -264,8 +265,9 @@ static void add_electronic_toggle( vehicle &veh, veh_menu &menu, const std::stri // can this menu option be selected by the user? // if toggled part potentially usable check if could be enabled now (sufficient fuel etc.) - bool allow = !state || std::any_of( found.begin(), found.end(), []( const vpart_reference & vp ) { - return vp.vehicle().can_enable( vp.part() ); + bool allow = !state || + std::any_of( found.begin(), found.end(), [&here]( const vpart_reference & vp ) { + return vp.vehicle().can_enable( here, vp.part() ); } ); const std::string msg = state ? _( "Turn on %s" ) : colorize( _( "Turn off %s" ), c_pink ); @@ -315,9 +317,9 @@ void vehicle::build_electronics_menu( veh_menu &menu ) } ); } - auto add_toggle = [this, &menu]( const std::string & name, const std::string & action, + auto add_toggle = [&here, this, &menu]( const std::string & name, const std::string & action, const std::string & flag ) { - add_electronic_toggle( *this, menu, name, action, flag ); + add_electronic_toggle( here, *this, menu, name, action, flag ); }; add_toggle( pgettext( "electronics menu option", "reactor" ), "TOGGLE_REACTOR", "REACTOR" ); @@ -588,7 +590,7 @@ double vehicle::engine_cold_factor( const vehicle_part &vp ) const return 0.0; } - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); double eff_temp = units::to_fahrenheit( get_weather().get_temperature( pos ) ); if( !vp.has_fault_flag( "BAD_COLD_START" ) ) { eff_temp = std::min( eff_temp, 20.0 ); @@ -685,7 +687,7 @@ bool vehicle::start_engine( vehicle_part &vp ) const double dmg = vp.damage_percent(); const time_duration start_time = engine_start_time( vp ); - const tripoint_bub_ms pos = bub_part_pos( &here, vp ); + const tripoint_bub_ms pos = bub_part_pos( here, vp ); if( ( 1 - dmg ) < vpi.engine_info->backfire_threshold && one_in( vpi.engine_info->backfire_freq ) ) { @@ -771,7 +773,7 @@ void vehicle::stop_engines() continue; } - sounds::sound( bub_part_pos( &here, vp ), 2, sounds::sound_t::movement, + sounds::sound( bub_part_pos( here, vp ), 2, sounds::sound_t::movement, _( "the engine go silent" ) ); std::string variant = vp.info().id.str(); @@ -817,7 +819,7 @@ void vehicle::start_engines( Character *driver, const bool take_control, const b for( const int p : engines ) { const vehicle_part &vp = parts[p]; if( !has_starting_engine_position && !vp.is_broken() && vp.enabled ) { - starting_engine_position = bub_part_pos( &here, vp ); + starting_engine_position = bub_part_pos( here, vp ); has_starting_engine_position = true; } has_engine = has_engine || is_engine_on( vp ); @@ -1144,12 +1146,12 @@ void vehicle::operate_scoop() _( "Whirrrr" ), _( "Ker-chunk" ), _( "Swish" ), _( "Cugugugugug" ) } }; - sounds::sound( bub_part_pos( &here, scoop ), rng( 20, 35 ), sounds::sound_t::combat, + sounds::sound( bub_part_pos( here, scoop ), rng( 20, 35 ), sounds::sound_t::combat, random_entry_ref( sound_msgs ), false, "vehicle", "scoop" ); std::vector parts_points; parts_points.reserve( 8 ); for( const tripoint_bub_ms ¤t : - here.points_in_radius( bub_part_pos( &here, scoop ), 1 ) ) { + here.points_in_radius( bub_part_pos( here, scoop ), 1 ) ) { parts_points.push_back( current ); } for( const tripoint_bub_ms &position : parts_points ) { @@ -1204,7 +1206,7 @@ void vehicle::alarm() _( "WHOOP WHOOP" ), _( "NEEeu NEEeu NEEeu" ), _( "BLEEEEEEP" ), _( "WREEP" ) } }; - sounds::sound( pos_bub( &here ), static_cast( rng( 45, 80 ) ), + sounds::sound( pos_bub( here ), static_cast( rng( 45, 80 ) ), sounds::sound_t::alarm, random_entry_ref( sound_msgs ), false, "vehicle", "car_alarm" ); if( one_in( 1000 ) ) { is_alarm_on = false; @@ -2142,8 +2144,8 @@ void vehicle::build_interact_menu( veh_menu &menu, map *here, const tripoint_bub .desc( string_format( !item_linked && !tow_linked ? "" : _( "Remove other cables first" ) ) ) .skip_locked_check() .hotkey( "DISCONNECT_CABLES" ) - .on_submit( [this, vp] { - unlink_cables( vp.mount_pos(), get_player_character(), true, true, true ); + .on_submit( [here, this, vp] { + unlink_cables( *here, vp.mount_pos(), get_player_character(), true, true, true ); get_player_character().pause(); } ); } @@ -2153,8 +2155,8 @@ void vehicle::build_interact_menu( veh_menu &menu, map *here, const tripoint_bub menu.add( menu_text ) .skip_locked_check() .hotkey( "DISCONNECT_CABLES" ) - .on_submit( [this, vp] { - unlink_cables( vp.mount_pos(), get_player_character(), true, true, false ); + .on_submit( [here, this, vp] { + unlink_cables( *here, vp.mount_pos(), get_player_character(), true, true, false ); get_player_character().pause(); } ); } @@ -2322,14 +2324,14 @@ void vehicle::build_interact_menu( veh_menu &menu, map *here, const tripoint_bub .enable( fuel_left( *here, itype_water ) && fuel_left( *here, itype_battery ) >= itype_water_purifier->charges_to_use() ) .hotkey( "PURIFY_WATER" ) - .on_submit( [this, here] { + .on_submit( [this, &here] { const auto sel = []( const vehicle_part & pt ) { return pt.is_tank() && pt.ammo_current() == itype_water; }; std::string title = string_format( _( "Purify water in tank" ), get_all_colors().get_name( itype_water->color ) ); - const std::optional vpr = veh_interact::select_part( *this, sel, title ); + const std::optional vpr = veh_interact::select_part( *here, *this, sel, title ); if( !vpr ) { return; diff --git a/tests/crafting_test.cpp b/tests/crafting_test.cpp index 371e710f23d11..1b0a73787f0fc 100644 --- a/tests/crafting_test.cpp +++ b/tests/crafting_test.cpp @@ -483,6 +483,7 @@ static void grant_profs_to_character( Character &you, const recipe &r ) static void prep_craft( const recipe_id &rid, const std::vector &tools, bool expect_craftable, int offset = 0, bool grant_profs = false, bool plug_in_tools = true ) { + map &here = get_map(); clear_avatar(); clear_map(); @@ -498,7 +499,7 @@ static void prep_craft( const recipe_id &rid, const std::vector &tools, const tripoint_bub_ms battery_pos = test_origin + tripoint::north; std::optional battery_item( itype_test_storage_battery ); - place_appliance( battery_pos, vpart_ap_test_storage_battery, player_character, battery_item ); + place_appliance( here, battery_pos, vpart_ap_test_storage_battery, player_character, battery_item ); give_tools( tools, plug_in_tools ); const inventory &crafting_inv = player_character.crafting_inventory(); @@ -2384,7 +2385,7 @@ TEST_CASE( "pseudo_tools_in_crafting_inventory", "[crafting][tools]" ) CHECK( player.crafting_inventory().charges_of( itype_water ) == 0 ); } WHEN( "the vehicle has a water faucet part" ) { - REQUIRE( veh->install_part( point_rel_ms::zero, vpart_water_faucet ) >= 0 ); + REQUIRE( veh->install_part( here, point_rel_ms::zero, vpart_water_faucet ) >= 0 ); THEN( "crafting inventory contains the liquid" ) { player.invalidate_crafting_inventory(); CHECK( player.crafting_inventory().count_item( itype_water_faucet ) == 1 ); @@ -2392,7 +2393,7 @@ TEST_CASE( "pseudo_tools_in_crafting_inventory", "[crafting][tools]" ) } } WHEN( "the vehicle has two water faucets" ) { - REQUIRE( veh->install_part( point_rel_ms::south, vpart_water_faucet ) >= 0 ); + REQUIRE( veh->install_part( here, point_rel_ms::south, vpart_water_faucet ) >= 0 ); THEN( "crafting inventory contains the liquid" ) { player.invalidate_crafting_inventory(); CHECK( player.crafting_inventory().count_item( itype_water_faucet ) == 1 ); diff --git a/tests/mapgen_remove_vehicles_test.cpp b/tests/mapgen_remove_vehicles_test.cpp index 3e982d2f27141..93214bdfa9168 100644 --- a/tests/mapgen_remove_vehicles_test.cpp +++ b/tests/mapgen_remove_vehicles_test.cpp @@ -27,11 +27,11 @@ void check_vehicle_still_works( vehicle &veh ) veh.engine_on = true; veh.velocity = 1000; veh.cruise_velocity = veh.velocity; - tripoint_bub_ms const startp = veh.pos_bub( &here ); + tripoint_bub_ms const startp = veh.pos_bub( here ); here.vehmove(); - REQUIRE( veh.pos_bub( &here ) != startp ); + REQUIRE( veh.pos_bub( here ) != startp ); - here.displace_vehicle( veh, startp - veh.pos_bub( &here ) ); + here.displace_vehicle( veh, startp - veh.pos_bub( here ) ); } vehicle *add_test_vehicle( map &m, tripoint_bub_ms loc ) diff --git a/tests/npc_test.cpp b/tests/npc_test.cpp index e9b8588fd6f6a..99dc6ec72deb2 100644 --- a/tests/npc_test.cpp +++ b/tests/npc_test.cpp @@ -475,8 +475,8 @@ TEST_CASE( "npc-movement" ) if( type == 'V' || type == 'W' || type == 'M' ) { vehicle *veh = here.add_vehicle( vehicle_prototype_none, p, 270_degrees, 0, 0 ); REQUIRE( veh != nullptr ); - veh->install_part( point_rel_ms::zero, vpart_frame ); - veh->install_part( point_rel_ms::zero, vpart_seat ); + veh->install_part( here, point_rel_ms::zero, vpart_frame ); + veh->install_part( here, point_rel_ms::zero, vpart_seat ); here.add_vehicle_to_cache( veh ); } // spawn npcs diff --git a/tests/vehicle_drag_test.cpp b/tests/vehicle_drag_test.cpp index 457f7fb3bbf91..c7c25ba1ad312 100644 --- a/tests/vehicle_drag_test.cpp +++ b/tests/vehicle_drag_test.cpp @@ -93,8 +93,8 @@ static bool test_drag( } const double c_air = veh_ptr->coeff_air_drag(); - const double c_rolling = veh_ptr->coeff_rolling_drag(); - const double c_water = veh_ptr->coeff_water_drag(); + const double c_rolling = veh_ptr->coeff_rolling_drag( here ); + const double c_water = veh_ptr->coeff_water_drag( here ); const int safe_v = veh_ptr->safe_ground_velocity( here, false ); const int max_v = veh_ptr->max_ground_velocity( here, false ); diff --git a/tests/vehicle_efficiency_test.cpp b/tests/vehicle_efficiency_test.cpp index 18e95a6398c21..28778d83fcb42 100644 --- a/tests/vehicle_efficiency_test.cpp +++ b/tests/vehicle_efficiency_test.cpp @@ -197,9 +197,9 @@ static int test_efficiency( const vproto_id &veh_id, int &expected_mass, veh.refresh_insides(); if( test_mass ) { - CHECK( to_gram( veh.total_mass() ) == expected_mass ); + CHECK( to_gram( veh.total_mass( here ) ) == expected_mass ); } - expected_mass = to_gram( veh.total_mass() ); + expected_mass = to_gram( veh.total_mass( here ) ); veh.check_falling_or_floating(); REQUIRE( !veh.is_in_water() ); const auto &starting_fuel = set_vehicle_fuel( veh, fuel_level ); @@ -208,7 +208,7 @@ static int test_efficiency( const vproto_id &veh_id, int &expected_mass, const float starting_fuel_per = fuel_percentage_left( veh, starting_fuel ); REQUIRE( std::abs( starting_fuel_per - 1.0f ) < 0.001f ); - const tripoint_bub_ms starting_point = veh.pos_bub( &here ); + const tripoint_bub_ms starting_point = veh.pos_bub( here ); veh.tags.insert( "IN_CONTROL_OVERRIDE" ); veh.engine_on = true; @@ -235,9 +235,9 @@ static int test_efficiency( const vproto_id &veh_id, int &expected_mass, REQUIRE( here.ter( here.get_bub( pos ) ) ); } // How much it moved - tiles_travelled += square_dist( starting_point, veh.pos_bub( &here ) ); + tiles_travelled += square_dist( starting_point, veh.pos_bub( here ) ); // Bring it back to starting point to prevent it from leaving the map - const tripoint_rel_ms displacement = starting_point - veh.pos_bub( &here ); + const tripoint_rel_ms displacement = starting_point - veh.pos_bub( here ); here.displace_vehicle( veh, displacement ); if( reset_velocity_turn < 0 ) { continue; diff --git a/tests/vehicle_fake_part_test.cpp b/tests/vehicle_fake_part_test.cpp index d7c6ffc729cde..5ced25f0ce582 100644 --- a/tests/vehicle_fake_part_test.cpp +++ b/tests/vehicle_fake_part_test.cpp @@ -178,12 +178,12 @@ TEST_CASE( "ensure_vehicle_weight_is_constant", "[vehicle] [vehicle_fake]" ) veh->velocity = veh->cruise_velocity; GIVEN( "A vehicle with a known weight" ) { - units::mass initial_weight = veh->total_mass(); + units::mass initial_weight = veh->total_mass( here ); WHEN( "The vehicle turns such that it is not perpendicular to a cardinal axis" ) { veh->turn( 45_degrees ); here.vehmove(); THEN( "The vehicle weight is constant" ) { - units::mass turned_weight = veh->total_mass(); + units::mass turned_weight = veh->total_mass( here ); CHECK( initial_weight == turned_weight ); } } @@ -258,7 +258,7 @@ TEST_CASE( "vehicle_to_vehicle_collision", "[vehicle] [vehicle_fake]" ) const tripoint_bub_ms test_origin( 30, 30, 0 ); vehicle *veh = here.add_vehicle( vehicle_prototype_test_van, test_origin, 30_degrees, 100, 0 ); REQUIRE( veh != nullptr ); - const tripoint_bub_ms global_origin = veh->pos_bub( &here ); + const tripoint_bub_ms global_origin = veh->pos_bub( here ); veh->tags.insert( "IN_CONTROL_OVERRIDE" ); veh->engine_on = true; @@ -266,7 +266,7 @@ TEST_CASE( "vehicle_to_vehicle_collision", "[vehicle] [vehicle_fake]" ) veh->cruise_velocity = target_velocity; veh->velocity = veh->cruise_velocity; here.vehmove(); - const tripoint_bub_ms global_move = veh->pos_bub( &here ); + const tripoint_bub_ms global_move = veh->pos_bub( here ); const tripoint_bub_ms obstacle_point = test_origin + 2 * ( global_move - global_origin ); vehicle *trg = here.add_vehicle( vehicle_prototype_schoolbus, obstacle_point, 90_degrees, 100, 0 ); REQUIRE( trg != nullptr ); diff --git a/tests/vehicle_interact_test.cpp b/tests/vehicle_interact_test.cpp index e8293b014be74..b6a7791ec5e92 100644 --- a/tests/vehicle_interact_test.cpp +++ b/tests/vehicle_interact_test.cpp @@ -51,7 +51,7 @@ static void test_repair( const std::vector &tools, bool plug_in_tools, boo const tripoint_bub_ms battery_pos = test_origin + tripoint::north_west; std::optional battery_item( itype_test_storage_battery ); - place_appliance( battery_pos, vpart_ap_test_storage_battery, player_character, battery_item ); + place_appliance( here, battery_pos, vpart_ap_test_storage_battery, player_character, battery_item ); for( const item &gear : tools ) { item_location added_tool = player_character.i_add( gear ); diff --git a/tests/vehicle_part_test.cpp b/tests/vehicle_part_test.cpp index 4c746a95de78d..c47b25d0ba4ed 100644 --- a/tests/vehicle_part_test.cpp +++ b/tests/vehicle_part_test.cpp @@ -197,7 +197,7 @@ static void test_craft_via_rig( const std::vector &items, int give_battery CHECK( veh.battery_power_level().first == expect_battery ); CHECK( veh.fuel_left( here, itype_water_clean ) == expect_water ); - veh.unboard_all(); + veh.unboard_all( here ); } TEST_CASE( "faucet_offers_cold_water", "[vehicle][vehicle_parts]" ) diff --git a/tests/vehicle_power_test.cpp b/tests/vehicle_power_test.cpp index 458a4f4899ecd..041815e89fc5a 100644 --- a/tests/vehicle_power_test.cpp +++ b/tests/vehicle_power_test.cpp @@ -73,7 +73,7 @@ TEST_CASE( "power_loss_to_cables", "[vehicle][power]" ) vehicle_part source_part( vpid, item( cord ) ); source_part.target.first = target_global; source_part.target.second = target_veh->pos_abs(); - source_veh->install_part( vcoords, std::move( source_part ) ); + source_veh->install_part( here, vcoords, std::move( source_part ) ); vcoords = target_vp->mount_pos(); vehicle_part target_part( vpid, item( cord ) ); @@ -82,7 +82,7 @@ TEST_CASE( "power_loss_to_cables", "[vehicle][power]" ) cord.get_var( "source_z", 0 ) ); target_part.target.first = here.get_abs( source_global ); target_part.target.second = source_veh->pos_abs(); - target_veh->install_part( vcoords, std::move( target_part ) ); + target_veh->install_part( here, vcoords, std::move( target_part ) ); }; const std::vector placements { { 4, 10, 0 }, { 6, 10, 0 }, { 8, 10, 0 } }; @@ -91,9 +91,9 @@ TEST_CASE( "power_loss_to_cables", "[vehicle][power]" ) REQUIRE( !here.veh_at( p ).has_value() ); vehicle *veh = here.add_vehicle( vehicle_prototype_none, p, 0_degrees, 0, 0 ); REQUIRE( veh != nullptr ); - const int frame_part_idx = veh->install_part( point_rel_ms::zero, vpart_frame ); + const int frame_part_idx = veh->install_part( here, point_rel_ms::zero, vpart_frame ); REQUIRE( frame_part_idx != -1 ); - const int bat_part_idx = veh->install_part( point_rel_ms::zero, vpart_small_storage_battery ); + const int bat_part_idx = veh->install_part( here, point_rel_ms::zero, vpart_small_storage_battery ); REQUIRE( bat_part_idx != -1 ); veh->refresh( ); here.add_vehicle_to_cache( veh ); @@ -148,11 +148,11 @@ TEST_CASE( "Solar_power", "[vehicle][power]" ) SECTION( "Summer day noon" ) { calendar::turn = calendar::turn_zero + calendar::season_length() + 1_days + 12_hours; - veh_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); REQUIRE( veh_ptr->fuel_left( here, fuel_type_battery ) == 0 ); WHEN( "30 minutes elapse" ) { - veh_ptr->update_time( calendar::turn + 30_minutes ); + veh_ptr->update_time( here, calendar::turn + 30_minutes ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); CHECK( power == Approx( 425 ).margin( 1 ) ); } @@ -161,11 +161,11 @@ TEST_CASE( "Solar_power", "[vehicle][power]" ) SECTION( "Summer before sunrise" ) { calendar::turn = calendar::turn_zero + calendar::season_length() + 1_days; calendar::turn = sunrise( calendar::turn ) - 1_hours; - veh_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); REQUIRE( veh_ptr->fuel_left( here, fuel_type_battery ) == 0 ); WHEN( "30 minutes elapse" ) { - veh_ptr->update_time( calendar::turn + 30_minutes ); + veh_ptr->update_time( here, calendar::turn + 30_minutes ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); CHECK( power == 0 ); } @@ -173,11 +173,11 @@ TEST_CASE( "Solar_power", "[vehicle][power]" ) SECTION( "Winter noon" ) { calendar::turn = calendar::turn_zero + 3 * calendar::season_length() + 1_days + 12_hours; - veh_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); REQUIRE( veh_ptr->fuel_left( here, fuel_type_battery ) == 0 ); WHEN( "30 minutes elapse" ) { - veh_ptr->update_time( calendar::turn + 30_minutes ); + veh_ptr->update_time( here, calendar::turn + 30_minutes ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); CHECK( power == Approx( 184 ).margin( 1 ) ); } @@ -192,8 +192,8 @@ TEST_CASE( "Solar_power", "[vehicle][power]" ) REQUIRE( veh_2_ptr != nullptr ); calendar::turn = calendar::turn_zero + 1_days; - veh_ptr->update_time( calendar::turn ); - veh_2_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); + veh_2_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); veh_2_ptr->discharge_battery( here, 100000 ); @@ -201,9 +201,9 @@ TEST_CASE( "Solar_power", "[vehicle][power]" ) REQUIRE( veh_2_ptr->fuel_left( here, fuel_type_battery ) == 0 ); // Vehicle 1 does 2x 30 minutes while vehicle 2 does 1x 60 minutes - veh_ptr->update_time( calendar::turn + 30_minutes ); - veh_ptr->update_time( calendar::turn + 60_minutes ); - veh_2_ptr->update_time( calendar::turn + 60_minutes ); + veh_ptr->update_time( here, calendar::turn + 30_minutes ); + veh_ptr->update_time( here, calendar::turn + 60_minutes ); + veh_2_ptr->update_time( here, calendar::turn + 60_minutes ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); int power_2 = veh_2_ptr->fuel_left( here, fuel_type_battery ); @@ -226,11 +226,11 @@ TEST_CASE( "Daily_solar_power", "[vehicle][power]" ) SECTION( "Spring day 2" ) { calendar::turn = calendar::turn_zero + 1_days; - veh_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); REQUIRE( veh_ptr->fuel_left( here, fuel_type_battery ) == 0 ); WHEN( "24 hours pass" ) { - veh_ptr->update_time( calendar::turn + 24_hours ); + veh_ptr->update_time( here, calendar::turn + 24_hours ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); CHECK( power == Approx( 5259 ).margin( 1 ) ); } @@ -238,11 +238,11 @@ TEST_CASE( "Daily_solar_power", "[vehicle][power]" ) SECTION( "Summer day 1" ) { calendar::turn = calendar::turn_zero + calendar::season_length(); - veh_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); REQUIRE( veh_ptr->fuel_left( here, fuel_type_battery ) == 0 ); WHEN( "24 hours pass" ) { - veh_ptr->update_time( calendar::turn + 24_hours ); + veh_ptr->update_time( here, calendar::turn + 24_hours ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); CHECK( power == Approx( 7925 ).margin( 1 ) ); } @@ -250,11 +250,11 @@ TEST_CASE( "Daily_solar_power", "[vehicle][power]" ) SECTION( "Autum day 1" ) { calendar::turn = calendar::turn_zero + 2 * calendar::season_length(); - veh_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); REQUIRE( veh_ptr->fuel_left( here, fuel_type_battery ) == 0 ); WHEN( "24 hours pass" ) { - veh_ptr->update_time( calendar::turn + 24_hours ); + veh_ptr->update_time( here, calendar::turn + 24_hours ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); CHECK( power == Approx( 5138 ).margin( 1 ) ); } @@ -262,11 +262,11 @@ TEST_CASE( "Daily_solar_power", "[vehicle][power]" ) SECTION( "Winter day 1" ) { calendar::turn = calendar::turn_zero + 3 * calendar::season_length(); - veh_ptr->update_time( calendar::turn ); + veh_ptr->update_time( here, calendar::turn ); veh_ptr->discharge_battery( here, 100000 ); REQUIRE( veh_ptr->fuel_left( here, fuel_type_battery ) == 0 ); WHEN( "24 hours pass" ) { - veh_ptr->update_time( calendar::turn + 24_hours ); + veh_ptr->update_time( here, calendar::turn + 24_hours ); int power = veh_ptr->fuel_left( here, fuel_type_battery ); CHECK( power == Approx( 2137 ).margin( 1 ) ); } diff --git a/tests/vehicle_ramp_test.cpp b/tests/vehicle_ramp_test.cpp index d2b3577c78486..46f965ef2efa1 100644 --- a/tests/vehicle_ramp_test.cpp +++ b/tests/vehicle_ramp_test.cpp @@ -139,7 +139,7 @@ static void ramp_transition_angled( const vproto_id &veh_id, const units::angle for( const tripoint_abs_ms &checkpt : vpts ) { int partnum = 0; vehicle *check_veh = here.veh_at_internal( here.get_bub( checkpt ), partnum ); - CAPTURE( veh_ptr->pos_bub( &here ) ); + CAPTURE( veh_ptr->pos_bub( here ) ); CAPTURE( veh_ptr->face.dir() ); CAPTURE( checkpt ); CHECK( check_veh == veh_ptr ); diff --git a/tests/vehicle_test.cpp b/tests/vehicle_test.cpp index 8495f9e572c9f..ce7493795766f 100644 --- a/tests/vehicle_test.cpp +++ b/tests/vehicle_test.cpp @@ -337,7 +337,7 @@ static void check_folded_item_to_parts_damage_transfer( const folded_item_damage // don't actually need point_rel_ms::north but damage_all filters out direct damage // do some damage so it is transferred when folding - ovp->vehicle().damage_all( 100, 100, damage_pure, ovp->mount_pos() + point_rel_ms::north ); + ovp->vehicle().damage_all( m, 100, 100, damage_pure, ovp->mount_pos() + point_rel_ms::north ); // fold vehicle into an item complete_activity( u, vehicle_folding_activity_actor( ovp->vehicle() ) ); @@ -454,8 +454,8 @@ TEST_CASE( "power_cable_stretch_disconnect" ) const tripoint_bub_ms app1_pos( HALF_MAPSIZE_X + 2, HALF_MAPSIZE_Y + 2, 0 ); const tripoint_bub_ms app2_pos( app1_pos + tripoint( 2, 2, 0 ) ); - place_appliance( app1_pos, vpart_ap_test_standing_lamp, player_character, stand_lamp1 ); - place_appliance( app2_pos, vpart_ap_test_standing_lamp, player_character, stand_lamp2 ); + place_appliance( m, app1_pos, vpart_ap_test_standing_lamp, player_character, stand_lamp1 ); + place_appliance( m, app2_pos, vpart_ap_test_standing_lamp, player_character, stand_lamp2 ); optional_vpart_position app1_part = m.veh_at( app1_pos ); optional_vpart_position app2_part = m.veh_at( app2_pos ); @@ -598,7 +598,7 @@ static void rack_check( const rack_preset &preset ) } for( const point_rel_ms &rack_pos : preset.install_racks ) { - vehs[0]->install_part( rack_pos, vpart_bike_rack ); + vehs[0]->install_part( m, rack_pos, vpart_bike_rack ); } for( const rack_activation &rack_act : preset.rack_orders ) { @@ -758,7 +758,7 @@ static int test_autopilot_moving( const vproto_id &veh_id, const vpart_id &extra vehicle &veh = *veh_ptr; if( !extra_part.is_null() ) { vehicle_part vp( extra_part, item( extra_part->base_item ) ); - const int part_index = veh.install_part( point_rel_ms::zero, std::move( vp ) ); + const int part_index = veh.install_part( here, point_rel_ms::zero, std::move( vp ) ); REQUIRE( part_index >= 0 ); } @@ -770,15 +770,15 @@ static int test_autopilot_moving( const vproto_id &veh_id, const vpart_id &extra int turns_left = 10; int tiles_travelled = 0; - const tripoint_bub_ms starting_point = veh.pos_bub( &here ); + const tripoint_bub_ms starting_point = veh.pos_bub( here ); while( veh.engine_on && turns_left > 0 ) { turns_left--; here.vehmove(); veh.idle( here, true ); // How much it moved - tiles_travelled += square_dist( starting_point, veh.pos_bub( &here ) ); + tiles_travelled += square_dist( starting_point, veh.pos_bub( here ) ); // Bring it back to starting point to prevent it from leaving the map - const tripoint_rel_ms displacement = starting_point - veh.pos_bub( &here ); + const tripoint_rel_ms displacement = starting_point - veh.pos_bub( here ); here.displace_vehicle( veh, displacement ); } return tiles_travelled; diff --git a/tests/vehicle_turrets_test.cpp b/tests/vehicle_turrets_test.cpp index a38ad96e44484..37eccf90fe93e 100644 --- a/tests/vehicle_turrets_test.cpp +++ b/tests/vehicle_turrets_test.cpp @@ -55,7 +55,7 @@ TEST_CASE( "vehicle_turret", "[vehicle][gun][magazine]" ) false, true ); REQUIRE( veh ); - const int turr_idx = veh->install_part( point_rel_ms::zero, turret_vpi->id ); + const int turr_idx = veh->install_part( here, point_rel_ms::zero, turret_vpi->id ); REQUIRE( turr_idx >= 0 ); vehicle_part &vp = veh->part( turr_idx ); CHECK( vp.is_turret() ); @@ -100,7 +100,7 @@ TEST_CASE( "vehicle_turret", "[vehicle][gun][magazine]" ) REQUIRE( qry.query() == turret_data::status::ready ); REQUIRE( qry.range() > 0 ); - player_character.setpos( &here, veh->bub_part_pos( &here, vp ) ); + player_character.setpos( &here, veh->bub_part_pos( here, vp ) ); int shots_fired = 0; // 3 attempts to fire, to account for possible misfires for( int attempt = 0; shots_fired == 0 && attempt < 3; attempt++ ) { diff --git a/tests/vision_test.cpp b/tests/vision_test.cpp index 53e8142291c59..a43fedae51c51 100644 --- a/tests/vision_test.cpp +++ b/tests/vision_test.cpp @@ -935,7 +935,7 @@ TEST_CASE( "vision_vehicle_camera_skew", "[shadowcasting][vision][vehicle][vehic v->remove_part( *horns.front() ); } if( fiddle > 1 ) { - REQUIRE( v->install_part( point_rel_ms::zero, vpart_inboard_mirror ) != -1 ); + REQUIRE( v->install_part( here, point_rel_ms::zero, vpart_inboard_mirror ) != -1 ); } if( fiddle > 0 ) { here.add_vehicle_to_cache( v ); diff --git a/tests/visitable_remove_test.cpp b/tests/visitable_remove_test.cpp index 781799b27645f..e9eda9b9a52e8 100644 --- a/tests/visitable_remove_test.cpp +++ b/tests/visitable_remove_test.cpp @@ -445,7 +445,7 @@ TEST_CASE( "visitable_remove", "[visitable]" ) v->add_item( here, vp->part(), obj ); } - vehicle_selector sel( p.pos_bub(), 1 ); + vehicle_selector sel( here, p.pos_bub( &here ), 1 ); REQUIRE( count_items( sel, container_id ) == count ); REQUIRE( count_items( sel, liquid_id ) == count );