2026/05/25 Memorial Day Update
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. Updated PRC8 Changelog doc.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 **** **** **** **** **** **** ****
|
||||
|
||||
@@ -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 **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -2077,21 +2093,70 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID,
|
||||
|
||||
if (nPropID != -1)
|
||||
{
|
||||
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpell, PRCGetCasterLevel());
|
||||
// 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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -3504,6 +3504,21 @@ int X2PreSpellCastCode2()
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// 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
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -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 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.</entry>
|
||||
<entry id="45451" lang="en" sex="m">Epic Scout</entry>
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user