Exemple #1
0
void muckle_over(int awardQP) {
    CharData *i;
    int reward = 0;

    for(i = character_list; i; i = i->next) {
        sendChar(i, "The quest is over.\r\n");
        REMOVE_BIT_AR(PRF_FLAGS(i), PRF_QUEST);

        if(!awardQP)
            break;

        reward = i->muckleTime/60 + (i->muckleTime % 60 > 0 ? 1:0);
        if(i->muckleTime == muckle_duration * 60)
            reward += 2;

        if(!IS_NPC(i) && reward) {
            sendChar(i, "You have been awarded %d quest points for your effort.\r\n", reward);
            GET_QP(i) += reward;
            mudlog(BRF, LVL_IMMORT, TRUE, "%s has received %d quest points for %s efforts in muckle.",
                    GET_NAME(i), reward, HSHR(i));
        }
        
        i->muckleTime = 0;
    }

    CONFIG_QUEST_ACTIVE = 0;
}
Exemple #2
0
void clear_quest(struct char_data *ch)
{
  GET_QUEST(ch) = NOTHING;
  GET_QUEST_TIME(ch) = -1;
  GET_QUEST_COUNTER(ch) = 0;
  REMOVE_BIT_AR(PRF_FLAGS(ch), PRF_QUEST);
  return;
}
Exemple #3
0
/*--------------------------------------------------------------------------*/
void set_quest(struct char_data *ch, qst_rnum rnum)
{
  GET_QUEST(ch) = QST_NUM(rnum);
  GET_QUEST_TIME(ch) = QST_TIME(rnum);
  GET_QUEST_COUNTER(ch) = QST_QUANTITY(rnum);
  SET_BIT_AR(PRF_FLAGS(ch), PRF_QUEST);
  return;
}
Exemple #4
0
/* This function controls the change to maxmove, maxmana, and maxhp for each
 * class every time they gain a level. */
