ff_u_elc_abl

During ELC, verify the ability points.

Variables

ENABLE__FF_U_ELC_ABL: (string) (opt-out) Set to "N" on module to disable unit.

Source code

// @code

#include "ff_i_core"

const string ENABLE__FF_U_ELC_ABL = "ENABLE__FF_U_ELC_ABL";


// -----------------------------------------------------------------------------

void OnPlayerELC()
{
  int nSubType = NWNX_ELC_GetValidationFailureSubType();
  if (nSubType != NWNX_ELC_SUBTYPE_ABILITY_POINT_BUY_SYSTEM_CALCULATION)
    return;

  object oPC = OBJECT_SELF;

  // racialtypes.2da / AbilitiesPointBuyNumber
  int nRacialType = GetRacialType(oPC);
  int nPointsTotal = StringToInt(Get2DAString("racialtypes", "AbilitiesPointBuyNumber", nRacialType));

  int nAbilityMin, nIncrement2, nIncrement3, nIncrement4;
  string sSQL = "SELECT value FROM ruleset WHERE label = 'CHARGEN_BASE_ABILITY_MIN'";
  sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), sSQL);
  if (SqlStep(sqlQuery))
     nAbilityMin = StringToInt(SqlGetString(sqlQuery, 0));

  sSQL = "SELECT value FROM ruleset WHERE label = 'CHARGEN_ABILITY_COST_INCREMENT2'";
  sqlQuery = SqlPrepareQueryObject(GetModule(), sSQL);
  if (SqlStep(sqlQuery))
     nIncrement2 = StringToInt(SqlGetString(sqlQuery, 0));

  sSQL = "SELECT value FROM ruleset WHERE label = 'CHARGEN_ABILITY_COST_INCREMENT3'";
  sqlQuery = SqlPrepareQueryObject(GetModule(), sSQL);
  if (SqlStep(sqlQuery))
     nIncrement3 = StringToInt(SqlGetString(sqlQuery, 0));

  sSQL = "SELECT value FROM ruleset WHERE label = 'CHARGEN_ABILITY_COST_INCREMENT4'";
  sqlQuery = SqlPrepareQueryObject(GetModule(), sSQL);
  if (SqlStep(sqlQuery))
     nIncrement4 = StringToInt(SqlGetString(sqlQuery, 0));

  if (nAbilityMin <= 0 || nIncrement2 <= 0 || nIncrement3 <= 0 || nIncrement4 <= 0)
  {
    LogError(__FILE__ + ": at least one of nAbilityMin, nIncrement2, nIncrement3, nIncrement4, nModifier is invalid");
    return;
  }

  int nAbility, nAdjust;
  int nPointsUsed;
  for (nAbility = ABILITY_STRENGTH; nAbility <= ABILITY_CHARISMA; nAbility++)
  {
    int nAbilityScore = nAbilityMin;
    switch (nAbility)
    {
        case ABILITY_STRENGTH: nAdjust = StringToInt(Get2DAString("racialtypes", "StrAdjust", nRacialType)); break;
        case ABILITY_DEXTERITY: nAdjust = StringToInt(Get2DAString("racialtypes", "DexAdjust", nRacialType)); break;
        case ABILITY_INTELLIGENCE: nAdjust = StringToInt(Get2DAString("racialtypes", "IntAdjust", nRacialType)); break;
        case ABILITY_CHARISMA: nAdjust = StringToInt(Get2DAString("racialtypes", "ChaAdjust", nRacialType)); break;
        case ABILITY_WISDOM: nAdjust = StringToInt(Get2DAString("racialtypes", "WisAdjust", nRacialType)); break;
        case ABILITY_CONSTITUTION: nAdjust = StringToInt(Get2DAString("racialtypes", "ConAdjust", nRacialType)); break;
    }
    int nCost2 = nIncrement2 + nAdjust;
    int nCost3 = nIncrement3 + nAdjust;
    int nCost4 = nIncrement4 + nAdjust;

    int nTarget = NWNX_Creature_GetRawAbilityScore(oPC, nAbility);
    int nLevel;
    for (nLevel = 1; nLevel <= GetPCLevel(oPC); nLevel++)
    {
      int nBonusAbility = NWNX_Creature_GetAbilityIncreaseByLevel(oPC, nLevel);
      if (nAbility == nBonusAbility)
        nTarget -= 1;
    }

    int nCurrent = nAbilityMin;
    while (nCurrent < nTarget)
    {
      if (nCurrent >= nCost4)
        nPointsUsed += 4;
      else if (nCurrent >= nCost3)
        nPointsUsed += 3;
      else if (nCurrent >= nCost2)
        nPointsUsed += 2;
      else
        nPointsUsed += 1;
      nCurrent += 1;
    }
  }

  if (nPointsUsed == nPointsTotal)
    NWNX_ELC_SkipValidationFailure();
  else if (nPointsUsed <= nPointsTotal)
  {
    LogWarning(GetPCInfo(oPC) + " entering module with less ability points than authorized. (" + IntToString(nPointsUsed) + " points used, " + IntToString(nPointsTotal) + " authorized).");
    NWNX_ELC_SkipValidationFailure();
  }
  else if (GetIsDebug())
  {
    LogWarning(GetPCInfo(oPC) + " entering module with invalid ability points than authorized. (" + IntToString(nPointsUsed) + " points used, " + IntToString(nPointsTotal) + " authorized. 'recommended' button might have been used).");
    NWNX_ELC_SkipValidationFailure();
  }
  else
    LogError(GetPCInfo(oPC) + " entering module was not authorized. (" + IntToString(nPointsUsed) + " points used, " + IntToString(nPointsTotal) + " authorized).");

}


// =============================================================================

void main()
{
  if (!GetModuleFlag(ENABLE__FF_U_ELC_ABL, TRUE))
    return;

  string sEvent = GetCurrentEvent();
  if (sEvent == ON_REGISTER)
    SubscribeToEvent(ON_DEFAULT_PLAYER_ELC_FAILURE, __FILE__);
  else if (sEvent == ON_DEFAULT_PLAYER_ELC_FAILURE)
    OnPlayerELC();
}