Bit Vectors

 

SMAUG has a nice implementation of bit vectors, that can be very useful.  Don’t know what a bit vector is? well think of it this way, it’s a bunch of Booleans.  Let me explain.  Since, data is stored in binary form, there are 32 bits that make up an integer type.  That means that there basically 32 on/off, true/false variables inside an int, if you use it correctly.  Making the functions to do all this stuff, isn’t hard, but why do that, when they are already there.  Here are the functions

 

IS_SET(int, bit)

TOGGLE_BIT(int, bit)

SET_BIT(int, bit)

REMOVE_BIT(int, bit)

 

now this may not look useful, but let’s see what it can do.  Say you wish to add a flag to players, that this player would be unable to be seen  All you would have to do is, go into mud.h, at the end of all the PCFLAGS, add a new one, then check for it wherever you set the flag, or need to check if the flag is there.  So you might add a new command, to do the following

 

TOGGLE_BIT(victim->pcdata->flags, PCFLAG_VISABLE)

 

then in the can_see function, if(IS_SET(victim, PCFLAG_VISABLE)).

You don’t have to add another Boolean to the char data, and bloat the pfile up even more, it’s all automatically handled through these bitvectors.  Of coruse if you want to create a new bitvector, then you have to write it to the pfile, but that’s just like writing and reading and integer type, so it’s no big deal.

 

Say you want to add an arena, that has some of the flags like, noflee, noheal, nowait ect..  So you set up an arena struct and add it in a similar way that sysdata is setup.  You’ll need to add (if you want to keep consistent with the SMAUG way of doing things) 2 dimensiolnalarray of strings like

 

char *  const   arena_flags [] = { “noheal”, “nowait”, “noflee” };

and add some defines for the flags in mud.h

 

#define ARENAFLAG_NOHEAL BV00

#define ARENAFLAG_NOWAIT BV01

#define ARENAFLAG_NOFLEE BV02

 

You already know how to toggle bits, but here it gets a bit more complicated.  You want a command to set the arena with certain flags, so how do you display all the flags, in a readable fashion, and how to you take an input line and get the flags out of that?  Well the answer to the latter is easy, since SMAUG comes with a function to do that.

 

ch_printf(ch, "Flags: %s\n\r", flag_string(arena.flags, arena_flags));

 

this line, takes the bitvector, arena.flags and the strings that it represents, arena_flags, and parses them.  Now to make this work, the first #define must relate to the first string in the area_flags array.

 

Now, how do you parse an input line that has a list of flags, like mset does.  It’s a bit more complicated, but still not all that hard.

 

char arg[MAX_INPUT_LENGTH];

 

while ( argument[0] != '\0' ) {

      int value;

      argument = one_argument( argument, arg );

       

      value = get_arenaflag( arg );

      if ( value < 0 || value > MAX_BITS )

            ch_printf( ch, "Unknown flag: %s\n\r", arg3 );

      else

            TOGGLE_BIT( arena.flags, 1 << value );

      }

      send_to_char("Ok.\n\r", ch);

      return;

}

 

The only thing that shouldn’t make sense (unless you don’t understand bit manipulation) is the get_arenaflag, function.  Well we haven’t quite made that yet, so let’s do that now.

 

int get_arenaflag( char *flag )

{

 

        int x;

 

        for ( x = 0; x < (sizeof(arena_flags) / sizeof(arena_flags[0])); x++ )

                if ( !str_cmp(flag, arena_flags[x]) )

                        return x;

        return -1;

}

 

Say you put the snippet of code that parses the user input, you could do like this:

 

arena flags noheal nowait noflee

 

and that would toggle all those flags, which you could then check for accordingly.