void advance_level(struct char_data *ch)
{
  int add_hp, add_mana = 0, add_move = 0, i;

  add_hp = con_app[GET_CON(ch)].hitp;

  switch (GET_CLASS(ch)) {

  case CLASS_ADEPT:
    add_hp += rand_number(3, 8);
    add_mana = rand_number(GET_LEVEL(ch), (int)(1.5 * GET_LEVEL(ch)));
    add_mana = MIN(add_mana, 10);
    add_move = rand_number(0, 2);
    break;

  case CLASS_MEDIC:
    add_hp += rand_number(5, 10);
    add_mana = rand_number(GET_LEVEL(ch), (int)(1.5 * GET_LEVEL(ch)));
    add_mana = MIN(add_mana, 10);
    add_move = rand_number(0, 2);
    break;

  case CLASS_BANDIT:
    add_hp += rand_number(7, 13);
    add_mana = 0;
    add_move = rand_number(1, 3);
    break;

  case CLASS_SOLDIER:
    add_hp += rand_number(10, 15);
    add_mana = 0;
    add_move = rand_number(1, 3);
    break;
  }

  ch->points.max_hit += MAX(1, add_hp);
  ch->points.max_move += MAX(1, add_move);

  if (GET_LEVEL(ch) > 1)
    ch->points.max_mana += add_mana;

  if (IS_ADEPT(ch) || IS_MEDIC(ch))
    GET_PRACTICES(ch) += MAX(2, wis_app[GET_WIS(ch)].bonus);
  else
    GET_PRACTICES(ch) += MIN(2, MAX(1, wis_app[GET_WIS(ch)].bonus));

  if (GET_LEVEL(ch) >= LVL_IMMORT) {
    for (i = 0; i < 3; i++)
      GET_COND(ch, i) = (char) -1;
    SET_BIT_AR(PRF_FLAGS(ch), PRF_HOLYLIGHT);
  }

  snoop_check(ch);
  save_char(ch);
}
Exemple #5
0
int
do_pass_remort_test(struct creature *ch)
{
    int i;

    // Wipe thier skills
    for (i = 1; i <= MAX_SKILLS; i++)
        SET_SKILL(ch, i, 0);

    do_start(ch, false);

    REMOVE_BIT(PRF_FLAGS(ch),
        PRF_NOPROJECT | PRF_ROOMFLAGS | PRF_HOLYLIGHT | PRF_NOHASSLE |
        PRF_LOG1 | PRF_LOG2 | PRF_NOWIZ);

    REMOVE_BIT(PLR_FLAGS(ch), PLR_HALT | PLR_INVSTART | PLR_MORTALIZED |
        PLR_OLCGOD);

    GET_INVIS_LVL(ch) = 0;
    GET_COND(ch, DRUNK) = 0;
    GET_COND(ch, FULL) = 0;
    GET_COND(ch, THIRST) = 0;

    // Give em another gen
    if (GET_REMORT_GEN(ch) == 10)
        account_set_quest_points(ch->account, ch->account->quest_points + 1);
    else
        GET_REMORT_GEN(ch)++;

    // At gen 1 they enter the world of pk, like it or not
    if (GET_REMORT_GEN(ch) >= 1 && RAW_REPUTATION_OF(ch) <= 0)
        gain_reputation(ch, 5);
    // Whack thier remort invis
    GET_WIMP_LEV(ch) = 0;       // wimpy
    GET_TOT_DAM(ch) = 0;        // cyborg damage

    // Tell everyone that they remorted
    char *msg = tmp_sprintf("%s completed gen %d remort test",
        GET_NAME(ch), GET_REMORT_GEN(ch));
    mudlog(LVL_IMMORT, BRF, false, "%s", msg);

    REMOVE_BIT(ch->in_room->room_flags, ROOM_NORECALL);

    // Save the char and its implants but not its eq
    creature_remort(ch);

    return 1;
}
Exemple #6
0
// Create a brand new character
struct creature *
account_create_char(struct account *account, const char *name)
{
    struct creature *ch;
    int i;

    if (chars_available(account) <= 0)
        return NULL;

    ch = make_creature(true);

    ch->player.name = strdup(tmp_capitalize(tmp_tolower(name)));
    ch->char_specials.saved.idnum = top_player_idnum() + 1;
    account->chars =
        g_list_append(account->chars, GINT_TO_POINTER(GET_IDNUM(ch)));

    sql_exec
        ("insert into players (idnum, name, account) values (%ld, '%s', %d)",
        GET_IDNUM(ch), tmp_sqlescape(name), account->id);

    // New characters shouldn't get old mail.
    if (has_mail(GET_IDNUM(ch))) {
        if (purge_mail(GET_IDNUM(ch)) > 0) {
            errlog("Purging pre-existing mailfile for new character.(%s)",
                GET_NAME(ch));
        }
    }
    // *** if this is our first player --- he be God ***
    if (GET_IDNUM(ch) == 1) {
        GET_EXP(ch) = 160000000;
        GET_LEVEL(ch) = LVL_GRIMP;

        ch->points.max_hit = 666;
        ch->points.max_mana = 555;
        ch->points.max_move = 444;

        GET_HOME(ch) = HOME_MODRIAN;
        ch->player_specials->saved.load_room = -1;
        ch->player_specials->saved.home_room = 1204;
    } else {
        ch->points.max_hit = 100;
        ch->points.max_mana = 100;
        ch->points.max_move = 82;

        GET_HOME(ch) = HOME_NEWBIE_SCHOOL;
        ch->player_specials->saved.load_room = -1;
        ch->player_specials->saved.home_room = -1;
    }
    ch->player_specials->rentcode = RENT_CREATING;

    set_title(ch, "");

    ch->player.short_descr = NULL;
    ch->player.long_descr = NULL;
    ch->player.description = NULL;

    ch->player.time.birth = time(NULL);
    ch->player.time.death = 0;
    ch->player.time.played = 0;
    ch->player.time.logon = time(NULL);

    for (i = 0; i < MAX_SKILLS; i++)
        ch->player_specials->saved.skills[i] = 0;

    for (i = 0; i < MAX_WEAPON_SPEC; i++) {
        ch->player_specials->saved.weap_spec[i].vnum = 0;
        ch->player_specials->saved.weap_spec[i].level = 0;
    }
    ch->player_specials->saved.imm_qp = 0;
    ch->player_specials->saved.quest_id = 0;
    ch->player_specials->saved.qlog_level = 0;

    GET_REMORT_CLASS(ch) = -1;
    ch->player.weight = 100;
    ch->player.height = 100;

    ch->points.hit = GET_MAX_HIT(ch);
    ch->points.mana = GET_MAX_MANA(ch);
    ch->points.move = GET_MAX_MOVE(ch);
    ch->points.armor = 100;

    SET_BIT(PRF_FLAGS(ch),
        PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE | PRF_AUTOEXIT | PRF_NOSPEW |
        PRF_NOPLUG);
    SET_BIT(PRF2_FLAGS(ch),
        PRF2_AUTO_DIAGNOSE | PRF2_AUTOPROMPT | PRF2_DISPALIGN |
        PRF2_NEWBIE_HELPER);

    ch->char_specials.saved.affected_by = 0;
    ch->char_specials.saved.affected2_by = 0;
    ch->char_specials.saved.affected3_by = 0;

    for (i = 0; i < 5; i++)
        GET_SAVE(ch, i) = 0;

    GET_COND(ch, FULL) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 24);
    GET_COND(ch, THIRST) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 24);
    GET_COND(ch, DRUNK) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 0);

    POOFIN(ch) = NULL;
    POOFOUT(ch) = NULL;
    return ch;
}
Exemple #7
0
void affect_from_char_II(struct char_data * ch, int skill, int type, int action)
{

 struct affected_type *aff, *next;
 struct affected_type *temp;
 struct affected_type af[3];
 int i, k;
 bool accum_affect = FALSE, accum_duration = FALSE;
 
 for (aff = ch->affected; aff; aff = next) {
    next = aff->next;
    if (aff->type == type) {
    affect_modify(ch, aff->location, aff->modifier, aff->bitvector, FALSE);
  REMOVE_FROM_LIST(aff, ch->affected, next);
  free(aff);
  affect_total(ch);
 }
}

if (action == 2) {
switch (skill) {
      case SPELL_POLYMORPH:
   if (PLR_FLAGGED(ch, PLR_RABBIT)){
REMOVE_BIT(PLR_FLAGS(ch), PLR_RABBIT);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel yourself growing, and your ears shrinking. You no longer feel like a rabbit.\r\n", ch);
act("$n's body grows, $s ears shrinking. $n no longer looks like a rabbit.\r\n", 0, ch, 0, 0, TO_ROOM);

}
if (PLR_FLAGGED(ch, PLR_BIRD)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_BIRD);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel yourself growing and your feathers falling away. You no longer feel like a bird.\r\n", ch);
act("$n's body grows, $s feathers falling away as it expands. $n no longer looks like a bird.\r\n", 0, ch, 0, 0, TO_ROOM);

}
if (PLR_FLAGGED(ch, PLR_WOLF)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_WOLF);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel your your fur shed and your teeth shrink. You no longer feel like a wolf.\r\n", ch);
act("$n's teeth shrink, $s fur shedding. $n no longer looks like a wolf.\r\n", 0, ch, 0, 0, TO_ROOM);
}
if (PLR_FLAGGED(ch, PLR_BEAR)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_BEAR);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("Your claws shrink as does the rest of your body. You no longer feel like a bear.\r\n", ch);
act("$n's claws shrink as does the rest of $s body. $n no longer looks like a bear.\r\n", 0, ch, 0, 0, TO_ROOM);
}
if (PLR_FLAGGED(ch, PLR_CAT)){
REMOVE_BIT(PLR_FLAGS(ch), PLR_CAT);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel your body growing, and your fur shedding. You no longer feel like a cat.\r\n", ch);
act("$n's body slowly grows, $s fur shedding. $n no longer looks like a cat.\r\n", 0, ch, 0, 0, TO_ROOM);
}

  for (k = 0; k < NUM_WEARS; k++)
  if (GET_EQ(ch, k)){
    GET_OBJ_DISGUISE(GET_EQ(ch, k)) = 0;
  }

       if (affected_by_spell(ch, SPELL_FLIGHT))
       affect_from_char_II(ch, SPELL_FLIGHT, SPELL_FLIGHT, 1);
       if (affected_by_spell(ch, SPELL_HASTE))
       affect_from_char_II(ch, SPELL_HASTE, SPELL_HASTE, 1);
       break;
      case SKILL_STANCE:

   if (!AFF_FLAGGED(ch, AFF_TIRED)) {
   for (i = 0; i < 3; i++) {
    af[0].type     = SPELL_DONTUSEME;
    af[0].location = APPLY_HITROLL;
    af[0].modifier = 2;
    af[0].duration = 7;
    af[0].bitvector = AFF_STANCE;

    af[1].type      = SPELL_DONTUSEME;
    af[1].location = APPLY_AC;
    af[1].modifier = -50;
    af[1].duration = 7;
    af[1].bitvector = AFF_STANCE;
 
    af[2].type      = SPELL_DONTUSEME;
    af[2].location = APPLY_STR;
    af[2].modifier = 2;
    af[2].duration = 7;
    af[2].bitvector = AFF_STANCE;


      if (af[i].bitvector || (af[i].location != APPLY_NONE)) {
        affect_join(ch, af+i, accum_duration, FALSE, accum_affect, FALSE);
      }
    }
}
     break;

    default:
      break;
  }
 }
}
Exemple #8
0
/*
 * Remove an affected_type structure from a char (called when duration
 * reaches zero). Pointer *af must never be NIL!  Frees mem and calls
 * affect_location_apply
 */
