2 Commits
4.91 ... main

Author SHA1 Message Date
Jaysyn904
b27d9d2e5f 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.
2026-05-27 15:53:01 -04:00
Jaysyn904
da1ff48ac3 2026/05/26 Update
Updated PRC8 version number.
Added SoundImpact to Damning Darkness in vfx_persistent.2da.
Updated CheckPRCLimitations() to make Darkness, Deeper Darkness & Damning Darkness work better.
Fixed PnP Darkness & PnP Damning Darkness.
Fixed Oversized Two-Weapon Fighting.
Updated TLK for Attune Gem.
Fixed typo in Calm Emotions description.
Updated changelog.
2026-05-26 22:53:34 -04:00
22 changed files with 577 additions and 280 deletions

View File

@@ -1,3 +1,32 @@
Commit: Jaysyn904
Date: Tues May 26
Added SoundImpact to Damning Darkness in vfx_persistent.2da.
Updated CheckPRCLimitations() to make Darkness, Deeper Darkness & Damning Darkness work better.
Fixed PnP Darkness & PnP Damning Darkness.
Fixed Oversized Two-Weapon Fighting.
Updated TLK for Attune Gem.
Fixed typo in Calm Emotions description.
Commit: Jaysyn904
Date: Mon May 25
Attune Gem was using the wrong prereqs.
Attune Gem didn't handle radial spells properly.
Attune Gem incorrectly allowed divine spells.
Attune Gem was checking the wrong resref for vanilla gems.
Attune Gem didn't handle stacks of gems properly.
Updated Attune Gem's TLK entry.
PRCGetSaveDC() wasn't using PRCGetSpellCastItem().
Damning Darkness' vfx_persistent.2da entry was typoed.
Damning Darkness was checking the wrong object for inventory item for validity.
Darkness invocation was checking the wrong object for inventory item for validity.
Deeper Darkness was checking the wrong object for inventory item for validity.
Darkness was checking the wrong object for inventory item for validity.
Fixed Dragon's Tooth range & save.
Hopefully fixed Seize Items' VFX.
Fixed Acolyte of the Skin's DR.
Commit: Jaysyn904
Date: Sun May 24
@@ -42,6 +71,7 @@ Fixed taking Ability Focus: Eldritch Blast from bricking a first level character
Archivist should use INT for epic spell DCs, not WIS.
Fixed Sublime Chord epic spell DCs.
Commit: Jaysyn904
Date: Sat May 2 12:46:30 2026

View File

@@ -5324,7 +5324,7 @@
5320 EttercapBerserker 16826796 16826797 ife_wildshape **** **** **** **** **** **** **** **** 293 **** 0 0 1 **** **** **** **** 1 **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1
5321 IceTrollBerserker 16826798 16826799 ife_X2ArSkin **** **** **** **** **** 13 **** **** 293 **** 0 0 1 **** **** **** **** 1 **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1
5322 WolfBerserker 16826800 16826801 ife_animal **** **** **** **** **** **** **** **** 293 **** 0 0 1 **** **** **** **** 1 **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1
5323 Verminlord 16836682 16836683 ife_X1PoisSav **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 3795 **** 1 -1 **** **** **** **** **** **** **** 16 24 **** **** FEAT_MASTER_OF_THE_ELEMENTS 5 **** **** **** **** **** 1 0
5323 Verminlord 16836682 16836683 ife_X1PoisSav **** **** **** **** **** **** **** **** 4460 **** 0 0 0 **** **** 3795 **** 1 -1 **** **** **** **** **** **** **** 16 24 **** **** FEAT_VERMINLORD 5 **** **** **** **** **** 1 0
5324 DespanaSchool 16836696 16836697 ife_X2CritDHalb 5 **** **** **** **** **** **** **** 28 94 0 0 1 22 **** 3798 **** 0.5 -1 **** **** **** **** **** **** **** **** **** **** **** FEAT_DESPANA_SCHOOL 6 1 **** **** **** **** 0 1
5325 Crinti_ShadowRide 16823084 16823085 spi_dimdoor **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 3799 **** **** 5 **** **** **** **** **** **** **** **** **** **** **** FEAT_BLADE_MEDITATION **** **** **** **** **** **** **** 1
5326 Crinti_ShadowWalk 16823086 16823087 is_teleport **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 3800 **** **** 1 **** 1 **** **** **** **** **** **** **** **** **** FEAT_BLADE_MEDITATION **** **** **** **** **** **** **** 1

View File

