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); }
/* Some initializations for characters, including initial skills If mode == 0, then act as though the character was entering the game for the first time. Otherwise, act as though the character is being set to that level. */ void do_start(struct creature *ch, int mode) { void advance_level(struct creature *ch, int8_t keep_internal); int8_t new_player = 0; int i; struct obj_data *implant_save[NUM_WEARS]; struct obj_data *tattoo_save[NUM_WEARS]; // remove implant affects for (i = 0; i < NUM_WEARS; i++) { if (GET_IMPLANT(ch, i)) implant_save[i] = raw_unequip_char(ch, i, EQUIP_IMPLANT); else implant_save[i] = NULL; if (GET_TATTOO(ch, i)) tattoo_save[i] = raw_unequip_char(ch, i, EQUIP_TATTOO); else tattoo_save[i] = NULL; } if (GET_EXP(ch) == 0 && !IS_REMORT(ch) && !IS_VAMPIRE(ch)) new_player = true; GET_LEVEL(ch) = 1; GET_EXP(ch) = 1; if (mode) roll_real_abils(ch); for (i = 1; i <= MAX_SKILLS; i++) SET_SKILL(ch, i, 0); if (IS_VAMPIRE(ch)) GET_LIFE_POINTS(ch) = 1; else GET_LIFE_POINTS(ch) = 3 * (GET_WIS(ch) + GET_CON(ch)) / 40; ch->points.max_hit = 20; ch->points.max_mana = 100; ch->points.max_move = 82; if (IS_TABAXI(ch)) { SET_SKILL(ch, SKILL_CLAW, LEARNED(ch)); SET_SKILL(ch, SKILL_BITE, LEARNED(ch)); } if (IS_ELF(ch)) { SET_SKILL(ch, SKILL_ARCHERY, LEARNED(ch)); } switch (GET_CLASS(ch)) { case CLASS_MAGIC_USER: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_CLERIC: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_THIEF: SET_SKILL(ch, SKILL_PUNCH, 15); SET_SKILL(ch, SKILL_SNEAK, 10); SET_SKILL(ch, SKILL_HIDE, 5); SET_SKILL(ch, SKILL_STEAL, 15); break; case CLASS_WARRIOR: SET_SKILL(ch, SKILL_PUNCH, 20); break; case CLASS_BARB: SET_SKILL(ch, SKILL_PUNCH, 15); break; case CLASS_PSIONIC: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_PHYSIC: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_CYBORG: SET_SKILL(ch, SKILL_PUNCH, 10); break; case CLASS_KNIGHT: SET_SKILL(ch, SKILL_PUNCH, 20); break; case CLASS_RANGER: SET_SKILL(ch, SKILL_PUNCH, 15); GET_MAX_MOVE(ch) += dice(4, 9); break; case CLASS_MONK: SET_SKILL(ch, SKILL_PUNCH, 20); break; case CLASS_MERCENARY: SET_SKILL(ch, SKILL_PUNCH, 20); case CLASS_BARD: SET_SKILL(ch, SKILL_PUNCH, 25); SET_SKILL(ch, SKILL_ARCHERY, 25); break; } if (new_player) { if (PAST_CLASS(GET_CLASS(ch))) { deposit_past_bank(ch->desc->account, 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch)); ch->points.gold = 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch); } else if (FUTURE_CLASS(GET_CLASS(ch))) { deposit_future_bank(ch->desc->account, 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch)); ch->points.cash = 8192 + number(256, 2048) + GET_INT(ch) + GET_WIS(ch); } // New players do not start with the gown at this point // This has been left in for reference for generic newbie starting gear for the future. // New players start with a hospital gown and items most dear to them /* struct obj_data *gown = read_object(33800); if (gown != NULL) { equip_char(ch, gown, WEAR_ABOUT, EQUIP_WORN); } */ // Good clerics start with a holy symbol on neck if ((GET_CLASS(ch) == CLASS_CLERIC) && IS_GOOD(ch)) { struct obj_data *talisman = read_object(1280); if (talisman != NULL) { equip_char(ch, talisman, WEAR_NECK_1, EQUIP_WORN); } } // Evil clerics start with a holy symbol on hold if ((GET_CLASS(ch) == CLASS_CLERIC) && IS_EVIL(ch)) { struct obj_data *symbol = read_object(1260); if (symbol != NULL) { equip_char(ch, symbol, WEAR_HOLD, EQUIP_WORN); } } // Good knights start with a holy symbol on finger if ((GET_CLASS(ch) == CLASS_KNIGHT) && IS_GOOD(ch)) { struct obj_data *ring = read_object(1287); if (ring != NULL) { equip_char(ch, ring, WEAR_FINGER_L, EQUIP_WORN); } } // Evil knights start with a holy symbol on neck if ((GET_CLASS(ch) == CLASS_KNIGHT) && IS_EVIL(ch)) { struct obj_data *pendant = read_object(1270); if (pendant != NULL) { equip_char(ch, pendant, WEAR_NECK_1, EQUIP_WORN); } } // Bards start with a percussion instrument held, and stringed in inventory if (GET_CLASS(ch) == CLASS_BARD) { struct obj_data *lute = read_object(3218); if (lute != NULL) { obj_to_char(lute, ch); } } set_title(ch, "the complete newbie"); } advance_level(ch, 0); GET_MAX_MOVE(ch) += GET_CON(ch); GET_HIT(ch) = GET_MAX_HIT(ch); GET_MANA(ch) = GET_MAX_MANA(ch); GET_MOVE(ch) = GET_MAX_MOVE(ch); GET_COND(ch, THIRST) = 24; GET_COND(ch, FULL) = 24; GET_COND(ch, DRUNK) = 0; if (new_player) { ch->player.time.played = 0; ch->player.time.logon = time(NULL); } for (i = 0; i < NUM_WEARS; i++) { if (implant_save[i]) equip_char(ch, implant_save[i], i, EQUIP_IMPLANT); if (tattoo_save[i]) equip_char(ch, tattoo_save[i], i, EQUIP_TATTOO); } }
/* * 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); }
const char *char_data::get_whoname( ) { char buf[MSL] = {'\0'}; short s1, s2, s3, s4, s5; const char *output; if ( IS_NPC(this) ) return ""; if ( IS_IMMORTAL(this) ) { if ( strcmp(pcdata->who_name,"off") ) return pcdata->who_name; switch ( get_level() ) { case MAX_LEVEL - 0: return "@@l~* CREATOR *~@@N "; case MAX_LEVEL - 1: return "@@B-* SUPREME *-@@N "; case MAX_LEVEL - 2: return "@@a-=MAJOR GOD=-@@N "; case MAX_LEVEL - 3: return "@@a--MINOR GOD--@@N "; case MAX_LEVEL - 4: return "@@c - IMMORTAL -@@N "; } } if ( IS_ADEPT(this) ) { if ( strcmp(pcdata->who_name,"off") ) return pcdata->who_name; switch ( get_level("adept") ) { case 1: return "@@W Mystic @@N"; case 2: return "@@a Templar @@N"; case 3: return "@@l Illusionist @@N"; case 4: return "@@e Crusader @@N"; case 5: return "@@d Warlock @@N"; case 6: return "@@a Paladin @@N"; case 7: return "@@r Ranger @@N"; case 8: return "@@c Gladiator @@N"; case 9: return "@@l Shogun @@N"; case 10: return "@@e Shamen @@N"; case 11: return "@@r Druid @@N"; case 12: return "@@b Conjurer @@N"; case 13: return "@@l Elementalist @@N"; case 14: return "@@m Runemaster @@N"; case 15: return "@@d Shadowmaster @@N"; case 16: return "@@b Beastmaster @@N"; case 17: return "@@R Warlord @@N"; case 18: return "@@e Dragonlord @@N"; case 19: return "@@d Demonlord @@N"; case 20: return "@@m Realm Lord @@N"; } } if ( IS_REMORT(this) ) { s1 = get_level("sor"); s2 = get_level("mon"); s3 = get_level("ass"); s4 = get_level("kni"); s5 = get_level("nec"); snprintf( buf, MSL, "@@m%2d %2d %2d %2d %2d@@N", s1 <= 0 ? 0 : s1, s2 <= 0 ? 0 : s2, s3 <= 0 ? 0 : s3, s4 <= 0 ? 0 : s4, s5 <= 0 ? 0 : s5 ); output = str_dup( buf ); return output; } else { s1 = get_level("mag"); s2 = get_level("cle"); s3 = get_level("thi"); s4 = get_level("war"); s5 = get_level("psi"); snprintf( buf, MSL, "@@b%2d %2d %2d %2d %2d@@N", s1 <= 0 ? 0 : s1, s2 <= 0 ? 0 : s2, s3 <= 0 ? 0 : s3, s4 <= 0 ? 0 : s4, s5 <= 0 ? 0 : s5 ); output = str_dup( buf ); return output; } return ""; }