Added Vow of Poverty

Added Vow of Poverty, Jaebrin, Hobgoblin Warsoul & Forsaker fixes (thanks PRC5 & @Fencas).  Added iprp_matcost.2da for new materials.  Updated PRC8 Tester module.  Cohorts updated to support 8 classes. Fixed ranged disarm w/ Fighter. Updated release archive.
This commit is contained in:
Jaysyn904
2024-12-26 17:37:36 -05:00
parent 02658b7717
commit e81e395031
73 changed files with 29545 additions and 28368 deletions

View File

@@ -124,7 +124,6 @@ int _CheckEpicSpellcastingForClass(object oPC, int nClass)
case CLASS_TYPE_WARMAGE: return GetIsEpicWarmage(oPC);
case CLASS_TYPE_BLIGHTER: return GetIsEpicBlighter(oPC);
case CLASS_TYPE_UR_PRIEST: return GetIsEpicUrPriest(oPC);
}
return FALSE;
}

View File

@@ -351,6 +351,10 @@ int GetSpellslotLevel(int nClass, object oPC)
//:: Marrutact cast as 6/7 sorcerers
else if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_MARRUTACT)
nLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS, oPC)*6/7;
//:: Hobgoblin Warsouls cast as sorcerers
else if(nClass == CLASS_TYPE_SORCERER && !GetLevelByClass(CLASS_TYPE_SORCERER, oPC) && GetRacialType(oPC) == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
nLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS, oPC);
//:: Gloura cast as bards
else if(nClass == CLASS_TYPE_BARD && !GetLevelByClass(CLASS_TYPE_BARD, oPC) && GetRacialType(oPC) == RACIAL_TYPE_GLOURA)
@@ -889,6 +893,12 @@ void CheckNewSpellbooks(object oPC)
&& GetRacialType(oPC) == RACIAL_TYPE_ARKAMOI)
nClass = CLASS_TYPE_SORCERER;
//Hobgoblin Warsouls cast as sorcs
if(nClass == CLASS_TYPE_MONSTROUS
&& !GetLevelByClass(CLASS_TYPE_SORCERER, oPC)
&& GetRacialType(oPC) == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
nClass = CLASS_TYPE_SORCERER;
//Redspawn cast as sorcs
if(nClass == CLASS_TYPE_MONSTROUS
&& !GetLevelByClass(CLASS_TYPE_SORCERER, oPC)

View File

@@ -12,15 +12,10 @@
@author Stratovarius
@date Created - 2019.12.28
Updated for .35 by Jaysyn 2023/03/10
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Test Void
//void main () {}
//////////////////////////////////////////////////
/* Function prototypes */
//////////////////////////////////////////////////
@@ -160,7 +155,7 @@ int GetMeldshaperLevel(object oMeldshaper, int nSpecificClass, int nMeld)
{
int nLevel;
if (DEBUG) DoDebug("GetMeldshaperLevel: "+GetName(oMeldshaper)+" is a "+IntToString(nSpecificClass));
//if (DEBUG) DoDebug("GetMeldshaperLevel: "+GetName(oMeldshaper)+" is a "+IntToString(nSpecificClass));
if(GetIsIncarnumClass(nSpecificClass))
{
@@ -178,7 +173,7 @@ int GetMeldshaperLevel(object oMeldshaper, int nSpecificClass, int nMeld)
}
}
if(DEBUG) DoDebug("Meldshaper Level: " + IntToString(nLevel));
//if(DEBUG) DoDebug("Meldshaper Level: " + IntToString(nLevel));
// Being bound to the Totem Chakra increases the level by one.
if (GetIsMeldBound(oMeldshaper, nMeld) == CHAKRA_TOTEM) nLevel++;
return nLevel;
@@ -188,7 +183,7 @@ int GetIncarnumLevelForClass(int nSpecificClass, object oMeldshaper)
{
int nLevel;
if (DEBUG) DoDebug("GetMeldshaperLevel: "+GetName(oMeldshaper)+" is a "+IntToString(nSpecificClass));
//if (DEBUG) DoDebug("GetMeldshaperLevel: "+GetName(oMeldshaper)+" is a "+IntToString(nSpecificClass));
if(GetIsIncarnumClass(nSpecificClass))
{
@@ -203,40 +198,29 @@ int GetIncarnumLevelForClass(int nSpecificClass, object oMeldshaper)
if(nSpecificClass == CLASS_TYPE_UMBRAL_DISCIPLE || nSpecificClass == CLASS_TYPE_INCANDESCENT_CHAMPION || nSpecificClass == CLASS_TYPE_NECROCARNATE)
nLevel = GetLevelByClass(nSpecificClass, oMeldshaper);
if(DEBUG) DoDebug("GetIncarnumLevelForClass: " + IntToString(nLevel));
//if(DEBUG) DoDebug("GetIncarnumLevelForClass: " + IntToString(nLevel));
return nLevel;
}
int GetHighestMeldshaperLevel(object oMeldshaper)
{
int n = 0;
int nHighest;
int nTemp;
while(n <= 8)
{
if(GetClassByPosition(n, oMeldshaper) != CLASS_TYPE_INVALID)
{
nTemp = GetMeldshaperLevel(oMeldshaper, GetClassByPosition(n, oMeldshaper),-1);
if(nTemp > nHighest)
nHighest = nTemp;
}
n++;
}
return nHighest;
}
/* int GetHighestMeldshaperLevel(object oMeldshaper)
{
return max(max(GetClassByPosition(1, oMeldshaper) != CLASS_TYPE_INVALID ? GetMeldshaperLevel(oMeldshaper, GetClassByPosition(1, oMeldshaper), -1) : 0,
/**return max(max(GetClassByPosition(1, oMeldshaper) != CLASS_TYPE_INVALID ? GetMeldshaperLevel(oMeldshaper, GetClassByPosition(1, oMeldshaper), -1) : 0,
GetClassByPosition(2, oMeldshaper) != CLASS_TYPE_INVALID ? GetMeldshaperLevel(oMeldshaper, GetClassByPosition(2, oMeldshaper), -1) : 0
),
GetClassByPosition(3, oMeldshaper) != CLASS_TYPE_INVALID ? GetMeldshaperLevel(oMeldshaper, GetClassByPosition(3, oMeldshaper), -1) : 0
);
} */
);**/
int nMax;
int i;
for(i = 1; i <= 8; i++)
{
int nClass = GetClassByPosition(i, oMeldshaper);
int nTest = GetMeldshaperLevel(oMeldshaper, GetClassByPosition(i, oMeldshaper), -1);
if (nTest > nMax)
nMax = nTest;
}
return nMax;
}
int GetIsIncarnumClass(int nClass)
{
@@ -286,68 +270,24 @@ int GetPrimaryIncarnumClass(object oMeldshaper = OBJECT_SELF)
}
else
{
int nClassLvl;
int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8;
int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl;
nClass1 = GetClassByPosition(1, oMeldshaper);
nClass2 = GetClassByPosition(2, oMeldshaper);
nClass3 = GetClassByPosition(3, oMeldshaper);
nClass4 = GetClassByPosition(4, oMeldshaper);
nClass5 = GetClassByPosition(5, oMeldshaper);
nClass6 = GetClassByPosition(6, oMeldshaper);
nClass7 = GetClassByPosition(7, oMeldshaper);
nClass8 = GetClassByPosition(8, oMeldshaper);
if(GetIsIncarnumClass(nClass1)) nClass1Lvl = GetLevelByClass(nClass1, oMeldshaper);
if(GetIsIncarnumClass(nClass2)) nClass2Lvl = GetLevelByClass(nClass2, oMeldshaper);
if(GetIsIncarnumClass(nClass3)) nClass3Lvl = GetLevelByClass(nClass3, oMeldshaper);
if(GetIsIncarnumClass(nClass4)) nClass4Lvl = GetLevelByClass(nClass4, oMeldshaper);
if(GetIsIncarnumClass(nClass5)) nClass5Lvl = GetLevelByClass(nClass5, oMeldshaper);
if(GetIsIncarnumClass(nClass6)) nClass6Lvl = GetLevelByClass(nClass6, oMeldshaper);
if(GetIsIncarnumClass(nClass7)) nClass7Lvl = GetLevelByClass(nClass7, oMeldshaper);
if(GetIsIncarnumClass(nClass8)) nClass8Lvl = GetLevelByClass(nClass8, oMeldshaper);
int nClassTest, nClassLvlTest, nMax, i;
for(i = 1; i <= 8; i++)
{
int nClassTest = GetClassByPosition(i, oMeldshaper);
if(GetIsIncarnumClass(nClassTest))
nClassLvlTest = GetLevelByClass(nClassTest, oMeldshaper);
else
nClassLvlTest = 0; // Reset to 0 each iteration that isn't incarnum
if (nClassLvlTest > nMax)
{
nMax = nClassLvlTest;
nClass = nClassTest;
}
}
nClass = nClass1;
nClassLvl = nClass1Lvl;
if(nClass2Lvl > nClassLvl)
{
nClass = nClass2;
nClassLvl = nClass2Lvl;
}
if(nClass3Lvl > nClassLvl)
{
nClass = nClass3;
nClassLvl = nClass3Lvl;
}
if(nClass4Lvl > nClassLvl)
{
nClass = nClass4;
nClassLvl = nClass4Lvl;
}
if(nClass5Lvl > nClassLvl)
{
nClass = nClass5;
nClassLvl = nClass5Lvl;
}
if(nClass6Lvl > nClassLvl)
{
nClass = nClass6;
nClassLvl = nClass6Lvl;
}
if(nClass7Lvl > nClassLvl)
{
nClass = nClass7;
nClassLvl = nClass7Lvl;
}
if(nClass8Lvl > nClassLvl)
{
nClass = nClass8;
nClassLvl = nClass8Lvl;
}
if(nClassLvl == 0)
if(nMax == 0) //No Incarnum classes
nClass = CLASS_TYPE_INVALID;
}
@@ -356,22 +296,12 @@ int GetPrimaryIncarnumClass(object oMeldshaper = OBJECT_SELF)
int GetFirstIncarnumClassPosition(object oMeldshaper = OBJECT_SELF)
{
if (GetIsIncarnumClass(GetClassByPosition(1, oMeldshaper)))
return 1;
if (GetIsIncarnumClass(GetClassByPosition(2, oMeldshaper)))
return 2;
if (GetIsIncarnumClass(GetClassByPosition(3, oMeldshaper)))
return 3;
if (GetIsIncarnumClass(GetClassByPosition(4, oMeldshaper)))
return 4;
if (GetIsIncarnumClass(GetClassByPosition(5, oMeldshaper)))
return 5;
if (GetIsIncarnumClass(GetClassByPosition(6, oMeldshaper)))
return 6;
if (GetIsIncarnumClass(GetClassByPosition(7, oMeldshaper)))
return 7;
if (GetIsIncarnumClass(GetClassByPosition(8, oMeldshaper)))
return 8;
int i;
for(i = 1; i <= 8; i++)
{
if (GetIsIncarnumClass(GetClassByPosition(i, oMeldshaper)))
return i;
}
return 0;
}
@@ -406,7 +336,7 @@ int GetMeldshapingClass(object oMeldshaper)
else if (GetLevelByClass(CLASS_TYPE_SOULBORN, oMeldshaper) && !GetLocalInt(oMeldshaper, "SecondMeldDone")) nClass = CLASS_TYPE_SOULBORN;
else if (GetLevelByClass(CLASS_TYPE_TOTEMIST, oMeldshaper) && !GetLocalInt(oMeldshaper, "ThirdMeldDone")) nClass = CLASS_TYPE_TOTEMIST;
else if (GetLevelByClass(CLASS_TYPE_SPINEMELD_WARRIOR, oMeldshaper) && !GetLocalInt(oMeldshaper, "FourthMeldDone")) nClass = CLASS_TYPE_SPINEMELD_WARRIOR;
if (DEBUG) DoDebug("GetMeldshapingClass is "+IntToString(nClass));
//if (DEBUG) DoDebug("GetMeldshapingClass is "+IntToString(nClass));
return nClass;
}
@@ -426,7 +356,7 @@ int GetMaxShapeSoulmeldCount(object oMeldshaper, int nClass)
//Limited to Con score - 10 or class limit, whichever is less
nMax = min(nMax, nCon);
if (DEBUG) DoDebug("GetMaxShapeSoulmeldCount is "+IntToString(nMax));
//if (DEBUG) DoDebug("GetMaxShapeSoulmeldCount is "+IntToString(nMax));
return nMax;
}
@@ -438,7 +368,7 @@ int GetTotalSoulmeldCount(object oMeldshaper)
nMax += GetMaxShapeSoulmeldCount(oMeldshaper, CLASS_TYPE_SPINEMELD_WARRIOR);
nMax += GetMaxShapeSoulmeldCount(oMeldshaper, CLASS_TYPE_NECROCARNATE);
if (DEBUG) DoDebug("GetTotalSoulmeldCount is "+IntToString(nMax));
//if (DEBUG) DoDebug("GetTotalSoulmeldCount is "+IntToString(nMax));
return nMax;
}
@@ -452,7 +382,7 @@ int GetMaxBindCount(object oMeldshaper, int nClass)
for(i = FEAT_EXTRA_CHAKRA_BIND_1; i <= FEAT_EXTRA_CHAKRA_BIND_10; i++)
if(GetHasFeat(i, oMeldshaper)) nMax += 1;
}
if (DEBUG) DoDebug("GetMaxBindCount is "+IntToString(nMax));
//if (DEBUG) DoDebug("GetMaxBindCount is "+IntToString(nMax));
return nMax;
}
@@ -461,22 +391,22 @@ void ShapeSoulmeld(object oMeldshaper, int nMeld)
PRCRemoveSpellEffects(nMeld, oMeldshaper, oMeldshaper);
GZPRCRemoveSpellEffects(nMeld, oMeldshaper, FALSE);
ActionCastSpellOnSelf(nMeld);
if (DEBUG) DoDebug("Shaping Soulmeld "+IntToString(nMeld)+" on "+GetName(oMeldshaper));
//if (DEBUG) DoDebug("Shaping Soulmeld "+IntToString(nMeld)+" on "+GetName(oMeldshaper));
}
void MarkMeldShaped(object oMeldshaper, int nMeld, int nClass)
{
if (DEBUG) DoDebug("MarkMeldShaped nMeld is "+IntToString(nMeld));
//if (DEBUG) DoDebug("MarkMeldShaped nMeld is "+IntToString(nMeld));
int nCont = TRUE;
int nTest, i;
while (nCont)
{
nTest = GetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(nClass)+IntToString(i));
if (DEBUG) DoDebug("MarkMeldShaped nTest is "+IntToString(nTest));
//if (DEBUG) DoDebug("MarkMeldShaped nTest is "+IntToString(nTest));
if (!nTest) // If it's blank
{
SetLocalInt(oMeldshaper, "ShapedMeld"+IntToString(nClass)+IntToString(i), nMeld);
if (DEBUG) DoDebug("MarkMeldShaped SetLocal");
//if (DEBUG) DoDebug("MarkMeldShaped SetLocal");
nCont = FALSE; // Break the loop
}
else
@@ -586,7 +516,7 @@ int GetShapedMeldsCount(object oMeldshaper)
if (nTest) // If it's not blank
nCount++;
}
if (DEBUG) DoDebug("GetTotalShapedMelds is "+IntToString(nCount));
//if (DEBUG) DoDebug("GetTotalShapedMelds is "+IntToString(nCount));
return nCount;
}
@@ -599,7 +529,7 @@ int GetTotalShapedMelds(object oMeldshaper, int nClass)
if (nTest) // If it's not blank
nCount++;
}
if (DEBUG) DoDebug("GetTotalShapedMelds is "+IntToString(nCount));
//if (DEBUG) DoDebug("GetTotalShapedMelds is "+IntToString(nCount));
return nCount;
}
@@ -641,7 +571,7 @@ int GetTotalBoundMelds(object oMeldshaper)
if (nTest) // If it's not blank
nCount++;
}
if (DEBUG) DoDebug("GetTotalBoundMelds is "+IntToString(nCount));
//if (DEBUG) DoDebug("GetTotalBoundMelds is "+IntToString(nCount));
return nCount;
}
@@ -649,7 +579,7 @@ int GetIsChakraUsed(object oMeldshaper, int nChakra, int nClass)
{
int nTest = GetLocalInt(oMeldshaper, "UsedMeld"+IntToString(nClass)+IntToString(nChakra));
if (DEBUG) DoDebug("GetIsChakraUsed is "+IntToString(nTest));
//if (DEBUG) DoDebug("GetIsChakraUsed is "+IntToString(nTest));
return nTest;
}
@@ -690,7 +620,7 @@ void ChakraBindUnequip(object oMeldshaper, object oItem)
else if (GetItemInSlot(INVENTORY_SLOT_NECK, oMeldshaper) == oItem && GetIsChakraBound(oMeldshaper, CHAKRA_THROAT)) nTest = INVENTORY_SLOT_NECK + 1;
else if (GetItemInSlot(INVENTORY_SLOT_BELT, oMeldshaper) == oItem && GetIsChakraBound(oMeldshaper, CHAKRA_WAIST)) nTest = INVENTORY_SLOT_BELT + 1;
else if (GetItemInSlot(INVENTORY_SLOT_CHEST, oMeldshaper) == oItem && (GetIsChakraBound(oMeldshaper, CHAKRA_SOUL) || GetIsChakraBound(oMeldshaper, CHAKRA_HEART))) nTest = INVENTORY_SLOT_CHEST + 1;
if (DEBUG) DoDebug("ChakraBindUnequip is "+IntToString(nTest-1));
//if (DEBUG) DoDebug("ChakraBindUnequip is "+IntToString(nTest-1));
if (nTest && !CheckSplitChakra(oMeldshaper, nTest-1) && GetIsItemPropertyValid(GetFirstItemProperty(oItem)) && oItem != GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oMeldshaper) && oItem != GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper) &&
oItem != GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper) && oItem != GetItemInSlot(INVENTORY_SLOT_CARMOUR, oMeldshaper)) // If it's bound you can't equip in that slot
{
@@ -715,7 +645,7 @@ string ChakraToString(int nChakra)
if (nChakra == CHAKRA_SOUL || nChakra == CHAKRA_DOUBLE_SOUL ) sReturn = "Soul";
if (nChakra == CHAKRA_TOTEM || nChakra == CHAKRA_DOUBLE_TOTEM ) sReturn = "Totem";
if (DEBUG) DoDebug("ChakraToString is "+IntToString(nChakra)+", Return is "+sReturn);
//if (DEBUG) DoDebug("ChakraToString is "+IntToString(nChakra)+", Return is "+sReturn);
return sReturn;
}
@@ -862,7 +792,7 @@ int GetCanBindChakra(object oMeldshaper, int nChakra)
int GetMaxEssentiaCount(object oMeldshaper, int nClass)
{
int nMax = StringToInt(Get2DACache(GetMeldshapingClassFile(nClass), "Essentia", GetIncarnumLevelForClass(nClass, oMeldshaper)-1));
if (DEBUG) DoDebug("GetMaxEssentiaCount is "+IntToString(nMax));
//if (DEBUG) DoDebug("GetMaxEssentiaCount is "+IntToString(nMax));
return nMax;
}
@@ -880,7 +810,7 @@ void SpawnTempEssentiaChecker(object oMeldshaper)
nTest = GetLocalInt(oMeldshaper, "TempEssentiaAmount"+IntToString(i));
if (nTest) // If it's not blank
{
if (DEBUG) DoDebug("Found "+IntToString(nTest)+" Temp Essentia in Meld "+IntToString(i));
//if (DEBUG) DoDebug("Found "+IntToString(nTest)+" Temp Essentia in Meld "+IntToString(i));
// There's still some temp essentia left in the meld
if (nTest > nRed)
{
@@ -888,7 +818,7 @@ void SpawnTempEssentiaChecker(object oMeldshaper)
SetLocalInt(oMeldshaper, "TempEssentiaAmount"+IntToString(i), nChange);
SetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(i), GetEssentiaInvested(oMeldshaper, i)-nChange);
ShapeSoulmeld(oMeldshaper, i);
if (DEBUG) DoDebug("Reducing Essentia in Meld "+IntToString(i)+" by "+IntToString(nChange));
//if (DEBUG) DoDebug("Reducing Essentia in Meld "+IntToString(i)+" by "+IntToString(nChange));
}
else // Means the reduction is higher than the temp essentia ammount
{
@@ -896,12 +826,12 @@ void SpawnTempEssentiaChecker(object oMeldshaper)
DeleteLocalInt(oMeldshaper, "TempEssentiaAmount"+IntToString(i));
SetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(i), GetEssentiaInvested(oMeldshaper, i)-nTest);
ShapeSoulmeld(oMeldshaper, i);
if (DEBUG) DoDebug("Deleted Temp Essentia in Meld "+IntToString(i)+", total "+IntToString(nTest));
//if (DEBUG) DoDebug("Deleted Temp Essentia in Meld "+IntToString(i)+", total "+IntToString(nTest));
}
// Reduce the remaining amount of reduction by the amount we just used up
nRed = nRed - nTest;
if (DEBUG) DoDebug("Remaining Temp Essentia to reduce "+IntToString(nRed));
//if (DEBUG) DoDebug("Remaining Temp Essentia to reduce "+IntToString(nRed));
if (0 >= nRed) break; // End the loop if we're done
}
}
@@ -976,7 +906,7 @@ int GetTotalEssentiaInvested(object oMeldshaper)
nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_ABROGATION)); // MELD_WITCH_ABROGATION
nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_SPIRITFLAY)); // MELD_WITCH_SPIRITFLAY
nCount += GetLocalInt(oMeldshaper, "MeldEssentia"+IntToString(MELD_WITCH_INTEGUMENT)); // MELD_WITCH_INTEGUMENT
if (DEBUG) DoDebug("GetTotalEssentiaInvested is "+IntToString(nCount));
//if (DEBUG) DoDebug("GetTotalEssentiaInvested is "+IntToString(nCount));
return nCount;
}
@@ -1014,7 +944,7 @@ int EssentiaIDToRealID(int nEssentiaID)
else if (nEssentiaID == 18641) nReal = MELD_WITCH_SPIRITFLAY;
else if (nEssentiaID == 18643) nReal = MELD_WITCH_INTEGUMENT;
if (DEBUG) DoDebug("EssentiaToRealID: nEssentiaID "+IntToString(nEssentiaID)+" nReal "+IntToString(nReal));
//if (DEBUG) DoDebug("EssentiaToRealID: nEssentiaID "+IntToString(nEssentiaID)+" nReal "+IntToString(nReal));
return nReal; // Return the real spellID
}
@@ -1227,7 +1157,7 @@ int GetOpposition(object oMeldshaper, object oTarget)
void SetTemporaryEssentia(object oMeldshaper, int nEssentia)
{
if (DEBUG) DoDebug("Set Temporary Essentia from "+IntToString(GetLocalInt(oMeldshaper, "TemporaryEssentia"))+" to "+IntToString(GetLocalInt(oMeldshaper, "TemporaryEssentia")+nEssentia));
//if (DEBUG) DoDebug("Set Temporary Essentia from "+IntToString(GetLocalInt(oMeldshaper, "TemporaryEssentia"))+" to "+IntToString(GetLocalInt(oMeldshaper, "TemporaryEssentia")+nEssentia));
SetLocalInt(oMeldshaper, "TemporaryEssentia", GetLocalInt(oMeldshaper, "TemporaryEssentia")+nEssentia);
}
@@ -1252,7 +1182,7 @@ int GetMaxEssentiaCapacityFeat(object oMeldshaper)
// Don't allow more than they have
if (nMax > GetTotalUsableEssentia(oMeldshaper)) nMax = GetTotalUsableEssentia(oMeldshaper);
if (DEBUG) DoDebug("GetMaxEssentiaCapacityFeat: nHD "+IntToString(nHD)+" nMax "+IntToString(nMax));
//if (DEBUG) DoDebug("GetMaxEssentiaCapacityFeat: nHD "+IntToString(nHD)+" nMax "+IntToString(nMax));
return nMax;
}
@@ -1418,7 +1348,7 @@ int GetFeatLockedEssentia(object oMeldshaper)
if (nTest) // If it's not blank
nTotal += GetLocalInt(oMeldshaper, "SpellEssentia"+IntToString(nTest));
}
if (DEBUG) DoDebug("GetFeatLockedEssentia return value "+IntToString(nTotal));
//if (DEBUG) DoDebug("GetFeatLockedEssentia return value "+IntToString(nTotal));
return nTotal;
}
@@ -1461,7 +1391,7 @@ int IncarnumFeats(object oMeldshaper)
for(i = FEAT_EPIC_ESSENTIA_1; i <= FEAT_EPIC_ESSENTIA_6; i++)
if(GetHasFeat(i, oMeldshaper)) nEssentia += 3;
if (DEBUG) DoDebug("IncarnumFeats return value "+IntToString(nEssentia));
//if (DEBUG) DoDebug("IncarnumFeats return value "+IntToString(nEssentia));
return nEssentia;
}
@@ -1488,7 +1418,7 @@ int GetTotalEssentia(object oMeldshaper)
if (GetLevelByClass(CLASS_TYPE_INCANDESCENT_CHAMPION, oMeldshaper)) nEssentia += GetMaxEssentiaCount(oMeldshaper, CLASS_TYPE_INCANDESCENT_CHAMPION);
nEssentia += IncarnumFeats(oMeldshaper);
if (DEBUG) DoDebug("GetTotalEssentia return value "+IntToString(nEssentia));
//if (DEBUG) DoDebug("GetTotalEssentia return value "+IntToString(nEssentia));
return nEssentia;
}
@@ -1505,7 +1435,7 @@ int GetIncarnumFeats(object oMeldshaper)
if (GetHasFeat(i, oMeldshaper))
nTotal += 1;
}
if (DEBUG) DoDebug("GetIncarnumFeats return value "+IntToString(nTotal));
//if (DEBUG) DoDebug("GetIncarnumFeats return value "+IntToString(nTotal));
return nTotal;
}
@@ -1513,7 +1443,7 @@ int GetIsBlademeldUsed(object oMeldshaper, int nChakra)
{
int nTest = GetLocalInt(oMeldshaper, "UsedBladeMeld"+IntToString(nChakra));
if (DEBUG) DoDebug("GetIsBlademeldUsed is "+IntToString(nTest));
//if (DEBUG) DoDebug("GetIsBlademeldUsed is "+IntToString(nTest));
return nTest;
}