@@ -2536,7 +2536,7 @@
2532 CLUTCH_OF_ORCUS 16829500 is_clutch_orcus N M vs 0x38 0x0a sp_clutch_orcus **** 3 **** **** **** **** 3 1500 hand **** VCO_MEHANEVIL02 **** SCO_LGRINEVIL01 VS_CHANT_NECR_HM vs_chant_necr_hf out 1000 **** VCA_OUTEVIL01 **** SCA_OUTNEG 0 **** **** **** **** **** **** 1 **** **** **** **** **** 2 **** 1 16829501 1 0 **** 1 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
2533 CRUSHING_FIST_OF_SPITE 16829502 is_crush_fs V M vs 0x3a 0x0c sp_crush_fs **** **** **** **** **** 9 9 1500 head VCO_MEHEDEVIL01 **** **** SCO_MEGRDEVIL01 VS_CHANT_EVOC_HM VS_CHANT_EVOC_HF up 1000 **** **** **** SDR_GHOSTLY 0 **** **** **** **** **** **** 1 **** **** **** **** **** 1 **** 1 16829503 1 0 **** 1 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
2534 CURSE_OF_THE_PUTRID_HUSK 16829504 is_curse_phusk I S vs 0x3a 0x0a sp_curse_phusk 3 **** **** **** **** 3 3 1500 hand **** VCO_MEHANODD03 **** SCO_LGSPRODD01 VS_CHANT_ILLU_HM VS_CHANT_ILLU_HF out 1000 **** VCA_OUTMIND01 **** SCA_OUTMIND01 0 **** **** **** **** **** Mind_Affecting 1 **** **** **** **** **** 2 **** 1 16829505 1 0 **** 1 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
2535 DAMNING_DARKNESS 16829506 is_damng_dark V T v 0x1a 0x2f sp_damng_dark **** 4 **** **** **** 4 4 1500 hand **** VCO_MEHANEVIL02 **** SCO_MEHANEVIL01 VS_CHANT_EVOC_HM VS_CHANT_EVOC_HF touch 1000 **** **** **** SDR_BLACKOUT 0 **** **** **** **** **** **** 1 **** **** **** **** **** 1 **** 1 16829507 1 0 **** 1 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
2535 DAMNING_DARKNESS 16829506 is_damng_dark V T v 0x3f 0x2f sp_damng_dark **** 4 **** **** **** 4 4 1500 hand **** VCO_MEHANEVIL02 **** SCO_MEHANEVIL01 VS_CHANT_EVOC_HM VS_CHANT_EVOC_HF touch 1000 **** **** **** SDR_BLACKOUT 0 **** **** **** **** **** **** 1 **** **** **** **** **** 1 **** 1 16829507 1 0 **** 1 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
2536 DEATH_BY_THORNS 16829508 is_dth_thorns C T vs 0x38 0x06 sp_dth_thorns **** 7 7 **** **** 7 7 1500 head VCO_MEHEDEVIL01 **** **** SCO_MEGRDEVIL01 VS_CHANT_CONJ_HM VS_CHANT_CONJ_HF Area 1000 VCO_MEHEDEVIL01 **** **** **** 0 **** **** **** **** **** **** 1 **** **** **** **** **** 1 **** 1 16829509 1 0 **** 1 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 7 **** 7 ****
2537 DEMONCALL 16829510 is_demoncall D P vs 0x38 0x09 sp_demoncall **** **** **** **** **** **** 2 1500 head VCO_MEHEDEVIL01 **** VCO_GRNDRED SCO_LGRINEVIL01 VS_CHANT_ENCH_LM VS_CHANT_ENCH_LF up 1000 **** **** **** sdr_demonhand 0 **** **** **** **** **** **** 1 **** **** **** **** **** 10 **** 1 16829511 1 0 **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** 2 **** **** **** **** **** **** ****
2538 DEMONFLESH 16829512 is_demonflesh T P vs 0x3a 0x09 sp_demonflesh **** **** **** **** **** **** 1 1500 head VCO_MEHEDEVIL01 **** **** SCO_LGSPREVIL01 VS_CHANT_CONJ_LM VS_CHANT_CONJ_LF self 1000 **** **** VCA_UPHEXEVIL01 SDR_PARALYZED 0 **** **** **** **** **** **** 1 **** **** **** **** **** 10 **** 1 16829513 1 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 1 **** **** **** **** **** **** ****

View File

