示例#1
0
void
gain_skill_prof(struct creature *ch, int skl)
{
    int learned;
    if (skl == SKILL_READ_SCROLLS || skl == SKILL_USE_WANDS)
        learned = 10;
    else
        learned = LEARNED(ch);

    // NPCs don't learn
    if (IS_NPC(ch))
        return;

    // You can't gain in a skill that you don't really know
    if (GET_LEVEL(ch) < SPELL_LEVEL(skl, GET_CLASS(ch))) {
        if (!IS_REMORT(ch))
            return;
        if (GET_LEVEL(ch) < SPELL_LEVEL(skl, GET_REMORT_CLASS(ch)))
            return;
    }
    // Check for remort classes too
    if (SPELL_GEN(skl, GET_CLASS(ch)) > 0 &&
        GET_REMORT_GEN(ch) < SPELL_GEN(skl, GET_CLASS(ch)))
        return;

    if (GET_SKILL(ch, skl) >= (learned - 10))
        if ((GET_SKILL(ch, skl) - GET_LEVEL(ch)) <= 66)
            SET_SKILL(ch, skl, GET_SKILL(ch, skl) + 1);
}
示例#2
0
/* this function enhances a PC's skill by a random factor */
void learn_from_mistake(struct char_data *ch, int skill)
{
    /* this code allows this func to be called EVERYTIME the PC fails */
    if (GET_SKILL(ch, skill) < 98) {
      GET_SKILL(ch, skill) += number(1, 2);
      send_to_char("You learn from your mistake.\r\n", ch);
    }
}
示例#3
0
void
perform_net_load(struct descriptor_data *d, char *arg)
{
    int skill_num, percent;
    long int cost;

    skip_spaces(&arg);
    if (!*arg) {
        d_printf(d, "Usage: load <program>\r\n");
        return;
    }

    skill_num = find_skill_num(arg);
    if (skill_num < 1) {
        d_printf(d, "Error: program '%s' not found\r\n", arg);
        return;
    }

    if ((SPELL_GEN(skill_num, CLASS_CYBORG) > 0
            && GET_CLASS(d->creature) != CLASS_CYBORG)
        || (GET_REMORT_GEN(d->creature) < SPELL_GEN(skill_num, CLASS_CYBORG))
        || (GET_LEVEL(d->creature) < SPELL_LEVEL(skill_num, CLASS_CYBORG))) {
        d_printf(d, "Error: resources unavailable to load '%s'\r\n", arg);
        return;
    }

    if (GET_SKILL(d->creature, skill_num) >= LEARNED(d->creature)) {
        d_printf(d, "Program fully installed on local system.\r\n");
        return;
    }

    cost = GET_SKILL_COST(d->creature, skill_num);
    d_printf(d, "Program cost: %10ld  Account balance; %'" PRId64 "\r\n",
        cost, d->account->bank_future);

    if (d->account->bank_future < cost) {
        d_printf(d, "Error: insufficient funds in your account\r\n");
        return;
    }

    withdraw_future_bank(d->account, cost);
    percent = MIN(MAXGAIN(d->creature),
        MAX(MINGAIN(d->creature), GET_INT(d->creature) * 2));
    percent = MIN(LEARNED(d->creature) -
        GET_SKILL(d->creature, skill_num), percent);
    SET_SKILL(d->creature, skill_num, GET_SKILL(d->creature,
            skill_num) + percent);
    d_printf(d,
        "Program download: %s terminating, %d percent transfer.\r\n",
        spell_to_str(skill_num), percent);
    if (GET_SKILL(d->creature, skill_num) >= LEARNED(d->creature))
        d_printf(d, "Program fully installed on local system.\r\n");
    else
        d_printf(d, "Program %d%% installed on local system.\r\n",
            GET_SKILL(d->creature, skill_num));
}
示例#4
0
/* code for skill improvement through use */
void improve_skill(struct char_data *ch, int skill, int chance)
{
  int percent = GET_SKILL(ch, skill);
  int newpercent, max;
  char skillbuf[MAX_STRING_LENGTH];
  char mybuf[256];

  max = max_lvl_skill[1][spells[find_skill_num_def(skill)].difficulty][(int) GET_LEVEL(ch)];
  if (percent >= max || IS_NPC(ch))
    return;
  if (number(1, (chance * 50)) > (GET_WIS(ch) + GET_INT(ch)))
    return;
  newpercent = 1;
  if (number(1, 120) <= GET_WIS(ch))
    newpercent++;
  if (number(1, 120) <= GET_INT(ch))
    newpercent++;
  percent += newpercent;
  percent = MIN(percent, max);
  SET_SKILL(ch, skill, percent);
  if (newpercent) {
    sprintf(mybuf, "SKILLIMPROVE: %s improved skill %s, int = %d, wis = %d, improved by = %d, now = %d", GET_NAME(ch), spells[find_skill_num_def(skill)].command, GET_INT(ch), GET_WIS(ch), newpercent, percent);
    mudlog(mybuf, 'D', COM_IMMORT, TRUE);
    sprintf(skillbuf, "{RYou feel your skill in {W%s {Rimproving.{x\r\n", spells[find_skill_num_def(skill)].command);
    send_to_char(skillbuf, ch);
  }
}
示例#5
0
int calcManaMulti(CharData *ch) {
    int multi = 100;

    if(ROOM_FLAGGED(ch->in_room, ROOM_MANA_REGEN))
        multi += 50;
    
    if(IS_AFFECTED(ch, AFF_WRAITHFORM))
        multi += 25;

    if((GET_CLASS(ch) == CLASS_SHADOW_DANCER) && (IS_DARK(ch->in_room) || IS_AFFECTED(ch, AFF_SHADOW_SPHERE)))
        multi += 50;

    if(IS_AFFECTED(ch, AFF_POISON))
        multi -= 100;

    if(!IS_NPC(ch)) {
        if( !IS_NPC(ch) && ROOM_FLAGGED(ch->in_room, ROOM_SUFFER) && ( GET_LEVEL(ch) < LVL_IMMORT ))
            multi -= 90;
        else if (!GET_COND(ch, THIRST) && IS_AMARA(ch))
            multi -= 90;
        else if (IS_IZARTI(ch) && IS_EVIL(ch))
            multi -= 90;
        else if (IS_DEMON(ch) && IS_GOOD(ch))
            multi -= 90;
    }

    if(GET_RACE(ch) == RACE_STROLL)
        multi += 100;

    /* Position calculations    */
    switch (GET_POS(ch)) {
        case POS_MEDITATING:
        case POS_SLEEPING:
            multi += 120;
            break;
        case POS_RESTING:
            multi += 60;
            break;
    }

    multi += (int)GET_SKILL(ch, SKILL_DEVOTION);

    // Don't let a player's regeneration completely stagnate...
    multi = MAX(multi, 25);
    return multi;
}
示例#6
0
int ok_pick(struct char_data *ch, obj_vnum keynum, int pickproof, int scmd)
{
  int percent;

  percent = number(1, 101);

  if (scmd == SCMD_PICK) {
    if (keynum < 0)
      send_to_char("Odd - you can't seem to find a keyhole.\r\n", ch);
    else if (pickproof)
      send_to_char("It resists your attempts to pick it.\r\n", ch);
    else if (percent > GET_SKILL(ch, SKILL_PICK_LOCK))
      send_to_char("You failed to pick the lock.\r\n", ch);
    else
      return (1);
    return (0);
  }
  return (1);
}
示例#7
0
//Returns two character's jointly best understood language skill index.
int Character::BestUnderstoodTongue(Character *target)
{
	int new_tongue		= GET_SKILL(this, SKILL_NEW_TONGUE)   + GET_SKILL(target, SKILL_NEW_TONGUE);
	int old_tongue		= GET_SKILL(this, SKILL_OLD_TONGUE)   + GET_SKILL(target, SKILL_OLD_TONGUE);
	int troll_tongue	= GET_SKILL(this, SKILL_TROLL_TONGUE) + GET_SKILL(target, SKILL_TROLL_TONGUE);

	if(new_tongue >= old_tongue && new_tongue >= troll_tongue)
		return SKILL_NEW_TONGUE;
	if(old_tongue >= new_tongue && new_tongue >= troll_tongue)
		return SKILL_OLD_TONGUE;
	if(troll_tongue >= new_tongue && troll_tongue >= old_tongue)
		return SKILL_TROLL_TONGUE;

	return (MAX(new_tongue, MAX(old_tongue, troll_tongue)));
}
示例#8
0
int ok_pick(struct char_data *ch, obj_vnum keynum, int pickproof, int scmd)
{
  int percent, skill_lvl;

  if (scmd != SCMD_PICK)
    return (1);

  percent = rand_number(1, 101);
  skill_lvl = GET_SKILL(ch, SKILL_PICK_LOCK) + dex_app_skill[GET_DEX(ch)].p_locks + race_app_skill[GET_RACE(ch)].p_locks;

  if (keynum == NOTHING)
    send_to_char(ch, "Odd - you can't seem to find a keyhole.\r\n");
  else if (pickproof)
    send_to_char(ch, "It resists your attempts to pick it.\r\n");
  else if (percent > skill_lvl)
    send_to_char(ch, "You failed to pick the lock.\r\n");
  else
    return (1);

  return (0);
}
示例#9
0
void hunt_aggro(struct char_data * ch)
{
  int dir;
  int skillnum = spells[find_skill_num("aggressive")].spellindex;
  struct char_data *hunted_ch;

  if (!ch || !HUNTING(ch) || FIGHTING(ch)) {
    return;
  }
  /*
   if (world[ch->in_room].zone != world[HUNTING(ch)->in_room].zone) {
   HUNTING(ch) = 0;
   return;
   }
   */
  if ((hunted_ch = find_hunted_char(HUNTING(ch)))) {
    if (ch->in_room == hunted_ch->in_room && !ROOM_FLAGGED(hunted_ch->in_room, ROOM_PEACEFUL)) {
      if (CAN_SEE(hunted_ch, ch) && GET_SKILL(hunted_ch, skillnum) > number(0, 101)) {
        improve_skill(ch, skillnum, SKUSE_AVERAGE);
        hit(hunted_ch, ch, TYPE_UNDEFINED);
      } else {
        if (CAN_SEE(ch, hunted_ch)) {
          hit(ch, hunted_ch, TYPE_UNDEFINED);
        }
      }
      return;
    }
  } else {
    return;
  }

  /* dez 19980805
   if (IS_NPC(ch) && MOB_FLAGGED(ch, MOB_SENTINEL)) {
   dir = find_first_step(ch->in_room, hunted_ch->in_room, 2);
   } else if (IS_NPC(ch) && MOB_FLAGGED(ch, MOB_STAY_ZONE)) {
   */
  if (IS_NPC(ch) && MOB_FLAGGED(ch, MOB_STAY_ZONE)) {
    dir = find_first_step(ch->in_room, hunted_ch->in_room, 1);
  } else {
    dir = find_first_step(ch->in_room, hunted_ch->in_room, 0);
  }

  if (dir < 0) {
    /* do not forget until player is dead or I die
     HUNTING(ch) = 0;
     */
    return;
  } else {
    perform_move(ch, dir, 1);
    if (ch->in_room == hunted_ch->in_room) {
      if (!ROOM_FLAGGED(ch->in_room, ROOM_PEACEFUL)) {
        if (CAN_SEE(hunted_ch, ch) && GET_SKILL(hunted_ch, skillnum) > number(0, 101)) {
          improve_skill(ch, skillnum, SKUSE_AVERAGE);
          hit(hunted_ch, ch, TYPE_UNDEFINED);
        } else {
          if (CAN_SEE(ch, hunted_ch)) {
            hit(ch, hunted_ch, TYPE_UNDEFINED);
          }
        }
      }
    }
    return;
  }
}
示例#10
0
void list_skills(Character * ch, Character *teacher)
{
	int i, sortpos, has_pracs;
	std::string HowGood, PracType;
	Weave* weave;

	*buf = 0;
	if(!IS_NPC(ch))
	{
		has_pracs = MAX(0, ch->PlayerData->skillpracs) + MAX(0, ch->PlayerData->tradepracs);

		if(IS_CHANNELER(ch) || IS_DREADLORD(ch) || IS_DREADGUARD(ch))
			has_pracs += MAX(0, ch->PlayerData->spellpracs);

		if(!has_pracs)
			strcpy(buf, "You have no practice sessions remaining.\r\n");
		else
		{
			sprintf(buf, "You have %d practice session%s remaining, ",
				ch->PlayerData->skillpracs, (ch->PlayerData->skillpracs == 1 ? "" : "s"));

			if(IS_CHANNELER(ch) || IS_DREADLORD(ch) || IS_DREADGUARD(ch))
			{
				sprintf(buf + strlen(buf), "%d spell practice%s remaining, ",
					ch->PlayerData->spellpracs, (ch->PlayerData->spellpracs == 1 ? "" : "s"));
			}
			sprintf(buf + strlen(buf), "and %d trade practice%s remaining.\r\n",
				ch->PlayerData->tradepracs, (ch->PlayerData->tradepracs == 1 ? "" : "s"));
		}
	}

	sprintf(buf + strlen(buf), "You are skilled in the following:\r\n");
	strcpy(buf2, buf);

	std::list<int> WeaveVnums = WeaveManager::GetManager().GetListOfWeaveVnums();
	for ( std::list<int>::iterator vI = WeaveVnums.begin();vI != WeaveVnums.end();++vI)
	{
		sortpos = i = (*vI);
		Weave* weave = WeaveManager::GetManager().GetWeave(i);

		if( weave == NULL ) continue;

		if (strlen(buf2) >= MAX_STRING_LENGTH - 32)
		{
			strcat(buf2, "**OVERFLOW**\r\n");
			break;
		}

		if( (GET_SKILL(ch, i) <= 0 && !teacher) || !ch->CanPractice(weave))
			continue;

		if( teacher && teacher->CanTeach( weave ) == false )
			continue;

		if(weave->levels())
			sprintf(HowGood, "(Level %d)", ch->GetSkillLevel(i));
		else
			HowGood = how_good(GET_SKILL(ch, i));

		char costStr[256];
		sprintf(costStr, "(Cost: %d)", calc_price(ch, i));

		if( weave->isElement() )
			sprintf(buf2 + strlen(buf2), "%-17s %10s, (Level %d)\r\n",
				weave->getName().c_str(), costStr, ch->GetSkillLevel(i));
		else
			sprintf(buf2 + strlen(buf2), "%-17s %10s, (%d%%), %s\r\n",
				weave->getName().c_str(), costStr, GET_SKILL(ch, i), HowGood.c_str());
	}

	page_string(ch->desc, buf2, 1);
}
示例#11
0
//Returns the average of the speaker and listener's speaking capabilities in their jointly best understood tongue.
int Character::CommunicationLevel(Character *receiver)
{
	int skill = this->BestUnderstoodTongue(receiver);
	return (GET_SKILL(this, skill) + GET_SKILL(receiver, skill)) / 2;
}
示例#12
0
int	cast_spell(struct char_data *ch, struct char_data *tch,
               struct obj_data *tobj, struct spell_info_type *sptr,
               char *tar_str)
{

    if (!magic_enabled)
        return (0);

    if (!sptr) {
        extended_mudlog(NRM, SYSL_BUGS, TRUE, "cast_spell() called without a valid sptr: ch: %s, tch: %s",
                        GET_NAME(ch), GET_NAME(tch));
        return (0);
    }

    if (GET_POS(ch) < sptr->min_position) {
        switch (GET_POS(ch)) {
        case POS_SLEEPING:
            send_to_char("You dream about great magical powers.\r\n", ch);
            break;
        case POS_RESTING:
            send_to_char("You cannot concentrate while resting.\r\n", ch);
            break;
        case POS_SITTING:
            send_to_char("You can't do this sitting!\r\n", ch);
            break;
        case POS_FIGHTING:
            send_to_char("Impossible!  You can't concentrate enough!\r\n", ch);
            break;
        default:
            send_to_char("You can't do much of anything like this!\r\n", ch);
            break;
        }
        return (0);
    }
    if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master == tch)) {
        send_to_char("You are afraid you might hurt your master!\r\n", ch);
        return (0);
    }
    if ((tch != ch) && IS_SET(sptr->targets, TAR_SELF_ONLY)) {
        send_to_char("You can only cast this spell upon yourself!\r\n", ch);
        return (0);
    }
    if ((tch == ch) && IS_SET(sptr->targets, TAR_NOT_SELF)) {
        send_to_char("You cannot cast this spell upon yourself!\r\n", ch);
        return (0);
    }
    if (IS_SET(sptr->routines, MAG_GROUPS) && !AFF_FLAGGED(ch, AFF_GROUP)) {
        send_to_char("You can't cast this spell if you're not in a group!\r\n",ch);
        return (0);
    }

    if (cast_mtrigger(tch, ch, tar_str, sptr) == 0)
        return (0);
    if (cast_otrigger(tobj, ch, tar_str, sptr) == 0)
        return (0);
    if (cast_wtrigger(ch, tch, tobj, tar_str, sptr) == 0)
        return (0);

    send_to_char(OK, ch);
    say_spell(ch, sptr, tch, tobj);

    return (call_magic(ch, tch, tobj, sptr, (GET_SKILL(ch, sptr->skill)/100), CAST_SPELL,
                       tar_str));
}
示例#13
0
void list_skills(struct char_data *ch)
{
  const char *overflow = "\r\n**OVERFLOW**\r\n";
  int i, sortpos;
  size_t len = 0, nlen;
  char buf2[MAX_STRING_LENGTH];

  len = snprintf(buf2, sizeof(buf2), "You have %d practice session%s remaining.\r\n"
	"You know of the following %ss:\r\n", GET_PRACTICES(ch),
	GET_PRACTICES(ch) == 1 ? "" : "s", SPLSKL(ch));

  int cnt = 0;
  for (sortpos = 1; sortpos <= MAX_SKILLS; sortpos++) {
    i = spell_sort_info[sortpos];
    if (GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_CLASS(ch)]) {
      cnt += 1;
      nlen = snprintf(buf2 + len, sizeof(buf2) - len, (cnt%2) ? "%-20s %s | " : "%-20s %s\r\n", spell_info[i].name, how_good(GET_SKILL(ch, i)));
      if (len + nlen >= sizeof(buf2) || nlen < 0)
        break;
      len += nlen;
    }
  }
  if (len >= sizeof(buf2))
    strcpy(buf2 + sizeof(buf2) - strlen(overflow) - 1, overflow); /* strcpy: OK */

  parse_at(buf2);
  page_string(ch->desc, buf2, TRUE);
}
示例#14
0
int	mag_manacost(struct char_data *ch, struct spell_info_type *sptr)
{
    return MAX(sptr->mana_max - (GET_SKILL(ch, sptr->skill)/100),
               sptr->mana_min);
}
示例#15
0
文件: save.c 项目: sean/dominionmud
/*
 * Read in a char.
 */