void affect_remove(struct char_data * ch, struct affected_type * af, int output)
{
  struct affected_type *temp;
  struct affected_type aff;
  bool accum_affect = FALSE;
  int k;

  if (ch->affected == NULL) {
    core_dump();
    return;
  }

  switch (af->type)
  {

    case SPELL_CHARM:
    { 
      struct char_data* victim = ch->master;
      if (output == 0) break;

      affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
      REMOVE_FROM_LIST(af, ch->affected, next);
      free(af);
      affect_total(ch);

      if (ch->master)
      {
        stop_follower(ch);
      }

      if (victim)
      {
        if(IS_NPC(ch))
        {
          SET_BIT(MOB_FLAGS(ch), MOB_AGGRESSIVE | MOB_MEMORY);
        }
        if (mag_savingthrow(victim, SAVING_SPELL))
        {
          hit(victim, ch, TYPE_UNDEFINED);
        }
      }
      return;
    }

    case SPELL_LIGHT:
      if (output == 0) break;
      if (!af->next || (af->next->type != af->type) ||
         (af->next->duration > 0)) 
      {
        if (world[ch->in_room].name != (char*) NULL)
        {
          world[ch->in_room].light -= 10;
        }
      }
      break;
    case SPELL_DARKNESS:
      if (output == 0) break;
      if (!af->next || (af->next->type != af->type) ||
         (af->next->duration > 0)) 
      {
        if (world[ch->in_room].name != (char*) NULL)
        {
          world[ch->in_room].light += 10;
        }
      }
      break;
    case SPELL_BLACK_PLAGUE:
      mag_affects(30, ch, ch, SPELL_BREATH_OF_LIFE, SAVING_SPELL);
      break;
    case SPELL_CALL_ANIMAL_SPIRIT:
    case SPELL_ANIMAL_SUMMONING:
    case SPELL_ANIMAL_SUMMONING_II:
    case SPELL_ANIMAL_SUMMONING_III:
    case SPELL_CONJURE_ELEMENTAL:
    case SPELL_GREATER_ELEMENTAL:
    case SPELL_DUST_DEVIL:
    case SPELL_STICKS_TO_SNAKES:
    case SPELL_SUMMON_INSECTS:
    case SPELL_AERIAL_SERVANT:
    case SPELL_SUMMON_GUARD:
      if (IS_NPC(ch))
      {
        if (GET_POS(ch) > POS_DEAD)
        {
          if (output == 1)
          {
            affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
            REMOVE_FROM_LIST(af, ch->affected, next);
            free(af);
            affect_total(ch);

            GET_NAME(ch, chname);
	    stop_fighting(ch); /*Fighting Bug Fix Jasrags*/
            sprintf(buf, "%s disappears into thin air as the summoning ends.", 
              chname);
            act(buf, FALSE, world[ch->in_room].people, 0, 0, TO_ROOM);
            FREE_NAME(chname);
            extract_char(ch);
            ch = NULL;
            return;
          }
        }
      }
      break;
   case SPELL_POLYMORPH:
   if (!PRF_FLAGGED(ch, PRF_NOTSELF)) {
          affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
          REMOVE_FROM_LIST(af, ch->affected, next);
          free(af);
          affect_total(ch);
          return;
   }
   break;
   case SPELL_DONTUSEME:
   if(AFF_FLAGGED(ch, AFF_STANCE) && !AFF_FLAGGED(ch, AFF_TIRED)) {
      aff.type = SKILL_STANCE;
      aff.duration = 2;
      aff.location = APPLY_STR;
      aff.modifier = -2;
      aff.bitvector = AFF_TIRED;
      accum_affect = FALSE;

      affect_to_char(ch, &aff);
    }
   break;
    default:
      break;
  }

  if (output && (af->type > 0) && (af->type <= MAX_SPELLS) && af->type != SPELL_POLYMORPH && af->type != SPELL_DONTUSEME) {
    if (!af->next || (af->next->type != af->type) ||
        (af->next->duration > 0)) {
      if (*spell_wear_off_msg[af->type]) {
        send_to_char(spell_wear_off_msg[af->type], ch);
        send_to_char("\r\n", ch);
      }
  }
}

if (output && (af->type > 0) && (af->type <= MAX_SPELLS) && af->type == SPELL_POLYMORPH)  {

  if (!af->next || (af->next->type != af->type) ||
        (af->next->duration > 0)) {
   if (PLR_FLAGGED(ch, PLR_RABBIT)){
REMOVE_BIT(PLR_FLAGS(ch), PLR_RABBIT);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel yourself growing, and your ears shrinking. You no longer feel like a rabbit.\r\n", ch);
act("$n's body grows, $s ears shrinking. $n no longer looks like a rabbit.\r\n", 0, ch, 0, 0, TO_ROOM);

}
if (PLR_FLAGGED(ch, PLR_BIRD)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_BIRD);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel yourself growing and your feathers falling away. You no longer feel like a bird.\r\n", ch);
act("$n's body grows, $s feathers falling away as it expands. $n no longer looks like a bird.\r\n", 0, ch, 0, 0, TO_ROOM);

}
if (PLR_FLAGGED(ch, PLR_WOLF)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_WOLF);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel your your fur shed and your teeth shrink. You no longer feel like a wolf.\r\n", ch);
act("$n's teeth shrink, $s fur shedding. $n no longer looks like a wolf.\r\n", 0, ch, 0, 0, TO_ROOM);
}
if (PLR_FLAGGED(ch, PLR_BEAR)) {
REMOVE_BIT(PLR_FLAGS(ch), PLR_BEAR);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("Your claws shrink as does the rest of your body. You no longer feel like a bear.\r\n", ch);
act("$n's claws shrink as does the rest of $s body. $n no longer looks like a bear.\r\n", 0, ch, 0, 0, TO_ROOM);
}
if (PLR_FLAGGED(ch, PLR_CAT)){
REMOVE_BIT(PLR_FLAGS(ch), PLR_CAT);
REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);
send_to_char("You feel your body growing, and your fur shedding. You no longer feel like a cat.\r\n", ch);
act("$n's body slowly grows, $s fur shedding. $n no longer looks like a cat.\r\n", 0, ch, 0, 0, TO_ROOM);
}

