// юзается исключительно в act.wizards.cpp в имм командах "advance" и "set exp". void gain_exp_regardless(CHAR_DATA * ch, int gain) { int is_altered = FALSE; int num_levels = 0; ch->set_exp(ch->get_exp() + gain); if (!IS_NPC(ch)) { if (gain > 0) { while (GET_LEVEL(ch) < LVL_IMPL && 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) { // Pereplut: глупый участок кода. // gain = MAX(-max_exp_loss_pc(ch), gain); // Cap max exp lost per death // GET_EXP(ch) += gain; // if (GET_EXP(ch) < 0) // GET_EXP(ch) = 0; 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); } } } }
int max_exp_gain_pc(CHAR_DATA * ch) { int result = 1; if (!IS_NPC(ch)) { int max_per_lev = level_exp(ch, GET_LEVEL(ch) + 1) - level_exp(ch, GET_LEVEL(ch) + 0); result = max_per_lev / (10 + GET_REMORT(ch)); } return result; }
void gain_exp_regardless(struct char_data * ch, int gain) { int is_altered = FALSE; int num_levels = 0; GET_EXP(ch) += gain; if (GET_EXP(ch) < 0) GET_EXP(ch) = 0; if (!IS_NPC(ch)) { while (GET_LEVEL(ch) < LVL_IMPL && GET_EXP(ch) >= level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1)) { GET_LEVEL(ch) += 1; num_levels++; 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, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE); if (num_levels == 1) send_to_char("You rise a level!\r\n", ch); else { sprintf(buf, "You rise %d levels!\r\n", num_levels); send_to_char(buf, ch); } set_title(ch, NULL); check_autowiz(ch); } } }
void gain_exp(struct char_data * ch, int gain) { int is_altered = FALSE; int num_levels = 0; char buf[128]; if (!IS_NPC(ch) && ((GET_LEVEL(ch) < 1 || GET_LEVEL(ch) >= LVL_IMMORT))) return; if (IS_NPC(ch)) { GET_EXP(ch) += gain; return; } if (gain > 0) { gain = MIN(max_exp_gain, gain); /* put a cap on the max gain per kill */ GET_EXP(ch) += gain; while (GET_LEVEL(ch) < LVL_IMMORT && GET_EXP(ch) >= level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1)) { GET_LEVEL(ch) += 1; num_levels++; 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, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE); if (num_levels == 1) send_to_char("You rise a level!\r\n", ch); else { sprintf(buf, "You rise %d levels!\r\n", num_levels); send_to_char(buf, ch); } set_title(ch, NULL); check_autowiz(ch); } } else if (gain < 0) { gain = MAX(-max_exp_loss, gain); /* Cap max exp lost per death */ GET_EXP(ch) += gain; if (GET_EXP(ch) < 0) GET_EXP(ch) = 0; } }
int max_exp_loss_pc(struct char_data *ch) { return (IS_NPC(ch) ? 1 : (level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 0)) / 3); }
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); }
int max_exp_loss_pc(CHAR_DATA * ch) { return (IS_NPC(ch) ? 1 : (level_exp(ch, GET_LEVEL(ch) + 1) - level_exp(ch, GET_LEVEL(ch) + 0)) / 3); }
/** * For the new experience system. We are concerned with whether the * player gets more hp, sp and new levels. * * Will tell the player about changed levels. * @param who Player. * @param op What we are checking to gain the level (eg, skill). */ void player_lvl_adj(object *who, object *op) { char buf[MAX_BUF]; /* When rolling stats */ if (!op) { op = who; } /* No exp gain for indirect skills */ if (op->type == SKILL && !op->last_eat) { LOG(llevBug,"BUG: player_lvl_adj() called for indirect skill %s (who: %s)\n", query_name(op, NULL), who == NULL ? "<null>" : query_name(who, NULL)); return; } if (op->level < MAXLEVEL && op->stats.exp >= (sint64) level_exp(op->level + 1, 1.0)) { op->level++; /* Show the player some effects. */ if (op->type == SKILL && who && who->type == PLAYER && who->map) { object *effect_ob; play_sound_player_only(CONTR(who), CMD_SOUND_EFFECT, "event01.ogg", 0, 0, 0, 0); if (level_up_arch) { /* Prepare effect */ effect_ob = arch_to_object(level_up_arch); effect_ob->map = who->map; effect_ob->x = who->x; effect_ob->y = who->y; if (!insert_ob_in_map(effect_ob, effect_ob->map, NULL, INS_NO_MERGE | INS_NO_WALK_ON)) { /* Something is wrong - remove object */ if (!QUERY_FLAG(effect_ob, FLAG_REMOVED)) { remove_ob(effect_ob); } } } } if (who && who->type == PLAYER && op->type != EXPERIENCE && op->type != SKILL && who->level > 1) { if (who->level > 4) { CONTR(who)->levhp[who->level] = (char) rndm(1, who->arch->clone.stats.maxhp); } else if (who->level > 2) { CONTR(who)->levhp[who->level] = (char) rndm(1, who->arch->clone.stats.maxhp / 2) + (who->arch->clone.stats.maxhp / 2); } else { CONTR(who)->levhp[who->level] = (char) who->arch->clone.stats.maxhp; } } if (op->level > 1 && op->type == EXPERIENCE) { if (who && who->type == PLAYER) { /* Mana */ if (op->stats.Pow) { if (op->level > 4) { CONTR(who)->levsp[op->level] = (char) rndm(1, who->arch->clone.stats.maxsp); } else { CONTR(who)->levsp[op->level] = (char) who->arch->clone.stats.maxsp; } } /* Grace */ else if (op->stats.Wis) { if (op->level > 4) { CONTR(who)->levgrace[op->level] = (char) rndm(1, who->arch->clone.stats.maxgrace); } else { CONTR(who)->levgrace[op->level] = (char) who->arch->clone.stats.maxgrace; } } } if (who) { snprintf(buf, sizeof(buf), "You are now level %d in %s based skills.", op->level, op->name); new_draw_info(NDI_UNIQUE | NDI_RED, who, buf); } } else if (op->level > 1 && op->type == SKILL) { if (who) { /* If we leveled up praying or wizardry, we need to send a spell list update */ if (op->stats.sp == SK_PRAYING || op->stats.sp == SK_SPELL_CASTING) { send_spelllist_cmd(who, NULL, SPLIST_MODE_UPDATE); } snprintf(buf, sizeof(buf), "You are now level %d in the skill %s.", op->level, op->name); new_draw_info(NDI_UNIQUE | NDI_RED, who, buf); } } else { if (who) { snprintf(buf, sizeof(buf), "You are now level %d.", op->level); new_draw_info(NDI_UNIQUE | NDI_RED, who, buf); } } if (who) { fix_player(who); } /* To increase more levels. */ player_lvl_adj(who, op); } else if (op->level > 1 && op->stats.exp < (sint64) level_exp(op->level, 1.0)) { op->level--; if (who) { fix_player(who); } if (op->type == EXPERIENCE) { if (who) { snprintf(buf, sizeof(buf), "-You are now level %d in %s based skills.", op->level, op->name); new_draw_info(NDI_UNIQUE | NDI_RED, who, buf); } } else if (op->type == SKILL) { if (who) { snprintf(buf, sizeof(buf), "-You are now level %d in the skill %s.", op->level, op->name); new_draw_info(NDI_UNIQUE | NDI_RED, who, buf); } } else { if (who) { snprintf(buf, sizeof(buf), "-You are now level %d.", op->level); new_draw_info(NDI_UNIQUE | NDI_RED, who, buf); } } /* To decrease more levels. */ player_lvl_adj(who, op); } }