Re: Bitvectors

From: Henrik Stuart (
Date: 01/05/02

Greetings all,

On Friday, January 04, 2002 5:56:47 AM you wrote:
> Hello all, I'm at the end of my rope, totally baffled, and dumbfounded as to
> why this <insert curse word here> won't work correctly. Well As the subject
> say's I have been fooling with bitvectors. I have created new AFF2_ AFF3_
> AFF4_ flags cause I ran out of AFF_ flags pretty fast when I added about
> 200+ new spells. Now I went into struct.h and added:

<- snipped ->

   Warning: mailer code contained herein. Might explode without notice
   if you like to complain about lines not being wrapped at exactly 79
   characters. :o)

   I know a lot of people already have responded to this,
   but still think there is a nicer solution to it - ok, it might not
   look as pretty with the #define's, but it works wonderfully (at
   least that's what I've been able to see from 5 minutes of testing,

   Instead of all the #define AFF_BLEH (1 << 3) etc., define affects
   as #define AFF_BLEH 3, basically like you define skills/spells. Add
   a #define at the bottom #define NUM_AFFECTS 200 (or however many
   you have). Then just above the struct with affected_by add this:

   #define NUM_AFFECT_VECTORS     (NUM_AFFECTS % (sizeof(long) * 8))

   This is how many bitvectors you need to have in your array. Then in
   the struct change: long affected_by; to long

   Now, the only disadvantage at the current point of time is that the
   AFF_FLAGGED macro will give some spiffy errors, so let's redefine
   that one. :o)

   #define AFF_FLAGGED(ch,flag) (((ch)->char_specials.saved.affected_by[((flag) / NUM_AFFECTS)]) & (1 << ((flag) % NUM_AFFECTS)))

   Now, this really requires that you understand modulo operations and
   what they do - please someone correct me if this define isn't right
   as it's kinda crucial for everything. :o)

   Now, since we are using an array we cannot set affects in the same
   way so we need a few macros to handle: setting an affect, toggling
   it and removing it, here goes:

   #define SET_AFFECT(ch,flag) (((ch)->char_specials.saved.affected_by[((flag) / NUM_AFFECTS)]) = (1 << ((flag) % NUM_AFFECTS)))
   #define TOGGLE_AFFECT(ch,flag) (((ch)->char_specials.saved.affected_by[((flag) / NUM_AFFECTS)]) ^= (1 << ((flag) % NUM_AFFECTS)))
   #define REMOVE_AFFECT(ch,flag) (((ch)->char_specials.saved.affected_by[((flag) / NUM_AFFECTS)]) &= ~(1 << ((flag) % NUM_AFFECTS)))

   Now, the chore is modifying ALL the places in your code that uses
   the old AFF_FLAGS macro (hint: you can find these easily by
   commenting it out).

   Then, when you need to set an affect with the above code you can
   merely do something analogous to:


   and so forth like normal sane persons would use macros. :o)
   Hope that it helps a bit. With this you should NEVER again have to
   add bitvectors or change anything in your code after having added
   spells other than the NUM_AFFECTS field.

   Alternative method using C++ compilers/STL:

   replace long affected_by; with std::vector<bool> affected_by;

   at boot run: affected_by.resize(NUM_AFFECTS);

   redefine AFF_ flags like above.

   #define AFF_FLAGGED(ch, flag) ((ch)->char_specials.saved.affected_by[(flag)])

   lots nicer, eh? :o)

   Also note if you want circle to compile with a c++ compiler there
   are a few things you will need to change. Here an there in the code
   things are defined as const char* (for instance NOPERSON, OK,
   etc.), but in db.h they are defined as extern char* NOPERSON.
   (or might be vice versa I forgot), this will cause you C++ compiler
   to complain about non-existant external variable NOPERSON (for
   instance) on linking. They should be fairly easy to solve. :o)

Yours truly,
  Henrik Stuart (

   | FAQ: |
   | Archives: |
   | Newbie List:   |

This archive was generated by hypermail 2b30 : 06/25/03 PDT