View File

@@ -223,6 +223,17 @@ int TattooFocus(int spell_id, int nSchool, object oCaster)
return nDC;
}
//Tattoo Focus DC boost based on spell school specialization
int JaebrinEnchant(int nSchool, object oCaster)
{
int nDC;
if(nSchool == SPELL_SCHOOL_ENCHANTMENT && GetRacialType(oCaster) == RACIAL_TYPE_JAEBRIN)
nDC = 1;
return nDC;
}
int ShadowWeaveDC(int spell_id, int nSchool, object oCaster)
{
// Account for the Shadow Weave feat
@@ -322,7 +333,7 @@ int SaintHolySpellPower(object oCaster)
}
//:: If it gets here, the caster does not have the feat
return 0;
}
}
//Draconic Power's elemental boost to spell DCs
int DraconicPowerDC(int spell_id, int nElement, object oCaster)
@@ -478,6 +489,18 @@ int StrengthFromMagic(object oCaster)
return 0;
}
// Hobgoblin Warsoul Soul Tyrant
int SoulTyrant(object oCaster)
{
if (GetRacialType(oCaster) != RACIAL_TYPE_HOBGOBLIN_WARSOUL)
return 0;
if (GetIsArcaneClass(PRCGetLastSpellCastClass(oCaster)))
return GetLocalInt(oCaster, "WarsoulTyrant");
return 0;
}
int PRCGetSpellSaveDC(int nSpellID = -1, int nSchool = -1, object oCaster = OBJECT_SELF)
{
if(nSpellID == -1)
@@ -487,8 +510,8 @@ int PRCGetSpellSaveDC(int nSpellID = -1, int nSchool = -1, object oCaster = OBJE
int nClass = PRCGetLastSpellCastClass(oCaster);
int nDC = 10;
if(nClass == CLASS_TYPE_BARD)
if(nClass == CLASS_TYPE_BARD)
nDC += StringToInt(Get2DACache("Spells", "Bard", nSpellID));
else if(nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_UR_PRIEST || nClass == CLASS_TYPE_OCULAR)
nDC += StringToInt(Get2DACache("Spells", "Cleric", nSpellID));
@@ -634,8 +657,6 @@ int PRCGetSpellSaveDC(int nSpellID = -1, int nSchool = -1, object oCaster = OBJE
}
}
return nDC;
}
@@ -756,8 +777,10 @@ int GetChangesToSaveDC(object oTarget, object oCaster, int nSpellID, int nSchool
nDC += Soulcaster(oCaster, nSpellID);
nDC += WyrmbaneHelmDC(oTarget, oCaster);
nDC += StrengthFromMagic(oCaster);
nDC += SoulTyrant(oCaster);
nDC += SaintHolySpellPower(oCaster);
nDC += GetLocalInt(oCaster, PRC_DC_ADJUSTMENT);//this is for builder use
nDC += JaebrinEnchant(nSchool, oCaster);
return nDC;
}

