Author Topic: Adjusting XP based on PC level  (Read 898 times)

Legacy_Gawain_VIII

  • Newbie
  • *
  • Posts: 28
  • Karma: +0/-0
Adjusting XP based on PC level
« on: April 24, 2016, 07:48:24 am »


               

I want to drastically slow XP advancement for a low-power module without actually placing level-caps...


 


What I'm thinking is to modify XP (regardless of source: monster kills, quest completion, DM rewards, etc.) by dividing the "standard" amount (minus default Multiclass * Party size penalties) by the PC's current level (rounded down, Min 10% of base XP or 1XP, whichever is greater, per reward event).


 


This way, a 2nd level character will take twice as long to earn the same number of XP as a 1st level character and a 5th level PC will take 5 times longer to gain the same number of EXP points while still guaranteeing ... I don't want to modify the experience chart--just the amount awarded.


 


Is this possible via scripting, or would I have to alter a .2da file?



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Adjusting XP based on PC level
« Reply #1 on: April 24, 2016, 08:22:53 am »


               For single player, SetModuleXPScale would probably do it. I haven't tried, but presumably you could call this OnPlayerLevelUp. It's going to be crude, though. Assuming the default scale is 10, you're limited to integers in the range 1-10 for your purpose. Beyond level 10, no more nerfing is possible.

Clearly that won't work for multiplayer, either.

Alternative is to set the module XP scale to zero. Write your own code for all XP-awarding events e.g. OnDeath using GiveXPToCreature.
               
               

               
            

Legacy_Wallack

  • Full Member
  • ***
  • Posts: 221
  • Karma: +0/-0
Adjusting XP based on PC level
« Reply #2 on: April 24, 2016, 05:59:35 pm »


               

Set the module xp to 0 and then create your own ondeath script that will give a fixedamount/level xp.



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Adjusting XP based on PC level
« Reply #3 on: April 28, 2016, 04:51:27 am »


               

Here is a scripted xp method that replicates the official xp tables. With this method you do not need to use the xp tables 2da. The only thing is that because the required use of floats, the return values may occasionally be off by 1 xp when compared to the standard xp table. Look at the notes in the script for any info.


 


You do need to set the modules default xp award to "0" and call the XPFromAnEncounter int function to return the proper xp amount from any on death script you wish to award xp's from.


 


Note that the party level is the suggested determiner for xp amount awarded. The method does not modify xp's awarded for favored class or unbalanced multiclass levels, that should be done to the returned amount from whatever method calling this function.


 


Use it if it helps with your endeavor.


 


/*::////////////////////////////////////////////////////////////////////////////
//:: Name: KMdS PNP Hard Core Rule Set 1.0
//:: System: KMdS NESS D&D 3rd ed XP Tables
//:: FileName: KMdS_XP_Table
//:: Copyright (c) 2005 Michael Careaga
//::////////////////////////////////////////////////////////////////////////////
 
    This is a scripted recreation of the 3rd ed D&D experience point table.
    There are 2 values returned that do not match the XP table.  It seems they
    didn't actually trust their own numbers so they fudged two of their xp
    table entries.  Looking at it from a purely mathmatical perspective, mine
    is the corrected version.
    KMdS
 
    note*
         Due to the necessary use of floats, and their conversion into int's,
         the actual xp value returned may occasionally be off by 1 XPwhen compared
         to the official 3rd ed D&D experience point tables.
 
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Kilr Mik d Spik
//:: Created On: 05/01/2005
//:://////////////////////////////////////////////////////////////////////////*/
 
//  ----------------------------------------------------------------------------
//  PUBLIC PROTOTYPES
//  ----------------------------------------------------------------------------
 
// This is the actual mathmatical formula for the D&D 3rd ed experience tables.
// Enter the level of the party involved in the kill and the CR of the
// creature killed.  You may adjust the base amount of experience to be awarded
// up or down by setting the percent awarded float to any positive float value.
int XPFromAnEncounter(int nPartyLevel, float fCreatureCR, float fPercentAwarded = 100.0f);
 
//  ----------------------------------------------------------------------------
//  FUNCTIONS
//  ----------------------------------------------------------------------------
 
// This divisor is used for encounters with creatures of less than CR1 , ie 1/8, 1/4, 1/3, 1/2,
// to proportionately adjust the XP's given based on the creatures CR.  Default return value = 1.
int Divisor(float fCreatureCR)
{
    int nDivisor;
    if      (fCreatureCR<0.25f)     nDivisor=8;
    else if (fCreatureCR<0.33f)     nDivisor=4;
    else if (fCreatureCR<0.50f)     nDivisor=3;
    else if (fCreatureCR<1.00f)     nDivisor=2;
    else                            nDivisor=1;
    return nDivisor;
}
 
// This is the multiplier used when determining XP's based on the difference in a
// PC's level vs a creatures CR.
float Multiplier(int nCreatureCR, int nPartyLvl)
{
    int nDeterminerValue = abs(nCreatureCR-nPartyLvl);
    float fMultiplier;
    if      (nDeterminerValue == 7) fMultiplier =12.0f;
    else if (nDeterminerValue == 6) fMultiplier = 8.0f;
    else if (nDeterminerValue == 5) fMultiplier = 6.0f;
    else if (nDeterminerValue == 4) fMultiplier = 4.0f;
    else if (nDeterminerValue == 3) fMultiplier = 3.0f;
    else if (nDeterminerValue == 2) fMultiplier = 2.0f;
    else if (nDeterminerValue == 1) fMultiplier = 1.5f;
    else if (nDeterminerValue == 0) fMultiplier = 1.0f;
    return fMultiplier;
}
 
