skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
#include <obj_parser.h>
#include <move_failures.h>

// These were determined empirically (with my hand :) -- Jeremy
#define DROP_H 40
#define PINCH_H 120

#define MAX_GET_NUMBER 20

inherit COMMAND_BASE;

mixed cmd( object *obs, string dir, string indir, mixed *args ) {
    object *dest;
    object ob;
    object dob;
    object *fail_dest;
    object *too_many;
    mixed *fail;
    mixed *ret;
    mixed *stuff;
    mixed amt;
    string sh;
    string hand_unit;
    string match_str;
    int i;
    int num;
    int cap;
    int perc;
    int handful;
    int total_num;
    mixed we;
    object env;
    object *bing;
    class obj_match result;

    if( indir && sizeof(obs) > 10 ) {
        add_failed_mess("Please be more specific as to what you want "
            "to get from.\n");
        return 0;
    }

    if( indir ) {
        match_str = args[0];
        dest = obs;
    } else {
        dest = ( ENV(TP)->query_mirror_room() ?
              ({ ENV(TP), ENV(TP)->query_mirror_room() }) : ({ ENV(TP) }) );
    }

    cap = (int)TP->query_max_weight();
    fail_dest = ({ });
    too_many = ({ });

    foreach( dob in dest ) {
        if( !is_in_me_or_environment( dob, TP ) )
            continue;

        if( dob->cannot_get_stuff() || dob->query_closed() || living(dob) ) {
            fail_dest += ({ dob });
            continue;
        }

        // Containers only.
        if( indir ) {
            result = match_objects_in_environments( match_str, dob );
            if( result->result != OBJ_PARSER_SUCCESS ) {
                add_failed_mess( match_objects_failed_mess( result ) );
                continue;
            }
            obs = result->objects;
        }

        // Containers only.
        if( living(dob) && !dob->allowed_to_loot(TP) ) {
            // Do basically the same check here as is done in the
            // match_objects_for_existence code.
            obs = filter( obs, (:
                  $(dob)->can_find_match_reference_inside_object( $1, TP ) :) );
            obs = filter( obs, (: member_array( $1,
                  $(dob)->query_holding() ) == -1 :) );
            if( !sizeof(obs) ) {
                fail_dest += ({ dob });
                continue;
            }
        }
        if( total_num + sizeof(obs) > MAX_GET_NUMBER ) {
            if( total_num > MAX_GET_NUMBER ) {
                too_many += obs;
                obs = ({ });
            } else {
                too_many += obs[MAX_GET_NUMBER - total_num..];
                obs = obs[0..MAX_GET_NUMBER - total_num - 1];
            }
        }

        total_num += sizeof(obs);

        ret = ({ ([ ]), ([ ]), ([ ]), ([ ]), ([ ]), });
        fail = ({ });

        foreach( ob in obs ) {
            if( ( living(dob) && !dob->allowed_to_loot( TP, ob ) ) ||
                ( ob->query_liquid() && ob->query_food_object() ) ||
                ( ENV(ob) && living( ENV(ob) ) ) ) {
                fail += ({ ob });
                num++;
                continue;
            }

            if( ob->query_continuous() ) {
                amt = ob->query_amount_types();

                if( amt["handful"] ) {
                    hand_unit = "handful";
                    handful = amt["handful"][0];
                } else if( amt["drop"] && ob->query_liquid() ) {
                    hand_unit = "drops";
                    handful = amt["drop"][0] * DROP_H;
                } else if( amt["pinch"] ) {
                    hand_unit = "pinches";
                    handful = amt["pinch"][0] * PINCH_H;
                } else { // Dunno what to do here - I guess give it to them.
                    handful = ob->query_amount();
                }

                if( ob->query_amount() > handful ) {
                    // Knock it down to a carryable amount.
                    // (I hope this is right...)
                    if( !match_str )
                        match_str = ob->query_name();
                    if( i = strsrch( match_str, "of" ) >= 0 )
                        i += 3;
                    if( hand_unit == "handful" )
                        handful = 1;

                    match_str = handful+" "+hand_unit+" of "+match_str[i..];

                    if( !ob = ob->query_parse_id(({ handful, match_str })) )
                        continue;
                }
            }

            env = ENV(ob);

            if( function_exists("do_get", ob ) ||
                function_exists("command_control", ob ) ) {
                if( function_exists("do_get", ob ) ) {
                    we = (int)call_other( ob, "do_get", dob, 0, match_str,
                         ({ 0, match_str }),
                         "<direct:object> from <indirect:object>");
                } else {
                    we = ob->command_control("get", dob, 0, match_str,
                         ({ 0, match_str }),
                         "<direct:object> from <indirect:object>");
                }

                if( !objectp(we) ) {
                    if( we ) {
                        we = (int)ob->query_weight();
                        perc = ( we * 100 ) / cap;
                        i = ( perc >= 95 ? 4 : perc / 25 );
                        if( !ret[i][env] )
                            ret[i][env] = ({ ob });
                        else
                            ret[i][env] += ({ ob });
                    } else {
                        if( member_array( ob,
                            TP->query_succ_mess_indir() ) == -1 &&
                            !query_notify_fail() && !living(ob) ) {
                            fail += ({ ob });
                        }
                        num++;
                    }
                    continue;
                } else {
                    ob = we;
                }
            }
            if( (int)ob->move(TP) == MOVE_OK ) {
                we = (int)ob->query_weight();
                perc = ( we * 100 ) / cap;
                i = ( perc >= 95 ? 4 : perc / 25 );

                if( !ret[i][env] )
                    ret[i][env] = ({ ob });
                else
                    ret[i][env] += ({ ob });

                if( interactive(TP) && ob->query_property("dropped") ) {
                    stuff = ob->query_property("dropped");

                    if( TP->query_name() != stuff[0] &&
                        query_ip_number(TP) == stuff[1] &&
                        sizeof( (HANDLER_DIR+"/multiplayer")->
                        check_allowed( TP, ({ stuff[0] }) ) ) ) {
                        sh = TP->query_cap_name()+" got "+
                        ob->query_short()+" from "+stuff[0]+" who "
                        "logged in from the same IP address.";
                        user_event("inform", sh, "multiplayer");
                        log_file("MULTIPLAYERS", ctime(time())+": "+
                             TP->convert_message(sh)+"\n");
                    } else if( TP->query_name() == stuff[0] &&
                        TP->query_refresh_time() > stuff[2] ) {
                        sh = TP->query_cap_name()+" picked up "+
                             TP->HIS+" equipment after a refresh.";
                        user_event("inform", sh, "multiplayer");
                        log_file("MULTIPLAYERS", ctime(time())+": "+
                             TP->convert_message(sh));
                    }
                }
            } else {
                fail += ({ ob });
                num++;
            }
        }

        /* Print out the different weight messages */
        for( i = 0; i < sizeof(ret); i++ ) {
            if( sizeof(ret[i]) ) {
                /* Print out the different environments for the weights. */
                foreach( env, bing in ret[i] ) {
                    if( TP->query_succ_mess_dir() )
                        bing -= TP->query_succ_mess_dir();

                    if( sizeof(bing) ) {
                        sh = query_multiple_short(bing);
                        write("You "+({"get", "get with a bit of difficulty",
                            "struggle somewhat to get", "find it very "
                            "difficult to get", "use all your strength and "
                            "just barely manage to get"})[i]+" "+sh+" from "+
                            inside_the_short(env)+".\n" );
                        say( (string)TP->one_short()+" "+({ "gets", "gets "
                            "with a bit of difficulty", "struggles somewhat "
                            "to get", "finds it very difficult to get",
                            "uses all "+TP->HIS+" strength and just barely "
                            "manages to get" })[i]+" "+sh+" from "+
                            inside_a_short(env)+".\n");
                    }
                }
            }
        }
        if( sizeof(fail) )
            add_failed_mess("You cannot get $I.\n", fail );
    }

    // This means everything failed.
    if( num == total_num ) {
        if( query_notify_fail() )
            return 0;

        if( indir ) {
            if( !num )
                add_failed_mess("There is no "+match_str+" in $I.\n", dest );
            if( sizeof(fail_dest) )
                add_failed_mess("You cannot get anything from $I.\n", fail_dest );
        }

        return -1;

    } else {
        // Success!
        if( sizeof(too_many) ) {
            add_succeeded_mess( ({ "You cannot pick up more than "+
                query_num(MAX_GET_NUMBER)+" objects at a time; "
                "discarding $I.\n", "" }), too_many );
        }
    }

    return 1;

} /* cmd() */

/** @ignore yes */
mixed query_patterns() {
    return ({
        "<indirect:object:here>", (: cmd( $1, 0, 0, 0 ) :),
        "<string> from <indirect:object>", (: cmd($1, $2, $3, $4) :),
    });
} /* query_patterns() */