View File

@@ -76,7 +76,7 @@ const int CLASS_TYPE_UMBRAL_DISCIPLE = 109;
const int CLASS_TYPE_ALIENIST = 110;
const int CLASS_TYPE_BLACK_BLOOD_CULTIST = 111;
const int CLASS_TYPE_WARLOCK = 112;
const int CLASS_TYPE_ANTI_PALADIN = 113;
const int CLASS_TYPE_FOCHLUCAN_LYRIST = 113;
const int CLASS_TYPE_DRAGONSONG_LYRIST = 114;
const int CLASS_TYPE_SPINEMELD_WARRIOR = 115;
const int CLASS_TYPE_NIGHTSHADE = 116;
@@ -195,7 +195,7 @@ const int CLASS_TYPE_TRUENAMER = 228;
const int CLASS_TYPE_MASTER_ALCHEMIST = 229;
const int CLASS_TYPE_BEREFT = 230;
const int CLASS_TYPE_BRIMSTONE_SPEAKER = 231;
const int CLASS_TYPE_FOCHLUCAN_LYRIST = 232;
const int CLASS_TYPE_SHUGENJA = 232;
const int CLASS_TYPE_SOHEI = 233;
const int CLASS_TYPE_CRUSADER = 234;
const int CLASS_TYPE_SWORDSAGE = 235;
@@ -219,6 +219,7 @@ const int CLASS_TYPE_FROSTRAGER = 252;
const int CLASS_TYPE_CRINTI_SHADOW_MARAUDER = 253;
const int CLASS_TYPE_SHADOW_THIEF_AMN = 254;
const int CLASS_TYPE_ANTI_PALADIN = -1;
const int CLASS_TYPE_NIGHTSTALKER = -1; //Just here to make things compile until it gets stripped out
const int CLASS_TYPE_MINSTREL_EDGE = -1;
const int CLASS_TYPE_BRAWLER = -1;
@@ -235,6 +236,6 @@ const int CLASS_TYPE_WITCH = -1;
const int CLASS_TYPE_TEMPLAR = -1;
const int CLASS_TYPE_MYSTIC = -1;
const int CLASS_TYPE_NOBLE = -1;
const int CLASS_TYPE_SHUGENJA = -1;
//void main (){}

