UW2_PRC8/_module/nss/sf_socket_inc.nss
Jaysyn904 5197ad9a4d Initial upload
Initial upload
2023-09-25 20:24:01 -04:00

713 lines
26 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Scarface's Socketed Items include
//:: V1.9
//:: sf_socket_inc
//:://////////////////////////////////////////////
/*
Written By Scarface
*/
//////////////////////////////////////////////////
#include "x2_inc_itemprop"
//////////////////////////////////////////////////
//:: Global Constants
//:: These constants can be set to your liking
//::
//:: NOTE:
//:: Do NOT set the constants higher than the
//:: maximum specified otherwise the system
//:: will fail to function correctly.
//////////////////////////////////////////////////
// Use this switch to decide if you want to allow a gem to
// be socketed even if one of the same type is already occupying
// a socket.
// Note: this obviously won't work with haste, keen etc.
// TRUE = Allow stacking : FALSE = No stacking
const int STACKABLE_GEMS = TRUE;
// If this switch is set TRUE then stackable gems will share a slot with
// another gem of the same type.
// If set FALSE then gems of the same type will take their own slot.
// However the gem will still be stacked in either case based on
// the STACKABLE_GEMS switch.
// Ignore this switch if STACKABLE_GEMS is set FALSE.
const int STACKABLE_GEMS_SHARE_SLOT = TRUE;
// Maximum Attack Bonus allowed on a weapon
// Do NOT set this higher than 20
const int MAX_ATTACK_BONUS = 18;
// Maximum Damage Bonus allowed on a weapon
// Use the dice roll damage DAMAGE_BONUS_* constants
// at the top of this script.
// Minimum allowed is DAMAGE_BONUS_1d4.
// Maximum allowed is DAMAGE_BONUS_2d12.
const int MAX_DAMAGE_BONUS = DAMAGE_BONUS_2d12;
// Maximum Enhancement Bonus allowed on a weapon
// Do NOT set this higher than 20
const int MAX_ENHANCEMENT_BONUS = 16;
// Maximum AC Bonus allowed on armour type items
// Do NOT set this higher than 20
const int MAX_AC_BONUS = 8;
// Maximum Damage Resistance allowed on armour type items
// The only values you can use for this to function
// correctly is: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50
const int MAX_DAMAGE_RESIST = 30; // XX/-
// Maximum Regeneration Bonus allowed on armour type items
// Do NOT set this higher than 20
const int MAX_REGEN_BONUS = 8;
// Maximum Ability Bonus allowed on armour type items
// Do NOT set this higher than 12
const int MAX_ABILITY_BONUS = 12;
// Maximum Vampiric allowed on a weapon
// Do NOT set this higher than 20
const int MAX_VAMP_REGEN_BONUS = 16;
// Maximum Massive Critical allowed on a weapon
// Use the dice roll damage DAMAGE_BONUS_* constants
// at the top of this script.
// Minimum allowed is DAMAGE_BONUS_1d4.
// Maximum allowed is DAMAGE_BONUS_2d12.
const int MAX_MASS_CRITS = DAMAGE_BONUS_2d12;
////////////////////////////////////////////////////////////////////////////////
//:: Required Constants from the 2da
//:: Do NOT touch anything below!!!
////////////////////////////////////////////////////////////////////////////////
const int IPRP_BONUSCOST = 1; // Bonus
const int IPRP_MELEECOST = 2; // Melee
const int IPRP_DAMAGECOST = 4; // Damage
const int IPRP_RESISTCOST = 7; // DamageResist
/*
For possible later use
const int IPRP_SOAKCOST = 6; // DamageSoak
const int IPRP_SRCOST = 11; // SpellResist
*/
// For debugging
const int DEBUG_MODE = TRUE;
////////////////////////////////////////////////////////////////////////////////
//:: Declair Functions
//:: Do NOT touch anything below!!!
////////////////////////////////////////////////////////////////////////////////
int SF_GetNextDamageBonusAmount(int iAmount);
int SF_GetMatchingItemProperty(object oItem, int iType, int iSubType = -1);
int SF_DamageBonusValueConstToInt(int iCostTableValue);
int SF_GetMatchingCostTableConst(itemproperty ipProp, int iCostTable);
int SF_DamageResistValueConstToInt(int iCostTableValue);
int SF_GetIsMeleeWeapon(object oItem, object oPC);
int SF_GetIsArmourType(object oItem, object oPC);
int SF_GetIsSocketUpgradable(object oPC, int iBonus, int iSockets);
void SF_GetSocketsLeft(object oItem, object oPC);
void SF_DecrementSocket(object oPC, object oItem, object oTarget, int iSockets, int iBonus);
void SF_SocketAttackBonusGem(object oItem, object oTarget, object oPC);
void SF_SocketDamageBonusGem(object oItem, object oTarget, object oPC, int iDamType);
void SF_SocketEnhancementBonusGem(object oItem, object oTarget, object oPC);
void SF_SocketKeenGem(object oItem, object oTarget, object oPC);
void SF_SocketACBonusGem(object oItem, object oTarget, object oPC);
void SF_SocketDamageResistGem(object oItem, object oTarget, object oPC, int iDamType);
void SF_SocketHasteGem(object oItem, object oTarget, object oPC);
void SF_SocketFreedomGem(object oItem, object oTarget, object oPC);
void SF_SocketImprovedEvasionGem(object oItem, object oTarget, object oPC);
void SF_SocketRegenerationGem(object oItem, object oTarget, object oPC);
void SF_SocketAbilityBonusGem(object oItem, object oTarget, object oPC, int iAbility);
void SF_SocketTrueSeeingGem(object oItem, object oTarget, object oPC);
void SF_SocketHolyAvengerGem(object oItem, object oTarget, object oPC);
void SF_SocketVampiricRegenerationGem(object oItem, object oTarget, object oPC);
////////////////////////////////////////////////////////////////////////////////
//:: Main Functions
//:: Do NOT touch anything below!!!
////////////////////////////////////////////////////////////////////////////////
int SF_GetNextDamageBonusAmount(int iAmount)
{
if (DEBUG_MODE)
{
SendMessageToPC(GetFirstPC(), "SF_GetNextDamageBonusAmount Before = " + IntToString(iAmount));
}
switch (iAmount)
{
case -1:
case 0: iAmount = DAMAGE_BONUS_1d4; break;
case 21: iAmount = DAMAGE_BONUS_1d6; break;
case 22: iAmount = DAMAGE_BONUS_1d8; break;
case 23: iAmount = DAMAGE_BONUS_1d10; break;
case 24: iAmount = DAMAGE_BONUS_1d12; break;
case 25: iAmount = DAMAGE_BONUS_2d4; break;
case 26: iAmount = DAMAGE_BONUS_2d6; break;
case 27: iAmount = DAMAGE_BONUS_2d8; break;
case 28: iAmount = DAMAGE_BONUS_2d10; break;
case 29: iAmount = DAMAGE_BONUS_2d12; break;
case 30: iAmount = 99; break;
default: iAmount = -99; break;
}
if (DEBUG_MODE)
{
SendMessageToPC(GetFirstPC(), "SF_GetNextDamageBonusAmount After = " + IntToString(iAmount));
}
return iAmount;
}
int SF_DamageBonusValueConstToInt(int iCostTableValue)
{
switch(iCostTableValue)
{
case 1: iCostTableValue = 1; break;
case 2: iCostTableValue = 2; break;
case 3: iCostTableValue = 3; break;
case 4: iCostTableValue = 4; break;
case 5: iCostTableValue = 5; break;
case 6: iCostTableValue = 21; break; // 1d4
case 7: iCostTableValue = 22; break; // 1d6
case 8: iCostTableValue = 23; break; // 1d8
case 9: iCostTableValue = 24; break; // 1d10
case 10: iCostTableValue = 27; break; // 2d6
case 11: iCostTableValue = 28; break; // 2d8
case 12: iCostTableValue = 26; break; // 2d4
case 13: iCostTableValue = 29; break; // 2d10
case 14: iCostTableValue = 25; break; // 1d12
case 15: iCostTableValue = 30; break; // 2d12
case 16: iCostTableValue = 6; break;
case 17: iCostTableValue = 7; break;
case 18: iCostTableValue = 8; break;
case 19: iCostTableValue = 9; break;
case 20: iCostTableValue = 10; break;
case 21: iCostTableValue = 11; break;
case 22: iCostTableValue = 12; break;
case 23: iCostTableValue = 13; break;
case 24: iCostTableValue = 14; break;
case 25: iCostTableValue = 15; break;
case 26: iCostTableValue = 16; break;
case 27: iCostTableValue = 17; break;
case 28: iCostTableValue = 18; break;
case 29: iCostTableValue = 19; break;
case 30: iCostTableValue = 20; break;
default: iCostTableValue = -1; break;
}
return iCostTableValue;
}
int SF_DamageResistValueConstToInt(int iCostTableValue)
{
switch(iCostTableValue)
{
case 1: iCostTableValue = 5; break;
case 2: iCostTableValue = 10; break;
case 3: iCostTableValue = 15; break;
case 4: iCostTableValue = 20; break;
case 5: iCostTableValue = 25; break;
case 6: iCostTableValue = 30; break;
case 7: iCostTableValue = 35; break;
case 8: iCostTableValue = 40; break;
case 9: iCostTableValue = 45; break;
case 10: iCostTableValue = 50; break;
default: iCostTableValue = -1; break;
}
return iCostTableValue;
}
int SF_GetMatchingItemProperty(object oItem, int iType, int iSubType = -1)
{
if (DEBUG_MODE)
{
SendMessageToPC(GetFirstPC(), "int iType: " + IntToString(iType) + " int iSubType: " + IntToString(iSubType));
}
itemproperty ipProp = GetFirstItemProperty(oItem);
int iCostTable, iCostValue, iMatchType, iMatchSubType;
while (GetIsItemPropertyValid(ipProp))
{
iMatchType = GetItemPropertyType(ipProp);
iMatchSubType = GetItemPropertySubType(ipProp);
if (DEBUG_MODE)
{
SendMessageToPC(GetFirstPC(), "iMatchType = " + IntToString(iMatchType) +
" iMatchSubType = " + IntToString(iMatchSubType));
}
if ((iMatchType == iType && iMatchSubType == iSubType) ||
iMatchType == iType && iMatchSubType == 65535)
{
iCostTable = GetItemPropertyCostTable(ipProp);
iCostValue = SF_GetMatchingCostTableConst(ipProp, iCostTable);
if (DEBUG_MODE)
{
SendMessageToPC(GetFirstPC(), "iCostTable = " + IntToString(iCostTable) +
" iCostValue = " + IntToString(iCostValue));
}
return iCostValue;
}
ipProp = GetNextItemProperty(oItem);
}
return FALSE;
}
int SF_GetMatchingCostTableConst(itemproperty ipProp, int iCostTable)
{
int iCostTableValue = GetItemPropertyCostTableValue(ipProp);
switch(iCostTable)
{
case IPRP_DAMAGECOST: iCostTable = SF_DamageBonusValueConstToInt(iCostTableValue); break;
case IPRP_BONUSCOST:
case IPRP_MELEECOST: iCostTable = iCostTableValue; break;
case IPRP_RESISTCOST: iCostTable = SF_DamageResistValueConstToInt(iCostTableValue); break;
default: iCostTable = -1;
}
return iCostTable;
}
int SF_GetDamageResistance(int iAmount)
{
switch (iAmount)
{
case 5: iAmount = IP_CONST_DAMAGERESIST_5; break;
case 10: iAmount = IP_CONST_DAMAGERESIST_10; break;
case 15: iAmount = IP_CONST_DAMAGERESIST_15; break;
case 20: iAmount = IP_CONST_DAMAGERESIST_20; break;
case 25: iAmount = IP_CONST_DAMAGERESIST_25; break;;
case 30: iAmount = IP_CONST_DAMAGERESIST_30; break;
case 35: iAmount = IP_CONST_DAMAGERESIST_35; break;
case 40: iAmount = IP_CONST_DAMAGERESIST_40; break;
case 45: iAmount = IP_CONST_DAMAGERESIST_45; break;
case 50: iAmount = IP_CONST_DAMAGERESIST_50; break;
default: iAmount = -1; break;
}
return iAmount;
}
void SF_DecrementSocket(object oPC, object oItem, object oTarget, int iSockets, int iBonus)
{
if ((!STACKABLE_GEMS_SHARE_SLOT && iBonus > 0) || !iBonus)
{
if (iSockets > 0)
{
iSockets --;
SetLocalInt(oItem, "SOCKETS", iSockets);
}
}
effect eVis = EffectVisualEffect(VFX_FNF_LOS_EVIL_10);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
FloatingTextStringOnCreature("Gem successfully socketed", oPC);
SF_GetSocketsLeft(oItem, oPC);
DestroyObject(oTarget);
}
int SF_GetIsMeleeWeapon(object oItem, object oPC)
{
if (!IPGetIsMeleeWeapon(oItem))
{
FloatingTextStringOnCreature("This Gem can't be socketed in this type" +
" of item", oPC);
return FALSE;
}
return TRUE;
}
int SF_GetIsArmourType(object oItem, object oPC)
{
int iBaseType = GetBaseItemType(oItem);
if (iBaseType == BASE_ITEM_AMULET || iBaseType == BASE_ITEM_ARMOR ||
iBaseType == BASE_ITEM_BELT || iBaseType == BASE_ITEM_BOOTS ||
iBaseType == BASE_ITEM_BRACER || iBaseType == BASE_ITEM_CLOAK ||
iBaseType == BASE_ITEM_HELMET || iBaseType == BASE_ITEM_SMALLSHIELD ||
iBaseType == BASE_ITEM_TOWERSHIELD || iBaseType == BASE_ITEM_LARGESHIELD ||
iBaseType == BASE_ITEM_RING)
{
return TRUE;
}
FloatingTextStringOnCreature("This Gem can't be socketed into this type" +
" of item", oPC);
return FALSE;
}
int SF_GetIsSocketUpgradable(object oPC, int iBonus, int iSockets)
{
if (!STACKABLE_GEMS && iBonus && iSockets)
{
FloatingTextStringOnCreature("A Gem of this type is already " +
"occupying a socket", oPC);
return FALSE;
}
if (!iSockets && !iBonus)
{
FloatingTextStringOnCreature("No more sockets left", oPC);
return FALSE;
}
if (!iSockets && iBonus && STACKABLE_GEMS && STACKABLE_GEMS_SHARE_SLOT)
{
return TRUE;
}
if (STACKABLE_GEMS && STACKABLE_GEMS_SHARE_SLOT)
{
return TRUE;
}
return TRUE;
}
void SF_GetSocketsLeft(object oItem, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS");
if (!iSockets)
{
FloatingTextStringOnCreature("No more sockets left", oPC);
}
else if (iSockets == 1)
{
FloatingTextStringOnCreature("1 socket left", oPC);
}
else
{
FloatingTextStringOnCreature(IntToString(iSockets) + " sockets left", oPC);
}
}
void SF_SocketAttackBonusGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iAttackBonus = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS, -1);
if (!SF_GetIsMeleeWeapon(oItem, oPC) &&
GetBaseItemType(oItem) != BASE_ITEM_GLOVES) return;
if (!SF_GetIsSocketUpgradable(oPC, iAttackBonus, iSockets)) return;
int iAmount = GetLocalInt(oTarget, "AMOUNT"),
iDamageToAdd = iAmount + iAttackBonus;
if (iDamageToAdd <= MAX_ATTACK_BONUS)
{
itemproperty iProp = ItemPropertyAttackBonus(iDamageToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iAttackBonus);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum +" + IntToString(MAX_ATTACK_BONUS) +
" Attack Bonus allowed", oPC);
}
}
void SF_SocketDamageBonusGem(object oItem, object oTarget, object oPC, int iDamType)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iDamBonus = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_DAMAGE_BONUS, iDamType);
if (!SF_GetIsMeleeWeapon(oItem, oPC) &&
GetBaseItemType(oItem) != BASE_ITEM_GLOVES) return;
if (!SF_GetIsSocketUpgradable(oPC, iDamBonus, iSockets)) return;
int iAmountToAdd = SF_GetNextDamageBonusAmount(iDamBonus);
if (iAmountToAdd <= MAX_DAMAGE_BONUS && iAmountToAdd > 0)
{
itemproperty iProp = ItemPropertyDamageBonus(iDamType, iAmountToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iDamBonus);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum Damage Bonus of this type allowed", oPC);
}
}
void SF_SocketEnhancementBonusGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iDamBonus = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS);
if (!SF_GetIsMeleeWeapon(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iDamBonus, iSockets)) return;
int iAmount = GetLocalInt(oTarget, "AMOUNT"),
iDamageToAdd = iAmount + iDamBonus;
if (iDamageToAdd <= MAX_ENHANCEMENT_BONUS)
{
itemproperty iProp = ItemPropertyEnhancementBonus(iDamageToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iDamBonus);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum +" +
IntToString(MAX_ENHANCEMENT_BONUS) +
" Enhancement Bonus allowed", oPC);
}
}
void SF_SocketKeenGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iKeen = GetItemHasItemProperty(oItem, ITEM_PROPERTY_KEEN);
if (!SF_GetIsMeleeWeapon(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iKeen, iSockets)) return;
if (!iKeen)
{
itemproperty iProp = ItemPropertyKeen();
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iKeen);
}
else FloatingTextStringOnCreature("A Gem of this type is already " +
"occupying a socket", oPC);
}
void SF_SocketACBonusGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iACBonus = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_AC_BONUS);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iACBonus, iSockets)) return;
int iAmount = GetLocalInt(oTarget, "AMOUNT"),
iACToAdd = iAmount + iACBonus;
if (iACToAdd <= MAX_AC_BONUS)
{
itemproperty iProp = ItemPropertyACBonus(iACToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iACBonus);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum +" +
IntToString(MAX_AC_BONUS) +
" AC Bonus allowed", oPC);
}
}
void SF_SocketDamageResistGem(object oItem, object oTarget, object oPC, int iDamType)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iDamResist = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_DAMAGE_RESISTANCE, iDamType);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iDamResist, iSockets)) return;
int iAmount = GetLocalInt(oTarget, "AMOUNT"),
iResistToAdd = iAmount + iDamResist;
if (iResistToAdd <= MAX_DAMAGE_RESIST)
{
iResistToAdd = SF_GetDamageResistance(iResistToAdd);
itemproperty iProp = ItemPropertyDamageResistance(iDamType, iResistToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iDamResist);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum " +
IntToString(MAX_DAMAGE_RESIST) +
"/- Damage Resistance of this type allowed", oPC);
}
}
void SF_SocketHasteGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iHaste = GetItemHasItemProperty(oItem, ITEM_PROPERTY_HASTE);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iHaste, iSockets)) return;
if (!iHaste)
{
itemproperty iProp = ItemPropertyHaste();
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iHaste);
}
else FloatingTextStringOnCreature("A Gem of this type is already " +
"occupying a socket", oPC);
}
void SF_SocketFreedomGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iFreedom = GetItemHasItemProperty(oItem, ITEM_PROPERTY_FREEDOM_OF_MOVEMENT);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iFreedom, iSockets)) return;
if (!iFreedom)
{
itemproperty iProp = ItemPropertyFreeAction();
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iFreedom);
}
else FloatingTextStringOnCreature("A Gem of this type is already " +
"occupying a socket", oPC);
}
void SF_SocketImprovedEvasionGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iImpEvasion = GetItemHasItemProperty(oItem, ITEM_PROPERTY_IMPROVED_EVASION);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iImpEvasion, iSockets)) return;
if (!iImpEvasion)
{
itemproperty iProp = ItemPropertyImprovedEvasion();
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iImpEvasion);
}
else FloatingTextStringOnCreature("A Gem of this type is already " +
"occupying a socket", oPC);
}
void SF_SocketRegenerationGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iRegenBonus = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_REGENERATION);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iRegenBonus, iSockets)) return;
int iAmount = GetLocalInt(oTarget, "AMOUNT"),
iRegenToAdd = iAmount + iRegenBonus;
if (iRegenToAdd <= MAX_REGEN_BONUS)
{
itemproperty iProp = ItemPropertyRegeneration(iRegenToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iRegenBonus);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum +" +
IntToString(MAX_REGEN_BONUS) +
" Regeneration allowed", oPC);
}
}
void SF_SocketAbilityBonusGem(object oItem, object oTarget, object oPC, int iAbility)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iCurrentAbility = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_ABILITY_BONUS, iAbility);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iAbility, iSockets)) return;
int iAmount = GetLocalInt(oTarget, "AMOUNT"),
iAmountToAdd = iAmount + iCurrentAbility;
if (iAmountToAdd <= MAX_ABILITY_BONUS)
{
itemproperty iProp = ItemPropertyAbilityBonus(iAbility, iAmountToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iCurrentAbility);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum +" +
IntToString(MAX_ABILITY_BONUS) +
" Ability Bonus of this type allowed", oPC);
}
}
void SF_SocketTrueSeeingGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iTrueSeeing = GetItemHasItemProperty(oItem, ITEM_PROPERTY_TRUE_SEEING);
if (!SF_GetIsArmourType(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iTrueSeeing, iSockets)) return;
if (!iTrueSeeing)
{
itemproperty iProp = ItemPropertyTrueSeeing();
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iTrueSeeing);
}
else FloatingTextStringOnCreature("A Gem of this type is already " +
"occupying a socket", oPC);
}
void SF_SocketHolyAvengerGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iHolyAvenger = GetItemHasItemProperty(oItem, ITEM_PROPERTY_HOLY_AVENGER);
if (!SF_GetIsMeleeWeapon(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iHolyAvenger, iSockets)) return;
if (!iHolyAvenger)
{
itemproperty iProp = ItemPropertyHolyAvenger();
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iHolyAvenger);
}
else FloatingTextStringOnCreature("A Gem of this type is already " +
"occupying a socket", oPC);
}
void SF_SocketVampiricRegenerationGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iRegenBonus = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_REGENERATION_VAMPIRIC);
if (!SF_GetIsMeleeWeapon(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iRegenBonus, iSockets)) return;
int iAmount = GetLocalInt(oTarget, "AMOUNT"),
iRegenToAdd = iAmount + iRegenBonus;
if (iRegenToAdd <= MAX_VAMP_REGEN_BONUS)
{
itemproperty iProp = ItemPropertyVampiricRegeneration(iRegenToAdd);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iRegenBonus);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum +" +
IntToString(MAX_VAMP_REGEN_BONUS) +
" Vampiric Regeneration allowed", oPC);
}
}
void SF_SocketMassiveCritsGem(object oItem, object oTarget, object oPC)
{
int iSockets = GetLocalInt(oItem, "SOCKETS"),
iMassCrit = SF_GetMatchingItemProperty(oItem, ITEM_PROPERTY_MASSIVE_CRITICALS);
if (!SF_GetIsMeleeWeapon(oItem, oPC)) return;
if (!SF_GetIsSocketUpgradable(oPC, iMassCrit, iSockets)) return;
int iAmount = SF_GetNextDamageBonusAmount(iMassCrit);
if (iAmount <= MAX_MASS_CRITS && iAmount > 0)
{
itemproperty iProp = ItemPropertyMassiveCritical(iAmount);
IPSafeAddItemProperty(oItem, iProp);
SF_DecrementSocket(oPC, oItem, oTarget, iSockets, iMassCrit);
}
else
{
FloatingTextStringOnCreature("Socketing this Gem will exceed the " +
"maximum Massive Critial allowed", oPC);
}
}