/***************************************************************************** * DikuMUD (C) 1990, 1991 by: * * Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, * * and Katja Nyboe. * *---------------------------------------------------------------------------* * MERC 2.1 (C) 1992, 1993 by: * * Michael Chastain, Michael Quan, and Mitchell Tse. * *---------------------------------------------------------------------------* * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. * * Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, * * gorog, Grishnakh, Nivek, Tricops, and Fireblade. * *---------------------------------------------------------------------------* * SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. * * Their contributions are greatly appreciated. * *---------------------------------------------------------------------------* * LoP (C) 2006, 2007, 2008 by: the LoP team. * *****************************************************************************/ #include <stdio.h> #include <string.h> #include <math.h> #include "h/mud.h" /* Calculate roughly how much experience a character is worth */ double get_exp_worth( CHAR_DATA *ch ) { double wexp; wexp = ( ch->level * ch->level * UMAX( 1, ch->level / 2 ) ); return durange( MIN_EXP_WORTH, wexp, MAX_EXP_WORTH ); } double exp_level( CHAR_DATA *ch, int level ) { double lvl; lvl = durange( 1, level, MAX_LEVEL ); return ( 20 + ( lvl * lvl * lvl ) ); } double xp_compute( CHAR_DATA *gch, CHAR_DATA *victim ) { double xp; if( ( victim->level - gch->level ) > 10 ) return 0; if( ( gch->level - victim->level ) > 10 ) return 0; xp = get_exp_worth( victim ); if( !is_npc( gch ) && is_npc( victim ) ) { int times = times_killed( gch, victim ); if( times >= 20 ) xp = 0; else if( times ) { xp = ( xp * ( 20 - times ) ) / 20; if( times > 15 ) xp /= 3; else if( times > 10 ) xp /= 1.5; } } return durange( 0, xp, exp_level( gch, gch->level ) ); } /* Advancement stuff. */ void advance_level( CHAR_DATA *ch ) { if( !is_npc( ch ) ) { set_char_color( AT_WHITE, ch ); if( ( ch->level % 2 ) == 1 ) { send_to_char( "You have gained another practice session.\r\n", ch ); ch->practice += 1; } /* Restore them if needed */ if( ch->hit < ch->max_hit ) ch->hit = ch->max_hit; if( ch->mana < ch->max_mana ) ch->mana = ch->max_mana; if( ch->move < ch->max_move ) ch->move = ch->max_move; if( ch->level == MAX_LEVEL ) { playing_printf( ch, "&[immortal]%s has just achieved Avatarhood!&[white]\r\n", ch->name ); do_help( ch, "M_ADVHERO_" ); ch->exp = 0.0; } } } void gain_exp( CHAR_DATA *ch, double gain ) { double modgain, oldexp, gained; if( is_npc( ch ) ) return; if( ch->level >= MAX_LEVEL ) { ch->exp = 0.0; return; } modgain = gain; /* No one goes below current exp for the level they are */ if( ( ch->exp + modgain ) < 0 ) modgain = ch->exp; modgain = dumin( modgain, exp_level( ch, ch->level ) ); oldexp = ch->exp; ch->exp = dumax( 0, ch->exp + ( int )modgain ); gained = ( ch->exp - oldexp ); if( not_authed( ch ) && ch->exp >= exp_level( ch, ch->level ) ) { send_to_char( "You can't ascend to a higher level until you are authorized.\r\n", ch ); ch->exp = ( exp_level( ch, ch->level ) - 1 ); return; } if( gained != 0 ) ch_printf( ch, "You %s %s experience points.\r\n", gained > 0 ? "received" : "lost", double_punct( fabs( gained ) ) ); while( ch->level < MAX_LEVEL && ch->exp >= exp_level( ch, ( ch->level + 1 ) ) ) { set_char_color( AT_WHITE + AT_BLINK, ch ); ch->level += 1; ch->exp -= exp_level( ch, ch->level ); ch_printf( ch, "You have obtained level %d!\r\n", ch->level ); advance_level( ch ); set_char_color( AT_PLAIN, ch ); } } /* Display your current exp, level, and surrounding level exp requirements - Thoric */ CMDF( do_level ) { int x, lowlvl, hilvl; char arg[MIL], *s1, *s2; s1 = color_str( AT_SCORE, ch ); s2 = color_str( AT_SCORE2, ch ); lowlvl = UMAX( 1, ch->level - 5 ); if( argument && argument[0] != '\0' ) { argument = one_argument( argument, arg ); lowlvl = URANGE( 1, ( atoi( arg ) - 5 ), MAX_LEVEL ); } hilvl = URANGE( lowlvl, ( lowlvl + 10 ), MAX_LEVEL ); ch_printf( ch, "\r\n%sExperience required from level %s%d %sto %s%d%s:\r\n", s1, s2, lowlvl, s1, s2, hilvl, s1 ); ch_printf( ch, "%s.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.\r\n", s1 ); for( x = lowlvl; x <= hilvl; x++ ) { ch_printf( ch, "%s%s%s%5d%s> %s%12s %sexp", s1, x == ch->level ? "*" : " ", s2, x, s1, s2, double_punct( exp_level( ch, x ) ), s1 ); if( x == ch->level ) ch_printf( ch, " %s(Current: %s%12s%s)", s1, s2, double_punct( ch->exp ), s1 ); else if( x == ( ch->level + 1 ) ) ch_printf( ch, " %s(Needed: %s%12s%s)", s1, s2, double_punct( exp_level( ch, ch->level + 1 ) - ch->exp ), s1 ); send_to_char( "\r\n", ch ); } ch_printf( ch, "%s.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.~`~.\r\n", s1 ); }