2026/04/20 Update

Aberrations shouldn't show up on the default Druid PnP Wildshape list.
Added Assassin to GetIsBioSpellCastClass()
Updated CloakedCastingDC() to work with Factotum's Cunning Brilliance.
Greatly expanded the possible class abilities for Factotum's Cunning Brilliance.
Fixed Sublime Chord related bug in PRCGetIsRealSpellKnownByClass().
This commit is contained in:
Jaysyn904
2026-04-20 15:53:14 -04:00
parent 0c813b4954
commit 0e9dabdfb3
7 changed files with 857 additions and 547 deletions

View File

@@ -403,21 +403,21 @@
399 Zombie 12827 nw_zombie01 24 2 1,00 0x00 399 Zombie 12827 nw_zombie01 24 2 1,00 0x00
400 Zombie_Lord 56579 nw_zombieboss 24 9 8,00 0x00 400 Zombie_Lord 56579 nw_zombieboss 24 9 8,00 0x00
401 Zombie_Warrior 12830 nw_zombwarr01 24 5 4,00 0x00 401 Zombie_Warrior 12830 nw_zombwarr01 24 5 4,00 0x00
402 BattleDevourer 12380 nw_battdevour 7 9 11,00 0x16 402 BattleDevourer 12380 nw_battdevour 7 9 11,00 0x10
403 Beholder 95219 x2_beholder001 7 11 11,00 0x16 403 Beholder 95219 x2_beholder001 7 11 11,00 0x10
404 BeholderMage 90374 x2_beholder003 7 21 15,00 0x16 404 BeholderMage 90374 x2_beholder003 7 21 15,00 0x10
405 Drider 3063 x2_drider001 7 6 7,00 0x16 405 Drider 3063 x2_drider001 7 6 7,00 0x10
406 DriderChief 3064 x2_drider002 7 11 10,00 0x16 406 DriderChief 3064 x2_drider002 7 11 10,00 0x10
407 DriderCleric 90389 x2_fdrider002 7 6 7,00 0x16 407 DriderCleric 90389 x2_fdrider002 7 6 7,00 0x10
408 DriderWizard 3066 x2_driderw01 7 6 8,00 0x16 408 DriderWizard 3066 x2_driderw01 7 6 8,00 0x10
409 Ettercap 2136 nw_ettercap 7 5 5,00 0x16 409 Ettercap 2136 nw_ettercap 7 5 5,00 0x10
410 Eyeball 84490 x2_beholder002 7 1 3,00 0x16 410 Eyeball 84490 x2_beholder002 7 1 3,00 0x10
411 HookHorror 12616 nw_horror 7 5 5,00 0x16 411 HookHorror 12616 nw_horror 7 5 5,00 0x10
412 IntellectDevourer 2093 nw_devour 7 8 7,00 0x16 412 IntellectDevourer 2093 nw_devour 7 8 7,00 0x10
413 Illithid 90403 x2_mindflayer001 7 8 9,00 0x16 413 Illithid 90403 x2_mindflayer001 7 8 9,00 0x10
414 Ulitharid 90404 x2_mindflayer002 7 16 20,00 0x16 414 Ulitharid 90404 x2_mindflayer002 7 16 20,00 0x10
415 UmberHulk 2138 nw_umberhulk 7 8 9,00 0x16 415 UmberHulk 2138 nw_umberhulk 7 8 9,00 0x10
416 WillOWisp 12814 nw_willowisp 7 9 9,00 0x16 416 WillOWisp 12814 nw_willowisp 7 9 9,00 0x10
417 Treant 16793778 prc_sum_treant 52 7 6,00 0x20 417 Treant 16793778 prc_sum_treant 52 7 6,00 0x20
418 ShamblingMound 16793779 prc_shambmound 52 8 6,00 0x20 418 ShamblingMound 16793779 prc_shambmound 52 8 6,00 0x20
419 TwigBlight 16793780 wol_twigblight 52 1 1,00 0x20 419 TwigBlight 16793780 wol_twigblight 52 1 1,00 0x20

