2025/11/30 Update

Updated module to NWN:EE v37-17
Updated NWNxEE libraries to latest.
Associated new PRC8 module script for the GUI event.
Deleted old prc_2da_cache creature from top hak as it's now unneeded.
Full compile.
This commit is contained in:
Jaysyn904
2025-11-30 22:04:26 -05:00
parent 243ed8a652
commit 8ca4aed814
1252 changed files with 19391 additions and 19766 deletions

View File

@@ -21,426 +21,6 @@
#include "npc_template_inc"
#include "inc_debug"
#include "prc_inc_json"
//:: Get a random General feat.
void ApplyParagonBonusFeat(object oCreature, int iFeat);
//:: Adds Paragon SLA's to jCreature.
//::
json json_AddParagonPowers(json jCreature)
{
// Get the existing SpecAbilityList (if it exists)
json jSpecAbilityList = GffGetList(jCreature, "SpecAbilityList");
// Create the SpecAbilityList if it doesn't exist
if (jSpecAbilityList == JsonNull())
{
jSpecAbilityList = JsonArray();
}
//:: Greater Dispelling 3x / Day
int i;
for (i = 0; i < 3; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 67);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", 15);
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
//:: Add Haste 3x / Day
for (i = 0; i < 3; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 78);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", 15);
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
//:: See Invisiblity 3x / Day
for (i = 0; i < 3; i++)
{
json jSpecAbility = JsonObject();
jSpecAbility = GffAddWord(jSpecAbility, "Spell", 157);
jSpecAbility = GffAddByte(jSpecAbility, "SpellCasterLevel", 15);
jSpecAbility = GffAddByte(jSpecAbility, "SpellFlags", 1);
// Manually add to the array
jSpecAbilityList = JsonArrayInsert(jSpecAbilityList, jSpecAbility);
}
//:: Add the list to the creature
jCreature = GffAddList(jCreature, "SpecAbilityList", jSpecAbilityList);
return jCreature;
}
//:: Directly modifies jCreature's Challenge Rating.
//:: This is useful for most XP calculations.
//::
json json_UpdateParagonCR(json jCreature, int nBaseCR, int nBaseHD)
{
int nNewCR;
//:: Calculate additional CR by HD
if(nBaseHD <= 6)
{
nNewCR = nBaseCR + 18;
}
else if(nBaseHD <= 16)
{
nNewCR = nBaseCR + 15;
}
else
{nNewCR = nBaseCR + 12;}
//:: Modify Challenge Rating
jCreature = GffReplaceFloat(jCreature, "ChallengeRating"/* /value" */, IntToFloat(nNewCR));
return jCreature;
}
//:: Get a random General feat.
void PickParagonBonusFeat(object oCreature)
{
//:: Paragon creatures get a +15 to all ability scores,
//:: so can always meet feat pre-reqs.
//:: Detect spellcasting classes (FOR FUTURE USE)
int i;
for (i = 1; i <= 8; i++)
{
if (GetIsArcaneClass(GetClassByPosition(i, oCreature)))
{
SetLocalInt(oCreature, "ParagonArcaneCaster", 0);
}
if (GetIsDivineClass(GetClassByPosition(i, oCreature)))
{
SetLocalInt(oCreature, "ParagonDivineCaster", 0);
}
}
switch (Random(18))
{
//:: Dodge -> Mobility -> Spring Attack
case 0:
{
int iDodge = GetHasFeat(FEAT_DODGE, oCreature);
int iMobility = GetHasFeat(FEAT_MOBILITY, oCreature);
int iSpringAttack = GetHasFeat(FEAT_SPRING_ATTACK, oCreature);
//:: Grant only the first missing feat in the chain
if (iDodge == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_DODGE);
}
else if (iMobility == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_MOBILITY);
}
else if (iSpringAttack == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_SPRING_ATTACK);
}
}
break;
//:: Power Attack -> Cleave -> Imp Power Attack -> Great Cleave
case 1:
{
int iPower = GetHasFeat(FEAT_POWER_ATTACK, oCreature);
int iCleave = GetHasFeat(FEAT_CLEAVE, oCreature);
int iImpPower = GetHasFeat(FEAT_IMPROVED_POWER_ATTACK, oCreature);
int iGrCleave = GetHasFeat(FEAT_GREAT_CLEAVE, oCreature);
//:: Grant only the first missing feat in the chain
if (iPower == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_POWER_ATTACK);
}
else if (iCleave == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_CLEAVE);
}
else if (iImpPower == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_IMPROVED_POWER_ATTACK);
}
else if (iGrCleave == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_GREAT_CLEAVE);
}
}
break;
//:: Expertise -> Imp Expertise -> Whirlwind Attack -> Imp Whirlwind Attack
case 2:
{
int iEx = GetHasFeat(FEAT_EXPERTISE, oCreature);
int iImpEx = GetHasFeat(FEAT_IMPROVED_EXPERTISE, oCreature);
int iWhirl = GetHasFeat(FEAT_WHIRLWIND_ATTACK, oCreature);
int iImpWhirl = GetHasFeat(FEAT_IMPROVED_WHIRLWIND, oCreature);
//:: Grant only the first missing feat in the chain
if (iEx == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_EXPERTISE);
}
else if (iImpEx == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_IMPROVED_EXPERTISE);
}
else if (iWhirl == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_WHIRLWIND_ATTACK);
}
else if (iImpWhirl == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_IMPROVED_WHIRLWIND);
}
}
break;
//:: Disarm -> Expertise -> Improved Disarm -> Imp Expertise
case 3:
{
int iDisarm = GetHasFeat(FEAT_DISARM, oCreature);
int iEx = GetHasFeat(FEAT_EXPERTISE, oCreature);
int iImpDisarm = GetHasFeat(FEAT_IMPROVED_DISARM, oCreature);
int iImpEx = GetHasFeat(FEAT_IMPROVED_EXPERTISE, oCreature);
//:: Grant only the first missing feat in the chain
if (iDisarm == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_DISARM);
}
else if (iEx == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_EXPERTISE);
}
else if (iImpDisarm == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_IMPROVED_DISARM);
}
else if (iImpEx == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_IMPROVED_EXPERTISE);
}
}
break;
//:: Toughness
case 4:
{
ApplyParagonBonusFeat(oCreature, FEAT_TOUGHNESS);
}
break;
//:: Great Fortitude
case 5:
{
ApplyParagonBonusFeat(oCreature, FEAT_GREAT_FORTITUDE);
}
break;
//:: Lightining Reflexes
case 6:
{
ApplyParagonBonusFeat(oCreature, FEAT_LIGHTNING_REFLEXES);
}
break;
//:: Iron Will -> Unnatural Will
case 7:
{
int iIronWill = GetHasFeat(FEAT_IRON_WILL, oCreature);
int iUnnaturalWill = GetHasFeat(FEAT_UNNATURAL_WILL, oCreature);
//:: Grant only the first missing feat in the chain
if (iIronWill == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_IRON_WILL);
}
else if (iUnnaturalWill == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_UNNATURAL_WILL);
}
}
break;
//:: Blind-Fight
case 8:
{
ApplyParagonBonusFeat(oCreature, FEAT_BLIND_FIGHT);
}
break;
//:: Improved Initiative
case 9:
{
ApplyParagonBonusFeat(oCreature, FEAT_IMPROVED_INITIATIVE);
}
break;
//:: Alertness
case 10:
{
ApplyParagonBonusFeat(oCreature, FEAT_ALERTNESS);
}
break;
//:: Blooded
case 11:
{
ApplyParagonBonusFeat(oCreature, FEAT_BLOODED);
}
break;
//:: Side-step Charge
case 12:
{
ApplyParagonBonusFeat(oCreature, FEAT_SIDESTEP_CHARGE);
}
break;
//:: Thug
case 13:
{
ApplyParagonBonusFeat(oCreature, FEAT_THUG);
}
break;
//:: Dive for Cover
case 14:
{
ApplyParagonBonusFeat(oCreature, FEAT_DIVE_FOR_COVER);
}
break;
//:: Endurance -> Strong Stomach
case 15:
{
int iEndurance = GetHasFeat(FEAT_ENDURANCE, oCreature);
int iStrStomach = GetHasFeat(FEAT_STRONG_STOMACH, oCreature);
//:: Grant only the first missing feat in the chain
if (iEndurance == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_ENDURANCE);
}
else if (iStrStomach == 0)
{
ApplyParagonBonusFeat(oCreature, FEAT_STRONG_STOMACH);
}
}
break;
//:: Resist Disease
case 16:
{
ApplyParagonBonusFeat(oCreature, FEAT_RESIST_DISEASE);
}
break;
//:: Resist Poison
case 17:
{
ApplyParagonBonusFeat(oCreature, FEAT_RESIST_POISON);
}
break;
}
}
//:: Check & apply the feat using EffectBonusFeat if it
//:: doesn't exist on the creature already
void ApplyParagonBonusFeat(object oCreature, int iFeat)
{
// If the creature does not already have the feat, apply it
if (!GetHasFeat(iFeat, oCreature))
{
effect eFeat = EffectBonusFeat(iFeat);
effect eLink = UnyieldingEffect(eFeat);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oCreature);
}
else
{
DelayCommand(0.0f, PickParagonBonusFeat(oCreature));
}
}
//:: Apply Paragon effects to a non-PC creature
void ApplyParagonEffects(object oCreature, int nBaseHD, int nBaseCR)
{
//:: Declare major variables
int nNewCR;
effect eParagon;
//:: Set maximum hit points for each HD
int nParagonHP = (GetMaxPossibleHP(oCreature) + (nBaseHD * GetAbilityModifier(ABILITY_CONSTITUTION, oCreature)));
SetCurrentHitPoints(oCreature, nParagonHP);
//:: Tripling the speed for all movement types
eParagon = EffectLinkEffects(eParagon, EffectMovementSpeedIncrease(300));
//:: +25 luck bonus on all attack rolls
eParagon = EffectLinkEffects(eParagon, EffectAttackIncrease(25));
//:: +20 luck bonus on damage rolls for melee and thrown ranged attacks
eParagon = EffectLinkEffects(eParagon, EffectDamageIncrease(20));
//:: AC Bonuses: +12 insight, +12 luck
eParagon = EffectLinkEffects(eParagon, EffectACIncrease(12, AC_DODGE_BONUS));
eParagon = EffectLinkEffects(eParagon, EffectACIncrease(12, AC_DEFLECTION_BONUS));
//:: Boost caster & SLA level by 15
SetLocalInt(oCreature, PRC_CASTERLEVEL_ADJUSTMENT, 15);
//:: Fire and cold resistance 10, or keep the higher existing resistance if applicable
eParagon = EffectLinkEffects(eParagon, EffectDamageResistance(DAMAGE_TYPE_FIRE, 10));
eParagon = EffectLinkEffects(eParagon, EffectDamageResistance(DAMAGE_TYPE_COLD, 10));
//:: Damage Reduction 20/epic or retain existing DR if higher
eParagon = EffectLinkEffects(eParagon, EffectDamageReduction(20, DAMAGE_POWER_ENERGY));
//:: Spell Resistance equal to CR +10, or retain existing SR if higher
int iExSR = GetSpellResistance(oCreature);
int nSpellResistance;
if (iExSR < nBaseCR + 10)
{
nSpellResistance = nBaseCR + 10;
}
else
{
nSpellResistance = 0;
}
eParagon = EffectLinkEffects(eParagon, EffectSpellResistanceIncrease(nSpellResistance));
//:: Fast Healing 20
eParagon = EffectLinkEffects(eParagon, EffectRegenerate(20, 6.0f));
//:: Saving Throws: +10 insight bonus on all saving throws
eParagon = EffectLinkEffects(eParagon, EffectSavingThrowIncrease(SAVING_THROW_ALL, 10));
//:: Skills: +10 competence bonus to all skill checks
int nSkillID = 0;
while (TRUE)
{
//:: Get & check skill
string sSkillLabel = Get2DACache("skills", "Label", nSkillID);
//:: Break when out of skills
if (sSkillLabel == "")
break;
//:: Apply the skill increase effect for the current skill
eParagon = EffectLinkEffects(eParagon, EffectSkillIncrease(nSkillID, 10));
//:: Move to the next skill ID
nSkillID++;
}
//:: Two free general feats.
PickParagonBonusFeat(oCreature);
PickParagonBonusFeat(oCreature);
eParagon = UnyieldingEffect(eParagon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eParagon, oCreature);
}
void main ()
{