View File

@@ -1233,16 +1233,17 @@ const int FEAT_RANGER_DUAL = 374;
const int FEAT_CAMOUFLAGE = 4486;
//Exalted Feat
const int FEAT_SAC_VOW = 3388;
const int FEAT_VOW_OBED = 3389;
const int FEAT_EXALTED_TURNING = 3168;
const int FEAT_HAND_HEALER = 3167;
const int FEAT_NIMBUSLIGHT = 3165;
const int FEAT_HOLYRADIANCE = 3164;
const int FEAT_STIGMATA = 3163;
const int FEAT_SERVHEAVEN = 3355;
const int FEAT_RANGED_SMITE = 3356;
const int FEAT_VOW_PURITY = 5360;
const int FEAT_SAC_VOW = 3388;
const int FEAT_VOW_OBED = 3389;
const int FEAT_EXALTED_TURNING = 3168;
const int FEAT_HAND_HEALER = 3167;
const int FEAT_NIMBUSLIGHT = 3165;
const int FEAT_HOLYRADIANCE = 3164;
const int FEAT_STIGMATA = 3163;
const int FEAT_SERVHEAVEN = 3355;
const int FEAT_RANGED_SMITE = 3356;
const int FEAT_VOW_PURITY = 5360;
const int FEAT_VOWOFPOVERTY = 26001;
//Vile Feat
const int FEAT_LICHLOVED = 3395;

