Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
247 lines
9.0 KiB
Plaintext
247 lines
9.0 KiB
Plaintext
/*:://////////////////////////////////////////////
|
|
//:: Spell Name Bestow Curse
|
|
//:: Spell FileName PHS_S_BestowCurs
|
|
//:://////////////////////////////////////////////
|
|
//:: In Game Spell desctiption
|
|
//:://////////////////////////////////////////////
|
|
Necromancy
|
|
Level: Clr 3, Sor/Wiz 4
|
|
Components: V, S
|
|
Casting Time: 1 standard action
|
|
Range: Touch
|
|
Target: Creature touched
|
|
Duration: Permanent
|
|
Saving Throw: Will negates
|
|
Spell Resistance: Yes
|
|
|
|
You place a curse on the subject, if they were not already cursed. Choose
|
|
one of the following three effects.
|
|
|
|
• -6 decrease to an ability score (minimum 3).
|
|
• -4 penalty on attack rolls, saves, and skill checks.
|
|
• Each turn, the target has a 50% chance to act normally; otherwise, it takes
|
|
no action.
|
|
|
|
The curse bestowed by this spell cannot be dispelled, but it can be removed
|
|
with a break enchantment, limited wish, miracle, remove curse, or wish
|
|
spell.
|
|
|
|
Bestow curse counters remove curse.
|
|
//:://////////////////////////////////////////////
|
|
//:: Spell Effects Applied / Notes
|
|
//:://////////////////////////////////////////////
|
|
As above. The 3rd effect is taken as a delayed effect (and a visual makes
|
|
sure it is kept going) via. DelayCommand and a function here.
|
|
|
|
Set the ability type in the spell menu (defaults to strength)
|
|
|
|
Note:
|
|
- The first one can be setup in the spells menu.
|
|
- The 3 options are 3 subdial choices.
|
|
|
|
//:://////////////////////////////////////////////
|
|
//:: Spell Turning Notes
|
|
//:://////////////////////////////////////////////
|
|
This is like Baleful polymorph. Some parts of the final effects are moved
|
|
into a function and so on.
|
|
//:://////////////////////////////////////////////
|
|
//:: Created By: Jasperre
|
|
//::////////////////////////////////////////////*/
|
|
|
|
#include "PHS_INC_SPELLS"
|
|
|
|
const int PHS_BESTOW_CURSE_ABILITY = 0;
|
|
const int PHS_BESTOW_CURSE_ROLLS = 1;
|
|
const int PHS_BESTOW_CURSE_RANDOM = 2;
|
|
|
|
// This is executed after 6 seconds, or 60 seconds. It will 50% of the time make
|
|
// the creature immobile via. Uncommandable.
|
|
// - When uncommandable, they have a pesudo-heartbeat run on them which will
|
|
// remove the uncommandableness if they get the curse removed
|
|
void DoRandomCurseBehaviour(object oTarget, int nCastTimes);
|
|
// Spellturning implimented effects
|
|
void DoEffects(object oTarget, effect eDur, effect eVis, int nSpellId, int nSpellSaveDC, object oCaster = OBJECT_SELF);
|
|
|
|
void main()
|
|
{
|
|
// Spell hook check.
|
|
if(!PHS_SpellHookCheck()) return;
|
|
|
|
// Declare major variables.
|
|
object oCaster = OBJECT_SELF;
|
|
object oTarget = GetSpellTargetObject();
|
|
int nSpellSaveDC = PHS_GetSpellSaveDC();
|
|
int nSpellId = GetSpellId();
|
|
|
|
// Make sure they are not immune to spells
|
|
if(PHS_TotalSpellImmunity(oTarget)) return;
|
|
|
|
// We link cirtain effects and apply eLink
|
|
effect eVis = EffectVisualEffect(VFX_IMP_REDUCE_ABILITY_SCORE);
|
|
effect eCurse;
|
|
|
|
// -4 penalty on attack rolls, saves, ability checks, and skill checks.
|
|
if(nSpellId == PHS_SPELL_BESTOW_CURSE_ROLLS)
|
|
{
|
|
effect eRollsSkill = EffectSkillDecrease(SKILL_ALL_SKILLS, 4);
|
|
effect eRollsSave = EffectSavingThrowDecrease(SAVING_THROW_ALL, 4);
|
|
effect eRollsAttack = EffectAttackDecrease(4);
|
|
// Link them - No visual
|
|
eCurse = EffectLinkEffects(eRollsSkill, eRollsSave);
|
|
eCurse = EffectLinkEffects(eCurse, eRollsAttack);
|
|
}
|
|
// Each turn, the target has a 50% chance to act normally; otherwise, it
|
|
// takes no action.
|
|
else if(nSpellId == PHS_SPELL_BESTOW_CURSE_CHANCE_NO_ACTION)
|
|
{
|
|
// Only a visual
|
|
eCurse = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE);
|
|
}
|
|
// Default to ability
|
|
else// if(nSpellId == PHS_SPELL_BESTOW_CURSE_ABILITY)
|
|
{
|
|
// Ability decrease in a stored constant, else strength.
|
|
int nAbility = PHS_GetLocalConstant(oCaster, "PHS_BESTOW_CURSE_ABIlITY_TYPE");
|
|
|
|
// Apply effects
|
|
// - The function defaults to strength
|
|
eCurse = PHS_SpecificAbilityCurse(nAbility, 6);
|
|
}
|
|
|
|
// Make it supernatural
|
|
eCurse = SupernaturalEffect(eCurse);
|
|
|
|
// Check PvP
|
|
if(!GetIsReactionTypeFriendly(oTarget))
|
|
{
|
|
// Signal spell cast at event
|
|
PHS_SignalSpellCastAt(oTarget, PHS_SPELL_BESTOW_CURSE);
|
|
|
|
// Check spell resistance
|
|
if(!PHS_SpellResistanceCheck(oCaster, oTarget))
|
|
{
|
|
// Check spell turning
|
|
int nSpellTurning = PHS_SpellTurningCheck(oCaster, oTarget, PHS_ArrayGetSpellLevel(PHS_SPELL_BALEFUL_POLYMORPH, GetLastSpellCastClass()));
|
|
|
|
// 1 = No effect
|
|
if(nSpellTurning == 1)
|
|
{
|
|
// Stop
|
|
return;
|
|
}
|
|
else if(nSpellTurning == 2)
|
|
{
|
|
// Affect the caster only, full power.
|
|
DoEffects(oCaster, eCurse, eVis, nSpellId, nSpellSaveDC);
|
|
}
|
|
else if(nSpellTurning == 3)
|
|
{
|
|
// Affects the caster OR the target, a % type thing. Set on local that can be
|
|
// retrieved. If damaging, part damage each. If not, % chance to affect either.
|
|
// Get the %. This one it is a chance of affecting us...
|
|
int nFraction = FloatToInt(GetLocalFloat(oCaster, PHS_SPELL_TURNING_FRACTION) * 100);
|
|
|
|
// Check
|
|
// - If the d100 is LESS then nFaction, it is GOOD for the target -
|
|
// thus we affect the caster. Else, affect the target normally.
|
|
if(d100() <= nFraction)
|
|
{
|
|
DoEffects(oCaster, eCurse, eVis, nSpellId, nSpellSaveDC);
|
|
}
|
|
else
|
|
{
|
|
DoEffects(oTarget, eCurse, eVis, nSpellId, nSpellSaveDC);
|
|
}
|
|
}
|
|
else //if(nSpellTurning == 4)
|
|
{
|
|
// 4 = Spell affects both people equally at full effect.
|
|
DoEffects(oTarget, eCurse, eVis, nSpellId, nSpellSaveDC);
|
|
DoEffects(oCaster, eCurse, eVis, nSpellId, nSpellSaveDC);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// This is executed after 6 seconds, or 60 seconds. It will 50% of the time make
|
|
// the creature immobile via. Uncommandable.
|
|
// - When uncommandable, they have a pesudo-heartbeat run on them which will
|
|
// remove the uncommandableness if they get the curse removed
|
|
void DoRandomCurseBehaviour(object oTarget, int nCastTimes)
|
|
{
|
|
// Check if they have the spells effects + is valid
|
|
if(GetHasSpellEffect(PHS_SPELL_BESTOW_CURSE_CHANCE_NO_ACTION, oTarget) &&
|
|
!GetIsDead(oTarget) && GetIsObjectValid(oTarget) &&
|
|
GetLocalInt(oTarget, "PHS_BESTOW_CURSE_TIMES_CAST_ON") == nCastTimes)
|
|
{
|
|
// 50% chance of no moving this turn
|
|
if(d100() <= 50)
|
|
{
|
|
// Fail!
|
|
FloatingTextStringOnCreature("The curse causes you to take no action this turn!", oTarget, FALSE);
|
|
|
|
// Apply a tempoary undispellable stais effect
|
|
effect eStop = EffectCutsceneImmobilize();
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eStop, oTarget, 5.9);
|
|
}
|
|
else
|
|
{
|
|
// Pass!
|
|
FloatingTextStringOnCreature("The curse lets you take a normal action this turn.", oTarget, FALSE);
|
|
}
|
|
// Another check 6 seconds from now.
|
|
DelayCommand(6.0, DoRandomCurseBehaviour(oTarget, nCastTimes));
|
|
}
|
|
else
|
|
{
|
|
PHS_SetCommandableOnSafe(oTarget, PHS_SPELL_BESTOW_CURSE);
|
|
}
|
|
}
|
|
|
|
// Spellturning implimented effects
|
|
void DoEffects(object oTarget, effect eDur, effect eVis, int nSpellId, int nSpellSaveDC, object oCaster = OBJECT_SELF)
|
|
{
|
|
int bContinue = TRUE;
|
|
if(oTarget == oCaster)
|
|
{
|
|
bContinue = PHS_SpellResistanceCheck(oCaster, oTarget);
|
|
}
|
|
if(bContinue)
|
|
{
|
|
// Times we have cast this spell stops the pesudo-turn checking running
|
|
// more then at once on a target
|
|
int nTimesCast = PHS_IncreaseStoredInteger(oTarget, "PHS_BESTOW_CURSE_TIMES_CAST_ON");
|
|
|
|
// Duration is permament (supernatural effect too)
|
|
|
|
// Check if they have the effects already.
|
|
if(GetHasSpellEffect(PHS_SPELL_BESTOW_CURSE, oTarget) ||
|
|
GetHasSpellEffect(PHS_SPELL_BESTOW_CURSE_ROLLS, oTarget) ||
|
|
GetHasSpellEffect(PHS_SPELL_BESTOW_CURSE_ABILITY, oTarget) ||
|
|
GetHasSpellEffect(PHS_SPELL_BESTOW_CURSE_CHANCE_NO_ACTION, oTarget) ||
|
|
PHS_GetHasEffect(EFFECT_TYPE_CURSE, oTarget))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Check immunity
|
|
if(!PHS_ImmunityCheck(oTarget, IMMUNITY_TYPE_CURSED))
|
|
{
|
|
// Check will save
|
|
if(!PHS_SavingThrow(SAVING_THROW_WILL, oTarget, nSpellSaveDC))
|
|
{
|
|
// Apply effects
|
|
PHS_ApplyPermanentAndVFX(oTarget, eVis, eDur);
|
|
|
|
// If it was the "Random" one, we start the check after 6
|
|
// seconds.
|
|
if(nSpellId == PHS_SPELL_BESTOW_CURSE_CHANCE_NO_ACTION)
|
|
{
|
|
DelayCommand(6.0, DoRandomCurseBehaviour(oTarget, nTimesCast));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|