> Does anyone have a good set of instructions or at least a good way of > describing how to switch to an unlimited bits system?? *cough* Richard > *cough*
If it helps, I can dump a bunch of code in your lap!! I wanted my unlimited bits to be a little easier to maintain and to be usable for other flags besides affects. Now when I add an affect, I just have to increment FINAL_AFF and clean compile. The array is defined like this: bit_field affected_by[SIZEFROMFINAL(FINAL_AFF)]; That sizefromfinal macro works out how big the array needs to be to fit FINAL_AFF bits in. Most of the functions also take a "final" bit, so it knows how far into the array to go when it's, say, saving them to file. That way they're reusable for other bit array thingies that have different size requirements. So the functions are called something like this: fprintf(fp, "AfBy %s\n", bit_array_flags(ch->affected_by, FINAL_AFF)); Oh, and see also I wanted it to be able to read in files that haven't been updated yet painlessly, so it's forwards compatible or backwards compatible or whichever one works that way. It separates groups of 32 bits with an 'x', so the old flags are just read in as being the first 32 bits of the array. I think I got that idea from the original unlimited bits code that Ammaross posted like 80 years ago, not the later version that he snippetized. There's some list_type stuff in there, that's basically just flag_type. Hopefully I've made some sense, I'm not very awake today. --Palrich. And here's the pile of code I threatened you with: typedef unsigned char bit_field; typedef bit_field *bit_array; #define UL_BITS (sizeof(bit_field)*8) #define SIZEFROMFINAL(a) \ (((a)/UL_BITS)+!!((a)%UL_BITS)) #define IS_FLAG(flag, bit) \ (flag[(bit)/UL_BITS] & (1 << ((bit)%UL_BITS))) #define TOGGLE_FLAG(flag, bit) \ (flag[bit/UL_BITS] ^= (1 << (bit%UL_BITS))) #define SET_FLAG(flag, bit) \ (flag[bit/UL_BITS] |= (1 << (bit%UL_BITS))) #define REMOVE_FLAG(flag, bit) \ (flag[bit/UL_BITS] &= ~(1 << (bit%UL_BITS))) #define IS_AFFECTED(ch, sn) \ (IS_FLAG(ch->affected_by, sn)) const char *bit_flags = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg"; void bit_array_init(bit_array s, int final) { int i, length; length = SIZEFROMFINAL(final); for ( i = 0; i < length; s[i++] = 0 ); } void bit_array_copy(bit_array target, const bit_array source, int final) { int i, length; length = SIZEFROMFINAL(final); for (i = 0; i < length; i++) target[i] = source[i]; } void fread_bit_array(FILE *fp, bit_array array) { int flag_base = 0, current_flag; char c; do {c = getc(fp);} while (isspace(c)); while (!isspace(c)) { if (c == 'x') flag_base += 32; else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { current_flag = (strchr(bit_flags, c)-bit_flags)+flag_base; SET_FLAG(array, current_flag); } c = getc(fp); } } char *bit_array_flags(const bit_array array, int maxelems) { int count, pos = 0; static char buf[128]; for (count = 0; count < maxelems; count++) { if (count && !(count%32)) buf[pos++] = 'x'; if (IS_FLAG(array, count)) buf[pos++] = bit_flags[count%32]; } buf[pos++] = 'x'; // there has to be SOMETHING there buf[pos++] = '\0'; return buf; } void bit_array_lookup(const struct list_type *list_table, bit_array var, char *argument) { char arg[MAX_INPUT_LENGTH]; int vector; for (;;) { argument = one_argument(argument, arg); if (arg[0] == '\0' || ((vector = list_value(arg, list_table)) < 0)) break; if (vector > -1) SET_FLAG(var, vector); } } char *bit_array_string(const struct list_type *list_table, const bit_array bits) { static char buf[MAX_STRING_LENGTH]; int flag; bool first = TRUE; buf[0] = '\0'; for (flag = 0; list_table[flag].name != NULL; flag++) { if (IS_FLAG(bits, list_table[flag].value)) { if (!first) strcat(buf, " "); first = FALSE; strcat(buf, list_table[flag].name); } } return (IS_NULLSTR(buf) ? "none" : buf); }