int fread_char( struct char_data *ch, FILE *fp )
{
  int         error_count = 0;
  char        *word;
  char        buf [ MAX_STRING_LENGTH ];
  struct affected_type *paf;
  int         sn;
  int         i;
  int         j;
  int         status;
  int         status1;
  char        *p;
  int         tmpi;
  int         num_keys;
  int         last_key = 0;
  
  char        def_sdesc  [] = "Your short description was corrupted.";
  char        def_ldesc  [] = "Your long description was corrupted.";
  char        def_desc   [] = "Your description was corrupted.";
  char        def_title  [] = "Your title was corrupted.";
  
  struct key_data key_tab [] = {
    { "ShtDsc", TRUE,  (int) &def_sdesc,	{ &GET_SHORT_DESC(ch),   NULL } },
    { "LngDsc", TRUE,  (int) &def_ldesc,	{ &GET_LONG_DESC(ch),    NULL } },
    { "Dscr",   TRUE,  (int) &def_desc,		{ &GET_DESCRIPTION(ch),  NULL } },
    { "Sx",     FALSE, SEX_MALE,		{ &GET_SEX(ch),          NULL } },
    { "Race",   FALSE, MAND,			{ &GET_RACE(ch),         NULL } },
    { "Lvl",    FALSE, MAND,			{ &GET_LEVEL(ch),        NULL } },
    { "Trst",   FALSE, 0,			{ &GET_TRUST(ch),        NULL } },
    { "HpMnMv", FALSE, MAND,			{ &GET_HIT(ch),
						  &GET_MAX_HIT(ch),
						  &GET_MANA(ch),
						  &GET_MAX_MANA(ch),
						  &GET_MOVE(ch),
						  &GET_MAX_MOVE(ch),     NULL } },
    { "Gold",   FALSE, 0,			{ &GET_GOLD(ch),         NULL } },
    { "Exp",    FALSE, MAND,			{ &GET_EXP(ch),          NULL } },
    { "Act",     FALSE, DEFLT,			{ &PLR_FLAGS(ch),        NULL } },
    { "Act2",    FALSE, DEFLT,			{ &PLR2_FLAGS(ch),       NULL } },
    { "AffdBy",  FALSE, 0,			{ &AFF_FLAGS(ch),        NULL } },
    { "AffdBy2", FALSE, 0,			{ &AFF2_FLAGS(ch),       NULL } },
    { "Pref",    FALSE, 0,			{ &PRF_FLAGS(ch),        NULL } },
    { "Pref2",   FALSE, 0,			{ &PRF2_FLAGS(ch),       NULL } },
    { "Pos",    FALSE, POS_STANDING, 		{ &GET_POS(ch),          NULL } },
    { "Prac",   FALSE, MAND,			{ &GET_PRACTICES(ch),    NULL } },
    { "PAlign",  FALSE, 0,			{ &GET_PERMALIGN(ch),    NULL } },
    { "CAlign",  FALSE, 0,			{ &GET_ALIGNMENT(ch),    NULL } },
    { "Ttle",   TRUE,  (int) &def_title,	{ &GET_TITLE(ch),        NULL } },
#if 0
    { "SavThr", FALSE, MAND,			{ &ch->saving_throw,  NULL } },
    { "Hit",    FALSE, MAND,			{ &ch->hitroll,       NULL } },
    { "Dam",    FALSE, MAND,			{ &ch->damroll,       NULL } },
    { "Armr",   FALSE, MAND,			{ &ch->armor,         NULL } },
    { "Wimp",   FALSE, 10,			{ &ch->wimpy,         NULL } },
    { "Deaf",   FALSE, 0,			{ &ch->deaf,          NULL } },
    { "Immskll",TRUE,  DEFLT,			{ &ch->pcdata->immskll,
                                                  NULL } },
    { "AtrPrm", FALSE, MAND,			{ &ch->pcdata->perm_str,
						  &ch->pcdata->perm_int,
						  &ch->pcdata->perm_wis,
						  &ch->pcdata->perm_dex,
						  &ch->pcdata->perm_con,
                                                  NULL } },
    { "AtrMd",  FALSE, MAND,			{ &ch->pcdata->mod_str,
						  &ch->pcdata->mod_int,
						  &ch->pcdata->mod_wis,
						  &ch->pcdata->mod_dex,
						  &ch->pcdata->mod_con,
                                                  NULL } },
    { "Cond",   FALSE, DEFLT,			{ &ch->pcdata->condition [0],
						  &ch->pcdata->condition [1],
						  &ch->pcdata->condition [2],
                                                  NULL } },
    { "Pglen",  FALSE, 20,			{ &ch->pcdata->pagelen,
                                                  NULL } },
    { "Playd",   FALSE, 0,			{ &ch->played,        NULL } },
#endif
    { "Paswd",   TRUE,  MAND,			{ &GET_PASSWD(ch),    NULL } },
    { "Poofin",  TRUE,  DEFLT,			{ &POOFIN(ch),        NULL } },
    { "Poofout", TRUE,  DEFLT,			{ &POOFOUT(ch),       NULL } },
    { "\0",     FALSE, 0                                                   } };
  
  for ( num_keys = 0; *key_tab [num_keys].key; )
    num_keys++;
  
  for ( ; !feof (fp) ; )
  {
    
    word = fread_word_stat( fp, &status );
    
    if ( !word )
    {
      log( "fread_char:  Error reading key.  EOF?" );
      fread_to_eol( fp );
      break;
    }
    
    /* This little diddy searches for the keyword
       from the last keyword found */
    
    for ( i = last_key;
          i < last_key + num_keys &&
                str_cmp (key_tab [i % num_keys].key, word); )
      i++;
    
    i = i % num_keys;
    
    if ( !str_cmp (key_tab [i].key, word) )
      last_key = i;
    else
      i = num_keys;
    
    if ( *key_tab [i].key )         /* Key entry found in key_tab */
    {
      if ( key_tab [i].string == SPECIFIED )
        log( "Key already specified." );
      
      /* Entry is a string */
      
      else
        if ( key_tab [i].string )
        {
          if ( ( p = fread_string( fp, (char*)&status ) ) && !status )
          {
            free( *(char **)key_tab [i].ptrs [0] );
            *(char **)key_tab [i].ptrs [0] = p;
          }
        }
      
      /* Entry is an integer */
        else
          for ( j = 0; key_tab [i].ptrs [j]; j++ )
          {
            tmpi = fread_number_stat( fp, &status );
            if ( !status )
              *(int *)key_tab [i].ptrs [j] = tmpi;
          }
      
      if ( status )
      {
        fread_to_eol( fp );
        continue;
      }
      else
        key_tab [i].string = SPECIFIED;
    }
    
    else if ( *word == '*' || !str_cmp( word, "Nm" ) )
      fread_to_eol( fp );
    
    else if ( !str_cmp( word, "End" ) )
      break;
    
    else if ( !str_cmp( word, "Room" ) )
    {
      ch->in_room = fread_number_stat( fp, &status );
      if ( !ch->in_room )
        ch->in_room = NOWHERE;
    }
    
    else if ( !str_cmp( word, "Race" ) )
    {
      i  = race_lookup( fread_string( fp, (char*)&status ) );
      
      if ( status )
        log( "Fread_char: Unknown Race." );
      else
        GET_RACE(ch) = i;
    }
    
    else if ( !str_cmp( word, "Skill" ) )
    {
      i  = fread_number_stat( fp, &status );
      sn = skill_lookup( fread_word_stat( fp, &status1 ) );
      
      if ( status || status1 )
      {
        log( "Fread_char: Error reading skill." );
        fread_to_eol( fp );
        continue;
      }
      
      if ( sn < 0 )
        log( "Fread_char: unknown skill." );
      else
        GET_SKILL(ch, sn) = i;
    }
    
    else if ( !str_cmp ( word, "Afft" ) )
    {
      
      int status;

      CREATE(paf, struct affected_type, 1);
      memset(paf, 0, sizeof( struct affected_type ));
      
      paf->type           = skill_lookup( fread_string( fp,
                                                        (char*)&status ) );
      paf->duration       = fread_number_stat( fp, &status );
      paf->modifier       = fread_number_stat( fp, &status );
      paf->location       = fread_number_stat( fp, &status );
      paf->bitvector      = fread_number_stat( fp, &status );
      paf->next           = ch->affected;
      ch->affected        = paf;
    }
    
    else
    {
示例#16
0
文件: save.c 项目: sean/dominionmud
/*
 * Write the char to the file.
 *
 * @param ch the character to be written
 * @param fp the file to write to
 */
void fwrite_char( struct char_data *ch, FILE *fp )
{
  extern struct race_data * races;
  
  struct affected_type *paf;
  int          sn, i;
  
  fprintf( fp, "#%s\n", IS_NPC( ch ) ? "MOB" : "PLAYER"		);
  
  fprintf( fp, "Name        %s~\n",	GET_NAME(ch)			);
  fprintf( fp, "ShtDsc      %s~\n",	GET_SHORT_DESC(ch) ?
	   GET_SHORT_DESC(ch) : "" );
  fprintf( fp, "LngDsc      %s~\n",	GET_LONG_DESC(ch) ?
	   GET_LONG_DESC(ch) : "" );
  fprintf( fp, "Dscr        %s~\n",	GET_DESCRIPTION(ch) ?
	   GET_DESCRIPTION(ch) : "" );
  // fprintf( fp, "Prmpt       %s~\n",	ch->pcdata->prompt	);
  fprintf( fp, "Sx          %d\n",	GET_SEX(ch)			);
  fprintf( fp, "Race        %s~\n",	races[ (int)GET_RACE(ch) ].name );
  fprintf( fp, "Lvl         %d\n",	GET_LEVEL(ch)			);
  fprintf( fp, "Trst        %d\n",	GET_TRUST(ch)			);
  /*
    fprintf( fp, "Playd       %ld\n",
    GET_PLAYED(ch) + (int)( time( 0 ) - GET_LOGON(ch) )		);
  */
  // fprintf( fp, "Note        %ld\n",   (unsigned long)ch->last_note );
  fprintf( fp, "Room        %ld\n",
	   (  ch->in_room == NOWHERE && ch->was_in_room )
	   ? ch->was_in_room : ch->in_room );
  
  fprintf( fp, "HpMnMv      %d %d %d %d %d %d\n",
	   GET_HIT(ch), GET_MAX_HIT(ch),
	   GET_MANA(ch), GET_MAX_MANA(ch),
	   GET_MOVE(ch), GET_MAX_MOVE(ch) );
  fprintf( fp, "Gold        %ld\n",	GET_GOLD(ch)		);
  fprintf( fp, "Exp         %ld\n",	GET_EXP(ch)		);
  fprintf( fp, "Act         %lld\n",  PLR_FLAGS(ch)           );
  fprintf( fp, "Act2        %lld\n",  PLR2_FLAGS(ch)          );
  fprintf( fp, "Pref        %lld\n",  PRF_FLAGS(ch)		);
  fprintf( fp, "Pref2       %lld\n",  PRF2_FLAGS(ch)		);
  fprintf( fp, "AffdBy      %lld\n",	AFF_FLAGS(ch)		);
  fprintf( fp, "AffdBy2     %lld\n",	AFF2_FLAGS(ch)		);
  /* Bug fix from Alander */
  fprintf( fp, "Pos         %d\n",
	   GET_POS(ch) == POS_FIGHTING ? POS_STANDING : GET_POS(ch) );
  fprintf( fp, "Prac        %d\n",    GET_PRACTICES(ch)       );
  fprintf( fp, "PAlign      %d\n",	GET_PERMALIGN(ch)	);
  fprintf( fp, "CAlign      %d\n",	GET_ALIGNMENT(ch)	);
  fprintf( fp, "SavThr      " );
  for ( i = 0; i < NUM_SAVES; i++ )
    fprintf( fp, "%d%s",    GET_SAVE(ch, i), (i != NUM_SAVES-1 ? ", " : "\n")	);
  fprintf( fp, "Hitroll     %d\n",	GET_HITROLL(ch)		);
  fprintf( fp, "Damroll     %d\n",	GET_DAMROLL(ch)		);
  fprintf( fp, "Armr        " );
  for ( i = 0; i < ARMOR_LIMIT; i++ )
    fprintf( fp, "%d%s",   GET_AC(ch, i), (i != ARMOR_LIMIT-1 ? ", " : "\n") );
  fprintf( fp, "Wimp        %d\n",	GET_WIMP_LEV(ch)	);
  
  if ( IS_NPC( ch ) ) {
    fprintf( fp, "Vnum        %ld\n",	GET_MOB_VNUM(ch)	);
  } else {
    fprintf( fp, "Paswd       %s~\n",	GET_PASSWD(ch)		);
    fprintf( fp, "Poofin      %s~\n",	POOFIN(ch) ?
	     POOFIN(ch) : "" );
    fprintf( fp, "Poofout     %s~\n",	POOFOUT(ch) ?
	     POOFOUT(ch) : "" );
    fprintf( fp, "Ttle        %s~\n",	GET_TITLE(ch) ?
	     GET_TITLE(ch) : "" );
    fprintf( fp, "AtrPrm      %d/%d %d %d %d %d %d %d\n",
	     ch->real_abils.str,
	     ch->real_abils.str_add,
	     ch->real_abils.intel,
	     ch->real_abils.wis,
	     ch->real_abils.dex,
	     ch->real_abils.con,
	     ch->real_abils.cha,
	     ch->real_abils.will );
    
    fprintf( fp, "AtrMd       %d/%d %d %d %d %d %d %d\n",
	     ch->aff_abils.str, 
	     ch->aff_abils.str_add, 
	     ch->aff_abils.intel, 
	     ch->aff_abils.wis, 
	     ch->aff_abils.dex, 
	     ch->aff_abils.con, 
	     ch->aff_abils.cha, 
	     ch->aff_abils.will );
    
    fprintf( fp, "Conditions  " );
    for ( i = 0; i < MAX_COND; i++ )
      fprintf( fp, "%d%s", GET_COND(ch, i), (i != MAX_COND-1 ? ", " : "\n") );
    
    fprintf( fp, "Addictions  " );
    for ( i = 0; i < MAX_COND; i++ )
      fprintf( fp, "%d%s", GET_ADDICT(ch, i), (i != MAX_COND-1 ? ", " : "\n") );
    
    for ( sn = 0; sn < MAX_SKILLS; sn++ ) {
      if ( skill_name( sn ) &&
           strcmp( skill_name( sn ), "!UNUSED!" ) &&
           GET_SKILL(ch, sn) > 0 ) {
	fprintf( fp, "Skill       %d '%s'\n",
		 GET_SKILL(ch, sn),
		 skill_name( sn ) );
      }
    }
  }
  
  for ( paf = ch->affected; paf; paf = paf->next )  {
    fprintf( fp, "Afft       %18s~ %3d %3d %3d %lld\n",
	     skill_name( paf->type ),
	     paf->duration,
	     paf->modifier,
	     paf->location,
	     paf->bitvector );
  }
  
  for ( paf = ch->affected2; paf; paf = paf->next )  {
    fprintf( fp, "Afft2       %18s~ %3d %3d %3d %lld\n",
	     skill_name( paf->type ),
	     paf->duration,
	     paf->modifier,
	     paf->location,
	     paf->bitvector );
  }
  
  fprintf( fp, "End\n\n" );
  return;
}
示例#17
0
/* the main engine of charm spell, and similar */
void effect_charm(struct char_data *ch, struct char_data *victim,
        int spellnum) {
  struct affected_type af;
  int elf_bonus = 0;

  if (!IS_NPC(victim) && (GET_RACE(victim) == RACE_ELF || //elven enchantment resistance
          GET_RACE(victim) == RACE_H_ELF)) // added check for IS_NPC because NPCRACE_HUMAN == RACE_ELF and NPCRACE_ABERRATION == RACE_H_ELF
    elf_bonus += 2;

  if (victim == ch)
    send_to_char(ch, "You like yourself even better!\r\n");

  else if (MOB_FLAGGED(victim, MOB_NOCHARM)) {
    send_to_char(ch, "Your victim doesn't seem vulnerable to this "
            "enchantments!\r\n");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);
  }
  
  else if (IS_AFFECTED(victim, AFF_MIND_BLANK)) {
    send_to_char(ch, "Your victim is protected from this "
            "enchantment!\r\n");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);
  }
  
  else if (AFF_FLAGGED(ch, AFF_CHARM))
    send_to_char(ch, "You can't have any followers of your own!\r\n");

  else if (AFF_FLAGGED(victim, AFF_CHARM))
    send_to_char(ch, "Your victim is already charmed.\r\n");

  else if (spellnum == SPELL_CHARM && (CASTER_LEVEL(ch) < GET_LEVEL(victim) ||
          GET_LEVEL(victim) >= 8))
    send_to_char(ch, "Your victim is too powerful.\r\n");

  else if ((spellnum == SPELL_DOMINATE_PERSON || spellnum == SPELL_MASS_DOMINATION) &&
          CASTER_LEVEL(ch) < GET_LEVEL(victim))
    send_to_char(ch, "Your victim is too powerful.\r\n");

    /* player charming another player - no legal reason for this */
  else if (!CONFIG_PK_ALLOWED && !IS_NPC(victim))
    send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n");

  else if (circle_follow(victim, ch))
    send_to_char(ch, "Sorry, following in circles is not allowed.\r\n");

  else if (mag_resistance(ch, victim, 0)) {
    send_to_char(ch, "You failed to penetrate the spell resistance!");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);
  }
  else if (mag_savingthrow(ch, victim, SAVING_WILL, elf_bonus)) {
    send_to_char(ch, "Your victim resists!\r\n");
    if (IS_NPC(victim))
      hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE);

  } else {
    /* slippery mind gives a second save */
    if (!IS_NPC(victim) && GET_SKILL(victim, SKILL_SLIPPERY_MIND)) {
      increase_skill(victim, SKILL_SLIPPERY_MIND);
      send_to_char(victim, "\tW*Slippery Mind*\tn  ");
      if (mag_savingthrow(ch, victim, SAVING_WILL, 0)) {
        return;
      }
    }

    if (victim->master)
      stop_follower(victim);

    add_follower(victim, ch);

    new_affect(&af);
    if (spellnum == SPELL_CHARM)
      af.spell = SPELL_CHARM;
    if (spellnum == SPELL_CHARM_ANIMAL)
      af.spell = SPELL_CHARM_ANIMAL;
    else if (spellnum == SPELL_DOMINATE_PERSON)
      af.spell = SPELL_DOMINATE_PERSON;
    else if (spellnum == SPELL_MASS_DOMINATION)
      af.spell = SPELL_MASS_DOMINATION;
    af.duration = 100;
    if (GET_CHA_BONUS(ch))
      af.duration += GET_CHA_BONUS(ch) * 4;
    SET_BIT_AR(af.bitvector, AFF_CHARM);
    affect_to_char(victim, &af);

    act("Isn't $n just such a nice fellow?", FALSE, ch, 0, victim, TO_VICT);
    //    if (IS_NPC(victim))
    //      REMOVE_BIT_AR(MOB_FLAGS(victim), MOB_SPEC);
  }
  // should never get here
}
示例#18
0
void
save_player_to_file(struct creature *ch, const char *path)
{
    void expire_old_grievances(struct creature *);
    // Save vital statistics
    FILE *ouf;
    char *tmp_path;
    struct alias_data *cur_alias;
    int idx;
    int hit = GET_HIT(ch), mana = GET_MANA(ch), move = GET_MOVE(ch);

    tmp_path = tmp_sprintf("%s.tmp", path);
    ouf = fopen(tmp_path, "w");

    if (!ouf) {
        fprintf(stderr, "Unable to open XML player file for save.[%s] (%s)\n",
            path, strerror(errno));
        return;
    }
    struct aff_stash *aff_stash = stash_creature_affects(ch);

    expire_old_grievances(ch);

    fprintf(ouf, "<creature name=\"%s\" idnum=\"%ld\">\n",
        GET_NAME(ch), ch->char_specials.saved.idnum);

    fprintf(ouf,
        "<points hit=\"%d\" mana=\"%d\" move=\"%d\" maxhit=\"%d\" maxmana=\"%d\" maxmove=\"%d\"/>\n",
        ch->points.hit, ch->points.mana, ch->points.move, ch->points.max_hit,
        ch->points.max_mana, ch->points.max_move);

    fprintf(ouf, "<money gold=\"%" PRId64 "\" cash=\"%" PRId64 "\" xp=\"%d\"/>\n",
        ch->points.gold, ch->points.cash, ch->points.exp);

    fprintf(ouf,
        "<stats level=\"%d\" sex=\"%s\" race=\"%s\" height=\"%d\" weight=\"%f\" align=\"%d\"/>\n",
        GET_LEVEL(ch), genders[(int)GET_SEX(ch)],
        race_name_by_idnum(GET_RACE(ch)), GET_HEIGHT(ch), GET_WEIGHT(ch),
        GET_ALIGNMENT(ch));

    fprintf(ouf, "<class name=\"%s\"", class_names[GET_CLASS(ch)]);
    if (GET_REMORT_CLASS(ch) != CLASS_UNDEFINED)
        fprintf(ouf, " remort=\"%s\"", class_names[GET_REMORT_CLASS(ch)]);
    if (GET_REMORT_GEN(ch) > 0)
        fprintf(ouf, " gen=\"%d\"", GET_REMORT_GEN(ch));

    if (IS_CYBORG(ch)) {
        if (GET_OLD_CLASS(ch) != -1)
            fprintf(ouf, " subclass=\"%s\"",
                borg_subchar_class_names[GET_OLD_CLASS(ch)]);
        if (GET_TOT_DAM(ch))
            fprintf(ouf, " total_dam=\"%d\"", GET_TOT_DAM(ch));
        if (GET_BROKE(ch))
            fprintf(ouf, " broken=\"%d\"", GET_BROKE(ch));
    }
    if (GET_CLASS(ch) == CLASS_MAGE &&
        GET_SKILL(ch, SPELL_MANA_SHIELD) > 0) {
        fprintf(ouf, " manash_low=\"%ld\" manash_pct=\"%ld\"",
            ch->player_specials->saved.mana_shield_low,
            ch->player_specials->saved.mana_shield_pct);
    }
    fprintf(ouf, "/>\n");

    fprintf(ouf,
        "<time birth=\"%ld\" death=\"%ld\" played=\"%ld\" last=\"%ld\"/>\n",
        ch->player.time.birth, ch->player.time.death, ch->player.time.played,
        ch->player.time.logon);

    fprintf(ouf,
        "<carnage pkills=\"%d\" akills=\"%d\" mkills=\"%d\" deaths=\"%d\" reputation=\"%d\"",
        GET_PKILLS(ch), GET_ARENAKILLS(ch), GET_MOBKILLS(ch),
        GET_PC_DEATHS(ch), ch->player_specials->saved.reputation);
    fprintf(ouf, "/>\n");

    fprintf(ouf,
        "<attr str=\"%d\" int=\"%d\" wis=\"%d\" dex=\"%d\" con=\"%d\" cha=\"%d\"/>\n",
            ch->real_abils.str, ch->real_abils.intel, ch->real_abils.wis,
            ch->real_abils.dex, ch->real_abils.con, ch->real_abils.cha);

    fprintf(ouf, "<condition hunger=\"%d\" thirst=\"%d\" drunk=\"%d\"/>\n",
        GET_COND(ch, FULL), GET_COND(ch, THIRST), GET_COND(ch, DRUNK));

    fprintf(ouf, "<player wimpy=\"%d\" lp=\"%d\" clan=\"%d\"/>\n",
        GET_WIMP_LEV(ch), GET_LIFE_POINTS(ch), GET_CLAN(ch));

    if (ch->desc)
        ch->player_specials->desc_mode = ch->desc->input_mode;
    if (ch->player_specials->rentcode == RENT_CREATING ||
        ch->player_specials->rentcode == RENT_REMORTING) {
        fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" "
            "currency=\"%d\" state=\"%s\"/>\n",
            ch->player_specials->rentcode, ch->player_specials->rent_per_day,
            ch->player_specials->rent_currency,
            desc_modes[(int)ch->player_specials->desc_mode]);
    } else {
        fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" currency=\"%d\"/>\n",
            ch->player_specials->rentcode, ch->player_specials->rent_per_day,
            ch->player_specials->rent_currency);
    }
    fprintf(ouf, "<home town=\"%d\" homeroom=\"%d\" loadroom=\"%d\"/>\n",
        GET_HOME(ch), GET_HOMEROOM(ch), GET_LOADROOM(ch));

    fprintf(ouf, "<quest");
    if (GET_QUEST(ch))
        fprintf(ouf, " current=\"%d\"", GET_QUEST(ch));
    if (GET_LEVEL(ch) >= LVL_IMMORT)
        fprintf(ouf, " allowance=\"%d\"", GET_QUEST_ALLOWANCE(ch));
    if (GET_IMMORT_QP(ch) != 0)
        fprintf(ouf, " points=\"%d\"", GET_IMMORT_QP(ch));
    fprintf(ouf, "/>\n");

    fprintf(ouf, "<bits flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\"/>\n",
        ch->char_specials.saved.act, ch->player_specials->saved.plr2_bits);
    if (PLR_FLAGGED(ch, PLR_FROZEN)) {
        fprintf(ouf, "<frozen thaw_time=\"%d\" freezer_id=\"%d\"/>\n",
            ch->player_specials->thaw_time, ch->player_specials->freezer_id);
    }

    fprintf(ouf, "<prefs flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" tongue=\"%s\"/>\n",
        ch->player_specials->saved.pref, ch->player_specials->saved.pref2,
        tongue_name(GET_TONGUE(ch)));

    fprintf(ouf, "<affects flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" flag3=\"%" PRIx32 "\"/>\n",
        ch->char_specials.saved.affected_by,
        ch->char_specials.saved.affected2_by,
        ch->char_specials.saved.affected3_by);

    for (idx = 0; idx < MAX_WEAPON_SPEC; idx++) {
        if (GET_WEAP_SPEC(ch, idx).level > 0)
            fprintf(ouf, "<weaponspec vnum=\"%d\" level=\"%d\"/>\n",
                GET_WEAP_SPEC(ch, idx).vnum,
                GET_WEAP_SPEC(ch, idx).level);
    }

    if (GET_TITLE(ch) && *GET_TITLE(ch)) {
        fprintf(ouf, "<title>%s</title>\n", xmlEncodeTmp(GET_TITLE(ch)));
    }

    if (GET_LEVEL(ch) >= 50) {
        fprintf(ouf, "<immort badge=\"%s\" qlog=\"%d\" invis=\"%d\"/>\n",
            xmlEncodeSpecialTmp(BADGE(ch)), GET_QLOG_LEVEL(ch),
            GET_INVIS_LVL(ch));
        if (POOFIN(ch) && *POOFIN(ch))
            fprintf(ouf, "<poofin>%s</poofin>\n", xmlEncodeTmp(POOFIN(ch)));
        if (POOFOUT(ch) && *POOFOUT(ch))
            fprintf(ouf, "<poofout>%s</poofout>\n", xmlEncodeTmp(POOFOUT(ch)));
    }
    if (ch->player.description && *ch->player.description) {
        fprintf(ouf, "<description>%s</description>\n",
            xmlEncodeTmp(tmp_gsub(tmp_gsub(ch->player.description, "\r\n",
                        "\n"), "\r", "")));
    }
    for (cur_alias = ch->player_specials->aliases; cur_alias;
        cur_alias = cur_alias->next)
        fprintf(ouf, "<alias type=\"%d\" alias=\"%s\" replace=\"%s\"/>\n",
            cur_alias->type, xmlEncodeSpecialTmp(cur_alias->alias),
            xmlEncodeSpecialTmp(cur_alias->replacement));

    for (struct affected_type *cur_aff = aff_stash->saved_affs;
         cur_aff;
         cur_aff = cur_aff->next)
        fprintf(ouf,
            "<affect type=\"%d\" duration=\"%d\" modifier=\"%d\" location=\"%d\" level=\"%d\" instant=\"%s\" affbits=\"%lx\" index=\"%d\" owner=\"%ld\"/>\n",
            cur_aff->type, cur_aff->duration, cur_aff->modifier,
            cur_aff->location, cur_aff->level,
            (cur_aff->is_instant) ? "yes" : "no", cur_aff->bitvector,
            cur_aff->aff_index, cur_aff->owner);

    if (!IS_IMMORT(ch)) {
        for (idx = 0; idx < MAX_SKILLS; idx++)
            if (ch->player_specials->saved.skills[idx] > 0)
                fprintf(ouf, "<skill name=\"%s\" level=\"%d\"/>\n",
                    spell_to_str(idx), GET_SKILL(ch, idx));
        write_tongue_xml(ch, ouf);
        for (GList * it = GET_RECENT_KILLS(ch); it; it = it->next) {
            struct kill_record *kill = it->data;
            fprintf(ouf, "<recentkill vnum=\"%d\" times=\"%d\"/>\n",
                kill->vnum, kill->times);
        }
        for (GList * it = GET_GRIEVANCES(ch); it; it = it->next) {
            struct grievance *grievance = it->data;
            fprintf(ouf,
                "<grievance time=\"%lu\" player=\"%d\" reputation=\"%d\" kind=\"%s\"/>\n",
                (long unsigned)grievance->time, grievance->player_id,
                grievance->rep, grievance_kind_descs[grievance->grievance]);
        }
    }

    
    if (IS_PC(ch) && ch->player_specials->tags) {
        GHashTableIter iter;
        char *key;

        g_hash_table_iter_init(&iter, ch->player_specials->tags);

        while (g_hash_table_iter_next(&iter, (gpointer *)&key, NULL)) {
            fprintf(ouf, "<tag tag=\"%s\"/>\n", key);
        }
    }

    fprintf(ouf, "</creature>\n");
    fclose(ouf);

    // on success, move temp file on top of the old file
    rename(tmp_path, path);

    restore_creature_affects(ch, aff_stash);
    free(aff_stash);

    GET_HIT(ch) = MIN(GET_MAX_HIT(ch), hit);
    GET_MANA(ch) = MIN(GET_MAX_MANA(ch), mana);
    GET_MOVE(ch) = MIN(GET_MAX_MOVE(ch), move);
}
示例#19
0
文件: races.c 项目: Calebros/aol
void race_affects(struct char_data *ch)
{
    int race;
    struct affected_type af;

    extern void affect_join(struct char_data *c, struct affected_type *a,
                            bool ad, bool avg, bool mod, bool avgmod);

    race = GET_RACE(ch);

    switch(race) {

    case RACE_HYLAR:
    case RACE_DAEWAR:
    case RACE_NEIDAR:
        af.type = SPELL_INFRAVISION;
        af.duration = -1;
        af.modifier = 0;
        af.location = APPLY_NONE;
        af.bitvector = AFF_INFRAVISION;
        affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE);

        if ( GET_SKILL(ch, SKILL_NATURAL_HARDINESS) < 60 ) {
            SET_SKILL(ch, SKILL_NATURAL_HARDINESS, 60);
        }
        break;

    case RACE_SILVANESTI:
    case RACE_QUALINESTI:
    case RACE_KAGONESTI:
    case RACE_HALFELVEN:
    case RACE_GNOME:
        af.type = SPELL_INFRAVISION;
        af.duration = -1;
        af.modifier = 0;
        af.location = APPLY_NONE;
        af.bitvector = AFF_INFRAVISION;
        affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE);
        break;

    case RACE_MINOTAUR:

        if ( GET_SKILL(ch, SKILL_GORE) < 60 ) {
            SET_SKILL(ch, SKILL_GORE, 60);
        }

