/* I worked on this code for Merc 2.2 with some changes from Rom24B6. So this code should be simular to use for any diku deriv codebase. The base working code below is exactly as it was when I pulled it from my codebase on Feb 11th, 2009. It's been tested and works. The idea came a few years ago from Avatar Mud. Basicly, this is just a general sublevel system that doesn't rely on Remort code, multiclassing or anything else. It just adds to the existing mud. Mortals = Levels 1 - 50 Heros = Level 51 (sublevels 1 - 999) Lords = Level 125 (sublevels 1 - 999) Basicly, this gives your mud an additional 2000 levels while all mobiles for heros and lords only need to be real levels 51 - 55 or so. Since sublevels have nothing to do with the actual levels, you don't need to create level 600 mobs. You can have a builder create a new hero area with all mobs set to level 51. All hero's no matter what thier sublevel is will gain exp from them. There are many other things that can be added such as the do_who command, adding the sublevels to the do_score, seperate spell/skills lists such as do_slist for mortals, do_hlist for heros and so on. To try out the hero code, make sure level_hero is set to 51, then advance a char to level 50, upon leveling, they will become a hero (level 51 )with a sublevel of 1. ---------------------------------------- Questions or Comments? Send me an email! Chris Bunting - cbunting99@gmail.com ---------------------------------------- Changes made to this version of Merc 2.2 ---------------------------------------- */ // * merc.h add... #define MAX_SUBLEVEL 999 #define MIN_SUBLEVEL 1 /* never set to 0 */ //-- added to char_data struct sh_int sublevel; // Others you may need.. #define LEVEL_HERO 51 #define LEVEL_LORD 125 //* comm.c find ch->level = 1; and add ch->sublevel = 0; /* EG: ch->level = 1; ch->sublevel = 0; ch->train = 21; ch->practice = 6; */ //* save.c //-- added to fwrite_char the line below: fprintf (fp, "SubLevel %d\n", ch->sublevel); //-- added to fread_char under CASE 'S' the line below: KEY ("SubLevel", ch->sublevel, fread_number (fp)); //* update.c //-- Took existing code in update.c gain_exp and reworked it for sublevels. /////////// Modified do_gain in update.c /////////// /* * Modified do_gain for lots of sublevels.. Chris */ void gain_exp (CHAR_DATA * ch, int gain) { char buf[MAX_STRING_LENGTH]; if (IS_NPC (ch) || ch->level >= LEVEL_IMMORTAL) return; // ch->exp = ch->exp + gain; ch->exp = UMAX (exp_per_level (ch, ch->pcdata->exp_lvl), ch->exp + gain); while (ch->level < LEVEL_IMMORTAL && ch->exp >= exp_per_level (ch, ch->pcdata->exp_lvl) * (ch->level + 1)) { /* * Mortals Level 1 - 50 */ while (ch->level < LEVEL_HERO) { send_to_char ("{MYou raise a level!!{x ", ch); ch->level += 1; advance_level (ch); sprintf (buf, "{wThe Mayor Yells, %s has now raised in power to level %d!{x", ch->name, ch->level); do_function (ch, &do_iecho, buf); sprintf (buf, "%s is now mortal level %d.", ch->name, ch->level); wiznet (ch, WIZ_LEVELS, get_trust (ch), buf); return; } /* * Heros Level 51, Sublevels 1 - 999 */ while (ch->level == LEVEL_HERO && ch->sublevel >= MIN_SUBLEVEL < MAX_SUBLEVEL) { send_to_char ("{MYou raise a sublevel!!{x ", ch); ch->exp = ch->exp - exp_per_level (ch, ch->pcdata->exp_lvl); ch->sublevel += 1; advance_level (ch); sprintf (buf, "{wThe Mayor Yells, %s has now raised in power to hero level %d!{x", ch->name, ch->sublevel); do_function (ch, &do_iecho, buf); sprintf (buf, "%s is now hero level %d.", ch->name, ch->sublevel); wiznet (ch, WIZ_LEVELS, get_trust (ch), buf); return; } /* * Lords Level 125, Sublevels 1 - 999 */ while (ch->level == LEVEL_LORD && ch->sublevel >= MIN_SUBLEVEL < MAX_SUBLEVEL) { send_to_char ("{MYou raise a sublevel!!{x ", ch); ch->exp = ch->exp - exp_per_level (ch, ch->pcdata->exp_lvl); ch->sublevel += 1; advance_level (ch); sprintf (buf, "{wThe Mayor Yells, %s has now raised in power to lord level %d!{x", ch->name, ch->sublevel); do_function (ch, &do_iecho, buf); sprintf (buf, "%s is now lord level %d.", ch->name, ch->sublevel); wiznet (ch, WIZ_LEVELS, get_trust (ch), buf); return; } } return; } // advance_level (update.c) add these above the last return; // These two bits are only used once per player. Upon reaching // Level 51 and 125 if (ch->sublevel < 1 && ch->level == LEVEL_HERO) { sprintf (buf, "{cWelcome to Hero %s!!{x\n\r", ch->name); send_to_char (buf, ch); ch->sublevel++; do_function (ch, &do_help, "GRATS_HERO"); } if (ch->sublevel >= 1 && ch->level == LEVEL_LORD) { sprintf (buf, "{cWelcome to Lord %s!!{x\n\r", ch->name); send_to_char (buf, ch); ch->sublevel = 1; do_function (ch, &do_help, "GRATS_LORD"); } /* This is just the basics of the system. do_slist can show all spells and skills for mortal levels 1 - 50. Rename do_slist to do_hlist for heros showing all level 51 or Hero skills spells. You can check for ch->level == LEVEL_HERO && sublevel 10 to give a new skill/spell to a hero at sublevel 10 and so on. */ ///// You may want this too.. do_advance void do_advance (CHAR_DATA * ch, char *argument) { char buf[MAX_STRING_LENGTH]; char arg1[MAX_INPUT_LENGTH]; bool sublevel = FALSE; CHAR_DATA *victim; int level; int iLevel; argument = one_argument (argument, arg1); if (arg1[0] == '\0' || argument[0] == '\0') { send_to_char ("Syntax: advance [sublevel|level] \n\r", ch); return; } if ((victim = get_char_world (ch, arg1)) == NULL) { send_to_char ("That player is not here.\n\r", ch); return; } if (IS_NPC (victim)) { send_to_char ("Not on NPC's.\n\r", ch); return; } if (victim->sublevel) { argument = one_argument (argument, arg1); if (argument[0] == '\0' || !is_number (argument) || (str_cmp (arg1, "level") && str_cmp (arg1, "sublevel"))) { send_to_char ("For chars that are heros/lords, please specify level or sublevel.\n\r", ch); return; } if (!str_cmp (arg1, "sublevel")) sublevel = TRUE; } if (!is_number (argument)) { send_to_char ("Usage: advance [sublevel|level] \n\r", ch); return; } level = atoi (argument); if (level <= 0 || level > MAX_LEVEL) { sprintf (buf, "Advance within range 1 to %d.\n\r", MAX_SUBLEVEL); send_to_char (buf, ch); return; } if (victim->sublevel && (level > victim->level || (sublevel && level <= victim->sublevel))) { send_to_char ("For hero or lords, you may only demote them to a\n\r" "lower level, or promote them sublevels.\n\r", ch); return; } /* * Lower level: * Reset to level 1. * Then raise again. * Currently, an imp can lower another imp. * -- Swiftest */ if (!sublevel && level <= victim->level) { int temp_prac; int temp_train; send_to_char ("Lowering a player's level!\n\r", ch); send_to_char ("**** OOOOHHHHHHHHHH NNNNOOOO ****\n\r", victim); temp_prac = victim->practice; temp_train = victim->train; victim->level = 1; victim->sublevel = 0; victim->exp = exp_per_level (victim, victim->pcdata->exp_lvl); victim->max_hit = 20; victim->max_mana = 100; victim->max_move = 100; victim->hit = victim->max_hit; victim->mana = victim->max_mana; victim->move = victim->max_move; advance_level (victim); victim->practice = temp_prac; victim->train = temp_train; } else { send_to_char ("Raising a player's level!\n\r", ch); send_to_char ("**** OOOOHHHHHHHHHH YYYYEEEESSS ****\n\r", victim); } if (victim->sublevel > 0) { for (iLevel = victim->sublevel; iLevel < level; iLevel++) { victim->sublevel += 1; advance_level (victim); } } else { for (iLevel = victim->level; iLevel < level; iLevel++) { victim->level += 1; advance_level (victim); } } sprintf (buf, "You are now level %d.\n\r", victim->level); send_to_char (buf, victim); victim->exp = exp_per_level (victim, victim->pcdata->exp_lvl) * UMAX (1, victim->level); victim->trust = 0; save_char_obj (victim); return; }