@@ -204,7 +204,7 @@
200 VFX_PER_FOGFREEZE C 5 **** **** **** **** **** 0 **** vps_fogfreeze vps_fogfreeze vps_fogfreeze 5 10 5 3400 1100 1900 0 0.25 0.25 **** sps_fog_loop **** sps_fog 0.3 vps_fogfreeze_L vps_fogfreeze_L vps_fogfreeze_L
201 VFX_PER_FOGYELLOW C 5 **** **** **** **** **** 0 **** vps_fogyell vps_fogyell vps_fogyell 5 10 5 3400 1100 1900 0 0.25 0.25 **** sps_fog_loop **** sps_fog 0.3 vps_fogyell_L vps_fogyell_L vps_fogyell_L
202 VFX_PER_FOGPURPLE C 5 **** **** **** **** **** 0 **** vps_fogpurp vps_fogpurp vps_fogpurp 5 10 5 3400 1100 1900 0 0.25 0.25 **** sps_fog_loop **** sps_fog 0.3 vps_fogpurp_L vps_fogpurp_L vps_fogpurp_L
203 AOE_PER_DAMNDARK C 6.7 **** **** sp_damng_darka sp_damng_darkb **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
203 AOE_PER_DAMNDARK C 6.7 **** **** sp_damng_darka sp_damng_darkb **** **** 1 **** **** **** **** **** **** **** **** **** **** **** **** sps_darkness **** **** **** **** **** **** ****
204 VFX_MOB_BRILLIANT_EMANATION C 30.48 **** **** sp_brill_emanA sp_brill_emanB **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
205 VFX_PER_UTTERDARK C 50 **** **** sp_utterdarkA sp_utterdarkB **** 0 844 **** **** **** **** **** **** **** **** **** **** **** **** sps_darkness **** **** **** **** **** **** ****
206 VFX_PER_ACHAIERAI C 3.048 **** **** sp_cloud_achai sp_cloud_achaiB **** 0 845 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****

View File

@@ -795,10 +795,14 @@ void ApplyBreath(struct breath BreathUsed, location lTargetArea, int bLinger = F
{
//Mettle is Evasion for Fort saves
if (GetHasMettle(oTarget, SAVING_THROW_FORT))
{
nAdjustedDamage = 0;
}
else
{
nAdjustedDamage /= 2;
}
}
}
else
nAdjustedDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, nSaveDC, nSaveDamageType);

View File

@@ -3760,8 +3760,19 @@ int GetAttackBonus(object oDefender, object oAttacker, object oWeap, int iOffhan
iAbilityBonus = iWis;
//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; */
// Expertise penalties apply to all attack rolls
if (iCombatMode == COMBAT_MODE_EXPERTISE) iCombatModeBonus -= 5;

View File

@@ -459,6 +459,31 @@ int CheckPRCLimitations(object oItem, object oPC = OBJECT_INVALID)
}
}
else if(ipType == ITEM_PROPERTY_AREA_OF_EFFECT)
{
// This should happen on equip, unequip, or dynamic IP addition
if(bEquip || bUnequip || !bEquip && !bUnequip)
{
// Remove existing AoE
effect eTest = GetFirstEffect(oPC);
while(GetIsEffectValid(eTest))
{
if(GetEffectCreator(eTest) == oItem
&& GetEffectType(eTest) == EFFECT_TYPE_AREA_OF_EFFECT)
{
RemoveEffect(oPC, eTest);
if(DEBUG) DoDebug("CheckPRCLimitations: Removing old AoE effect");
}
eTest = GetNextEffect(oPC);
}
// Create new AoE - Skip when unequipping
if(!bUnequip)
{
AssignCommand(oItem, _prc_inc_itmrstr_ApplyAoE(oPC, oItem, GetItemPropertySubType(ipTest), GetItemPropertyCostTable(ipTest)));
}
}
}
/* else if(ipType == ITEM_PROPERTY_AREA_OF_EFFECT)
{
// This should only happen on equip or unequip
@@ -483,7 +508,7 @@ int CheckPRCLimitations(object oItem, object oPC = OBJECT_INVALID)
AssignCommand(oItem, _prc_inc_itmrstr_ApplyAoE(oPC, oItem, GetItemPropertySubType(ipTest), GetItemPropertyCostTable(ipTest)));
}// end if - Equip event
}// end if - Equip or Unequip event
}// end if - AoE iprp
}// end if - AoE iprp */
else if(ipType == ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N)
{
// Only equippable items can provide bonus spell slots

View File

@@ -76,7 +76,7 @@
/* This variable MUST be updated with every new version of the PRC!!! */
const string PRC_VERSION = "PRC8 4.91";
const string PRC_VERSION = "PRC8 4.92";
/* This variable MUST be updated every time 'assemble_spellbooks.bat' is run!!! */

View File

@@ -1143,6 +1143,15 @@ void DoWeaponEquip(object oPC, object oItem, int nHand)
if (!bIsRestricted)
{
if (GetHasFeat(FEAT_OTWF, oPC))
{
// When wielding a one-handed weapon in your off hand, you take penalties for fighting with two weapons as if you were wielding a light weapon in your off hand
if (nWeaponSize == nRealSize && nHand == ATTACK_BONUS_OFFHAND)
{
SetCompositeAttackBonus(oPC, "OTWFL", 2, ATTACK_BONUS_OFFHAND);
SetCompositeAttackBonus(oPC, "OTWFR", 2, ATTACK_BONUS_ONHAND);
}
}
/* if (GetHasFeat(FEAT_OTWF, oPC))
{
// When wielding a one-handed weapon in your off hand, you take penalties for fighting with two weapons as if you were wielding a light weapon in your off hand
if (nWeaponSize == nRealSize && nHand == ATTACK_BONUS_OFFHAND)
@@ -1156,7 +1165,7 @@ void DoWeaponEquip(object oPC, object oItem, int nHand)
SetCompositeAttackBonus(oPC, "OTWFR", 0, ATTACK_BONUS_ONHAND);
}
}
} */
}
//check for proficiency

View File

@@ -1727,6 +1727,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);
if (!bEpicRunes) { if(nCaster > 20) nCaster = 20; }
@@ -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;
}