// This base value adjustment to XP's awarded is needed to duplicate the XP values
// given in the 3rd ed D&D XP tables.
float BaseAwardAdjustment(int nCreatureCR, int nPartyLvl)
{
    int nCRDifference = nCreatureCR-nPartyLvl;
    float fBaseAwardAdjustment;
    if      (nCRDifference ==  7) fBaseAwardAdjustment = -25200.0f;
    else if (nCRDifference ==  6) fBaseAwardAdjustment = -14400.0f;
    else if (nCRDifference ==  5) fBaseAwardAdjustment =  -9000.0f;
    else if (nCRDifference ==  4) fBaseAwardAdjustment =  -4800.0f;
    else if (nCRDifference ==  3) fBaseAwardAdjustment =  -2700.0f;
    else if (nCRDifference ==  2) fBaseAwardAdjustment =  -1200.0f;
    else if (nCRDifference ==  1) fBaseAwardAdjustment =   -450.0f;
    else if (nCRDifference ==  0) fBaseAwardAdjustment =      0.0f;
    else if (nCRDifference == -1) fBaseAwardAdjustment =    200.0f;
    else if (nCRDifference == -2) fBaseAwardAdjustment =    300.0f;
    else if (nCRDifference == -3) fBaseAwardAdjustment =    300.0f;
    else if (nCRDifference == -4) fBaseAwardAdjustment =    300.0f;
    else if (nCRDifference == -5) fBaseAwardAdjustment =    275.0f;
    else if (nCRDifference == -6) fBaseAwardAdjustment =    250.0f;
    else if (nCRDifference == -7) fBaseAwardAdjustment =    237.5f;
    return fBaseAwardAdjustment;
}
 
int XPFromAnEncounter(int nPartyLevel, float fCreatureCR, float fPercentAwarded = 100.0f)
{
    // PNP D&D XP tables are set to a base experience of 300.
    int BASEEXPERIENCE = 300;
    int nDivisor = Divisor(fCreatureCR);
 
    // The minimum CR for figuring xp award is 1.0.  If less than that, set to 1.0 by default.
    if(fCreatureCR<1.0f) fCreatureCR=1.0f;
 
    int nCreatureCR = FloatToInt(fCreatureCR);
    int nCreatureCRvsPartyLevel = nCreatureCR-nPartyLevel;
    int nXpsToAwardForTheKill = BASEEXPERIENCE * nCreatureCR;
    float fXpsToAwardForTheKill;
 
 
    // If the difference between the CR and player levels is greater than 7, return no xp's awarded.
    if      (abs(nCreatureCRvsPartyLevel) > 7) return 0;
    // Otherwise, if the creatures CR is equal to or greater than the party's level
    else if (nCreatureCRvsPartyLevel >= 0)
        fXpsToAwardForTheKill = nXpsToAwardForTheKill * Multiplier(nCreatureCR, nPartyLevel);
    // The creatures CR is less than the party's level
    else
        fXpsToAwardForTheKill = nXpsToAwardForTheKill / Multiplier(nCreatureCR, nPartyLevel);
 
    fXpsToAwardForTheKill += BaseAwardAdjustment(nCreatureCR, nPartyLevel);
    nXpsToAwardForTheKill = FloatToInt(fXpsToAwardForTheKill);
 
    fPercentAwarded/=100.0;
    nXpsToAwardForTheKill/=nDivisor;
    return nXpsToAwardForTheKill = FloatToInt((nXpsToAwardForTheKill * fPercentAwarded)+0.01);
}

               
               

               
            

Legacy_Gawain_VIII

  • Newbie
  • *
  • Posts: 28
  • Karma: +0/-0
Adjusting XP based on PC level
« Reply #4 on: April 29, 2016, 02:05:37 am »


               

This is great! Thanks.


 


So, if I understand this correctly (please, bear with me), I should #include this your script in a general OnDeath script for all my creatures and use the final int nXpsToAwardForTheKill when calculating my nerf...


 


Using LilacSoul's Generator & the NWN Lexicon as references, I've come up with:



#include "nw_i0_tool"
#include "KMdS_XP_Table"
void main()
{
// Who killed me?
object oPC = GetLastKiller();
 
// Is the killer a henchman, familiar, or summon? If so, find the PC owner.
while (GetIsObjectValid(GetMaster(oPC)));
    {
    oPC=GetMaster(oPC);
    }
 
if (!GetIsPC(oPC)) return;

// Find the Party Leader 
object oPartyMember = GetFirstFactionMember(oPC, TRUE);
// Cycle through each member of the party
while(GetIsObjectValid(oPartyMember) == TRUE)
    {
// Divide calculated XP by PC's Level
    int nNerfXP = nXpsToAwardForTheKill/GetHitDice(oPartyMember);
// Give nerfed XP to PC
    GiveXPToCreature(oPartyMember, nNerfXP);
// Go to the next PC in the party and repeat until everyone has been awarded the correct nerfed amount
    oPartyMember = GetNextFactionMember(oPC, TRUE);
    }
}

If my thinking is correct, when a creature is killed, this will:


1) Find who made the killing blow


2) if it was a henchman or familiar, locate the owning PC


3) find the Party leader of the killer (or owning PC)


4) Find KMdS's calculated XP amount based on PARTY level


5) Apply XP nerf based on CHARACTER level


6) Give the current PC the nerfed amount


7) Repeat 4-6 with the next PC in the Party list until all party members have been awarded


 


If I put this together correctly, it should give XP to everyone, no matter who made the kill (Buff-Bots don't get left behind) and everyone's XP is nerfed based on their *own* level and not the level of the killer.


 


As KMdS's script doesn't take multiclass penalties into account, I've decided I can live without that since this is intended to be used in a low-level module. Having someone high enough level to actually receive the penalty would be less likely.


 


Did I miss anything?



               
               

               


                     Modifié par Gawain_VIII, 29 avril 2016 - 02:53 .