View File

@@ -10,8 +10,9 @@ int PRCGetSaveDC(object oTarget, object oCaster, int nSpellID = -1);
//called just from above and from inc_epicspells //called just from above and from inc_epicspells
int GetChangesToSaveDC(object oTarget, object oCaster, int nSpellID, int nSchool); int GetChangesToSaveDC(object oTarget, object oCaster, int nSpellID, int nSchool);
#include "prc_inc_factotum"
#include "prc_add_spl_pen" #include "prc_add_spl_pen"
// #include "prc_inc_spells" // #include "prc_inc_spells"
// #include "prc_class_const" // #include "prc_class_const"
// #include "prc_feat_const" // #include "prc_feat_const"
@@ -445,6 +446,31 @@ int AngrySpell(int spell_id, int nSchool, object oCaster)
} }
int CloakedCastingDC(int spell_id, object oTarget, object oCaster) int CloakedCastingDC(int spell_id, object oTarget, object oCaster)
{
int nDC;
int iBeguiler = GetLevelByClass(CLASS_TYPE_BEGUILER, oCaster);
int iFactotum = GetLevelByClass(CLASS_TYPE_FACTOTUM, oCaster);
int iEffectiveLevel = 0;
// Check if character has Beguiler levels OR has learned Cloaked Casting via Cunning Brilliance
if(iBeguiler || (iFactotum && GetIsAbilitySaved(oCaster, FEAT_CLOAKED_CASTING)))
{
if(GetIsDeniedDexBonusToAC(oTarget, oCaster, TRUE))
{
// Use Beguiler level if available, otherwise use Factotum level
iEffectiveLevel = iBeguiler ? iBeguiler : iFactotum;
if(iEffectiveLevel >= 14)
nDC = 2;
else if(iEffectiveLevel >= 2)
nDC = 1;
}
}
return nDC;
}
/* int CloakedCastingDC(int spell_id, object oTarget, object oCaster)
{ {
int nDC; int nDC;
int iBeguiler = GetLevelByClass(CLASS_TYPE_BEGUILER, oCaster); int iBeguiler = GetLevelByClass(CLASS_TYPE_BEGUILER, oCaster);
@@ -461,7 +487,7 @@ int CloakedCastingDC(int spell_id, object oTarget, object oCaster)
} }
return nDC; return nDC;
} } */
// Wyrmbane Helm // Wyrmbane Helm
int WyrmbaneHelmDC(object oTarget, object oCaster) int WyrmbaneHelmDC(object oTarget, object oCaster)

View File

@@ -203,6 +203,10 @@ const int FEAT_CHARMING_THE_ARROW = 25998;
//:: Skill Based Feats //:: Skill Based Feats
const int FEAT_JUMP = 2884; const int FEAT_JUMP = 2884;
//:: Beguiler
const int FEAT_CLOAKED_CASTING = 23592;
const int FEAT_SURPRISE_CASTING = 23593;
//:: Lion of Talisid //:: Lion of Talisid
const int FEAT_LOT_LIONS_COURAGE = 25614; const int FEAT_LOT_LIONS_COURAGE = 25614;
const int FEAT_LOT_LIONS_POUNCE = 25615; const int FEAT_LOT_LIONS_POUNCE = 25615;
@@ -3241,8 +3245,9 @@ const int FEAT_CWSM_FRIGHTFUL_PRESENCE = 2359;
const int FEAT_VIRTUOSO_REVEALING_MELODY = 4176; const int FEAT_VIRTUOSO_REVEALING_MELODY = 4176;
const int FEAT_VIRTUOSO_PERFORMANCE = 4177; const int FEAT_VIRTUOSO_PERFORMANCE = 4177;
// hexblade feats //:: Hexblade feats
const int FEAT_HEXCURSE = 3664; const int FEAT_HEXCURSE = 3664;
const int FEAT_METTLE = 3665;
const int FEAT_SWIFT_CAST = 3827; const int FEAT_SWIFT_CAST = 3827;
// Status markers // Status markers

