diff --git a/src/item.cpp b/src/item.cpp index a3f62c8b1d402..06ecf2b6746ad 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -13244,8 +13244,11 @@ ret_val item::link_to( vehicle &veh, const point &mount, link_state link_t return ret_val::make_failure( _( "That vehicle already has a tow-line attached." ) ); } else if( !veh.is_external_part( veh.mount_to_tripoint( mount ) ) ) { return ret_val::make_failure( _( "You can't attach a tow-line to an internal part." ) ); - } else if( !veh.part( veh.part_at( mount ) ).carried_stack.empty() ) { - return ret_val::make_failure( _( "You can't attach a tow-line to a racked part." ) ); + } else { + const int part_at = veh.part_at( mount ); + if( part_at != -1 && !veh.part( part_at ).carried_stack.empty() ) { + return ret_val::make_failure( _( "You can't attach a tow-line to a racked part." ) ); + } } } else { const link_up_actor *it_actor = static_cast diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 77ad04666b890..aa76e26efead1 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -6741,17 +6741,25 @@ void vehicle::invalidate_towing( bool first_vehicle, Character *remover ) } const int tow_cable_idx = get_tow_part(); if( first_vehicle ) { - vehicle *other_veh = is_towing() ? tow_data.get_towed() : + const bool first_veh_is_towing = is_towing(); + vehicle *other_veh = first_veh_is_towing ? tow_data.get_towed() : is_towed() ? tow_data.get_towed_by() : nullptr; + const int other_tow_cable_idx = other_veh ? other_veh->get_tow_part() : -1; + const point other_tow_cable_mount = other_veh && other_tow_cable_idx > -1 ? + other_veh->part( other_tow_cable_idx ).mount : point(); + if( other_veh ) { + other_veh->invalidate_towing(); + } if( tow_cable_idx > -1 ) { vehicle_part &vp = parts[tow_cable_idx]; item drop = part_to_item( vp ); drop.set_damage( 0 ); - const int other_tow_cable_idx = other_veh ? other_veh->get_tow_part() : -1; + tripoint drop_pos = global_part_pos3( vp ); + remove_part( vp ); if( other_tow_cable_idx > -1 ) { drop.reset_link( false ); - drop.link_to( *other_veh, other_veh->part( other_tow_cable_idx ).mount ); - if( is_towing() ) { + drop.link_to( *other_veh, other_tow_cable_mount, link_state::vehicle_tow ); + if( first_veh_is_towing ) { drop.link().source = link_state::no_link; drop.link().target = link_state::vehicle_tow; } else { @@ -6770,12 +6778,8 @@ void vehicle::invalidate_towing( bool first_vehicle, Character *remover ) put_into_vehicle_or_drop( *remover, item_drop_reason::deliberate, drops ); } } else { - get_map().add_item_or_charges( global_part_pos3( vp ), drop ); + get_map().add_item_or_charges( drop_pos, drop ); } - remove_part( vp ); - } - if( other_veh ) { - other_veh->invalidate_towing(); } tow_data.clear_towing(); } else {