tfe-1.0/area/
tfe-1.0/files/
tfe-1.0/logs/
tfe-1.0/logs/immortal/
tfe-1.0/logs/mob/
tfe-1.0/logs/object/
tfe-1.0/logs/player/
tfe-1.0/logs/room/
tfe-1.0/notes/clans/
tfe-1.0/player/
tfe-1.0/prev/
tfe-1.0/prev/area/
tfe-1.0/prev/player/
tfe-1.0/prev/rooms/
tfe-1.0/rooms/
tfe-1.0/src-gc/
tfe-1.0/src-msvc/
tfe-1.0/src-unix/
tfe-1.0/www/
tfe-1.0/www/html/
#include <ctype.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include "define.h"
#include "struct.h"


/*
 *   GLOBAL CONSTANTS
 */


int max_permission  = MAX_PERMISSION;

flag_data affect_flags = { "Affect", &aff_char_table[0].name,
  &aff_char_table[1].name, &MAX_ENTRY_AFF_CHAR };

flag_data permission_flags = { "Permission", &permission_name[1],
  &permission_name[2], &max_permission };

flag_data material_flags = { "Materials", &material_table[0].name,
  &material_table[1].name, &MAX_ENTRY_METAL };


const char* flag_handler( const char** title, const char*** name1,
  const char*** name2, int** bit, int* max, int* uses_flag,
  const char* can_edit, char_data* ch, char* argument, int types )
{
  const char*  string;
  int            i, j;
  bool          exact;

  if( *argument == '\0' ) {
    for( i = j = 0; i < types; i++ )
      if( uses_flag[i] ) {
        if( j++ != 0 )
          page( ch, "\n\r" );
        display_flags( title[i], name1[i], name2[i], bit[i], max[i], ch );
        }
    return empty_string;
    }

  for( i = 0; i < types; i++ ) 
    if( uses_flag[i] && matches( argument, title[i] ) ) {
      display_flags( title[i], name1[i], name2[i], bit[i], max[i], ch );
      return empty_string;
      }

  for( exact = TRUE; ; exact = FALSE ) {
    for( i = 0; i < types; i++ )  
      if( uses_flag[i] && ( string = set_flags( name1[i], name2[i],
        bit[i], max[i], uses_flag[i] == 1 ? can_edit : NULL,
        ch, argument, exact, !exact && i == types-1 ) ) != NULL )
        return string;
    if( !exact )
      break;
    }

  return NULL;
}


/*
 *   DISPLAY ROUTINES
 */


void display_flags( const char* text, const char** name1,
  const char** name2, int* bit, int max, char_data* ch )
{
  char   buf  [ TWO_LINES ];
  int      i;

  if( *text == '*' ) 
    page_title( ch, "%s ", &text[1] );
  else 
    page( ch, "%s Flags:\n\r", text );

  for( i = 0; i < max; i++ ) {
    sprintf( buf, "%15s (%1c)%s", *(name1+i*(name2-name1)),
      is_set( bit, i ) ? '*' : ' ', i%4 == 3 ? "\n\r" : "" );
    page( ch, buf );
    }

  if( i%4 != 0 )
    page( ch, "\n\r" );     
}


void flag_data :: sprint( char* tmp, int* bit )
{
  int i;

  tmp[0] = '\0';

  if( *max < 16 && *bit+1 == ( 1 << *max ) ) {
    strcpy( tmp, "all" );
    return;
    }

  for( i = 0; i < *max; i++ )
    if( is_set( bit, i ) )
      sprintf( tmp+strlen( tmp ), "%s%s", *tmp == '\0' ? "" : ", ",
        *(name1+i*(name2-name1)) );

  if( *tmp == '\0' ) 
    strcpy( tmp, "none" );
}
  

void flag_data :: display( char_data* ch, int* bit )
{
  char   buf  [ TWO_LINES ];
  int      i;

  page( ch, "%s Flags:\n\r", title );

  for( i = 0; i < *max; i++ ) {
    sprintf( buf, "%15s (%1c)%s", *(name1+i*(name2-name1)),
      is_set( bit, i ) ? '*' : ' ',
      i%4 == 3 ? "\n\r" : "" );
    page( ch, buf );
    }

  if( i%4 != 0 )
    page( ch, "\n\r" );     
}


/*
 *   SET ROUTINE
 */


void flag_data :: set( char_data* ch, char* argument, int* bit )
{
  if( *argument == '\0' )
    display( ch, bit );
  else 
    set_flags( name1, name2, bit, *max, NULL, ch,
      argument, FALSE, TRUE );
}


const char* set_flags( const char** name1, const char** name2, int* bit,
  int max, const char* can_edit, char_data* ch, char* argument,
  bool exact, bool fail_msg )
{
  char* tmp = static_string( );

  for( int i = 0; i < max; i++ ) {
    if( matches( argument, *(name1+i*(name2-name1)), exact ) ) {
      if( can_edit != NULL ) {
        send( ch, can_edit );
        return can_edit;
        } 
      switch_bit( bit, i );
      sprintf( tmp, "%s set to %s.\n\r", *(name1+i*(name2-name1)),
        true_false( bit, i ) );
      *tmp = toupper( *tmp );
      send( ch, tmp );
      tmp[ strlen( tmp )-2 ] = '\0';
      return tmp;
      }
    }

  if( fail_msg )
    send( ch, "Unknown flag - use no argument for list.\n\r" );

  return NULL;
}


