2026/01/12 Late Update

Hexblade doesn't get Shield proficency.
Forsaker gets Craft (Alchemy) and Craft (Poison) as class skills.
Forsaker can use default helms now.
Forsaker can use arms & armor made from special materials.
Fixed Dread Necromancer Spirit Worm TLK error.
Disabled AI Talent for Awesome Blow.
Fixed Warlock + Battlecaster ASF w/ Chain Shirt.
Add Material and Quality itemprops to special material crafting.
Fixed bug where breaking concentration can screw up next manifestation due to variables not being cleared.
Tweaked Defensive Manifestation.
Hexblades can't cast in heavy armor.
+1 Attack Bonus from Masterwork is removed after enchantment to +1.
Fixed issue where Forsaker's Ability Boost would stack with each login.
Tweaked Celebrant of Sharess TLK entry.
Tweaked Soulblade Warrior TLK entry.
Tweaked Vow of Poverty's TLK entry.
This commit is contained in:
Jaysyn904
2026-01-14 00:12:38 -05:00
parent 2961d49e7d
commit 06931be120
17 changed files with 640 additions and 100 deletions

View File

@@ -806,7 +806,14 @@ void CraftingHB(object oPC, object oItem, itemproperty ip, int nCost, int nXP, s
FloatingTextStringOnCreature("Crafting Complete!", oPC);
DeleteLocalInt(oPC, PRC_CRAFT_HB);
//if(GetIsItemPropertyValid(ip))
ApplyProperties(oPC, oItem, ip, nCost, nXP, sFile, nLine);
ApplyProperties(oPC, oItem, ip, nCost, nXP, sFile, nLine);
if(GetLocalInt(oPC, "PRC_CRAFT_REMOVE_MASTERWORK"))
{
RemoveMasterworkProperties(oItem);
DeleteLocalInt(oPC, "PRC_CRAFT_REMOVE_MASTERWORK");
}
if(sFile == "craft_golem")
{
}
@@ -1874,12 +1881,18 @@ void main()
int bCheck = FALSE;
TakeGoldFromCreature(GetLocalInt(oPC, PRC_CRAFT_COST), oPC, TRUE);
if(GetCraftingFeat(oNewItem) != FEAT_CRAFT_ARMS_ARMOR)
CopyItem(oNewItem, oPC, TRUE);
{
SetLocalInt(oPC, "PRC_CRAFT_REMOVE_MASTERWORK", TRUE);
CopyItem(oNewItem, oPC, TRUE);
}
else if(GetIsSkillSuccessful(oPC, nSkill, GetCraftingDC(oNewItem)))
{
bCheck = (nMaterial & PRC_CRAFT_FLAG_MASTERWORK) ? GetIsSkillSuccessful(oPC, nSkill, 20) : TRUE;
if(bCheck)
CopyItem(oNewItem, oPC, TRUE);
{
SetLocalInt(oPC, "PRC_CRAFT_REMOVE_MASTERWORK", TRUE);
CopyItem(oNewItem, oPC, TRUE);
}
}
AllowExit(DYNCONV_EXIT_FORCE_EXIT);
}
@@ -2147,8 +2160,6 @@ void main()
break;
}
/*
case <CONSTANT>:
{

View File

@@ -78,7 +78,34 @@ void main()
// should be handled transparently by the system
if(DEBUG) DoDebug("prc_forsake_abil: ERROR: Conversation abort section run");
}
// Handle PC response
// Handle PC response
else
{
int nChoice = GetChoice(oPC);
if(DEBUG) DoDebug("prc_forsake_abil: Handling PC response, stage = " + IntToString(nStage) + "; nChoice = " +
IntToString(nChoice) + "; choice text = '" + GetChoiceText(oPC) + "'");
if(nStage == STAGE_SELECT_ABIL)
{
if(DEBUG) DoDebug("prc_forsake_abil: nChoice: " + IntToString(nChoice));
effect eAbility = EffectAbilityIncrease(nChoice, 1);
eAbility = UnyieldingEffect(eAbility);
eAbility = TagEffect(eAbility, "ForsakerAbilityBoost");
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAbility, oPC); //Give the boost
SetPersistantLocalInt(oPC, "ForsakerBoost"+IntToString(nClass), nChoice+1); //Register the boost has been given
DeletePersistantLocalInt(oPC,"ForsakerBoostCheck");
// And we're all done
AllowExit(DYNCONV_EXIT_FORCE_EXIT);
}
if(DEBUG) DoDebug("prc_forsake_abil: New stage: " + IntToString(nStage));
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
/* // Handle PC response
else
{
int nChoice = GetChoice(oPC);
@@ -100,5 +127,5 @@ void main()
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
} */
}

View File

