/**************************************************************************/
// bit.cpp - see below
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with the dawn license *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
**************************************************************************/
/***************************************************************************
* File: bit.cpp *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
* *
* This code was written by Jason Dinkel and inspired by Russ Taylor, *
* and has been used here for OLC - OLC would not be what it is without *
* all the previous coders who released their source code. *
* *
***************************************************************************/
#include "include.h" // dawn standard includes
#define STNM(flag) flag, #flag
struct flag_stat_type
{
const struct flag_type *structure;
const char *name;
bool stat;
};
/*****************************************************************************
Name: flag_stat_table
Purpose: This table catagorizes the tables following the lookup
functions below into stats and flags. Flags can be toggled
but stats can only be assigned. Update this table when a
new set of flags is installed.
****************************************************************************/
const struct flag_stat_type flag_stat_table[] =
{
// { structure, text version type },
{ STNM(ac_types), true },
{ STNM(apply_types), true },
{ STNM(area_import_format_types), true },
{ STNM(ban_types), true },
{ STNM(buildrestrict_types), true },
{ STNM(castnames_types), true },
{ STNM(category_types), true },
{ STNM(colourmode_types), true },
{ STNM(com_category_types), true },
{ STNM(commandlog_types), true },
{ STNM(damtype_types), true },
{ STNM(direction_types), true },
{ STNM(help_category_types), true },
{ STNM(immhelp_types), true },
{ STNM(item_types), true },
{ STNM(mixtype_types), true },
{ STNM(position_types), true },
{ STNM(preference_types), true },
{ STNM(sector_types), true },
{ STNM(sex_types), true },
{ STNM(size_types), true },
{ STNM(sktype_types), true }, // different types of entries in the skill_table
{ STNM(target_types), true },
{ STNM(textsearch_types), true },
{ STNM(to_types), true },
{ STNM(weapon_class_types), true },
{ STNM(wear_location_types), true },
{ STNM(wear_location_strings_types), true },
{ STNM(laston_wizlist_types), true },
// NOTE: ALL TRUE TABLES MUST BE ABOVE HERE
{ STNM(act_flags), false },
{ STNM(act2_flags), false },
{ STNM(affect_flags), false },
{ STNM(affect2_flags), false },
{ STNM(align_flags), false },
{ STNM(attune_flags), false },
{ STNM(classnames_flags), false },
{ STNM(commandflag_flags), false },
{ STNM(container_flags), false },
{ STNM(council_flags), false },
{ STNM(dedit_flags), false },
{ STNM(exit_flags), false },
//{ STNM(grantgroup_flags), false },
{ STNM(language_flags), false },
{ STNM(objextra_flags), false },
{ STNM(objextra2_flags), false },
//{ STNM(objextra3_flags), false },
{ STNM(form_flags), false },
{ STNM(imm_flags), false },
{ STNM(off_flags), false },
{ STNM(olc_flags), false },
{ STNM(part_flags), false },
{ STNM(res_flags ), false },
{ STNM(room_flags ), false },
{ STNM(room2_flags), false },
{ STNM(tendency_flags), false },
{ STNM(vuln_flags), false },
{ STNM(weapon_flags), false },
{ STNM(wear_flags), false },
{ 0,"", 0 }
};
/*****************************************************************************
Name: is_stat( table )
Purpose: Returns true if the table is a stat table and false if flag.
Called by: flag_value and flag_string.
Note: This function is local and used only in bit.c.
****************************************************************************/
bool is_stat( const struct flag_type *flag_table )
{
int flag;
for (flag = 0; flag_stat_table[flag].structure && flag_stat_table[flag].stat; flag++)
{
if ( flag_stat_table[flag].structure == flag_table
&& flag_stat_table[flag].stat )
return true;
}
return false;
}
/**************************************************************************/
// Kal - Aug 01
const char *get_flag_table_name( const struct flag_type *flag_table )
{
int flag;
for (flag = 0; flag_stat_table[flag].structure; flag++)
{
if (flag_stat_table[flag].structure == flag_table){
return flag_stat_table[flag].name;
}
}
return "unknown";
}
/**************************************************************************/
/*
* This function is Russ Taylor's creation. Thanks Russ!
* All code copyright (C) Russ Taylor, permission to use and/or distribute
* has NOT been granted. Use only in this OLC package has been granted.
*/
/*****************************************************************************
Name: flag_lookup( flag, table )
Purpose: Returns the value of a single, settable flag from the table.
Called by: flag_value and flag_string.
Note: This function is local and used only in bit.c.
****************************************************************************/
int flag_lookup (const char *name, const struct flag_type *flag_table)
{
int flag;
// first try an exact match, then do a substring match
// exact
for (flag = 0; flag_table[flag].name != NULL; flag++)
{
if ( !str_cmp( name, flag_table[flag].name )
&& flag_table[flag].settable )
return flag_table[flag].bit;
}
// substring
for (flag = 0; flag_table[flag].name != NULL; flag++)
{
if ( !str_prefix( name, flag_table[flag].name )
&& flag_table[flag].settable )
return flag_table[flag].bit;
}
return NO_FLAG;
}
/*****************************************************************************
Name: flag_value( table, flag )
Purpose: Returns the value of the flags entered. Multi-flags accepted.
Called by: olc.c and olc_act.c.
// use wordflag_to_value( const struct flag_type *flag_table, const char *wordtext)
// to convert a text into a value ignoring if the wordtext is settable.
****************************************************************************/
int flag_value( const struct flag_type *flag_table, char *argument)
{
char word[MIL];
int bit;
int marked = 0;
bool found = false;
if(IS_NULLSTR(argument)){
return NO_FLAG;
}
if ( is_stat( flag_table ) )
{
one_argument( argument, word );
if ( ( bit = flag_lookup( word, flag_table ) ) != NO_FLAG ){
return bit;
}else{
return NO_FLAG;
}
}
// Accept multiple flags.
for (; ;)
{
argument = one_argument( argument, word );
if ( word[0] == '\0' )
break;
if ( ( bit = flag_lookup( word, flag_table ) ) != NO_FLAG )
{
SET_BIT( marked, bit );
found = true;
}
}
if ( found ){
return marked;
}else{
return NO_FLAG;
}
}
/*****************************************************************************
Name: flag_string( table, flags/stat )
Purpose: Returns string with name(s) of the flags or stat entered.
Called by: act_olc.c, olc.c, and olc_save.c.
****************************************************************************/
char *flag_string( const struct flag_type *flag_table, int bits )
{
static int i;
static char buf[5][MSL];
char tbuf[MIL];
int flag;
bool bit_found=false;
// rotate buffers
++i%=5;
buf[i][0] = '\0';
// 2 different modes... if their is a stat table to be written
// a different mode is used from checking each bit is written
if (is_stat( flag_table )){
for (flag = 0; flag_table[flag].name && !bit_found; flag++)
{
if ( flag_table[flag].bit == bits ){
strcat( buf[i], " " );
strcat( buf[i], flag_table[flag].name );
bit_found=true;
}
}
// report that we have a missing value in a table
if(!bit_found && bits!=-1)
{
sprintf(tbuf," `#`RVALUE%dMISSING!!!`&",bits);
strcat( buf[i], tbuf);
}
}else{
// write bits the long way so we can record if a bit isn't written due
// to no matching bit in the flag table.
// Also write only one bit word for a single bit allowing multiple
// words for a bit value in a table (colour vs color) and single words in
// stored files.
for (int bit_index=0; bit_index<32; bit_index++)
{
bit_found=false;
int bit_value = 1<<bit_index;
if (!IS_SET(bit_value, bits))
continue;
for (flag = 0; flag_table[flag].name && !bit_found; flag++)
{
if ( IS_SET(bit_value, flag_table[flag].bit) )
{
strcat( buf[i], " ");
strcat( buf[i], flag_table[flag].name );
bit_found= true;
}
}
// report that we have a missing bit in a table
if(!bit_found && bits!=-1)
{
sprintf(tbuf," `#`RBIT#%d(%c)MISSING!!!`&",
bit_index,(bit_index <= 'Z' - 'A'?'A' + bit_index :
'a' + bit_index - ( 'Z' - 'A' + 1 )));
strcat( buf[i], tbuf);
}
}
} // non stat table (multiple bit table)
// return the result
return (buf[i][0] != '\0') ? buf[i]+1 : (char*)"none";
}
/*****************************************************************************
Name: flagging_info( table, flags/stat )
Purpose: tells a char what flags they just toggled
Called by: olc.c
****************************************************************************/
/**************************************************************************/
// perform only exact case insensitive matching
// returns a pointer to the table entry or NULL if unfound
// Kal - Feb 99
classgroup_type * classgroup_lookup(const char* name)
{
int index;
for(index=0; !IS_NULLSTR(classgroup_table[index].name);index++){
if(!str_cmp(classgroup_table[index].name, name)){
return &classgroup_table[index];
}
}
return NULL;
}
/**************************************************************************/
affectprofile_type * affectprofile_lookup(const char *name)
{
int index;
for(index=0; !IS_NULLSTR(affectprofile_table[index].name);index++){
if(!str_cmp(affectprofile_table[index].name, name)){
return &affectprofile_table[index];
}
}
return NULL;
}
/**************************************************************************/
// encode the bits into A->Z a->e form
char *flags_print(int flag)
{
int count, pos = 0;
static char buf[52];
for (count = 0; count < 32; count++)
{
if (IS_SET(flag,1<<count))
{
if (count < 26)
buf[pos] = 'A' + count;
else
buf[pos] = 'a' + (count - 26);
pos++;
}
}
if (pos == 0)
{
buf[pos] = '0';
pos++;
}
buf[pos] = '\0';
return buf;
}
/**************************************************************************/
// convert bits from the form A->Z a->e into a number value
int flags_read(char *flagtext)
{
int number;
char c;
char *p=flagtext;
bool negative = false;
do{
c=*p++;
}
while ( is_space(c));
if (c == '-')
{
negative = true;
c = *p++;
}
number = 0;
if (!is_digit(c))
{
while (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
{
number += flag_convert(c);
c = *p++;
}
}else{
while (is_digit(c))
{
number = number * 10 + c - '0';
c = *p++;
}
}
if(negative){
number*=-1;
}
return number;
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/