View File

@@ -565,6 +565,8 @@ int PRCGetCasterLevel(object oCaster = OBJECT_SELF)
iReturnLevel = GetLevelByClass(CLASS_TYPE_ABERRATION);
else if(nRace == RACIAL_TYPE_ARKAMOI)
iReturnLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS);
else if(nRace == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
iReturnLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS);
else if(nRace == RACIAL_TYPE_REDSPAWN_ARCANISS)
iReturnLevel = GetLevelByClass(CLASS_TYPE_MONSTROUS)*3/4;
else if(nRace == RACIAL_TYPE_MARRUTACT)
@@ -749,6 +751,9 @@ int GetIsArcaneClass(int nClass, object oCaster = OBJECT_SELF)
|| (nClass == CLASS_TYPE_MONSTROUS
&& GetRacialType(oCaster) == RACIAL_TYPE_ARKAMOI
&& !GetLevelByClass(CLASS_TYPE_SORCERER))
|| (nClass == CLASS_TYPE_MONSTROUS
&& GetRacialType(oCaster) == RACIAL_TYPE_HOBGOBLIN_WARSOUL
&& !GetLevelByClass(CLASS_TYPE_SORCERER))
|| (nClass == CLASS_TYPE_MONSTROUS
&& GetRacialType(oCaster) == RACIAL_TYPE_REDSPAWN_ARCANISS
&& !GetLevelByClass(CLASS_TYPE_SORCERER))
@@ -2513,6 +2518,8 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
nArcane += GetLevelByClass(CLASS_TYPE_ABERRATION);
if(nRace == RACIAL_TYPE_ARKAMOI)
nArcane += GetLevelByClass(CLASS_TYPE_MONSTROUS);
if(nRace == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
nArcane += GetLevelByClass(CLASS_TYPE_MONSTROUS);
if(nRace == RACIAL_TYPE_REDSPAWN_ARCANISS)
nArcane += GetLevelByClass(CLASS_TYPE_MONSTROUS)*3/4;
if(nRace == RACIAL_TYPE_MARRUTACT)
@@ -2679,6 +2686,7 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
|| nRace == RACIAL_TYPE_ARKAMOI
|| nRace == RACIAL_TYPE_MARRUTACT
|| nRace == RACIAL_TYPE_REDSPAWN_ARCANISS
|| nRace == RACIAL_TYPE_HOBGOBLIN_WARSOUL
|| nRace == RACIAL_TYPE_RAKSHASA
|| nRace == RACIAL_TYPE_ARANEA
&& !GetLevelByClass(CLASS_TYPE_SORCERER))
@@ -5857,7 +5865,7 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
int GetFirstArcaneClassPosition(object oCaster = OBJECT_SELF)
{
int i;
for(i = 1; i < 9; i++)
for(i = 1; i <= 8; i++)
{
if(GetIsArcaneClass(GetClassByPosition(i, oCaster), oCaster))
return i;
@@ -5869,7 +5877,7 @@ int GetFirstArcaneClassPosition(object oCaster = OBJECT_SELF)
int GetFirstDivineClassPosition(object oCaster = OBJECT_SELF)
{
int i;
for(i = 1; i < 9; i++)
for(i = 1; i <= 8; i++)
{
if(GetIsDivineClass(GetClassByPosition(i, oCaster), oCaster))
return i;
@@ -5892,7 +5900,7 @@ int GetPrimaryArcaneClass(object oCaster = OBJECT_SELF)
else
{
int i, nClassTmp, nClassLvl;
for(i = 1; i < 9; i++)
for(i = 1; i <= 8; i++)
{
nClassTmp = GetClassByPosition(i, oCaster);
if(GetIsArcaneClass(nClassTmp, oCaster) && nClassTmp != CLASS_TYPE_SUBLIME_CHORD)
@@ -5936,7 +5944,7 @@ int GetPrimaryDivineClass(object oCaster = OBJECT_SELF)
else
{
int i, nClassTmp, nClassLvl;
for(i = 1; i < 9; i++)
for(i = 1; i <= 8; i++)
{
nClassTmp = GetClassByPosition(i, oCaster);
if(GetIsDivineClass(nClassTmp, oCaster))
@@ -5961,7 +5969,7 @@ int GetPrimarySpellcastingClass(object oCaster = OBJECT_SELF)
int nClass;
int i, nClassTmp, nClassLvl;
for(i = 1; i < 9; i++)
for(i = 1; i <= 8; i++)
{
nClassTmp = GetClassByPosition(i, oCaster);
if(GetIsArcaneClass(nClassTmp, oCaster)

View File

@@ -1709,8 +1709,25 @@ int DoGrappleOptions(object oPC, object oTarget, int nExtraBonus, int nSwitch =
}
if (GetHasFeat(FEAT_EARTHS_EMBRACE, oPC))
{
int nDam = d12();
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam), oTarget);
// Add in unarmed damage
int nDamageSize = FindUnarmedDamage(oPC);
int nDie = StringToInt(Get2DACache("iprp_monstcost", "Die", nDamageSize));
int nNum = StringToInt(Get2DACache("iprp_monstcost", "NumDice", nDamageSize));
int nRoll;
//Potential die options
if(nDie == 4) nRoll = d4(nNum);
else if(nDie == 6) nRoll = d6(nNum);
else if(nDie == 8) nRoll = d8(nNum);
else if(nDie == 10) nRoll = d10(nNum);
else if(nDie == 12) nRoll = d12(nNum);
else if(nDie == 20) nRoll = d20(nNum);
FloatingTextStringOnCreature("Earth's Embrace chokes the life from your foe", oPC, FALSE);
int nDam = d12() + nRoll;
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDam, DAMAGE_TYPE_BLUDGEONING), oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectACDecrease(4)), oPC, 6.0);
}
}

View File

@@ -243,7 +243,7 @@ void CastDomainSpell(object oPC, int nSlot, int nLevel)
if(!nCount)
{
int n;
for(n = 1; n < 8; n++)
for(n = 1; n < 9; n++)
{
nClass = GetClassByPosition(n, oPC);

View File

@@ -424,7 +424,7 @@ void EvalPRCFeats(object oPC)
if (ToBFeats(oPC))
ExecuteScript("tob_feats", oPC);
if (GetIsIncarnumUser(oPC))
if (GetIsIncarnumUser(oPC) || GetRacialType(oPC) == RACIAL_TYPE_JAEBRIN)
ExecuteScript("moi_events", oPC);
if (GetIsBinder(oPC))

View File

@@ -16,6 +16,11 @@ const string COHORT_TAG = "prc_cohort";
int Cohort_X_class1 (cohort class pos1)
int Cohort_X_class2 (cohort class pos2)
int Cohort_X_class3 (cohort class pos3)
int Cohort_X_class4 (cohort class pos4)
int Cohort_X_class5 (cohort class pos5)
int Cohort_X_class6 (cohort class pos6)
int Cohort_X_class7 (cohort class pos7)
int Cohort_X_class8 (cohort class pos8)
int Cohort_X_order (cohort law/chaos measure)
int Cohort_X_moral (cohort good/evil measure)
int Cohort_X_ethran (cohort has ethran feat)
@@ -595,9 +600,9 @@ void StoreCohort(object oCohort)
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class3", GetClassByPosition(3, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class4", GetClassByPosition(4, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class5", GetClassByPosition(5, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class6", GetClassByPosition(6, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class6", GetClassByPosition(6, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class7", GetClassByPosition(7, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class8", GetClassByPosition(8, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_class8", GetClassByPosition(8, oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_order", GetLawChaosValue(oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_moral", GetGoodEvilValue(oCohort));
SetCampaignInt( COHORT_DATABASE, "Cohort_"+IntToString(nCohortCount)+"_ethran", GetHasFeat(FEAT_ETHRAN, oCohort));
@@ -833,7 +838,7 @@ int GetMaximumCohortCount(object oPC)
return nCount;
}
int GetIsCohortChoiceValid(string sName, int nRace, int nClass1, int nClass2, int nClass3, int nOrder, int nMoral, int nEthran, string sKey, int nDeleted, object oPC)
int GetIsCohortChoiceValid(string sName, int nRace, int nClass1, int nClass2, int nClass3, int nClass4, int nClass5, int nClass6, int nClass7, int nClass8, int nOrder, int nMoral, int nEthran, string sKey, int nDeleted, object oPC)
{
//has been deleted
if(nDeleted)
@@ -891,7 +896,12 @@ int GetIsCohortChoiceValid(string sName, int nRace, int nClass1, int nClass2, in
&& !nEthran
&& nClass1 != CLASS_TYPE_BARBARIAN
&& nClass2 != CLASS_TYPE_BARBARIAN
&& nClass3 != CLASS_TYPE_BARBARIAN)
&& nClass3 != CLASS_TYPE_BARBARIAN
&& nClass4 != CLASS_TYPE_BARBARIAN
&& nClass5 != CLASS_TYPE_BARBARIAN
&& nClass6 != CLASS_TYPE_BARBARIAN
&& nClass7 != CLASS_TYPE_BARBARIAN
&& nClass8 != CLASS_TYPE_BARBARIAN)
bIsValid = FALSE;
}
//OrcWarlord
@@ -916,6 +926,7 @@ int GetIsCohortChoiceValid(string sName, int nRace, int nClass1, int nClass2, in
&& nRace != RACIAL_TYPE_GRAYORC
&& nRace != RACIAL_TYPE_OROG
&& nRace != RACIAL_TYPE_TANARUKK
&& nRace != RACIAL_TYPE_FROSTBLOOD_ORC
)
bIsValid = FALSE;
}
@@ -934,12 +945,17 @@ int GetIsCohortChoiceValidByID(int nID, object oPC)
int nClass1=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class1");
int nClass2=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class2");
int nClass3=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class3");
int nClass4=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class4");
int nClass5=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class5");
int nClass6=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class6");
int nClass7=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class7");
int nClass8=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_class8");
int nOrder= GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_order");
int nMoral= GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_moral");
int nEthran=GetCampaignInt( COHORT_DATABASE, "Cohort_"+sID+"_ethran");
string sKey = GetCampaignString( COHORT_DATABASE, "Cohort_"+sID+"_cdkey");
int nDeleted = GetCampaignInt(COHORT_DATABASE, "Cohort_"+sID+"_deleted");
return GetIsCohortChoiceValid(sName, nRace, nClass1, nClass2, nClass3, nOrder, nMoral, nEthran, sKey, nDeleted, oPC);
return GetIsCohortChoiceValid(sName, nRace, nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8, nOrder, nMoral, nEthran, sKey, nDeleted, oPC);
}
int GetCanRegister(object oPC)

View File

@@ -19,6 +19,8 @@ int PRCDoRangedTouchAttack(object oTarget, int nDisplayFeedback = TRUE, object o
return GetLocalInt(oCaster, sCacheName);
if(GetPersistantLocalInt(oCaster, "template_102")) // TEMPLATE_DEMILICH
nAttackBonus += GetHitDice(oCaster);
if(GetLocalInt(oCaster, "WarsoulTyrant")) // Hobgoblin Warsoul
nAttackBonus += GetLocalInt(oCaster, "WarsoulTyrant");
if(GetHasFeat(FEAT_SHIELD_WARD, oTarget))
{
@@ -63,6 +65,8 @@ int PRCDoMeleeTouchAttack(object oTarget, int nDisplayFeedback = TRUE, object oC
return GetLocalInt(oCaster, sCacheName);
if(GetPersistantLocalInt(oCaster, "template_102")) // TEMPLATE_DEMILICH
nAttackBonus += GetHitDice(oCaster);
if(GetLocalInt(oCaster, "WarsoulTyrant")) // Hobgoblin Warsoul
nAttackBonus += GetLocalInt(oCaster, "WarsoulTyrant");
if(GetHasFeat(FEAT_SHIELD_WARD, oTarget))
{
int nBase = GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget));

View File

@@ -803,6 +803,9 @@ int SpellDamagePerDice(object oCaster, int nDice)
int nDam = 0;
nDam += GetLocalInt(oCaster, "StrengthFromMagic") * nDice * 2;
if (GetLocalInt(oCaster, "WarsoulTyrant"))
nDam += nDice * GetHitDice(oCaster);
if (DEBUG) DoDebug("SpellDamagePerDice returning "+IntToString(nDam)+" for "+GetName(oCaster));
@@ -1217,6 +1220,15 @@ int PRCMySavingThrow(int nSavingThrow, object oTarget, int nDC, int nSaveType =
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(), DAMAGE_TYPE_MAGICAL), oSaveVersus);
ApplyAbilityDamage(oSaveVersus, ABILITY_WISDOM, 1, DURATION_TYPE_TEMPORARY, TRUE, -1.0);
}
}
// Hobgoblin Warsoul spell eater
if(nSaveRoll == 1 && GetRacialType(oTarget) == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
{
//Apply the Aid VFX impact and effects
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_HOLY_AID), oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectAttackIncrease(2), oTarget, 6.0);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectTemporaryHitpoints(5), oTarget, 60.0);
}
return nSaveRoll;
@@ -1339,6 +1351,8 @@ int GetCasterLvl(int iTypeSpell, object oCaster = OBJECT_SELF)
//Arkamoi + Redspawn include MH HD as sorc
if(nRace == RACIAL_TYPE_ARKAMOI)
iTemp = GetLevelByClass(CLASS_TYPE_MONSTROUS, oCaster);
if(nRace == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
iTemp = GetLevelByClass(CLASS_TYPE_MONSTROUS, oCaster);
if(nRace == RACIAL_TYPE_REDSPAWN_ARCANISS)
iTemp = GetLevelByClass(CLASS_TYPE_MONSTROUS, oCaster)*3/4;
if(nRace == RACIAL_TYPE_MARRUTACT)
@@ -1403,7 +1417,6 @@ int GetCasterLvl(int iTypeSpell, object oCaster = OBJECT_SELF)
case CLASS_TYPE_VASSAL:
return GetCasterLvlDivine(iTypeSpell, oCaster);
case CLASS_TYPE_ANTI_PALADIN:
case CLASS_TYPE_PALADIN:
case CLASS_TYPE_RANGER:
case CLASS_TYPE_SOHEI:
@@ -3057,4 +3070,4 @@ int X2PreSpellCastCode()
}
//:: Test Void
//void main (){}
// void main (){}

View File

@@ -392,6 +392,7 @@ int GetTurningClassLevel(object oCaster = OBJECT_SELF, int nTurnType = SPELL_TUR
//full classes
nLevel += GetLevelByClass(CLASS_TYPE_CLERIC, oCaster);
nLevel += GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oCaster);
nLevel += GetLevelByClass(CLASS_TYPE_TRUENECRO);
nLevel += GetLevelByClass(CLASS_TYPE_SOLDIER_OF_LIGHT, oCaster);
nLevel += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
nLevel += GetLevelByClass(CLASS_TYPE_MORNINGLORD, oCaster);

View File

@@ -72,6 +72,7 @@ const int RACIAL_TYPE_SPIRETOPDRAGON = 77;
const int RACIAL_TYPE_BRALANI = 159;
const int RACIAL_TYPE_BROWNIE = 53;
const int RACIAL_TYPE_GRIG = 133;
const int RACIAL_TYPE_JAEBRIN = 78;
const int RACIAL_TYPE_NIXIE = 134;
const int RACIAL_TYPE_NYMPH = 135;
const int RACIAL_TYPE_PIXIE = 226;
@@ -236,10 +237,10 @@ const int RACIAL_TYPE_KARSITE = 65;
/* Standard Races */
//Human
//:: Human
const int RACIAL_TYPE_SILVERBROW_HUMAN = 110;
//Elf
//:: Elf
const int RACIAL_TYPE_AQELF = 161;
const int RACIAL_TYPE_AVARIEL = 162;
const int RACIAL_TYPE_DROW_FEMALE = 163;
@@ -253,7 +254,7 @@ const int RACIAL_TYPE_WILD_ELF = 167;
const int RACIAL_TYPE_WOOD_ELF = 168;
const int RACIAL_TYPE_GREY_ELF = 169;
//Dwarf
//:: Dwarf
const int RACIAL_TYPE_ARC_DWARF = 151;
const int RACIAL_TYPE_DREAM_DWARF = 157;
const int RACIAL_TYPE_FIREBLOOD_DWARF = 106;
@@ -264,7 +265,7 @@ const int RACIAL_TYPE_GLACIER_DWARF = 154;
const int RACIAL_TYPE_URDINNIR = 155;
const int RACIAL_TYPE_WILD_DWARF = 156;
//Gnome
//:: Gnome
const int RACIAL_TYPE_CHAOS_GNOME = 177;
const int RACIAL_TYPE_DEEP_GNOME = 174;
const int RACIAL_TYPE_FIRE_GNOME = 173;
@@ -275,7 +276,7 @@ const int RACIAL_TYPE_STONEHUNTER_GNOME = 105;
const int RACIAL_TYPE_SVIRFNEBLIN = 174;
const int RACIAL_TYPE_WHISPER_GNOME = 179;
//Halfling
//:: Halfling
const int RACIAL_TYPE_DEEP_HALFLING = 194;
const int RACIAL_TYPE_GHOSTWISE_HALFLING = 190;
const int RACIAL_TYPE_GLIMMERSKIN_HALFING = 109;
@@ -285,28 +286,30 @@ const int RACIAL_TYPE_STRONGHEART_HALFLING = 192;
const int RACIAL_TYPE_TALLFELLOW_HALFLING = 193;
const int RACIAL_TYPE_TUNDRA_HALFLING = 191;
//Goblin
//:: Goblinoid
const int RACIAL_TYPE_BLUE_GOBLIN = 143;
const int RACIAL_TYPE_DEKANTER = 142;
const int RACIAL_TYPE_GOBLIN = 213;
const int RACIAL_TYPE_SNOW_GOBLIN = 141;
//"Greenskin" Races
const int RACIAL_TYPE_BUGBEAR = 217;
const int RACIAL_TYPE_HOBGOBLIN = 221;
const int RACIAL_TYPE_SUNSCORCH_HOBGOBLIN = 111;
const int RACIAL_TYPE_VARAG = 232;
const int RACIAL_TYPE_HOBGOBLIN_WARSOUL = 233;
//:: "Greenskin" Races
const int RACIAL_TYPE_FLIND = 211;
const int RACIAL_TYPE_FROSTBLOOD_ORC = 108;
const int RACIAL_TYPE_GNOLL = 216;
const int RACIAL_TYPE_GRAYORC = 184;
const int RACIAL_TYPE_HALFOGRE = 229;
const int RACIAL_TYPE_HOBGOBLIN = 221;
const int RACIAL_TYPE_KOBOLD = 215;
const int RACIAL_TYPE_MINOTAUR = 218;
const int RACIAL_TYPE_OGRE = 212;
const int RACIAL_TYPE_OMAGE = 211;
const int RACIAL_TYPE_OROG = 187;
const int RACIAL_TYPE_ORC = 214;
const int RACIAL_TYPE_SUNSCORCH_HOBGOBLIN = 111;
const int RACIAL_TYPE_TROLL = 231;
const int RACIAL_TYPE_VARAG = 232;

View File

@@ -111,6 +111,14 @@ int PRCGetSpellResistance(object oTarget, object oCaster)
iSpellRes = nCont;
}
// Hobgoblin Wsrsoul
if(GetRacialType(oTarget) == RACIAL_TYPE_HOBGOBLIN_WARSOUL)
{
int nCont = 8 + GetHitDice(oTarget);
if(nCont > iSpellRes)
iSpellRes = nCont;
}
// Exordius Weapon of Legacy
if(GetLocalInt(oTarget, "ExordiusSR"))
{

View File

@@ -929,6 +929,8 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
int nLevel;
int nAdjust = GetLocalInt(oManifester, PRC_CASTERLEVEL_ADJUSTMENT);
nAdjust -= GetLocalInt(oManifester, "WoLManifPenalty");
if(DEBUG) DoDebug("GetManifesterLevel Specific Class: " + IntToString(nSpecificClass), oManifester);
// The function user needs to know the character's manifester level in a specific class
// instead of whatever the character last manifested a power as
@@ -960,7 +962,7 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
nLevel = GetLocalInt(oManifester, "AbysmPsion");
nMaxPowerLevel = TRUE;
}
if(DEBUG) DoDebug("GetManifesterLevel Specific Class Manif Level: " + IntToString(nLevel), oManifester);
// This is for learning powers, we need to ignore some adjustments
if (nMaxPowerLevel) return nLevel;
@@ -993,7 +995,7 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
{
//Gets the manifesting class
int nManifestingClass = GetManifestingClass(oManifester);
// if(DEBUG) DoDebug("Manifesting class: " + IntToString(nManifestingClass), oManifester);
if(DEBUG) DoDebug("Manifesting Class #2: " + IntToString(nManifestingClass), oManifester);
nLevel = GetLevelByClass(nManifestingClass, oManifester);
// Add levels from +ML PrCs only for the first manifesting class
nLevel += GetPsionicPRCLevels(oManifester, nManifestingClass);
@@ -1016,7 +1018,7 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
nLevel = GetLocalInt(oManifester, "AbysmPsion");
nMaxPowerLevel = TRUE;
}
if(DEBUG) DoDebug("GetManifesterLevel Unspecific Class Manif Level: " + IntToString(nLevel), oManifester);
// This is for learning powers, we need to ignore some adjustments
if (nMaxPowerLevel) return nLevel;
@@ -1061,7 +1063,7 @@ int GetManifesterLevel(object oManifester, int nSpecificClass = CLASS_TYPE_INVAL
nLevel += nAdjust;
// This spam is technically no longer necessary once the manifester level getting mechanism has been confirmed to work
// if(DEBUG) FloatingTextStringOnCreature("Manifester Level: " + IntToString(nLevel), oManifester, FALSE);
if(DEBUG) FloatingTextStringOnCreature("Manifester Level: " + IntToString(nLevel), oManifester, FALSE);
return nLevel;
}

View File

@@ -2703,7 +2703,24 @@ void RedspawnHealing(object oCaster, int nSpellID, int nSpellLevel)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nSpellLevel*2), oCaster);
}
}
}
void WarsoulTyrant(object oCaster, int nCastingClass)
{
// This race only
if (GetRacialType(oCaster) != RACIAL_TYPE_HOBGOBLIN_WARSOUL)
return;
int nStrength = GetLocalInt(oCaster, "WarsoulTyrant");
// Only applies to arcane spells
if (GetIsArcaneClass(nCastingClass, oCaster))
{
// First time here
if (nStrength)
DelayCommand(1.0, DeleteLocalInt(oCaster, "WarsoulTyrant"));
}
}
// this will execute the prespellcastcode, whose full functionality is incoded in X2PreSpellCastCode2(),
// as a script, to save loading time for spells scripts and reduce memory usage of NWN
@@ -3145,6 +3162,7 @@ int X2PreSpellCastCode2()
// Races
ArkamoiStrength(oCaster, nCastingClass);
WarsoulTyrant(oCaster, nCastingClass);
RedspawnHealing(oCaster, nSpellID, nSpellLevel);
// Feats