for (k = 0; k < NUM_WEARS; k++)
  if (GET_EQ(ch, k)){
    GET_OBJ_DISGUISE(GET_EQ(ch, k)) = 0;
  }

}
} 

  affect_modify(ch, af->location, af->modifier, af->bitvector, FALSE);
  REMOVE_FROM_LIST(af, ch->affected, next);
  free(af);
  affect_total(ch);
}
Exemple #9
0
/* Extract a ch completely from the world, and leave his stuff behind */
void extract_char(struct char_data * ch)
{
  struct char_data *k, *temp;
  struct descriptor_data *t_desc;
  struct obj_data *obj;
  int i, freed = 0;
  //int j;

  extern struct char_data *combat_list;

  ACMD(do_return);

  void die_follower(struct char_data * ch);


  if (!IS_NPC(ch) && !ch->desc) {
    for (t_desc = descriptor_list; t_desc; t_desc = t_desc->next) {
      if (t_desc->original == ch) {
	do_return(t_desc->character, "", 0, 0);
      }
    }
  }

  if (ch->in_room == NOWHERE) {
    log("SYSERR: NOWHERE extracting char. (handler.c, extract_char)");
    exit(1);
  }

  if (ch->followers || ch->master) {
    die_follower(ch);
  }

  if (RIDING(ch) || RIDDEN_BY(ch))
   dismount_char(ch);

   REMOVE_BIT(PLR_FLAGS(ch), PLR_FISHING);

   REMOVE_BIT(PLR_FLAGS(ch), PLR_FISH_ON);

   REMOVE_BIT(PLR_FLAGS(ch), PLR_DIGGING);

   REMOVE_BIT(PLR_FLAGS(ch), PLR_DIG_ON);

   REMOVE_BIT(PLR_FLAGS(ch), PLR_FIRE_ON);

   REMOVE_BIT(PRF_FLAGS(ch), PRF_NOTSELF);

   //REMOVE_BIT(PRF_FLAGS(ch), PRF_DISGUISE);
   //REMOVE_BIT(PLR_FLAGS(ch), PLR_MAGE);
   //REMOVE_BIT(PLR_FLAGS(ch), PLR_MONK);
   //REMOVE_BIT(PLR_FLAGS(ch), PLR_KNIGHT);
   //REMOVE_BIT(PLR_FLAGS(ch), PLR_CLERIC);
   //REMOVE_BIT(PLR_FLAGS(ch), PLR_BARD);
   //REMOVE_BIT(PLR_FLAGS(ch), PLR_BEGGAR);
   REMOVE_BIT(PLR_FLAGS(ch), PLR_COURIER);
   REMOVE_BIT(PLR_FLAGS(ch), PLR_BEAR);
   REMOVE_BIT(PLR_FLAGS(ch), PLR_BIRD);
   REMOVE_BIT(PLR_FLAGS(ch), PLR_WOLF);
   REMOVE_BIT(PLR_FLAGS(ch), PLR_RABBIT);
   REMOVE_BIT(PLR_FLAGS(ch), PLR_CAT);

  /* Forget snooping, if applicable */
  if (ch->desc) {
    if (ch->desc->snooping) {
      ch->desc->snooping->snoop_by = NULL;
      ch->desc->snooping = NULL;
    }

    if (ch->desc->snoop_by) {
      SEND_TO_Q("Your victim is no longer among us.\r\n",
		ch->desc->snoop_by);
      ch->desc->snoop_by->snooping = NULL;
      ch->desc->snoop_by = NULL;
    }
  }

  /* transfer objects to room, if any */
  while (ch->carrying) {
    obj = ch->carrying;
    obj_from_char(obj);
    obj_to_room(obj, ch->in_room);
  }

  /* transfer equipment to room, if any */
  for (i = 0; i < NUM_WEARS; i++) {
    if (GET_EQ(ch, i)) {
      obj_to_room(unequip_char(ch, i), ch->in_room);
    }
  }

  if (FIGHTING(ch)) {
    stop_fighting(ch);
  }

  for (k = combat_list; k; k = temp) {
    temp = k->next_fighting;
    if (FIGHTING(k) == ch) {
      stop_fighting(k);
    }
  }

  char_from_room(ch);

  /* pull the char from the list */
  REMOVE_FROM_LIST(ch, character_list, next);

  if (ch->desc && ch->desc->original) {
    do_return(ch, NULL, 0, 0);
  }

  if (!IS_NPC(ch)) {
    save_char(ch, NOWHERE);
    Crash_delete_crashfile(ch);
  } else {
    if (GET_MOB_RNUM(ch) > -1) {     /* if mobile */
      mob_index[GET_MOB_RNUM(ch)].number--;
    }
    clearMemory(ch);		/* Only NPC's can have memory */

    if (SCRIPT(ch)) {
      extract_script(SCRIPT(ch));
    }

    free_char(ch);
    freed = 1;
  }

  if (!freed && ch->desc != NULL) {
    STATE(ch->desc) = CON_MENU;
    SEND_TO_Q(MENU, ch->desc);
  } else {  /* if a player gets purged from within the game */
    if (ch->master || ch->followers)
      die_follower(ch);
    if (!freed) {
      free_char(ch);
    }
  }
}
Exemple #10
0
/*
 * 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
    {
Exemple #11
0
/*
 * Load a char and inventory into a new ch structure.
 */
