PRC8/nwn/nwnprc/trunk/include/inc_item_props.nss
Jaysyn904 57b8d88878 Renamed inc_array to stop nwnx include collisions
Renamed inc_array to stop nwnx include collisions  Added missing bonus feat 2da for Forest Master. Changed prc_newspellbook.hak to prc_nsb.hak to prevent issues with nwserver.  Updated tester module.  Updated release archive.
2024-03-03 18:06:25 -05:00

1650 lines
70 KiB
Plaintext

//::///////////////////////////////////////////////
//:: [Item Property Function]
//:: [inc_item_props.nss]
//:://////////////////////////////////////////////
/** @file
This file defines several functions used to
manipulate item properties. In particular,
It defines functions used in the prc_* files
to apply passive feat bonuses.
Take special note of SetCompositeBonus. This
function is crucial for allowing bonuses of the
same type from different PRCs to stack.
*/
//:://////////////////////////////////////////////
//:: Created By: Aaon Graywolf
//:: Created On: Dec 19, 2003
//:://////////////////////////////////////////////
//:: Update: Jan 4 2002
//:: - Extended Composite bonus function to handle pretty much
//:: every property that can possibly be composited.
//////////////////////////////
// Function Prototypes //
//////////////////////////////
#include "prc_feat_const"
#include "prc_misc_const"
//:: Test void
//:: void main (){}
/**
* Checks oItem for all properties matching iType and iSubType. Removes all
* these properties and returns their total CostTableVal.
* This function should only be used for Item Properties that have simple
* integer CostTableVals, such as AC, Save/Skill Bonuses, etc.
*
* @param oItem The item on which to look for the itemproperties. Usually a
* skin object.
* @param iType ITEM_PROPERTY_* constant of the itemproperty to look for.
* @param iSubType IP_CONST_* constant of itemproperty SubType if applicable.
* @return The total CostTableValue of the itemproperties found
* matching iType and iSubType.
*/
int TotalAndRemoveProperty(object oItem, int iType, int iSubType = -1);
/**
* Used to roll bonuses from multiple sources into a single property.
* Only supports properties which have simple integer CostTableVals.
* See the code for a list of supported types. Some important properties
* that CANNOT be composited are SpellResistance, DamageBonus, DamageReduction
* DamageResistance and MassiveCritical, as these use 2da-referencing constants
* instead of integers for CostTableVals.
*
* <DEPRECATED>
* LocalInts from SetCompositeBonus() when applied to the skin need to be
* added to DeletePRCLocalInts() in prc_inc_function in order for the system to
* properly clear the properties when the itemproperties are removed using
* ScrubPCSkin().
* When applied to equipment, the LocalInts need to be added to
* DeletePRCLocalIntsT() in inc_item_props.
* </DEPRECATED>
*
* Use SetCompositeBonus() for the skin, SetCompositeBonusT() for other equipment.
*
*
* @param oPC Object wearing / using the item
* @param oItem Object to apply bonus to
* @param sBonus String name of the source for this bonus
* @param iVal Integer value to set this bonus to
* @param iType ITEM_PROPERTY_* constant of itemproperty to apply
* @param iSubType IP_CONST_* constant of itemproperty SubType if applicable
*/
void SetCompositeBonus(object oItem, string sBonus, int iVal, int iType, int iSubType = -1);
/**
* See SetCompositeBonus(). This is an equivalent, except it applies the itemproperties as
* temporary ones with duration of 9999 seconds.
*/
void SetCompositeBonusT(object oItem, string sBonus, int iVal, int iType, int iSubType = -1);
/**
* Calculates the total Bonus AC granted by itemproperties on an item.
*
* @param oItem The item to calculate AC bonus given by.
* @return The total of all AC bonus itemproperties on oItem.
*/
int GetACBonus(object oItem);
/**
* Calculates the Base AC (i.e. AC without bonuses) of an item
*
* @param oItem The item to calculate base AC for.
* @return The base AC, as calculated by removing the value returned by
* GetACBonus() on the item from the value returned by GetItemACValue().
*/
int GetBaseAC(object oItem);
/**
* Gets the itemproperty number of a specific SR value
*/
int GetSRByValue(int nValue);
/**
* Returns the opposite element from iElem or -1 if iElem is not valid
* Can be useful for determining elemental strengths and weaknesses
*
* @param iElem IP_CONST_DAMAGETYPE_* constant.
* @return IP_CONST_DAMAGETYPE_* constant of the opposing damage type.
*/
int GetOppositeElement(int iElem);
/**
* Used to find the damage type done by any given weapon using 2da lookups.
* Only usable on weapon items.
*
* @param oWeapon The weapon whose damage type to examine.
* @return One of IP_CONST_DAMAGETYPE_BLUDGEONING,
* IP_CONST_DAMAGETYPE_PIERCING,
* IP_CONST_DAMAGETYPE_SLASHING
* if used on a weapon item. Otherwise -1.
*/
int GetItemPropertyDamageType(object oWeapon);
/**
* Used to find the damage type done by any given weapon using 2da lookups.
* Only usable on weapon items.
*
* @param oWeapon The weapon whose damage type to examine.
* @return One of DAMAGE_TYPE_BLUDGEONING,
* DAMAGE_TYPE_PIERCING,
* DAMAGE_TYPE_SLASHING
* if used on a weapon item. Otherwise -1.
*/
int GetItemDamageType(object oWeapon);
/**
* To ensure a damage bonus stacks with any existing enhancement bonus,
* create a temporary damage bonus on the weapon. You do not want to do this
* if the weapon is of the "slashing and piercing" type, because the
* enhancement bonus is considered "physical", not "slashing" or "piercing".
*
* Because of this strange Bioware behavior, you'll want to only call this code as such:
*
* if (StringToInt(Get2DACache("baseitems","WeaponType",GetBaseItemType(oWeapon))) != 4)
* {
* IPEnhancementBonusToDamageBonus(oWeapon);
* }
*
*
* @param oWeap The weapon to perform the operation on.
*/
void IPEnhancementBonusToDamageBonus(object oWeap);
/**
* Used to roll bonuses from multiple sources into a single property
* Only supports damage bonuses in a linear fashion - +1 through +20.
*
* Note: If you do not define iSubType, the damage applied will most likely not
* stack with any enhancement bonus. See IPEnhancementBonusToDamageBonus() above.
*
* <DEPRECATED>
* LocalInts from SetCompositeDamageBonus() need to be added to
* DeletePRCLocalInts() in prc_inc_function.
* LocalInts from SetCompositeDamageBonusT() need to be added to
* DeletePRCLocalIntsT() in inc_item_props.
* </DEPRECATED>
*
*
* @param oItem Object to apply bonus to
* @param sBonus String name of the source for this bonus
* @param iVal Integer value to set this bonus to (damage +1 through +20)
* @param iSubType IP_CONST_DAMAGETYPE* constant -- leave blank to use the weapon's damage type.
*/
void SetCompositeDamageBonusT(object oItem, string sBonus, int iVal, int iSubType = -1); // for temporary bonuses
/**
* Removes a number of itemproperties matching the parameters.
*
* @param oItem The item to remove itemproperties from.
* @param iType ITEM_PROPERTY_* constant.
* @param iSubType IP_CONST_* constant of the itemproperty subtype or -1 to
* match all possible subtypes. Also use -1 if the itemproperty
* has no subtypes.
* @param iCostVal CostTableValue of the itemproperty to remove. Again, -1 for
* any.
* @param iNum How many matching itemproperties to remove. -1 for all. Defaults
* to 1.
* @param sFlag Name of a local integer on the item to set to 0 when this is run.
* If anyone knows why the fuck this is done, please write here - Ornedan
* @param iParam1 Param1 value of the itemproperty to remove. Again, -1 for any.
* @param iDuration DURATION_TYPE_* constant. The duration type of the itemproperty.
* Again, -1 for any.
*/
void RemoveSpecificProperty(object oItem, int iType, int iSubType = -1, int iCostVal = -1, int iNum = 1,
string sFlag = "", int iParam1 = -1, int iDuration = DURATION_TYPE_PERMANENT);
/**
* Finds the first itemproperty matching the parameters.
* Use GetIsItemPropertyValid() to check if an itemproperty exists.
*
* @param oItem The item to remove itemproperties from.
* @param iType ITEM_PROPERTY_* constant.
* @param iSubType IP_CONST_* constant of the itemproperty subtype or -1 to
* match all possible subtypes. Also use -1 if the itemproperty
* has no subtypes.
* @param iCostVal CostTableValue of the itemproperty to remove. Again, -1 for
* any.
* @param iParam1 Param1 value of the itemproperty to remove. Again, -1 for any.
* @param iDuration DURATION_TYPE_* constant. The duration type of the itemproperty.
* Again, -1 for any.
*/
itemproperty GetSpecificProperty(object oItem, int iType, int iSubType = -1, int iCostVal = -1,
int iParam1 = -1, int iDuration = DURATION_TYPE_PERMANENT);
/**
* Keeps track of Attack Bonus effects and stacks them appropriately... you cannot set up
* "special" attack bonuses against races or alignments, but it will keep seperate tabs on
* on-hand attack bonuses and off-hand attack bonuses.
*
* NOTE: This attack bonus is an effect on the creature, not an item property. Item Property
* attacks have the downside that they pierce DR, whereas effects do not.
*
* NOTE: DO *NOT* USE THIS FUNCTION WITH SPELL/SLA EFFECTS. They stack fine on their own.
*
* <DEPRECATED>
* LocalInts in and finally SetCompositeAttackBonus() need to be added to
* DeletePRCLocalInts() in prc_inc_function.
* </DEPRECATED>
*
*
* @param oPC PC/NPC you wish to apply an attack bonus effect to
* @param sBonus The unique name you wish to give this attack bonus
* @param iVal The amount the attack bonus should be (there is a hardcoded limit of 20)
* @param iSubType ATTACK_BONUS_MISC applies to both hands, ATTACK_BONUS_ONHAND applies to the right (main)
* hand, and ATTACK_BONUS_OFFHAND applies to the left (off) hand
*/
void SetCompositeAttackBonus(object oPC, string sBonus, int iVal, int iSubType = ATTACK_BONUS_MISC);
/**
* Internal function.
* Handles maintaining a list of composite itemproperty names for
* use when clearing the itemproperties away.
*
* @param oItem The item a composite bonus is being set on.
* @param sBase The base name for the local variables used. For differentiating between
* permanent and temporary lists.
* @param sComposite The name of a composite property being set.
*/
void UpdateUsedCompositeNamesList(object oItem, string sBase, string sComposite);
/**
* Internal function.
* Deletes all the composite itemproperty names listed and deletes the list.
*
* @param oItem The item being cleaned of composite properties.
* @param sBase The base name for the local variables used. For differentiating between
* permanent and temporary lists.
*/
void DeleteNamedComposites(object oItem, string sBase);
/**
* Determines if any of the given item's itemproperties would make it a
* magical item.
*
* @param oItem The item to test
* @return TRUE if the item is a magical item, FALSE otherwise
*/
int GetIsMagicItem(object oItem);
/**
* Special function for adding ip feats to creatures hide.
* The hide is always equipped so it easier to use GetHasFeat()
* than to loop over all ips to check if given skin was already
* added.
* @param nFeat The ID of real feat we want to add (row number in feat.2da)
* @param IPFeat The ID of ip feat (row number in iprp_feats.2da)
* @param oSkin Target item to which we add the feat - should be an equipped
* creature skin (the script doesn't check it it's valid)
* @param oPC Owner of oSkin
*/
void AddSkinFeat(int nFeat, int IPFeat, object oSkin, object oPC = OBJECT_SELF, float fDuration = 0.0f);
//////////////////////////////////////////////////
/* Include section */
//////////////////////////////////////////////////
#include "inc_2dacache"
#include "inc_persist_loca"
#include "inc_prc_npc"
//#include "inc_utility"
#include "prc_ipfeat_const"
#include "prc_inc_array"
//////////////////////////////
// Function Definitions //
//////////////////////////////
int TotalAndRemoveProperty(object oItem, int iType, int iSubType = -1)
{
itemproperty ip = GetFirstItemProperty(oItem);
int total = 0;
while(GetIsItemPropertyValid(ip)){
if(GetItemPropertyType(ip) == iType && (GetItemPropertySubType(ip) == iSubType || iSubType == -1)){
total += GetItemPropertyCostTableValue(ip);
RemoveItemProperty(oItem, ip);
}
ip = GetNextItemProperty(oItem);
}
return total;
}
itemproperty GetSpecificProperty(object oItem, int iType, int iSubType = -1, int iCostVal = -1,
int iParam1 = -1, int iDuration = DURATION_TYPE_PERMANENT)
{
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip)){
if(GetItemPropertyType(ip) == iType &&
(GetItemPropertyDurationType(ip) == iDuration || iDuration == -1) &&
(GetItemPropertySubType(ip) == iSubType || iSubType == -1) &&
(GetItemPropertyCostTableValue(ip) == iCostVal || iCostVal == -1) &&
(GetItemPropertyParam1Value(ip) == iParam1 || iParam1 == -1)
)
{
return ip;
}
ip = GetNextItemProperty(oItem);
}
return ip;
}
void RemoveSpecificProperty(object oItem, int iType, int iSubType = -1, int iCostVal = -1, int iNum = 1,
string sFlag = "", int iParam1 = -1, int iDuration = DURATION_TYPE_PERMANENT)
{
int iRemoved = 0;
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip) && (iRemoved < iNum || iNum == -1)){
if(GetItemPropertyType(ip) == iType &&
(GetItemPropertyDurationType(ip) == iDuration || iDuration == -1) &&
(GetItemPropertySubType(ip) == iSubType || iSubType == -1) &&
(GetItemPropertyCostTableValue(ip) == iCostVal || iCostVal == -1) &&
(GetItemPropertyParam1Value(ip) == iParam1 || iParam1 == -1)
)
{
RemoveItemProperty(oItem, ip);
iRemoved++;
}
ip = GetNextItemProperty(oItem);
}
SetLocalInt(oItem, sFlag, 0);
}
//SetCompositeBonus is a special case that doesn't need to use DelayAddItemProperty because
//the property that is added is always different from the one that was deleted by TotalAndRemoveProperty.
void SetCompositeBonus(object oItem, string sBonus, int iVal, int iType, int iSubType = -1)
{
int iOldVal = GetLocalInt(oItem, sBonus);
int iChange = iVal - iOldVal;
int iCurVal = 0;
if(iChange == 0) return;
// Store the bonus name for use during cleanup
UpdateUsedCompositeNamesList(oItem, "PRC_CBon", sBonus);
//Moved TotalAndRemoveProperty into switch to prevent
//accidental deletion of unsupported property types
switch(iType)
{
case ITEM_PROPERTY_ABILITY_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
iCurVal -= GetPersistantLocalInt(GetItemPossessor(oItem), "LetoAbility_"+IntToString(iSubType));
if (DEBUG) DoDebug("Ability Decrease #1: oItem "+GetName(oItem)+" sBonus "+sBonus+" iChange "+IntToString(iChange)+" iCurVal "+IntToString(iCurVal)+" iSubType "+IntToString(iSubType));
if ((iCurVal + iChange) > 50)
{
iVal -= iCurVal + iChange - 50;
iCurVal = 50;
iChange = 0;
}
if(iCurVal+iChange > 0)
{
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAbilityBonus(iSubType, iCurVal + iChange), oItem);
if (DEBUG) DoDebug("Ability Increase");
}
else if(iCurVal+iChange < 0)
{
if (DEBUG) DoDebug("Ability Decrease #2: oItem "+GetName(oItem)+" sBonus "+sBonus+" iChange "+IntToString(iChange)+" iSubType "+IntToString(iSubType));
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDecreaseAbility(iSubType, -1*(iCurVal + iChange)), oItem);
}
break;
case ITEM_PROPERTY_AC_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonus(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_AC_BONUS_VS_ALIGNMENT_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonusVsAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonusVsDmgType(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_AC_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonusVsRace(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_AC_BONUS_VS_SPECIFIC_ALIGNMENT:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonusVsSAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ATTACK_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAttackBonus(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAttackBonusVsAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ATTACK_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAttackBonusVsRace(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ATTACK_BONUS_VS_SPECIFIC_ALIGNMENT:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAttackBonusVsSAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_ABILITY_SCORE:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 10)
{
iVal -= iCurVal + iChange - 10;
iCurVal = 10;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDecreaseAbility(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_AC:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 5)
{
iVal -= iCurVal + iChange - 5;
iCurVal = 5;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDecreaseAC(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 5)
{
iVal -= iCurVal + iChange - 5;
iCurVal = 5;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAttackPenalty(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 5)
{
iVal -= iCurVal + iChange - 5;
iCurVal = 5;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementPenalty(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_SAVING_THROWS:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyReducedSavingThrow(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyReducedSavingThrowVsX(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_SKILL_MODIFIER:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 10)
{
iVal -= iCurVal + iChange - 10;
iCurVal = 10;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDecreaseSkill(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementBonus(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementBonusVsAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementBonusVsRace(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_SPECIFIC_ALIGNEMENT:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementBonusVsSAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_MIGHTY:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyMaxRangeStrengthMod(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_REGENERATION:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyRegeneration(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_REGENERATION_VAMPIRIC:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyVampiricRegeneration(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_SAVING_THROW_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyBonusSavingThrowVsX(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyBonusSavingThrow(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_SKILL_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 50)
{
iVal -= iCurVal + iChange - 50;
iCurVal = 50;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertySkillBonus(iSubType, iCurVal + iChange), oItem);
break;
}
SetLocalInt(oItem, sBonus, iVal);
}
int GetACBonus(object oItem)
{
if(!GetIsObjectValid(oItem)) return 0;
itemproperty ip = GetFirstItemProperty(oItem);
int iTotal = 0;
while(GetIsItemPropertyValid(ip)){
if(GetItemPropertyType(ip) == ITEM_PROPERTY_AC_BONUS)
iTotal += GetItemPropertyCostTableValue(ip);
ip = GetNextItemProperty(oItem);
}
return iTotal;
}
int GetBaseAC(object oItem){ return GetItemACValue(oItem) - GetACBonus(oItem); }
int GetOppositeElement(int iElem)
{
switch(iElem){
case IP_CONST_DAMAGETYPE_ACID:
return DAMAGE_TYPE_ELECTRICAL;
case IP_CONST_DAMAGETYPE_COLD:
return IP_CONST_DAMAGETYPE_FIRE;
case IP_CONST_DAMAGETYPE_DIVINE:
return IP_CONST_DAMAGETYPE_NEGATIVE;
case IP_CONST_DAMAGETYPE_ELECTRICAL:
return IP_CONST_DAMAGETYPE_ACID;
case IP_CONST_DAMAGETYPE_FIRE:
return IP_CONST_DAMAGETYPE_COLD;
case IP_CONST_DAMAGETYPE_NEGATIVE:
return IP_CONST_DAMAGETYPE_POSITIVE;
}
return -1;
}
int TotalAndRemovePropertyT(object oItem, int iType, int iSubType = -1)
{
itemproperty ip = GetFirstItemProperty(oItem);
int total = 0;
int iTemp;
while(GetIsItemPropertyValid(ip)){
if(GetItemPropertyType(ip) == iType && (GetItemPropertySubType(ip) == iSubType || iSubType == -1)){
iTemp = GetItemPropertyCostTableValue(ip);
total = iTemp > total ? iTemp : total;
if (GetItemPropertyDurationType(ip)== DURATION_TYPE_TEMPORARY) RemoveItemProperty(oItem, ip);
}
ip = GetNextItemProperty(oItem);
}
return total;
}
//SetCompositeBonusT is a special case that doesn't need to use DelayAddItemProperty because
//the property that is added is always different from the one that was deleted by TotalAndRemovePropertyT.
void SetCompositeBonusT(object oItem, string sBonus, int iVal, int iType, int iSubType = -1)
{
int iOldVal = GetLocalInt(oItem, sBonus);
if (GetLocalInt(GetItemPossessor(oItem),"ONREST")) iOldVal =0;
int iChange = iVal - iOldVal;
int iCurVal = 0;
if(iChange == 0) return;
// Store the bonus name for use during cleanup
UpdateUsedCompositeNamesList(oItem, "PRC_CBonT", sBonus);
//Moved TotalAndRemoveProperty into switch to prevent
//accidental deletion of unsupported property types
switch(iType)
{
case ITEM_PROPERTY_ABILITY_BONUS:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 50)
{
iVal -= iCurVal + iChange - 50;
iCurVal = 50;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAbilityBonus(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_AC_BONUS:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyACBonus(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_AC_BONUS_VS_ALIGNMENT_GROUP:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyACBonusVsAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyACBonusVsDmgType(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_AC_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyACBonusVsRace(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_AC_BONUS_VS_SPECIFIC_ALIGNMENT:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyACBonusVsSAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ATTACK_BONUS:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonus(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonusVsAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ATTACK_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonusVsRace(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ATTACK_BONUS_VS_SPECIFIC_ALIGNMENT:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackBonusVsSAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
if(iCurVal+iChange > 0)
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageBonusVsRace(iSubType, DAMAGE_TYPE_SLASHING, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_ABILITY_SCORE:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDecreaseAbility(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DECREASED_AC:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 5)
{
iVal -= iCurVal + iChange - 5;
iCurVal = 5;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDecreaseAC(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 5)
{
iVal -= iCurVal + iChange - 5;
iCurVal = 5;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyAttackPenalty(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DECREASED_ENHANCEMENT_MODIFIER:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 5)
{
iVal -= iCurVal + iChange - 5;
iCurVal = 5;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyEnhancementPenalty(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DECREASED_SAVING_THROWS:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyReducedSavingThrowVsX(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyReducedSavingThrow(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_DECREASED_SKILL_MODIFIER:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 10)
{
iVal -= iCurVal + iChange - 10;
iCurVal = 10;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDecreaseSkill(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyEnhancementBonus(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyEnhancementBonusVsAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_RACIAL_GROUP:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyEnhancementBonusVsRace(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_SPECIFIC_ALIGNEMENT:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyEnhancementBonusVsSAlign(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_MIGHTY:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyMaxRangeStrengthMod(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_REGENERATION:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyRegeneration(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_REGENERATION_VAMPIRIC:
iCurVal = TotalAndRemovePropertyT(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyVampiricRegeneration(iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_SAVING_THROW_BONUS:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyBonusSavingThrowVsX(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iVal -= iCurVal + iChange - 20;
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyBonusSavingThrow(iSubType, iCurVal + iChange), oItem,9999.0);
break;
case ITEM_PROPERTY_SKILL_BONUS:
iCurVal = TotalAndRemovePropertyT(oItem, iType, iSubType);
if ((iCurVal + iChange) > 50)
{
iVal -= iCurVal + iChange - 50;
iCurVal = 50;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertySkillBonus(iSubType, iCurVal + iChange), oItem,9999.0);
break;
}
SetLocalInt(oItem, sBonus, iVal);
}
int GetItemPropertyDamageType(object oWeapon)
{
if(GetObjectType(oWeapon) != OBJECT_TYPE_ITEM)
return -1;
int iWeaponType = GetBaseItemType(oWeapon);
int iDamageType = StringToInt(Get2DACache("baseitems","WeaponType",iWeaponType));
switch(iDamageType)
{
case 1: return IP_CONST_DAMAGETYPE_PIERCING; break;
case 2: return IP_CONST_DAMAGETYPE_BLUDGEONING; break;
case 3: return IP_CONST_DAMAGETYPE_SLASHING; break;
case 4: return IP_CONST_DAMAGETYPE_SLASHING; break; // slashing & piercing... slashing bonus.
default: return -1;
}
return -1;
}
int GetItemDamageType(object oWeapon)
{
if(GetObjectType(oWeapon) != OBJECT_TYPE_ITEM)
return -1;
int iWeaponType = GetBaseItemType(oWeapon);
int iDamageType = StringToInt( Get2DACache("baseitems","WeaponType",iWeaponType) );
switch(iDamageType)
{
case 1: return DAMAGE_TYPE_PIERCING; break;
case 2: return DAMAGE_TYPE_BLUDGEONING; break;
case 3: return DAMAGE_TYPE_SLASHING; break;
case 4: return DAMAGE_TYPE_SLASHING; break; // slashing & piercing... slashing bonus.
default: return -1;
}
return -1;
}
// To ensure the damage bonus stacks with any existing enhancement bonus,
// we create a temporary damage bonus on the weapon. We do not want to do this
// if the weapon is of the "slashing and piercing" type, because the
// enhancement bonus is considered "physical", not "slashing" or "piercing".
// If you borrow this code, make sure to keep the "IPEnh" and realize that
// "slashing and piercing" weapons need a special case.
void IPEnhancementBonusToDamageBonus(object oWeap)
{
int iBonus = 0;
int iTemp;
if (GetLocalInt(oWeap, "IPEnh") || !GetIsObjectValid(oWeap)) return;
itemproperty ip = GetFirstItemProperty(oWeap);
while(GetIsItemPropertyValid(ip))
{
if(GetItemPropertyType(ip) == ITEM_PROPERTY_ENHANCEMENT_BONUS)
iTemp = GetItemPropertyCostTableValue(ip);
iBonus = iTemp > iBonus ? iTemp : iBonus;
ip = GetNextItemProperty(oWeap);
}
SetCompositeDamageBonusT(oWeap,"IPEnh",iBonus);
}
int TotalAndRemoveDamagePropertyT(object oItem, int iSubType)
{
itemproperty ip = GetFirstItemProperty(oItem);
int iPropertyValue;
int total = 0;
int iTemp;
while(GetIsItemPropertyValid(ip))
{
iPropertyValue = GetItemPropertyCostTableValue(ip);
if((GetItemPropertyType(ip) == ITEM_PROPERTY_DAMAGE_BONUS) &&
(GetItemPropertySubType(ip) == iSubType) &&
((iPropertyValue < 6) || (iPropertyValue > 15)))
{
total = iPropertyValue > total ? iPropertyValue : total;
if (GetItemPropertyDurationType(ip)== DURATION_TYPE_TEMPORARY) RemoveItemProperty(oItem, ip);
}
ip = GetNextItemProperty(oItem);
}
return total;
}
void SetCompositeDamageBonusT(object oItem, string sBonus, int iVal, int iSubType = -1)
{
int iOldVal = GetLocalInt(oItem, sBonus);
int iChange = iVal - iOldVal;
int iLinearDamage = 0;
int iCurVal = 0;
if(iChange == 0) return;
// Store the bonus name for use during cleanup
UpdateUsedCompositeNamesList(oItem, "PRC_CBonT", sBonus);
if (iSubType == -1) iSubType = GetItemPropertyDamageType(oItem);
if (iSubType == -1) return; // if it's still -1 we're not dealing with a weapon.
iCurVal = TotalAndRemoveDamagePropertyT(oItem, iSubType);
if (iCurVal > 15) iCurVal -= 10; // values 6-20 are in the 2da as lines 16-30
iLinearDamage = iCurVal + iChange;
if (iLinearDamage > 20)
{
iVal = iLinearDamage - 20; // Change the stored value to reflect the fact that we overflowed
iLinearDamage = 20; // This is prior to adjustment due to non-linear values
}
if (iLinearDamage > 5) iLinearDamage += 10; // values 6-20 are in the 2da as lines 16-30
AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyDamageBonus(iSubType, iLinearDamage), oItem,9999.0);
SetLocalInt(oItem, sBonus, iVal);
}
void TotalRemovePropertyT(object oItem)
{
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
if(GetItemPropertyDurationType(ip)== DURATION_TYPE_TEMPORARY)
RemoveItemProperty(oItem, ip);
ip = GetNextItemProperty(oItem);
}
}
void DeletePRCLocalIntsT(object oPC, object oItem = OBJECT_INVALID)
{
// See if we were given a valid item as parameter. If we were, we
// will be removing ints from it.
// Otherwise, we will take the item in each slot and removing the
// ints that should be on it.
int bGivenObject = GetIsObjectValid(oItem);
// RIGHT HAND
if(!bGivenObject)
oItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
if(bGivenObject || GetIsObjectValid(oItem))
{
// Clear composite bonuses
TotalRemovePropertyT(oItem);
DeleteNamedComposites(oItem, "PRC_CBonT");
/* Clear other stuff
*
* All the commented out values are the ones that didn't seem to be used anywhere anymore - Ornedan
*/
//Stormlord
DeleteLocalInt(oItem,"STShock"); /// @todo Rewrite the Stormlord not to directly manipulate values
DeleteLocalInt(oItem,"STThund");
DeleteLocalInt(oItem,"ManArmsCore");
//Vile/Sanctify & Un/Holy Martial Strike
DeleteLocalInt(oItem,"SanctMar");
DeleteLocalInt(oItem,"MartialStrik");
DeleteLocalInt(oItem,"UnholyStrik");
DeleteLocalInt(oItem,"USanctMar");
//Duelist Precise Strike
DeleteLocalInt(oItem,"DuelistPreciseSlash");
//DeleteLocalInt(oItem,"DuelistPreciseSmash");
// Dispater
DeleteLocalInt(oItem,"DispIronPowerA");
DeleteLocalInt(oItem,"DispIronPowerD");
// Dragonwrack
DeleteLocalInt(oItem,"DWright");
}
// LEFT HAND
if(!bGivenObject)
oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
if(bGivenObject || GetIsObjectValid(oItem))
{
if(!bGivenObject)
{
// Clear composite bonuses
TotalRemovePropertyT(oItem);
DeleteNamedComposites(oItem, "PRC_CBonT");
}
//Vile/Sanctify & Un/Holy Martial Strike
DeleteLocalInt(oItem,"SanctMar");
DeleteLocalInt(oItem,"MartialStrik");
DeleteLocalInt(oItem,"UnholyStrik");
DeleteLocalInt(oItem,"USanctMar");
// Dragonwrack
DeleteLocalInt(oItem,"DWleft");
// Dispater
DeleteLocalInt(oItem,"DispIronPowerA");
DeleteLocalInt(oItem,"DispIronPowerD");
}
// CHEST
if(!bGivenObject)
oItem = GetItemInSlot(INVENTORY_SLOT_CHEST,oPC);
if(bGivenObject || GetIsObjectValid(oItem))
{
if(!bGivenObject)
{
// Clear composite bonuses
TotalRemovePropertyT(oItem);
DeleteNamedComposites(oItem, "PRC_CBonT");
}
// Frenzied Berzerker
DeleteLocalInt(oItem,"AFrenzy");
// Shadowlord
DeleteLocalInt(oItem,"ShaDiscorp");
// Dragonwrack
DeleteLocalInt(oItem,"Dragonwrack");
}
// LEFT RING
if(!bGivenObject)
oItem = GetItemInSlot(INVENTORY_SLOT_LEFTRING,oPC);
if(bGivenObject || GetIsObjectValid(oItem))
{
if(!bGivenObject)
{
// Clear composite bonuses
TotalRemovePropertyT(oItem);
DeleteNamedComposites(oItem, "PRC_CBonT");
}
}
// ARMS
if(!bGivenObject)
oItem = GetItemInSlot(INVENTORY_SLOT_ARMS,oPC);
if(bGivenObject || GetIsObjectValid(oItem))
{
if(!bGivenObject)
{
// Clear composite bonuses
TotalRemovePropertyT(oItem);
DeleteNamedComposites(oItem, "PRC_CBonT");
}
// Disciple of Mephistopheles
DeleteLocalInt(oItem,"DiscMephGlove");
}
}
void SetCompositeAttackBonus(object oPC, string sBonus, int iVal, int iSubType = ATTACK_BONUS_MISC)
{
object oCastingObject = CreateObject(OBJECT_TYPE_PLACEABLE, "x0_rodwonder", GetLocation(oPC));
int iSpl = 2732; //SPELL_SET_COMPOSITE_ATTACK_BONUS;
SetLocalString(oCastingObject, "SET_COMPOSITE_STRING", sBonus);
SetLocalInt(oCastingObject, "SET_COMPOSITE_VALUE", iVal);
SetLocalInt(oCastingObject, "SET_COMPOSITE_SUBTYPE", iSubType);
DelayCommand(0.1, AssignCommand(oCastingObject, ActionCastSpellAtObject(iSpl, oPC, METAMAGIC_NONE, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE)));
DestroyObject(oCastingObject, 6.0);
}
int GetSRByValue(int nValue)
{
switch(nValue)
{
case 1: return 52;
case 2: return 53;
case 3: return 54;
case 4: return 55;
case 5: return 56;
case 6: return 57;
case 7: return 58;
case 8: return 59;
case 9: return 60;
case 10: return 0;
case 12: return 1;
case 14: return 2;
case 16: return 3;
case 18: return 4;
case 20: return 5;
case 22: return 6;
case 24: return 7;
case 26: return 8;
case 28: return 9;
case 30: return 10;
case 32: return 11;
case 34: return 12;
case 36: return 13;
case 38: return 14;
case 40: return 15;
case 42: return 16;
case 44: return 17;
case 46: return 18;
case 48: return 19;
case 50: return 20;
case 52: return 21;
case 54: return 22;
case 56: return 23;
case 58: return 24;
case 60: return 25;
case 11: return 26;
case 13: return 27;
case 15: return 28;
case 17: return 29;
case 19: return 30;
case 21: return 31;
case 23: return 32;
case 25: return 33;
case 27: return 34;
case 29: return 35;
case 31: return 36;
case 33: return 37;
case 35: return 38;
case 37: return 39;
case 39: return 40;
case 41: return 41;
case 43: return 42;
case 45: return 43;
case 47: return 44;
case 49: return 45;
case 51: return 46;
case 53: return 47;
case 55: return 48;
case 57: return 49;
case 59: return 50;
case 61: return 51;
}
if(nValue < 1)
return -1;
if(nValue > 98)
return 61;//99 max
if(nValue > 61)
return 51;//61 flat cap
return -1;
}
void UpdateUsedCompositeNamesList(object oItem, string sBase, string sComposite)
{
// Add the bonus name to the list if it isn't there already
if(!GetLocalInt(oItem, sBase + "_Exist_" + sComposite))
{
if(DEBUG) DoDebug("Storing the composite name '" + sComposite + "' for later deletion");
string sArrayName = sBase + "_Names";
// Create the array if it doesn't exist already
if(!array_exists(oItem, sArrayName))
array_create(oItem, sArrayName);
// Store the bonus name in a list
array_set_string(oItem, sArrayName, array_get_size(oItem, sArrayName), sComposite);
// Store a marker so we don't need to loop over the list to find out if the name has been stored already
SetLocalInt(oItem, sBase + "_Exist_" + sComposite, TRUE);
}
}
void DeleteNamedComposites(object oItem, string sBase)
{
if(DEBUG) DoDebug("Deleting composite bonus list '" + sBase + "' on " + DebugObject2Str(oItem));
string sArrayName = sBase + "_Names";
string sComposite;
int nMax = array_get_size(oItem, sArrayName);
int i = 0;
// Delete all composite values and markers
for(; i < nMax; i++)
{
sComposite = array_get_string(oItem, sArrayName, i);
if(DEBUG) DoDebug("Deleting bonus marker '" + sComposite + "'");
DeleteLocalInt(oItem, sComposite);
DeleteLocalInt(oItem, sBase + "_Exist_" + sComposite);
}
// Delete the array
array_delete(oItem, sArrayName);
}
int GetIsMagicItem(object oItem)
{
itemproperty ip = GetFirstItemProperty(oItem);
int nType;
int nSubtype;
while(GetIsItemPropertyValid(ip)) //loop through item properties looking for a magical one
{
if(GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT)
{ //ignore temporary properties
nType = GetItemPropertyType(ip);
if((nType >= 0 && nType <= 9) || //read from itempropdef.2da
(nType >= 13 && nType <= 20) ||
(nType == 26) ||
(nType >= 32 && nType <= 44) ||
(nType == 46) ||
(nType >= 51 && nType <= 59) ||
(nType == 61) ||
(nType >= 67 && nType <= 69) ||
(nType >= 71 && nType <= 80) ||
(nType == 82) ||
(nType == 84) ||
(nType >= 100 && nType <= 105) ||
(nType >= 133 && nType <= 134))
{
return 1; //magical property
}
nSubtype = GetItemPropertySubType(ip);
if(nType == ITEM_PROPERTY_BONUS_FEAT)
{
if(GetBaseItemType(oItem) == BASE_ITEM_WHIP)
{
if(nSubtype != IP_CONST_FEAT_DISARM_WHIP)
return 1;
}
else
return 1;
}
ip = GetNextItemProperty(oItem);
}
}
return 0;
}
int FeatToIprop(int nFeat)
{
switch(nFeat)
{
case FEAT_WEAPON_FOCUS_BASTARD_SWORD: return IP_CONST_FEAT_WEAPON_FOCUS_BASTARD_SWORD;
case FEAT_WEAPON_FOCUS_BATTLE_AXE: return IP_CONST_FEAT_WEAPON_FOCUS_BATTLE_AXE;
case FEAT_WEAPON_FOCUS_CLUB: return IP_CONST_FEAT_WEAPON_FOCUS_CLUB;
case FEAT_WEAPON_FOCUS_DAGGER: return IP_CONST_FEAT_WEAPON_FOCUS_DAGGER;
case FEAT_WEAPON_FOCUS_DART: return IP_CONST_FEAT_WEAPON_FOCUS_DART;
case FEAT_WEAPON_FOCUS_DIRE_MACE: return IP_CONST_FEAT_WEAPON_FOCUS_DIRE_MACE;
case FEAT_WEAPON_FOCUS_DOUBLE_AXE: return IP_CONST_FEAT_WEAPON_FOCUS_DOUBLE_AXE;
case FEAT_WEAPON_FOCUS_DWAXE: return IP_CONST_FEAT_WEAPON_FOCUS_DWAXE;
case FEAT_WEAPON_FOCUS_GREAT_AXE: return IP_CONST_FEAT_WEAPON_FOCUS_GREAT_AXE;
case FEAT_WEAPON_FOCUS_GREAT_SWORD: return IP_CONST_FEAT_WEAPON_FOCUS_GREAT_SWORD;
case FEAT_WEAPON_FOCUS_HALBERD: return IP_CONST_FEAT_WEAPON_FOCUS_HALBERD;
case FEAT_WEAPON_FOCUS_HAND_AXE: return IP_CONST_FEAT_WEAPON_FOCUS_HAND_AXE;
case FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW: return IP_CONST_FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW;
case FEAT_WEAPON_FOCUS_HEAVY_FLAIL: return IP_CONST_FEAT_WEAPON_FOCUS_HEAVY_FLAIL;
case FEAT_WEAPON_FOCUS_KAMA: return IP_CONST_FEAT_WEAPON_FOCUS_KAMA;
case FEAT_WEAPON_FOCUS_KATANA: return IP_CONST_FEAT_WEAPON_FOCUS_KATANA;
case FEAT_WEAPON_FOCUS_KUKRI: return IP_CONST_FEAT_WEAPON_FOCUS_KUKRI;
case FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW: return IP_CONST_FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW;
case FEAT_WEAPON_FOCUS_LIGHT_FLAIL: return IP_CONST_FEAT_WEAPON_FOCUS_LIGHT_FLAIL;
case FEAT_WEAPON_FOCUS_LIGHT_HAMMER: return IP_CONST_FEAT_WEAPON_FOCUS_LIGHT_HAMMER;
case FEAT_WEAPON_FOCUS_LIGHT_MACE: return IP_CONST_FEAT_WEAPON_FOCUS_LIGHT_MACE;
case FEAT_WEAPON_FOCUS_LONG_SWORD: return IP_CONST_FEAT_WEAPON_FOCUS_LONG_SWORD;
case FEAT_WEAPON_FOCUS_LONGBOW: return IP_CONST_FEAT_WEAPON_FOCUS_LONGBOW;
case FEAT_WEAPON_FOCUS_MORNING_STAR: return IP_CONST_FEAT_WEAPON_FOCUS_MORNING_STAR;
case FEAT_WEAPON_FOCUS_STAFF: return IP_CONST_FEAT_WEAPON_FOCUS_STAFF;
case FEAT_WEAPON_FOCUS_RAPIER: return IP_CONST_FEAT_WEAPON_FOCUS_RAPIER;
case FEAT_WEAPON_FOCUS_SCIMITAR: return IP_CONST_FEAT_WEAPON_FOCUS_SCIMITAR;
case FEAT_WEAPON_FOCUS_SCYTHE: return IP_CONST_FEAT_WEAPON_FOCUS_SCYTHE;
case FEAT_WEAPON_FOCUS_SHORTBOW: return IP_CONST_FEAT_WEAPON_FOCUS_SHORTBOW;
case FEAT_WEAPON_FOCUS_SPEAR: return IP_CONST_FEAT_WEAPON_FOCUS_SPEAR;
case FEAT_WEAPON_FOCUS_SHORT_SWORD: return IP_CONST_FEAT_WEAPON_FOCUS_SHORT_SWORD;
case FEAT_WEAPON_FOCUS_SHURIKEN: return IP_CONST_FEAT_WEAPON_FOCUS_SHURIKEN;
case FEAT_WEAPON_FOCUS_SICKLE: return IP_CONST_FEAT_WEAPON_FOCUS_SICKLE;
case FEAT_WEAPON_FOCUS_SLING: return IP_CONST_FEAT_WEAPON_FOCUS_SLING;
case FEAT_WEAPON_FOCUS_THROWING_AXE: return IP_CONST_FEAT_WEAPON_FOCUS_THROWING_AXE;
case FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD: return IP_CONST_FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD;
case FEAT_WEAPON_FOCUS_WAR_HAMMER: return IP_CONST_FEAT_WEAPON_FOCUS_WAR_HAMMER;
case FEAT_WEAPON_FOCUS_WHIP: return IP_CONST_FEAT_WEAPON_FOCUS_WHIP;
case FEAT_WEAPON_FOCUS_EAGLE_CLAW: return IP_CONST_FEAT_WEAPON_FOCUS_EAGLE_CLAW;
case FEAT_WEAPON_FOCUS_FALCHION: return IP_CONST_FEAT_WEAPON_FOCUS_FALCHION;
case FEAT_WEAPON_FOCUS_HEAVY_MACE: return IP_CONST_FEAT_WEAPON_FOCUS_HEAVY_MACE;
case FEAT_WEAPON_FOCUS_LIGHT_PICK: return IP_CONST_FEAT_WEAPON_FOCUS_LIGHT_PICK;
case FEAT_WEAPON_FOCUS_HEAVY_PICK: return IP_CONST_FEAT_WEAPON_FOCUS_HEAVY_PICK;
case FEAT_WEAPON_FOCUS_KATAR: return IP_CONST_FEAT_WEAPON_FOCUS_KATAR;
case FEAT_WEAPON_FOCUS_SAI: return IP_CONST_FEAT_WEAPON_FOCUS_SAI;
case FEAT_WEAPON_FOCUS_NUNCHAKU: return IP_CONST_FEAT_WEAPON_FOCUS_NUNCHAKU;
case FEAT_WEAPON_FOCUS_MAUL: return IP_CONST_FEAT_WEAPON_FOCUS_MAUL;
case FEAT_WEAPON_FOCUS_SAP: return IP_CONST_FEAT_WEAPON_FOCUS_SAP;
case FEAT_WEAPON_FOCUS_DOUBLE_SCIMITAR: return IP_CONST_FEAT_WEAPON_FOCUS_DOUBLE_SCIMITAR;
case FEAT_WEAPON_FOCUS_GOAD: return IP_CONST_FEAT_WEAPON_FOCUS_GOAD;
case FEAT_WEAPON_FOCUS_TRIDENT: return IP_CONST_FEAT_WEAPON_FOCUS_TRIDENT;
case FEAT_WEAPON_FOCUS_ELVEN_LIGHTBLADE: return IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_LIGHTBLADE;
case FEAT_WEAPON_FOCUS_ELVEN_THINBLADE: return IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_THINBLADE;
case FEAT_WEAPON_FOCUS_ELVEN_COURTBLADE: return IP_CONST_FEAT_WEAPON_FOCUS_ELVEN_COURTBLADE;
case FEAT_WEAPON_SPECIALIZATION_CLUB: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_CLUB ;
case FEAT_WEAPON_SPECIALIZATION_DAGGER: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_DAGGER ;
case FEAT_WEAPON_SPECIALIZATION_DART: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_DART ;
case FEAT_WEAPON_SPECIALIZATION_HEAVY_CROSSBOW: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_HEAVY_CROSSBOW ;
case FEAT_WEAPON_SPECIALIZATION_LIGHT_CROSSBOW: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_LIGHT_CROSSBOW ;
case FEAT_WEAPON_SPECIALIZATION_LIGHT_MACE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_LIGHT_MACE ;
case FEAT_WEAPON_SPECIALIZATION_MORNING_STAR: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_MORNING_STAR ;
case FEAT_WEAPON_SPECIALIZATION_STAFF: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_STAFF ;
case FEAT_WEAPON_SPECIALIZATION_SPEAR: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SPEAR ;
case FEAT_WEAPON_SPECIALIZATION_SICKLE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SICKLE ;
case FEAT_WEAPON_SPECIALIZATION_SLING: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SLING ;
case FEAT_WEAPON_SPECIALIZATION_UNARMED_STRIKE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_UNARMED_STRIKE ;
case FEAT_WEAPON_SPECIALIZATION_LONGBOW: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_LONGBOW ;
case FEAT_WEAPON_SPECIALIZATION_SHORTBOW: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SHORTBOW ;
case FEAT_WEAPON_SPECIALIZATION_SHORT_SWORD: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SHORT_SWORD ;
case FEAT_WEAPON_SPECIALIZATION_RAPIER: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_RAPIER ;
case FEAT_WEAPON_SPECIALIZATION_SCIMITAR: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SCIMITAR ;
case FEAT_WEAPON_SPECIALIZATION_LONG_SWORD: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_LONG_SWORD ;
case FEAT_WEAPON_SPECIALIZATION_GREAT_SWORD: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_GREAT_SWORD ;
case FEAT_WEAPON_SPECIALIZATION_HAND_AXE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_HAND_AXE ;
case FEAT_WEAPON_SPECIALIZATION_THROWING_AXE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_THROWING_AXE ;
case FEAT_WEAPON_SPECIALIZATION_BATTLE_AXE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_BATTLE_AXE ;
case FEAT_WEAPON_SPECIALIZATION_GREAT_AXE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_GREAT_AXE ;
case FEAT_WEAPON_SPECIALIZATION_HALBERD: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_HALBERD ;
case FEAT_WEAPON_SPECIALIZATION_LIGHT_HAMMER: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_LIGHT_HAMMER ;
case FEAT_WEAPON_SPECIALIZATION_LIGHT_FLAIL: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_LIGHT_FLAIL ;
case FEAT_WEAPON_SPECIALIZATION_WAR_HAMMER: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_WAR_HAMMER ;
case FEAT_WEAPON_SPECIALIZATION_HEAVY_FLAIL: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_HEAVY_FLAIL ;
case FEAT_WEAPON_SPECIALIZATION_KAMA: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_KAMA ;
case FEAT_WEAPON_SPECIALIZATION_KUKRI: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_KUKRI ;
case FEAT_WEAPON_SPECIALIZATION_SHURIKEN: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SHURIKEN ;
case FEAT_WEAPON_SPECIALIZATION_SCYTHE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_SCYTHE ;
case FEAT_WEAPON_SPECIALIZATION_KATANA: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_KATANA ;
case FEAT_WEAPON_SPECIALIZATION_BASTARD_SWORD: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_BASTARD_SWORD ;
case FEAT_WEAPON_SPECIALIZATION_DIRE_MACE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_DIRE_MACE ;
case FEAT_WEAPON_SPECIALIZATION_DOUBLE_AXE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_DOUBLE_AXE ;
case FEAT_WEAPON_SPECIALIZATION_TWO_BLADED_SWORD: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_TWO_BLADED_SWORD;
case FEAT_WEAPON_SPECIALIZATION_DWAXE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_DWAXE;
case FEAT_WEAPON_SPECIALIZATION_WHIP: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_WHIP;
case FEAT_WEAPON_SPECIALIZATION_ELVEN_LIGHTBLADE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_ELVEN_LIGHTBLADE;
case FEAT_WEAPON_SPECIALIZATION_ELVEN_THINBLADE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_ELVEN_THINBLADE;
case FEAT_WEAPON_SPECIALIZATION_ELVEN_COURTBLADE: return IP_CONST_FEAT_WEAPON_SPECIALIZATION_ELVEN_COURTBLADE;
}
return - 1;
}
int FocusToWeapProf(int nFeat)
{
switch(nFeat)
{
case FEAT_WEAPON_FOCUS_CLUB: return BASE_ITEM_CLUB;
case FEAT_WEAPON_FOCUS_DAGGER: return BASE_ITEM_DAGGER;
case FEAT_WEAPON_FOCUS_DART: return BASE_ITEM_DART;
case FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW: return BASE_ITEM_HEAVYCROSSBOW;
case FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW: return BASE_ITEM_LIGHTCROSSBOW;
case FEAT_WEAPON_FOCUS_LIGHT_MACE: return BASE_ITEM_LIGHTMACE;
case FEAT_WEAPON_FOCUS_MORNING_STAR: return BASE_ITEM_MORNINGSTAR;
case FEAT_WEAPON_FOCUS_STAFF: return BASE_ITEM_QUARTERSTAFF;
case FEAT_WEAPON_FOCUS_SPEAR: return BASE_ITEM_SHORTSPEAR;
case FEAT_WEAPON_FOCUS_SICKLE: return BASE_ITEM_SICKLE;
case FEAT_WEAPON_FOCUS_SLING: return BASE_ITEM_SLING;
case FEAT_WEAPON_FOCUS_LONGBOW: return BASE_ITEM_LONGBOW;
case FEAT_WEAPON_FOCUS_SHORTBOW: return BASE_ITEM_SHORTBOW;
case FEAT_WEAPON_FOCUS_SHORT_SWORD: return BASE_ITEM_SHORTSWORD;
case FEAT_WEAPON_FOCUS_RAPIER: return BASE_ITEM_RAPIER;
case FEAT_WEAPON_FOCUS_SCIMITAR: return BASE_ITEM_SCIMITAR;
case FEAT_WEAPON_FOCUS_LONG_SWORD: return BASE_ITEM_LONGSWORD;
case FEAT_WEAPON_FOCUS_GREAT_SWORD: return BASE_ITEM_GREATSWORD;
case FEAT_WEAPON_FOCUS_HAND_AXE: return BASE_ITEM_HANDAXE;
case FEAT_WEAPON_FOCUS_THROWING_AXE: return BASE_ITEM_THROWINGAXE;
case FEAT_WEAPON_FOCUS_BATTLE_AXE: return BASE_ITEM_BATTLEAXE;
case FEAT_WEAPON_FOCUS_GREAT_AXE: return BASE_ITEM_GREATAXE;
case FEAT_WEAPON_FOCUS_HALBERD: return BASE_ITEM_HALBERD;
case FEAT_WEAPON_FOCUS_LIGHT_HAMMER: return BASE_ITEM_LIGHTHAMMER;
case FEAT_WEAPON_FOCUS_LIGHT_FLAIL: return BASE_ITEM_LIGHTFLAIL;
case FEAT_WEAPON_FOCUS_WAR_HAMMER: return BASE_ITEM_WARHAMMER;
case FEAT_WEAPON_FOCUS_HEAVY_FLAIL: return BASE_ITEM_HEAVYFLAIL;
case FEAT_WEAPON_FOCUS_KAMA: return BASE_ITEM_KAMA;
case FEAT_WEAPON_FOCUS_KUKRI: return BASE_ITEM_KUKRI;
case FEAT_WEAPON_FOCUS_SHURIKEN: return BASE_ITEM_SHURIKEN;
case FEAT_WEAPON_FOCUS_SCYTHE: return BASE_ITEM_SCYTHE;
case FEAT_WEAPON_FOCUS_KATANA: return BASE_ITEM_KATANA;
case FEAT_WEAPON_FOCUS_BASTARD_SWORD: return BASE_ITEM_BASTARDSWORD;
case FEAT_WEAPON_FOCUS_DIRE_MACE: return BASE_ITEM_DIREMACE;
case FEAT_WEAPON_FOCUS_DOUBLE_AXE: return BASE_ITEM_DOUBLEAXE;
case FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD: return BASE_ITEM_TWOBLADEDSWORD;
case FEAT_WEAPON_FOCUS_DWAXE: return BASE_ITEM_DWARVENWARAXE;
case FEAT_WEAPON_FOCUS_WHIP: return BASE_ITEM_WHIP;
case FEAT_WEAPON_FOCUS_EAGLE_CLAW: return BASE_ITEM_EAGLE_CLAW;
case FEAT_WEAPON_FOCUS_FALCHION: return BASE_ITEM_FALCHION;
case FEAT_WEAPON_FOCUS_GOAD: return BASE_ITEM_GOAD;
case FEAT_WEAPON_FOCUS_HEAVY_MACE: return BASE_ITEM_HEAVY_MACE;
case FEAT_WEAPON_FOCUS_LIGHT_PICK: return BASE_ITEM_LIGHT_PICK;
case FEAT_WEAPON_FOCUS_HEAVY_PICK: return BASE_ITEM_HEAVY_PICK;
case FEAT_WEAPON_FOCUS_KATAR: return BASE_ITEM_KATAR;
case FEAT_WEAPON_FOCUS_SAI: return BASE_ITEM_SAI;
case FEAT_WEAPON_FOCUS_NUNCHAKU: return BASE_ITEM_NUNCHAKU;
case FEAT_WEAPON_FOCUS_MAUL: return BASE_ITEM_MAUL;
case FEAT_WEAPON_FOCUS_SAP: return BASE_ITEM_SAP;
case FEAT_WEAPON_FOCUS_DOUBLE_SCIMITAR: return BASE_ITEM_DOUBLE_SCIMITAR;
case FEAT_WEAPON_FOCUS_TRIDENT: return BASE_ITEM_TRIDENT;
case FEAT_WEAPON_FOCUS_ELVEN_LIGHTBLADE: return BASE_ITEM_ELVEN_LIGHTBLADE;
case FEAT_WEAPON_FOCUS_ELVEN_THINBLADE: return BASE_ITEM_ELVEN_THINBLADE;
case FEAT_WEAPON_FOCUS_ELVEN_COURTBLADE: return BASE_ITEM_ELVEN_COURTBLADE;
}
return - 1;
}
void AddSkinFeat(int nFeat, int IPFeat, object oSkin, object oPC = OBJECT_SELF, float fDuration = 0.0f)
{
// Already has that feat - do nothing
if(GetHasFeat(nFeat, oPC))
return;
int nDurType = fDuration == 0.0f ? DURATION_TYPE_PERMANENT : DURATION_TYPE_TEMPORARY;
AddItemProperty(nDurType, ItemPropertyBonusFeat(IPFeat), oSkin, fDuration);
}