dbna/clans/
dbna/councils/
dbna/deity/
dbna/gods/
dbna/houses/
dbna/space/
/****************************************************************************
 * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame      |   \\._.//   *
 * -----------------------------------------------------------|   (0...0)   *
 * SMAUG 1.4 (C) 1994, 1995, 1996, 1998  by Derek Snider      |    ).:.(    *
 * -----------------------------------------------------------|    {o o}    *
 * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus,      |   / ' ' \   *
 * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek,      |~'~.VxvxV.~'~*
 * Tricops and Fireblade                                      |             *
 * ------------------------------------------------------------------------ *
 * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael        *
 * Chastain, Michael Quan, and Mitchell Tse.                                *
 * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.     *
 ****************************************************************************/

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mud.h"


int get_otype args( ( char *type ) );
int get_aflag args( ( char *flag ) );
int get_npc_race args( ( char *type ) );
int get_actflag args( ( char *flag ) );
int get_risflag args( ( char *flag ) );
int get_partflag args( ( char *flag ) );
int get_attackflag args( ( char *flag ) );
int get_defenseflag args( ( char *flag ) );
int get_langflag args( ( char *flag ) );
int get_langnum args( ( char *flag ) );
int get_trigflag args( ( char *flag ) );
int get_plrflag args( ( char *flag ) );
int get_pcflag args( ( char *flag ) );

extern int top_affect;

/* Made by Karn */
void do_mpmrppset( CHAR_DATA * ch, char *argument )
{
  CHAR_DATA *victim;
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  int value;
  int i;

  argument = one_argument( argument, arg1 );
  one_argument( argument, arg2 );
  victim = NULL;

  if( !IS_NPC( ch ) )
  {
    send_to_char( "Huh?!?\n\r", ch );
    return;
  }

  if( arg1[0] == '\0' )
  {
    send_to_char( "'kay, genius. How do you plan to edit RPPs without specifying WHO?\n\r", ch );
    send_to_char( "Syntax: rppedit <name> +/-5\n\r", ch );
    return;
  }

  if( ( victim = get_char_world( ch, arg1 ) ) == NULL )
  {
    send_to_char( "They aren't here.\n\r", ch );
    return;
  }

  if( arg2[0] == '\0' && arg3[0] == '\0' )
  {
    value = victim->pcdata->quest_curr;
    ch_printf( ch, "Target currently has %d RPPs.\n", value );
    value = victim->pcdata->quest_accum;
    ch_printf( ch, "Target has earned %d RPPs total.\n\r", value );
    return;
  }

  if( ( victim = get_char_room( ch, arg1 ) ) == NULL )
  {
    send_to_char( "Sorry, boss. Gotta be in the room with 'em.\n\r", ch );
    return;
  }

  if( IS_NPC( victim ) )
  {
    send_to_char( "No.\n\r", ch );
    return;
  }

  if( arg2[0] == '+' || arg2[0] == '-' )
  {
    i = 1;
    while( arg2[i] != '\0' )
    {
      arg3[i - 1] = arg2[i];
      i++;
    }
    value = atoi( arg3 );
//    if ( ( arg2[0] == '+' && ( value == 5 || value == 10 ) )
    if( ( arg2[0] == '+' && ( value == 5 ) ) || ( arg2[0] == '-' && ( value % 5 == 0 ) ) )
    {
      if( IS_NPC( victim ) )
      {
        send_to_char( "No.\n\r", ch );
        return;
      }
/*      if( get_trust( ch ) < get_trust( victim ) )
      {
        send_to_char( "No.\n\r", ch );
        return;
      }*/
      if( arg2[0] == '+' )
      {
        victim->pcdata->quest_curr += value;
        victim->pcdata->quest_accum += value;
        ch_printf( ch, "Target has been given %d RPPs.\n\r", value );
        ch_printf( victim, "You have been awarded %d RPPs for your quality roleplaying.\n\r", value );
        return;
      }
      if( arg2[0] == '-' )
      {
	if ( victim->pcdata->quest_curr <= 0 )
	return;
        victim->pcdata->quest_curr -= value;
        ch_printf( ch, "Target's RPPs have been reduced by %d.\n\r", value );
        ch_printf( victim, "Your RPPs have been reduced by %d.\n\r", value );
        return;
      }
    }
    else
    {
//      send_to_char("You may only change by increments of 5 or 10.\n\r", ch);
      send_to_char( "You may only change by increments of 5.\n\r", ch );
      return;
    }
  }
  else
  {
    send_to_char( "Must specify whether to add or subtract RPP.\n\r", ch );
    return;
  }
  return;
}