bool load_char_obj( struct descriptor_data * d, const char * name )
{
  FILE      *fp;
  struct char_data *ch;
  char       strsave [ MAX_INPUT_LENGTH ];
  bool       found;
  char       sorry_player [] =
    "********************************************************\n\r"
    "** One or more of the critical fields in your player  **\n\r"
    "** file were corrupted since you last played.  Please **\n\r"
    "** contact an administrator or programmer to          **\n\r"
    "** investigate the recovery of your characters.       **\n\r"
    "********************************************************\n\r";
  char       sorry_object [] =
    "********************************************************\n\r"
    "** One or more of the critical fields in your player  **\n\r"
    "** file were corrupted leading to the loss of one or  **\n\r"
    "** more of your possessions.                          **\n\r"
    "********************************************************\n\r";
  char       sorry_alias [] =
    "********************************************************\n\r"
    "** One or more of the critical fields in your player  **\n\r"
    "** file were corrupted leading to the loss of one or  **\n\r"
    "** more of your aliases.                              **\n\r"
    "********************************************************\n\r";
  
  ch  				= new_character( TRUE );
  
  d->character			= ch;
  GET_DESC(ch)			= d;
  ch->player.name   = str_dup( name );
  /*
  ch->pcdata->prompt                  = str_dup( daPrompt );
  ch->last_note                       = 0;
  */
  strcpy( GET_PASSWD(ch), "" );
  POOFIN(ch)			= str_dup( "" );
  POOFOUT(ch)			= str_dup( "" );
  GET_TITLE(ch)			= str_dup( "" );
  GET_STR(ch)			= 10;
  GET_ADD(ch)			= 10; 
  GET_INT(ch)			= 10; 
  GET_WIS(ch)			= 10; 
  GET_DEX(ch)			= 10; 
  GET_CON(ch)			= 10; 
  GET_CHA(ch)			= 10; 
  GET_WILL(ch)			= 10; 
  GET_COND(ch, DRUNK)	= 48;
  GET_COND(ch, FULL)	= 48;
  GET_COND(ch, THIRST)	= 48;
  GET_COND(ch, TIRED)	= 48;
  
  // ch->pcdata->switched                = FALSE;
  
  found = FALSE;
  fclose( fpReserve );
  
  /* parsed player file directories by Yaz of 4th Realm */
  /* decompress if .gz file exists - Thx Alander */
  sprintf( strsave, "%s/%s/%s%s", PLAYER_DIR,
           player_dir( GET_NAME(ch) ),
           capitalize( GET_NAME(ch) ), ".gz" );
  
    if ( ( fp = fopen( strsave, "r" ) ) ) {
      char       buf     [ MAX_STRING_LENGTH ];
      
      fclose( fp );
      sprintf( buf, "gzip -dfq %s", strsave );
      system( buf );
    }

    sprintf( strsave, "%s/%s/%s", PLAYER_DIR,
             player_dir( GET_NAME(ch) ),
             capitalize( GET_NAME(ch) ) );

    if ( ( fp = fopen( strsave, "r" ) ) ) {
	char buf[ MAX_STRING_LENGTH ];
	int iNest;

	for ( iNest = 0; iNest < MAX_NEST; iNest++ )
	    rgObjNest[iNest] = NULL;

	found = TRUE;
	for ( ; ; )
	{
	    char *word;
	    char  letter;
	    int   status;

	    letter = fread_letter( fp );
	    if ( letter == '*' )
	    {
		fread_to_eol( fp );
		continue;
	    }

	    if ( letter != '#' )
	    {
              log( "Load_char_obj: # not found." );
              break;
	    }

	    word = fread_word_stat( fp, &status );

	    if ( !str_cmp( word, "PLAYER" ) )
	    {
	        if ( fread_char ( ch, fp ) )
		{
		    sprintf( buf,
			    "Load_char_obj:  %s section PLAYER corrupt.\n\r",
			    name );
		    log( buf );
		    SEND_TO_Q( sorry_player, d );

		    /* 
		     * In case you are curious,
		     * it is ok to leave ch alone for close_socket
		     * to free.
		     * We want to now kick the bad character out as
		     * what we are missing are MANDATORY fields.  -Kahn
		     */
		    SET_BIT( PRF_FLAGS(ch), PLR_DELETED );
		    return TRUE;
		}
	    }
	    else if ( !str_cmp( word, "OBJECT" ) )
	    {
	        if ( !fread_obj_char( ch, fp ) )
		{
		    sprintf( buf,
			    "Load_char_obj:  %s section OBJECT corrupt.\n\r",
			    name );
		    log( buf );
		    SEND_TO_Q( sorry_object, d );
		    return FALSE;
		}
	    }
	    else if ( !str_cmp( word, "ALIAS"    ) ) {
              if ( !fread_alias( ch, fp ) )
              {
                sprintf( buf,
                         "Load_char_obj: %s section ALIAS corrupt.\n\r",
                         name );
                log( buf );
                SEND_TO_Q( sorry_alias, d );
                return FALSE;
              }
            }
	    else if ( !str_cmp( word, "END"    ) ) break;
	    else
	    {
		log( "Load_char_obj: bad section." );
		break;
	    }
	} /* for */

	fclose( fp );
    }

    fpReserve = fopen( NULL_FILE, "r" );

    if ( found )
      rent_adjust( d->character );
    
    return found;
}
Exemple #12
0
/*
 * 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;
}
Exemple #13
0
/*
 * This function controls the change to maxmove, maxmana, and maxhp for
 * each char_class every time they gain a level.
 */
