929 lines
33 KiB
Plaintext
929 lines
33 KiB
Plaintext
//::///////////////////////////////////////////////
|
||
//:: Scarface's Socketed Items include
|
||
//:: V2.4
|
||
//:: sf_sockets_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 if one is available.
|
||
// 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 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_1d10;
|
||
|
||
// 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_MASSIVE_CRITICALS = DAMAGE_BONUS_1d10;
|
||
|
||
// Maximum Attack Bonus allowed on a weapon
|
||
// Do NOT set this higher than 20
|
||
const int MAX_ATTACK_BONUS = 8;
|
||
|
||
// Maximum Enhancement Bonus allowed on a weapon
|
||
// Do NOT set this higher than 20
|
||
const int MAX_ENHANCEMENT_BONUS = 6;
|
||
|
||
// Maximum AC Bonus allowed on armour type items
|
||
// Do NOT set this higher than 20
|
||
const int MAX_AC_BONUS = 6;
|
||
|
||
// 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_RESISTANCE = 20; // XX/-
|
||
|
||
// Maximum Regeneration Bonus allowed on armour type items
|
||
// Do NOT set this higher than 20
|
||
const int MAX_REGENERATION = 6;
|
||
|
||
// Maximum Ability Bonus allowed on armour type items
|
||
// Do NOT set this higher than 12
|
||
const int MAX_ABILITY_BONUS = 4;
|
||
|
||
// Maximum Vampiric allowed on a weapon
|
||
// Do NOT set this higher than 20
|
||
const int MAX_VAMP_REGEN_BONUS = 5;
|
||
|
||
// Maximum Saving Throw bonus allowed on armour items
|
||
// Do NOT set this higher than 20
|
||
const int MAX_SAVING_THROWS = 4;
|
||
|
||
// Maximum Skill bonus allowed on armour items
|
||
// Do NOT set this higher than 50
|
||
const int MAX_SKILL_BONUS = 15;
|
||
|
||
// Maximum Mighty bonus allowed on ranged items
|
||
// Do NOT set this higher than 10
|
||
const int MAX_MIGHTY = 8;
|
||
|
||
// Maximum Spell Resistance allowed on armour items
|
||
// Do NOT set this higher than 32
|
||
const int MAX_SPELL_RESISTANCE = 24;
|
||
|
||
// Debug mode switch.
|
||
const int DEBUG = FALSE;
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
//:: Declared Functions
|
||
//:: Do NOT touch anything below!!!
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
void SF_Debug(string sDebug);
|
||
struct ItemProperty SF_GetItemPropertyToAdd(object oTarget, int nIPType, int nIPSubType, int nIPValue);
|
||
int SF_GetNextSpellResistanceValue(int nValue);
|
||
int SF_GetIsDamageValid(object oTarget, int nIPType, int nIPSubType);
|
||
int SF_GetCurrentDamageValue(int nValue);
|
||
int SF_GetDamageValue(int nValue, int nNextValue = TRUE);
|
||
int SF_GetNextDamageResistValue(int nValue);
|
||
int SF_DamageBonusCostValue(int nCostTableValue);
|
||
int SF_DamageResistCostValue(int nCostTableValue);
|
||
int SF_GetNumSpellUses(int nValue);
|
||
string SF_GetDamageValueString(int nValue);
|
||
int SF_GetMatchingCostTableValue(itemproperty ipProp, int nCostTable);
|
||
int SF_GetMatchingItemProperty(object oItem, int nType, int nSubType = -1);
|
||
int SF_GetIsCorrectItemType(object oPC, object oItem, int nIPType);
|
||
int SF_GetMaxBonus(int nIPType);
|
||
int SF_GetHasSockets(object oPC, object oTarget);
|
||
int SF_GetIsSocketUpgradable(object oPC, object oTarget, int nOldValue);
|
||
void SF_DecrementSocket(object oPC, object oItem, object oTarget, int nOldValue);
|
||
void SF_SocketGemToItem(object oPC, object oTarget, object oActivated);
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
//:: Main Functions
|
||
//:: Do NOT touch anything below!!!
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
const string fSound = "sim_cntresist";
|
||
|
||
const string COLORTOKEN = " ##################$%&'()*+,-./0123456789:;;==?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[[]^_`abcdefghijklmnopqrstuvwxyz{|}~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||
|
||
string ColorString(string sText, int nRed=255, int nGreen=255, int nBlue=255)
|
||
{
|
||
return "<c" + GetSubString(COLORTOKEN, nRed, 1) + GetSubString(COLORTOKEN, nGreen, 1) + GetSubString(COLORTOKEN, nBlue, 1) + ">" + sText + "</c>";
|
||
}
|
||
|
||
void SD_SOCKET_EFF(object oPC, object oTarget)
|
||
{
|
||
int iLength, nSockets;
|
||
string sName, sNew, sRename, sIname, sMess;
|
||
effect eVis;
|
||
nSockets = GetLocalInt(oTarget, "SOCKET_SLOTS");
|
||
sName = GetName(oTarget);
|
||
iLength = GetStringLength(sName);
|
||
sNew = GetSubString(sName, 0, iLength-7);
|
||
sRename = sNew + "(" + IntToString(nSockets) + ")</c>";
|
||
SetName(oTarget, sRename);
|
||
|
||
eVis = EffectVisualEffect(VFX_FNF_LOS_HOLY_10);
|
||
sIname = "The Gem fuses itself to your "+GetName(oTarget);
|
||
sMess = ColorString(sIname, 0, 191, 255);
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
|
||
FloatingTextStringOnCreature(sMess, oPC);
|
||
AssignCommand(oPC, PlaySound("gui_picklockopen"));
|
||
}
|
||
|
||
void Repel (object oPC)
|
||
{
|
||
effect eVis = EffectVisualEffect(VFX_IMP_SPELL_MANTLE_USE);
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC);
|
||
}
|
||
|
||
|
||
|
||
void SF_Debug(string sDebug) {
|
||
|
||
PrintString(sDebug);
|
||
SendMessageToPC(GetFirstPC(), sDebug);
|
||
}
|
||
|
||
struct ItemProperty {int Restriction; int Value; int OldValue; int Damage; itemproperty ItemProp; };
|
||
struct ItemProperty SF_GetItemPropertyToAdd(object oTarget, int nIPType, int nIPSubType, int nIPValue) {
|
||
|
||
struct ItemProperty IP;
|
||
int nBaseItem = GetBaseItemType(oTarget);
|
||
|
||
switch (nIPType) {
|
||
|
||
case ITEM_PROPERTY_ABILITY_BONUS: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyAbilityBonus(nIPSubType, IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_AC_BONUS: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyACBonus(IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_DAMAGE_BONUS: {
|
||
|
||
if (IPGetIsRangedWeapon(oTarget)) { IP.Restriction = 9999; break; }
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Damage = SF_GetDamageValue(IP.OldValue - 1);
|
||
IP.Value = SF_GetDamageValue(nIPValue + IP.OldValue);
|
||
IP.ItemProp = ItemPropertyDamageBonus(nIPSubType, IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_DAMAGE_RESISTANCE: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = SF_GetNextDamageResistValue(nIPValue + IP.OldValue);
|
||
IP.ItemProp = ItemPropertyDamageResistance(nIPSubType, IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_ATTACK_BONUS: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyAttackBonus(IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_ENHANCEMENT_BONUS: {
|
||
|
||
if (IPGetIsRangedWeapon(oTarget) ||
|
||
nBaseItem == BASE_ITEM_GLOVES ||
|
||
nBaseItem == BASE_ITEM_MAGICSTAFF) { IP.Restriction = 9999; break; }
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyEnhancementBonus(IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_REGENERATION_VAMPIRIC: {
|
||
|
||
if (nBaseItem == BASE_ITEM_GLOVES) { IP.Restriction = 9999; break; }
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyVampiricRegeneration(IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_HASTE: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyHaste();
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_HOLY_AVENGER: {
|
||
|
||
if (IPGetIsRangedWeapon(oTarget) ||
|
||
nBaseItem == BASE_ITEM_GLOVES ||
|
||
nBaseItem == BASE_ITEM_MAGICSTAFF) { IP.Restriction = 9999; break; }
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
IP.ItemProp = ItemPropertyHolyAvenger();
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_KEEN: {
|
||
|
||
if (IPGetIsRangedWeapon(oTarget) ||
|
||
nBaseItem == BASE_ITEM_GLOVES ||
|
||
nBaseItem == BASE_ITEM_MAGICSTAFF) { IP.Restriction = 9999; break; }
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyKeen();
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_MASSIVE_CRITICALS: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Damage = SF_GetDamageValue(IP.OldValue - 1);
|
||
IP.Value = SF_GetDamageValue(nIPValue + IP.OldValue);
|
||
IP.ItemProp = ItemPropertyMassiveCritical(IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_REGENERATION: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyRegeneration(IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_SAVING_THROW_BONUS: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyBonusSavingThrow(nIPSubType, IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_SKILL_BONUS: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertySkillBonus(nIPSubType, IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_SPELL_RESISTANCE: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = SF_GetNextSpellResistanceValue(nIPValue + IP.OldValue);
|
||
IP.ItemProp = ItemPropertyBonusSpellResistance(IP.Value);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_TRUE_SEEING: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyTrueSeeing();
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_IMPROVED_EVASION: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyImprovedEvasion();
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_BONUS_FEAT: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyBonusFeat(nIPSubType);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_FREEDOM_OF_MOVEMENT: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyFreeAction();
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_CAST_SPELL: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyCastSpell(nIPSubType, SF_GetNumSpellUses(nIPValue));
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_ONHITCASTSPELL: {
|
||
|
||
if (!IPGetIsMeleeWeapon(oTarget) &&
|
||
nBaseItem != BASE_ITEM_ARMOR &&
|
||
nBaseItem != BASE_ITEM_GLOVES &&
|
||
nBaseItem != BASE_ITEM_MAGICSTAFF) { IP.Restriction = 9999; break; }
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyOnHitCastSpell(nIPSubType, nIPValue);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyBonusLevelSpell(nIPSubType, nIPValue);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_UNLIMITED_AMMUNITION: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyUnlimitedAmmo(nIPSubType);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_EXTRA_RANGED_DAMAGE_TYPE: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, nIPSubType);
|
||
if (IP.OldValue == -999) { IP.Restriction = 9998; break; }
|
||
IP.ItemProp = ItemPropertyExtraRangeDamageType(nIPSubType);
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_MIGHTY: {
|
||
|
||
IP.OldValue = SF_GetMatchingItemProperty(oTarget, nIPType, -1);
|
||
if (IP.OldValue < 0) { IP.OldValue = 0; }
|
||
IP.Value = nIPValue + IP.OldValue;
|
||
IP.ItemProp = ItemPropertyMaxRangeStrengthMod(IP.Value);
|
||
break;
|
||
}
|
||
}
|
||
|
||
return IP;
|
||
}
|
||
|
||
int SF_GetNextSpellResistanceValue(int nValue) {
|
||
|
||
switch (nValue) {
|
||
|
||
case -1:
|
||
case 0: { nValue = IP_CONST_SPELLRESISTANCEBONUS_10; break; }
|
||
case 10: { nValue = IP_CONST_SPELLRESISTANCEBONUS_12; break; }
|
||
case 12: { nValue = IP_CONST_SPELLRESISTANCEBONUS_14; break; }
|
||
case 14: { nValue = IP_CONST_SPELLRESISTANCEBONUS_16; break; }
|
||
case 16: { nValue = IP_CONST_SPELLRESISTANCEBONUS_18; break; }
|
||
case 18: { nValue = IP_CONST_SPELLRESISTANCEBONUS_20; break; }
|
||
case 20: { nValue = IP_CONST_SPELLRESISTANCEBONUS_22; break; }
|
||
case 22: { nValue = IP_CONST_SPELLRESISTANCEBONUS_24; break; }
|
||
case 24: { nValue = IP_CONST_SPELLRESISTANCEBONUS_26; break; }
|
||
case 26: { nValue = IP_CONST_SPELLRESISTANCEBONUS_28; break; }
|
||
case 28: { nValue = IP_CONST_SPELLRESISTANCEBONUS_30; break; }
|
||
case 30: { nValue = IP_CONST_SPELLRESISTANCEBONUS_32; break; }
|
||
case 32: { nValue = 99; break; }
|
||
default: { nValue = -99; break; }
|
||
}
|
||
|
||
return nValue;
|
||
}
|
||
|
||
int SF_GetDamageValue(int nValue, int nNextValue = TRUE) {
|
||
|
||
if (nNextValue < 1) { nValue --; }
|
||
|
||
switch (nValue) {
|
||
|
||
case -1:
|
||
case 0: { nValue = DAMAGE_BONUS_1d4; break; }
|
||
case 21: { nValue = DAMAGE_BONUS_1d6; break; }
|
||
case 22: { nValue = DAMAGE_BONUS_1d8; break; }
|
||
case 23: { nValue = DAMAGE_BONUS_1d10; break; }
|
||
case 24: { nValue = DAMAGE_BONUS_1d12; break; }
|
||
case 25: { nValue = DAMAGE_BONUS_2d4; break; }
|
||
case 26: { nValue = DAMAGE_BONUS_2d6; break; }
|
||
case 27: { nValue = DAMAGE_BONUS_2d8; break; }
|
||
case 28: { nValue = DAMAGE_BONUS_2d10; break; }
|
||
case 29: { nValue = DAMAGE_BONUS_2d12; break; }
|
||
case 30: { nValue = 99; break; }
|
||
default: { nValue = -99; break; }
|
||
}
|
||
|
||
return nValue;
|
||
}
|
||
|
||
int SF_GetNextDamageResistValue(int nValue) {
|
||
|
||
switch (nValue) {
|
||
|
||
case -1:
|
||
case 0: { nValue = IP_CONST_DAMAGERESIST_5; break; }
|
||
case 5: { nValue = IP_CONST_DAMAGERESIST_10; break; }
|
||
case 10: { nValue = IP_CONST_DAMAGERESIST_15; break; }
|
||
case 15: { nValue = IP_CONST_DAMAGERESIST_20; break; }
|
||
case 20: { nValue = IP_CONST_DAMAGERESIST_25; break; }
|
||
case 25: { nValue = IP_CONST_DAMAGERESIST_30; break; }
|
||
case 30: { nValue = IP_CONST_DAMAGERESIST_35; break; }
|
||
case 35: { nValue = IP_CONST_DAMAGERESIST_40; break; }
|
||
case 40: { nValue = IP_CONST_DAMAGERESIST_45; break; }
|
||
case 45: { nValue = IP_CONST_DAMAGERESIST_50; break; }
|
||
case 50: { nValue = 99; break; }
|
||
default: { nValue = -99; break; }
|
||
}
|
||
|
||
return nValue;
|
||
}
|
||
|
||
int SF_DamageBonusCostValue(int nCostTableValue)
|
||
{
|
||
|
||
switch(nCostTableValue)
|
||
{
|
||
case 1: { nCostTableValue = 1; break; }
|
||
case 2: { nCostTableValue = 2; break; }
|
||
case 3: { nCostTableValue = 3; break; }
|
||
case 4: { nCostTableValue = 4; break; }
|
||
case 5: { nCostTableValue = 5; break; }
|
||
case 6: { nCostTableValue = 21; break; }// 1d4
|
||
case 7: { nCostTableValue = 22; break; }// 1d6
|
||
case 8: { nCostTableValue = 23; break; }// 1d8
|
||
case 9: { nCostTableValue = 24; break; }// 1d10
|
||
case 10: { nCostTableValue = 27; break; }// 2d6
|
||
case 11: { nCostTableValue = 28; break; }// 2d8
|
||
case 12: { nCostTableValue = 26; break; }// 2d4
|
||
case 13: { nCostTableValue = 29; break; }// 2d10
|
||
case 14: { nCostTableValue = 25; break; }// 1d12
|
||
case 15: { nCostTableValue = 30; break; }// 2d12
|
||
case 16: { nCostTableValue = 6; break; }
|
||
case 17: { nCostTableValue = 7; break; }
|
||
case 18: { nCostTableValue = 8; break; }
|
||
case 19: { nCostTableValue = 9; break; }
|
||
case 20: { nCostTableValue = 10; break; }
|
||
case 21: { nCostTableValue = 11; break; }
|
||
case 22: { nCostTableValue = 12; break; }
|
||
case 23: { nCostTableValue = 13; break; }
|
||
case 24: { nCostTableValue = 14; break; }
|
||
case 25: { nCostTableValue = 15; break; }
|
||
case 26: { nCostTableValue = 16; break; }
|
||
case 27: { nCostTableValue = 17; break; }
|
||
case 28: { nCostTableValue = 18; break; }
|
||
case 29: { nCostTableValue = 19; break; }
|
||
case 30: { nCostTableValue = 20; break; }
|
||
default: { nCostTableValue = -1; break; }
|
||
}
|
||
return nCostTableValue;
|
||
}
|
||
|
||
int SF_DamageResistCostValue(int nCostTableValue) {
|
||
|
||
switch(nCostTableValue)
|
||
{
|
||
case 1: { nCostTableValue = 5; break; }
|
||
case 2: { nCostTableValue = 10; break; }
|
||
case 3: { nCostTableValue = 15; break; }
|
||
case 4: { nCostTableValue = 20; break; }
|
||
case 5: { nCostTableValue = 25; break; }
|
||
case 6: { nCostTableValue = 30; break; }
|
||
case 7: { nCostTableValue = 35; break; }
|
||
case 8: { nCostTableValue = 40; break; }
|
||
case 9: { nCostTableValue = 45; break; }
|
||
case 10: { nCostTableValue = 50; break; }
|
||
default: { nCostTableValue = -1; break; }
|
||
}
|
||
|
||
return nCostTableValue;
|
||
}
|
||
|
||
int SF_SpellResistCostValue(int nCostTableValue) {
|
||
|
||
switch (nCostTableValue) {
|
||
|
||
case 0: { nCostTableValue = 10; break; }
|
||
case 1: { nCostTableValue = 12; break; }
|
||
case 2: { nCostTableValue = 14; break; }
|
||
case 3: { nCostTableValue = 16; break; }
|
||
case 4: { nCostTableValue = 18; break; }
|
||
case 5: { nCostTableValue = 20; break; }
|
||
case 6: { nCostTableValue = 22; break; }
|
||
case 7: { nCostTableValue = 24; break; }
|
||
case 8: { nCostTableValue = 26; break; }
|
||
case 9: { nCostTableValue = 28; break; }
|
||
case 10: { nCostTableValue = 30; break; }
|
||
case 11: { nCostTableValue = 32; break; }
|
||
default: { nCostTableValue = -1; break; }
|
||
}
|
||
|
||
return nCostTableValue;
|
||
}
|
||
|
||
int SF_GetNumSpellUses(int nValue) {
|
||
|
||
switch (nValue) {
|
||
|
||
case 1: { nValue = IP_CONST_CASTSPELL_NUMUSES_1_USE_PER_DAY; break; }
|
||
case 2: { nValue = IP_CONST_CASTSPELL_NUMUSES_2_USES_PER_DAY; break; }
|
||
case 3: { nValue = IP_CONST_CASTSPELL_NUMUSES_3_USES_PER_DAY; break; }
|
||
case 4: { nValue = IP_CONST_CASTSPELL_NUMUSES_4_USES_PER_DAY; break; }
|
||
case 5: { nValue = IP_CONST_CASTSPELL_NUMUSES_5_USES_PER_DAY; break; }
|
||
case 6: { nValue = IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE; break; }
|
||
default: { nValue = -1; break; }
|
||
}
|
||
|
||
return nValue;
|
||
}
|
||
|
||
string SF_GetDamageValueString(int nValue) {
|
||
|
||
string sValue = "";
|
||
|
||
switch (nValue) {
|
||
|
||
case DAMAGE_BONUS_1d4: { sValue = "1d4"; break; }
|
||
case DAMAGE_BONUS_1d6: { sValue = "1d6"; break; }
|
||
case DAMAGE_BONUS_1d8: { sValue = "1d8"; break; }
|
||
case DAMAGE_BONUS_1d10: { sValue = "1d10"; break; }
|
||
case DAMAGE_BONUS_1d12: { sValue = "1d12"; break; }
|
||
case DAMAGE_BONUS_2d4: { sValue = "2d4"; break; }
|
||
case DAMAGE_BONUS_2d6: { sValue = "2d6"; break; }
|
||
case DAMAGE_BONUS_2d8: { sValue = "2d8"; break; }
|
||
case DAMAGE_BONUS_2d10: { sValue = "2d10"; break; }
|
||
case DAMAGE_BONUS_2d12: { sValue = "2d12"; break; }
|
||
}
|
||
|
||
return sValue;
|
||
}
|
||
|
||
int SF_GetIsItemActivatedValid(object oTarget) {
|
||
|
||
int nBaseType = GetBaseItemType(oTarget);
|
||
|
||
switch (nBaseType) {
|
||
|
||
case BASE_ITEM_AMULET:
|
||
case BASE_ITEM_ARMOR:
|
||
case BASE_ITEM_BASTARDSWORD:
|
||
case BASE_ITEM_BATTLEAXE:
|
||
case BASE_ITEM_BELT:
|
||
case BASE_ITEM_BOOTS:
|
||
case BASE_ITEM_BRACER:
|
||
case BASE_ITEM_CLOAK:
|
||
case BASE_ITEM_CLUB:
|
||
case BASE_ITEM_DAGGER:
|
||
case BASE_ITEM_DIREMACE:
|
||
case BASE_ITEM_DOUBLEAXE:
|
||
case BASE_ITEM_DWARVENWARAXE:
|
||
case BASE_ITEM_GLOVES:
|
||
case BASE_ITEM_GREATAXE:
|
||
case BASE_ITEM_GREATSWORD:
|
||
case BASE_ITEM_HALBERD:
|
||
case BASE_ITEM_HANDAXE:
|
||
case BASE_ITEM_HEAVYCROSSBOW:
|
||
case BASE_ITEM_HEAVYFLAIL:
|
||
case BASE_ITEM_HELMET:
|
||
case BASE_ITEM_KAMA:
|
||
case BASE_ITEM_KATANA:
|
||
case BASE_ITEM_KUKRI:
|
||
case BASE_ITEM_LARGESHIELD:
|
||
case BASE_ITEM_LIGHTCROSSBOW:
|
||
case BASE_ITEM_LIGHTFLAIL:
|
||
case BASE_ITEM_LIGHTHAMMER:
|
||
case BASE_ITEM_LIGHTMACE:
|
||
case BASE_ITEM_LONGBOW:
|
||
case BASE_ITEM_LONGSWORD:
|
||
case BASE_ITEM_MAGICSTAFF:
|
||
case BASE_ITEM_MORNINGSTAR:
|
||
case BASE_ITEM_QUARTERSTAFF:
|
||
case BASE_ITEM_RAPIER:
|
||
case BASE_ITEM_RING:
|
||
case BASE_ITEM_SCIMITAR:
|
||
case BASE_ITEM_SCYTHE:
|
||
case BASE_ITEM_SHORTBOW:
|
||
case BASE_ITEM_SHORTSPEAR:
|
||
case BASE_ITEM_SHORTSWORD:
|
||
case BASE_ITEM_SICKLE:
|
||
case BASE_ITEM_SLING:
|
||
case BASE_ITEM_SMALLSHIELD:
|
||
case BASE_ITEM_TOWERSHIELD:
|
||
case BASE_ITEM_TRIDENT:
|
||
case BASE_ITEM_TWOBLADEDSWORD:
|
||
case BASE_ITEM_WARHAMMER:
|
||
case BASE_ITEM_WHIP: {
|
||
|
||
nBaseType = TRUE;
|
||
break;
|
||
}
|
||
default: nBaseType = FALSE;
|
||
}
|
||
|
||
return nBaseType;
|
||
}
|
||
|
||
int SF_GetMatchingCostTableValue(itemproperty ipProp, int nCostTable) {
|
||
|
||
int nCostTableValue = GetItemPropertyCostTableValue(ipProp);
|
||
|
||
switch(nCostTable) {
|
||
|
||
/* IPRP_BONUSCOST */
|
||
/* IPRP_MELEECOST */
|
||
/* IPRP_SKILLCOST */
|
||
case 1: case 2: case 25:{ nCostTable = nCostTableValue; break; }
|
||
|
||
/* IPRP_DAMAGECOST */
|
||
case 4: { nCostTable = SF_DamageBonusCostValue(nCostTableValue); break; }
|
||
|
||
/* IPRP_RESISTCOST */
|
||
case 7: { nCostTable = SF_DamageResistCostValue(nCostTableValue); break; }
|
||
|
||
/* IPRP_SRCOST */
|
||
case 11: { nCostTable = SF_SpellResistCostValue(nCostTableValue); break; }
|
||
|
||
/* DEFAULT COST */
|
||
default: { nCostTable = -999; break; }
|
||
}
|
||
|
||
return nCostTable;
|
||
}
|
||
int SF_GetMatchingItemProperty(object oItem, int nType, int nSubType = -1) {
|
||
|
||
itemproperty ipProp = GetFirstItemProperty(oItem);
|
||
int nMatchType; int nMatchSubType;
|
||
|
||
// Bug fix - Saving Throws weirdness
|
||
if (nType == 40) { nType = 41; }
|
||
|
||
if (DEBUG) {
|
||
|
||
SF_Debug("IP Type To Find = " + IntToString(nType));
|
||
SF_Debug("IP Subtype To Find = " + IntToString(nSubType));
|
||
}
|
||
|
||
|
||
while (GetIsItemPropertyValid(ipProp)) {
|
||
|
||
nMatchType = GetItemPropertyType(ipProp);
|
||
nMatchSubType = GetItemPropertySubType(ipProp);
|
||
|
||
if (DEBUG) {
|
||
|
||
SF_Debug("IP Loop: ");
|
||
SF_Debug("IP Type To Found = " + IntToString(nMatchType));
|
||
SF_Debug("IP Subtype To Found = " + IntToString(nMatchSubType));
|
||
}
|
||
|
||
if ((nMatchType == nType && nMatchSubType == nSubType) ||
|
||
nMatchType == nType && nMatchSubType == 65535) {
|
||
|
||
nMatchType = SF_GetMatchingCostTableValue(ipProp, GetItemPropertyCostTable(ipProp));
|
||
|
||
if (DEBUG) {
|
||
|
||
SF_Debug("Matching IP Found!!!");
|
||
SF_Debug("IP Cost Table = " + IntToString(nMatchType));
|
||
}
|
||
|
||
return nMatchType;
|
||
}
|
||
|
||
ipProp = GetNextItemProperty(oItem);
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
int SF_GetIsCorrectItemType(object oPC, object oTarget, int nIPType) {
|
||
|
||
int nBaseItem = GetBaseItemType(oTarget);
|
||
|
||
switch(nIPType) {
|
||
|
||
case ITEM_PROPERTY_MIGHTY:
|
||
case ITEM_PROPERTY_EXTRA_RANGED_DAMAGE_TYPE:
|
||
case ITEM_PROPERTY_UNLIMITED_AMMUNITION: {
|
||
|
||
if (IPGetIsRangedWeapon(oTarget)) { nBaseItem = TRUE; }
|
||
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_MASSIVE_CRITICALS:
|
||
case ITEM_PROPERTY_ATTACK_BONUS:
|
||
case ITEM_PROPERTY_DAMAGE_BONUS:
|
||
case ITEM_PROPERTY_ENHANCEMENT_BONUS:
|
||
case ITEM_PROPERTY_KEEN:
|
||
case ITEM_PROPERTY_HOLY_AVENGER:
|
||
case ITEM_PROPERTY_ONHITCASTSPELL:
|
||
case ITEM_PROPERTY_REGENERATION_VAMPIRIC: {
|
||
|
||
if (IPGetIsMeleeWeapon(oTarget) ||
|
||
nBaseItem == BASE_ITEM_GLOVES ||
|
||
nBaseItem == BASE_ITEM_MAGICSTAFF) { nBaseItem = TRUE; }
|
||
|
||
break;
|
||
}
|
||
case ITEM_PROPERTY_ABILITY_BONUS:
|
||
case ITEM_PROPERTY_AC_BONUS:
|
||
case ITEM_PROPERTY_BONUS_FEAT:
|
||
case ITEM_PROPERTY_CAST_SPELL:
|
||
case ITEM_PROPERTY_DAMAGE_REDUCTION:
|
||
case ITEM_PROPERTY_DAMAGE_RESISTANCE:
|
||
case ITEM_PROPERTY_FREEDOM_OF_MOVEMENT:
|
||
case ITEM_PROPERTY_HASTE:
|
||
case ITEM_PROPERTY_IMPROVED_EVASION:
|
||
case ITEM_PROPERTY_REGENERATION:
|
||
case ITEM_PROPERTY_SAVING_THROW_BONUS:
|
||
case ITEM_PROPERTY_SKILL_BONUS:
|
||
case ITEM_PROPERTY_SPELL_RESISTANCE:
|
||
case ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N:
|
||
case ITEM_PROPERTY_TRUE_SEEING: {
|
||
|
||
if (IPGetIsRangedWeapon(oTarget)) { nBaseItem = TRUE; break; }
|
||
|
||
switch (nBaseItem) {
|
||
|
||
case BASE_ITEM_AMULET:
|
||
case BASE_ITEM_GLOVES:
|
||
case BASE_ITEM_MAGICSTAFF:
|
||
case BASE_ITEM_ARMOR:
|
||
case BASE_ITEM_BELT:
|
||
case BASE_ITEM_BOOTS:
|
||
case BASE_ITEM_BRACER:
|
||
case BASE_ITEM_CLOAK:
|
||
case BASE_ITEM_HELMET:
|
||
case BASE_ITEM_SMALLSHIELD:
|
||
case BASE_ITEM_TOWERSHIELD:
|
||
case BASE_ITEM_LARGESHIELD:
|
||
case BASE_ITEM_RING: { nBaseItem = TRUE; }
|
||
}
|
||
break;
|
||
}
|
||
default: { nBaseItem = FALSE; break; }
|
||
}
|
||
|
||
if (!nBaseItem) {
|
||
|
||
FloatingTextStringOnCreature("This type of gem can not be socketed into this type of item.", oPC);
|
||
}
|
||
|
||
return nBaseItem;
|
||
}
|
||
|
||
int SF_GetMaxBonus(int nIPType) {
|
||
|
||
int nMaxBonus;
|
||
|
||
switch (nIPType) {
|
||
|
||
// Weapon Bonuses
|
||
case ITEM_PROPERTY_ATTACK_BONUS: { nMaxBonus = MAX_ATTACK_BONUS; break; }
|
||
case ITEM_PROPERTY_DAMAGE_BONUS: { nMaxBonus = MAX_DAMAGE_BONUS; break; }
|
||
case ITEM_PROPERTY_ENHANCEMENT_BONUS: { nMaxBonus = MAX_ENHANCEMENT_BONUS; break; }
|
||
case ITEM_PROPERTY_MASSIVE_CRITICALS: { nMaxBonus = MAX_MASSIVE_CRITICALS; break; }
|
||
case ITEM_PROPERTY_REGENERATION_VAMPIRIC: { nMaxBonus = MAX_VAMP_REGEN_BONUS; break; }
|
||
case ITEM_PROPERTY_MIGHTY: { nMaxBonus = MAX_MIGHTY; break; }
|
||
|
||
// Armour Bonuses
|
||
case ITEM_PROPERTY_ABILITY_BONUS: { nMaxBonus = MAX_ABILITY_BONUS; break; }
|
||
case ITEM_PROPERTY_AC_BONUS: { nMaxBonus = MAX_AC_BONUS; break; }
|
||
case ITEM_PROPERTY_DAMAGE_RESISTANCE: { nMaxBonus = MAX_DAMAGE_RESISTANCE; break; }
|
||
case ITEM_PROPERTY_REGENERATION: { nMaxBonus = MAX_REGENERATION; break; }
|
||
case ITEM_PROPERTY_SAVING_THROW_BONUS: { nMaxBonus = MAX_SAVING_THROWS; break; }
|
||
case ITEM_PROPERTY_SKILL_BONUS: { nMaxBonus = MAX_SKILL_BONUS; break; }
|
||
case ITEM_PROPERTY_SPELL_RESISTANCE: { nMaxBonus = MAX_SPELL_RESISTANCE; break; }
|
||
|
||
default: nMaxBonus = 0;
|
||
}
|
||
|
||
return nMaxBonus;
|
||
}
|
||
|
||
int SF_GetHasSockets(object oPC, object oTarget) {
|
||
|
||
int nSockets = GetLocalInt(oTarget, "SOCKET_SLOTS");
|
||
|
||
FloatingTextStringOnCreature(IntToString(nSockets) + " socket(s) left", oPC);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void SF_DecrementSocket(object oPC, object oItem, object oTarget, int nOldValue)
|
||
{
|
||
int nSockets = GetLocalInt(oTarget, "SOCKET_SLOTS");
|
||
|
||
if ((!STACKABLE_GEMS_SHARE_SLOT && STACKABLE_GEMS && nOldValue > 0) || (nOldValue <= 0))
|
||
{
|
||
if (nSockets > 0) { nSockets --; SetLocalInt(oTarget, "SOCKET_SLOTS", nSockets); }
|
||
}
|
||
|
||
AssignCommand(oPC, ClearAllActions());
|
||
AssignCommand(oPC, ActionUnequipItem(oTarget));
|
||
DestroyObject(oItem);
|
||
//SF_GetHasSockets(oPC, oTarget);
|
||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_LOS_HOLY_30), oPC);
|
||
}
|
||
|
||
int SF_GetIsSocketUpgradable(object oPC, object oTarget, int nOldValue)
|
||
{
|
||
int nSockets = GetLocalInt(oTarget, "SOCKET_SLOTS");
|
||
|
||
if (!STACKABLE_GEMS && nOldValue && nSockets) {
|
||
|
||
FloatingTextStringOnCreature("You can not socket another gem of this type.", oPC);
|
||
Repel(oPC);
|
||
return FALSE;
|
||
}
|
||
if (!nSockets && !nOldValue) {
|
||
|
||
FloatingTextStringOnCreature("No more sockets left", oPC);
|
||
Repel(oPC);
|
||
return FALSE;
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
void SF_SocketGemToItem(object oPC, object oTarget, object oGem) {
|
||
|
||
int nIPType = GetLocalInt(oGem, "IP_TYPE");
|
||
int nIPSubType = GetLocalInt(oGem, "IP_SUBTYPE");
|
||
int nIPValue = GetLocalInt(oGem, "IP_VALUE");
|
||
|
||
struct ItemProperty IP = SF_GetItemPropertyToAdd(oTarget, nIPType, nIPSubType, nIPValue);
|
||
|
||
if (!SF_GetIsCorrectItemType(oPC, oTarget, nIPType)) { return; }
|
||
|
||
// Restrictions (Keen.. etc obviously won't work for gloves or staffs and so on)
|
||
if (IP.Restriction == 9999) {
|
||
|
||
FloatingTextStringOnCreature("This type of gem can not be socketed into this type of item.", oPC);
|
||
Repel(oPC);
|
||
return;
|
||
}
|
||
|
||
// Item Properties i.e. haste, imp evasion, true seeing... etc should not work if already present
|
||
if (IP.Restriction == 9998) {
|
||
|
||
FloatingTextStringOnCreature("Gems of this type do not stack.", oPC);
|
||
Repel(oPC);
|
||
return;
|
||
}
|
||
|
||
if (!SF_GetIsSocketUpgradable(oPC, oTarget, IP.OldValue)) { return; }
|
||
|
||
int nMaxBonus = SF_GetMaxBonus(nIPType);
|
||
|
||
switch (nIPType) {
|
||
|
||
case ITEM_PROPERTY_MASSIVE_CRITICALS:
|
||
case ITEM_PROPERTY_DAMAGE_BONUS: {
|
||
|
||
if (IP.Damage == nMaxBonus) {
|
||
|
||
FloatingTextStringOnCreature("Maximum bonus allowed for this gem type is " + SF_GetDamageValueString(MAX_DAMAGE_BONUS) + ".", oPC);
|
||
Repel(oPC);
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
|
||
default: {
|
||
|
||
if (IP.Value > nMaxBonus) {
|
||
|
||
FloatingTextStringOnCreature("Maximum bonus allowed for this gem type is " + IntToString(nMaxBonus) + ".", oPC);
|
||
Repel(oPC);
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
IPSafeAddItemProperty(oTarget, IP.ItemProp);
|
||
SF_DecrementSocket(oPC, oGem, oTarget, IP.OldValue);
|
||
SD_SOCKET_EFF(oPC, oTarget);
|
||
}
|
||
|
||
//void main(){}
|