void do_mpmset( CHAR_DATA * ch, char *argument )
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  char outbuf[MAX_STRING_LENGTH];
  CHAR_DATA *victim;
  int value, v2;
  int minattr, maxattr;
  bool pcflag = FALSE;

  /*
   * A desc means switched.. too many loopholes if we allow that.. 
   */
  if( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ) || ch->desc )
  {
    send_to_char( "Huh?\n\r", ch );
    return;
  }

  smash_tilde( argument );

  argument = one_argument( argument, arg1 );
  argument = one_argument( argument, arg2 );
  strcpy( arg3, argument );

  if( !*arg1 )
  {
    progbug( "MpMset: no args", ch );
    return;
  }

  if( ( victim = get_char_room( ch, arg1 ) ) == NULL )
  {
    progbug( "MpMset: no victim", ch );
    return;
  }

  if( IS_IMMORTAL( victim ) )
  {
    send_to_char( "You can't do that!\n\r", ch );
    return;
  }

  if( IS_NPC( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
  {
    progbug( "MpMset: victim is proto", ch );
    return;
  }

  if( IS_NPC( victim ) )
  {
    minattr = 1;
    maxattr = 110;
  }
  else
  {
    minattr = 1;
    maxattr = 110;
  }

  value = is_number( arg3 ) ? atoi( arg3 ) : -1;
  if( atoi( arg3 ) < -1 && value == -1 )
    value = atoi( arg3 );

  if( !str_cmp( arg2, "str" ) )
  {
    if( value < minattr || value > maxattr )
    {
      progbug( "MpMset: Invalid str", ch );
      return;
    }
    victim->perm_str = value;
    return;
  }

  if( !str_cmp( arg2, "int" ) )
  {
    if( value < minattr || value > maxattr )
    {
      progbug( "MpMset: Invalid int", ch );
      return;
    }
    victim->perm_int = value;
    return;
  }

  if( !str_cmp( arg2, "dex" ) )
  {
    if( value < minattr || value > maxattr )
    {
      progbug( "MpMset: Invalid dex", ch );
      return;
    }
    victim->perm_dex = value;
    return;
  }

  if( !str_cmp( arg2, "con" ) )
  {
    if( value < minattr || value > maxattr )
    {
      progbug( "MpMset: Invalid con", ch );
      return;
    }
    victim->perm_con = value;
    return;
  }

  if( !str_cmp( arg2, "lck" ) )
  {
    if( value < minattr || value > maxattr )
    {
      progbug( "MpMset: Invalid lck", ch );
      return;
    }
    victim->perm_lck = value;
    return;
  }
  if( !str_cmp( arg2, "affected" ) )
  {
    if( !argument || argument[0] == '\0' )
    {
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_aflag( arg3 );
      if( !( value < 0 && value > MAX_BITS ) )
        xTOGGLE_BIT( victim->affected_by, value );
    }
    if( IS_NPC( victim ) && xIS_SET( victim->act, ACT_PROTOTYPE ) )
      victim->pIndexData->affected_by = victim->affected_by;
    return;
  }

  if( !str_cmp( arg2, "sav1" ) )
  {
    if( value < -30 || value > 30 )
    {
      progbug( "MpMset: Invalid sav1", ch );
      return;
    }
    victim->saving_poison_death = value;
    return;
  }

  if( !str_cmp( arg2, "sav2" ) )
  {
    if( value < -30 || value > 30 )
    {
      progbug( "MpMset: Invalid sav2", ch );
      return;
    }
    victim->saving_wand = value;
    return;
  }

  if( !str_cmp( arg2, "sav3" ) )
  {
    if( value < -30 || value > 30 )
    {
      progbug( "MpMset: Invalid sav3", ch );
      return;
    }
    victim->saving_para_petri = value;
    return;
  }

  if( !str_cmp( arg2, "sav4" ) )
  {
    if( value < -30 || value > 30 )
    {
      progbug( "MpMset: Invalid sav4", ch );
      return;
    }
    victim->saving_breath = value;
    return;
  }

  if( !str_cmp( arg2, "sav5" ) )
  {
    if( value < -30 || value > 30 )
    {
      progbug( "MpMset: Invalid sav5", ch );
      return;
    }
    victim->saving_spell_staff = value;
    return;
  }

  if( !str_cmp( arg2, "sex" ) )
  {
    if( value < 0 || value > 2 )
    {
      progbug( "MpMset: Invalid sex", ch );
      return;
    }
    victim->sex = value;
    return;
  }

  if( !str_cmp( arg2, "class" ) )
  {
    if( IS_NPC( victim ) )  /* Broken by Haus... fixed by Thoric */
    {
      if( value >= MAX_NPC_CLASS || value < 0 )
      {
        progbug( "MpMset: Invalid npc class", ch );
        return;
      }
      victim->class = value;
      return;
    }
    progbug( "MpMset: can't set pc class", ch );
  }

  if( !str_cmp( arg2, "race" ) )
  {
    value = get_npc_race( arg3 );
    if( value < 0 )
      value = atoi( arg3 );
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc race", ch );
      return;
    }
    if( value < 0 || value >= MAX_NPC_RACE )
    {
      progbug( "MpMset: Invalid npc race", ch );
      return;
    }
    victim->race = value;
    return;
  }

  if( !str_cmp( arg2, "armor" ) )
  {
    if( value < -300 || value > 300 )
    {
      send_to_char( "AC range is -300 to 300.\n\r", ch );
      return;
    }
    victim->armor = value;
    return;
  }

  if( !str_cmp( arg2, "level" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc level", ch );
      return;
    }

    if( value < 0 || value > LEVEL_AVATAR + 5 )
    {
      progbug( "MpMset: Invalid npc level", ch );
      return;
    }
    victim->level = value;
    return;
  }

  if( !str_cmp( arg2, "numattacks" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc numattacks", ch );
      return;
    }

    if( value < 0 || value > 20 )
    {
      progbug( "MpMset: Invalid npc numattacks", ch );
      return;
    }
    victim->numattacks = value;
    return;
  }

  if( !str_cmp( arg2, "gold" ) || !str_cmp( arg2, "zeni" ) )
  {
    victim->gold = value;
    return;
  }

  if( !str_cmp( arg2, "hitroll" ) )
  {
    victim->hitroll = URANGE( 0, value, 85 );
    return;
  }

  if( !str_cmp( arg2, "damroll" ) )
  {
    victim->damroll = URANGE( 0, value, 65 );
    return;
  }

  if( !str_cmp( arg2, "hp" ) )
  {
    if( value < 1 || value > 32700 )
    {
      progbug( "MpMset: Invalid hp", ch );
      return;
    }
    victim->max_hit = value;
    return;
  }

  if( !str_cmp( arg2, "mana" ) )
  {
    if( value < 0 || value > 30000 )
    {
      progbug( "MpMset: Invalid mana", ch );
      return;
    }
    victim->max_mana = value;
    return;
  }

  if( !str_cmp( arg2, "move" ) )
  {
    if( value < 0 || value > 30000 )
    {
      progbug( "MpMset: Invalid move", ch );
      return;
    }
    victim->max_move = value;
    return;
  }

  if( !str_cmp( arg2, "practice" ) )
  {
    if( value < 0 || value > 100 )
    {
      progbug( "MpMset: Invalid practice", ch );
      return;
    }
    victim->practice = value;
    return;
  }

  if( !str_cmp( arg2, "align" ) )
  {
    if( value < -1000 || value > 1000 )
    {
      progbug( "MpMset: Invalid align", ch );
      return;
    }
    victim->alignment = value;
    return;
  }

/* non-functional for now -- Blod
    if ( !str_cmp( arg2, "quest" ) )
    {
	if ( IS_NPC(victim) )
	{
	    progbug("MpMset: can't set npc quest", ch);
	    return;
	}

	if ( value < 0 || value > 500 )
	{
	    progbug("MpMset: Invalid pc quest", ch);
	    return;
	}

	victim->pcdata->quest = value;
	return;
    }
*/

  if( !str_cmp( arg2, "questplus" ) )
  {
    if( IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set npc qp", ch );
      return;
    }

    if( value < 0 || value > 5000 )
    {
      progbug( "MpMset: Invalid pc qp", ch );
      return;
    }
    sprintf( log_buf, "%s raising glory of %s by %d ...", ch->name, victim->name, value );
    log_string( log_buf );
    victim->pcdata->quest_curr += value;
    victim->pcdata->quest_accum += value;
    return;
  }

  if( !str_cmp( arg2, "favor" ) )
  {
    if( IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set npc favor", ch );
      return;
    }

    if( value < -2500 || value > 2500 )
    {
      progbug( "MpMset: Invalid pc favor", ch );
      return;
    }

    victim->pcdata->favor = value;
    return;
  }

  if( !str_cmp( arg2, "mentalstate" ) )
  {
    if( value < -100 || value > 100 )
    {
      progbug( "MpMset: Invalid mentalstate", ch );
      return;
    }
    victim->mental_state = value;
    return;
  }

  if( !str_cmp( arg2, "emotion" ) )
  {
    if( value < -100 || value > 100 )
    {
      progbug( "MpMset: Invalid emotion", ch );
      return;
    }
    victim->emotional_state = value;
    return;
  }

  if( !str_cmp( arg2, "thirst" ) )
  {
    if( IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set npc thirst", ch );
      return;
    }

    if( value < 0 || value > 100 )
    {
      progbug( "MpMset: Invalid pc thirst", ch );
      return;
    }

    victim->pcdata->condition[COND_THIRST] = value;
    return;
  }

  if( !str_cmp( arg2, "drunk" ) )
  {
    if( IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set npc drunk", ch );
      return;
    }

    if( value < 0 || value > 100 )
    {
      progbug( "MpMset: Invalid pc drunk", ch );
      return;
    }

    victim->pcdata->condition[COND_DRUNK] = value;
    return;
  }

  if( !str_cmp( arg2, "full" ) )
  {
    if( IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set npc full", ch );
      return;
    }

    if( value < 0 || value > 100 )
    {
      progbug( "MpMset: Invalid pc full", ch );
      return;
    }

    victim->pcdata->condition[COND_FULL] = value;
    return;
  }

  if( !str_cmp( arg2, "blood" ) )
  {
    progbug( "MpMset: can't set blood because vampires don't exist.", ch );
    return;
  }

  if( !str_cmp( arg2, "name" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc name", ch );
      return;
    }

    STRFREE( victim->name );
    victim->name = STRALLOC( arg3 );
    return;
  }

  if( !str_cmp( arg2, "deity" ) )
  {
    DEITY_DATA *deity;

    if( IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set npc deity", ch );
      return;
    }

    if( !arg3 || arg3[0] == '\0' )
    {
      STRFREE( victim->pcdata->deity_name );
      victim->pcdata->deity_name = STRALLOC( "" );
      victim->pcdata->deity = NULL;
      return;
    }

    deity = get_deity( arg3 );
    if( !deity )
    {
      progbug( "MpMset: Invalid deity", ch );
      return;
    }
    STRFREE( victim->pcdata->deity_name );
    victim->pcdata->deity_name = QUICKLINK( deity->name );
    victim->pcdata->deity = deity;
    return;
  }

  if( !str_cmp( arg2, "short" ) )
  {
    STRFREE( victim->short_descr );
    victim->short_descr = STRALLOC( arg3 );
    return;
  }

  if( !str_cmp( arg2, "long" ) )
  {
    STRFREE( victim->long_descr );
    strcpy( buf, arg3 );
    strcat( buf, "\n\r" );
    victim->long_descr = STRALLOC( buf );
    return;
  }

  if( !str_cmp( arg2, "title" ) )
  {
    if( IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set npc title", ch );
      return;
    }

    set_title( victim, arg3 );
    return;
  }

  if( !str_cmp( arg2, "spec" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc spec", ch );
      return;
    }

    if( !str_cmp( arg3, "none" ) )
    {
      victim->spec_fun = NULL;
      return;
    }

    if( ( victim->spec_fun = spec_lookup( arg3 ) ) == 0 )
    {
      progbug( "MpMset: Invalid spec", ch );
      return;
    }
    return;
  }

  if( !str_cmp( arg2, "flags" ) )
  {
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no flags", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      pcflag = FALSE;
      argument = one_argument( argument, arg3 );
      if( IS_NPC( victim ) )
        value = get_actflag( arg3 );
      else
        value = get_plrflag( arg3 );
      if( !IS_NPC( victim ) && ( value < 0 || value > MAX_BITS ) )
      {
        pcflag = TRUE;
        value = get_pcflag( arg3 );
      }

      if( value < 0 || value > MAX_BITS )
        progbug( "MpMset: Invalid flag", ch );
      else
      {
        if( value == ACT_PROTOTYPE && IS_NPC( victim ) )
          progbug( "MpMset: can't set prototype flag", ch );
        else if( value == ACT_IS_NPC && IS_NPC( victim ) )
          progbug( "MpMset: can't remove npc flag", ch );
        else
        {
          if( pcflag )
            TOGGLE_BIT( victim->pcdata->flags, 1 << value );
          else
            xTOGGLE_BIT( victim->act, value );
        }
      }
    }
    return;
  }


  /*
   * save some more finger-leather for setting RIS stuff
   * Why there's can_modify checks here AND in the called function, Ill
   * never know, so I removed them.. -- Alty
   */
  if( !str_cmp( arg2, "r" ) )
  {
    sprintf( outbuf, "%s resistant %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    return;
  }
  if( !str_cmp( arg2, "i" ) )
  {
    sprintf( outbuf, "%s immune %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    return;
  }
  if( !str_cmp( arg2, "s" ) )
  {
    sprintf( outbuf, "%s susceptible %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    return;
  }
  if( !str_cmp( arg2, "ri" ) )
  {
    sprintf( outbuf, "%s resistant %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    sprintf( outbuf, "%s immune %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    return;
  }

  if( !str_cmp( arg2, "rs" ) )
  {
    sprintf( outbuf, "%s resistant %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    sprintf( outbuf, "%s susceptible %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    return;
  }
  if( !str_cmp( arg2, "is" ) )
  {
    sprintf( outbuf, "%s immune %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    sprintf( outbuf, "%s susceptible %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    return;
  }
  if( !str_cmp( arg2, "ris" ) )
  {
    sprintf( outbuf, "%s resistant %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    sprintf( outbuf, "%s immune %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    sprintf( outbuf, "%s susceptible %s", arg1, arg3 );
    do_mpmset( ch, outbuf );
    return;
  }

  if( !str_cmp( arg2, "resistant" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc resistant", ch );
      return;
    }
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no resistant", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_risflag( arg3 );
      if( value < 0 || value > 31 )
        progbug( "MpMset: Invalid resistant", ch );
      else
        TOGGLE_BIT( victim->resistant, 1 << value );
    }
    return;
  }

  if( !str_cmp( arg2, "immune" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc immune", ch );
      return;
    }
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no immune", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_risflag( arg3 );
      if( value < 0 || value > 31 )
        progbug( "MpMset: Invalid immune", ch );
      else
        TOGGLE_BIT( victim->immune, 1 << value );
    }
    return;
  }

  if( !str_cmp( arg2, "susceptible" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc susceptible", ch );
      return;
    }
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no susceptible", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_risflag( arg3 );
      if( value < 0 || value > 31 )
        progbug( "MpMset: Invalid susceptible", ch );
      else
        TOGGLE_BIT( victim->susceptible, 1 << value );
    }
    return;
  }

  if( !str_cmp( arg2, "part" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc part", ch );
      return;
    }
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no part", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_partflag( arg3 );
      if( value < 0 || value > 31 )
        progbug( "MpMset: Invalid part", ch );
      else
        TOGGLE_BIT( victim->xflags, 1 << value );
    }
    return;
  }

  if( !str_cmp( arg2, "attack" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc attack", ch );
      return;
    }
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no attack", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_attackflag( arg3 );
      if( value < 0 )
        progbug( "MpMset: Invalid attack", ch );
      else
        xTOGGLE_BIT( victim->attacks, value );
    }
    return;
  }

  if( !str_cmp( arg2, "defense" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc defense", ch );
      return;
    }
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no defense", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_defenseflag( arg3 );
      if( value < 0 || value > MAX_BITS )
        progbug( "MpMset: Invalid defense", ch );
      else
        xTOGGLE_BIT( victim->defenses, value );
    }
    return;
  }

  if( !str_cmp( arg2, "pos" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc pos", ch );
      return;
    }
    if( value < 0 || value > POS_STANDING )
    {
      progbug( "MpMset: Invalid pos", ch );
      return;
    }
    victim->position = value;
    return;
  }

  if( !str_cmp( arg2, "defpos" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc defpos", ch );
      return;
    }
    if( value < 0 || value > POS_STANDING )
    {
      progbug( "MpMset: Invalid defpos", ch );
      return;
    }
    victim->defposition = value;
    return;
  }

  if( !str_cmp( arg2, "speaks" ) )
  {
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no speaks", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_langflag( arg3 );
      v2 = get_langnum( arg3 );
      if( value == LANG_UNKNOWN )
        progbug( "MpMset: Invalid speaks", ch );
      else if( !IS_NPC( victim ) )
      {
        int valid_langs = LANG_COMMON | LANG_SAIYAN | LANG_HALFBREED | LANG_NAMEK
          | LANG_ANDROID | LANG_ICER | LANG_BIO_ANDROID | LANG_KAIO | LANG_DEMON | LANG_WIZARD;

        if( !( value &= valid_langs ) )
        {
          progbug( "MpMset: Invalid player language", ch );
          continue;
        }
        if( v2 == -1 )
          ch_printf( ch, "Unknown language: %s\n\r", arg3 );
        else
          TOGGLE_BIT( victim->speaks, 1 << v2 );
      }
      else
      {
        if( v2 == -1 )
          ch_printf( ch, "Unknown language: %s\n\r", arg3 );
        else
          TOGGLE_BIT( victim->speaks, 1 << v2 );
      }
    }
    if( !IS_NPC( victim ) )
    {
      REMOVE_BIT( victim->speaks, race_table[victim->race]->language );
      if( !knows_language( victim, victim->speaking, victim ) )
        victim->speaking = race_table[victim->race]->language;
    }
    return;
  }

  if( !str_cmp( arg2, "speaking" ) )
  {
    if( !IS_NPC( victim ) )
    {
      progbug( "MpMset: can't set pc speaking", ch );
      return;
    }
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpMset: no speaking", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_langflag( arg3 );
      if( value == LANG_UNKNOWN )
        progbug( "MpMset: Invalid speaking", ch );
      else
      {
        v2 = get_langnum( arg3 );
        if( v2 == -1 )
          ch_printf( ch, "Unknown language: %s\n\r", arg3 );
        else
          TOGGLE_BIT( victim->speaks, 1 << v2 );
      }
    }
    return;
  }

  progbug( "MpMset: Invalid field", ch );
  return;
}

