1650 lines
70 KiB
Plaintext
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 "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);
|
|
} |