Well I think you're all crazy ;)
I guess I'll throw in my unlimited bits code.  I think it has some good
features.
New flags can be added easily; all you have to do is increment FINAL_AFF or
whatever and clean compile.
You can painlessly change the integer type used to store bits (char, short,
int..) by changing one typedef.  It will load and save areas the same, no
matter.
Yes it can read flags from stock area files.

I'm not going to give full installation instructions, since that would be
really long and I doubt anyone will actually use this.
I'm just posting it because it's pretty good code and maybe can give you
some ideas.
If you do use it and run into a problem, email me.

/* merc.h.  These will need to be near the top of the file */
typedef struct flag_type flag_type;
typedef unsigned long bit_field; //change this to use a diff integer type
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 )    ((unsigned)flag[bit/UL_BITS]>>bit%UL_BITS&1)
#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))
void bit_array_lookup(const flag_type *flag_table, bit_array var, char
*argument);
char *bit_array_string(const flag_type *flag_table, const bit_array bits);
char *bit_array_flags(const bit_array array, int maxelems);
void bit_array_copy(bit_array target, const bit_array source, int final);
void bit_array_init(bit_array s, int final);
void fread_bit_array(FILE *fp, bit_array array);

/* replace old IS_AFFECTED */
#define IS_AFFECTED(ch, sn)     (IS_FLAG(ch->affected_by, sn))

/* in char_data and mob_index_data, wherever else you need more bits */
/* FINAL_AFF should be set equal to the highest affect you have */
    bit_field           affected_by[SIZEFROMFINAL(FINAL_AFF)];


/* in some .c file */
const char *bit_flags = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg";

/* sets all bits to 0 */
/* used in recycle.c and mem.c */
void bit_array_init(bit_array s, int final)
{
  int i, length;
  length = SIZEFROMFINAL(final);
  for ( i = 0; i < length; s[i++] = 0 );
}

/* copies one bit array to another */
/* used mainly to copy mob index affects when creating mobs */
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];
}

/* read in a bit array from a file */
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);
  }
}

/* returns the ABCxABCx style string for writing to a file */
char *bit_array_flags(const bit_array array, int maxelems)
{
  int count, pos = 0;
  static char buf[MSL];

  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 always has to be SOMETHING there
  buf[pos++] = '\0';
  return buf;
}

/* reads a string like "sanctuary haste blind" and toggles those bits in the
array */
/* used for OLC and "flag" command */
void bit_array_lookup(const flag_type *flag_table, bit_array var, char
*argument)
{
  char arg[MAX_INPUT_LENGTH];
  int vector;
  for (;;)
  {
    argument = one_argument(argument, arg);
    if (arg[0] == '\0' || ((vector = flag_lookup(arg, flag_table)) < 0))
      break;
    if (vector > -1)
      TOGGLE_FLAG(var, vector);
  }
}

/* returns a string like "sanctuary blind haste" from the bits set in the
array */
/* used in "stat" command and OLC */
char *bit_array_string(const flag_type *flag_table, const bit_array bits)
{
  static char buf[MAX_STRING_LENGTH];
  int flag;
  bool first = TRUE;

  buf[0] = '\0';

  for (flag = 0; flag_table[flag].name != NULL; flag++)
  {
    if (IS_FLAG(bits, flag_table[flag].bit))
    {
      if (!first)
        strcat(buf, " " );
      first = FALSE;
      strcat(buf, flag_table[flag].name);
    }
  }
  return (buf[0] ? buf : "none");
}

--Palrich


Reply via email to