diff --git a/nwn/nwnprc/trunk/2das/spells.2da b/nwn/nwnprc/trunk/2das/spells.2da index fd2abc51..4cebe19e 100644 --- a/nwn/nwnprc/trunk/2das/spells.2da +++ b/nwn/nwnprc/trunk/2das/spells.2da @@ -4056,7 +4056,7 @@ 4052 Epic_Spell_Planar_Cell 16833473 ife_planarcell T S vs 0x00 0x06 ss_ep_planarcell **** **** **** **** **** **** 9 1500 hand **** **** **** **** vs_chant_conj_hm vs_chant_conj_hf out 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** **** **** 2 16833475 0 0 **** 1 5134 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 4053 Epic_Spell_Psionic_Salvo 16833476 ife_psionicsalvo E M vs 0x00 0x02 ss_ep_psionicsal **** **** **** **** **** **** 9 1500 hand **** **** **** **** vs_chant_illu_hm vs_chant_illu_hf out 1000 **** vco_gazeevil **** sco_gazeevil 1 vpr_ectomind01 homing hand spr_ectomind01 path **** 0 **** **** **** **** **** 2 **** 2 16833478 0 0 **** 1 5136 **** **** 1 sphere 22.86 **** 19 **** **** **** **** **** **** **** **** **** **** **** **** **** 4054 Epic_Spell_Rain_of_Fire 16833479 ife_rainoffire V P vs 0x00 0x01 ss_ep_rainoffire **** **** **** **** **** **** 9 1500 hand **** **** **** sco_mebalfire01 vs_chant_conj_lm vs_chant_conj_lf up 1000 **** **** **** **** 0 **** **** **** **** **** Fire 1 **** **** **** **** **** 11 **** 2 16833481 0 0 **** 1 5138 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** -4055 Epic_Spell_Risen_Reunited 16833482 ife_risenreunite C P vs 0x00 0x01 **** **** **** **** **** **** **** 9 1500 hand vco_smhanholy01 **** **** **** vs_chant_necr_hm vs_chant_necr_hf up 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 9 **** 2 16833484 0 0 **** 0 5140 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** +4055 Epic_Spell_Risen_Reunited 16833482 ife_risenreunite C P vs 0x00 0x01 ss_ep_reunited **** **** **** **** **** **** 9 1500 hand vco_smhanholy01 **** **** **** vs_chant_necr_hm vs_chant_necr_hf up 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 9 **** 2 16833484 0 0 **** 0 5140 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 4056 Epic_Spell_Ruin 16833485 ife_ruin T L vs 0x00 0x02 ss_ep_ruin **** **** **** **** **** **** 9 1500 hand **** **** **** **** vs_chant_conj_hm vs_chant_conj_hf area 1000 **** **** **** **** 0 **** **** **** **** **** **** 1 **** **** **** **** **** 2 **** 2 16833487 0 0 **** 1 5142 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 4057 Epic_Spell_Singular_Sunder 16833488 ife_singularsund T S vs 0x00 0x02 ss_ep_singsunder **** **** **** **** **** **** 9 1500 hand **** **** **** **** vs_chant_necr_hm vs_chant_necr_hf out 1000 **** **** **** **** 1 vpr_ringsmal homing hand spr_ringsmal path **** 0 **** **** **** **** **** **** **** 2 16833490 0 0 **** 1 5144 **** **** 1 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 4058 Epic_Spell_Spell_Worm 16833491 ife_spellworm E S vs 0x00 0x02 ss_ep_spellworm **** **** **** **** **** **** 9 1500 head vco_mehedmind01 **** **** **** vs_chant_evoc_lm vs_chant_evoc_lf out 1000 **** **** **** **** 0 **** **** **** **** **** Mind-Affecting 0 **** **** **** **** **** **** **** 2 16833493 0 0 **** 1 5146 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** diff --git a/nwn/nwnprc/trunk/epicspellscripts/ep_cnv_risres.nss b/nwn/nwnprc/trunk/epicspellscripts/ep_cnv_risres.nss new file mode 100644 index 00000000..71177a5a --- /dev/null +++ b/nwn/nwnprc/trunk/epicspellscripts/ep_cnv_risres.nss @@ -0,0 +1,178 @@ +//::////////////////////////////////////////////// +//:: Risen Reunited Conversation +//:: ep_cnv_risres +//::////////////////////////////////////////////// +/** @file + This lets you choose which party member to res + + + @author Stratovarius + @date Created - 11.10.2006 + + @modified Jaysyn + @date 2025-05-09 17:38:32 +*/ +//::////////////////////////////////////////////// +//::////////////////////////////////////////////// + +#include "prc_alterations" +#include "inc_dynconv" + +////////////////////////////////////////////////// +/* Constant defintions */ +////////////////////////////////////////////////// + +const int STAGE_CHOOSE_TARGET = 0; +const int STAGE_CONFIRMATION = 1; + +////////////////////////////////////////////////// +/* Aid functions */ +////////////////////////////////////////////////// + + +void StorePCForRecovery(object oPC, object oChoice, int nChoice) +{ + SetLocalObject(oPC, "RisResTarget" + IntToString(nChoice), oChoice); +} + +object RetrievePC(object oPC, int nChoice) +{ + return GetLocalObject(oPC, "RisResTarget" + IntToString(nChoice)); +} + +////////////////////////////////////////////////// +/* Main function */ +////////////////////////////////////////////////// + +void main() +{ + object oPC = GetPCSpeaker(); + /* Get the value of the local variable set by the conversation script calling + * this script. Values: + * DYNCONV_ABORTED Conversation aborted + * DYNCONV_EXITED Conversation exited via the exit node + * DYNCONV_SETUP_STAGE System's reply turn + * 0 Error - something else called the script + * Other The user made a choice + */ + int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE); + // The stage is used to determine the active conversation node. + // 0 is the entry node. + int nStage = GetStage(oPC); + + // Check which of the conversation scripts called the scripts + if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort + return; + + if(nValue == DYNCONV_SETUP_STAGE) + { + // Check if this stage is marked as already set up + // This stops list duplication when scrolling + if(!GetIsStageSetUp(nStage, oPC)) + { + // variable named nStage determines the current conversation node + // Function SetHeader to set the text displayed to the PC + // Function AddChoice to add a response option for the PC. The responses are show in order added + if(nStage == STAGE_CHOOSE_TARGET) + { + // Set the header + string sAmount = "Which character would you like to resurrect?"; + SetHeader(sAmount); + + // This reads all of the legal choices + object oChoice = GetFirstPC(); + int nChoice = 1; + while (GetIsObjectValid(oChoice)) // People in party + { + // If the selection is a PC + if (GetIsPC(oChoice) && oChoice != oPC && GetIsDead(oChoice)) + { + AddChoice(GetName(oChoice), nChoice, oPC); + StorePCForRecovery(oPC, oChoice, nChoice); + } + nChoice += 1; + oChoice = GetNextPC(); + } + + MarkStageSetUp(STAGE_CHOOSE_TARGET, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it + SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values + } + else if(nStage == STAGE_CONFIRMATION)//confirmation + { + object oChoice = RetrievePC(oPC, GetLocalInt(oPC, "RisResChoice")); + AddChoice(GetStringByStrRef(4752), TRUE); // "Yes" + AddChoice(GetStringByStrRef(4753), FALSE); // "No" + + string sText = "You have selected " + GetName(oChoice) + " as the character to resurrect.\n"; + sText += "Is this correct?"; + + SetHeader(sText); + MarkStageSetUp(STAGE_CONFIRMATION, oPC); + } + } + + // Do token setup + SetupTokens(); + } + // End of conversation cleanup + else if(nValue == DYNCONV_EXITED) + { + // End of conversation cleanup + DeleteLocalObject(oPC, "RisResTarget" + IntToString(GetLocalInt(oPC, "RisResChoice"))); + DeleteLocalInt(oPC, "RisResChoice"); + } + // Abort conversation cleanup. + // NOTE: This section is only run when the conversation is aborted + // while aborting is allowed. When it isn't, the dynconvo infrastructure + // handles restoring the conversation in a transparent manner + else if(nValue == DYNCONV_ABORTED) + { + // End of conversation cleanup + DeleteLocalObject(oPC, "RisResTarget" + IntToString(GetLocalInt(oPC, "RisResChoice"))); + DeleteLocalInt(oPC, "RisResChoice"); + } + // Handle PC responses + else + { + // variable named nChoice is the value of the player's choice as stored when building the choice list + // variable named nStage determines the current conversation node + int nChoice = GetChoice(oPC); + if(nStage == STAGE_CHOOSE_TARGET) + { + SetLocalInt(oPC, "RisResChoice", nChoice); + nStage = STAGE_CONFIRMATION; + } + else if(nStage == STAGE_CONFIRMATION)//confirmation + { + // Res and Exit + if(nChoice == TRUE) + { + object oChoice = RetrievePC(oPC, GetLocalInt(oPC, "RisResChoice")); + // Res the target + SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), oChoice); + SPApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectHeal(GetMaxHitPoints(oChoice) + 10, oChoice), oChoice); + ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_RAISE_DEAD), GetLocation(oChoice)); + + ExecuteScript("prc_pw_ressurection", oChoice); + if (GetPRCSwitch(PRC_PW_DEATH_TRACKING) && GetIsPC(oChoice)) + SetPersistantLocalInt(oChoice, "persist_dead", FALSE); + AssignCommand(oChoice, ActionJumpToObject(oPC)); + + // And we're all done + AllowExit(DYNCONV_EXIT_FORCE_EXIT); + + } + else + { + nStage = STAGE_CHOOSE_TARGET; + MarkStageNotSetUp(STAGE_CHOOSE_TARGET, oPC); + MarkStageNotSetUp(STAGE_CONFIRMATION, oPC); + } + DeleteLocalObject(oPC, "RisResTarget" + IntToString(GetLocalInt(oPC, "RisResChoice"))); + DeleteLocalInt(oPC, "RisResChoice"); + } + + // Store the stage value. If it has been changed, this clears out the choices + SetStage(nStage, oPC); + } +} diff --git a/nwn/nwnprc/trunk/epicspellscripts/ss_ep_reunited.nss b/nwn/nwnprc/trunk/epicspellscripts/ss_ep_reunited.nss new file mode 100644 index 00000000..4c86c3bc --- /dev/null +++ b/nwn/nwnprc/trunk/epicspellscripts/ss_ep_reunited.nss @@ -0,0 +1,49 @@ +//:://///////////////////////////////////////////// +//:: Name Epic Spell: Risen Reunited +//:: FileName ss_ep_reunited.nss +//:://////////////////////////////////////////////9 +/** @file Epic Spell: Risen Reunited +School: Conjuration (Healing) +Components: V,S +Range: Personal +Target: Any known deceased creature +Duration: Instantaneous +Saving Throw: None (harmless) +Spell Resistance: No (harmless) + +You concentrate on any deceased creature*, regardless of proximity, +and resurrect them. Following the instant they regain life, the spell + teleports the subject to your location. + +*Upon casting this spell, a conversation will appear listing all +available players who are dead. Choose the player from this list to +resurrect and teleport to you. + +Author: Stratovarius +Created: 12/10/06 + +Updated: Jaysyn +Modified: 2025-05-09 17:41:28 +**/ +//::////////////////////////////////////////////// +//::////////////////////////////////////////////// + +#include "prc_inc_spells" +#include "inc_dynconv" + +void main() +{ + PRCSetSchool(SPELL_SCHOOL_CONJURATION); + + // Run the spellhook. + if (!X2PreSpellCastCode()) return; + + //Define vars + object oPC = OBJECT_SELF; + + StartDynamicConversation("ep_cnv_risres", oPC, DYNCONV_EXIT_ALLOWED_SHOW_CHOICE, FALSE, TRUE, oPC); + + PRCSetSchool(); +} + + \ No newline at end of file diff --git a/nwn/nwnprc/trunk/include/prc_inc_assoc.nss b/nwn/nwnprc/trunk/include/prc_inc_assoc.nss index 18e3f572..165242de 100644 --- a/nwn/nwnprc/trunk/include/prc_inc_assoc.nss +++ b/nwn/nwnprc/trunk/include/prc_inc_assoc.nss @@ -22,6 +22,9 @@ void AddAssociate(object oMaster, object oAssociate); //removes associate with unsummon vfx void DestroyAssociate(object oAssociate); +//applies fiendiosh template +void ApplyFiendishTemplate(object oCompanion, object oCompSkin); + //applies exalted companion bonuses void ApplyExaltedCompanion(object oCompanion, object oCompSkin); @@ -101,6 +104,54 @@ void CleanProperties(object oItem) } } +void ApplyFiendishTemplate(object oTarget, object oCompSkin) +{ + int nHD = GetHitDice(oTarget); + effect eDR; + int nResist; + + if (nHD >= 12) + { + eDR = EffectDamageReduction(10, DAMAGE_POWER_PLUS_THREE); + nResist = 20; + } + else if (12 > nHD && nHD >= 8) + { + eDR = EffectDamageReduction(5, DAMAGE_POWER_PLUS_TWO); + nResist = 15; + } + else if (8 > nHD && nHD >= 4) + { + eDR = EffectDamageReduction(5, DAMAGE_POWER_PLUS_ONE); + nResist = 10; + } + else if (4 > nHD) + { + nResist = 5; + } + + effect eFire = EffectDamageResistance(DAMAGE_TYPE_FIRE, nResist); + effect eCold = EffectDamageResistance(DAMAGE_TYPE_COLD, nResist); + effect eVis = EffectUltravision(); + effect eLink = EffectLinkEffects(eDR, eFire); + eLink = EffectLinkEffects(eLink, eCold); + eLink = EffectLinkEffects(eLink, eVis); + eLink = SupernaturalEffect(eLink); + ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget); + + itemproperty ipIP = PRCItemPropertyBonusFeat(FEAT_TEMPLATE_FIENDISH_SMITE_GOOD); + IPSafeAddItemProperty(oCompSkin, ipIP, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE); + + if(GetAlignmentGoodEvil(oTarget) != ALIGNMENT_EVIL) + AdjustAlignment(oTarget, ALIGNMENT_EVIL, 80, FALSE); + + SetSubRace(oTarget, "Undead (Extraplanar)"); + + SetLocalInt(oTarget, "FiendishTemplate", 1); + +} + + void ApplyExaltedCompanion(object oCompanion, object oCompSkin) { int nHD = GetHitDice(oCompanion); diff --git a/nwn/nwnprc/trunk/spells/sp_vile_death.nss b/nwn/nwnprc/trunk/spells/sp_vile_death.nss index fd6fd190..74768ace 100644 --- a/nwn/nwnprc/trunk/spells/sp_vile_death.nss +++ b/nwn/nwnprc/trunk/spells/sp_vile_death.nss @@ -21,6 +21,7 @@ Created: 5/17/09 #include "prc_inc_spells" #include "prc_inc_template" +#include "prc_inc_assoc" void main() { @@ -28,13 +29,23 @@ void main() PRCSetSchool(SPELL_SCHOOL_NECROMANCY); - object oPC = OBJECT_SELF; - object oTarget = PRCGetSpellTargetObject(); + object oPC = OBJECT_SELF; + object oTarget = PRCGetSpellTargetObject(); + object oSkin = GetPCSkin(oTarget); if(MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD) - { - SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_BLASPHEMY), oTarget); - ApplyTemplateToObject(TEMPLATE_FIENDISH, oTarget); - } - PRCSetSchool(); + { + if(GetIsPC(oTarget)) + { + SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_BLASPHEMY), oTarget); + ApplyTemplateToObject(TEMPLATE_FIENDISH, oTarget); + } + else + { + SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_BLASPHEMY), oTarget); + ApplyFiendishTemplate(oTarget, oSkin); + } + } + + PRCSetSchool(); } \ No newline at end of file