void
advance_level(struct creature *ch, int8_t keep_internal)
{
    int add_hp[2], add_mana[2], add_move[2], i, char_class;
    char *msg;

    add_hp[0] = add_hp[1] = constitution_hitpoint_bonus(GET_CON(ch));
    add_mana[0] = add_mana[1] = wisdom_mana_bonus(GET_WIS(ch));
    add_move[0] = add_move[1] = MAX(0, GET_CON(ch) - 15);

    for (i = 0; i < 2; i++) {

        if (i == 0)
            char_class = MIN(GET_CLASS(ch), NUM_CLASSES - 1);
        else
            char_class = MIN(GET_REMORT_CLASS(ch), NUM_CLASSES - 1);
        if (char_class < 0)
            continue;

        switch (char_class) {
        case CLASS_MAGIC_USER:
            add_hp[i] /= 5;
            add_hp[i] += number(3, 10);
            add_mana[i] += number(1, 11) + (GET_LEVEL(ch) / 3);
            add_move[i] += number(1, 3);
            break;
        case CLASS_CLERIC:
            add_hp[i] /= 2;
            add_hp[i] += number(5, 11);
            add_mana[i] += number(1, 10) + (GET_LEVEL(ch) / 5);
            add_move[i] += number(1, 4);
            break;
        case CLASS_BARD:
            add_hp[i] = add_hp[i] / 3;
            add_hp[i] += number(5, 10);
            add_mana[i] += number(1, 4) + (GET_LEVEL(ch) / 10);
            add_move[i] += number(10, 18);
            break;
        case CLASS_THIEF:
            add_hp[i] /= 3;
            add_hp[i] += number(4, 10);
            add_mana[i] = add_mana[i] * 3 / 10;
            add_move[i] += number(2, 6);
            break;
        case CLASS_MERCENARY:
            add_hp[i] += number(6, 14);
            add_mana[i] = add_mana[i] * 5 / 10;
            add_mana[i] += number(1, 5) + GET_LEVEL(ch) / 10;
            add_move[i] += number(3, 9);
            break;
        case CLASS_WARRIOR:
            add_hp[i] += number(10, 15);
            add_mana[i] = add_mana[i] * 4 / 10;
            add_mana[i] += number(1, 5);
            add_move[i] += number(5, 10);
            break;
        case CLASS_BARB:
            add_hp[i] += number(13, 18);
            add_mana[i] = add_mana[i] * 3 / 10;
            add_mana[i] += number(0, 3);
            add_move[i] += number(5, 10);
            break;
        case CLASS_KNIGHT:
            add_hp[i] += number(7, 13);
            add_mana[i] = add_mana[i] * 7 / 10;
            add_mana[i] += number(1, 4) + (GET_LEVEL(ch) / 15);
            add_move[i] += number(3, 8);
            break;
        case CLASS_RANGER:
            add_hp[i] += number(4, 11);
            add_mana[i] = add_mana[i] * 6 / 10;
            add_mana[i] += number(1, 6) + (GET_LEVEL(ch) / 8);
            add_move[i] += number(6, 14);
            break;
        case CLASS_PSIONIC:
            add_hp[i] /= 3;
            add_hp[i] += number(3, 8);
            add_mana[i] = add_mana[i] * 6 / 10;
            add_mana[i] += number(1, 7) + (GET_LEVEL(ch) / 5);
            add_move[i] += number(2, 6);
            break;
        case CLASS_PHYSIC:
            add_hp[i] /= 4;
            add_hp[i] += number(4, 9);
            add_mana[i] = add_mana[i] * 6 / 10;
            add_mana[i] += number(1, 6) + (GET_LEVEL(ch) / 3);
            add_move[i] += number(2, 10);
            break;
        case CLASS_CYBORG:
            add_hp[i] /= 2;
            add_hp[i] += number(6, 14);
            add_mana[i] = add_mana[i] * 3 / 10;
            add_mana[i] += number(1, 2) + (GET_LEVEL(ch) / 15);
            add_move[i] += number(5, 8);
            break;
        case CLASS_MONK:
            add_hp[i] /= 3;
            add_hp[i] += number(6, 12);
            add_mana[i] = add_mana[i] * 3 / 10;
            add_mana[i] += number(1, 2) + (GET_LEVEL(ch) / 22);
            add_move[i] += number(6, 9);
            break;
        default:
            add_hp[i] /= 2;
            add_hp[i] += number(5, 16);
            add_mana[i] = add_mana[i] * 5 / 10;
            add_mana[i] += number(1, 13) + (GET_LEVEL(ch) / 4);
            add_move[i] += number(7, 15);
            break;
        }
    }

    if (IS_RACE(ch, RACE_HALF_ORC) || IS_RACE(ch, RACE_ORC)) {
        add_move[0] *= 2;
        add_move[1] *= 2;
    }
    ch->points.max_hit += MAX(1, add_hp[0]);
    ch->points.max_move += MAX(1, add_move[0]);

    if (GET_LEVEL(ch) > 1)
        ch->points.max_mana += add_mana[0];

    GET_LIFE_POINTS(ch) += (GET_LEVEL(ch) * (GET_WIS(ch) + GET_CON(ch))) / 300;
    if (PLR_FLAGGED(ch, PLR_HARDCORE))
        GET_LIFE_POINTS(ch) += 1;

    if (IS_REMORT(ch) && GET_REMORT_GEN(ch)) {

        if (add_hp[0] < 0 || add_hp[1] < 0) {
            errlog("remort level (%s) add_hp: [0]=%d,[1]=%d",
                GET_NAME(ch), add_hp[0], add_hp[1]);
        }

        ch->points.max_hit += add_hp[1] / 4;
        ch->points.max_mana += add_mana[1] / 2;
        ch->points.max_move += add_move[1] / 4;

    }

    if (GET_LEVEL(ch) >= LVL_AMBASSADOR) {
        for (i = 0; i < 3; i++)
            GET_COND(ch, i) = -1;
        SET_BIT(PRF_FLAGS(ch), PRF_HOLYLIGHT);
        SET_BIT(PRF_FLAGS(ch), PRF_NOHASSLE);
    }
    if (GET_LEVEL(ch) == 10)
        SET_BIT(PRF2_FLAGS(ch), PRF2_NEWBIE_HELPER);

    // special section for improving read_scrolls and use_wands
    if (CHECK_SKILL(ch, SKILL_READ_SCROLLS) > 10)
        SET_SKILL(ch, SKILL_READ_SCROLLS, 
                  MIN(100, CHECK_SKILL(ch, SKILL_READ_SCROLLS) +
                      MIN(10, number(1, GET_INT(ch) / 2))));
    if (CHECK_SKILL(ch, SKILL_USE_WANDS) > 10)
        SET_SKILL(ch, SKILL_USE_WANDS,
                  MIN(100, CHECK_SKILL(ch, SKILL_USE_WANDS) +
                      MIN(10, number(1, GET_INT(ch) / 2))));

    crashsave(ch);
    int rid = -1;
    if (ch->in_room != NULL)
        rid = ch->in_room->number;
    msg = tmp_sprintf("%s advanced to level %d in room %d%s",
        GET_NAME(ch), GET_LEVEL(ch), rid, is_tester(ch) ? " <TESTER>" : "");
    if (keep_internal)
        slog("%s", msg);
    else
        mudlog(GET_INVIS_LVL(ch), BRF, true, "%s", msg);
}