From 5ea23cb0aab48a0ef9de74110666ee2a8b89aaa7 Mon Sep 17 00:00:00 2001 From: Jaysyn904 <68194417+Jaysyn904@users.noreply.github.com> Date: Fri, 1 May 2026 14:58:32 -0400 Subject: [PATCH] May Day Update Fixed Expanded Incarnum Capacity II-V to require the previous feat as a prereq. Fixed bonus feats granted by soulmelds to be removed when rebinding. --- nwn/nwnprc/trunk/2das/feat.2da | 10 +- nwn/nwnprc/trunk/include/moi_inc_moifunc.nss | 110 +++++++++++++++++- .../trunk/newspellbook/moi_ft_rebind.nss | 36 +++++- .../trunk/newspellbook/moi_inc_rapid.nss | 23 +++- .../trunk/newspellbook/moi_inc_rpdcnv.nss | 16 ++- .../trunk/newspellbook/moi_mld_aprib.nss | 45 ++++++- .../trunk/newspellbook/moi_mld_astral.nss | 55 ++++++++- .../trunk/newspellbook/moi_mld_basmsk.nss | 53 ++++++++- .../trunk/newspellbook/moi_mld_bldtln.nss | 74 +++++++++++- .../trunk/newspellbook/moi_mld_cryshlm.nss | 39 ++++++- .../trunk/newspellbook/moi_mld_drgnfr.nss | 58 ++++++++- .../trunk/newspellbook/moi_mld_frsthl.nss | 56 ++++++++- .../trunk/newspellbook/moi_mld_impboots.nss | 37 +++++- .../trunk/newspellbook/moi_mld_lamiablt.nss | 58 ++++++++- .../trunk/newspellbook/moi_mld_maulgntl.nss | 64 +++++++++- .../trunk/newspellbook/moi_mld_mntcrb.nss | 50 +++++++- .../trunk/newspellbook/moi_mld_phoenix.nss | 32 ++++- .../trunk/newspellbook/moi_mld_thftglvs.nss | 41 ++++++- .../trunk/newspellbook/moi_mld_wormtail.nss | 53 ++++++++- 19 files changed, 865 insertions(+), 45 deletions(-) diff --git a/nwn/nwnprc/trunk/2das/feat.2da b/nwn/nwnprc/trunk/2das/feat.2da index 304b4241..86a38fb3 100644 --- a/nwn/nwnprc/trunk/2das/feat.2da +++ b/nwn/nwnprc/trunk/2das/feat.2da @@ -8947,11 +8947,11 @@ 8943 DoubleChakra_Heart 16838122 16838125 ife_overchannel **** **** **** **** **** **** **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_COMBAT_CASTING 4 **** 6 **** **** **** 0 1 8944 DoubleChakra_Soul 16838123 16838125 ife_overchannel **** **** **** **** **** **** **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_COMBAT_CASTING 4 **** 6 **** **** **** 0 1 8945 DoubleChakra_Totem 16838124 16838125 ife_overchannel **** **** **** **** **** **** **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_COMBAT_CASTING 4 **** 6 **** **** **** 0 1 -8946 ExpandedSoulmeldCapacity_1 16838126 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_1 4 **** **** **** **** **** 0 1 -8947 ExpandedSoulmeldCapacity_2 16838127 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_2 4 **** **** **** **** **** 0 1 -8948 ExpandedSoulmeldCapacity_3 16838128 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_3 4 **** **** **** **** **** 0 1 -8949 ExpandedSoulmeldCapacity_4 16838129 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_4 4 **** **** **** **** **** 0 1 -8950 ExpandedSoulmeldCapacity_5 16838130 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** **** **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_5 4 **** **** **** **** **** 0 1 +8946 ExpandedSoulmeldCapacity_1 16838126 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** **** **** 0 0 1 **** **** **** 8947 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_1 4 **** **** **** **** **** 0 1 +8947 ExpandedSoulmeldCapacity_2 16838127 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** 8946 **** 0 0 1 **** **** **** 8948 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_2 4 **** **** **** **** **** 0 1 +8948 ExpandedSoulmeldCapacity_3 16838128 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** 8947 **** 0 0 1 **** **** **** 8949 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_3 4 **** **** **** **** **** 0 1 +8949 ExpandedSoulmeldCapacity_4 16838129 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** 8948 **** 0 0 1 **** **** **** 8950 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_4 4 **** **** **** **** **** 0 1 +8950 ExpandedSoulmeldCapacity_5 16838130 16838131 ife_X2EpicWill **** **** **** **** **** 15 **** **** 8949 **** 0 0 1 **** **** **** **** 1 **** 53 **** **** **** **** **** **** **** **** **** **** FEAT_EXPANDED_SOULMELD_CAPACITY_5 4 **** **** **** **** **** 0 1 8951 BlademeldShout 16838142 16838143 ir_GenHowl **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 18646 **** 1 -1 **** 1 **** **** **** **** **** **** **** **** **** FEAT_SUDDEN_EMPOWER 5 **** **** **** **** **** 0 1 8952 RebindBlademeld 16838140 16838141 ife_X1HTym **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 18645 **** 1 10 **** 1 **** **** **** **** **** **** **** **** **** FEAT_SUDDEN_EMPOWER 5 **** **** **** **** **** 0 1 8953 Meldshield_Invest 16838148 16838150 ife_X1ADAbj **** **** **** **** **** **** **** **** **** **** 0 0 0 **** **** 18633 **** 1 -1 **** 1 **** **** **** **** **** **** **** **** **** FEAT_SUDDEN_EMPOWER 5 **** **** **** **** **** 0 0 diff --git a/nwn/nwnprc/trunk/include/moi_inc_moifunc.nss b/nwn/nwnprc/trunk/include/moi_inc_moifunc.nss index 12f5e008..030f6024 100644 --- a/nwn/nwnprc/trunk/include/moi_inc_moifunc.nss +++ b/nwn/nwnprc/trunk/include/moi_inc_moifunc.nss @@ -15,10 +15,118 @@ */ //::////////////////////////////////////////////// //::////////////////////////////////////////////// - +#include "moi_meld_const" ////////////////////////////////////////////////// /* Function prototypes */ ////////////////////////////////////////////////// +/** + * @brief Retrieves the effect tag associated with a specific soulmeld. + * + * Maps a soulmeld identifier to its corresponding effect tag string used + * for applying or removing feat-granting effects tied to that soulmeld. + * + * @param nMeldId The integer identifier of the soulmeld (e.g., MELD_FROST_HELM). + * + * @return A string representing the effect tag associated with the given + * soulmeld, or an empty string ("") if the soulmeld ID is not recognized. + * + * @note The returned tag is intended for use with effect tagging systems, + * such as applying or removing effects via GetEffectTag(). + * + * @warning If a new soulmeld is added and not included in this switch, + * this function will return an empty string, which may cause + * dependent systems to fail silently. + */ +string GetSoulmeldTag(int nMeldId) +{ + if (nMeldId == MELD_FROST_HELM) return "SOULMELD_FROST_HELM_FEATS"; + else if (nMeldId == MELD_IMPULSE_BOOTS) return "SOULMELD_IMPULSE_BOOTS_FEATS"; + else if (nMeldId == MELD_PHOENIX_BELT) return "SOULMELD_PHOENIX_BELT_FEATS"; + else if (nMeldId == MELD_WORMTAIL_BELT) return "SOULMELD_WORMTAIL_BELT_FEATS"; + else if (nMeldId == MELD_APPARITION_RIBBON) return "SOULMELD_APPARITION_RIBBON_FEATS"; + else if (nMeldId == MELD_MANTICORE_BELT) return "SOULMELD_MANTICORE_BELT_FEATS"; + else if (nMeldId == MELD_THEFT_GLOVES) return "SOULMELD_THEFT_GLOVES_FEATS"; + else if (nMeldId == MELD_BLOODTALONS) return "SOULMELD_BLOODTALONS_FEATS"; + else if (nMeldId == MELD_LAMIA_BELT) return "SOULMELD_LAMIA_BELT_FEATS"; + else if (nMeldId == MELD_CRYSTAL_HELM) return "SOULMELD_CRYSTAL_HELM_FEATS"; + else if (nMeldId == MELD_BASILISK_MASK) return "SOULMELD_BASILISK_MASK_FEATS"; + else if (nMeldId == MELD_ASTRAL_VAMBRACES) return "SOULMELD_ASTRAL_VAMBRACES_FEATS"; + else if (nMeldId == MELD_MAULING_GAUNTLETS) return "SOULMELD_MAULING_GAUNTLETS_FEATS"; + else if (nMeldId == MELD_DRAGONFIRE_MASK) return "SOULMELD_DRAGONFIRE_MASK_FEATS"; + else return ""; +} + +/** + * @brief Removes all effects from a creature that match a specific soulmeld tag. + * + * Iterates through all active effects on the specified object and removes any + * effect whose tag matches the provided soulmeld tag. This is typically used + * to strip feat-granting effects associated with a single soulmeld. + * + * @param oPC The creature (typically a player character) from which effects + * will be removed. + * @param sMeldTag The effect tag identifying the soulmeld-related feat effects + * to remove. + * + * @note This function performs an exact string comparison using GetEffectTag(). + * + * @warning Passing an empty string ("") as sMeldTag may result in unintended + * behavior if any effects are tagged with an empty string. + */ +void RemoveSpecificSoulmeldFeats(object oPC, string sMeldTag) +{ + effect eEffect = GetFirstEffect(oPC); + while(GetIsEffectValid(eEffect)) + { + if(GetEffectTag(eEffect) == sMeldTag) + RemoveEffect(oPC, eEffect); + + eEffect = GetNextEffect(oPC); + } +} + +/** + * @brief Removes all soulmeld-related feat effects from a creature. + * + * Iterates through all active effects on the specified object and removes any + * effects that match known soulmeld feat tags. These effects are assumed to + * have been applied to grant feats associated with specific soulmelds. + * + * @param oPC The creature (typically a player character) from which soulmeld + * feat effects will be removed. + * + * @note This function relies on effect tags to identify soulmeld feat effects. + * Only effects with explicitly listed tags will be removed. + * + * @warning Any soulmeld feat effect not included in the tag list will remain + * active. Ensure new soulmelds are added here if they apply feat effects. + */ +void RemoveSoulmeldFeatEffects(object oPC) +{ + effect eEffect = GetFirstEffect(oPC); + while(GetIsEffectValid(eEffect)) + { + string sTag = GetEffectTag(eEffect); + if(sTag == "SOULMELD_FROST_HELM_FEATS" || + sTag == "SOULMELD_IMPULSE_BOOTS_FEATS" || + sTag == "SOULMELD_PHOENIX_BELT_FEATS" || + sTag == "SOULMELD_WORMTAIL_BELT_FEATS" || + sTag == "SOULMELD_APPARITION_RIBBON_FEATS" || + sTag == "SOULMELD_MANTICORE_BELT_FEATS" || + sTag == "SOULMELD_THEFT_GLOVES_FEATS" || + sTag == "SOULMELD_BLOODTALONS_FEATS" || + sTag == "SOULMELD_LAMIA_BELT_FEATS" || + sTag == "SOULMELD_CRYSTAL_HELM_FEATS" || + sTag == "SOULMELD_BASILISK_MASK_FEATS" || + sTag == "SOULMELD_ASTRAL_VAMBRACES_FEATS" || + sTag == "SOULMELD_MAULING_GAUNTLETS_FEATS" || + sTag == "SOULMELD_DRAGONFIRE_MASK_FEATS") + { + RemoveEffect(oPC, eEffect); + } + eEffect = GetNextEffect(oPC); + } +} /** * Determines the given creature's Meldshaper level. diff --git a/nwn/nwnprc/trunk/newspellbook/moi_ft_rebind.nss b/nwn/nwnprc/trunk/newspellbook/moi_ft_rebind.nss index 1ab9201a..a711580c 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_ft_rebind.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_ft_rebind.nss @@ -4,7 +4,7 @@ int RebindFeatToChakra(int nSpellId) { int nReturn = -1; - if (nSpellId == 18977) nReturn = CHAKRA_CROWN; + if (nSpellId == 18977) nReturn = CHAKRA_CROWN; else if (nSpellId == 18978) nReturn = CHAKRA_FEET ; else if (nSpellId == 18979) nReturn = CHAKRA_HANDS ; else if (nSpellId == 18980) nReturn = CHAKRA_ARMS ; @@ -19,7 +19,33 @@ int RebindFeatToChakra(int nSpellId) return nReturn; } -void main() +void main() +{ + object oMeldshaper = OBJECT_SELF; + int nClass = GetPrimaryIncarnumClass(oMeldshaper); + int nChakra = RebindFeatToChakra(GetSpellId()); + int nMeld = GetIsChakraBound(oMeldshaper, nChakra); + + // Get the swap target + int nTest = GetIsChakraUsed(oMeldshaper, nChakra, nClass); + int nTest2 = GetIsChakraUsed(oMeldshaper, nChakra+11, nClass); + int nSwap = nTest2; + if (nMeld == nTest2) nSwap = nTest; + + // Clean only the specific soulmelds being reconfigured + RemoveSpecificSoulmeldFeats(oMeldshaper, GetSoulmeldTag(nMeld)); + RemoveSpecificSoulmeldFeats(oMeldshaper, GetSoulmeldTag(nSwap)); + + // Unbind the meld, then bind it + DeleteLocalInt(oMeldshaper, "BoundMeld"+IntToString(nChakra)); + BindMeldToChakra(oMeldshaper, nSwap, nChakra, nClass); + + // Shape them both + ShapeSoulmeld(oMeldshaper, nMeld); + ShapeSoulmeld(oMeldshaper, nSwap); +} + +/* void main() { object oMeldshaper = OBJECT_SELF; int nClass = GetPrimaryIncarnumClass(oMeldshaper); @@ -40,10 +66,10 @@ void main() // Shape them both ShapeSoulmeld(oMeldshaper, nMeld); - ShapeSoulmeld(oMeldshaper, nSwap); + ShapeSoulmeld(oMeldshaper, nSwap); */ /* if (GetLocalInt(oMeldshaper, "PerfectMeldshaper")) return; AssignCommand(oMeldshaper, ClearAllActions(TRUE)); SetLocalInt(oMeldshaper, "RebindSoulmeldCnv", GetSpellId()); - StartDynamicConversation("moi_rebindcnv", oMeldshaper, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oMeldshaper); */ -} + StartDynamicConversation("moi_rebindcnv", oMeldshaper, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oMeldshaper); +}*/ diff --git a/nwn/nwnprc/trunk/newspellbook/moi_inc_rapid.nss b/nwn/nwnprc/trunk/newspellbook/moi_inc_rapid.nss index 17956e50..7cf14316 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_inc_rapid.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_inc_rapid.nss @@ -1,4 +1,23 @@ -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" +#include "inc_dynconv" + +// Stage constant for Rapid Meldshaping +const int STAGE_SELECT_UNSHAPE_MELD = 3; + +void main() +{ + object oMeldshaper = OBJECT_SELF; + if (GetLocalInt(oMeldshaper, "PerfectMeldshaper")) return; + AssignCommand(oMeldshaper, ClearAllActions(TRUE)); + SetLocalInt(oMeldshaper, "RapidMeldshaping", GetSpellId()); + + // Set the initial stage for unshape selection + SetStage(STAGE_SELECT_UNSHAPE_MELD, oMeldshaper); + + StartDynamicConversation("moi_inc_rpdcnv", oMeldshaper, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oMeldshaper); +} + +/* #include "moi_inc_moifunc" #include "inc_dynconv" void main() @@ -8,4 +27,4 @@ void main() AssignCommand(oMeldshaper, ClearAllActions(TRUE)); SetLocalInt(oMeldshaper, "RapidMeldshaping", GetSpellId()); StartDynamicConversation("moi_inc_rpdcnv", oMeldshaper, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oMeldshaper); -} +} */ diff --git a/nwn/nwnprc/trunk/newspellbook/moi_inc_rpdcnv.nss b/nwn/nwnprc/trunk/newspellbook/moi_inc_rpdcnv.nss index a52467f0..a11fad97 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_inc_rpdcnv.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_inc_rpdcnv.nss @@ -313,12 +313,20 @@ void main() } else if(nStage == STAGE_CONFIRM_UNSHAPE_SELECTION) { - if (nChoice) - { - PRCRemoveSpellEffects(GetIsChakraUsed(oMeldshaper, GetLocalInt(oMeldshaper, "nChakra"), nClass), oMeldshaper, oMeldshaper); +/* if (nChoice) + { + PRCRemoveSpellEffects(GetIsChakraUsed(oMeldshaper, GetLocalInt(oMeldshaper, "nChakra"), nClass), oMeldshaper, oMeldshaper); DeleteLocalInt(oMeldshaper, "nChakra"); nStage = STAGE_SELECT_CHAKRA; - } + } */ + if (nChoice) + { + int nMeldId = GetIsChakraUsed(oMeldshaper, GetLocalInt(oMeldshaper, "nChakra"), nClass); + RemoveSpecificSoulmeldFeats(oMeldshaper, GetSoulmeldTag(nMeldId)); + PRCRemoveSpellEffects(nMeldId, oMeldshaper, oMeldshaper); + DeleteLocalInt(oMeldshaper, "nChakra"); + nStage = STAGE_SELECT_CHAKRA; + } else { nStage = STAGE_SELECT_UNSHAPE_MELD; diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_aprib.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_aprib.nss index 89a5c451..f08cd620 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_aprib.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_aprib.nss @@ -29,8 +29,49 @@ it was activated. Each day, you can spend a total number of rounds incorporeal e //:: //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + + effect eLink; + + // Add Blind-Fight as effect + eLink = EffectBonusFeat(FEAT_BLIND_FIGHT); + + if (nEssentia) eLink = EffectLinkEffects(eLink, VersusRacialTypeEffect(EffectDamageIncrease(IPGetDamageBonusConstantFromNumber(nEssentia)), RACIAL_TYPE_UNDEAD)); + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_APPARITION_RIBBON_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Throat bind (incorporeal) — check regular or double Throat + int nBoundToThroat = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_THROAT)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_THROAT)) == nMeldId) + nBoundToThroat = TRUE; + + if (nBoundToThroat) + { + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_APPARITION_RIBBON_THROAT), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + } + + // Keep meld identification as item property + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_APPARITION_RIBBON), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); +} + +/* #include "moi_inc_moifunc" void main() { @@ -56,7 +97,7 @@ void main() ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oMeldshaper, 9999.0); IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_APPARITION_RIBBON), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); -} +} */ /* void main() { diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_astral.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_astral.nss index 335cef39..7dd28e06 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_astral.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_astral.nss @@ -45,8 +45,59 @@ You gain two slam attacks, which act as primary natural weapons. The slam attack //:: //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + int nBonus = (1 + nEssentia) * 2; + + effect eLink = EffectDamageReduction(nBonus, DAMAGE_POWER_PLUS_ONE); + if (GetIsMeldBound(oMeldshaper) == CHAKRA_ARMS || GetIsMeldBound(oMeldshaper) == CHAKRA_DOUBLE_ARMS) + { + int nChoice = GetLocalInt(oMeldshaper, "AstralVambraces"); + //FloatingTextStringOnCreature("Astral Vambrace Arms Chakra nChoice "+IntToString(nChoice), oMeldshaper, FALSE); + if (nChoice == 1) eLink = EffectLinkEffects(eLink, EffectTemporaryHitpoints(5)); + //else if (nChoice == 2) Handled in prc_speed + else if (nChoice == 3) eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_CLEAVE)); + else if (nChoice == 4) eLink = EffectLinkEffects(eLink, EffectACIncrease(1, AC_DEFLECTION_BONUS)); + else if (nChoice == 5) eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_IMPROVED_BULLRUSH)); + else if (nChoice == 6) eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_MOBILITY)); + else if (nChoice == 7) eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_POWER_ATTACK)); + else if (nChoice == 8) eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_ACID, 5)); + else if (nChoice == 9) eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_COLD, 5)); + else if (nChoice == 10) eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 5)); + else if (nChoice == 11) eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_FIRE, 5)); + else if (nChoice == 12) eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_SONIC, 5)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_ASTRAL_VAMBRACES_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item property + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_ASTRAL_VAMBRACES), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + if (GetIsMeldBound(oMeldshaper) == CHAKRA_HANDS || GetIsMeldBound(oMeldshaper) == CHAKRA_DOUBLE_HANDS) + { + string sResRef = "prc_hdarc_slam_"; + int nSize = PRCGetCreatureSize(oMeldshaper); + // This is correct to get the right damage profile + sResRef += GetAffixForSize(nSize+1); + AddNaturalPrimaryWeapon(oMeldshaper, sResRef, 2); + SetLocalString(oMeldshaper, "IncarnumPrimaryAttackL", sResRef); + } +} + +/* #include "moi_inc_moifunc" void main() { @@ -84,4 +135,4 @@ void main() AddNaturalPrimaryWeapon(oMeldshaper, sResRef, 2); SetLocalString(oMeldshaper, "IncarnumPrimaryAttackL", sResRef); } -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_basmsk.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_basmsk.nss index 9aa93a07..01e64e32 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_basmsk.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_basmsk.nss @@ -34,8 +34,57 @@ By directing your gaze on a creature within 30 feet, you can temporarily turn th //:: Double Totem Bind support added //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + effect eLink = EffectUltravision(); + + if (nEssentia) eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_SPOT, nEssentia * 2)); + + // Check for Brow bind and add Blind-Fight if bound + int nBoundToBrow = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_BROW)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_BROW)) == nMeldId) + nBoundToBrow = TRUE; + + if (nBoundToBrow) + { + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_BLIND_FIGHT)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_BASILISK_MASK_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item properties + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_BASILISK_MASK), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Totem bind (petrifying gaze) — check regular or double Totem + int nBoundToTotem = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_TOTEM)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_TOTEM)) == nMeldId) + nBoundToTotem = TRUE; + + if (nBoundToTotem) + { + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_BASILISK_MASK_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + } +} + + +/* #include "moi_inc_moifunc" void main() { @@ -66,7 +115,7 @@ void main() if (nBoundToTotem) IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_BASILISK_MASK_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); -} +} */ /* void main() { diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_bldtln.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_bldtln.nss index 3ff37eae..acd2050c 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_bldtln.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_bldtln.nss @@ -34,8 +34,78 @@ You can make two claw attacks that each deal 1d4 points of damage plus your Stre //:: Double Chakra Bind support added //:: Double Totem bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void BloodtalonsTotem(object oMeldshaper, int nEssentia) +{ + IPSafeAddItemProperty(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper), ItemPropertyAttackBonus(nEssentia), 99999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE); + IPSafeAddItemProperty(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper), ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + AddEventScript(GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oMeldshaper), EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE); + IPSafeAddItemProperty(GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper), ItemPropertyAttackBonus(nEssentia), 99999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE); + IPSafeAddItemProperty(GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper), ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1), 99999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + AddEventScript(GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oMeldshaper), EVENT_ITEM_ONHIT, "moi_events", TRUE, FALSE); +} + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + effect eLink = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE); + + if (nEssentia) eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_SPOT, nEssentia*2)); + + // Add Diehard as effect + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_DIEHARD)); + + // Hands bind (Weapon Finesse) — check regular or double Hands + int nBoundToHands = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_HANDS)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_HANDS)) == nMeldId) + nBoundToHands = TRUE; + + if (nBoundToHands) + { + // Add Weapon Finesse as effect + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_WEAPON_FINESSE)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_BLOODTALONS_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item property + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_BLOODTALONS), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Totem bind (claws) — check regular or double Totem + int nBoundToTotem = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_TOTEM)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_TOTEM)) == nMeldId) + nBoundToTotem = TRUE; + + if (nBoundToTotem) + { + string sResRef = "prc_claw_1d6l_"; + int nSize = PRCGetCreatureSize(oMeldshaper); + sResRef += GetAffixForSize(nSize); + AddNaturalPrimaryWeapon(oMeldshaper, sResRef, 2); + SetLocalString(oMeldshaper, "IncarnumPrimaryAttackL", sResRef); + SetLocalInt(oMeldshaper, "ClearEventTotem", TRUE); + + // All natural attacks end up here + DelayCommand(3.0, BloodtalonsTotem(oMeldshaper, nEssentia)); + } +} + +/* #include "moi_inc_moifunc" void BloodtalonsTotem(object oMeldshaper, int nEssentia) { @@ -87,7 +157,7 @@ void main() // All natural attacks end up here DelayCommand(3.0, BloodtalonsTotem(oMeldshaper, nEssentia)); } -} +} */ /* void main() { diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_cryshlm.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_cryshlm.nss index 545305a3..da030d01 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_cryshlm.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_cryshlm.nss @@ -32,8 +32,43 @@ Your melee attacks gain the force descriptor, making them useful against incorpo //:: Double Chakra Bind support added //:; Fixed broken Brow bind //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + int nMeldId = PRCGetSpellId(); + + effect eLink = EffectSavingThrowIncrease(SAVING_THROW_WILL, 2, SAVING_THROW_TYPE_MIND_SPELLS); + + if (nEssentia) eLink = EffectLinkEffects(eLink, EffectACIncrease(nEssentia, AC_DEFLECTION_BONUS)); + + // Check for Brow bind and add Blind-Fight if bound + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_BROW)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_BROW)) == nMeldId) + { + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_BLIND_FIGHT)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_CRYSTAL_HELM_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item property + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_CRYSTAL_HELM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); +} + + +/* #include "moi_inc_moifunc" void main() { @@ -54,4 +89,4 @@ void main() ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(eLink), oMeldshaper, 9999.0); IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_CRYSTAL_HELM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_drgnfr.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_drgnfr.nss index 1e5685d6..003c7ee7 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_drgnfr.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_drgnfr.nss @@ -40,8 +40,62 @@ You can emanate an aura of frightful presence once per round as a swift action. //:: Double Totem Bind support added //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + + effect eLink = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE); + if (nEssentia) eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_SPOT, 2 * nEssentia)); + + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_LOWLIGHTVISION)); + + // Brow bind (darkvision) — check regular or double Brow + int nBoundToBrow = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_BROW)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_BROW)) == nMeldId) + nBoundToBrow = TRUE; + + if (nBoundToBrow) eLink = EffectLinkEffects(eLink, EffectUltravision()); + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_DRAGONFIRE_MASK_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_DRAGONFIRE_MASK), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Totem bind (frightful presence) — check regular or double Totem + int nBoundToTotem = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_TOTEM)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_TOTEM)) == nMeldId) + nBoundToTotem = TRUE; + + if (nBoundToTotem) + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_DRAGONFIRE_MASK_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Throat bind (breath weapon) — check regular or double Throat + int nBoundToThroat = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_THROAT)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_THROAT)) == nMeldId) + nBoundToThroat = TRUE; + + if (nBoundToThroat) + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_DRAGONFIRE_MASK_THROAT), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); +} + + +/* #include "moi_inc_moifunc" void main() { @@ -82,7 +136,7 @@ void main() if (nBoundToThroat) IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_DRAGONFIRE_MASK_THROAT), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); } - + */ /* void main() diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_frsthl.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_frsthl.nss index b064d723..82a40847 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_frsthl.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_frsthl.nss @@ -34,8 +34,60 @@ As a standard action, you can produce a trilling sound that stuns opponents with //:: Double Chakra Bind support added //:: Double Totem bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_FROST_HELM); + effect eLink = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE); + + if (nEssentia) eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_COLD, nEssentia * 5)); + + // Add Cold Endurance as tagged effect + eLink = EffectLinkEffects(eLink, EffectBonusFeat(IP_CONST_FEAT_COLD_ENDURANCE)); + + // Tag the entire effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_FROST_HELM_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item properties + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_FROST_HELM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Crown bind (cold ray) + int nBoundToCrown = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_CROWN)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_CROWN)) == nMeldId) + nBoundToCrown = TRUE; + + if (nBoundToCrown) + { + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_FROST_HELM_CROWN), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + } + + // Totem bind (stun) + int nBoundToTotem = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_TOTEM)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_TOTEM)) == nMeldId) + nBoundToTotem = TRUE; + + if (nBoundToTotem) + { + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_FROST_HELM_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + } +} + + +/* #include "moi_inc_moifunc" void main() { @@ -71,7 +123,7 @@ void main() { IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_FROST_HELM_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); } -} +} */ /* void main() { diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_impboots.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_impboots.nss index 5abd5a7d..2e740266 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_impboots.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_impboots.nss @@ -27,8 +27,41 @@ You gain the evasion ability. //:: //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + effect eLink = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE); + + if (nEssentia) eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nEssentia)); + + // Add Uncanny Dodge as effect + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_UNCANNY_DODGE_1)); + + // Check for Feet bind and add Evasion if bound + if (GetIsMeldBound(oMeldshaper) == CHAKRA_FEET || GetIsMeldBound(oMeldshaper) == CHAKRA_DOUBLE_FEET) + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_EVASION)); + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_IMPULSE_BOOTS_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item property + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_IMPULSE_BOOTS), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); +} + + +/* #include "moi_inc_moifunc" void main() { @@ -44,4 +77,4 @@ void main() if (GetIsMeldBound(oMeldshaper) == CHAKRA_FEET || GetIsMeldBound(oMeldshaper) == CHAKRA_DOUBLE_FEET) IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_FEAT_EVASION), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_lamiablt.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_lamiablt.nss index 91094f87..a79ca96a 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_lamiablt.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_lamiablt.nss @@ -34,8 +34,62 @@ The lower part of your body below your lamia belt takes on the shape of a lion, //:: Double Totem Bind support added //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + int nBonus = 4 + (nEssentia * 2); + effect eLink = EffectLinkEffects(EffectSkillIncrease(SKILL_HIDE, nBonus), EffectSkillIncrease(SKILL_BLUFF, nBonus)); + + // Waist bind (speed + Spring Attack) — check regular or double Waist + int nBoundToWaist = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_WAIST)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_WAIST)) == nMeldId) + nBoundToWaist = TRUE; + + if (nBoundToWaist) + { + // Add Spring Attack as effect using FEAT_* constant + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_SPRING_ATTACK)); + SetLocalInt(oMeldshaper, "LamiaBeltSpeed", TRUE); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_LAMIA_BELT_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item property + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_LAMIA_BELT), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Totem bind (claws) — check regular or double Totem + int nBoundToTotem = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_TOTEM)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_TOTEM)) == nMeldId) + nBoundToTotem = TRUE; + + if (nBoundToTotem) + { + string sResRef = "prc_claw_1d6l_"; + int nSize = PRCGetCreatureSize(oMeldshaper); + sResRef += GetAffixForSize(nSize); + AddNaturalSecondaryWeapon(oMeldshaper, sResRef, 2); + SetLocalString(oMeldshaper, "IncarnumSecondaryAttackL", sResRef); + } +} + + +/* #include "moi_inc_moifunc" void main() { @@ -74,7 +128,7 @@ void main() AddNaturalSecondaryWeapon(oMeldshaper, sResRef, 2); SetLocalString(oMeldshaper, "IncarnumSecondaryAttackL", sResRef); } -} +} */ /* void main() diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_maulgntl.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_maulgntl.nss index 58592e67..0b741809 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_maulgntl.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_maulgntl.nss @@ -33,8 +33,68 @@ You gain a morale bonus on unarmed strike damage equal to the morale bonus on St //:: //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + effect eLink = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE); + + // Check for Hands bind and add Improved Unarmed Strike if bound + int nBoundToHands = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_HANDS)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_HANDS)) == nMeldId) + nBoundToHands = TRUE; + + if (nBoundToHands) + { + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_IMPROVED_UNARMED_STRIKE)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_MAULING_GAUNTLETS_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_MAULING_GAUNTLETS), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Arms bind (keen) — check regular or double Arms + int nBoundToArms = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_ARMS)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_ARMS)) == nMeldId) + nBoundToArms = TRUE; + + if (nBoundToArms) + { + // Apply keen to equipped melee weapons with a tag for future use + object oWeapR = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oMeldshaper); + if (GetIsObjectValid(oWeapR) && IPGetIsMeleeWeapon(oWeapR)) + { + itemproperty ipKeen = ItemPropertyKeen(); + ipKeen = TagItemProperty(ipKeen, "moi_MaulingGauntletsKeen"); + IPSafeAddItemProperty(oWeapR, ipKeen, 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE); + } + object oWeapL = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oMeldshaper); + if (GetIsObjectValid(oWeapL) && IPGetIsMeleeWeapon(oWeapL)) + { + itemproperty ipKeen = ItemPropertyKeen(); + ipKeen = TagItemProperty(ipKeen, "moi_MaulingGauntletsKeen"); + IPSafeAddItemProperty(oWeapL, ipKeen, 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE); + } + } +} + + +/* #include "moi_inc_moifunc" void main() { @@ -79,7 +139,7 @@ void main() IPSafeAddItemProperty(oWeapL, ipKeen, 9999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, TRUE); } } -} +} */ /* void main() { diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_mntcrb.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_mntcrb.nss index 9d03cd7a..c175a942 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_mntcrb.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_mntcrb.nss @@ -34,8 +34,54 @@ As a standard action, you can snap your tail to loose a volley of spikes equal t //:: Double Chakra Bind support added //:: Double Totem bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + int nBonus = 2 + (nEssentia * 2); + effect eLink = EffectLinkEffects(EffectSkillIncrease(SKILL_SPOT, nBonus), EffectSkillIncrease(SKILL_JUMP, nBonus)); + + // Check for Waist bind and add Spring Attack if bound + int nBoundToWaist = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_WAIST)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_WAIST)) == nMeldId) + nBoundToWaist = TRUE; + + if (nBoundToWaist) + { + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_SPRING_ATTACK)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_MANTICORE_BELT_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_MANTICORE_BELT), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Totem bind (spike volley) — check regular or double Totem + int nBoundToTotem = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_TOTEM)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_TOTEM)) == nMeldId) + nBoundToTotem = TRUE; + + if (nBoundToTotem) + { + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_MANTICORE_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + } +} + +/* #include "moi_inc_moifunc" void main() { @@ -69,7 +115,7 @@ void main() { IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_MANTICORE_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); } -} +} */ /* void main() { diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_phoenix.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_phoenix.nss index 15c854e4..06e8b4fe 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_phoenix.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_phoenix.nss @@ -33,8 +33,36 @@ As a standard action, you can create a momentary ring of fire that surrounds you //:: //:: Double Totem Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + effect eLink = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE); + + if (nEssentia) eLink = EffectLinkEffects(eLink, EffectDamageResistance(DAMAGE_TYPE_FIRE, nEssentia * 5)); + + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_HEAT_ENDURANCE)); + + eLink = TagEffect(eLink, "SOULMELD_PHOENIX_BELT_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_PHOENIX_BELT), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + if (GetIsMeldBound(oMeldshaper) == CHAKRA_TOTEM || GetIsMeldBound(oMeldshaper) == CHAKRA_DOUBLE_TOTEM) + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_PHOENIX_BELT_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); +} + +/* #include "moi_inc_moifunc" void main() { @@ -50,4 +78,4 @@ void main() if (GetIsMeldBound(oMeldshaper) == CHAKRA_TOTEM || GetIsMeldBound(oMeldshaper) == CHAKRA_DOUBLE_TOTEM) IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_PHOENIX_BELT_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_thftglvs.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_thftglvs.nss index 311ffbfa..48a9ea77 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_thftglvs.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_thftglvs.nss @@ -27,8 +27,45 @@ You gain the trapfinding ability. //:: //:: Double Chakra Bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + int nBonus = 2 + (nEssentia * 2); + effect eLink = EffectLinkEffects(EffectSkillIncrease(SKILL_OPEN_LOCK, nBonus), EffectSkillIncrease(SKILL_DISABLE_TRAP, nBonus)); + eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_PICK_POCKET, nBonus)); + + // Check for Hands bind and add Trapfinding if bound + int nBoundToHands = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_HANDS)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_HANDS)) == nMeldId) + nBoundToHands = TRUE; + + if (nBoundToHands) + { + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_TRAPFINDING)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_THEFT_GLOVES_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item property + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_THEFT_GLOVES), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); +} + +/* #include "moi_inc_moifunc" void main() { @@ -50,7 +87,7 @@ void main() if (nBoundToHands) IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_FEAT_TRAPFINDING), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); -} +} */ /* void main() { diff --git a/nwn/nwnprc/trunk/newspellbook/moi_mld_wormtail.nss b/nwn/nwnprc/trunk/newspellbook/moi_mld_wormtail.nss index c649466e..efd79464 100644 --- a/nwn/nwnprc/trunk/newspellbook/moi_mld_wormtail.nss +++ b/nwn/nwnprc/trunk/newspellbook/moi_mld_wormtail.nss @@ -34,8 +34,57 @@ You can use your wormtail belt //:: Double Chakra Bind support added //:: Double Totem bind support added //:: +//:: Updated on: 2026-05-01 12:04:32 +//:: +//:: Fixed Bonus feats hanging stay around after +//:: reshaping soulmelds. +//:: //:://////////////////////////////////////////////////////// -#include "moi_inc_moifunc" +#include "moi_inc_moifunc" + +void main() +{ + object oMeldshaper = PRCGetSpellTargetObject(); + int nMeldId = PRCGetSpellId(); + int nEssentia = GetEssentiaInvested(oMeldshaper); + int nBonus = 2 + nEssentia; + effect eLink = EffectACIncrease(nBonus, AC_NATURAL_BONUS); + + // Check for Waist bind and add Awesome Blow if bound + int nBoundToWaist = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_WAIST)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_WAIST)) == nMeldId) + nBoundToWaist = TRUE; + + if (nBoundToWaist) + { + // Add Awesome Blow as effect + eLink = EffectLinkEffects(eLink, EffectBonusFeat(FEAT_AWESOME_BLOW)); + } + + // Tag the effect link for easy removal + eLink = TagEffect(eLink, "SOULMELD_WORMTAIL_BELT_FEATS"); + eLink = SupernaturalEffect(eLink); + + ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMeldshaper, 9999.0); + + // Keep meld identification as item properties + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_WORMTAIL_BELT), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + + // Totem bind (stinger) — check regular or double Totem + int nBoundToTotem = FALSE; + if (GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_TOTEM)) == nMeldId || + GetLocalInt(oMeldshaper, "BoundMeld" + IntToString(CHAKRA_DOUBLE_TOTEM)) == nMeldId) + nBoundToTotem = TRUE; + + if (nBoundToTotem) + { + IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_WORMTAIL_BELT_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); + } +} + + +/* #include "moi_inc_moifunc" void main() { @@ -69,7 +118,7 @@ void main() { IPSafeAddItemProperty(GetPCSkin(oMeldshaper), ItemPropertyBonusFeat(IP_CONST_MELD_WORMTAIL_BELT_TOTEM), 9999.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING); } -} +} */ /* void main() {