View File

@@ -948,6 +948,71 @@ int SpellAlignmentRestrictions(object oCaster, int nSpellID, int nCastingClass)
}
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)

View File

@@ -10,6 +10,7 @@
//:://////////////////////////////////////////////
#include "prc_feat_const"
#include "inc_item_props"
#include "prc_x2_itemprop"
// * Applies the Acolyte's AC bonuses as CompositeBonuses on object's skin.
// * iLevel = integer AC Bonus
@@ -24,12 +25,9 @@ void AcolyteFiendSkin(object oPC, object oSkin, int iLevel)
// * iLevel = IP_CONST_DAMAGEREDUCTION_*
void AcolyteSymbiosis(object oPC, object oSkin, int iLevel)
{
if(GetLocalInt(oSkin, "AcolyteSymbBonus") == iLevel) return;
itemproperty ipIP = ItemPropertyDamageReduction(iLevel, IP_CONST_DAMAGESOAK_20_HP);
IPSafeAddItemProperty(oSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
//RemoveSpecificProperty(oSkin, ITEM_PROPERTY_DAMAGE_REDUCTION, GetLocalInt(oSkin, "AcolyteSymbBonus"), IP_CONST_DAMAGESOAK_20_HP, 1, "AcolyteSymbBonus");
RemoveSpecificProperty(oSkin, ITEM_PROPERTY_DAMAGE_REDUCTION, IP_CONST_DAMAGESOAK_20_HP, GetLocalInt(oSkin, "AcolyteSymbBonus"), 1, "AcolyteSymbBonus");
//AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageReduction(iLevel, IP_CONST_DAMAGESOAK_20_HP), oSkin);
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageReduction(IP_CONST_DAMAGESOAK_20_HP, iLevel), oSkin);
SetLocalInt(oSkin, "AcolyteSymbBonus", iLevel);
}

View File

