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.