/** * Проверка стартовых и итоговых статов. * Если невалидные стартовые статы - чар отправляется на реролл. * Если невалидные только итоговые статы - идет перезапись со стартовых с учетом мортов и славы. */ bool check_stats(CHAR_DATA *ch) { // иммов травмировать не стоит if (IS_IMMORTAL(ch)) { return 1; } int have_stats = ch->get_inborn_str() + ch->get_inborn_dex() + ch->get_inborn_int() + ch->get_inborn_wis() + ch->get_inborn_con() + ch->get_inborn_cha(); // чар со старым роллом статов или после попыток поправить статы в файле if (bad_start_stats(ch)) { snprintf(buf, MAX_STRING_LENGTH, "\r\n%sВаши параметры за вычетом перевоплощений:\r\n" "Сила: %d, Ловкость: %d, Ум: %d, Мудрость: %d, Телосложение: %d, Обаяние: %d\r\n" "Если вы долго отсутствовали в игре, то изменения, касающиеся стартовых параметров были следующие:%s\r\n" "\r\n" "\tДобавлено ограничение на максимальный класс защиты:\r\n" "\tВоры, наемники и дружинники - -250\r\n" "\tКупцы, богатыри, витязи, охотники, кузнецы - -200\r\n" "\tЛекари, волхвы - -150\r\n" "\tКудесники, чернокнижники, колдуны, волшебники - -100\r\n" "\r\n" "\tТелосложение: изменились коэффициенты профессий и максимальное родное тело (50) в расчетах при\r\n" "\tполучении уровня, поэтому изменены границы стартового телосложения у некоторых профессий,\r\n" "\tв целом это увеличивает кол-во жизней персонажа тем сильнее, чем больше у него было ремортов.\r\n" "\r\n", CCIGRN(ch, C_SPR), ch->get_inborn_str() - GET_REMORT(ch), ch->get_inborn_dex() - GET_REMORT(ch), ch->get_inborn_int() - GET_REMORT(ch), ch->get_inborn_wis() - GET_REMORT(ch), ch->get_inborn_con() - GET_REMORT(ch), ch->get_inborn_cha() - GET_REMORT(ch), CCNRM(ch, C_SPR)); SEND_TO_Q(buf, ch->desc); // данную фигню мы делаем для того, чтобы из ролла нельзя было случайно так просто выйти // сразу, не раскидав статы, а то много любителей тригов и просто нажатий не глядя ch->set_str(MIN_STR(ch)); ch->set_dex(MIN_DEX(ch)); ch->set_int(MIN_INT(ch)); ch->set_wis(MIN_WIS(ch)); ch->set_con(MIN_CON(ch)); ch->set_cha(MIN_CHA(ch)); snprintf(buf, MAX_STRING_LENGTH, "%sПросим вас заново распределить основные параметры персонажа.%s\r\n", CCIGRN(ch, C_SPR), CCNRM(ch, C_SPR)); SEND_TO_Q(buf, ch->desc); SEND_TO_Q("\r\n* В связи с проблемами перевода фразы ANYKEY нажмите ENTER *", ch->desc); STATE(ch->desc) = CON_RESET_STATS; return 0; } // стартовые статы в поряде, но слава не сходится (снялась по времени или иммом) if (bad_real_stats(ch, have_stats)) { recalculate_stats(ch); } return 1; }
void gain_exp(CHAR_DATA * ch, int gain) { int is_altered = FALSE; int num_levels = 0; char buf[128]; if (IS_NPC(ch)) { ch->set_exp(ch->get_exp() + gain); return; } else { ch->dps_add_exp(gain); ZoneExpStat::add(zone_table[world[IN_ROOM(ch)]->zone].number, gain); } if (!IS_NPC(ch) && ((GET_LEVEL(ch) < 1 || GET_LEVEL(ch) >= LVL_IMMORT))) return; if (gain > 0 && GET_LEVEL(ch) < LVL_IMMORT) { gain = MIN(max_exp_gain_pc(ch), gain); // put a cap on the max gain per kill ch->set_exp(ch->get_exp() + gain); if (GET_EXP(ch) >= level_exp(ch, LVL_IMMORT)) { if (!GET_GOD_FLAG(ch, GF_REMORT) && GET_REMORT(ch) < MAX_REMORT) { if (Remort::can_remort_now(ch)) { send_to_char(ch, "%sПоздравляем, вы получили право на перевоплощение!%s\r\n", CCIGRN(ch, C_NRM), CCNRM(ch, C_NRM)); } else { send_to_char(ch, "%sПоздравляем, вы набрали максимальное количество опыта!\r\n" "%s%s\r\n", CCIGRN(ch, C_NRM), Remort::WHERE_TO_REMORT_STR.c_str(), CCNRM(ch, C_NRM)); } SET_GOD_FLAG(ch, GF_REMORT); } } ch->set_exp(MIN(GET_EXP(ch), level_exp(ch, LVL_IMMORT) - 1)); while (GET_LEVEL(ch) < LVL_IMMORT && GET_EXP(ch) >= level_exp(ch, GET_LEVEL(ch) + 1)) { ch->set_level(ch->get_level() + 1); num_levels++; sprintf(buf, "%sВы достигли следующего уровня!%s\r\n", CCWHT(ch, C_NRM), CCNRM(ch, C_NRM)); send_to_char(buf, ch); advance_level(ch); is_altered = TRUE; } if (is_altered) { sprintf(buf, "%s advanced %d level%s to level %d.", GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch)); mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE); } } else if (gain < 0 && GET_LEVEL(ch) < LVL_IMMORT) { gain = MAX(-max_exp_loss_pc(ch), gain); // Cap max exp lost per death ch->set_exp(ch->get_exp() + gain); while (GET_LEVEL(ch) > 1 && GET_EXP(ch) < level_exp(ch, GET_LEVEL(ch))) { ch->set_level(ch->get_level() - 1); num_levels++; sprintf(buf, "%sВы потеряли уровень. Вам должно быть стыдно!%s\r\n", CCIRED(ch, C_NRM), CCNRM(ch, C_NRM)); send_to_char(buf, ch); decrease_level(ch); is_altered = TRUE; } if (is_altered) { sprintf(buf, "%s decreases %d level%s to level %d.", GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch)); mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE); } } if ((GET_EXP(ch) < level_exp(ch, LVL_IMMORT) - 1) && GET_GOD_FLAG(ch, GF_REMORT) && gain && (GET_LEVEL(ch) < LVL_IMMORT)) { if (Remort::can_remort_now(ch)) { send_to_char(ch, "%sВы потеряли право на перевоплощение!%s\r\n", CCIRED(ch, C_NRM), CCNRM(ch, C_NRM)); } CLR_GOD_FLAG(ch, GF_REMORT); } char_stat::add_class_exp(GET_CLASS(ch), gain); update_clan_exp(ch, gain); }