@@ -21,6 +21,8 @@
#include "shd_inc_myst"
#include "prc_inc_template"
void ResetLionSwiftness(object oPC)
{
int nLevel = GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oPC);
@@ -385,6 +387,30 @@ void RestStarted(object oPC)
SetLocalInt(oPC, "DRUNKEN_MASTER_IS_IN_DRUNKEN_RAGE", 0);
SetLocalInt(oPC, "DRUNKEN_MASTER_IS_DRUNK_LIKE_A_DEMON", 0);
}
// Clean up temporary Darkness item properties from inventory
object oItem = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oItem))
{
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_AREA_OF_EFFECT, DURATION_TYPE_TEMPORARY, IP_CONST_AOE_DARKNESS);
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_AREA_OF_EFFECT, DURATION_TYPE_TEMPORARY, IP_CONST_AOE_DAMNING_DARKNESS);
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_AREA_OF_EFFECT, DURATION_TYPE_TEMPORARY, IP_CONST_AOE_DEEPER_DARKNESS);
oItem = GetNextItemInInventory(oPC);
}
// Also check equipped items
int i;
for(i = 0; i < NUM_INVENTORY_SLOTS; i++)
{
oItem = GetItemInSlot(i, oPC);
if(GetIsObjectValid(oItem))
{
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_AREA_OF_EFFECT, DURATION_TYPE_TEMPORARY, IP_CONST_AOE_DARKNESS);
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_AREA_OF_EFFECT, DURATION_TYPE_TEMPORARY, IP_CONST_AOE_DAMNING_DARKNESS);
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_AREA_OF_EFFECT, DURATION_TYPE_TEMPORARY, IP_CONST_AOE_DEEPER_DARKNESS);
}
}
/* Left here in case the multisummon trick is ever broken. In that case, use this to make Astral Constructs get unsummoned properly
if(GetHasFeat(whatever feat determines if the PC can manifest Astral Construct here)){
int i = 1;

View File

@@ -1,3 +1,6 @@
//
// prc_sneak_att.nss
//
// Written by WodahsEht.
// Calculates the total sneak attack damage die given by all classes,
// and applies the resulting bonuses to the skin. KNOWN ISSUE:
@@ -114,6 +117,13 @@ void main()
int iRogueSneakDice = GetRogueSneak(oPC);
int iBlackguardSneakDice = GetBlackguardSneak(oPC);
// Daring Outlaw: Add half of Swashbuckler levels to Rogue sneak attack
if (GetHasFeat(FEAT_DARING_OUTLAW, oPC))
{
int nSwashbucklerLevel = GetLevelByClass(CLASS_TYPE_SWASHBUCKLER, oPC);
iRogueSneakDice += (nSwashbucklerLevel / 2);
}
// Special case in case someone multiclasses Telflammar Shadowlord and Assassin -- These are the only
// two classes that use Assassin Death Attack, and normally they would not stack.
if((GetLevelByClass(CLASS_TYPE_SHADOWLORD) >= 6) && (GetLevelByClass(CLASS_TYPE_ASSASSIN)))

View File

@@ -225,6 +225,10 @@ void DoWeaponUnequip(object oPC, object oItem)
}
}
// Clear OTWF bonuses
SetCompositeAttackBonus(oPC, "OTWFL", 0, ATTACK_BONUS_OFFHAND);
SetCompositeAttackBonus(oPC, "OTWFR", 0, ATTACK_BONUS_ONHAND);
// if(DEBUG) DoDebug("prc_restwpnsize - OnUnEquip"); // <-script no longer exists
// remove any TWF penalties

View File

@@ -9,6 +9,10 @@
Modified: June 12, 2006
Flaming_Sword: Added touch attack roll
Fixed by: Jaysyn
Date: 2026-05-26 19:53:19
*/
#include "prc_sp_func"
@@ -56,15 +60,16 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel)
else
{
object oItemTarget = oTarget;
if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{ //touch attack roll if target creature is not an ally
// ally = friendly or party member
if(!spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster))
iAttackRoll = PRCDoMeleeTouchAttack(oTarget);
if(iAttackRoll > 0)
{
oItemTarget = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget);
if(DEBUG) DoDebug("Darkness: Chest item = " + DebugObject2Str(oItemTarget));
if(!GetIsObjectValid(oItemTarget))
{
//no armor, check other slots
@@ -73,32 +78,52 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel)
{
oItemTarget = GetItemInSlot(i, oTarget);
if(GetIsObjectValid(oItemTarget))
{
if(DEBUG) DoDebug("Darkness: Found item in slot " + IntToString(i));
break;//end for loop
}
}
}
// Apply item property if valid item found
if(GetIsObjectValid(oItemTarget))
{
if(DEBUG) DoDebug("Darkness: Applying IP to " + DebugObject2Str(oItemTarget));
itemproperty ipDarkness = ItemPropertyAreaOfEffect(IP_CONST_AOE_DARKNESS, nCasterLevel);
IPSafeAddItemProperty(oItemTarget, ipDarkness, fDuration);
if(DEBUG) DoDebug("Darkness: IP applied");
DelayCommand(0.1, VoidCheckPRCLimitations(oItemTarget, OBJECT_INVALID));
}
// Otherwise fall through to location-based AOE
}
else
{
// Touch attack failed - do nothing
return 0;
}
}
else if(GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE)
{
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAOE, oTarget, fDuration, TRUE, -1, nCasterLevel);
object oAoE = GetAreaOfEffectObject(GetSpellTargetLocation(), "VFX_PER_DARKNESS");
SetAllAoEInts(SPELL_DARKNESS, oAoE, PRCGetSpellSaveDC(SPELL_DARKNESS, SPELL_SCHOOL_EVOCATION), 0, nCasterLevel);
}
// If nothing is valid
else if (!GetIsObjectValid(oItemTarget) && !GetIsObjectValid(oItemTarget))
{
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, PRCGetSpellTargetLocation(), fDuration);
object oAoE = GetAreaOfEffectObject(GetSpellTargetLocation(), "VFX_PER_DARKNESS");
SetAllAoEInts(SPELL_DARKNESS, oAoE, PRCGetSpellSaveDC(SPELL_DARKNESS, SPELL_SCHOOL_EVOCATION), 0, nCasterLevel);
}
// Ground casting or creatures with no equipment - location-based AOE
else if(GetObjectType(oTarget) != OBJECT_TYPE_CREATURE || !GetIsObjectValid(oItemTarget))
{
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, PRCGetSpellTargetLocation(), fDuration);
object oAoE = GetAreaOfEffectObject(GetSpellTargetLocation(), "VFX_PER_DARKNESS");
SetAllAoEInts(SPELL_DARKNESS, oAoE, PRCGetSpellSaveDC(SPELL_DARKNESS, SPELL_SCHOOL_EVOCATION), 0, nCasterLevel);
}
// Valid item found on creature - apply item property
else
{
//otherwise items get an IP
if(DEBUG) DoDebug("Darkness: Applying IP to " + DebugObject2Str(oItemTarget));
itemproperty ipDarkness = ItemPropertyAreaOfEffect(IP_CONST_AOE_DARKNESS, nCasterLevel);
IPSafeAddItemProperty(oItemTarget, ipDarkness, fDuration);
//this applies the effects relating to it
if(DEBUG) DoDebug("Darkness: IP applied");
DelayCommand(0.1, VoidCheckPRCLimitations(oItemTarget, OBJECT_INVALID));
}
}

