2026/01/10 Update
Added three starting packages for the Binder class. Updated any PrCs that can advance invokers to allow invocation feats during level up. Updated invoker feats to require Eldritch Blast & DFA Breath where appropriate. Fixed bad constant on Rising Phoenix. Fixed Oozemaster Oozy Touch/Glob bonus feat bug. Vassal of Bahamut's Platinum Armor is now much closer to PnP. Craft (Alchemy) is a class skill for Binders. Moved packages into \Craft2das\ so the PRC8 would continue to build. Updated personal_switch.2da to not stack Power Attack by default. Fixed creature size related screw-up that happened when I was trying to fix unarmed damage for large creatures. +10 Jump bonus for Leaping Dragon Stance was being improperly gated by Blood Claw Master. Fixed duration bug w/ Supress Weapon. Fixed broken loop bug w/ Supress Weapon. Restoration shouldn't be able to remove Crack of Doom user's AB penalty. Epic Vassal's of Bahamut now get their proper allowance. Mirror Images might not spawning in dead anymore. YMMV, Harrowport. Added package TLK worksheet to notes.
This commit is contained in:
@@ -9,6 +9,8 @@ const int PRC_SIZEMASK_SIMPLE = 4; // 'simple' size changes that have si
|
||||
|
||||
const int PRC_SIZEMASK_ALL = 7; // PRC_SIZEMASK_NORMAL | PRC_SIZEMASK_NOABIL | PRC_SIZEMASK_SIMPLE
|
||||
|
||||
const int PRC_SIZEMASK_PRC = 0x08; // For systems that need PRC size scale
|
||||
|
||||
//wrapper for biowares GetSpellId()
|
||||
//used for actioncastspell
|
||||
int PRCGetSpellId(object oCaster = OBJECT_SELF);
|
||||
@@ -493,29 +495,6 @@ int PRCGetCreatureSize(object oObject = OBJECT_SELF, int nSizeMask = PRC_SIZEMAS
|
||||
int nSize = StringToInt(Get2DAString("appearance", "SizeCategory", GetAppearanceType(oObject)));
|
||||
if (DEBUG) DoDebug("Appearance-based GetCreatureSize, returning size: "+IntToString(nSize));
|
||||
if (DEBUG) DoDebug("Bioware GetCreatureSize, returning size: "+IntToString(GetCreatureSize(oObject)));
|
||||
|
||||
// Check for racial size feats FIRST - these override appearance size
|
||||
if(GetHasFeat(FEAT_TINY, oObject))
|
||||
nSize = 3; // PRC Tiny
|
||||
else if(GetHasFeat(FEAT_SMALL, oObject))
|
||||
nSize = 4; // PRC Small
|
||||
else if(GetHasFeat(FEAT_LARGE, oObject))
|
||||
nSize = 6; // PRC Large
|
||||
else if(GetHasFeat(FEAT_HUGE, oObject))
|
||||
nSize = 7; // PRC Huge
|
||||
else
|
||||
{
|
||||
// Map appearance sizes to PRC sizes when no racial feat present
|
||||
if(nSize == 1) nSize = 3; // Tiny creatures
|
||||
else if(nSize == 2) nSize = 4; // Small creatures
|
||||
else if(nSize == 3) nSize = 5; // Medium creatures
|
||||
else if(nSize == 4) nSize = 6; // Large creatures
|
||||
else if(nSize == 5) nSize = 7; // Huge creatures
|
||||
}
|
||||
|
||||
if (DEBUG) DoDebug("Has FEAT_LARGE: " + IntToString(GetHasFeat(FEAT_LARGE, oObject)));
|
||||
if (DEBUG) DoDebug("PRCGetCreatureSize: After racial feats, nSize = " + IntToString(nSize));
|
||||
|
||||
//CEP adds other sizes, take them into account too
|
||||
if(nSize == 20)
|
||||
nSize = CREATURE_SIZE_DIMINUTIVE;
|
||||
@@ -582,7 +561,6 @@ int PRCGetCreatureSize(object oObject = OBJECT_SELF, int nSizeMask = PRC_SIZEMAS
|
||||
if (DEBUG) DoDebug("PRCGetCreatureSize, returning size: "+IntToString(nSize));
|
||||
return nSize;
|
||||
}
|
||||
|
||||
int GetIsChakraBound(object oMeldshaper, int nChakra)
|
||||
{
|
||||
int nTest = GetLocalInt(oMeldshaper, "BoundMeld"+IntToString(nChakra));
|
||||
|
||||
@@ -112,13 +112,13 @@ int PerformJump(object oPC, location lLoc, int bDoKnockDown = TRUE)
|
||||
if (Ninja_AbilitiesEnabled(oPC))
|
||||
{
|
||||
bIsRunningJump = TRUE;
|
||||
iBonus = 4;
|
||||
iBonus += 4;
|
||||
}
|
||||
}
|
||||
if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC))
|
||||
{
|
||||
bIsRunningJump = TRUE;
|
||||
//iBonus = 10; //:: This is granted in the stance.
|
||||
//iBonus += 10; //:: This is handled in the stance now.
|
||||
}
|
||||
// PnP rules are height * 6 for run and height * 2 for jump.
|
||||
// I can't get height so that is assumed to be 6.
|
||||
|
||||
@@ -275,210 +275,6 @@ void ApplyUnarmedAttackEffects(object oCreature)
|
||||
// Monk: 1d6 at level 1, 1d8 at level 4, 1d10 at level 8, 2d6 at level 12, 2d8 at level 16, 2d10 at level 20
|
||||
// Frostrager: 1d6 at level 1, 1d8 at level 4
|
||||
int FindUnarmedDamage(object oCreature)
|
||||
{
|
||||
DoDebug("FindUnarmedDamage: FUNCTION CALLED AT ALL");
|
||||
if (DEBUG) DoDebug("=== FindUnarmedDamage DEBUG START ===");
|
||||
if (DEBUG) DoDebug("Creature: " + GetName(oCreature));
|
||||
|
||||
int iDamage = 0;
|
||||
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk");
|
||||
int iShou = GetLevelByClass(CLASS_TYPE_SHOU, oCreature);
|
||||
int iBrawler = GetLevelByClass(CLASS_TYPE_BRAWLER, oCreature);
|
||||
int iSacredFist = GetLevelByClass(CLASS_TYPE_SACREDFIST, oCreature);
|
||||
int iEnlightenedFist = GetLevelByClass(CLASS_TYPE_ENLIGHTENEDFIST, oCreature);
|
||||
int iHenshin = GetLevelByClass(CLASS_TYPE_HENSHIN_MYSTIC, oCreature);
|
||||
int iZuoken = GetLevelByClass(CLASS_TYPE_FIST_OF_ZUOKEN, oCreature);
|
||||
int iShadowSunNinja = GetLevelByClass(CLASS_TYPE_SHADOW_SUN_NINJA, oCreature);
|
||||
int iFrost = GetLevelByClass(CLASS_TYPE_FROSTRAGER, oCreature);
|
||||
int iAscetic = GetLevelByClass(CLASS_TYPE_NINJA, oCreature);
|
||||
int iRonove = 0;
|
||||
int iMonkDamage = 1;
|
||||
int iShouDamage = 1;
|
||||
int iBrawlerDamage = 1;
|
||||
int iFrostDamage = 1;
|
||||
int iSUSDamage = 1;
|
||||
int iDieIncrease = 0;
|
||||
int iSize;
|
||||
|
||||
if (GetHasSpellEffect(VESTIGE_RONOVE, oCreature) && GetLevelByClass(CLASS_TYPE_BINDER, oCreature))
|
||||
iRonove = GetLocalInt(oCreature, "RonovesFists");
|
||||
|
||||
//:: Determine creature size
|
||||
if( GetIsPolyMorphedOrShifted(oCreature) || GetPRCSwitch(PRC_APPEARANCE_SIZE))
|
||||
{
|
||||
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG) DoDebug("FindUnarmedDamage: Before size adjustment, iSize = " + IntToString(iSize));
|
||||
|
||||
// Start with feat-based size calculation
|
||||
iSize = 5; // medium
|
||||
if (GetHasFeat(FEAT_TINY, oCreature)) iSize = 3;
|
||||
if (GetHasFeat(FEAT_SMALL, oCreature)) iSize = 4;
|
||||
if (GetHasFeat(FEAT_LARGE, oCreature)) iSize = 6;
|
||||
if (GetHasFeat(FEAT_HUGE, oCreature)) iSize = 7;
|
||||
|
||||
if (DEBUG) DoDebug("FindUnarmedDamage: After size adjustment, iSize = " + IntToString(iSize));
|
||||
|
||||
if (DEBUG) DoDebug("Has FEAT_LARGE: " + IntToString(GetHasFeat(FEAT_LARGE, oCreature)));
|
||||
if (DEBUG) DoDebug("Size adjustment value: " + IntToString(PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE)));
|
||||
|
||||
// Only apply size adjustment if no explicit size feat is present
|
||||
// This prevents overriding racial size feats like Centaur's FEAT_LARGE
|
||||
if (!GetHasFeat(FEAT_TINY, oCreature) &&
|
||||
!GetHasFeat(FEAT_SMALL, oCreature) &&
|
||||
!GetHasFeat(FEAT_LARGE, oCreature) &&
|
||||
!GetHasFeat(FEAT_HUGE, oCreature))
|
||||
{
|
||||
iSize += PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE);
|
||||
}
|
||||
|
||||
if (iSize < 1) iSize = 1;
|
||||
if (iSize > 9) iSize = 9;
|
||||
|
||||
if (DEBUG) DoDebug("FindUnarmedDamage: Final iSize = " + IntToString(iSize));
|
||||
if (DEBUG) DoDebug("FindUnarmedDamage: iMonkDamage = " + IntToString(iMonkDamage));
|
||||
if (DEBUG) DoDebug("FindUnarmedDamage: 2DA lookup result = " + IntToString(StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iMonkDamage))));
|
||||
|
||||
}
|
||||
/* //:: Determine creature size
|
||||
if( GetIsPolyMorphedOrShifted(oCreature) || GetPRCSwitch(PRC_APPEARANCE_SIZE))
|
||||
{
|
||||
iSize = PRCGetCreatureSize(oCreature) - CREATURE_SIZE_MEDIUM + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSize = 5; // medium
|
||||
if (GetHasFeat(FEAT_TINY, oCreature)) iSize = 3;
|
||||
if (GetHasFeat(FEAT_SMALL, oCreature)) iSize = 4;
|
||||
if (GetHasFeat(FEAT_LARGE, oCreature)) iSize = 6;
|
||||
if (GetHasFeat(FEAT_HUGE, oCreature)) iSize = 7;
|
||||
iSize += PRCGetCreatureSize(oCreature) - PRCGetCreatureSize(oCreature, PRC_SIZEMASK_NONE);
|
||||
if (iSize < 1) iSize = 1;
|
||||
if (iSize > 9) iSize = 9;
|
||||
} */
|
||||
|
||||
// Sacred Fist code break protection
|
||||
if (GetHasFeat(FEAT_SF_CODE, oCreature)) iSacredFist = 0;
|
||||
|
||||
// Combine monk-like levels
|
||||
iMonk += iSacredFist + iHenshin + iEnlightenedFist + iShou + iZuoken + iShadowSunNinja;
|
||||
|
||||
// Superior Unarmed Strike
|
||||
if (GetHasFeat(FEAT_SUPERIOR_UNARMED_STRIKE, oCreature))
|
||||
{
|
||||
iMonk += 4;
|
||||
int nHD = GetHitDice(oCreature);
|
||||
if (nHD >= 16) iSUSDamage = IP_CONST_MONSTERDAMAGE_2d6;
|
||||
else if (nHD >= 12) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d10;
|
||||
else if (nHD >= 8) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d8;
|
||||
else if (nHD >= 4) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d6;
|
||||
else if (nHD >= 3) iSUSDamage = IP_CONST_MONSTERDAMAGE_1d4;
|
||||
}
|
||||
|
||||
// Ascetic Stalker
|
||||
if (GetHasFeat(FEAT_ASCETIC_STALKER, oCreature))
|
||||
iMonk += iAscetic;
|
||||
|
||||
// Cap monk progression
|
||||
if (iMonk > 16 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE)) iMonk = 16;
|
||||
else if (iMonk > 20) iMonk = 20;
|
||||
|
||||
// Ronove replacement
|
||||
if (iRonove > iMonk) iMonk = iRonove;
|
||||
|
||||
// Monk damage calculation (2DA row)
|
||||
if (iMonk > 0) iMonkDamage = iMonk / 4 + 3;
|
||||
if (DEBUG) DoDebug("iMonkDamage row = " + IntToString(iMonkDamage));
|
||||
if (iSize == 5 && iMonkDamage == 7 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
|
||||
iMonkDamage = 8;
|
||||
|
||||
// Shou Disciple base damage
|
||||
if (iShou > 0)
|
||||
{
|
||||
int nRow;
|
||||
if (iShou == 1) nRow = 3;
|
||||
else if (iShou == 2) nRow = 4;
|
||||
else if (iShou == 3) nRow = 5;
|
||||
else if (iShou == 4) nRow = 5;
|
||||
else if (iShou == 5) nRow = 6;
|
||||
else nRow = 3;
|
||||
|
||||
if (nRow > 6) nRow = 6;
|
||||
|
||||
iShouDamage = StringToInt(Get2DACache("unarmed_dmg", "size" + IntToString(iSize), nRow));
|
||||
}
|
||||
|
||||
// Frostrager
|
||||
if (iFrost > 0) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d6;
|
||||
if (iFrost > 3) iFrostDamage = IP_CONST_MONSTERDAMAGE_1d8;
|
||||
|
||||
// Brawler
|
||||
if (iBrawler > 0) iBrawlerDamage = iBrawler / 6 + 3;
|
||||
if (iBrawler >= 36) iBrawlerDamage += 2;
|
||||
|
||||
// Armor/shield penalties
|
||||
if (iMonkDamage > 1)
|
||||
{
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
|
||||
int bShieldEq = GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_LARGESHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
|
||||
if (GetBaseAC(oArmor) > 0 || bShieldEq)
|
||||
iMonkDamage = 1;
|
||||
}
|
||||
|
||||
if (iShouDamage > 1)
|
||||
{
|
||||
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
|
||||
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
|
||||
int bShieldEq = GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_LARGESHIELD ||
|
||||
GetBaseItemType(oShield) == BASE_ITEM_TOWERSHIELD;
|
||||
if (GetBaseAC(oArmor) > 3 || bShieldEq)
|
||||
iShouDamage = 1;
|
||||
}
|
||||
|
||||
// Determine IoDM die increase
|
||||
if (GetHasFeat(FEAT_INCREASE_DAMAGE2, oCreature)) iDieIncrease = 2;
|
||||
else if (GetHasFeat(FEAT_INCREASE_DAMAGE1, oCreature)) iDieIncrease = 1;
|
||||
|
||||
// Lookup monk damage in 2DA
|
||||
iMonkDamage = StringToInt(Get2DACache("unarmed_dmg","size" + IntToString(iSize), iMonkDamage));
|
||||
if (DEBUG) DoDebug("FindUnarmedDamage: Final damage value = " + IntToString(iMonkDamage));
|
||||
|
||||
// 3.0e monk special cases
|
||||
if (iSize <= 5 && !GetPRCSwitch(PRC_3_5e_FIST_DAMAGE))
|
||||
{
|
||||
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d6) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d12;
|
||||
if (iMonkDamage == IP_CONST_MONSTERDAMAGE_2d10) iMonkDamage = IP_CONST_MONSTERDAMAGE_1d20;
|
||||
}
|
||||
|
||||
// Apply IoDM die increase last, after 2DA lookups
|
||||
if (iMonkDamage > 0) iMonkDamage = StepDie(iMonkDamage, iDieIncrease);
|
||||
if (iShouDamage > 0) iShouDamage = StepDie(iShouDamage, iDieIncrease);
|
||||
if (iBrawlerDamage > 0) iBrawlerDamage = StepDie(iBrawlerDamage, iDieIncrease);
|
||||
if (iFrostDamage > 0) iFrostDamage = StepDie(iFrostDamage, iDieIncrease);
|
||||
if (iSUSDamage > 0) iSUSDamage = StepDie(iSUSDamage, iDieIncrease);
|
||||
|
||||
// Select best damage
|
||||
iDamage = iMonkDamage;
|
||||
iDamage = (DamageAvg(iShouDamage ) > DamageAvg(iDamage)) ? iShouDamage : iDamage;
|
||||
iDamage = (DamageAvg(iFrostDamage ) > DamageAvg(iDamage)) ? iFrostDamage : iDamage;
|
||||
iDamage = (DamageAvg(iSUSDamage ) > DamageAvg(iDamage)) ? iSUSDamage : iDamage;
|
||||
iDamage = (DamageAvg(iBrawlerDamage) > DamageAvg(iDamage)) ? iBrawlerDamage : iDamage;
|
||||
|
||||
if (DEBUG) DoDebug("prc_inc_unarmed: iDamage "+IntToString(iDamage));
|
||||
|
||||
return iDamage;
|
||||
|
||||
if (DEBUG) DoDebug("=== FindUnarmedDamage DEBUG END ===");
|
||||
}
|
||||
|
||||
|
||||
/* int FindUnarmedDamage(object oCreature)
|
||||
{
|
||||
int iDamage = 0;
|
||||
int iMonk = GetLevelByClass(CLASS_TYPE_MONK, oCreature) + GetLocalInt(oCreature, "LiPengMonk");
|
||||
@@ -645,7 +441,6 @@ int FindUnarmedDamage(object oCreature)
|
||||
|
||||
return iDamage;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Adds appropriate feats to the skin. Stolen from SoulTaker + expanded with overwhelming/devastating critical.
|
||||
|
||||
Reference in New Issue
Block a user