View File

@@ -532,7 +532,8 @@ int GetIsBioSpellCastClass(int nClass)
|| nClass == CLASS_TYPE_SHAMAN || nClass == CLASS_TYPE_SHAMAN
|| nClass == CLASS_TYPE_DRUID || nClass == CLASS_TYPE_DRUID
|| nClass == CLASS_TYPE_PALADIN || nClass == CLASS_TYPE_PALADIN
|| nClass == CLASS_TYPE_RANGER; || nClass == CLASS_TYPE_RANGER
|| nClass == CLASS_TYPE_ASSASSIN;
} }
int GetIsNSBClass(int nClass) int GetIsNSBClass(int nClass)
@@ -675,8 +676,19 @@ int PRCGetIsRealSpellKnownByClass(int nRealSpellID, int nClass, object oPC = OBJ
string sSpellLevel = Get2DACache(sFile, "Level", nSpellbookSpell); string sSpellLevel = Get2DACache(sFile, "Level", nSpellbookSpell);
if (sSpellLevel != "") if (sSpellLevel != "")
nSpellLevel = StringToInt(sSpellLevel); nSpellLevel = StringToInt(sSpellLevel);
if (nClass == CLASS_TYPE_SUBLIME_CHORD)
{
// Sublime Chord gets access to 4th level spells at level 1
// Skip level requirement check for this class
}
else
{
// Original level check for other classes
if ((GetLevelByClass(nClass) < nSpellLevel) || nSpellLevel == -1) if ((GetLevelByClass(nClass) < nSpellLevel) || nSpellLevel == -1)
return FALSE; // not high enough level return FALSE; // not high enough level
}
/* if ((GetLevelByClass(nClass) < nSpellLevel) || nSpellLevel == -1)
return FALSE; // not high enough level */
// at this stage, prepared casters know the spell and only spontaneous classes need checking // at this stage, prepared casters know the spell and only spontaneous classes need checking
// there are exceptions and these need hardcoding: // there are exceptions and these need hardcoding:

View File

@@ -241,6 +241,170 @@ int GetIsAbilitySaved(object oPC, int nAbil)
} }
void FactotumTriggerAbil(object oPC, int nAbil) void FactotumTriggerAbil(object oPC, int nAbil)
{
object oSkin = GetPCSkin(oPC);
effect eEffect;
if (nAbil == FEAT_BARBARIAN_RAGE)
ExecuteScript("NW_S1_BarbRage", oPC);
else if (nAbil == FEAT_BARBARIAN_ENDURANCE)
eEffect = EffectBonusFeat(IP_CONST_FEAT_BarbEndurance);
else if (nAbil == FEAT_SNEAK_ATTACK)
{
SetLocalInt(oPC, "FactotumSneak", TRUE);
DelayCommand(0.1, ExecuteScript("prc_sneak_att", oPC));
DelayCommand(59.9, DeleteLocalInt(oPC, "FactotumSneak"));
DelayCommand(60.0, ExecuteScript("prc_sneak_att", oPC));
}
else if (nAbil == FEAT_METTLE) // Mettle
{
eEffect = EffectBonusFeat(FEAT_METTLE);
/* SetLocalInt(oPC, "FactotumMettle", TRUE);
DelayCommand(60.0, DeleteLocalInt(oPC, "FactotumMettle")); */
}
else if (nAbil == FEAT_CRUSADER_SMITE)
{
eEffect = EffectBonusFeat(FEAT_CRUSADER_SMITE);
}
else if (nAbil == FEAT_CLOAKED_CASTING)
{
eEffect = EffectBonusFeat(FEAT_CLOAKED_CASTING);
}
else if (nAbil == FEAT_DRAGONSHAMAN_RESOLVE)
{
// Draconic Resolve - immunity to sleep, paralysis, fear
eEffect = EffectImmunity(IMMUNITY_TYPE_PARALYSIS);
eEffect = EffectLinkEffects(eEffect, EffectImmunity(IMMUNITY_TYPE_SLEEP));
eEffect = EffectLinkEffects(eEffect, EffectImmunity(IMMUNITY_TYPE_FEAR));
}
// Favored Enemy feats
else if (nAbil == FEAT_FAVORED_ENEMY_ABERRATION)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_ABERRATION);
else if (nAbil == FEAT_FAVORED_ENEMY_ANIMAL)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_ANIMAL);
else if (nAbil == FEAT_FAVORED_ENEMY_BEAST)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_BEAST);
else if (nAbil == FEAT_FAVORED_ENEMY_CONSTRUCT)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_CONSTRUCT);
else if (nAbil == FEAT_FAVORED_ENEMY_DRAGON)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_DRAGON);
else if (nAbil == FEAT_FAVORED_ENEMY_DWARF)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_DWARF);
else if (nAbil == FEAT_FAVORED_ENEMY_ELEMENTAL)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_ELEMENTAL);
else if (nAbil == FEAT_FAVORED_ENEMY_ELF)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_ELF);
else if (nAbil == FEAT_FAVORED_ENEMY_FEY)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_FEY);
else if (nAbil == FEAT_FAVORED_ENEMY_GIANT)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_GIANT);
else if (nAbil == FEAT_FAVORED_ENEMY_GNOME)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_GNOME);
else if (nAbil == FEAT_FAVORED_ENEMY_GOBLINOID)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_GOBLINOID);
else if (nAbil == FEAT_FAVORED_ENEMY_HALFELF)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_HALFELF);
else if (nAbil == FEAT_FAVORED_ENEMY_HALFLING)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_HALFLING);
else if (nAbil == FEAT_FAVORED_ENEMY_HALFORC)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_HALFORC);
else if (nAbil == FEAT_FAVORED_ENEMY_HUMAN)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_HUMAN);
else if (nAbil == FEAT_FAVORED_ENEMY_MAGICAL_BEAST)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_MAGICAL_BEAST);
else if (nAbil == FEAT_FAVORED_ENEMY_MONSTROUS)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_MONSTROUS);
else if (nAbil == FEAT_FAVORED_ENEMY_ORC)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_ORC);
else if (nAbil == FEAT_FAVORED_ENEMY_OOZE)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_OOZE);
else if (nAbil == FEAT_FAVORED_ENEMY_OUTSIDER)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_OUTSIDER);
else if (nAbil == FEAT_FAVORED_ENEMY_PLANT)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_PLANT);
else if (nAbil == FEAT_FAVORED_ENEMY_REPTILIAN)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_REPTILIAN);
else if (nAbil == FEAT_FAVORED_ENEMY_SHAPECHANGER)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_SHAPECHANGER);
else if (nAbil == FEAT_FAVORED_ENEMY_UNDEAD)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_UNDEAD);
else if (nAbil == FEAT_FAVORED_ENEMY_VERMIN)
eEffect = EffectBonusFeat(FEAT_FAVORED_ENEMY_VERMIN);
// Other existing abilities
else if (nAbil == FEAT_NATURE_SENSE)
{
eEffect = EffectBonusFeat(FEAT_NATURE_SENSE);
}
else if (nAbil == FEAT_WOODLAND_STRIDE)
{
eEffect = EffectBonusFeat(FEAT_WOODLAND_STRIDE);
}
else if (nAbil == FEAT_TRACKLESS_STEP)
{
eEffect = EffectBonusFeat(FEAT_TRACKLESS_STEP);
}
else if (nAbil == FEAT_RESIST_NATURES_LURE)
{
eEffect = EffectBonusFeat(FEAT_RESIST_NATURES_LURE);
}
else if (nAbil == FEAT_VENOM_IMMUNITY)
{
effect eImmunity = EffectImmunity(IMMUNITY_TYPE_POISON);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmunity, oPC, 60.0);
}
else if (nAbil == FEAT_EVASION)
{
eEffect = EffectBonusFeat(FEAT_EVASION);
}
else if (nAbil == FEAT_STILL_MIND)
{
eEffect = EffectBonusFeat(FEAT_STILL_MIND);
}
else if (nAbil == FEAT_PURITY_OF_BODY)
{
// Purity of Body - disease immunity
effect eImmunity = EffectImmunity(IMMUNITY_TYPE_DISEASE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmunity, oPC, 60.0);
}
else if (nAbil == FEAT_IMPROVED_EVASION)
{
eEffect = EffectBonusFeat(FEAT_IMPROVED_EVASION);
}
else if (nAbil == FEAT_USE_POISON)
{
eEffect = EffectBonusFeat(FEAT_USE_POISON);
}
else if (nAbil == FEAT_DIVINE_HEALTH)
{
// Divine Health - disease immunity
effect eImmunity = EffectImmunity(IMMUNITY_TYPE_DISEASE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmunity, oPC, 60.0);
}
else if (nAbil == FEAT_CRIPPLING_STRIKE)
{
eEffect = EffectBonusFeat(FEAT_CRIPPLING_STRIKE);
}
else if (nAbil == FEAT_DEFENSIVE_ROLL)
{
eEffect = EffectBonusFeat(FEAT_DEFENSIVE_ROLL);
}
else if (nAbil == FEAT_OPPORTUNIST)
{
eEffect = EffectBonusFeat(FEAT_OPPORTUNIST);
}
else if (nAbil == FEAT_SLIPPERY_MIND)
{
eEffect = EffectBonusFeat(FEAT_SLIPPERY_MIND);
}
eEffect = TagEffect(eEffect, "FactotumCunningBrilliance");
eEffect = ExtraordinaryEffect(eEffect);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oPC, 60.0);
}
/* void FactotumTriggerAbil(object oPC, int nAbil)
{ {
object oSkin = GetPCSkin(oPC); object oSkin = GetPCSkin(oPC);
itemproperty ipIP; itemproperty ipIP;
@@ -264,7 +428,7 @@ void FactotumTriggerAbil(object oPC, int nAbil)
ipIP = PRCItemPropertyBonusFeat(IP_CONST_FEAT_CRUSADER_SMITE); ipIP = PRCItemPropertyBonusFeat(IP_CONST_FEAT_CRUSADER_SMITE);
IPSafeAddItemProperty(oSkin, ipIP, 60.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); IPSafeAddItemProperty(oSkin, ipIP, 60.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
} } */
void TriggerInspiration(object oPC, int nCombat) void TriggerInspiration(object oPC, int nCombat)
{ {

View File

@@ -9,6 +9,7 @@
//::////////////////////////////////////////////// //:://////////////////////////////////////////////
#include "prc_inc_factotum" #include "prc_inc_factotum"
#include "prc_feat_const"
#include "inc_dynconv" #include "inc_dynconv"
////////////////////////////////////////////////// //////////////////////////////////////////////////
@@ -16,7 +17,8 @@
////////////////////////////////////////////////// //////////////////////////////////////////////////
const int STAGE_SELECT_ABILITIES = 0; const int STAGE_SELECT_ABILITIES = 0;
const int STAGE_CONFIRM_SELECTION = 1; const int STAGE_SELECT_FAVORED_ENEMY = 1;
const int STAGE_CONFIRM_SELECTION = 2;
const int CHOICE_BACK_TO_LSELECT = -1; const int CHOICE_BACK_TO_LSELECT = -1;
@@ -165,17 +167,100 @@ void main()
if(DEBUG) DoDebug("prc_fact_cunconv: Building level selection"); if(DEBUG) DoDebug("prc_fact_cunconv: Building level selection");
SetHeader("Choose the class abilities you would like to learn. You can only learn three for today."); SetHeader("Choose the class abilities you would like to learn. You can only learn three for today.");
if (!GetIsAbilitySaved(oPC, FEAT_BARBARIAN_ENDURANCE)) AddChoice("Barbarian Fast Movement", FEAT_BARBARIAN_ENDURANCE); if (!GetIsAbilitySaved(oPC, FEAT_BARBARIAN_ENDURANCE)) AddChoice("Barbarian: Fast Movement", FEAT_BARBARIAN_ENDURANCE);
if (!GetIsAbilitySaved(oPC, FEAT_BARBARIAN_RAGE)) AddChoice("Barbarian Rage", FEAT_BARBARIAN_RAGE); if (!GetIsAbilitySaved(oPC, FEAT_BARBARIAN_RAGE)) AddChoice("Barbarian: Rage", FEAT_BARBARIAN_RAGE);
if (!GetIsAbilitySaved(oPC, FEAT_SNEAK_ATTACK)) AddChoice("Sneak Attack", FEAT_SNEAK_ATTACK); if (!GetIsAbilitySaved(oPC, FEAT_CLOAKED_CASTING)) AddChoice("Beguiler: Cloaked Casting", FEAT_CLOAKED_CASTING);
if (!GetIsAbilitySaved(oPC, 3665)) AddChoice("Mettle", 3665); if (!GetIsAbilitySaved(oPC, FEAT_CRUSADER_SMITE)) AddChoice("Crusader: Smite", FEAT_CRUSADER_SMITE);
if (!GetIsAbilitySaved(oPC, FEAT_CRUSADER_SMITE)) AddChoice("Crusader Smite", FEAT_CRUSADER_SMITE); if (!GetIsAbilitySaved(oPC, FEAT_DRAGONSHAMAN_RESOLVE)) AddChoice("Dragon Shaman: Draconic Resolve", FEAT_DRAGONSHAMAN_RESOLVE);
if (!GetIsAbilitySaved(oPC, FEAT_NATURE_SENSE)) AddChoice("Druid: Nature Sense", FEAT_NATURE_SENSE);
if (!GetIsAbilitySaved(oPC, FEAT_WOODLAND_STRIDE)) AddChoice("Druid: Woodland Stride", FEAT_WOODLAND_STRIDE);
if (!GetIsAbilitySaved(oPC, FEAT_TRACKLESS_STEP)) AddChoice("Druid: Trackless Step", FEAT_TRACKLESS_STEP);
if (!GetIsAbilitySaved(oPC, FEAT_RESIST_NATURES_LURE)) AddChoice("Druid: Resist Nature's Lure", FEAT_RESIST_NATURES_LURE);
if (!GetIsAbilitySaved(oPC, FEAT_VENOM_IMMUNITY)) AddChoice("Druid: Venom Immunity", FEAT_VENOM_IMMUNITY);
if (!GetIsAbilitySaved(oPC, FEAT_METTLE)) AddChoice("Hexblade: Mettle", FEAT_METTLE);
if (!GetIsAbilitySaved(oPC, FEAT_EVASION)) AddChoice("Monk: Evasion", FEAT_EVASION);
if (!GetIsAbilitySaved(oPC, FEAT_STILL_MIND)) AddChoice("Monk: Still Mind", FEAT_STILL_MIND);
if (!GetIsAbilitySaved(oPC, FEAT_PURITY_OF_BODY)) AddChoice("Monk: Purity of Body", FEAT_PURITY_OF_BODY);
if (!GetIsAbilitySaved(oPC, FEAT_IMPROVED_EVASION)) AddChoice("Monk: Improved Evasion", FEAT_IMPROVED_EVASION);
if (!GetIsAbilitySaved(oPC, FEAT_USE_POISON)) AddChoice("Ninja: Poison Use", FEAT_USE_POISON);
if (!GetIsAbilitySaved(oPC, FEAT_DIVINE_HEALTH)) AddChoice("Paladin: Divine Health", FEAT_DIVINE_HEALTH);
if (!GetIsAbilitySaved(oPC, FEAT_CRIPPLING_STRIKE)) AddChoice("Rogue: Crippling Strike", FEAT_CRIPPLING_STRIKE);
if (!GetIsAbilitySaved(oPC, FEAT_DEFENSIVE_ROLL)) AddChoice("Rogue: Defensive Strike", FEAT_DEFENSIVE_ROLL);
if (!GetIsAbilitySaved(oPC, FEAT_OPPORTUNIST)) AddChoice("Rogue: Opportunist", FEAT_OPPORTUNIST);
if (!GetIsAbilitySaved(oPC, FEAT_SLIPPERY_MIND)) AddChoice("Rogue: Slippery Mind", FEAT_SLIPPERY_MIND);
if (!GetIsAbilitySaved(oPC, FEAT_SNEAK_ATTACK)) AddChoice("Rogue: Sneak Attack", FEAT_SNEAK_ATTACK);
AddChoice("Ranger: Favored Enemy", -1000); // Favored Enemy submenu trigger
// Set the next, previous and wait tokens to default values // Set the next, previous and wait tokens to default values
SetDefaultTokens(); SetDefaultTokens();
// Set the convo quit text to "Abort" // Set the convo quit text to "Abort"
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_ABORT_CONVO)); SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_ABORT_CONVO));
} }
// Favored Enemy selection stage
else if(nStage == STAGE_SELECT_FAVORED_ENEMY)
{
if(DEBUG) DoDebug("prc_fact_cunconv: Building favored enemy selection");
SetHeader("Choose your Favored Enemy type:");
// Add specific favored enemy feats
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_ABERRATION))
AddChoice("Aberration", FEAT_FAVORED_ENEMY_ABERRATION);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_ANIMAL))
AddChoice("Animal", FEAT_FAVORED_ENEMY_ANIMAL);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_BEAST))
AddChoice("Beast", FEAT_FAVORED_ENEMY_BEAST);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_CONSTRUCT))
AddChoice("Construct", FEAT_FAVORED_ENEMY_CONSTRUCT);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_DRAGON))
AddChoice("Dragon", FEAT_FAVORED_ENEMY_DRAGON);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_DWARF))
AddChoice("Dwarf", FEAT_FAVORED_ENEMY_DWARF);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_ELEMENTAL))
AddChoice("Elemental", FEAT_FAVORED_ENEMY_ELEMENTAL);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_ELF))
AddChoice("Elf", FEAT_FAVORED_ENEMY_ELF);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_FEY))
AddChoice("Fey", FEAT_FAVORED_ENEMY_FEY);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_GIANT))
AddChoice("Giant", FEAT_FAVORED_ENEMY_GIANT);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_GNOME))
AddChoice("Gnome", FEAT_FAVORED_ENEMY_GNOME);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_GOBLINOID))
AddChoice("Goblinoid", FEAT_FAVORED_ENEMY_GOBLINOID);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_HALFELF))
AddChoice("Half-Elf", FEAT_FAVORED_ENEMY_HALFELF);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_HALFLING))
AddChoice("Halfling", FEAT_FAVORED_ENEMY_HALFLING);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_HALFORC))
AddChoice("Half-Orc", FEAT_FAVORED_ENEMY_HALFORC);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_HUMAN))
AddChoice("Human", FEAT_FAVORED_ENEMY_HUMAN);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_MAGICAL_BEAST))
AddChoice("Magical Beast", FEAT_FAVORED_ENEMY_MAGICAL_BEAST);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_MONSTROUS))
AddChoice("Monstrous Humanoid", FEAT_FAVORED_ENEMY_MONSTROUS);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_ORC))
AddChoice("Orc", FEAT_FAVORED_ENEMY_ORC);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_OOZE))
AddChoice("Ooze", FEAT_FAVORED_ENEMY_OOZE);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_OUTSIDER))
AddChoice("Outsider", FEAT_FAVORED_ENEMY_OUTSIDER);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_PLANT))
AddChoice("Plant", FEAT_FAVORED_ENEMY_PLANT);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_REPTILIAN))
AddChoice("Reptilian Humanoid", FEAT_FAVORED_ENEMY_REPTILIAN);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_SHAPECHANGER))
AddChoice("Shapechanger", FEAT_FAVORED_ENEMY_SHAPECHANGER);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_UNDEAD))
AddChoice("Undead", FEAT_FAVORED_ENEMY_UNDEAD);
if (!GetIsAbilitySaved(oPC, FEAT_FAVORED_ENEMY_VERMIN))
AddChoice("Vermin", FEAT_FAVORED_ENEMY_VERMIN);
SetDefaultTokens();
SetCustomToken(DYNCONV_TOKEN_EXIT, GetStringByStrRef(DYNCONV_STRREF_ABORT_CONVO));
}
// Selection confirmation stage // Selection confirmation stage
else if(nStage == STAGE_CONFIRM_SELECTION) else if(nStage == STAGE_CONFIRM_SELECTION)
{ {
@@ -212,13 +297,31 @@ void main()
{ {
int nChoice = GetChoice(oPC); int nChoice = GetChoice(oPC);
if(DEBUG) DoDebug("prc_fact_cunconv: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " + IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'"); if(DEBUG) DoDebug("prc_fact_cunconv: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " + IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
if(nStage == STAGE_SELECT_ABILITIES) if(nStage == STAGE_SELECT_ABILITIES)
{ {
if(DEBUG) DoDebug("prc_fact_cunconv: Level selected"); if(DEBUG) DoDebug("prc_fact_cunconv: Ability selected");
// Check if Favored Enemy was selected
if(nChoice == -1000) // Our special value
{
nStage = STAGE_SELECT_FAVORED_ENEMY;
}
else
{
SetLocalInt(oPC, "CunningBrilliance", nChoice);
nStage = STAGE_CONFIRM_SELECTION;
}
MarkStageNotSetUp(STAGE_SELECT_ABILITIES, oPC);
}
else if(nStage == STAGE_SELECT_FAVORED_ENEMY)
{
if(DEBUG) DoDebug("prc_fact_cunconv: Favored enemy selected");
SetLocalInt(oPC, "CunningBrilliance", nChoice); SetLocalInt(oPC, "CunningBrilliance", nChoice);
nStage = STAGE_CONFIRM_SELECTION; nStage = STAGE_CONFIRM_SELECTION;
MarkStageNotSetUp(STAGE_SELECT_ABILITIES, oPC); MarkStageNotSetUp(STAGE_SELECT_FAVORED_ENEMY, oPC);
} }
else if(nStage == STAGE_CONFIRM_SELECTION) else if(nStage == STAGE_CONFIRM_SELECTION)
{ {

View File

@@ -110,7 +110,7 @@ const int TYPE_WILD_SHAPE = 1; //0x01
const int TYPE_ELEMENTAL_SHAPE = 2; //0x02 const int TYPE_ELEMENTAL_SHAPE = 2; //0x02
const int TYPE_DRAGON_SHAPE = 4; //0x04 const int TYPE_DRAGON_SHAPE = 4; //0x04
const int TYPE_POLYMORPH_SELF = 8; //0x08 const int TYPE_POLYMORPH_SELF = 8; //0x08
const int TYPE_ABERRANT_SHAPE = 16; //0x16 const int TYPE_ABERRANT_SHAPE = 16; //0x10
const int TYPE_PLANT_SHAPE = 32; //0x20 const int TYPE_PLANT_SHAPE = 32; //0x20
////////////////////////////////////////////////// //////////////////////////////////////////////////