View File

@@ -31,6 +31,10 @@ tiny needle hidden inside it.
Author: Tenjac
Created:
Fixed by: Jaysyn
Date: 2026-05-26 19:53:19
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
@@ -63,8 +67,15 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel)
if(nMetaMagic & METAMAGIC_EXTEND)
fDuration *= 2;
int nShadow = PRCMax(GetLocalInt(oCaster, "ShadowMantle_Shoulder"), GetLocalInt(oTarget, "ShadowMantle_Shoulder"));
if (nShadow) nPnP = FALSE;
if (DEBUG) DoDebug("sp_damng_dark: oCaster "+GetName(oCaster)+" oTarget "+GetName(oTarget)+" nSwitch "+IntToString(nPnP));
if(!nPnP)
{
if (nShadow)
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAOE, oCaster, fDuration);
else
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, PRCGetSpellTargetLocation(), fDuration);
object oAoE = GetAreaOfEffectObject(PRCGetSpellTargetLocation(), "AOE_PER_DAMNDARK");
@@ -73,15 +84,16 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel)
else
{
object oItemTarget = oTarget;
if(GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{ //touch attack roll if target creature is not an ally
// ally = friendly or party member
if(!spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster))
iAttackRoll = PRCDoMeleeTouchAttack(oTarget);
if(iAttackRoll > 0)
{
oItemTarget = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget);
if(DEBUG) DoDebug("Damning Darkness: Chest item = " + DebugObject2Str(oItemTarget));
if(!GetIsObjectValid(oItemTarget))
{
//no armor, check other slots
@@ -90,33 +102,52 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel)
{
oItemTarget = GetItemInSlot(i, oTarget);
if(GetIsObjectValid(oItemTarget))
{
if(DEBUG) DoDebug("Damning Darkness: Found item in slot " + IntToString(i));
break;//end for loop
}
}
}
}
if(GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE || !GetIsObjectValid(oItemTarget))
// Apply item property if valid item found
if(GetIsObjectValid(oItemTarget))
{
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAOE, oTarget, fDuration, TRUE, -1, nCasterLevel);
object oAoE = GetAreaOfEffectObject(GetLocation(oTarget), "AOE_PER_DAMNDARK");
SetAllAoEInts(SPELL_DAMNING_DARKNESS, oAoE, PRCGetSpellSaveDC(SPELL_DAMNING_DARKNESS, SPELL_SCHOOL_EVOCATION), 0, nCasterLevel);
if(DEBUG) DoDebug("Damning Darkness: Applying IP to " + DebugObject2Str(oItemTarget));
itemproperty ipDarkness = ItemPropertyAreaOfEffect(IP_CONST_AOE_DAMNING_DARKNESS, nCasterLevel);
IPSafeAddItemProperty(oItemTarget, ipDarkness, fDuration);
if(DEBUG) DoDebug("Damning Darkness: IP applied");
DelayCommand(0.1, VoidCheckPRCLimitations(oItemTarget, OBJECT_INVALID));
}
// If nothing is valid
else if (!GetIsObjectValid(oItemTarget) && !GetIsObjectValid(oItemTarget))
{
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, PRCGetSpellTargetLocation(), fDuration);
object oAoE = GetAreaOfEffectObject(GetSpellTargetLocation(), "AOE_PER_DAMNDARK");
SetAllAoEInts(SPELL_DAMNING_DARKNESS, oAoE, PRCGetSpellSaveDC(SPELL_DAMNING_DARKNESS, SPELL_SCHOOL_EVOCATION), 0, nCasterLevel);
// Otherwise fall through to location-based AOE
}
else
{
//otherwise items get an IP
// Touch attack failed - do nothing
return 0;
}
}
else if(GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE)
{
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, PRCGetSpellTargetLocation(), fDuration);
object oAoE = GetAreaOfEffectObject(PRCGetSpellTargetLocation(), "AOE_PER_DAMNDARK");
SetAllAoEInts(SPELL_DAMNING_DARKNESS, oAoE, PRCGetSpellSaveDC(SPELL_DAMNING_DARKNESS, SPELL_SCHOOL_EVOCATION), 0, nCasterLevel);
}
// Ground casting or creatures with no equipment - location-based AOE
else if(GetObjectType(oTarget) != OBJECT_TYPE_CREATURE || !GetIsObjectValid(oItemTarget))
{
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, PRCGetSpellTargetLocation(), fDuration);
object oAoE = GetAreaOfEffectObject(PRCGetSpellTargetLocation(), "AOE_PER_DAMNDARK");
SetAllAoEInts(SPELL_DAMNING_DARKNESS, oAoE, PRCGetSpellSaveDC(SPELL_DAMNING_DARKNESS, SPELL_SCHOOL_EVOCATION), 0, nCasterLevel);
}
// Valid item found on creature - apply item property
else
{
if(DEBUG) DoDebug("Damning Darkness: Applying IP to " + DebugObject2Str(oItemTarget));
itemproperty ipDarkness = ItemPropertyAreaOfEffect(IP_CONST_AOE_DAMNING_DARKNESS, nCasterLevel);
IPSafeAddItemProperty(oItemTarget, ipDarkness, fDuration);
//this applies the effects relating to it
if(DEBUG) DoDebug("Damning Darkness: IP applied");
DelayCommand(0.1, VoidCheckPRCLimitations(oItemTarget, OBJECT_INVALID));
}
}

