toc/
toc/account/a/
toc/area/backup/
toc/area/imc/
toc/caste/
toc/caste/backup/
toc/clans/
toc/classes/
toc/crash/
toc/gods/
toc/guilds/
toc/lname/s/
toc/maps/backup/
toc/player/a/
toc/src/
toc/system/backup/
toc/tableprog/
/****************************************************************************
 * [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));

extern int top_affect;


void do_mpmset(CHAR_DATA * ch, char *argument)
{
   char arg1[MIL];
   char arg2[MIL];
   char arg3[MIL];
   char buf[MSL];
   char outbuf[MSL];
   CHAR_DATA *victim;
   int value, v2;
   int minattr, maxattr;

   /* 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_new(ch, arg1, 1)) == 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 = 25;
   }
   else
   {
      minattr = 3;
      maxattr = 18;
   }

   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, "wis"))
   {
      if (value < minattr || value > maxattr)
      {
         progbug("MpMset: Invalid wis", ch);
         return;
      }
      victim->perm_wis = 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, "cha"))
   {
      if (value < minattr || value > maxattr)
      {
         progbug("MpMset: Invalid cha", ch);
         return;
      }
      victim->perm_cha = 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, "agi"))
   {
      if (value < 15 || value > 450)
      {
         progbug("MpMset: Invalid agi", ch);
         return;
      }
      victim->perm_agi = value;
      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, "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, "gold"))
   {
      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 > MAX_HPMANA)
      {
         progbug("MpMset: Invalid hp", ch);
         return;
      }
      victim->max_hit = value;
      return;
   }

   if (!str_cmp(arg2, "mana"))
   {
      if (value < 0 || value > MAX_HPMANA)
      {
         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"))
   {
      if (IS_NPC(victim))
      {
         progbug("MpMset: can't set npc blood", ch);
         return;
      }

      if (value < 0 || value > MAX_LEVEL + 10)
      {
         progbug("MpMset: Invalid pc blood", ch);
         return;
      }

      victim->pcdata->condition[COND_BLOODTHIRST] = value;
      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 (!IS_NPC(victim))
      {
         progbug("MpMset: can't set pc flags", ch);
         return;
      }

      if (!argument || argument[0] == '\0')
      {
         progbug("MpMset: no flags", ch);
         return;
      }
      while (argument[0] != '\0')
      {
         argument = one_argument(argument, arg3);
         value = get_actflag(arg3);
         if (value < 0 || value > MAX_BITS)
            progbug("MpMset: Invalid flag", ch);
         else
         {
            if (value == ACT_PROTOTYPE)
               progbug("MpMset: can't set prototype flag", ch);
            else if (value == ACT_IS_NPC)
               progbug("MpMset: can't remove npc flag", ch);
/*
	     else if ( value == ACT_POLYMORPHED )
		progbug("MpMset: can't change polymorphed flag", ch);
*/
            else
               xTOGGLE_BIT(victim->act, value);
         }
      }
      return;
   }

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

      if (!argument || argument[0] == '\0')
      {
         progbug("MpMset: no affected", ch);
         return;
      }
      while (argument[0] != '\0')
      {
         argument = one_argument(argument, arg3);
         value = get_aflag(arg3);
         if (value < 0 || value > MAX_BITS)
            progbug("MpMset: Invalid affected", ch);
         else
            xTOGGLE_BIT(victim->affected_by, 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_ELVEN | LANG_DWARVEN | LANG_OGRE | LANG_HOBBIT | LANG_FAIRY;

            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[MIL];
   char arg2[MIL];
   char arg3[MIL];
   char buf[MSL];
   OBJ_DATA *obj;
   char outbuf[MSL];
   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, "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:
         break;
      case ITEM_SCROLL:
      case ITEM_POTION:
         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_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;
}