[
www.khaostheory.net]
(1500 + (300 * (level - 1)) + penalty + ((penalty / 5) * (level - 1))) was the formula I used to make it as you can see in the source.
As for how experience is calculated, let's see what the original code looks like... Well, it looks quite a bit more complicated than a simple formula can show. Interestingly, Alignments may be more than just three specific sections. Also, there is a randomizer, also it looks like you get a bonus for time played, if that hasn't changed since original code. Never noticed it so it could have changed. And, of course, they may have changed every single bit of this over the years so none of it is even close, who knows, but may likely have bits still used.
void group_gain( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *gch;
CHAR_DATA *lch;
int xp;
int members;
int group_levels;
/*
* Monsters don't get kill xp's or alignment changes.
* P-killing doesn't help either.
* Dying of mortal wounds or poison doesn't give xp to anyone!
*/
if ( victim == ch )
return;
members = 0;
group_levels = 0;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( is_same_group( gch, ch ) )
{
members++;
group_levels += IS_NPC(gch) ? gch->level / 2 : gch->level;
}
}
if ( members == 0 )
{
bug( "Group_gain: members.", members );
members = 1;
group_levels = ch->level ;
}
lch = (ch->leader != NULL) ? ch->leader : ch;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
OBJ_DATA *obj;
OBJ_DATA *obj_next;
if ( !is_same_group( gch, ch ) || IS_NPC(gch))
continue;
/* Taken out, add it back if you want it
if ( gch->level - lch->level >= 5 )
{
send_to_char( "You are too high for this group.\n\r", gch );
continue;
}
if ( gch->level - lch->level <= -5 )
{
send_to_char( "You are too low for this group.\n\r", gch );
continue;
}
*/
xp = xp_compute( gch, victim, group_levels );
sprintf( buf, "You receive %d experience points.\n\r", xp );
send_to_char( buf, gch );
gain_exp( gch, xp );
for ( obj = ch->carrying; obj != NULL; obj = obj_next )
{
obj_next = obj->next_content;
if ( obj->wear_loc == WEAR_NONE )
continue;
if ( ( IS_OBJ_STAT(obj, ITEM_ANTI_EVIL) && IS_EVIL(ch) )
|| ( IS_OBJ_STAT(obj, ITEM_ANTI_GOOD) && IS_GOOD(ch) )
|| ( IS_OBJ_STAT(obj, ITEM_ANTI_NEUTRAL) && IS_NEUTRAL(ch) ) )
{
act( "You are zapped by $p.", ch, obj, NULL, TO_CHAR );
act( "$n is zapped by $p.", ch, obj, NULL, TO_ROOM );
obj_from_char( obj );
obj_to_room( obj, ch->in_room );
}
}
}
return;
}
/*
* Compute xp for a kill.
* Also adjust alignment of killer.
* Edit this function to change xp computations.
*/
int xp_compute( CHAR_DATA *gch, CHAR_DATA *victim, int total_levels )
{
int xp,base_exp;
int align,level_range;
int change;
int time_per_level;
level_range = victim->level - gch->level;
/* compute the base exp */
switch (level_range)
{
default : base_exp = 0; break;
case -9 : base_exp = 1; break;
case -8 : base_exp = 2; break;
case -7 : base_exp = 5; break;
case -6 : base_exp = 9; break;
case -5 : base_exp = 11; break;
case -4 : base_exp = 22; break;
case -3 : base_exp = 33; break;
case -2 : base_exp = 50; break;
case -1 : base_exp = 66; break;
case 0 : base_exp = 83; break;
case 1 : base_exp = 99; break;
case 2 : base_exp = 121; break;
case 3 : base_exp = 143; break;
case 4 : base_exp = 165; break;
}
if (level_range > 4)
base_exp = 160 + 20 * (level_range - 4);
/* do alignment computations */
align = victim->alignment - gch->alignment;
if (IS_SET(victim->act,ACT_NOALIGN))
{
/* no change */
}
else if (align > 500) /* monster is more good than slayer */
{
change = (align - 500) * base_exp / 500 * gch->level/total_levels;
change = UMAX(1,change);
gch->alignment = UMAX(-1000,gch->alignment - change);
}
else if (align < -500) /* monster is more evil than slayer */
{
change = ( -1 * align - 500) * base_exp/500 * gch->level/total_levels;
change = UMAX(1,change);
gch->alignment = UMIN(1000,gch->alignment + change);
}
else /* improve this someday */
{
change = gch->alignment * base_exp/500 * gch->level/total_levels;
gch->alignment -= change;
}
/* calculate exp multiplier */
if (IS_SET(victim->act,ACT_NOALIGN))
xp = base_exp;
else if (gch->alignment > 500) /* for goodie two shoes */
{
if (victim->alignment < -750)
xp = (base_exp *4)/3;
else if (victim->alignment < -500)
xp = (base_exp * 5)/4;
else if (victim->alignment > 750)
xp = base_exp / 4;
else if (victim->alignment > 500)
xp = base_exp / 2;
else if (victim->alignment > 250)
xp = (base_exp * 3)/4;
else
xp = base_exp;
}
else if (gch->alignment < -500) /* for baddies */
{
if (victim->alignment > 750)
xp = (base_exp * 5)/4;
else if (victim->alignment > 500)
xp = (base_exp * 11)/10;
else if (victim->alignment < -750)
xp = base_exp/2;
else if (victim->alignment < -500)
xp = (base_exp * 3)/4;
else if (victim->alignment < -250)
xp = (base_exp * 9)/10;
else
xp = base_exp;
}
else if (gch->alignment > 200) /* a little good */
{
if (victim->alignment < -500)
xp = (base_exp * 6)/5;
else if (victim->alignment > 750)
xp = base_exp/2;
else if (victim->alignment > 0)
xp = (base_exp * 3)/4;
else
xp = base_exp;
}
else if (gch->alignment < -200) /* a little bad */
{
if (victim->alignment > 500)
xp = (base_exp * 6)/5;
else if (victim->alignment < -750)
xp = base_exp/2;
else if (victim->alignment < 0)
xp = (base_exp * 3)/4;
else
xp = base_exp;
}
else /* neutral */
{
if (victim->alignment > 500 || victim->alignment < -500)
xp = (base_exp * 4)/3;
else if (victim->alignment < 200 && victim->alignment > -200)
xp = base_exp/2;
else
xp = base_exp;
}
/* more exp at the low levels */
if (gch->level < 6)
xp = 10 * xp / (gch->level + 4);
/* less at high */
if (gch->level > 35 )
xp = 15 * xp / (gch->level - 25 );
/* reduce for playing time */
{
/* compute quarter-hours per level */
time_per_level = 4 *
(gch->played + (int) (current_time - gch->logon))/3600
/ gch->level;
time_per_level = URANGE(2,time_per_level,12);
if (gch->level < 15) /* make it a curve */
time_per_level = UMAX(time_per_level,(15 - gch->level));
xp = xp * time_per_level / 12;
}
/* randomize the rewards */
xp = number_range (xp * 3/4, xp * 5/4);
/* adjust for grouping */
xp = xp * gch->level/( UMAX(1,total_levels -1) );
return xp;
}
Edited 6 time(s). Last edit at 11/28/2018 09:29AM by KoeKhaos.