//  GET_AC(ch) -= 12;
        break;

    case RACE_KENDER:
        af.type = SPELL_INFRAVISION;
        af.duration = -1;
        af.modifier = 0;
        af.location = APPLY_NONE;
        af.bitvector = AFF_INFRAVISION;
        affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE);

        if ( GET_SKILL(ch, SKILL_HIDE) < 60 ) {
            SET_SKILL(ch, SKILL_HIDE, 60);
        }
        if ( GET_SKILL(ch, SKILL_SNEAK) < 60 ) {
            SET_SKILL(ch, SKILL_SNEAK, 60);
        }
        if ( GET_SKILL(ch, SKILL_PICK_LOCK) < 60 ) {
            SET_SKILL(ch, SKILL_PICK_LOCK, 60);
        }

        if ( GET_SKILL(ch, SKILL_STEAL) < 60 ) {
            SET_SKILL(ch, SKILL_STEAL, 60);
        }

        break;

    default:
        break;
    }
}
示例#20
0
void medit_parse(struct descriptor_data *d, char *arg)
{

    int number;
    int mob_number;  // the RNUM

    switch(d->edit_mode)
    {
    case MEDIT_CONFIRM_EDIT:
        /* if player hits 'Y' then edit mob */
        switch (*arg) {
        case 'y':
        case 'Y':
            medit_disp_menu(d);
            break;
        case 'n':
        case 'N':
            STATE(d) = CON_PLAYING;
            /* free up the editing mob */
            if (d->edit_mob)
                Mem->DeleteCh(d->edit_mob);
            d->edit_mob = NULL;
            d->edit_number = 0;
            PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
            break;
        default:
            send_to_char("That's not a valid choice!\r\n", CH);
            send_to_char("Do you wish to edit it?\r\n", CH);
            break;
        }
        break;                      /* end of MEDIT_CONFIRM_EDIT */

    case MEDIT_CONFIRM_SAVESTRING:
        switch(*arg) {
        case 'y':
        case 'Y':
            // first write to the internal tables
            if (!from_ip_zone(d->edit_number)) {
                sprintf(buf,"%s wrote new mob #%ld",
                        GET_CHAR_NAME(d->character), d->edit_number);
                mudlog(buf, d->character, LOG_WIZLOG, TRUE);
            }
            mob_number = real_mobile(d->edit_number);
            if (mob_number > 0) {
                // first we go through the entire list of mobs to find out
                // which are pointing to this prototype; if it is, it gets
                // replaced
                struct char_data *i, *temp;
                int c;
                for (i = character_list; i; i = i->next) {
                    if (mob_number == i->nr) {
                        // alloc a temp mobile
                        temp = Mem->GetCh();
                        *temp = *i;
                        *i = *d->edit_mob;
                        /* copy game-time dependent vars over */
                        i->in_room = temp->in_room;
                        i->nr = mob_number;
                        i->affected = temp->affected;
                        i->carrying = temp->carrying;
                        i->cyberware = temp->cyberware;
                        i->bioware = temp->bioware;
                        // any eq worn
                        for (c = 0; c < NUM_WEARS; ++c)
                            i->equipment[c] = temp->equipment[c];
                        i->next_in_room = temp->next_in_room;
                        i->next = temp->next;
                        i->next_fighting = temp->next_fighting;
                        i->followers = temp->followers;
                        i->master = temp->master;
                        i->char_specials.fighting = temp->char_specials.fighting;
                        i->char_specials.hunting = temp->char_specials.hunting;
                        i->mob_specials.last_direction = temp->mob_specials.last_direction;
                        i->mob_specials.memory = temp->mob_specials.memory;
                        i->mob_specials.wait_state = temp->mob_specials.wait_state;
                        Mem->ClearCh(temp);
                    } // end if statement

                } // end for loop

                // now you can free the old prototype and put in the new one
                if (mob_proto[mob_number].player.physical_text.keywords)
                    delete [] mob_proto[mob_number].player.physical_text.keywords;
                if (mob_proto[mob_number].player.title)
                    delete [] mob_proto[mob_number].player.title;
                if (mob_proto[mob_number].player.physical_text.name)
                    delete [] mob_proto[mob_number].player.physical_text.name;
                if (mob_proto[mob_number].player.physical_text.room_desc)
                    delete [] mob_proto[mob_number].player.physical_text.room_desc;
                if (mob_proto[mob_number].player.physical_text.look_desc)
                    delete [] mob_proto[mob_number].player.physical_text.look_desc;
                if (mob_proto[mob_number].mob_specials.arrive)
                    delete [] mob_proto[mob_number].mob_specials.arrive;
                if (mob_proto[mob_number].mob_specials.leave)
                    delete [] mob_proto[mob_number].mob_specials.leave;


                mob_proto[mob_number] = *d->edit_mob;
                mob_proto[mob_number].nr = mob_number;

            } else {  // if not, we need to make a new spot in the list
                int             counter;
                int             found = FALSE;

                struct char_data *new_mob_proto;
                struct index_data *new_mob_index;
                struct char_data *temp_mob;

                // two because you are adding one and you need one over
                new_mob_index = new struct index_data[top_of_mobt + 2];
                new_mob_proto = new struct char_data[top_of_mobt + 2];
                // count through the tables
                for (counter = 0; counter < top_of_mobt + 1; counter++) {
                    /* if we haven't found it */
                    if (!found) {
                        /* check if current virtual is bigger than our virtual */
                        if (MOB_VNUM_RNUM(counter) > d->edit_number) {
                            /* eureka. insert now */
                            /*---------*/
                            new_mob_index[counter].vnum = d->edit_number;
                            new_mob_index[counter].number = 0;
                            new_mob_index[counter].func = NULL;
                            /*---------*/
                            new_mob_proto[counter] = *(d->edit_mob);
                            new_mob_proto[counter].in_room = NOWHERE;
                            /* it is now safe (and necessary!) to assign real number to
                             * the edit_mob, which has been -1 all this time */
                            d->edit_mob->nr = counter;
                            /* and assign to prototype as well */
                            new_mob_proto[counter].nr = counter;
                            found = TRUE;
                            /* insert the other proto at this point */
                            new_mob_index[counter + 1] = mob_index[counter];
                            new_mob_proto[counter + 1] = mob_proto[counter];
                            new_mob_proto[counter + 1].nr = counter + 1;
                        } else {
                            /* just copy from old to new, no num change */
                            new_mob_proto[counter] = mob_proto[counter];
                            new_mob_index[counter] = mob_index[counter];
                        }

                    } else { // if !found else
                        /* we HAVE already found it.. therefore copy to mobile + 1 */
                        new_mob_index[counter + 1] = mob_index[counter];
                        new_mob_proto[counter + 1] = mob_proto[counter];
                        new_mob_proto[counter + 1].nr = counter + 1;
                    }
                } // for loop through list


                /* if we STILL haven't found it, means the mobile was > than all
                * the other mobs.. so insert at end */
                if (!found) {
                    new_mob_index[top_of_mobt + 1].vnum = d->edit_number;
                    new_mob_index[top_of_mobt + 1].number = 0;
                    new_mob_index[top_of_mobt + 1].func = NULL;

                    clear_char(new_mob_proto + top_of_mobt + 1);
                    new_mob_proto[top_of_mobt + 1] = *(d->edit_mob);
                    new_mob_proto[top_of_mobt + 1].in_room = NOWHERE;
                    new_mob_proto[top_of_mobt + 1].nr = top_of_mobt + 1;
                    /* it is now safe (and necessary!) to assign real number to
                     * the edit_mob, which has been -1 all this time */
                    d->edit_mob->nr = top_of_mobt + 1;
                }
                top_of_mobt++;

                /* we also have to renumber all the mobiles currently    *
                *  existing in the world. This is because when I start   *
                * extracting mobiles, bad things will happen!           */
                for (temp_mob = character_list; temp_mob; temp_mob = temp_mob->next)
                    if (GET_MOB_RNUM (temp_mob) >= d->edit_mob->nr)
                        GET_MOB_RNUM (temp_mob)++;

                /* free and replace old tables */
                delete [] mob_proto;
                delete [] mob_index;
                mob_proto = new_mob_proto;
                mob_index = new_mob_index;

                /* RENUMBER ZONE TABLES HERE, only              *
                *   because I ADDED a mobile!                   *
                *   This code shamelessly ripped off from db.c */

                int zone, cmd_no;
                for (zone = 0; zone <= top_of_zone_table; zone++)
                    for (cmd_no = 0; cmd_no < zone_table[zone].num_cmds; cmd_no++) {
                        switch (ZCMD.command) {
                        case 'M':
                            ZCMD.arg1 = (ZCMD.arg1 >= d->edit_mob->nr ? ZCMD.arg1 + 1 : ZCMD.arg1);
                            break;
                        }

                    }

            } // finally done putting the mobile into memory

            send_to_char("Writing mobile to disk...", CH);
            write_mobs_to_disk(d->character->player_specials->saved.zonenum);

            // again, here we don't delete it cause we don't want to end up
            // deleting the strings from the prototypes
            if (d->edit_mob)
                Mem->ClearCh(d->edit_mob);
            d->edit_mob = NULL;
            STATE(d) = CON_PLAYING;
            PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
            send_to_char("Done.\r\n", d->character);
            break;
        case 'n':
        case 'N':
            send_to_char("Mobile not saved, aborting.\r\n", d->character);
            STATE(d) = CON_PLAYING;
            // complete nuke
            if (d->edit_mob)
                Mem->DeleteCh(d->edit_mob);
            d->edit_mob = NULL;
            d->edit_number = 0;
            d->edit_zone = 0;
            PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
            break;
        default:
            send_to_char("Invalid choice!\r\n", d->character);
            send_to_char("Do you wish to save this mobile internally?\r\n", d->character);
            break;
        }

        break;

    case MEDIT_MAIN_MENU:
        switch (*arg) {
        case 'q':
        case 'Q':
            d->edit_mode = MEDIT_CONFIRM_SAVESTRING;
            medit_parse(d, "y");
            break;
        case 'x':
        case 'X':
            d->edit_mode = MEDIT_CONFIRM_SAVESTRING;
            medit_parse(d, "n");
            break;
        case '1':
            send_to_char("Enter keywords:", CH);
            d->edit_mode = MEDIT_EDIT_NAMELIST;
            break;
        case '2':
            send_to_char("Enter name:", CH);
            d->edit_mode = MEDIT_SHORT_DESCR;
            break;
        case '3':
            send_to_char("Enter room description:", CH);
            d->edit_mode = MEDIT_REG_DESCR;
            d->str = new (char *);
            if (!d->str) {
                mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
                shutdown();
            }

            *(d->str) = NULL;
            d->max_str = MAX_REG_DESC_LENGTH;
            d->mail_to = 0;
            break;
        case '4':
            // go to modify.cc
            send_to_char("Enter look description:\r\n", CH);
            d->edit_mode = MEDIT_LONG_DESCR;
            d->str = new (char *);
            if (!d->str) {
                mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
                shutdown();
            }

            *(d->str) = NULL;
            d->max_str = MAX_MESSAGE_LENGTH;
            d->mail_to = 0;
            break;
        case '5':
            medit_disp_mobflags_menu(d);
            d->edit_mode = MEDIT_MOB_FLAGS;
            break;
        case '6':
            medit_disp_affected_menu(d);
            d->edit_mode = MEDIT_AFF_FLAGS;
            break;
        case '8':
            send_to_char("Enter average nuyen: ", CH);
            d->edit_mode = MEDIT_NUYEN;
            break;
        case '9':
            send_to_char("Enter bonus karma points: ", CH);
            d->edit_mode = MEDIT_EXPERIENCE;
            break;
        case 'a':
            medit_disp_att_menu(d);
            d->edit_mode = MEDIT_ATTRIBUTES;
            break;
        case 'b':
            send_to_char("Enter level: ", CH);
            d->edit_mode = MEDIT_LEVEL;
            break;
        case 'c':
            send_to_char("Enter ballistic armor points: ", CH);
            d->edit_mode = MEDIT_BALLISTIC;
            break;
        case 'd':
            send_to_char("Enter impact armor points: ", CH);
            d->edit_mode = MEDIT_IMPACT;
            break;
        case 'e':
            send_to_char("Enter max physical points: ", CH);
            d->edit_mode = MEDIT_PHYSICAL;
            break;
        case 'f':
            send_to_char("Enter max mental points: ", CH);
            d->edit_mode = MEDIT_MENTAL;
            break;
        case 'g':
            medit_disp_pos_menu(d);
            send_to_char("Enter position: ", CH);
            d->edit_mode = MEDIT_POSITION;
            break;
        case 'h':
            medit_disp_pos_menu(d);
            send_to_char("Enter default position: ", CH);
            d->edit_mode = MEDIT_DEFAULT_POSITION;
            break;
        case 'i':
            medit_disp_gender_menu(d);
            d->edit_mode = MEDIT_GENDER;
            break;
        case 'j':
            send_to_char("Enter weight (in kilograms): ", CH);
            d->edit_mode = MEDIT_WEIGHT;
            break;
        case 'k':
            send_to_char("Enter height (in centimeters): ", CH);
            d->edit_mode = MEDIT_HEIGHT;
            break;
        case 'l':
            medit_disp_class_menu(d);
            d->edit_mode = MEDIT_CLASS;
            break;
        case 'm':
            medit_disp_attack_menu(d);
            d->edit_mode = MEDIT_ATTACK_TYPE;
            break;
        case 'n':
            medit_disp_skill_menu(d);
            d->edit_mode = MEDIT_SKILLS;
            break;
        case 'o':
            send_to_char("Enter arrive text: ", CH);
            d->edit_mode = MEDIT_ARRIVE_MSG;
            break;
        case 'p':
            send_to_char("Enter leave text: ", CH);
            d->edit_mode = MEDIT_LEAVE_MSG;
            break;

        default:
            medit_disp_menu(d);
            break;
        }
        break;

    case MEDIT_EDIT_NAMELIST:
        if (MOB->player.physical_text.keywords)
            delete [] MOB->player.physical_text.keywords;
        MOB->player.physical_text.keywords = str_dup(arg);
        medit_disp_menu(d);
        break;

    case MEDIT_SHORT_DESCR:
        if (MOB->player.physical_text.name)
            delete [] MOB->player.physical_text.name;
        MOB->player.physical_text.name = str_dup(arg);
        medit_disp_menu(d);
        break;

    case MEDIT_ARRIVE_MSG:
        if (MOB->mob_specials.arrive)
            delete [] MOB->mob_specials.arrive;
        MOB->mob_specials.arrive = str_dup(arg);
        medit_disp_menu(d);
        break;

    case MEDIT_LEAVE_MSG:
        if (MOB->mob_specials.leave)
            delete [] MOB->mob_specials.leave;
        MOB->mob_specials.leave = str_dup(arg);
        medit_disp_menu(d);
        break;

    case MEDIT_REG_DESCR:
        // you should not come here
        break;

    case MEDIT_LONG_DESCR:
        // you should not come here
        break;

    case MEDIT_MOB_FLAGS:
        number = atoi(arg);
        if ((number < 0) || (number > MOB_MAX))
            medit_disp_mobflags_menu(d);
        else {
            if (number == 0) // 0 = quit
                medit_disp_menu(d);
            else {
                MOB_FLAGS(MOB).ToggleBit(number-1);
                medit_disp_mobflags_menu(d);
            }
        }
        break;

    case MEDIT_AFF_FLAGS:
        number = atoi(arg);
        if ((number < 0) || (number > AFF_MAX))
            medit_disp_affected_menu(d);
        else {
            if (number == 0) // 0 = quit
                medit_disp_menu(d);
            else {
                AFF_FLAGS(MOB).ToggleBit(number - 1);
                medit_disp_affected_menu(d);
            }
        }
        break;

    case MEDIT_NUYEN:
        number = atoi(arg);
        if ((number < 0) || (number > 999999)) {
            send_to_char("Value must range between 0 and 999999.\r\n", CH);
            send_to_char("Enter average nuyen: ", CH);
        } else {
            GET_NUYEN(MOB) = number;
            send_to_char("Enter average credstick value: ", CH);
            d->edit_mode = MEDIT_CREDSTICK;
        }
        break;

    case MEDIT_CREDSTICK:
        number = atoi(arg);
        if ((number < 0) || (number > 999999)) {
            send_to_char("Value must range between 0 and 999999.\r\n", CH);
            send_to_char("Enter average credstick value: ", CH);
        } else {
            GET_BANK(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_EXPERIENCE:
        number = atoi(arg);
        if ((number < 0) || (number > 7500)) {
            send_to_char("Value must range between 0 and 7500.\r\n", CH);
            send_to_char("Enter bonus karma points: ", CH);
        } else {
            int karma;
            if (number > (karma=calc_karma(NULL, MOB))) {
                send_to_char("Bonus karma may not be higher than actual karma.  Lowering.\r\n", CH);
                number = karma;
            }
            GET_KARMA(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_SKILLS:
        switch (*arg) {
        case '0':
            medit_disp_menu(d);
            break;
        case '1':
            medit_disp_skills(d);
            send_to_char("Enter a skill (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL1;
            break;
        case '2':
            medit_disp_skills(d);
            send_to_char("Enter a skill (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL2;
            break;
        case '3':
            medit_disp_skills(d);
            send_to_char("Enter a skill (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL3;
            break;
        case '4':
            medit_disp_skills(d);
            send_to_char("Enter a skill (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL4;
            break;
        case '5':
            medit_disp_skills(d);
            send_to_char("Enter a skill (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL5;
            break;

        default:
            medit_disp_skill_menu(d);
            break;
        }
        break; // end of MEDIT_SKILLS

    case MEDIT_SKILL1:
        number = atoi(arg);
        if ((number < 0) || (number > MAX_SKILLS)) {
            medit_disp_skills(d);
            send_to_char(CH, "Value must range between 1 and %d.\r\n", MAX_SKILLS);
            send_to_char("Enter a skill (0 to quit): ", CH);
        } else if (number == 0) { // 0 = quit
            medit_disp_skill_menu(d);
            d->edit_mode = MEDIT_SKILLS;
        } else {
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[0], 0)
            MOB->mob_specials.mob_skills[0] = number; // to adjust it
            send_to_char("Enter skill level (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL1_VAL;
        }
        break;

    case MEDIT_SKILL2:
        number = atoi(arg);
        if ((number < 0) || (number > MAX_SKILLS)) {
            medit_disp_skills(d);
            send_to_char(CH, "Value must range between 1 and %d.\r\n", MAX_SKILLS);
            send_to_char("Enter a skill (0 to quit): ", CH);
        } else if (number == 0) { // 0 = quit
            medit_disp_skill_menu(d);
            d->edit_mode = MEDIT_SKILLS;
        } else {
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[0], 0)
            MOB->mob_specials.mob_skills[0] = number; // to adjust it
            send_to_char("Enter skill level (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL2_VAL;
        }
        break;
    case MEDIT_SKILL3:
        number = atoi(arg);
        if ((number < 0) || (number > MAX_SKILLS)) {
            medit_disp_skills(d);
            send_to_char(CH, "Value must range between 1 and %d.\r\n", MAX_SKILLS);
            send_to_char("Enter a skill (0 to quit): ", CH);
        } else if (number == 0) { // 0 = quit
            medit_disp_skill_menu(d);
            d->edit_mode = MEDIT_SKILLS;
        } else {
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[0], 0)
            MOB->mob_specials.mob_skills[0] = number; // to adjust it
            send_to_char("Enter skill level (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL3_VAL;
        }
        break;
    case MEDIT_SKILL4:
        number = atoi(arg);
        if ((number < 0) || (number > MAX_SKILLS)) {
            medit_disp_skills(d);
            send_to_char(CH, "Value must range between 1 and %d.\r\n", MAX_SKILLS);
            send_to_char("Enter a skill (0 to quit): ", CH);
        } else if (number == 0) { // 0 = quit
            medit_disp_skill_menu(d);
            d->edit_mode = MEDIT_SKILLS;
        } else {
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[0], 0)
            MOB->mob_specials.mob_skills[0] = number; // to adjust it
            send_to_char("Enter skill level (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL4_VAL;
        }
        break;
    case MEDIT_SKILL5:
        number = atoi(arg);
        if ((number < 0) || (number > MAX_SKILLS)) {
            medit_disp_skills(d);
            send_to_char(CH, "Value must range between 1 and %d.\r\n", MAX_SKILLS);
            send_to_char("Enter a skill (0 to quit): ", CH);
        } else if (number == 0) { // 0 = quit
            medit_disp_skill_menu(d);
            d->edit_mode = MEDIT_SKILLS;
        } else {
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[0], 0)
            MOB->mob_specials.mob_skills[0] = number; // to adjust it
            send_to_char("Enter skill level (0 to quit): ", CH);
            d->edit_mode = MEDIT_SKILL5_VAL;
        }
        break;

    case MEDIT_SKILL1_VAL:
        number = atoi(arg);
        if ((number < 0) || (number > 50)) {
            send_to_char("Skill level must be between 1 and 50.\r\n", CH);
            send_to_char("Enter skill level: ", CH);
        } else if (number == 0) {
            MOB->mob_specials.mob_skills[0] = 0;
            MOB->mob_specials.mob_skills[1] = 0;
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        } else {
            MOB->mob_specials.mob_skills[1] = number;
            GET_SKILL(MOB, MOB->mob_specials.mob_skills[0]) = MOB->mob_specials.mob_skills[1];
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[0],
                      MOB->mob_specials.mob_skills[1]);
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        }
        break;

    case MEDIT_SKILL2_VAL:
        number = atoi(arg);
        if ((number < 0) || (number > 50)) {
            send_to_char("Skill level must be between 1 and 50.\r\n", CH);
            send_to_char("Enter skill level: ", CH);
        } else if (number == 0) {
            MOB->mob_specials.mob_skills[2] = 0;
            MOB->mob_specials.mob_skills[3] = 0;
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        } else {
            MOB->mob_specials.mob_skills[3] = number;
            GET_SKILL(MOB, MOB->mob_specials.mob_skills[2]) = MOB->mob_specials.mob_skills[3];
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[2],
                      MOB->mob_specials.mob_skills[3]);
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        }
        break;

    case MEDIT_SKILL3_VAL:
        number = atoi(arg);
        if ((number < 0) || (number > 50)) {
            send_to_char("Skill level must be between 1 and 50.\r\n", CH);
            send_to_char("Enter skill level: ", CH);
        } else if (number == 0) {
            MOB->mob_specials.mob_skills[4] = 0;
            MOB->mob_specials.mob_skills[5] = 0;
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        } else {
            MOB->mob_specials.mob_skills[5] = number;
            GET_SKILL(MOB, MOB->mob_specials.mob_skills[4]) = MOB->mob_specials.mob_skills[5];
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[4],
                      MOB->mob_specials.mob_skills[5]);
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        }
        break;

    case MEDIT_SKILL4_VAL:
        number = atoi(arg);
        if ((number < 0) || (number > 50)) {
            send_to_char("Skill level must be between 1 and 50.\r\n", CH);
            send_to_char("Enter skill level: ", CH);
        } else if (number == 0) {
            MOB->mob_specials.mob_skills[6] = 0;
            MOB->mob_specials.mob_skills[7] = 0;
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        } else {
            MOB->mob_specials.mob_skills[7] = number;
            GET_SKILL(MOB, MOB->mob_specials.mob_skills[6]) = MOB->mob_specials.mob_skills[7];
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[6],
                      MOB->mob_specials.mob_skills[7]);
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        }
        break;

    case MEDIT_SKILL5_VAL:
        number = atoi(arg);
        if ((number < 0) || (number > 50)) {
            send_to_char("Skill level must be between 1 and 50.\r\n", CH);
            send_to_char("Enter skill level: ", CH);
        } else if (number == 0) {
            MOB->mob_specials.mob_skills[8] = 0;
            MOB->mob_specials.mob_skills[9] = 0;
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        } else {
            MOB->mob_specials.mob_skills[9] = number;
            GET_SKILL(MOB, MOB->mob_specials.mob_skills[8]) = MOB->mob_specials.mob_skills[9];
            SET_SKILL(MOB, MOB->mob_specials.mob_skills[8],
                      MOB->mob_specials.mob_skills[9]);
            d->edit_mode = MEDIT_SKILLS;
            medit_disp_skill_menu(d);
        }
        break;


    case MEDIT_ATTRIBUTES:
        switch (*arg) {
        case '1':
            send_to_char("Enter body attribute: ", CH);
            d->edit_mode = MEDIT_BOD;
            break;
        case '2':
            send_to_char("Enter quickness attribute: ", CH);
            d->edit_mode = MEDIT_QUI;
            break;
        case '3':
            send_to_char("Enter strength attribute: ", CH);
            d->edit_mode = MEDIT_STR;
            break;
        case '4':
            send_to_char("Enter charisma attribute: ", CH);
            d->edit_mode = MEDIT_CHA;
            break;
        case '5':
            send_to_char("Enter intelligence attribute: ", CH);
            d->edit_mode = MEDIT_INT;
            break;
        case '6':
            send_to_char("Enter willpower attribute: ", CH);
            d->edit_mode = MEDIT_WIL;
            break;
        case '7':
            send_to_char("Enter magic attribute: ", CH);
            d->edit_mode = MEDIT_MAG;
            break;
        case 'q':
        case 'Q': // back to main menu
            medit_disp_menu(d);
            break;
        default:
            medit_disp_att_menu(d);
            break;
        }
        break;

    case MEDIT_BOD:
        number = atoi(arg);
        if ((number < 1) || (number > 50)) {
            send_to_char("Value must range between 1 and 50.\r\n", CH);
            send_to_char("Enter body attribute: ", CH);
        } else {
            GET_REAL_BOD(MOB) = number;
            MOB->real_abils.bod_index = number * 100;
            medit_disp_att_menu(d);
        }
        break;

    case MEDIT_QUI:
        number = atoi(arg);
        if ((number < 1) || (number > 50)) {
            send_to_char("Value must range between 1 and 50.\r\n", CH);
            send_to_char("Enter quickness attribute: ", CH);
        } else {
            GET_REAL_QUI(MOB) = number;
            GET_REAL_REA(MOB) = (number + GET_REAL_INT(MOB)) >> 1;
            medit_disp_att_menu(d);
        }
        break;

    case MEDIT_STR:
        number = atoi(arg);
        if ((number < 1) || (number > 50)) {
            send_to_char("Value must range between 1 and 50.\r\n", CH);
            send_to_char("Enter strength attribute: ", CH);
        } else {
            GET_REAL_STR(MOB) = number;
            medit_disp_att_menu(d);
        }
        break;

    case MEDIT_CHA:
        number = atoi(arg);
        if ((number < 1) || (number > 50)) {
            send_to_char("Value must range between 1 and 50.\r\n", CH);
            send_to_char("Enter charisma attribute: ", CH);
        } else {
            GET_REAL_CHA(MOB) = number;
            medit_disp_att_menu(d);
        }
        break;

    case MEDIT_INT:
        number = atoi(arg);
        if ((number < 1) || (number > 50)) {
            send_to_char("Value must range between 1 and 50.\r\n", CH);
            send_to_char("Enter intelligence attribute: ", CH);
        } else {
            GET_REAL_INT(MOB) = number;
            GET_REAL_REA(MOB) = (number + GET_REAL_QUI(MOB)) >> 1;
            medit_disp_att_menu(d);
        }
        break;

    case MEDIT_WIL:
        number = atoi(arg);
        if ((number < 1) || (number > 50)) {
            send_to_char("Value must range between 1 and 50.\r\n", CH);
            send_to_char("Enter willpower attribute: ", CH);
        } else {
            GET_REAL_WIL(MOB) = number;
            medit_disp_att_menu(d);
        }
        break;

    case MEDIT_MAG:
        number = atoi(arg);
        if ((number < 0) || (number > 50)) {
            send_to_char("Value must range between 0 and 50.\r\n", CH);
            send_to_char("Enter magic attribute: ", CH);
        } else {
            MOB->real_abils.mag = number * 100;
            medit_disp_att_menu(d);
        }
        break;

    case MEDIT_LEVEL:
        number = atoi(arg);
        if (number < 0) {
            send_to_char("Invalid choice.\r\n", CH);
            send_to_char("Enter level: ", CH);
        } else {
            GET_LEVEL(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_BALLISTIC:
        number = atoi(arg);
        if (number < 0) {
            send_to_char("Value must be greater than 0.\r\n", CH);
            send_to_char("Enter ballistic armor points: ", CH);
        } else {
            GET_BALLISTIC(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_IMPACT:
        number = atoi(arg);
        if (number < 0) {
            send_to_char("Value must be greater than 0.\r\n", CH);
            send_to_char("Enter impact armor points: ", CH);
        } else {
            GET_IMPACT(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_PHYSICAL:
        number = atoi(arg);
        if ((number < 0) || (number > 10)) {
            send_to_char("Value must range between 0 and 10.\r\n", CH);
            send_to_char("Enter max physical points: ", CH);
        } else {
            GET_MAX_PHYSICAL(MOB) = number * 100;
            GET_PHYSICAL(MOB) = number * 100;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_MENTAL:
        number = atoi(arg);
        if ((number < 0) || (number > 10)) {
            send_to_char("Value must range between 0 and 10.\r\n", CH);
            send_to_char("Enter max mental points: ", CH);
        } else {
            GET_MAX_MENTAL(MOB) = number * 100;
            GET_MENTAL(MOB) = number * 100;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_WEIGHT:
        number = atoi(arg);
        if (number < 0) {
            send_to_char("Value must be greater than 0.\r\n", CH);
            send_to_char("Enter weight (in kilograms): ", CH);
        } else {
            GET_WEIGHT(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_HEIGHT:
        number = atoi(arg);
        if (number < 0) {
            send_to_char("Value must be greater than 0.\r\n", CH);
            send_to_char("Enter height (in centimeters): ", CH);
        } else {
            GET_HEIGHT(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_CLASS:
        number = atoi(arg);
        if ((number < 1) || (number > NUM_MOB_CLASSES))
            medit_disp_class_menu(d);
        else {
            GET_RACE(MOB) = (number - 1);
            medit_disp_menu(d);
        }
        break;

    case MEDIT_POSITION:
        number = atoi(arg);
        if ((number < POS_MORTALLYW) || (number > POS_STANDING)) {
            send_to_char("Invalid choice.\r\nEnter position: ", CH);
            medit_disp_pos_menu(d);
        } else {
            GET_POS(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_DEFAULT_POSITION:
        number = atoi(arg);
        if ((number < POS_MORTALLYW) || (number > POS_STANDING)) {
            send_to_char("Invalid choice.\r\nEnter default position: ", CH);
            medit_disp_pos_menu(d);
        } else {
            GET_DEFAULT_POS(MOB) = number;
            medit_disp_menu(d);
        }
        break;

    case MEDIT_GENDER:
        number = atoi(arg);
        if ((number < 0) || (number > 3)) {
            send_to_char("Invalid choice.\r\n", CH);
            medit_disp_gender_menu(d);
        } else if (number != 0) // 0 = quit
            GET_SEX(MOB) = (number - 1);
        medit_disp_menu(d);
        break;

    case MEDIT_ATTACK_TYPE:
        number = atoi(arg);
        if ((number < 0) || (number > NUM_ATTACK_TYPES)) {
            send_to_char("Invalid choice.\r\n", CH);
            medit_disp_attack_menu(d);
        } else if (number != 0) // 0 = quit
            MOB->mob_specials.attack_type = number-1 + TYPE_HIT;
        medit_disp_menu(d);
        break;

    }
}
示例#21
0
void mag_objectmagic(struct char_data *ch, struct obj_data *obj,
                     char *argument)
{
    int i, k;
    struct char_data *tch = NULL, *next_tch;
    struct obj_data *tobj = NULL;

    if (!magic_enabled)
        return;

    one_argument(argument, arg);

    k = generic_find(arg, FIND_CHAR_ROOM | FIND_OBJ_INV | FIND_OBJ_ROOM |
                     FIND_OBJ_EQUIP, ch, &tch, &tobj);

    switch (GET_OBJ_TYPE(obj)) {
    case ITEM_STAFF:
        act("You tap $p three times on the ground.", FALSE, ch, obj, 0, TO_CHAR);
        if (obj->action_description)
            act(obj->action_description, FALSE, ch, obj, 0, TO_ROOM);
        else
            act("$n taps $p three times on the ground.", FALSE, ch, obj, 0, TO_ROOM);

        if (GET_OBJ_VAL(obj, 2) <= 0) {
            send_to_char("It seems powerless.\r\n", ch);
            act("Nothing seems to happen.", FALSE, ch, obj, 0, TO_ROOM);
        } else {
            GET_OBJ_VAL(obj, 2)--;
            WAIT_STATE(ch, PULSE_VIOLENCE);
            /* Level to cast spell at. */
            k = GET_OBJ_VAL(obj, 0) ? GET_OBJ_VAL(obj, 0) : DEFAULT_STAFF_LVL;

            /*
             * Problem : Area/mass spells on staves can cause crashes.
             * Solution: Remove the special nature of area/mass spells on staves.
             * Problem : People like that behavior.
             * Solution: We special case the area/mass spells here.
             */
            if (HAS_SPELL_ROUTINE(get_spell(GET_OBJ_VAL(obj, 3), __FILE__, __FUNCTION__), MAG_MASSES | MAG_AREAS)) {
                for (i = 0, tch = world[IN_ROOM(ch)].people; tch; tch = tch->next_in_room)
                    i++;
                while (i-- > 0)
                    call_magic(ch, NULL, NULL, get_spell(GET_OBJ_VAL(obj, 3), __FILE__, __FUNCTION__), k, CAST_STAFF, 0);
            } else {
                for (tch = world[IN_ROOM(ch)].people; tch; tch = next_tch) {
                    next_tch = tch->next_in_room;
                    if (ch != tch)
                        call_magic(ch, tch, NULL, get_spell(GET_OBJ_VAL(obj, 3), __FILE__, __FUNCTION__), k, CAST_STAFF, 0);
                }
            }
        }
        break;
    case ITEM_WAND:
        if (k == FIND_CHAR_ROOM) {
            if (tch == ch) {
                act("You point $p at yourself.", FALSE, ch, obj, 0, TO_CHAR);
                act("$n points $p at $mself.", FALSE, ch, obj, 0, TO_ROOM);
            } else {
                act("You point $p at $N.", FALSE, ch, obj, tch, TO_CHAR);
                if (obj->action_description)
                    act(obj->action_description, FALSE, ch, obj, tch, TO_ROOM);
                else
                    act("$n points $p at $N.", TRUE, ch, obj, tch, TO_ROOM);
            }
        } else if (tobj != NULL) {
            act("You point $p at $P.", FALSE, ch, obj, tobj, TO_CHAR);
            if (obj->action_description)
                act(obj->action_description, FALSE, ch, obj, tobj, TO_ROOM);
            else
                act("$n points $p at $P.", TRUE, ch, obj, tobj, TO_ROOM);
        } else if (IS_SET(get_spell(GET_OBJ_VAL(obj, 3), __FILE__, __FUNCTION__)->routines, MAG_AREAS | MAG_MASSES)) {
            /* Wands with area spells don't need to be pointed. */
            act("You point $p outward.", FALSE, ch, obj, NULL, TO_CHAR);
            act("$n points $p outward.", TRUE, ch, obj, NULL, TO_ROOM);
        } else {
            act("At what should $p be pointed?", FALSE, ch, obj, NULL, TO_CHAR);
            return;
        }

        if (GET_OBJ_VAL(obj, 2) <= 0) {
            send_to_char("It seems powerless.\r\n", ch);
            act("Nothing seems to happen.", FALSE, ch, obj, 0, TO_ROOM);
            return;
        }
        GET_OBJ_VAL(obj, 2)--;
        WAIT_STATE(ch, PULSE_VIOLENCE);
        if (GET_OBJ_VAL(obj, 0))
            call_magic(ch, tch, tobj, get_spell(GET_OBJ_VAL(obj, 3), __FILE__, __FUNCTION__),
                       GET_OBJ_VAL(obj, 0), CAST_WAND, 0);
        else
            call_magic(ch, tch, tobj, get_spell(GET_OBJ_VAL(obj, 3), __FILE__, __FUNCTION__),
                       DEFAULT_WAND_LVL, CAST_WAND, 0);
        break;
    case ITEM_SCROLL:
        if (*arg) {
            if (!k) {
                act("There is nothing to here to affect with $p.", FALSE,
                    ch, obj, NULL, TO_CHAR);
                return;
            }
        } else
            tch = ch;

        act("You recite $p which dissolves.", TRUE, ch, obj, 0, TO_CHAR);
        if (obj->action_description)
            act(obj->action_description, FALSE, ch, obj, NULL, TO_ROOM);
        else
            act("$n recites $p.", FALSE, ch, obj, NULL, TO_ROOM);

        WAIT_STATE(ch, PULSE_VIOLENCE);
        for (i = 1; i <= 3; i++)
            if (call_magic(ch, tch, tobj, get_spell(GET_OBJ_VAL(obj, i), __FILE__, __FUNCTION__),
                           GET_OBJ_VAL(obj, 0), CAST_SCROLL, 0) <= 0)
                break;

        if (obj != NULL)
            extract_obj(obj);
        break;
    case ITEM_POTION:
        tch = ch;
        act("You quaff $p.", FALSE, ch, obj, NULL, TO_CHAR);
        if (obj->action_description)
            act(obj->action_description, FALSE, ch, obj, NULL, TO_ROOM);
        else
            act("$n quaffs $p.", TRUE, ch, obj, NULL, TO_ROOM);

        WAIT_STATE(ch, PULSE_VIOLENCE);
        for (i = 1; i <= 3; i++)
            if (call_magic(ch, ch, NULL, get_spell(GET_OBJ_VAL(obj, i), __FILE__, __FUNCTION__),
                           GET_OBJ_VAL(obj, 0), CAST_POTION, 0) <= 0)
                break;

        if (obj != NULL)
            extract_obj(obj);
        break;
    case ITEM_SPELLBOOK:
        tch = ch;
        act("You study $p.", FALSE, ch, obj, NULL, TO_CHAR);
        if (obj->action_description)
            act(obj->action_description, FALSE, ch, obj, NULL, TO_ROOM);
        else
            act("$n studies $p.", TRUE, ch, obj, NULL, TO_ROOM);

        WAIT_STATE(ch, PULSE_VIOLENCE);
        for (i = 1; i <= 3; i++) {
            if (GET_OBJ_VAL(obj, i) < 0) break;
            if (GET_SKILL(ch, GET_OBJ_VAL(obj, i)) < 1)
                SET_SKILL(ch, GET_OBJ_VAL(obj, i), GET_OBJ_VAL(obj, 0));
        }

        if (obj != NULL)
            extract_obj(obj);
        break;
    default:
        extended_mudlog(NRM, SYSL_BUGS, TRUE, "Unknown object_type %d in mag_objectmagic.",
                        GET_OBJ_TYPE(obj));
        break;
    }
}