Oh, and it does require the bitmask C version be installed.
Here's an example of how it was used inside of do_get
if ( arg2[0] == '\0' ) {
// olist is an OBJ_DATA**, or an array. It must be freed and it's NULL terminated.
olist = nget_obj_list(ch, arg1, type ? ch->in_room->contents);
if ( olist[0] == NULL ) {
act( "I see no $T here.", ch, NULL, arg1, TO_CHAR );
free(olist);
return;
}
// For each item in olist, grab it. it means it met our search critera from nget_obj_list().
for(i = 0;olist[i];++i) {
if (olist[i]->item_type == ITEM_CONTAINER || olist[i]->item_type == ITEM_CORPSE_NPC)
continue;
get_obj( ch, olist[i], NULL );
}
free(olist);
}
// below this point all goes into act_obj.c or similar
typedef struct obj_find {
int number; // number in the list to act on.
int multiple; // How many times? Negative 1 is all.
BITMASK flags; // Flags to look for.
char *arg; // string to parse!
int valid; // Is it valid?
} OBJ_FIND_DATA;
OBJ_FIND_DATA *recursive_obj_flag_search(OBJ_FIND_DATA *ofd) {
char buf[MSL];
char *arg, *ptr= buf;
for(arg = ofd->arg;;++arg) {
if (!arg || *arg == 0 || *arg == ' ') {
*ptr = 0;
return ofd;
}
if (*arg == '.') {
*ptr = 0;
break;
}
*ptr = *arg;
++ptr;
}
if (is_number(buf)) {
ofd->number = atoi(buf);
if (ofd->number < 1 || ofd->number > 100)
ofd->valid = FALSE;
}
else if (!strcmp(buf, "hum"))
set_bit(&ofd->flags, ITEM_HUM);
else if (!strcmp(buf, "all"))
ofd->multiple = 100;
else if (!strcmp(buf, "empty"))
set_bit(&ofd->flags, 1000); // Looking for empty object
else if (buf[0] == 'X' || buf[0] == 'x' || buf[0] == '*') {
if (!is_number(buf+1))
ofd->valid = FALSE;
ofd->multiple = atoi(buf+1);
if (ofd->multiple < 1 || ofd->multiple > 100)
ofd->valid = FALSE;
}
ofd->arg = arg+1;
return recursive_obj_flag_search(ofd);
}
OBJ_DATA **nget_obj_list(CHAR_DATA *ch, char *arg, OBJ_DATA *from_list) {
OBJ_FIND_DATA ofd;
static BITMASK bmclear;
OBJ_DATA **oarray;
int which = 0;
int num_pass;
int count = 0;
oarray = (OBJ_DATA **) malloc(sizeof(OBJ_DATA *) * 101);
BITMASK found = bmclear;
OBJ_DATA *pObj;
ofd.valid = TRUE;
ofd.number = 1;
ofd.multiple = 1;
ofd.flags = bmclear;
ofd.arg = arg;
if (!recursive_obj_flag_search(&ofd)->valid) {
free_bitmask(&ofd.flags);
oarray[0] = 0;
return oarray;
}
while(which < ofd.multiple || (!strcmp(ofd.arg, "all") && which < 100)) {
num_pass = 0;
for(pObj = from_list;pObj;pObj = pObj->next_content) {
if (pObj->wear_loc != WEAR_NONE)
continue;
if (strcmp(ofd.arg, "all") && !is_name (ofd.arg, pObj->name))
continue;
if (!can_see_obj(ch, pObj))
continue;
if (is_set(&ofd.flags, ITEM_HUM))
if (!IS_SET(pObj->extra_flags, ITEM_HUM))
continue;
if (is_set(&ofd.flags, 1000)) // For empty things only
if (pObj->item_type != ITEM_ARROW || pObj->value[3] != 0)
continue;
if (is_set(&found, (int)pObj))
continue;
++num_pass;
if (num_pass == ofd.number)
break;
}
oarray[which] = pObj;
if (pObj == NULL)
break;
set_bit(&found, (int)pObj);
++which;
}
oarray[which] = NULL;
free_bitmask(&found);
free_bitmask(&ofd.flags);
return oarray;
}