void do_mposet( CHAR_DATA * ch, char *argument )
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  OBJ_DATA *obj;
  char outbuf[MAX_STRING_LENGTH];
  int value, tmp;

  /*
   * A desc means switched.. too many loopholes if we allow that.. 
   */
  if( !IS_NPC( ch ) || IS_AFFECTED( ch, AFF_CHARM ) || ch->desc )
  {
    send_to_char( "Huh?\n\r", ch );
    return;
  }

  smash_tilde( argument );

  argument = one_argument( argument, arg1 );
  argument = one_argument( argument, arg2 );
  strcpy( arg3, argument );

  if( !*arg1 )
  {
    progbug( "MpOset: no args", ch );
    return;
  }

  if( ( obj = get_obj_here( ch, arg1 ) ) == NULL )
  {
    progbug( "MpOset: no object", ch );
    return;
  }

  if( IS_OBJ_STAT( obj, ITEM_PROTOTYPE ) )
  {
    progbug( "MpOset: can't set prototype items", ch );
    return;
  }
  separate_obj( obj );
  value = atoi( arg3 );

  if( !str_cmp( arg2, "value0" ) || !str_cmp( arg2, "v0" ) )
  {
    obj->value[0] = value;
    return;
  }

  if( !str_cmp( arg2, "value1" ) || !str_cmp( arg2, "v1" ) )
  {
    obj->value[1] = value;
    return;
  }

  if( !str_cmp( arg2, "value2" ) || !str_cmp( arg2, "v2" ) )
  {
    obj->value[2] = value;
    return;
  }

  if( !str_cmp( arg2, "value3" ) || !str_cmp( arg2, "v3" ) )
  {
    obj->value[3] = value;
    return;
  }

  if( !str_cmp( arg2, "value4" ) || !str_cmp( arg2, "v4" ) )
  {
    obj->value[4] = value;
    return;
  }

  if( !str_cmp( arg2, "value5" ) || !str_cmp( arg2, "v5" ) )
  {
    obj->value[5] = value;
    return;
  }

  if( !str_cmp( arg2, "type" ) )
  {
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpOset: no type", ch );
      return;
    }
    value = get_otype( argument );
    if( value < 1 )
    {
      progbug( "MpOset: Invalid type", ch );
      return;
    }
    obj->item_type = ( sh_int ) value;
    return;
  }

  if( !str_cmp( arg2, "flags" ) )
  {
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpOset: no flags", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_oflag( arg3 );
      if( value < 0 || value > MAX_BITS )
        progbug( "MpOset: Invalid flag", ch );
      else
      {
        if( value == ITEM_PROTOTYPE )
          progbug( "MpOset: can't set prototype flag", ch );
        else
          xTOGGLE_BIT( obj->extra_flags, value );
      }
    }
    return;
  }

  if( !str_cmp( arg2, "wear" ) )
  {
    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpOset: no wear", ch );
      return;
    }
    while( argument[0] != '\0' )
    {
      argument = one_argument( argument, arg3 );
      value = get_wflag( arg3 );
      if( value < 0 || value > 31 )
        progbug( "MpOset: Invalid wear", ch );
      else
        TOGGLE_BIT( obj->wear_flags, 1 << value );
    }

    return;
  }

  if( !str_cmp( arg2, "level" ) )
  {
    obj->level = value;
    return;
  }

  if( !str_cmp( arg2, "weight" ) )
  {
    obj->weight = value;
    return;
  }

  if( !str_cmp( arg2, "cost" ) )
  {
    obj->cost = value;
    return;
  }

  if( !str_cmp( arg2, "timer" ) )
  {
    obj->timer = value;
    return;
  }

  if( !str_cmp( arg2, "name" ) )
  {
    STRFREE( obj->name );
    obj->name = STRALLOC( arg3 );
    return;
  }

  if( !str_cmp( arg2, "short" ) )
  {
    STRFREE( obj->short_descr );
    obj->short_descr = STRALLOC( arg3 );
    /*
     * Feature added by Narn, Apr/96 
     * * If the item is not proto, add the word 'rename' to the keywords
     * * if it is not already there.
     */
    if( str_infix( "mprename", obj->name ) )
    {
      sprintf( buf, "%s %s", obj->name, "mprename" );
      STRFREE( obj->name );
      obj->name = STRALLOC( buf );
    }
    return;
  }

  if( !str_cmp( arg2, "long" ) )
  {
    STRFREE( obj->description );
    strcpy( buf, arg3 );
    obj->description = STRALLOC( buf );
    return;
  }

  if( !str_cmp( arg2, "actiondesc" ) )
  {
    if( strstr( arg3, "%n" ) || strstr( arg3, "%d" ) || strstr( arg3, "%l" ) )
    {
      progbug( "MpOset: Illegal actiondesc", ch );
      return;
    }
    STRFREE( obj->action_desc );
    obj->action_desc = STRALLOC( arg3 );
    return;
  }

  if( !str_cmp( arg2, "affect" ) )
  {
    AFFECT_DATA *paf;
    sh_int loc;
    int bitv;

    argument = one_argument( argument, arg2 );
    if( arg2[0] == '\0' || !argument || argument[0] == 0 )
    {
      progbug( "MpOset: Bad affect syntax", ch );
      send_to_char( "Usage: oset <object> affect <field> <value>\n\r", ch );
      return;
    }
    loc = get_atype( arg2 );
    if( loc < 1 )
    {
      progbug( "MpOset: Invalid affect field", ch );
      return;
    }
    if( loc >= APPLY_AFFECT && loc < APPLY_WEAPONSPELL )
    {
      bitv = 0;
      while( argument[0] != '\0' )
      {
        argument = one_argument( argument, arg3 );
        if( loc == APPLY_AFFECT )
          value = get_aflag( arg3 );
        else
          value = get_risflag( arg3 );
        if( value < 0 || value > 31 )
          progbug( "MpOset: bad affect flag", ch );
        else
          SET_BIT( bitv, 1 << value );
      }
      if( !bitv )
        return;
      value = bitv;
    }
    else
    {
      argument = one_argument( argument, arg3 );
      value = atoi( arg3 );
    }
    CREATE( paf, AFFECT_DATA, 1 );
    paf->type = -1;
    paf->duration = -1;
    paf->location = loc;
    paf->modifier = value;
    xCLEAR_BITS( paf->bitvector );
    paf->next = NULL;
    LINK( paf, obj->first_affect, obj->last_affect, next, prev );
    ++top_affect;
    return;
  }

  if( !str_cmp( arg2, "rmaffect" ) )
  {
    AFFECT_DATA *paf;
    sh_int loc, count;

    if( !argument || argument[0] == '\0' )
    {
      progbug( "MpOset: no rmaffect", ch );
      return;
    }
    loc = atoi( argument );
    if( loc < 1 )
    {
      progbug( "MpOset: Invalid rmaffect", ch );
      return;
    }

    count = 0;

    for( paf = obj->first_affect; paf; paf = paf->next )
    {
      if( ++count == loc )
      {
        UNLINK( paf, obj->first_affect, obj->last_affect, next, prev );
        DISPOSE( paf );
        send_to_char( "Removed.\n\r", ch );
        --top_affect;
        return;
      }
    }
    progbug( "MpOset: rmaffect not found", ch );
    return;
  }

  /*
   * save some finger-leather
   */
  if( !str_cmp( arg2, "ris" ) )
  {
    sprintf( outbuf, "%s affect resistant %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    sprintf( outbuf, "%s affect immune %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    sprintf( outbuf, "%s affect susceptible %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    return;
  }

  if( !str_cmp( arg2, "r" ) )
  {
    sprintf( outbuf, "%s affect resistant %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    return;
  }

  if( !str_cmp( arg2, "i" ) )
  {
    sprintf( outbuf, "%s affect immune %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    return;
  }
  if( !str_cmp( arg2, "s" ) )
  {
    sprintf( outbuf, "%s affect susceptible %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    return;
  }

  if( !str_cmp( arg2, "ri" ) )
  {
    sprintf( outbuf, "%s affect resistant %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    sprintf( outbuf, "%s affect immune %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    return;
  }

  if( !str_cmp( arg2, "rs" ) )
  {
    sprintf( outbuf, "%s affect resistant %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    sprintf( outbuf, "%s affect susceptible %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    return;
  }

  if( !str_cmp( arg2, "is" ) )
  {
    sprintf( outbuf, "%s affect immune %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    sprintf( outbuf, "%s affect susceptible %s", arg1, arg3 );
    do_mposet( ch, outbuf );
    return;
  }

  /*
   * Make it easier to set special object values by name than number
   *            -Thoric
   */
  tmp = -1;
  switch ( obj->item_type )
  {
    case ITEM_WEAPON:
      if( !str_cmp( arg2, "weapontype" ) )
      {
        int x;

        value = -1;
        for( x = 0; x < sizeof( attack_table ) / sizeof( attack_table[0] ); x++ )
          if( !str_cmp( arg3, attack_table[x] ) )
            value = x;
        if( value < 0 )
        {
          progbug( "MpOset: Invalid weapon type", ch );
          return;
        }
        tmp = 3;
        break;
      }
      if( !str_cmp( arg2, "condition" ) )
        tmp = 0;
      break;
    case ITEM_ARMOR:
      if( !str_cmp( arg2, "condition" ) )
        tmp = 3;
      if( !str_cmp( arg2, "ac" ) )
        tmp = 1;
      break;
    case ITEM_SALVE:
      if( !str_cmp( arg2, "slevel" ) )
        tmp = 0;
      if( !str_cmp( arg2, "maxdoses" ) )
        tmp = 1;
      if( !str_cmp( arg2, "doses" ) )
        tmp = 2;
      if( !str_cmp( arg2, "delay" ) )
        tmp = 3;
      if( !str_cmp( arg2, "spell1" ) )
        tmp = 4;
      if( !str_cmp( arg2, "spell2" ) )
        tmp = 5;
      if( tmp >= 4 && tmp <= 5 )
        value = skill_lookup( arg3 );
      break;
    case ITEM_SCROLL:
    case ITEM_POTION:
    case ITEM_PILL:
      if( !str_cmp( arg2, "slevel" ) )
        tmp = 0;
      if( !str_cmp( arg2, "spell1" ) )
        tmp = 1;
      if( !str_cmp( arg2, "spell2" ) )
        tmp = 2;
      if( !str_cmp( arg2, "spell3" ) )
        tmp = 3;
      if( tmp >= 1 && tmp <= 3 )
        value = skill_lookup( arg3 );
      break;
    case ITEM_STAFF:
    case ITEM_WAND:
      if( !str_cmp( arg2, "slevel" ) )
        tmp = 0;
      if( !str_cmp( arg2, "spell" ) )
      {
        tmp = 3;
        value = skill_lookup( arg3 );
      }
      if( !str_cmp( arg2, "maxcharges" ) )
        tmp = 1;
      if( !str_cmp( arg2, "charges" ) )
        tmp = 2;
      break;
    case ITEM_CONTAINER:
      if( !str_cmp( arg2, "capacity" ) )
        tmp = 0;
      if( !str_cmp( arg2, "cflags" ) )
        tmp = 1;
      if( !str_cmp( arg2, "key" ) )
        tmp = 2;
      break;
    case ITEM_SWITCH:
    case ITEM_LEVER:
    case ITEM_PULLCHAIN:
    case ITEM_BUTTON:
      if( !str_cmp( arg2, "tflags" ) )
      {
        tmp = 0;
        value = get_trigflag( arg3 );
      }
      break;
  }
  if( tmp >= 0 && tmp <= 3 )
  {
    obj->value[tmp] = value;
    return;
  }

  progbug( "MpOset: Invalid field", ch );
  return;
}