@@ -121,8 +121,94 @@ void main()
// Item is a creature weapon, allow it
return;
}
// Check if the item being equipped is magical
// Only check the item being equipped, not entire inventory
int bIsMagical = FALSE;
int nPropertyCount = 0;
itemproperty ipCheck = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(ipCheck))
{
string sTag = GetItemPropertyTag(ipCheck);
int nType = GetItemPropertyType(ipCheck);
// Check for protected properties
if(sTag == "Tag_PRC_OnHitKeeper" ||
sTag == "Quality_Masterwork" ||
sTag == "Material_Mithral" ||
sTag == "Material_Adamantine" ||
sTag == "Material_Darkwood" ||
sTag == "Material_ColdIron" ||
sTag == "Material_MundaneCrystal" ||
sTag == "Material_DeepCrystal" ||
nType == ITEM_PROPERTY_MATERIAL) // All material properties
{
// Protected property - skip, don't set bIsMagical
}
else
{
// Check for helmet carveout: +1 Concentration only
if(GetBaseItemType(oItem) == BASE_ITEM_HELMET &&
GetItemPropertyType(ipCheck) == ITEM_PROPERTY_SKILL_BONUS &&
GetItemPropertySubType(ipCheck) == SKILL_CONCENTRATION &&
GetItemPropertyCostTableValue(ipCheck) == 1)
{
// This is a +1 Concentration helmet with no other properties, allow it
bIsMagical = FALSE;
break;
}
else
{
bIsMagical = TRUE;
break;
}
}
ipCheck = GetNextItemProperty(oItem);
}
// Check if the item being equipped is magical
/* while (GetIsItemPropertyValid(ipCheck))
{
// Skip protected properties
if(GetItemPropertyTag(ipCheck) != "Tag_PRC_OnHitKeeper")
{
nPropertyCount++;
// Check for helmet carveout: +1 Concentration only
if(GetBaseItemType(oItem) == BASE_ITEM_HELMET &&
nPropertyCount == 1 &&
GetItemPropertyType(ipCheck) == ITEM_PROPERTY_SKILL_BONUS &&
GetItemPropertySubType(ipCheck) == SKILL_CONCENTRATION &&
GetItemPropertyCostTableValue(ipCheck) == 1)
{
// This is a +1 Concentration helmet with no other properties, allow it
bIsMagical = FALSE;
break;
}
else
{
bIsMagical = TRUE;
break;
}
}
ipCheck = GetNextItemProperty(oItem);
} */
// Apply torch exclusion here (after magical item determination)
if(bIsMagical && GetResRef(oItem) == "nw_it_torch001")
{
bIsMagical = FALSE;
}
// If item is magical, unequip it
if(bIsMagical)
{
AssignCommand(oPC, ClearAllActions(TRUE));
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
/* // Check if the item being equipped is magical
// Only check the item being equipped, not entire inventory
int bIsMagical = FALSE;
itemproperty ipCheck = GetFirstItemProperty(oItem);
@@ -144,7 +230,7 @@ void main()
AssignCommand(oPC, ActionUnequipItem(oItem));
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
}
// If non-magical weapon and Forsaker has DR bypass, add bonuses
*/ // If non-magical weapon and Forsaker has DR bypass, add bonuses
else if(!bIsMagical && (IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem)) && (nForsakerLvl >= 3))
{
// Add DR bypass bonuses to non-magical weapons
@@ -167,7 +253,8 @@ void main()
}
}
}
// We are called from the OnPlayerUnEquipItem eventhook. Clean up Forsaker properties
// We are called from the OnPlayerUnEquipItem eventhook. Clean up Forsaker properties
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
{
oPC = GetItemLastUnequippedBy();

View File

@@ -10,22 +10,32 @@
#include "prc_inc_template"
#include "prc_inc_factotum"
void RestoreForsakerAbilities(object oPC)
{
int nForsakerLevel = GetLevelByClass(CLASS_TYPE_FORSAKER, oPC);
int i;
for(i = 1; i <= nForsakerLevel; i++)
{
int nAbility = GetPersistantLocalInt(oPC, "ForsakerBoost" + IntToString(i));
if(nAbility > 0 && nAbility <= 6)
{
effect eAbility = EffectAbilityIncrease(nAbility - 1, 1);
eAbility = SupernaturalEffect(eAbility);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAbility, oPC);
}
}
void RestoreForsakerAbilities(object oPC)
{
int nForsakerLevel = GetLevelByClass(CLASS_TYPE_FORSAKER, oPC);
int i;
// Remove existing Forsaker ability effects first
effect eLoop = GetFirstEffect(oPC);
while(GetIsEffectValid(eLoop))
{
if(GetEffectTag(eLoop) == "ForsakerAbilityBoost")
RemoveEffect(oPC, eLoop);
eLoop = GetNextEffect(oPC);
}
for(i = 1; i <= nForsakerLevel; i++)
{
int nAbility = GetPersistantLocalInt(oPC, "ForsakerBoost" + IntToString(i));
if(nAbility > 0 && nAbility <= 6)
{
effect eAbility = EffectAbilityIncrease(nAbility - 1, 1);
eAbility = SupernaturalEffect(eAbility);
eAbility = TagEffect(eAbility, "ForsakerAbilityBoost"); // Add tag for removal
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAbility, oPC);
}
}
}
/**