2026/05/27 Update
Verminlord requires Eldritch Blast as a prereq. Mettle branch in ApplyBreath() is fixed. Zen Archery now applies to Rays / Eldritch Blast. Runes will only support divine spells. School Specialization shouldn't block multiclass Red Wizards of Thay from divine spells in their opposition schools. Scepters, Runes, Skull Talismans & Attuned Gems are considered spell-completion items for RWoT School Specialization. Fixed Acolyte of the Skin's Damage Reduction. For real this time. Sneak Attack now takes Daring Outlaw / Swashbuckler into consideration. Updated Changelog.
This commit is contained in:
@@ -795,9 +795,13 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
|
||||
{
|
||||
//Mettle is Evasion for Fort saves
|
||||
if (GetHasMettle(oTarget, SAVING_THROW_FORT))
|
||||
{
|
||||
nAdjustedDamage = 0;
|
||||
|
||||
nAdjustedDamage /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
nAdjustedDamage /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -3759,9 +3759,20 @@ int GetAttackBonus(object oDefender, object oAttacker, object oWeap, int iOffhan
|
||||
&& GetHasFeat(FEAT_INTUITIVE_ATTACK, oAttacker) )
|
||||
iAbilityBonus = iWis;
|
||||
|
||||
//touch attacks always use dex, no matter what. Therefore override any calculations we have done so far
|
||||
//touch attacks always use dex, no matter what. Therefore override any calculations we have done so far
|
||||
//unless it's a ranged touch attack and the attacker has Zen Archery with higher WIS
|
||||
if(iTouchAttackType)
|
||||
{
|
||||
if((iTouchAttackType == TOUCH_ATTACK_RANGED || iTouchAttackType == TOUCH_ATTACK_RANGED_SPELL)
|
||||
&& iWis > iDex && GetHasFeat(FEAT_ZEN_ARCHERY, oAttacker))
|
||||
iAbilityBonus = iWis;
|
||||
else
|
||||
iAbilityBonus = iDex;
|
||||
}
|
||||
|
||||
/* //touch attacks always use dex, no matter what. Therefore override any calculations we have done so far
|
||||
if(iTouchAttackType)
|
||||
iAbilityBonus = iDex;
|
||||
iAbilityBonus = iDex; */
|
||||
|
||||
// Expertise penalties apply to all attack rolls
|
||||
if (iCombatMode == COMBAT_MODE_EXPERTISE) iCombatModeBonus -= 5;
|
||||
|
||||
@@ -1726,6 +1726,24 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI
|
||||
|
||||
if(!GetIsObjectValid(oTarget)) oTarget = PRCGetSpellTargetObject();
|
||||
int nCaster = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster));
|
||||
|
||||
// Get the spell and class
|
||||
if(!nSpell) nSpell = PRCGetSpellId();
|
||||
int nLastClass = PRCGetLastSpellCastClass();
|
||||
|
||||
// Check if the casting class is divine
|
||||
if (!GetIsDivineClass(nLastClass))
|
||||
{
|
||||
FloatingTextStringOnCreature("Inscribe Rune can only be used with divine spells.", oCaster, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Check if the spell is on the caster's divine spell list
|
||||
if (!GetHasSpellOnClassList(oCaster, nSpell))
|
||||
{
|
||||
FloatingTextStringOnCreature("You must have this spell on your divine spell list to inscribe it.", oCaster, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//:: Check for Inscribe Epic Runes and cap CL at 20 if it doesn't exist.
|
||||
int bEpicRunes = GetHasFeat(EPIC_FEAT_INSCRIBE_EPIC_RUNES, oCaster);
|
||||
@@ -1744,7 +1762,6 @@ int InscribeRune(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALI
|
||||
// Runecraft local int that counts uses/charges
|
||||
int nCount = GetLocalInt(oCaster, "RuneCounter");
|
||||
|
||||
int nLastClass = PRCGetLastSpellCastClass();
|
||||
if (nLastClass == CLASS_TYPE_CLERIC || nLastClass == CLASS_TYPE_UR_PRIEST) nSpellLevel = StringToInt(lookup_spell_cleric_level(nSpell));
|
||||
else if (nLastClass == CLASS_TYPE_DRUID) nSpellLevel = StringToInt(lookup_spell_druid_level(nSpell));
|
||||
else if (nLastClass == CLASS_TYPE_WIZARD || nLastClass == CLASS_TYPE_SORCERER) nSpellLevel = StringToInt(lookup_spell_level(nSpell));
|
||||
@@ -3624,31 +3641,6 @@ int CICraftCheckCreateInfusion(object oSpellTarget, object oCaster, int nID = 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* // -------------------------------------------------------------------------
|
||||
// Create the infused herb item
|
||||
// -------------------------------------------------------------------------
|
||||
object oInfusion = CICreateInfusion(oCaster, nID);
|
||||
|
||||
if (GetIsObjectValid(oInfusion))
|
||||
{
|
||||
SetIdentified(oInfusion, TRUE);
|
||||
ActionPlayAnimation(ANIMATION_FIREFORGET_READ, 1.0);
|
||||
SpendXP(oCaster, costs.nXPCost);
|
||||
SpendGP(oCaster, costs.nGoldCost);
|
||||
DestroyObject(oSpellTarget);
|
||||
FloatingTextStrRefOnCreature(8502, oCaster); // Item creation successful
|
||||
|
||||
if (!costs.nTimeCost) costs.nTimeCost = 1;
|
||||
AdvanceTimeForPlayer(oCaster, RoundsToSeconds(costs.nTimeCost));
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
FloatingTextStringOnCreature("Infusion creation failed", oCaster); // Item creation failed
|
||||
FloatingTextStrRefOnCreature(76417, oCaster); // Item creation failed
|
||||
return TRUE;
|
||||
} */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -947,7 +947,72 @@ int SpellAlignmentRestrictions(object oCaster, int nSpellID, int nCastingClass)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int RedWizRestrictedSchool(object oCaster, int nSchool, int nCastingClass, object oSpellCastItem)
|
||||
int RedWizRestrictedSchool(object oCaster, int nSchool, int nCastingClass, object oSpellCastItem)
|
||||
{
|
||||
// No need for wasting CPU on non-Red Wizards
|
||||
if(GetLevelByClass(CLASS_TYPE_RED_WIZARD, oCaster))
|
||||
{
|
||||
//can't cast prohibited spells from scrolls, wands, infused herbs, scepters, runes, gems, or skull talismans
|
||||
if(GetIsObjectValid(oSpellCastItem))
|
||||
{
|
||||
int nType = GetBaseItemType(oSpellCastItem);
|
||||
string sTag = GetTag(oSpellCastItem);
|
||||
|
||||
// Check base item types for standard items
|
||||
if(nType != BASE_ITEM_MAGICWAND
|
||||
&& nType != BASE_ITEM_ENCHANTED_WAND
|
||||
&& nType != BASE_ITEM_SCROLL
|
||||
&& nType != BASE_ITEM_SPELLSCROLL
|
||||
&& nType != BASE_ITEM_ENCHANTED_SCROLL
|
||||
&& nType != BASE_ITEM_INFUSED_HERB
|
||||
&& nType != BASE_ITEM_CRAFTED_SCEPTER) // ADD THIS LINE
|
||||
{
|
||||
// Check tags for custom crafted items
|
||||
if(sTag != "prc_rune_1"
|
||||
&& sTag != "prc_attunegem"
|
||||
&& sTag != "prc_skulltalis")
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direct casting: skip restriction for divine classes
|
||||
if(GetIsDivineClass(nCastingClass))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Determine forbidden schools
|
||||
int iRWRes;
|
||||
switch(nSchool)
|
||||
{
|
||||
case SPELL_SCHOOL_ABJURATION: iRWRes = FEAT_RW_RES_ABJ; break;
|
||||
case SPELL_SCHOOL_CONJURATION: iRWRes = FEAT_RW_RES_CON; break;
|
||||
case SPELL_SCHOOL_DIVINATION: iRWRes = FEAT_RW_RES_DIV; break;
|
||||
case SPELL_SCHOOL_ENCHANTMENT: iRWRes = FEAT_RW_RES_ENC; break;
|
||||
case SPELL_SCHOOL_EVOCATION: iRWRes = FEAT_RW_RES_EVO; break;
|
||||
case SPELL_SCHOOL_ILLUSION: iRWRes = FEAT_RW_RES_ILL; break;
|
||||
case SPELL_SCHOOL_NECROMANCY: iRWRes = FEAT_RW_RES_NEC; break;
|
||||
case SPELL_SCHOOL_TRANSMUTATION: iRWRes = FEAT_RW_RES_TRS; break;
|
||||
}
|
||||
|
||||
// Compare the spell's school versus the restricted schools
|
||||
if(iRWRes && GetHasFeat(iRWRes, oCaster))
|
||||
{
|
||||
FloatingTextStrRefOnCreature(16822359, oCaster, FALSE); // "You cannot cast spells of your prohibited schools. Spell terminated."
|
||||
return FALSE;
|
||||
}
|
||||
// Other arcane casters cannot benefit from red wizard bonuses
|
||||
if(GetIsArcaneClass(nCastingClass) && nCastingClass != CLASS_TYPE_WIZARD)
|
||||
{
|
||||
FloatingTextStringOnCreature("You have attempted to illegaly merge another arcane caster with a Red Wizard. All spellcasting will now fail.", oCaster, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* int RedWizRestrictedSchool(object oCaster, int nSchool, int nCastingClass, object oSpellCastItem)
|
||||
{
|
||||
// No need for wasting CPU on non-Red Wizards
|
||||
if(GetLevelByClass(CLASS_TYPE_RED_WIZARD, oCaster))
|
||||
@@ -994,7 +1059,7 @@ int RedWizRestrictedSchool(object oCaster, int nSchool, int nCastingClass, objec
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*/
|
||||
int PnPSpellSchools(object oCaster, int nCastingClass, int nSchool, object oSpellCastItem)
|
||||
{
|
||||
if(GetPRCSwitch(PRC_PNP_SPELL_SCHOOLS)
|
||||
|
||||
Reference in New Issue
Block a user