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.
365 lines
14 KiB
Plaintext
365 lines
14 KiB
Plaintext
/**
|
|
* @file
|
|
* Spellscript for Bright Evening Star SLAs
|
|
*
|
|
*/
|
|
//::By ebonfowl for the PRC
|
|
//::Dedicated to Edgar, the real Ebonfowl
|
|
|
|
#include "prc_inc_template"
|
|
#include "prc_inc_combat"
|
|
#include "prc_sp_func"
|
|
#include "prc_add_spell_dc"
|
|
#include "prc_inc_spells"
|
|
|
|
void DispelMonitor(object oCaster, object oTarget, int nSpellID, int nBeatsRemaining)
|
|
{
|
|
if((--nBeatsRemaining == 0) ||
|
|
PRCGetDelayedSpellEffectsExpired(nSpellID, oTarget, oCaster)
|
|
)
|
|
{
|
|
if(DEBUG) DoDebug("sp_hypattern: Spell expired, clearing");
|
|
PRCRemoveEffectsFromSpell(oTarget, nSpellID);
|
|
|
|
}
|
|
else
|
|
DelayCommand(6.0f, DispelMonitor(oCaster, oTarget, nSpellID, nBeatsRemaining));
|
|
}
|
|
|
|
void ConcentrationHB(object oCaster, object oTarget, int nSpellID, int nBeatsRemaining)
|
|
{
|
|
if(GetBreakConcentrationCheck(oCaster))
|
|
{
|
|
//FloatingTextStringOnCreature("Crafting: Concentration lost!", oPC);
|
|
//DeleteLocalInt(oPC, PRC_CRAFT_HB);
|
|
//return;
|
|
DispelMonitor(oCaster, oTarget, nSpellID, nBeatsRemaining);
|
|
}
|
|
else
|
|
DelayCommand(6.0f, ConcentrationHB(oCaster, oTarget, nSpellID, nBeatsRemaining));
|
|
}
|
|
|
|
void main()
|
|
{
|
|
object oPC = OBJECT_SELF;
|
|
object oArea = GetArea(oPC);
|
|
int nCasterLevel, nDC, nSpell, nUses;
|
|
int nSLA = GetSpellId();
|
|
effect eNone;
|
|
int nInstant = FALSE;
|
|
|
|
object oWOL = GetItemPossessedBy(oPC, "WOL_BrtEvnStar");
|
|
|
|
// You get nothing if you aren't wielding the item
|
|
if(oWOL != GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC) && oWOL != GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC)) return;
|
|
|
|
switch(nSLA){
|
|
case WOL_BES_FIRE_OF_THE_HEART:
|
|
{
|
|
nCasterLevel = 5;
|
|
nSpell = SPELL_FAERIE_FIRE;
|
|
nUses = 999;
|
|
break;
|
|
}
|
|
case WOL_BES_ENTHRALLING_LIGHT:
|
|
{
|
|
nUses = 3;
|
|
if (nUses > GetLegacyUses(oPC, nSLA))
|
|
{
|
|
object oCaster = OBJECT_SELF;
|
|
nCasterLevel = 5;
|
|
int nSpellID = PRCGetSpellId();
|
|
PRCSetSchool(GetSpellSchool(nSpellID));
|
|
if (!X2PreSpellCastCode()) return;
|
|
object oTarget;// = PRCGetSpellTargetObject();
|
|
location lLocation = PRCGetSpellTargetLocation();
|
|
int nSaveDC = 11;
|
|
if (11 + GetAbilityModifier(ABILITY_CHARISMA, oPC) > nSaveDC)
|
|
nSaveDC = 11 + GetAbilityModifier(ABILITY_CHARISMA, oPC);
|
|
float fDuration = RoundsToSeconds(nCasterLevel); //modify if necessary
|
|
|
|
effect eLink = EffectFascinate();
|
|
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE));
|
|
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE));
|
|
|
|
int nHDBonus = nCasterLevel;
|
|
if (nHDBonus > 10) nHDBonus = 10;
|
|
int nMaxHD = d4(2) + nHDBonus;
|
|
int nSumHD = 0;
|
|
float nRadius = RADIUS_SIZE_HUGE;
|
|
int i, nHD, nKillSwitch;
|
|
|
|
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, nRadius, lLocation, TRUE);
|
|
ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_RAINBOW_PATTERN), lLocation);
|
|
|
|
while(GetIsObjectValid(oTarget) && nKillSwitch == 0)
|
|
{
|
|
if(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
|
{
|
|
nHD = GetHitDice(oTarget);
|
|
nSumHD = nSumHD + nHD;
|
|
if (nSumHD <= nMaxHD)
|
|
{
|
|
PRCSignalSpellEvent(oTarget, FALSE);
|
|
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget);
|
|
DelayCommand(6.0f, ConcentrationHB(oCaster, oTarget, nSpellID, FloatToInt(fDuration)));
|
|
}
|
|
else nKillSwitch = 1;
|
|
}
|
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, nRadius, lLocation, TRUE);
|
|
}
|
|
|
|
PRCSetSchool();
|
|
}
|
|
SetLegacyUses(oPC, nSLA);
|
|
break;
|
|
}
|
|
case WOL_BES_COLOR_SPRAY:
|
|
{
|
|
nCasterLevel = 5;
|
|
nSpell = SPELL_COLOR_SPRAY;
|
|
nUses = 3;
|
|
nDC = 11;
|
|
if (11 + GetAbilityModifier(ABILITY_CHARISMA, oPC) > nDC)
|
|
nDC = 11 + GetAbilityModifier(ABILITY_CHARISMA, oPC);
|
|
break;
|
|
}
|
|
case WOL_BES_BLINDING_FLASH:
|
|
{
|
|
nUses = 3;
|
|
if (nUses > GetLegacyUses(oPC, nSLA))
|
|
{
|
|
if (!X2PreSpellCastCode()) return;
|
|
|
|
PRCSetSchool(SPELL_SCHOOL_NECROMANCY);
|
|
|
|
//Declare major varibles
|
|
object oCaster = OBJECT_SELF;
|
|
object oTarget = PRCGetSpellTargetObject();
|
|
int CasterLvl = 5;
|
|
nDC = 13;
|
|
if (12 + GetAbilityModifier(ABILITY_CHARISMA, oPC) > nDC)
|
|
nDC = 12 + GetAbilityModifier(ABILITY_CHARISMA, oPC);
|
|
|
|
float fDuration = RoundsToSeconds(CasterLvl);
|
|
|
|
effect eVis = EffectVisualEffect(VFX_IMP_BLIND_DEAF_M);
|
|
|
|
effect eBlind = EffectBlindness();
|
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
|
effect eLink = EffectLinkEffects(eBlind, eDur);
|
|
|
|
if(!GetIsReactionTypeFriendly(oTarget))
|
|
{
|
|
//Fire cast spell at event
|
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, SPELL_BES_BLINDING_FLASH));
|
|
//Do SR check
|
|
if (!PRCDoResistSpell(oCaster, oTarget) && PRCGetIsAliveCreature(oTarget))
|
|
{
|
|
// Make Fortitude save to negate
|
|
if (!PRCMySavingThrow(SAVING_THROW_FORT, oTarget, nDC))
|
|
{
|
|
|
|
//Apply visual and effects
|
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, SPELL_BES_BLINDING_FLASH, CasterLvl);
|
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
|
}
|
|
}
|
|
}
|
|
PRCSetSchool();
|
|
}
|
|
SetLegacyUses(oPC, nSLA);
|
|
break;
|
|
}
|
|
case WOL_BES_SHOOTING_STARS:
|
|
{
|
|
nCasterLevel = 10;
|
|
nSpell = SPELL_MAGIC_MISSILE;
|
|
nUses = 2;
|
|
break;
|
|
}
|
|
case WOL_BES_GLITTERING_MOTES:
|
|
{
|
|
nCasterLevel = 5;
|
|
nSpell = SPELL_GLITTERDUST;
|
|
nUses = 1;
|
|
nDC = 13;
|
|
if (12 + GetAbilityModifier(ABILITY_CHARISMA, oPC) > nDC)
|
|
nDC = 12 + GetAbilityModifier(ABILITY_CHARISMA, oPC);
|
|
break;
|
|
}
|
|
case WOL_BES_TWINKLE:
|
|
{
|
|
nCasterLevel = 11;
|
|
nSpell = SPELL_BLINK;
|
|
nUses = 3;
|
|
break;
|
|
}
|
|
case WOL_BES_SILVER_STARLIGHT:
|
|
{
|
|
nUses = 1;
|
|
if (nUses > GetLegacyUses(oPC, nSLA))
|
|
{
|
|
DeleteLocalInt(oPC, "X2_L_LAST_SPELLSCHOOL_VAR");
|
|
SetLocalInt(oPC, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_EVOCATION);
|
|
/*
|
|
Spellcast Hook Code
|
|
Added 2003-06-20 by Georg
|
|
If you want to make changes to all spells,
|
|
check x2_inc_spellhook.nss to find out more
|
|
|
|
*/
|
|
|
|
if (!X2PreSpellCastCode())
|
|
{
|
|
// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
|
|
return;
|
|
}
|
|
|
|
// End of Spell Cast Hook
|
|
|
|
//Declare major variables
|
|
effect eVis = EffectVisualEffect(VFX_IMP_DEATH);
|
|
effect eVis2 = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
|
|
effect eStrike = EffectVisualEffect(VFX_FNF_SUNBEAM);
|
|
effect eDam;
|
|
effect eBlind = EffectBlindness();
|
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
|
effect eLink = EffectLinkEffects(eBlind, eDur);
|
|
int CasterLvl = 15;
|
|
int nDamage;
|
|
int nOrgDam;
|
|
int nMax;
|
|
float fDelay;
|
|
int nBlindLength = 3;
|
|
|
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eStrike, PRCGetSpellTargetLocation());
|
|
//Get the first target in the spell area
|
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, PRCGetSpellTargetLocation());
|
|
while(GetIsObjectValid(oTarget))
|
|
{
|
|
|
|
nCasterLevel= CasterLvl;
|
|
//Limit caster level
|
|
if (nCasterLevel > 20)
|
|
{
|
|
nCasterLevel = 20;
|
|
}
|
|
|
|
// Make a faction check
|
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oPC))
|
|
{
|
|
fDelay = PRCGetRandomDelay(1.0, 2.0);
|
|
//Fire cast spell at event for the specified target
|
|
SignalEvent(oTarget, EventSpellCastAt(oPC, SPELL_BES_SILVER_STARLIGHT));
|
|
//Make an SR check
|
|
if (!PRCDoResistSpell(oPC, oTarget, nCasterLevel, 1.0))
|
|
{
|
|
//Extra effects to undead, oozes and shapechangers
|
|
if (MyPRCGetRacialType(oTarget) == RACIAL_TYPE_OOZE
|
|
|| MyPRCGetRacialType(oTarget) == RACIAL_TYPE_SHAPECHANGER)
|
|
{
|
|
//Roll damage and save
|
|
nDamage = d6(nCasterLevel);
|
|
nMax = 6;
|
|
}
|
|
else
|
|
{
|
|
//Roll damage and save
|
|
nDamage = d6(3);
|
|
nOrgDam = nDamage;
|
|
nMax = 6;
|
|
nCasterLevel = 3;
|
|
//Get the adjusted damage due to Reflex Save, Evasion or Improved Evasion
|
|
}
|
|
|
|
nDamage += SpellDamagePerDice(oPC, nCasterLevel);
|
|
nDC = 20;
|
|
if (17 + GetAbilityModifier(ABILITY_CHARISMA, oPC) > nDC)
|
|
nDC = 17 + GetAbilityModifier(ABILITY_CHARISMA, oPC);
|
|
|
|
//Check that a reflex save was made.
|
|
if(PRCMySavingThrow(SAVING_THROW_REFLEX, oTarget, (nDC), SAVING_THROW_TYPE_DIVINE, oPC, 1.0) == 0)
|
|
{
|
|
DelayCommand(1.0, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nBlindLength),TRUE,-1,CasterLvl));
|
|
}
|
|
else
|
|
{
|
|
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, 0, SAVING_THROW_TYPE_DIVINE);
|
|
}
|
|
//Set damage effect
|
|
eDam = PRCEffectDamage(oTarget, nDamage, DAMAGE_TYPE_DIVINE);
|
|
if(nDamage > 0)
|
|
{
|
|
//Apply the damage effect and VFX impact
|
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget));
|
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
|
PRCBonusDamage(oTarget);
|
|
}
|
|
}
|
|
}
|
|
//Get the next target in the spell area
|
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, PRCGetSpellTargetLocation());
|
|
}
|
|
|
|
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
|
|
// Getting rid of the integer used to hold the spells spell school
|
|
}
|
|
SetLegacyUses(oPC, nSLA);
|
|
break;
|
|
}
|
|
case WOL_BES_STARLIGHT_DISPELLING:
|
|
{
|
|
nCasterLevel = 15;
|
|
if(GetIsObjectValid(oArea)
|
|
&& !GetIsDay()
|
|
&& GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND
|
|
&& !GetIsAreaInterior(oArea))
|
|
{
|
|
nCasterLevel = 20;
|
|
}
|
|
nSpell = SPELL_GREATER_DISPELLING;
|
|
nUses = 1;
|
|
break;
|
|
}
|
|
case WOL_BES_TALES_IN_THE_SKY:
|
|
{
|
|
if(GetIsObjectValid(oArea)
|
|
&& !GetIsDay()
|
|
&& GetIsAreaAboveGround(oArea) == AREA_ABOVEGROUND
|
|
&& !GetIsAreaInterior(oArea))
|
|
{
|
|
nCasterLevel = 15;
|
|
nSpell = SPELL_LEGEND_LORE;
|
|
nUses = 1;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
PrintString("Tales in the Sky is only usable outside at night.");
|
|
break;
|
|
}
|
|
}
|
|
case WOL_BES_CALL_DOWN_A_STAR:
|
|
{
|
|
nCasterLevel = 17;
|
|
nSpell = SPELL_SUMMON_CREATURE_IX_FIRE;
|
|
nUses = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check uses per day
|
|
if (GetLegacyUses(oPC, nSLA) >= nUses)
|
|
{
|
|
FloatingTextStringOnCreature("You have used " + GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSLA))) + " the maximum amount of times today.", oPC, FALSE);
|
|
return;
|
|
}
|
|
if (nSpell > 0)
|
|
{
|
|
DoRacialSLA(nSpell, nCasterLevel, nDC, nInstant);
|
|
SetLegacyUses(oPC, nSLA);
|
|
FloatingTextStringOnCreature("You have "+IntToString(nUses - GetLegacyUses(oPC, nSLA))+ " uses of " + GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSLA))) + " remaining today.", oPC, FALSE);
|
|
}
|
|
}
|
|
|