bool repair_part( vehicle &veh, vehicle_part &pt, Character &who_c ) { // @todo: Get rid of this cast after moving relevant functions down to Character player &who = ( player & )who_c; int part_index = veh.index_of_part( &pt ); auto &vp = pt.info(); // @todo: Expose base part damage somewhere, don't recalculate it here const auto reqs = pt.is_broken() ? vp.install_requirements() : vp.repair_requirements() * pt.damage_level( 4 ); inventory map_inv; map_inv.form_from_map( who.pos(), PICKUP_RANGE ); if( !reqs.can_make_with_inventory( who.crafting_inventory() ) ) { who.add_msg_if_player( m_info, _( "You don't meet the requirements to repair the %s." ), pt.name().c_str() ); return false; } // consume items extracting any base item (which we will need if replacing broken part) item base( vp.item ); for( const auto &e : reqs.get_components() ) { for( auto &obj : who.consume_items( who.select_item_component( e, 1, map_inv ), 1 ) ) { if( obj.typeId() == vp.item ) { base = obj; } } } for( const auto &e : reqs.get_tools() ) { who.consume_tools( who.select_tool_component( e, 1, map_inv ), 1 ); } who.invalidate_crafting_inventory(); for( const auto &sk : pt.is_broken() ? vp.install_skills : vp.repair_skills ) { who.practice( sk.first, calc_xp_gain( vp, sk.first ) ); } // If part is broken, it will be destroyed and references invalidated std::string partname = pt.name(); if( pt.is_broken() ) { const int dir = pt.direction; point loc = pt.mount; auto replacement_id = pt.info().get_id(); g->m.spawn_items( who.pos(), pt.pieces_for_broken_part() ); veh.remove_part( part_index ); const int partnum = veh.install_part( loc, replacement_id, std::move( base ) ); veh.parts[partnum].direction = dir; veh.part_removal_cleanup(); } else { veh.set_hp( pt, pt.info().durability ); } // @todo: NPC doing that who.add_msg_if_player( m_good, _( "You repair the %1$s's %2$s." ), veh.name.c_str(), partname.c_str() ); return true; }
turret_data vehicle::turret_query( vehicle_part &pt ) { if( !pt.is_turret() || pt.removed || pt.is_broken() ) { return turret_data(); } return turret_data( this, &pt ); }
bool vehicle::can_enable( const vehicle_part &pt, bool alert ) const { if( std::none_of( parts.begin(), parts.end(), [&pt]( const vehicle_part & e ) { return &e == &pt; } ) || pt.removed ) { debugmsg( "Cannot enable removed or non-existent part" ); } if( pt.is_broken() ) { return false; } if( pt.info().has_flag( "PLANTER" ) && !warm_enough_to_plant() ) { if( alert ) { add_msg( m_bad, _( "It is too cold to plant anything now." ) ); } return false; } // @todo: check fuel for combustion engines if( pt.info().epower < 0 && fuel_left( fuel_type_battery, true ) <= 0 ) { if( alert ) { add_msg( m_bad, _( "Insufficient power to enable %s" ), pt.name() ); } return false; } return true; }