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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 () {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(){}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user