void set_flags( char_data* ch, char*& argument, int* bit, const char* flags )
{
  bool set;
  int    i;

  if( *argument != '+' && *argument != '-' )
    return;

  set = ( *argument++ == '+' ); 
  
  for( ; *argument != '\0' && *argument != ' '; argument++ ) { 
    for( i = 0; ; i++ ) {
      if( flags[i] == '\0' ) {
        send( ch, "Unknown flag: %c.\n\r", *argument );
        break; 
        }
      else if( flags[i] == *argument ) {
        send( ch, "%c bit %s.\n\r", *argument,
          set ? "set" : "removed" );
        assign_bit( bit, i, set );
        break;
        }
      }
    }
}


/* 
 *   TOGGLE FUNCTION
 */


void set_bool( char_data* ch, char* argument, const char* text,
  int& flag )
{
  if( !strncasecmp( "true", argument, strlen( argument ) ) ) {
    flag = TRUE;
    }
  else if( !strncasecmp( "false", argument, strlen( argument ) ) ) {
    flag = FALSE;
    }
  else {
    send( ch, "%s can be set either true or false.\n\r", text );
    return;
    }

  send( ch, "%s set %s.\n\r", text, flag ? "true" : "false" );
}


bool toggle( char_data* ch, char* arg, const char* text,
  int* bit, int flag )
{
  bool already;

  if( !strcasecmp( arg, "on" ) ) {
    if( ( already = is_set( bit, flag ) ) == FALSE ) 
      set_bit( bit, flag );
    }
  else if( !strcasecmp( arg, "off" )  ) {
    if( ( already = !is_set( bit, flag ) ) == FALSE )
      remove_bit( bit, flag );
    }
  else 
    return FALSE;

  if( already )
    send( ch, "%s already %s.\n\r", text, arg );
  else
    send( ch, "%s turned %s.\n\r", text, arg );

  return TRUE;
}


/*
 *   GET_FLAGS ROUTINE
 */


bool get_flags( char_data* ch, char*& argument, int* bit, const char* flags,
  const char* function )
{
  int     i;

  *bit = 0;
 
  if( *argument != '-' )
    return TRUE;

  argument++;

  for( ; *argument != ' ' && *argument != '\0'; argument ++ ) {
    for( i = 0; ; i++ ) {
      if( flags[i] == '\0' ) {
        send( ch, "%s: illegal option %c.\n\r", function, *argument ); 
        return FALSE;
        }
      if( *argument == flags[i] ) {
        set_bit( bit, i );
        break;
        }
      }
    }

  skip_spaces( argument );

  return TRUE;
}


/* 
 *   ALTER ROUTINE
 */


void alter_flags( int* modify, int* next, int* prev, int max )
{
  int i;

  for( i = 0; i < max; i++ )
    if( is_set( prev, i ) != is_set( next, i ) 
      && is_set( modify, i ) != is_set( next, i ) )
      switch_bit( modify, i );
}


/*
 *  LEVEL ROUTINES
 */


void display_levels( const char* text, const char** name1,
  const char** name2, int* bit, int max, char_data* ch )
{
  char   buf  [ TWO_LINES ];
  int      i;
  int  level;

  page_title( ch, "%s Levels", text );

  for( i = 0; i < max; i++ ) {
    level = level_setting( bit, i );
    sprintf( buf, "%15s (%c)%s", *(name1+i*(name2-name1)),
      level == 0 ? '-' : '0'+level, i%4 == 3 ? "\n\r" : "" );
    page( ch, buf );
    }

  if( i%4 != 0 )
    page( ch, "\n\r" );     
}


bool set_levels( const char** name1, const char** name2, int* bit,
  int max, char_data* ch, char* argument, bool exact )
{
  int        i;
  int    level;

  for( i = 0; i < max; i++ ) {
    if( matches( argument, *(name1+i*(name2-name1)), exact ) ) {
      if( *argument == '\0' || ( !is_number( argument )
        && *argument != '-' && !strcasecmp( argument, "off" ) ) ) {
        send( ch,
          "You must specify to what level you wish to set that.\n\r\n\r" );
        send( ch, "[ Current setting: %s ]\n\r",
          number_word( level_setting( bit, i ) ) );
        return TRUE;
        }
      if( ( level = atoi( argument ) ) < 0 || level > 3 ) {
        send( ch, "The allowed level range is from zero to three.\n\r" );
        return TRUE;
        }
      set_level( bit, i, level );
      if( level == 0 ) 
        send( ch, "%s turned off.\n\r",
          *(name1+i*(name2-name1)) );
      else
        send( ch, "%s set to level %s.\n\r",
          *(name1+i*(name2-name1)), number_word( level ) );
      return TRUE;
      }
    }

  return FALSE;
}