View File

@@ -1,6 +1,6 @@
//::///////////////////////////////////////////////
//:: Name Damning Darkness
//:: FileName sp_damng_dark.nss
//:: FileName sp_damng_darka.nss
//:://////////////////////////////////////////////
/**@file Damning Darkness
Evocation [Darkness, Evil]
@@ -31,55 +31,116 @@ tiny needle hidden inside it.
Author: Tenjac
Created: 6/12/06
Fixed by: Jaysyn
Date: 2026-05-26 19:53:19
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
void DarkLoop(object oTarget, object oPC);
#include "prc_alterations"
#include "prc_inc_spells"
void DarkLoop(object oTarget, object oPC, int nMetaMagic);
void main()
{
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
object oTarget = GetEnteringObject();
object oPC = GetAreaOfEffectCreator();
int nMetaMagic = PRCGetMetaMagicFeat();
int nCasterLvl = PRCGetCasterLevel(oPC);
effect eInvis = EffectInvisibility(INVISIBILITY_TYPE_DARKNESS);
effect eDark = EffectDarkness();
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
effect eLink = EffectLinkEffects(eDark, eDur);
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, (600.0f * nCasterLvl));
DarkLoop(oTarget, oPC);
effect eLink = EffectLinkEffects(eDark, eDur);
eLink = TagEffect(eLink, "BIO_DARKNESS");
effect eLink2 = EffectLinkEffects(eInvis, eDur);
eLink2 = TagEffect(eLink2, "PNP_DARKNESS");
effect ePnP = EffectLinkEffects(eDur, EffectDarkness());
if(GetPRCSwitch(PRC_PNP_DARKNESS_35ED))
{
ePnP = EffectLinkEffects(eDur, EffectConcealment(20));
ePnP = TagEffect(ePnP, "PNP35_DARKNESS");
}
object oTarget = GetEnteringObject();
object oPC = GetAreaOfEffectCreator();
int iShadow = GetLevelByClass(CLASS_TYPE_SHADOWLORD,oTarget);
if (iShadow)
SPApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectUltravision(), oTarget,0.0f,FALSE);
if (iShadow>1)
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectConcealment(20), oTarget,0.0f,FALSE);
int nDuration = PRCGetCasterLevel(oPC);
if ((nMetaMagic & METAMAGIC_EXTEND))
{
nDuration = nDuration *2;
}
if(GetIsObjectValid(oTarget) && oTarget != oPC)
{
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oPC))
{
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_DAMNING_DARKNESS));
}
else
{
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_DAMNING_DARKNESS, FALSE));
}
if (iShadow)
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink2, oTarget,0.0f,FALSE);
else
{
if(GetPRCSwitch(PRC_PNP_DARKNESS))
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, ePnP, oTarget,0.0f,FALSE);
else
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget,0.0f,FALSE);
}
}
else if (oTarget == oPC)
{
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_DAMNING_DARKNESS, FALSE));
if(GetPRCSwitch(PRC_PNP_DARKNESS))
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, ePnP, oTarget,0.0f,FALSE);
else
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink2, oTarget,0.0f,FALSE);
}
// Set local variable to mark target as in AOE for damage tracking
SetLocalInt(oTarget, "PRC_DamningDarkness_InAOE", TRUE);
// Start damage loop
DarkLoop(oTarget, oPC, nMetaMagic);
PRCSetSchool();
}
void DarkLoop(object oTarget, object oPC)
void DarkLoop(object oTarget, object oPC, int nMetaMagic)
{
if(GetIsObjectValid(oTarget))
// Check if target is still marked as being in the AOE
if(GetIsObjectValid(oTarget) && GetLocalInt(oTarget, "PRC_DamningDarkness_InAOE"))
{
if(GetAlignmentGoodEvil(oTarget) == ALIGNMENT_GOOD)
{
int nDam = SpellDamagePerDice(oPC, 2) + d6(2);
int nDam = PRCMaximizeOrEmpower(6, 2, nMetaMagic) + SpellDamagePerDice(oPC, 2);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_DIVINE), oTarget);
}
else if(GetAlignmentGoodEvil(oTarget) == ALIGNMENT_NEUTRAL)
{
int nDam = SpellDamagePerDice(oPC, 2) + d6(2);
int nDam = PRCMaximizeOrEmpower(6, 1, nMetaMagic) + SpellDamagePerDice(oPC, 1);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDam, DAMAGE_TYPE_DIVINE), oTarget);
}
else
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE), oTarget, 1.0f);
// Evil creatures take no damage
}
}
DelayCommand(6.0f, DarkLoop(oTarget, oPC));
DelayCommand(6.0f, DarkLoop(oTarget, oPC, nMetaMagic));
}

View File

@@ -31,10 +31,13 @@ tiny needle hidden inside it.
Author: Tenjac
Created:
Fixed by: Jaysyn
Date: 2026-05-26 19:53:19
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "prc_inc_spells"
@@ -42,21 +45,24 @@ void main()
{
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
//Declare major variables
//Get the object that is exiting the AOE
object oTarget = GetExitingObject();
object oPC = GetAreaOfEffectCreator();
effect eAOE;
// Clear the in-AOE marker to stop damage tracking
DeleteLocalInt(oTarget, "PRC_DamningDarkness_InAOE");
if(GetHasSpellEffect(SPELL_DAMNING_DARKNESS, oTarget))
{
//Search through the valid effects on the target.
eAOE = GetFirstEffect(oTarget);
while (GetIsEffectValid(eAOE))
{
if (GetEffectCreator(eAOE) == GetAreaOfEffectCreator())
if (GetEffectCreator(eAOE) == oPC)
{
if(GetEffectType(eAOE) == EFFECT_TYPE_DARKNESS)
{
//If the effect was created by CotA then remove it
//If the effect was created by Damning Darkness then remove it
if(GetEffectSpellId(eAOE) == SPELL_DAMNING_DARKNESS)
{
RemoveEffect(oTarget, eAOE);

View File

@@ -7347,7 +7347,7 @@ You make yourself - including clothing, armor, weapons and equipment - look diff
<entry id="45448" lang="en" sex="m">Disguise Self, Normal Form</entry>
<entry id="45449" lang="en" sex="m">Attune Gem</entry>
<entry id="45450" lang="en" sex="m">Type of Feat: Item Creation
Prerequisite: Intelligence 13, Arcane Spells level 3.
Prerequisite: Intelligence 13, Craft (General) 1, Arcane Spells level 3.
Specifics: You can cast any arcane spell you have prepared as a gem. The caster must have the spell memorized to be able to create the gem. Crafting a gem costs Spell level * Caster level * 50 in gold pieces for a normal caster (half base cost). It also takes XP equal to 1/25th of the base cost. If you cannot pay the casting cost or the XP loss would drop you a level, the crafting will fail, and the spell will be lost. Crafting the gem requires a gem with a value of 50gp * spell level. A gem is permanent until used. Gems target those who activate them.
Use: Selected.</entry>
<entry id="45451" lang="en" sex="m">Epic Scout</entry>
@@ -27344,7 +27344,7 @@ Save: Will negates
Spell Resistance: Yes
This spell calms agitated creatures. You have no control over the affected creatures, but Calm Emotions can stop raging creatures from fighting or joyous ones from reveling. Creatures so affected cannot take violent actions (although they can defend themselves) or do anything destructive. Any aggressive action against or damage dealt to a calmed creature immediately breaks the spell on all calmed creatures.
This spell automatically suppresses any morale bonuses granted by spells such as Bless, Good Hope and Rage, as well as negating a Bard's ability to inspire courage or a Barbarian's rage ability. It also suppresses any feat effects and removes the Confused condition from all targets.</entry>
This spell automatically suppresses any morale bonuses granted by spells such as Bless, Good Hope and Rage, as well as negating a Bard's ability to inspire courage or a Barbarian's rage ability. It also suppresses any fear effects and removes the Confused condition from all targets.</entry>
<entry id="51124" lang="en" sex="m">Repulsion</entry>
<entry id="51125" lang="en" sex="m">School: Abjuration
Level: Cleric/Healer 7, Sorcerer/Wizard 6