diff --git a/PRC8_ChangeLog.txt b/PRC8_ChangeLog.txt index 9cebbdcc..8188fa1f 100644 --- a/PRC8_ChangeLog.txt +++ b/PRC8_ChangeLog.txt @@ -1,3 +1,47 @@ +Commit: Jaysyn904 +Date: Sun May 24 + +Warforged Scouts can take Warforged Juggernaut. +FEAT_EXTRA_GRANTED_MANEUVER is for Crusaders, not Swordsages. +FEAT_EXTRA_GRANTED_MANEUVER now shows all 5 granted maneuvers after 19th lvl. +Mirror Image onCastAt script now uses PRCGetCasterLevel() +Summon Hamatula now uses PRCGetCasterLevel() +Spiritual Weapon now uses PRCGetCasterLevel() +Heal & Harm now SignalEvent on placeables. DEITY$ only knows how many modules this broke. +Hospitaler had incorrect epic bonus feat progression +Hospitaler had incorrect bonus feat list. +Hospitaler was missing Ride from its skill list. +Runecaster had incorrect epic bonus feat progression +Runecaster had incorrect bonus feat list. +Warmage Edge should work with magic staves. +Added PRC_RETH_DEKALA_AURA_HOSTILE_ONLY switch and modified Vilefire aura to use it. +Spells that use DoCone() should now respect Mastery of Shaping. +Removed Hospitaler from list of classes that use the Fighter Bonus Feat list. +ExtraordinarySpellAim() now handles persistent AoEs +Acid Fog, Blade Barrier, Creeping Doom, Grease, Incindiary Cloud, Wall of Fire, Wall of Frost, Prismatic Wall, Prismatic Sphere, Sleet Storm and Spike Growth now respect Extraordinary Spell Aim. +Archivist wasn't specifically set as a divine class in classes.2da. +Added Create Infusion & Craft Scepter to the Archvist's feat 2da. +The Lich class is now getting the correct level based stat updates. +Fixed Create Infusion and Craft Scepter to use character level instead of caster level in feat.2da. +Added default level up package for Scout. +Added default level up package for Swashbuckler. +Fixed the prc cache creature to be cutscene invisible, regardless of which function is creating it. +Added special handling in PRCGetLastSpellCastClass() for Bard/Sublime Chord to fix the DC issue. +Added more CEP2 wings to PRCIsFlying() +Added X2_CI_CRAFTSCEPTER_FEAT_ID to CIGetIsSpellRestrictedFromCraftFeat() +Fixed Small Shield handling in ArcaneSpellFailure() +Fixed Troglodyte's racial Stench ability. +Vow of Poverty dialog no longer shows up when you rest & chose to skil the feat for the previous level. +Swashbuckler Grace now supports 60 levels. +Swashbuckler Dodge now respects Daring Outlaw and supports 60 levels. +Blinding Glory isn't a Glory Domain spell in the PRC8. +Fixed TLK typo in Knight (Cavalier) package description. +Fixed Contingent Resurrection from stealing epic spell slots. +Fixed bonus spell slot itemprops for newspellbook casters. (@lightbeard) +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 diff --git a/nwn/nwnprc/trunk/2das/feat.2da b/nwn/nwnprc/trunk/2das/feat.2da index 6ddb57c6..15f271f3 100644 --- a/nwn/nwnprc/trunk/2das/feat.2da +++ b/nwn/nwnprc/trunk/2das/feat.2da @@ -2473,7 +2473,7 @@ 2469 TribalFrenzy 16825723 16825718 ife_cfrenzy **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 1597 **** 1 -1 **** 1 **** **** **** **** **** **** **** **** **** **** 4 **** **** **** **** **** 0 0 2470 AbilityBoost 16825719 16825720 ife_X2GrCha1 **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1 2471 DevotedBodyguards 16825721 16825722 ife_epAlliedMa **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1 -2472 AttuneGem 16822665 16822666 ife_X2PlnrTurn **** **** **** 13 **** **** **** **** **** **** 0 0 1 **** **** 1781 **** 1 -1 **** 0 **** **** **** **** **** **** **** **** **** **** 4 **** **** **** **** **** 0 0 +2472 AttuneGem 16822665 16822666 ife_X2PlnrTurn **** **** **** 13 **** **** **** **** **** **** 0 0 1 **** **** 1781 **** 1 -1 **** 0 **** **** **** **** **** **** **** **** **** **** 4 **** 5 **** **** **** 0 0 2473 WidenSpell 16822648 16822649 ife_X2PlnrTurn **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 1637 **** 1 35 **** 1 **** **** **** **** **** **** **** **** **** **** 4 **** **** **** **** **** 0 0 2474 EnlargeSpellArea 16822650 16822651 ife_legendaryart **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** FEAT_ALERTNESS 5 **** **** **** **** **** 0 1 2475 StunningStrike 16827037 16827038 ife_X2SpTghBne **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 2470 **** 1 5 **** **** **** **** **** **** **** **** **** **** **** **** 4 **** **** **** **** **** 0 1 diff --git a/nwn/nwnprc/trunk/2das/spells.2da b/nwn/nwnprc/trunk/2das/spells.2da index 619b5730..e797b9fb 100644 --- a/nwn/nwnprc/trunk/2das/spells.2da +++ b/nwn/nwnprc/trunk/2das/spells.2da @@ -1783,7 +1783,7 @@ 1779 ShieldAlly 16827626 ife_mastelem T M 0 **** 0x03 prc_knght_shally **** **** **** **** **** **** 9 0 head **** vco_smhanevil01 **** sco_mehannatr01 vs_chant_ench_lm vs_chant_ench_lf self 0 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 10 **** 3 **** 0 0 **** 0 2843 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 1780 ImprovedShieldAlly 16827628 ife_mastelem T M 0 **** 0x03 prc_knght_ishlly **** **** **** **** **** **** 9 0 head **** vco_smhanevil01 **** sco_mehannatr01 vs_chant_ench_lm vs_chant_ench_lf self 0 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 10 **** 3 **** 0 0 **** 0 2844 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 1781 AttuneGem 16822665 is_divprot G L v **** 0x09 prc_radialbug **** **** **** **** **** **** 1 1500 hand **** vco_mehanodd02 vco_lgrinodd01 sco_lgrinodd01 vs_chant_conj_hm vs_chant_conj_hf out 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 1782 1783 **** **** **** 15 **** 1 16828494 1 0 **** 0 2472 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** -1782 AttuneGemCraft 16822665 is_divprot G L v **** 0x09 prc_ft_attunegem **** **** **** **** **** **** 1 1500 hand **** vco_mehanelec02 vco_lgrinelec01 sco_lgrinelec01 vs_chant_conj_hm vs_chant_conj_hf out 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 15 1781 1 16828494 1 0 **** 0 392694184 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** +1782 AttuneGemCraft 16822665 is_divprot G L v **** 0x01 prc_ft_attunegem **** **** **** **** **** **** 1 1500 hand **** vco_mehanelec02 vco_lgrinelec01 sco_lgrinelec01 vs_chant_conj_hm vs_chant_conj_hf out 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 15 1781 1 16828494 1 0 **** 0 392694184 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 1783 AttuneGemCheckGem 16822665 is_curpfail G L v **** 0x09 prc_ft_attngemsl **** **** **** **** **** **** 1 1500 hand **** vco_mehanacid02 vco_lgrinacid01 sco_lgrinelec01 vs_chant_conj_hm vs_chant_conj_hf out 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 15 1781 1 16828494 1 0 **** 0 392759720 **** **** 0 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 1784 SummonUndeadI 16847420 is_SumUndead1 C S vs 0x3a 0x2c sp_sum_undead **** 1 **** **** **** 1 1 1500 hand **** vco_mebalsonc01 **** sco_mebalsonc01 vs_chant_necr_lm vs_chant_necr_lf touch 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 15 **** 1 16847421 1 0 **** 0 **** **** **** 0 **** **** **** **** **** **** **** **** **** **** 1 **** **** **** **** **** **** **** 1785 SummonUndeadII 16847422 is_SumUndead2 C S vs 0x3a 0x2c sp_sum_undead **** 2 **** **** **** 2 2 1500 hand **** vco_mebalsonc01 **** sco_mebalsonc01 vs_chant_necr_lm vs_chant_necr_lf touch 1000 **** **** **** **** 0 **** **** **** **** **** **** 0 **** **** **** **** **** 15 **** 1 16847423 1 0 **** 0 **** **** **** 0 **** **** **** **** **** **** **** **** **** **** 2 **** **** **** **** **** **** **** diff --git a/nwn/nwnprc/trunk/2das/vfx_persistent.2da b/nwn/nwnprc/trunk/2das/vfx_persistent.2da index fa32c314..fe5906d6 100644 --- a/nwn/nwnprc/trunk/2das/vfx_persistent.2da +++ b/nwn/nwnprc/trunk/2das/vfx_persistent.2da @@ -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_damn_darkA sp_damn_darkB **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** +203 AOE_PER_DAMNDARK C 6.7 **** **** sp_damng_darka sp_damng_darkb **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** 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 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** diff --git a/nwn/nwnprc/trunk/include/prc_add_spell_dc.nss b/nwn/nwnprc/trunk/include/prc_add_spell_dc.nss index b8ecd637..f138edee 100644 --- a/nwn/nwnprc/trunk/include/prc_add_spell_dc.nss +++ b/nwn/nwnprc/trunk/include/prc_add_spell_dc.nss @@ -690,7 +690,7 @@ int PRCGetSpellSaveDC(int nSpellID = -1, int nSchool = -1, object oCaster = OBJE int PRCGetSaveDC(object oTarget, object oCaster, int nSpellID = -1) { - object oItem = GetSpellCastItem(); + object oItem = PRCGetSpellCastItem(); if(nSpellID == -1) nSpellID = PRCGetSpellId(); int nSchool = GetSpellSchool(nSpellID); diff --git a/nwn/nwnprc/trunk/include/prc_x2_craft.nss b/nwn/nwnprc/trunk/include/prc_x2_craft.nss index 46c24e81..887b65a0 100644 --- a/nwn/nwnprc/trunk/include/prc_x2_craft.nss +++ b/nwn/nwnprc/trunk/include/prc_x2_craft.nss @@ -1968,16 +1968,24 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, return TRUE; // tried item creation but do not know how to do it } - // No point scribing Gems from items, and its not allowed. - if (oItem != OBJECT_INVALID) - { - FloatingTextStringOnCreature("You cannot attune a Gem from an item.", oCaster, FALSE); - return TRUE; - } + // Only allow arcane spellcasters + int nClass = PRCGetLastSpellCastClass(); + if (!GetIsArcaneClass(nClass, oCaster)) + { + FloatingTextStringOnCreature("Only arcane casters can attune gems.", oCaster, FALSE); + return TRUE; + } + + // No point scribing Gems from items, and its not allowed. + if (oItem != OBJECT_INVALID) + { + FloatingTextStringOnCreature("You cannot attune a Gem from an item.", oCaster, FALSE); + return TRUE; + } // oTarget here should be the gem. If it's not, fail. if(!GetIsObjectValid(oTarget)) oTarget = PRCGetSpellTargetObject(); // Only accepts bioware gems & Craftable Natural Resources gems, but not gem dust. - int bIsBioGem = (GetStringLeft(GetResRef(oTarget), 5) == "it_gem"); + int bIsBioGem = (GetStringLeft(GetResRef(oTarget), 9) == "nw_it_gem"); int bIsCNRGem = (GetStringLeft(GetResRef(oTarget), 6) == "cnrgem"); int bIsDust = (GetStringLeft(GetResRef(oTarget), 10) == "cnrgemdust"); @@ -1987,21 +1995,12 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, return TRUE; } -/* if ((GetStringLeft(GetResRef(oTarget), 5) == "it_gem") || (GetStringLeft(GetResRef(oTarget), 6) == "cnrgem") && (GetStringLeft(GetResRef(oTarget), 10) != "cnrgemdust")) - { - FloatingTextStringOnCreature("Spell target is not a valid gem.", oCaster, FALSE); - // And out we go - return TRUE; - } */ - int nCaster = GetAlternativeCasterLevel(oCaster, PRCGetCasterLevel(oCaster)); int nDC = PRCGetSaveDC(oTarget, oCaster); if(!nSpell) nSpell = PRCGetSpellId(); int nSpellLevel; - if (PRCGetLastSpellCastClass() == CLASS_TYPE_CLERIC || PRCGetLastSpellCastClass() == CLASS_TYPE_UR_PRIEST) nSpellLevel = StringToInt(lookup_spell_cleric_level(nSpell)); - else if (PRCGetLastSpellCastClass() == CLASS_TYPE_DRUID) nSpellLevel = StringToInt(lookup_spell_druid_level(nSpell)); - else if (PRCGetLastSpellCastClass() == CLASS_TYPE_WIZARD || PRCGetLastSpellCastClass() == CLASS_TYPE_SORCERER) nSpellLevel = StringToInt(lookup_spell_level(nSpell)); + if (PRCGetLastSpellCastClass() == CLASS_TYPE_WIZARD || PRCGetLastSpellCastClass() == CLASS_TYPE_SORCERER) nSpellLevel = StringToInt(lookup_spell_level(nSpell)); // If none of these work, check the innate level of the spell if (nSpellLevel == 0) nSpellLevel = StringToInt(lookup_spell_innate(nSpell)); // Minimum level. @@ -2034,13 +2033,13 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, if (!GetHasGPToSpend(oCaster, costs.nGoldCost)) { - FloatingTextStringOnCreature("You do not have enough gold to scribe this Gem.", oCaster, FALSE); + FloatingTextStringOnCreature("You do not have enough gold to attue this Gem.", oCaster, FALSE); // Since they don't have enough, the spell casts normally return TRUE; } if (!GetHasXPToSpend(oCaster, costs.nXPCost) ) { - FloatingTextStringOnCreature("You do not have enough experience to scribe this Gem.", oCaster, FALSE); + FloatingTextStringOnCreature("You do not have enough experience to attune this Gem.", oCaster, FALSE); // Since they don't have enough, the spell casts normally return TRUE; } @@ -2057,7 +2056,24 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, } // Steal all the code from craft wand. - int nPropID = IPGetIPConstCastSpellFromSpellID(nSpell); + //int nPropID = IPGetIPConstCastSpellFromSpellID(nSpell); + + // Handle subradial spells - keep original for radial menu + int nSpellOriginal = nSpell; + int nSpellMaster = nSpellOriginal; + if (GetIsSubradialSpell(nSpellOriginal)) + { + nSpellMaster = GetMasterSpellFromSubradial(nSpellOriginal); + } + + // Prefer iprp mapping for original subradial, fallback to master + int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellOriginal); + int nSpellUsedForIP = nSpellOriginal; + if (nPropID < 0) + { + nPropID = IPGetIPConstCastSpellFromSpellID(nSpellMaster); + nSpellUsedForIP = nSpellMaster; + } // * GZ 2003-09-11: If the current spell cast is not acid fog, and // * returned property ID is 0, bail out to prevent @@ -2075,22 +2091,71 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, return TRUE; } - if (nPropID != -1) + if (nPropID != -1) + { + // Handle stack - reduce original stack by 1 + int nOriginalStack = GetItemStackSize(oTarget); + if (nOriginalStack > 1) + SetItemStackSize(oTarget, nOriginalStack - 1); + + // Create a NEW single gem in a work container to prevent auto-stacking + string sResRef = GetResRef(oTarget); + object oWorkContainer = IPGetIPWorkContainer(oCaster); + object oWorkGem = CreateItemOnObject(sResRef, oWorkContainer, 1); + + // Add properties to the NEW gem only + itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpellUsedForIP, PRCGetCasterLevel()); + AddItemProperty(DURATION_TYPE_PERMANENT,ipLevel, oWorkGem); + itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpellUsedForIP, PRCGetMetaMagicFeat()); + AddItemProperty(DURATION_TYPE_PERMANENT,ipMeta, oWorkGem); + itemproperty ipDC = ItemPropertyCastSpellDC(nSpellUsedForIP, PRCGetSaveDC(PRCGetSpellTargetObject(), OBJECT_SELF)); + AddItemProperty(DURATION_TYPE_PERMANENT,ipDC, oWorkGem); + + int nUseType = IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE; + if (nCharges == 1) + { + nUseType = IP_CONST_CASTSPELL_NUMUSES_2_CHARGES_PER_USE; + nCharges = 3; + } + itemproperty ipProp = ItemPropertyCastSpell(nPropID, nUseType); + AddItemProperty(DURATION_TYPE_PERMANENT, ipProp, oWorkGem); + + SetItemCharges(oWorkGem, nCharges); + SetXP(oCaster, nNewXP); + TakeGoldFromCreature(costs.nGoldCost, oCaster, TRUE); + + string sName; + sName = Get2DACache("spells", "Name", nSpellUsedForIP); + sName = "Gem of "+GetStringByStrRef(StringToInt(sName)); + SetName(oWorkGem, sName); + + // Copy the work gem to create the final attuned gem in caster's inventory + object oNewGem = CopyObject(oWorkGem, GetLocation(oCaster), oCaster, "prc_attunegem"); + + // Destroy the work gem + DestroyObject(oWorkGem, 0.1); + + // If original stack was 1, destroy it too + if (nOriginalStack == 1) + DestroyObject(oTarget, 0.1); + } + +/* if (nPropID != -1) { - itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpell, PRCGetCasterLevel()); + // Handle stack splitting - reduce original stack and create single gem to work with + int nOriginalStack = GetItemStackSize(oTarget); + if (nOriginalStack > 1) + { + SetItemStackSize(oTarget, nOriginalStack - 1); + oTarget = CreateItemOnObject(GetResRef(oTarget), oCaster, 1); + } + + itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpell, PRCGetCasterLevel()); AddItemProperty(DURATION_TYPE_PERMANENT,ipLevel, oTarget); itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpell, PRCGetMetaMagicFeat()); AddItemProperty(DURATION_TYPE_PERMANENT,ipMeta, oTarget); itemproperty ipDC = ItemPropertyCastSpellDC(nSpell, PRCGetSaveDC(PRCGetSpellTargetObject(), OBJECT_SELF)); AddItemProperty(DURATION_TYPE_PERMANENT,ipDC, oTarget); - -/* if (nCharges == 1) // This is to handle one use Gems so the spellhooking works - { - itemproperty ipProp = ItemPropertyCastSpell(nPropID,IP_CONST_CASTSPELL_NUMUSES_2_CHARGES_PER_USE); - AddItemProperty(DURATION_TYPE_PERMANENT,ipProp, oTarget); - // This is done so the item exists when it is used for the game to read data off of - nCharges = 3; - } */ int nUseType = IP_CONST_CASTSPELL_NUMUSES_1_CHARGE_PER_USE; if (nCharges == 1) @@ -2139,7 +2204,7 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID, object oNewGem = CopyObject(oTarget, GetLocation(oCaster), oCaster, "prc_attunegem"); DestroyObject(oTarget, 0.1); } - + */ // If we have made it this far, they have crafted the Gem and the spell has been used up, so it returns false. return FALSE; } diff --git a/nwn/nwnprc/trunk/include/x2_inc_spellhook.nss b/nwn/nwnprc/trunk/include/x2_inc_spellhook.nss index 0ea543e5..5bac81dd 100644 --- a/nwn/nwnprc/trunk/include/x2_inc_spellhook.nss +++ b/nwn/nwnprc/trunk/include/x2_inc_spellhook.nss @@ -3503,6 +3503,21 @@ int X2PreSpellCastCode2() nContinue = FALSE; } } + + //--------------------------------------------------------------------------- + // Attuned Gem Use check + //--------------------------------------------------------------------------- + if(nContinue && (GetBaseItemType(oSpellCastItem) == BASE_ITEM_GEM) && (GetTag(oSpellCastItem) == "prc_attunegem")) + { + int bIsSubradial = GetIsSubradialSpell(nSpellID); + + if(bIsSubradial) + { + nSpellID = GetMasterSpellFromSubradial(nSpellID); + } + int nItemCL = GetCastSpellCasterLevelFromItem(oSpellCastItem, nSpellID); + if(DEBUG) DoDebug("x2_inc_spellhook >> X2PreSpellCastCode2: Attuned Gem Found"); + } //--------------------------------------------------------------------------- // No casting while using expertise diff --git a/nwn/nwnprc/trunk/newspellbook/inv_dra_darkness.nss b/nwn/nwnprc/trunk/newspellbook/inv_dra_darkness.nss index 68c4a79f..4bdc56c0 100644 --- a/nwn/nwnprc/trunk/newspellbook/inv_dra_darkness.nss +++ b/nwn/nwnprc/trunk/newspellbook/inv_dra_darkness.nss @@ -39,14 +39,14 @@ void main() if(iAttackRoll > 0) { oItemTarget = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); - if(!GetIsObjectValid(oTarget)) + if(!GetIsObjectValid(oItemTarget)) { //no armor, check other slots int i; for(i=0;i<14;i++) { oItemTarget = GetItemInSlot(i, oTarget); - if(GetIsObjectValid(oTarget)) + if(GetIsObjectValid(oItemTarget)) break;//end for loop } } diff --git a/nwn/nwnprc/trunk/newspellbook/tob_dpst_drgtth.nss b/nwn/nwnprc/trunk/newspellbook/tob_dpst_drgtth.nss index ad3603a1..94939f4d 100644 --- a/nwn/nwnprc/trunk/newspellbook/tob_dpst_drgtth.nss +++ b/nwn/nwnprc/trunk/newspellbook/tob_dpst_drgtth.nss @@ -6,6 +6,10 @@ ---------------- 27/01/08 by Stratovarius + + Fixed by: Jaysyn + On: 2026-05-25 19:11:53 + */ /** @file Dragon's Tooth @@ -23,7 +27,7 @@ void main() { object oInitiator = OBJECT_SELF; object oCreature = CreateObject(OBJECT_TYPE_PLACEABLE, "tob_dpst_pillar", PRCGetSpellTargetLocation()); - object oProneTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(10.0), GetLocation(oInitiator)); + object oProneTarget = MyFirstObjectInShape(SHAPE_SPHERE, FeetToMeters(60.0), PRCGetSpellTargetLocation()); while(GetIsObjectValid(oProneTarget)) { int nDC = 10 + GetHitDice(oInitiator)/2 + GetAbilityModifier(ABILITY_STRENGTH, oInitiator); @@ -34,11 +38,11 @@ void main() nDC += 1; } // Save check - if (!PRCMySavingThrow(SAVING_THROW_WILL, oProneTarget, nDC)) + if (!PRCMySavingThrow(SAVING_THROW_REFLEX, oProneTarget, nDC)) { ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ExtraordinaryEffect(EffectKnockdown()), oProneTarget, 6.0); } - oProneTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(10.0), GetLocation(oInitiator)); + oProneTarget = MyNextObjectInShape(SHAPE_SPHERE, FeetToMeters(60.0), PRCGetSpellTargetLocation()); } } diff --git a/nwn/nwnprc/trunk/newspellbook/true_utr_sezitem.nss b/nwn/nwnprc/trunk/newspellbook/true_utr_sezitem.nss index fa75e712..5a20a6f6 100644 --- a/nwn/nwnprc/trunk/newspellbook/true_utr_sezitem.nss +++ b/nwn/nwnprc/trunk/newspellbook/true_utr_sezitem.nss @@ -76,7 +76,6 @@ void main() } // Impact Effects - //ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_DUR_FLOATING_DISK), GetLocation(oTarget)); - ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_FLOATING_DISK), GetLocation(oTarget), 3.0f); + ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_BIGBYS_FORCEFUL_HAND), GetLocation(oTarget)); }// end if - Successful utterance } diff --git a/nwn/nwnprc/trunk/scripts/prc_acolyte.nss b/nwn/nwnprc/trunk/scripts/prc_acolyte.nss index c45aac8d..6ebb0809 100644 --- a/nwn/nwnprc/trunk/scripts/prc_acolyte.nss +++ b/nwn/nwnprc/trunk/scripts/prc_acolyte.nss @@ -26,8 +26,10 @@ void AcolyteSymbiosis(object oPC, object oSkin, int iLevel) { if(GetLocalInt(oSkin, "AcolyteSymbBonus") == iLevel) return; - RemoveSpecificProperty(oSkin, ITEM_PROPERTY_DAMAGE_REDUCTION, GetLocalInt(oSkin, "AcolyteSymbBonus"), IP_CONST_DAMAGESOAK_20_HP, 1, "AcolyteSymbBonus"); - AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageReduction(iLevel, IP_CONST_DAMAGESOAK_20_HP), oSkin); + //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); } diff --git a/nwn/nwnprc/trunk/spells/nw_s0_darkness.nss b/nwn/nwnprc/trunk/spells/nw_s0_darkness.nss index af496ea5..76e6ea46 100644 --- a/nwn/nwnprc/trunk/spells/nw_s0_darkness.nss +++ b/nwn/nwnprc/trunk/spells/nw_s0_darkness.nss @@ -65,14 +65,14 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel) if(iAttackRoll > 0) { oItemTarget = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); - if(!GetIsObjectValid(oTarget)) + if(!GetIsObjectValid(oItemTarget)) { //no armor, check other slots int i; for(i=0;i<14;i++) { oItemTarget = GetItemInSlot(i, oTarget); - if(GetIsObjectValid(oTarget)) + if(GetIsObjectValid(oItemTarget)) break;//end for loop } } diff --git a/nwn/nwnprc/trunk/spells/sp_damng_dark.nss b/nwn/nwnprc/trunk/spells/sp_damng_dark.nss index 1824b2c0..90b42980 100644 --- a/nwn/nwnprc/trunk/spells/sp_damng_dark.nss +++ b/nwn/nwnprc/trunk/spells/sp_damng_dark.nss @@ -82,14 +82,14 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel) if(iAttackRoll > 0) { oItemTarget = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); - if(!GetIsObjectValid(oTarget)) + if(!GetIsObjectValid(oItemTarget)) { //no armor, check other slots int i; for(i=0;i<14;i++) { oItemTarget = GetItemInSlot(i, oTarget); - if(GetIsObjectValid(oTarget)) + if(GetIsObjectValid(oItemTarget)) break;//end for loop } } diff --git a/nwn/nwnprc/trunk/spells/sp_deepdarkness.nss b/nwn/nwnprc/trunk/spells/sp_deepdarkness.nss index 2379ded4..7c38d4aa 100644 --- a/nwn/nwnprc/trunk/spells/sp_deepdarkness.nss +++ b/nwn/nwnprc/trunk/spells/sp_deepdarkness.nss @@ -53,14 +53,14 @@ int DoSpell(object oCaster, object oTarget, int nCasterLevel) if(iAttackRoll > 0) { oItemTarget = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget); - if(!GetIsObjectValid(oTarget)) + if(!GetIsObjectValid(oItemTarget)) { //no armor, check other slots int i; for(i=0;i<14;i++) { oItemTarget = GetItemInSlot(i, oTarget); - if(GetIsObjectValid(oTarget)) + if(GetIsObjectValid(oItemTarget)) break;//end for loop } } diff --git a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk index bbcb9ce9..558b979f 100644 Binary files a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk and b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk differ diff --git a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml index bdfe6442..db3adb1b 100644 --- a/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml +++ b/nwn/nwnprc/trunk/tlk/prc8_consortium.tlk.xml @@ -7347,7 +7347,7 @@ You make yourself - including clothing, armor, weapons and equipment - look diff Disguise Self, Normal Form Attune Gem Type of Feat: Item Creation -Prerequisite: Intelligence 13, Arcane Spells level 2. +Prerequisite: Intelligence 13, 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. Epic Scout diff --git a/nwn/nwnprc/trunk/tlk/prc_consortium.tlk b/nwn/nwnprc/trunk/tlk/prc_consortium.tlk index bbcb9ce9..4f61d108 100644 Binary files a/nwn/nwnprc/trunk/tlk/prc_consortium.tlk and b/nwn/nwnprc/trunk/tlk/prc_consortium.tlk differ