EXP settings - Avlis
Posted: Thu May 27, 2004 11:03 pm
Here are Avlis' current EXP settings:
* set Module EXP slider to 0
* change nw_c2_default7 (and all other OnDeath scripts, as needed) to use ExecuteScript("3ed_exp_sys", OBJECT_SELF)
* make sure the following script is in your module
Using this will ensure 100% compatibility with Avlis' EXP system for combat. This is not necessary under CoPaP guidelines, as there is room for deviance above and below Avlis' settings - I am only posting this as a point of reference.
- Aloro
* set Module EXP slider to 0
* change nw_c2_default7 (and all other OnDeath scripts, as needed) to use ExecuteScript("3ed_exp_sys", OBJECT_SELF)
* make sure the following script is in your module
Code: Select all
// Name : 3ed_exp_sys.nss
// Purpose : Calculate xp for a killed creature using DMG 3rd edition rules
// Author : Aloro, based on avlis_exp_sys by Orl and Pap
// Date : created on January 29, 2004
// Modified : Feb 04, 2004 - Aloro - added towing rules, lowered max exp
// Modified : Feb 05, 2004 - Aloro - added distance calculation, var. party bonus
// Modified : Feb 07, 2004 - Aloro - tweaked towing (count highlevel 3x)
// Modified : Feb 10, 2004 - Aloro - lowered exp slider, min exp for low CR
// changed 2 GetIsObjectValid checks to GetIsPC
// Modified : Feb 11, 2004 - Aloro - lowered bonus to 1d4
// Modified : Feb 19, 2004 - Aloro - lowered exp slider & party bonus
// Modified : Mar 18, 2004 - Aloro - fixed divide by zero error, per Mistcaller
// Modified : May 06, 2004 - Aloro - added check to see if killer is DM
const int iMaximumXP = 250; // maximum for a single character
const float fSlider = 0.007; // % of Standard DMG experience rewarded
const float fDistance = 50.0; // maximum distance from killer to give experience
const float fPtySizeBonus = 0.035; // bonus per person in a group (after first)
const int iPtySizeBMax = 4; // number of party members to give bonus for
void main()
{
// make sure a PC, an associate, or a trap killed the creature
object oKiller = GetLastKiller();
object oMaster;
if (!GetIsPC(oKiller))
{
if (GetObjectType(oKiller) == OBJECT_TYPE_TRIGGER)
{
// killed by a trap
object oCreator = GetTrapCreator(oKiller);
// GetIsPC check added by Aloro Feb 10, 2004
// replaced object valid check
if (GetIsPC(oCreator))
oKiller = oCreator;
else
return; // not killed by PC placed trap
}
else
{
// test for familiar / summon
oMaster = GetMaster(oKiller);
// GetIsPC check added by Aloro Feb 10, 2004
// replaced object valid check
if (GetIsPC(oMaster))
oKiller = oMaster;
else
return; // not killed by PC pet - forget it
}
}
if (GetIsDM(oKiller) || GetIsDMPossessed(oKiller)) return;
float fEXP;
float fCR = GetChallengeRating(OBJECT_SELF);
int iCR = FloatToInt(fCR);
// exp charts start at CR 1 - lower CRs are handled later on
if (iCR < 1)
iCR = 1;
int iEXP;
int iHitDice;
int iPartyLevelSum = 0;
int iPartyMembers = 0;
int iHighLevel = 0;
int iPartyLevelAvg;
int iDifference;
int iBonus = d4(1);
object oKilledArea = GetArea(OBJECT_SELF);
// Get party average level
object oMember = GetFirstFactionMember(oKiller, FALSE);
while (GetIsObjectValid(oMember))
{
// only count those party members in the area
if (GetArea(oMember) == oKilledArea)
{
// only count members within specified distance
if (GetDistanceBetween(oMember, oKiller) <= fDistance)
{
// do not count familiars and summons as party members
oMaster = GetMaster(oMember);
if (oMaster == OBJECT_INVALID)
{
if (GetHitDice(oMember) > iHighLevel)
iHighLevel = GetHitDice(oMember);
iPartyMembers++;
iHitDice = GetHitDice(oMember);
iPartyLevelSum += iHitDice;
}
}
}
oMember = GetNextFactionMember(oKiller, FALSE);
}
// count the highest level person thrice for party average
// this is to minimize towing
iPartyLevelSum += iHighLevel;
iPartyLevelSum += iHighLevel;
iPartyMembers += 2;
iPartyLevelAvg = iPartyLevelSum / iPartyMembers;
// don't count anyone thrice when dividing shares though
iPartyMembers -= 2;
// calculate base experience when avg level = monster CR
fEXP = 300.0 * iPartyLevelAvg;
// calculate experience
iDifference = iCR - iPartyLevelAvg;
switch (iDifference)
{
case -7:
fEXP /= 12;
break;
case -6:
fEXP /= 8;
break;
case -5:
fEXP = fEXP * 3 / 16;
break;
case -4:
fEXP /= 4;
break;
case -3:
fEXP /= 3;
break;
case -2:
fEXP /= 2;
break;
case -1:
fEXP = fEXP * 2 / 3;
break;
case 0:
break;
case 1:
fEXP = fEXP * 3 / 2;
break;
case 2:
fEXP *= 2;
break;
case 3:
fEXP *= 3;
break;
case 4:
fEXP *= 4;
break;
case 5:
fEXP *= 6;
break;
case 6:
fEXP *= 8;
break;
case 7:
fEXP *= 12;
break;
}
// if CR is more than 7 levels higher or lower than party avg, exp = 1
if (abs(iDifference) > 7)
fEXP = 1.0;
// Calculations for CR < 1
if (fCR < 1.0)
fEXP *= fCR;
// factor in EXP slider
fEXP *= fSlider;
// Divide EXP into equal shares
if (iPartyMembers > 0)
fEXP /= iPartyMembers;
// minimum 1 exp for all kills
if (fEXP < 1.0)
fEXP = 1.0;
// use constants defined above to give party bonus - currently:
// 5% exp bonus for each party member after the first, max 20%
if (iPartyMembers > 1)
{
iPartyMembers--;
if (iPartyMembers > iPtySizeBMax)
iPartyMembers = iPtySizeBMax;
float fPartyBonus = iPartyMembers * fPtySizeBonus;
fPartyBonus += 1.0;
fEXP *= fPartyBonus;
}
iEXP = FloatToInt(fEXP);
// no bonus exp when high level party kills low level NPC
if (fCR <= 3.0 && abs(iDifference) > 7)
iBonus = 0;
// Give 1d4 bonus EXP
iEXP += iBonus;
// Make sure EXP does not exceed maximum
if (iEXP > iMaximumXP)
iEXP = iMaximumXP;
// Reward EXP
object oPC = GetFirstFactionMember(oKiller, TRUE);
while (GetIsObjectValid(oPC))
{
if (GetArea(oPC) == oKilledArea)
{
if (GetDistanceBetween(oPC, oKiller) <= fDistance)
GiveXPToCreature(oPC, iEXP);
}
oPC = GetNextFactionMember(oKiller, TRUE);
}
}
- Aloro