HiddenTradition_PRC8/_removed/inc_item_props.nss
2024-06-20 15:47:42 -04:00

422 lines
16 KiB
Plaintext

//::///////////////////////////////////////////////
//:: [Item Property Function]
//:: [inc_item_props.nss]
//:://////////////////////////////////////////////
//:: 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.
// * Checks to see if oPC has an item created by sRes in his/her inventory
int GetHasItem(object oPC, string sRes);
// * Sets up the pcskin object on oPC
// * If it already exists, simply return it
// * Otherwise, create and equip it
object GetPCSkin(object oPC);
// * 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.
// * iType = ITEM_PROPERTY_* of bonus
// * iSubType = IP_CONST_* of bonus SubType if applicable
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 switch for a list of supported types. Some important properties
// * that CANNOT be composited are SpellResistance, DamageBonus, DamageReduction
// * DamageResistance and MassiveCritical, as these use constants instead of
// * integers for CostTableVals.
// *
// * oPC = Object wearing / using the item
// * oItem = Object to apply bonus to
// * sBonus = String name of the source for this bonus
// * iVal = Integer value to set this bonus to
// * iType: ITEM_PROPERTY_* of bonus
// * iSubType: IP_CONST_* of bonus SubType if applicable
void SetCompositeBonus(object oItem, string sBonus, int iVal, int iType, int iSubType = -1);
// * Returns the total Bonus AC of oItem
int GetACBonus(object oItem);
// * Returns the Base AC (i.e. AC without bonuses) of oItem
int GetBaseAC(object oItem);
// * Removes a Presice Strike bonus from oWeap.
// * Existing bonuses are determined by reading LocalInt "PStrkBonus" on oWeap
void DuelistRemovePreciseStrike(object oWeap);
// * Returns the opposite element from iElem or -1 if iElem is not valid
// * Can be useful for determining elemental strengths and weaknesses
// * iElem = IP_CONST_DAMAGETYPE_*
int GetOppositeElement(int iElem);
int GetHasItem(object oPC, string sRes)
{
object oItem = GetFirstItemInInventory(oPC);
while(GetIsObjectValid(oItem) && GetResRef(oItem) != sRes)
oItem = GetNextItemInInventory(oPC);
return GetResRef(oItem) == sRes;
}
object GetPCSkin(object oPC)
{
object oSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
//Added GetHasItem check to prevent creation of extra skins on module entry
if(!GetIsObjectValid(oSkin) && !GetHasItem(oPC, "base_prc_skin")){
oSkin = CreateItemOnObject("base_prc_skin", oPC);
AssignCommand(oPC, ActionEquipItem(oSkin, INVENTORY_SLOT_CARMOUR));
}
return oSkin;
}
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;
}
void RemoveSpecificProperty(object oItem, int iType, int iSubType = -1, int iCostVal = -1, int iNum = 1, string sFlag = "")
{
int iRemoved = 0;
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip) && iRemoved < iNum){
if(GetItemPropertyType(ip) == iType && GetItemPropertySubType(ip) == iSubType && GetItemPropertyCostTableValue(ip) == iCostVal){
RemoveItemProperty(oItem, ip);
iRemoved++;
}
ip = GetNextItemProperty(oItem);
}
SetLocalInt(oItem, sFlag, 0);
}
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;
//Moved TotalAndRemoveProperty into switch to prevent
//accidental deletion of unsupported property types
switch(iType)
{
case ITEM_PROPERTY_ABILITY_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 12)
{
iCurVal = 12;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAbilityBonus(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_AC_BONUS:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAttackBonusVsSAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_ABILITY_SCORE:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iCurVal = 20;
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)
{
iCurVal = 5;
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)
{
iCurVal = 5;
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)
{
iCurVal = 5;
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)
{
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyReducedSavingThrowVsX(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_SAVING_THROWS_SPECIFIC:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 20)
{
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyReducedSavingThrow(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_DECREASED_SKILL_MODIFIER:
iCurVal = TotalAndRemoveProperty(oItem, iType, iSubType);
if ((iCurVal + iChange) > 10)
{
iCurVal = 10;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementBonusVsSAlign(iSubType, iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_MIGHTY:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyMaxRangeStrengthMod(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_REGENERATION:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iCurVal = 20;
iChange = 0;
}
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyRegeneration(iCurVal + iChange), oItem);
break;
case ITEM_PROPERTY_REGENERATION_VAMPIRIC:
iCurVal = TotalAndRemoveProperty(oItem, iType);
if ((iCurVal + iChange) > 20)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 20;
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)
{
iCurVal = 50;
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); }
//Added a flag to make sure bonus is only removed once
void DuelistRemovePreciseStrike(object oWeap)
{
int iPStrkBonus = GetLocalInt(oWeap, "PStrkBonus");
if(iPStrkBonus != 0)
RemoveSpecificProperty(oWeap, ITEM_PROPERTY_DAMAGE_BONUS, IP_CONST_DAMAGETYPE_SLASHING, iPStrkBonus, 1, "PStrkBonus");
}
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;
}