void put_into_vehicle_or_drop( player &p, const std::list<item> &items, const tripoint &where ) { if( const cata::optional<vpart_reference> vp = g->m.veh_at( where ).part_with_feature( "CARGO" ) ) { put_into_vehicle( p, items, vp->vehicle(), vp->part_index() ); return; } drop_on_map( p, items, where ); }
void put_into_vehicle_or_drop( Character &c, item_drop_reason reason, const std::list<item> &items, const tripoint &where, bool force_ground ) { const cata::optional<vpart_reference> vp = g->m.veh_at( where ).part_with_feature( "CARGO", false ); if( vp && !force_ground ) { put_into_vehicle( c, reason, items, vp->vehicle(), vp->part_index() ); return; } drop_on_map( c, reason, items, where ); }
void put_into_vehicle_or_drop( player &p, const std::list<item> &items, const tripoint &where ) { int veh_part = 0; vehicle *veh = g->m.veh_at( where, veh_part ); if( veh != nullptr ) { veh_part = veh->part_with_feature( veh_part, "CARGO" ); if( veh_part >= 0 ) { put_into_vehicle( p, items, *veh, veh_part ); return; } } drop_on_map( items, where ); }
// I'd love to have this not duplicate so much code from Pickup::pick_one_up(), // but I don't see a clean way to do that. static void move_items( player &p, const tripoint &src, bool from_vehicle, const tripoint &dest, bool to_vehicle, std::list<int> &indices, std::list<int> &quantities ) { tripoint source = src + p.pos(); tripoint destination = dest + p.pos(); int s_cargo = -1; vehicle *s_veh = nullptr; // load vehicle information if requested if( from_vehicle ) { const cata::optional<vpart_reference> vp = g->m.veh_at( source ).part_with_feature( "CARGO", false ); assert( vp ); s_veh = &vp->vehicle(); s_cargo = vp->part_index(); assert( s_cargo >= 0 ); } while( p.moves > 0 && !indices.empty() ) { int index = indices.back(); int quantity = quantities.back(); indices.pop_back(); quantities.pop_back(); item *temp_item = from_vehicle ? g->m.item_from( s_veh, s_cargo, index ) : g->m.item_from( source, index ); if( temp_item == nullptr ) { continue; // No such item. } item leftovers = *temp_item; if( quantity != 0 && temp_item->count_by_charges() ) { // Reinserting leftovers happens after item removal to avoid stacking issues. leftovers.charges = temp_item->charges - quantity; if( leftovers.charges > 0 ) { temp_item->charges = quantity; } } else { leftovers.charges = 0; } // Check that we can pick it up. if( !temp_item->made_of_from_type( LIQUID ) ) { // This is for hauling across zlevels, remove when going up and down stairs // is no longer teleportation int distance = src.z == dest.z ? std::max( rl_dist( src, dest ), 1 ) : 1; p.mod_moves( -Pickup::cost_to_move_item( p, *temp_item ) * distance ); if( to_vehicle ) { put_into_vehicle_or_drop( p, item_drop_reason::deliberate, { *temp_item }, destination ); } else { drop_on_map( p, item_drop_reason::deliberate, { *temp_item }, destination ); } // Remove from map or vehicle. if( from_vehicle ) { s_veh->remove_item( s_cargo, index ); } else { g->m.i_rem( source, index ); } } // If we didn't pick up a whole stack, put the remainder back where it came from. if( leftovers.charges > 0 ) { bool to_map = !from_vehicle; if( !to_map ) { to_map = !s_veh->add_item( s_cargo, leftovers ); } if( to_map ) { g->m.add_item_or_charges( source, leftovers ); } } } }
// I'd love to have this not duplicate so much code from Pickup::pick_one_up(), // but I don't see a clean way to do that. static void move_items( const tripoint &src, bool from_vehicle, const tripoint &dest, bool to_vehicle, std::list<int> &indices, std::list<int> &quantities ) { tripoint source = src + g->u.pos(); tripoint destination = dest + g->u.pos(); int s_cargo, d_cargo; // oui oui, mon frere s_cargo = d_cargo = -1; vehicle *s_veh, *d_veh; // 2diva4me s_veh = d_veh = nullptr; // load vehicle information if requested if( from_vehicle ) { const cata::optional<vpart_reference> vp = g->m.veh_at( source ).part_with_feature( "CARGO", false ); assert( vp ); s_veh = &vp->vehicle(); s_cargo = vp->part_index(); assert( s_cargo >= 0 ); } if( to_vehicle ) { const cata::optional<vpart_reference> vp = g->m.veh_at( destination ).part_with_feature( "CARGO", false ); assert( vp ); d_veh = &vp->vehicle(); d_cargo = vp->part_index(); assert( d_cargo >= 0 ); } while( g->u.moves > 0 && !indices.empty() ) { int index = indices.back(); int quantity = quantities.back(); indices.pop_back(); quantities.pop_back(); item *temp_item = from_vehicle ? g->m.item_from( s_veh, s_cargo, index ) : g->m.item_from( source, index ); if( temp_item == nullptr ) { continue; // No such item. } item leftovers = *temp_item; if( quantity != 0 && temp_item->count_by_charges() ) { // Reinserting leftovers happens after item removal to avoid stacking issues. leftovers.charges = temp_item->charges - quantity; if( leftovers.charges > 0 ) { temp_item->charges = quantity; } } else { leftovers.charges = 0; } // Check that we can pick it up. if( !temp_item->made_of( LIQUID ) ) { g->u.mod_moves( -Pickup::cost_to_move_item( g->u, *temp_item ) ); if( to_vehicle ) { put_into_vehicle_or_drop( g->u, { *temp_item }, destination ); } else { drop_on_map( g->u, { *temp_item }, destination ); } // Remove from map or vehicle. if( from_vehicle ) { s_veh->remove_item( s_cargo, index ); } else { g->m.i_rem( source, index ); } } // If we didn't pick up a whole stack, put the remainder back where it came from. if( leftovers.charges > 0 ) { bool to_map = !from_vehicle; if( !to_map ) { to_map = !s_veh->add_item( s_cargo, leftovers ); } if( to_map ) { g->m.add_item_or_charges( source, leftovers ); } } } }