static void stash_on_pet( std::vector<item> &dropped_items, std::vector<item> &dropped_worn_items,
                          point drop_target )
{
    Creature *critter = g->critter_at( drop_target.x, drop_target.y);
    if( critter == NULL ) {
        return;
    }
    monster *pet = dynamic_cast<monster *>(critter);
    if( pet == NULL || !pet->has_effect("pet") ) {
        return;
    }

    for( auto &item_to_stash : dropped_items ) {
        stash_on_pet( &item_to_stash, pet );
    }
    for( auto &item_to_stash : dropped_worn_items ) {
        stash_on_pet( &item_to_stash, pet );
    }
}
void activity_handlers::stash_do_turn( player_activity *act, player *p )
{
    const tripoint pos = act->placement + p->pos();

    monster *pet = g->critter_at<monster>( pos );
    if( pet != nullptr && pet->has_effect( effect_pet ) ) {
        stash_on_pet( obtain_activity_items( *act, *p ), *pet );
    } else {
        p->add_msg_if_player( _( "The pet has moved somewhere else." ) );
        p->cancel_activity();
    }
}
static void place_item_activity( std::list<item *> &selected_items, std::list<int> &item_quantities,
                                 std::list<item *> &selected_worn_items,
                                 std::list<int> &worn_item_quantities,
                                 enum item_place_type type, point drop_target )
{
    std::vector<item> dropped_items;
    std::vector<item> dropped_worn_items;
    int prev_volume = g->u.volume_capacity();
    bool taken_off = false;
    // Make the relative coordinates absolute.
    drop_target.x += g->u.xpos();
    drop_target.y += g->u.ypos();
    if( type == DROP_WORN || type == STASH_WORN ) {
        // TODO: Add the logic where dropping a worn container drops a number of contents as well.
        // Stash previous volume and compare it to volume after taking off each article of clothing.
        taken_off = g->u.takeoff( selected_worn_items.front(), false, &dropped_worn_items );
        // Whether it succeeds or fails, we're done processing it.
        selected_worn_items.pop_front();
        worn_item_quantities.pop_front();
        if( taken_off ) {
            // Move cost for taking off worn item.
            g->u.moves -= 250;
        } else {
            // If we failed to take off the item, bail out.
            return;
        }
    } else { // Unworn items.
        if( selected_items.front()->count_by_charges() ) {
            dropped_items.push_back(
                g->u.reduce_charges( selected_items.front(), item_quantities.front() ) );
            selected_items.pop_front();
            item_quantities.pop_front();
        } else {
            dropped_items.push_back( g->u.i_rem( selected_items.front() ) );
            // Process one item at a time.
            if( --item_quantities.front() <= 0 ) {
                selected_items.pop_front();
                item_quantities.pop_front();
            }
        }
    }

    if( type == DROP_WORN || type == DROP_NOT_WORN ) {
        // Drop handles move cost.
        g->drop( dropped_items, dropped_worn_items, g->u.volume_capacity() - prev_volume,
                 drop_target.x, drop_target.y );
    } else { // Stashing on a pet.
        stash_on_pet( dropped_items, dropped_worn_items, drop_target );
    }
}