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

@@ -39,8 +39,10 @@ int InvocationASFCheck(object oInvoker, int nClass)
case 1: nASF -= 5; break;//light
case 2: nASF -= 10; break;//light
case 3: nASF -= 20; break;//light
case 4: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 20 : 0; break;//medium;
case 5: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 30 : 0; break;//medium
//case 4: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 20 : 0; break; //medium;
//case 5: nASF -= GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 30 : 0; break; //medium
case 4: nASF = GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 0 : nASF; break; //medium
case 5: nASF = GetHasFeat(FEAT_BATTLE_CASTER, oInvoker) ? 0 : nASF; break; //medium;
default: break;
}
}

View File

@@ -1808,6 +1808,11 @@ int GetCraftingDC(object oItem)
void MakeMasterwork(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
itemproperty ip = ItemPropertyQuality(IP_CONST_QUALITY_MASTERWORK);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
int nBase = GetBaseItemType(oItem);
if((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) ||
@@ -1817,6 +1822,70 @@ void MakeMasterwork(object oItem)
{
//no armour check penalty here
if(GetItemArmourCheckPenalty(oItem) == 0) return;
ip = ItemPropertySkillBonus(SKILL_BALANCE, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_CLIMB, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_HIDE, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_PICK_POCKET, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_SET_TRAP, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_TUMBLE, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_JUMP, 1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
else if(GetWeaponType(nBase))
{
ip = ItemPropertyAttackBonus(1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
else if(StringToInt(Get2DACache("prc_craft_gen_it", "Type", nBase)) == PRC_CRAFT_ITEM_TYPE_AMMO)
{
ip = ItemPropertyAttackBonus(1);
ip = TagItemProperty(ip, "Quality_Masterwork");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
else
return;
}
/* void MakeMasterwork(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
int nBase = GetBaseItemType(oItem);
if((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD)
)
{
//no armour check penalty here
if(GetItemArmourCheckPenalty(oItem) == 0) return;
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_HIDE, 1) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, 1), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oItem, ItemPropertySkillBonus(SKILL_PICK_POCKET, 1) , 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
@@ -1830,17 +1899,226 @@ void MakeMasterwork(object oItem)
}
else if(StringToInt(Get2DACache("prc_craft_gen_it", "Type", nBase)) == PRC_CRAFT_ITEM_TYPE_AMMO)
{
/*
int nDamageType = (nBase == BASE_ITEM_BULLET) ? DAMAGE_TYPE_BLUDGEONING : DAMAGE_TYPE_PIERCING;
itemproperty ip1 = ItemPropertyDamageBonus(nDamageType, IP_CONST_DAMAGEBONUS_1);
*/
//int nDamageType = (nBase == BASE_ITEM_BULLET) ? DAMAGE_TYPE_BLUDGEONING : DAMAGE_TYPE_PIERCING;
//itemproperty ip1 = ItemPropertyDamageBonus(nDamageType, IP_CONST_DAMAGEBONUS_1);
IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(1), 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
}
else
return;
}
*/
void MakeAdamantine(object oItem)
void MakeAdamantine(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
{
int nBonus = 0;
switch(GetItemBaseAC(oItem))
{
case 1:
case 2:
case 3: nBonus = IP_CONST_DAMAGERESIST_1; break;
case 4:
case 5: nBonus = IP_CONST_DAMAGERESIST_2; break;
case 6:
case 7:
case 8: nBonus = IP_CONST_DAMAGERESIST_3; break;
}
if(nBonus)
{
itemproperty ip = ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_BLUDGEONING, nBonus);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_PIERCING, nBonus);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyDamageResistance(IP_CONST_DAMAGETYPE_SLASHING, nBonus);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyMaterial(IP_MATERIAL_ADAMANTINE);
ip = TagItemProperty(ip, "Material_Adamantine");
IPSafeAddItemProperty(oItem, ip, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
}
void MakeDarkwood(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
itemproperty ip = ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
int nBase = GetBaseItemType(oItem);
if(((nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD))
)
{
int nBonus = 2;
if(nBase == BASE_ITEM_SMALLSHIELD) nBonus = 1;
ip = ItemPropertySkillBonus(SKILL_BALANCE, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_CLIMB, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_HIDE, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_PICK_POCKET, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_TUMBLE, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_JUMP, nBonus);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyMaterial(IP_MATERIAL_WOOD_DARKWOOD_ZALANTAR);
ip = TagItemProperty(ip, "Material_Darkwood");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
void MakeDragonhide(object oItem)
{
//Does nothing so far
}
void MakeMithral(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
itemproperty ip = ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
int nBase = GetBaseItemType(oItem);
if(GetWeaponType(nBase))
{
ip = ItemPropertyMaterial(IP_MATERIAL_MITHRAL);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
else if(((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD))
)
{
int nBonus = 3;
int nPenalty = GetItemArmourCheckPenalty(oItem);
if(nBonus > nPenalty) nBonus = nPenalty;
ip = ItemPropertySkillBonus(SKILL_BALANCE, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_CLIMB, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_HIDE, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_MOVE_SILENTLY, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_PICK_POCKET, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_SET_TRAP, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_TUMBLE, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertySkillBonus(SKILL_JUMP, nBonus);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
ip = ItemPropertyMaterial(IP_MATERIAL_MITHRAL);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
if(GetItemBaseAC(oItem) == 1)
{
ip = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
else
{
ip = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT);
ip = TagItemProperty(ip, "Material_Mithral");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
}
void MakeColdIron(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_COLD_IRON);
ip = TagItemProperty(ip, "Material_ColdIron");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeSilver(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_SILVER);
ip = TagItemProperty(ip, "Material_ColdIron");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeMundaneCrystal(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_MUNDANE);
ip = TagItemProperty(ip, "Material_MundaneCrystal");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeDeepCrystal(object oItem)
{
//Does nothing so far
itemproperty ip = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_DEEP);
ip = TagItemProperty(ip, "Material_DeepCrystal");
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
/* void MakeAdamantine(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
if(GetBaseItemType(oItem) == BASE_ITEM_ARMOR)
@@ -1867,9 +2145,9 @@ void MakeAdamantine(object oItem)
IPSafeAddItemProperty(oItem, ipAdamantine, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
}
} */
void MakeDarkwood(object oItem)
/* void MakeDarkwood(object oItem)
{
if(GetPlotFlag(oItem)) return; //sanity check
IPSafeAddItemProperty(oItem, ItemPropertyWeightReduction(IP_CONST_REDUCEDWEIGHT_50_PERCENT), 0.0, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
@@ -1892,8 +2170,9 @@ void MakeDarkwood(object oItem)
IPSafeAddItemProperty(oItem, ipDarkwood, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
*/
void MakeDragonhide(object oItem)
/* void MakeDragonhide(object oItem)
{
//Does nothing so far
}
@@ -1929,35 +2208,40 @@ void MakeMithral(object oItem)
IPSafeAddItemProperty(oItem, ipMithral, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
}
*/
void MakeColdIron(object oItem)
/* void MakeColdIron(object oItem)
{
//Does nothing so far
itemproperty ipColdIron = ItemPropertyMaterial(IP_MATERIAL_COLD_IRON);
IPSafeAddItemProperty(oItem, ipColdIron, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
*/
void MakeSilver(object oItem)
/* void MakeSilver(object oItem)
{
//Does nothing so far
itemproperty ipSilver = ItemPropertyMaterial(IP_MATERIAL_SILVER);
IPSafeAddItemProperty(oItem, ipSilver, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
void MakeMundaneCrystal(object oItem)
*/
/* void MakeMundaneCrystal(object oItem)
{
//Does nothing so far
itemproperty ipCrystal = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_MUNDANE);
IPSafeAddItemProperty(oItem, ipCrystal, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
*/
void MakeDeepCrystal(object oItem)
/* void MakeDeepCrystal(object oItem)
{
//Does nothing so far
itemproperty ipDeepCrystal = ItemPropertyMaterial(IP_MATERIAL_GEM_CRYSTAL_DEEP);
IPSafeAddItemProperty(oItem, ipDeepCrystal, 0.0f, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
*/
//Creates an item on oOwner, from the baseitemtype and base AC (for armour)
object CreateStandardItem(object oOwner, int nBaseItemType, int nBaseAC = -1)
{
@@ -2985,4 +3269,4 @@ int ITEM_APPR_WEAPON_COLOR_MIDDLE = 1;
int ITEM_APPR_WEAPON_COLOR_TOP = 2;
*/
// void main () {}
//:: void main () {}

View File

@@ -120,6 +120,10 @@ const int PRC_GEM_PERLEVEL = 6;
// Craft Skull Talisman constants
const int PRC_SKULL_BASECOST = 7;
int GetWeaponType(int nBaseItem);
void RemoveMasterworkProperties(object oItem);
// * Returns TRUE if an item is a Craft Base Item
// * to be used in spellscript that can be cast on items - i.e light
int CIGetIsCraftFeatBaseItem( object oItem );
@@ -214,6 +218,78 @@ int CICraftCheckCreateInfusion(object oSpellTarget, object oCaster, int nID = 0)
/* Function definitions */
//////////////////////////////////////////////////
void RemoveMasterworkProperties(object oItem)
{
if(DEBUG) DoDebug("RemoveMasterworkProperties() called on: " + DebugObject2Str(oItem));
int nBase = GetBaseItemType(oItem);
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Item base type: " + IntToString(nBase));
int nRemoved = 0;
// For armor/shields: remove only the Quality property, keep skill bonuses
if((nBase == BASE_ITEM_ARMOR) ||
(nBase == BASE_ITEM_SMALLSHIELD) ||
(nBase == BASE_ITEM_LARGESHIELD) ||
(nBase == BASE_ITEM_TOWERSHIELD))
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Processing armor/shield");
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
string sTag = GetItemPropertyTag(ip);
int nType = GetItemPropertyType(ip);
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Found property - Type: " + IntToString(nType) +
", Tag: " + sTag +
", String: " + DebugIProp2Str(ip));
if(sTag == "Quality_Masterwork" && nType == ITEM_PROPERTY_QUALITY)
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Removing Quality property");
RemoveItemProperty(oItem, ip);
nRemoved++;
ip = GetFirstItemProperty(oItem); // Restart iteration
continue;
}
ip = GetNextItemProperty(oItem);
}
}
// For weapons/ammo: remove both Quality and Attack Bonus properties
if(GetWeaponType(nBase) ||
StringToInt(Get2DACache("prc_craft_gen_it", "Type", nBase)) == 4)
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Processing weapon/ammo");
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
string sTag = GetItemPropertyTag(ip);
int nType = GetItemPropertyType(ip);
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Found property - Type: " + IntToString(nType) +
", Tag: " + sTag +
", String: " + DebugIProp2Str(ip));
// Check for both Quality and Attack Bonus with Quality_Masterwork tag
if(sTag == "Quality_Masterwork" &&
(nType == ITEM_PROPERTY_QUALITY || nType == ITEM_PROPERTY_ATTACK_BONUS))
{
if(DEBUG) DoDebug("prc_x2_craft >> RemoveMasterworkProperties(): Removing property type " + IntToString(nType));
RemoveItemProperty(oItem, ip);
nRemoved++;
ip = GetFirstItemProperty(oItem); // Restart iteration
continue;
}
ip = GetNextItemProperty(oItem);
}
}
if(DEBUG) DoDebug("prc_x2_craft: RemoveMasterworkProperties() completed. Removed " +
IntToString(nRemoved) + " properties.");
}
// * Returns the innate level of a spell. If bDefaultZeroToOne is given
// * Level 0 spell will be returned as level 1 spells
@@ -2416,8 +2492,8 @@ int CIDoCraftItemFromConversation(int nNumber)
DeleteLocalObject(oPC,"X2_CI_CRAFT_MAJOR");
DeleteLocalObject(oPC,"X2_CI_CRAFT_MINOR");
if (!GetIsObjectValid(oMajor))
if (!GetIsObjectValid(oMajor))
{
FloatingTextStrRefOnCreature(83374,oPC); //"Invalid target"
DeleteLocalInt(oPC,"X2_CRAFT_SUCCESS");
@@ -2472,7 +2548,7 @@ int CIDoCraftItemFromConversation(int nNumber)
{
oContainer = GetItemPossessedBy(oPC,"x2_it_craftcont");
}
// Do the crafting...
object oRet = CIUseCraftItemSkill( oPC, nSkill, stItem.sResRef, stItem.nDC, oContainer) ;
@@ -2481,7 +2557,9 @@ int CIDoCraftItemFromConversation(int nNumber)
if (GetIsObjectValid(oRet))
{
// -----------------------------------------------------------------------
RemoveMasterworkProperties(oMajor);
// -----------------------------------------------------------------------
// Copy all item properties from the major object on the resulting item
// Through we problably won't use this, its a neat thing to have for the
// community
@@ -2499,7 +2577,8 @@ int CIDoCraftItemFromConversation(int nNumber)
{
//TakeGoldFromCreature(stItem.nCost, oPC,TRUE);
SpendGP(oPC, stItem.nCost);
IPCopyItemProperties(oMajor,oRet);
RemoveMasterworkProperties(oMajor);
IPCopyItemProperties(oMajor,oRet);
}
// set success variable for conversation
SetLocalInt(oPC,"X2_CRAFT_SUCCESS",TRUE);

View File

@@ -557,6 +557,9 @@ void _ManifestationHB(object oManifester, location lManifester, object oMfToken)
{
if(DEBUG) DoDebug("_ManifestationHB(): Manifester moved or lost concentration, destroying token");
_DestroyManifestationToken(oManifester, oMfToken);
//:: Clean up variables
_CleanManifestationVariables(oManifester);
// Inform manifester
FloatingTextStrRefOnCreature(16828435, oManifester, FALSE); // "You have lost concentration on the power you were attempting to manifest!"
@@ -810,6 +813,25 @@ struct manifestation EvaluateManifestation(object oManifester, object oTarget, s
manif.bCanManifest = FALSE;
}
// Check defensive manifestation BEFORE PP deduction
if(GetLocalInt(oManifester, "PRC_DefensiveManifestActive"))
{
int nPowerLevel = GetPowerLevel(oManifester);
int nDC = 15 + nPowerLevel;
if(!GetPRCIsSkillSuccessful(oManifester, SKILL_CONCENTRATION, nDC))
{
// Failed - deduct PP and prevent manifestation
LosePowerPoints(oManifester, manif.nPPCost, TRUE);
PayMetapsionicsFocuses(manif);
manif.bCanManifest = FALSE;
SendMessageToPC(oManifester, "Defensive manifestation concentration check failed.");
return manif;
}
manif.bDefensive = TRUE;
}
// Psi-like abilities ignore PP costs and metapsi
if(!bIsPsiLike)
{
@@ -820,7 +842,7 @@ struct manifestation EvaluateManifestation(object oManifester, object oTarget, s
PayMetapsionicsFocuses(manif);
}
if(GetLocalInt(oManifester, "PRC_DefensiveManifestActive"))
/* if(GetLocalInt(oManifester, "PRC_DefensiveManifestActive"))
{
// Concentration check (DC 15 + power level)
int nPowerLevel = GetPowerLevel(oManifester);
@@ -837,7 +859,7 @@ struct manifestation EvaluateManifestation(object oManifester, object oTarget, s
// Set defensive flag for any other systems that need it
SendMessageToPC(oManifester, "Defensive manifestion concentration check successful.");
manif.bDefensive = TRUE;
}
} */
//* APPLY SIDE-EFFECTS THAT RESULT FROM SUCCESSFULL MANIFESTATION HERE *//
// Psicraft for all those who can see
@@ -1118,4 +1140,4 @@ struct manifestation EvaluateDiaDragChannel(object oManifester, object oTarget,
}
// Test main
//void main(){}
//:: void main(){}

View File

@@ -327,8 +327,25 @@ int ArcaneSpellFailure(object oCaster, int nCastingClass, int nSpellLevel, int n
default: break;
}
}
// Hexblade can cast in light/medium armour and while using small shield.
else if(nCastingClass == CLASS_TYPE_HEXBLADE)
// Hexblade can cast in light armour only.
else if(nCastingClass == CLASS_TYPE_HEXBLADE)
{
//armors
switch(nAC)
{
case 1: nASF -= 5; break; //light
case 2: nASF -= 10; break; //light
case 3: nASF -= 20; break; //light
case 4: nASF = bBattleCaster ? 0 : nASF; break; //medium with Battlecaster
case 5: nASF = bBattleCaster ? 0 : nASF; break; //medium with Battlecaster
default: break;
}
}
// WRONG: Hexblade can cast in light/medium armour and while using small shield.
//:: RIGHT: Hexblades are proficient with all simple and martial weapons, and with light armor but not with shields.
/* else if(nCastingClass == CLASS_TYPE_HEXBLADE)
{
//shields
if(GetBaseItemType(oShield) == BASE_ITEM_SMALLSHIELD) nASF -= 5;
@@ -345,7 +362,7 @@ int ArcaneSpellFailure(object oCaster, int nCastingClass, int nSpellLevel, int n
case 8: nASF -= bBattleCaster ? 45 : 0; break;
default: break;
}
}
} */
// Bards cannot cast in light armour and while using small shield in 3e
/* else if(nCastingClass == CLASS_TYPE_BARD)
{