PRC8/nwn/nwnprc/trunk/include/prc_inc_clsfunc.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
Updated AMS marker feats.  Removed arcane & divine marker feats.  Updated Dread Necromancer for epic progression. Updated weapon baseitem models.  Updated new weapons for crafting & npc equip.
 Updated prefix.  Updated release archive.
2024-02-11 14:01:05 -05:00

1620 lines
64 KiB
Plaintext

/*
Class functions.
This scripts holds all functions used for classes in includes.
This prevents us from having one include for each class or set of classes.
Stratovarius
*/
////////////////Begin Generic////////////////
// Function Definitions:
// Include Files:
#include "prc_inc_spells"
//#include "prc_alterations"
//#include "prcsp_engine"
//#include "prc_inc_function"
//#include "prc_x2_itemprop"
//#include "prc_class_const"
//#include "prc_feat_const"
//#include "prc_ipfeat_const"
//#include "inc_utility"
//
//#include "pnp_shft_poly"
//#include "x2_inc_spellhook"
//#include "prc_inc_combat"
//#include "prc_inc_sp_tch"
////////////////End Generic////////////////
////////////////Begin Drunken Master//////////////////////
// Function Definitions:
// Searches oPC's inventory and finds the first valid alcoholic beverage container
// (empty) and returns TRUE if a proper container was found. This function takes
// action and returns a boolean.
int UseBottle(object oPC);
// Searches oPC's inventory for an alcoholic beverage and if one is found it's
// destroyed and replaced by an empty container. This function is only used in
// the Breath of Fire spell script.
int UseAlcohol(object oPC = OBJECT_SELF);
// Removes all Alcohol effects for oTarget. Used in B o Flame.
void RemoveAlcoholEffects(object oTarget = OBJECT_SELF);
// Creates an empty bottle on oPC.
// sTag: the tag of the alcoholic beverage used (ale, spirits, wine)
void CreateBottleOnObject(object oPC, string sTag);
// Applies Drunk Like a Demno effects
void DrunkLikeDemon();
// Add the non-drunken master drinking effects.
void MakeDrunk(int nSpellID);
// Have the drunken master say one of 6 phrases.
void DrunkenMasterSpeakString();
// Creates an empty bottle on oPC.
// nBeverage: the spell id of the alcoholic beverage used (ale, spirits, wine)
void DrunkenMasterCreateEmptyBottle(int nSpellID);
// Determines the DC needed to save against the cast spell-like ability
// replace PRCGetSaveDC
int GetSpellDCSLA(object oCaster, int iSpelllvl,int iAbi = ABILITY_WISDOM);
void DoArchmageHeirophantSLA(object oPC, object oTarget, location lTarget, int nSLAID);
// Functions:
int UseBottle(object oPC)
{
object oItem = GetFirstItemInInventory(oPC);
//search oPC for a bottle:
string sTag;
while(oItem != OBJECT_INVALID)
{
sTag = GetTag(oItem);
if(sTag == "NW_IT_THNMISC001"
|| sTag == "NW_IT_THNMISC002"
|| sTag == "NW_IT_THNMISC003"
|| sTag == "NW_IT_THNMISC004")
{
SetPlotFlag(oItem, FALSE);
DestroyObject(oItem);
return TRUE;
}
else
oItem = GetNextItemInInventory();
}
return FALSE;
}
int UseAlcohol(object oPC = OBJECT_SELF)
{
object oItem = GetFirstItemInInventory(oPC);
//search oPC for alcohol:
string sTag = GetTag(oItem);
while(oItem != OBJECT_INVALID)
{
if(sTag == "NW_IT_MPOTION021"
|| sTag == "NW_IT_MPOTION022"
|| sTag == "NW_IT_MPOTION023"
|| sTag == "DragonsBreath")
{
SetPlotFlag(oItem, FALSE);
if(GetItemStackSize(oItem) > 1)
{
SetItemStackSize(oItem, GetItemStackSize(oItem) - 1);
// Create an Empty Bottle:
CreateBottleOnObject(oPC, sTag);
return TRUE;
}
else
{
DestroyObject(oItem);
// Create an Empty Bottle:
CreateBottleOnObject(oPC, sTag);
return TRUE;
}
}
else
oItem = GetNextItemInInventory();
}
return FALSE;
}
void CreateBottleOnObject(object oPC, string sTag)
{
if(sTag == "NW_IT_MPOTION021") // Ale
{
CreateItemOnObject("nw_it_thnmisc002", oPC);
}
else if(sTag == "NW_IT_MPOTION022") // Spirits
{
CreateItemOnObject("nw_it_thnmisc003", oPC);
}
else if(sTag == "NW_IT_MPOTION023") // Wine
{
CreateItemOnObject("nw_it_thnmisc004", oPC);
}
else // Other beverage
{
CreateItemOnObject("nw_it_thnmisc001", oPC);
}
}
int GetIsDrunk(object oTarget = OBJECT_SELF)
{
return GetHasSpellEffect(406, oTarget)
|| GetHasSpellEffect(407, oTarget)
|| GetHasSpellEffect(408, oTarget);
}
void RemoveAlcoholEffects(object oTarget = OBJECT_SELF)
{
PRCRemoveSpellEffects(406, OBJECT_SELF, oTarget);
PRCRemoveSpellEffects(407, OBJECT_SELF, oTarget);
PRCRemoveSpellEffects(408, OBJECT_SELF, oTarget);
}
void DrunkenRage()
{
float fDuration = GetLevelByClass(CLASS_TYPE_DRUNKEN_MASTER) > 9 ? HoursToSeconds(3) : HoursToSeconds(1);
effect eLink = EffectLinkEffects(EffectAbilityIncrease(ABILITY_STRENGTH, 4), EffectAbilityIncrease(ABILITY_CONSTITUTION, 4));
eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_WILL, 2));
eLink = EffectLinkEffects(eLink, EffectACDecrease(2));
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_BLUR));
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_AURA_FIRE));
eLink = ExtraordinaryEffect(eLink);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, fDuration);
FloatingTextStringOnCreature("Drunken Rage Activated", OBJECT_SELF);
}
void DrunkLikeDemon()
{
// A Drunken Master has had a drink. Add effects:
effect eLink = EffectLinkEffects(EffectAbilityIncrease(ABILITY_STRENGTH, 1), EffectAbilityIncrease(ABILITY_CONSTITUTION, 1));
eLink = EffectLinkEffects(eLink, EffectAbilityDecrease(ABILITY_WISDOM, 1));
eLink = EffectLinkEffects(eLink, EffectAbilityDecrease(ABILITY_INTELLIGENCE, 1));
eLink = EffectLinkEffects(eLink, EffectAbilityDecrease(ABILITY_DEXTERITY, 1));
eLink = EffectLinkEffects(eLink, EffectVisualEffect(VFX_DUR_BLUR));
//run checks to see if Dex Modifier will be changed:
if(!(GetAbilityModifier(ABILITY_DEXTERITY) % 2))
{
//restore AC, Ref save and Tumble to previous values
eLink = EffectLinkEffects(eLink, EffectACIncrease(1));
eLink = EffectLinkEffects(eLink, EffectSavingThrowIncrease(SAVING_THROW_REFLEX, 1));
eLink = EffectLinkEffects(eLink, EffectSkillIncrease(SKILL_TUMBLE, 1));
}
eLink = ExtraordinaryEffect(eLink);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, HoursToSeconds(1));
FloatingTextStringOnCreature("You are Drunk Like a Demon", OBJECT_SELF);
}
void MakeDrunk(int nSpellID)
{
if(Random(100) < 40)
AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING));
else
AssignCommand(OBJECT_SELF, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_DRUNK));
int nPoints;
switch(nSpellID)
{
case 406: nPoints = 1; break;//Ale
case 407: nPoints = 2; break;//Wine
case 408: nPoints = 3; break;//Spirits
}
//ApplyAbilityDamage(oTarget, ABILITY_INTELLIGENCE, nPoints, DURATION_TYPE_TEMPORARY, TRUE, 60.0);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, SupernaturalEffect(EffectAbilityDecrease(ABILITY_INTELLIGENCE, nPoints)), OBJECT_SELF, 60.0);
AssignCommand(OBJECT_SELF, ActionSpeakStringByStrRef(10499));
}
void DrunkenMasterSpeakString()
{
switch(d6())
{
case 1: AssignCommand(OBJECT_SELF, ActionSpeakString("Now that's the stuff!")); break;
case 2: AssignCommand(OBJECT_SELF, ActionSpeakString("That one really hit the spot!")); break;
case 3: AssignCommand(OBJECT_SELF, ActionSpeakString("That should keep me warm!")); break;
case 4: AssignCommand(OBJECT_SELF, ActionSpeakString("Good stuff!")); break;
case 5: AssignCommand(OBJECT_SELF, ActionSpeakString("Bless the Wine Gods!")); break;
case 6: AssignCommand(OBJECT_SELF, ActionSpeakString("Just what I needed!")); break;
}
}
void DrunkenMasterCreateEmptyBottle(int nSpellID)
{
switch(nSpellID)
{
case 406: CreateItemOnObject("nw_it_thnmisc002", OBJECT_SELF); break;//Ale
case 407: CreateItemOnObject("nw_it_thnmisc004", OBJECT_SELF); break;//Wine
case 408: CreateItemOnObject("nw_it_thnmisc003", OBJECT_SELF); break;//Spirits
default: CreateItemOnObject("nw_it_thnmisc001", OBJECT_SELF); break;//Other
}
}
////////////////End Drunken Master//////////////////
////////////////Begin Samurai//////////////////
// This function is probably utterly broken: the match found variable is not reset in the loop and the returned value will be equal to the last match - Ornedan
int GetPropertyValue(object oWeapon, int iType, int iSubType = -1, int bDebug = FALSE);
int GetPropertyValue(object oWeapon, int iType, int iSubType = -1, int bDebug = FALSE)
{
int bReturn = -1;
if(oWeapon == OBJECT_INVALID){return FALSE;}
int bMatch = FALSE;
if (GetItemHasItemProperty(oWeapon, iType))
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("It has the property."));}
itemproperty ip = GetFirstItemProperty(oWeapon);
while(GetIsItemPropertyValid(ip))
{
if(GetItemPropertyType(ip) == iType)
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Again..."));}
bMatch = TRUE;
if (iSubType > -1)
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Subtype Required."));}
if(GetItemPropertySubType(ip) != iSubType)
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Subtype wrong."));}
bMatch = FALSE;
}
else
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Subtype Correct."));}
}
}
}
if (bMatch)
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Match found."));}
if (GetItemPropertyCostTableValue(ip) > -1)
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Cost value found, returning."));}
bReturn = GetItemPropertyCostTableValue(ip);
}
else
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("No cost value for property, returning TRUE."));}
bReturn = 1;
}
}
else
{
if(bDebug){AssignCommand(GetFirstPC(), SpeakString("Match not found."));}
}
ip = GetNextItemProperty(oWeapon);
}
}
return bReturn;
}
void WeaponUpgradeVisual();
object GetSamuraiToken(object oSamurai);
void WeaponUpgradeVisual()
{
object oPC = GetPCSpeaker();
int iCost = GetLocalInt(oPC, "CODI_SAM_WEAPON_COST");
object oToken = GetSamuraiToken(oPC);
int iToken = StringToInt(GetTag(oToken));
int iGold = GetGold(oPC);
if(iGold + iToken < iCost)
{
SendMessageToPC(oPC, "You sense the gods are angered!");
AdjustAlignment(oPC, ALIGNMENT_CHAOTIC, 25, FALSE);
object oWeapon = GetItemPossessedBy(oPC, "codi_sam_mw");
DestroyObject(oWeapon);
return;
}
else if(iToken <= iCost)
{
iCost = iCost - iToken;
DestroyObject(oToken);
TakeGoldFromCreature(iCost, oPC, TRUE);
}
else if (iToken > iCost)
{
object oNewToken = CopyObject(oToken, GetLocation(oPC), oPC, IntToString(iToken - iCost));
DestroyObject(oToken);
}
effect eVis = EffectVisualEffect(VFX_FNF_DISPEL_DISJUNCTION);
AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,6.0));
AssignCommand(oPC, ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY2));
DelayCommand(0.1, SetCommandable(FALSE, oPC));
DelayCommand(6.5, SetCommandable(TRUE, oPC));
DelayCommand(5.0,ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oPC)));
}
object GetSamuraiToken(object oSamurai)
{
object oItem = GetFirstItemInInventory(oSamurai);
while(oItem != OBJECT_INVALID)
{
if(GetResRef(oItem) == "codi_sam_token")
{
return oItem;
}
oItem = GetNextItemInInventory(oSamurai);
}
return OBJECT_INVALID;
}
////////////////End Samurai//////////////////
////////////////Begin Vile Feat//////////////////
int Vile_Feat(int iTypeWeap)
{
switch(iTypeWeap)
{
case BASE_ITEM_BASTARDSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_BASTARDSWORD);
case BASE_ITEM_BATTLEAXE: return GetHasFeat(FEAT_VILE_MARTIAL_BATTLEAXE);
case BASE_ITEM_CLUB: return GetHasFeat(FEAT_VILE_MARTIAL_CLUB);
case BASE_ITEM_DAGGER: return GetHasFeat(FEAT_VILE_MARTIAL_DAGGER);
case BASE_ITEM_DART: return GetHasFeat(FEAT_VILE_MARTIAL_DART);
case BASE_ITEM_DIREMACE: return GetHasFeat(FEAT_VILE_MARTIAL_DIREMACE);
case BASE_ITEM_DOUBLEAXE: return GetHasFeat(FEAT_VILE_MARTIAL_DOUBLEAXE);
case BASE_ITEM_DWARVENWARAXE: return GetHasFeat(FEAT_VILE_MARTIAL_DWAXE);
case BASE_ITEM_GREATAXE: return GetHasFeat(FEAT_VILE_MARTIAL_GREATAXE);
case BASE_ITEM_GREATSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_GREATSWORD);
case BASE_ITEM_HALBERD: return GetHasFeat(FEAT_VILE_MARTIAL_HALBERD);
case BASE_ITEM_HANDAXE: return GetHasFeat(FEAT_VILE_MARTIAL_HANDAXE);
case BASE_ITEM_HEAVYCROSSBOW: return GetHasFeat(FEAT_VILE_MARTIAL_HEAVYCROSSBOW);
case BASE_ITEM_HEAVYFLAIL: return GetHasFeat(FEAT_VILE_MARTIAL_HEAVYFLAIL);
case BASE_ITEM_KAMA: return GetHasFeat(FEAT_VILE_MARTIAL_KAMA);
case BASE_ITEM_KATANA: return GetHasFeat(FEAT_VILE_MARTIAL_KATANA);
case BASE_ITEM_KUKRI: return GetHasFeat(FEAT_VILE_MARTIAL_KUKRI);
case BASE_ITEM_LIGHTCROSSBOW: return GetHasFeat(FEAT_VILE_MARTIAL_LIGHTCROSSBOW);
case BASE_ITEM_LIGHTFLAIL: return GetHasFeat(FEAT_VILE_MARTIAL_LIGHTFLAIL);
case BASE_ITEM_LIGHTHAMMER: return GetHasFeat(FEAT_VILE_MARTIAL_LIGHTHAMMER);
case BASE_ITEM_LIGHTMACE: return GetHasFeat(FEAT_VILE_MARTIAL_MACE);
case BASE_ITEM_LONGBOW: return GetHasFeat(FEAT_VILE_MARTIAL_LONGBOW);
case BASE_ITEM_LONGSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_LONGSWORD);
case BASE_ITEM_MORNINGSTAR: return GetHasFeat(FEAT_VILE_MARTIAL_MORNINGSTAR);
case BASE_ITEM_QUARTERSTAFF: return GetHasFeat(FEAT_VILE_MARTIAL_QUARTERSTAFF);
case BASE_ITEM_RAPIER: return GetHasFeat(FEAT_VILE_MARTIAL_RAPIER);
case BASE_ITEM_SCIMITAR: return GetHasFeat(FEAT_VILE_MARTIAL_SCIMITAR);
case BASE_ITEM_SCYTHE: return GetHasFeat(FEAT_VILE_MARTIAL_SCYTHE);
case BASE_ITEM_SHORTBOW: return GetHasFeat(FEAT_VILE_MARTIAL_SHORTBOW);
case BASE_ITEM_SHORTSPEAR: return GetHasFeat(FEAT_VILE_MARTIAL_SPEAR);
case BASE_ITEM_SHORTSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_SHORTSWORD);
case BASE_ITEM_SHURIKEN: return GetHasFeat(FEAT_VILE_MARTIAL_SHURIKEN);
case BASE_ITEM_SLING: return GetHasFeat(FEAT_VILE_MARTIAL_SLING);
case BASE_ITEM_SICKLE: return GetHasFeat(FEAT_VILE_MARTIAL_SICKLE);
case BASE_ITEM_TWOBLADEDSWORD: return GetHasFeat(FEAT_VILE_MARTIAL_TWOBLADED);
case BASE_ITEM_WARHAMMER: return GetHasFeat(FEAT_VILE_MARTIAL_WARHAMMER);
case BASE_ITEM_WHIP: return GetHasFeat(FEAT_VILE_MARTIAL_WHIP);
case BASE_ITEM_TRIDENT: return GetHasFeat(FEAT_VILE_MARTIAL_TRIDENT);
//new items
case BASE_ITEM_ELVEN_LIGHTBLADE: return (GetHasFeat(FEAT_VILE_MARTIAL_SHORTSWORD) || GetHasFeat(FEAT_VILE_MARTIAL_RAPIER));
case BASE_ITEM_ELVEN_THINBLADE: return (GetHasFeat(FEAT_VILE_MARTIAL_LONGSWORD) || GetHasFeat(FEAT_VILE_MARTIAL_RAPIER));
case BASE_ITEM_ELVEN_COURTBLADE: return GetHasFeat(FEAT_VILE_MARTIAL_GREATSWORD);
}
return FALSE;
}
////////////////End Vile Feat//////////////////
////////////////Begin Soul Inc//////////////////
const int IPRP_CONST_ONHIT_DURATION_5_PERCENT_1_ROUNDS = 20;
int Sanctify_Feat(int iTypeWeap)
{
switch(iTypeWeap)
{
case BASE_ITEM_BASTARDSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_BASTARDSWORD);
case BASE_ITEM_BATTLEAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_BATTLEAXE);
case BASE_ITEM_CLUB: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_CLUB);
case BASE_ITEM_DAGGER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DAGGER);
case BASE_ITEM_DART: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DART);
case BASE_ITEM_DIREMACE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DIREMACE);
case BASE_ITEM_DOUBLEAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DOUBLEAXE);
case BASE_ITEM_DWARVENWARAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_DWAXE);
case BASE_ITEM_GREATAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_GREATAXE);
case BASE_ITEM_GREATSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_GREATSWORD);
case BASE_ITEM_HALBERD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HALBERD);
case BASE_ITEM_HANDAXE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HANDAXE);
case BASE_ITEM_HEAVYCROSSBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HEAVYCROSSBOW);
case BASE_ITEM_HEAVYFLAIL: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_HEAVYFLAIL);
case BASE_ITEM_KAMA: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_KAMA);
case BASE_ITEM_KATANA: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_KATANA);
case BASE_ITEM_KUKRI: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_KUKRI);
case BASE_ITEM_LIGHTCROSSBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LIGHTCROSSBOW);
case BASE_ITEM_LIGHTFLAIL: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LIGHTFLAIL);
case BASE_ITEM_LIGHTHAMMER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LIGHTHAMMER);
case BASE_ITEM_LIGHTMACE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_MACE);
case BASE_ITEM_LONGBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LONGBOW);
case BASE_ITEM_LONGSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_LONGSWORD);
case BASE_ITEM_MORNINGSTAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_MORNINGSTAR);
case BASE_ITEM_QUARTERSTAFF: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_QUARTERSTAFF);
case BASE_ITEM_RAPIER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_RAPIER);
case BASE_ITEM_SCIMITAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SCIMITAR);
case BASE_ITEM_SCYTHE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SCYTHE);
case BASE_ITEM_SHORTBOW: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHORTBOW);
case BASE_ITEM_SHORTSPEAR: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SPEAR);
case BASE_ITEM_SHORTSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHORTSWORD);
case BASE_ITEM_SHURIKEN: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHURIKEN);
case BASE_ITEM_SLING: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SLING);
case BASE_ITEM_SICKLE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_SICKLE);
case BASE_ITEM_TWOBLADEDSWORD: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_TWOBLADED);
case BASE_ITEM_WARHAMMER: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_WARHAMMER);
case BASE_ITEM_WHIP: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_WHIP);
case BASE_ITEM_TRIDENT: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_TRIDENT);
//new items
case BASE_ITEM_ELVEN_LIGHTBLADE: return (GetHasFeat(FEAT_SANCTIFY_MARTIAL_SHORTSWORD) || GetHasFeat(FEAT_SANCTIFY_MARTIAL_RAPIER));
case BASE_ITEM_ELVEN_THINBLADE: return (GetHasFeat(FEAT_SANCTIFY_MARTIAL_LONGSWORD) || GetHasFeat(FEAT_SANCTIFY_MARTIAL_RAPIER));
case BASE_ITEM_ELVEN_COURTBLADE: return GetHasFeat(FEAT_SANCTIFY_MARTIAL_GREATSWORD);
}
return FALSE;
}
int DamageConv(int iMonsDmg)
{
switch(iMonsDmg)
{
case IP_CONST_MONSTERDAMAGE_1d4: return 1;
case IP_CONST_MONSTERDAMAGE_1d6: return 2;
case IP_CONST_MONSTERDAMAGE_1d8: return 3;
case IP_CONST_MONSTERDAMAGE_1d10: return 4;
case IP_CONST_MONSTERDAMAGE_1d12: return 5;
case IP_CONST_MONSTERDAMAGE_1d20: return 6;
case IP_CONST_MONSTERDAMAGE_2d4: return 10;
case IP_CONST_MONSTERDAMAGE_2d6: return 11;
case IP_CONST_MONSTERDAMAGE_2d8: return 12;
case IP_CONST_MONSTERDAMAGE_2d10: return 13;
case IP_CONST_MONSTERDAMAGE_2d12: return 14;
case IP_CONST_MONSTERDAMAGE_2d20: return 15;
case IP_CONST_MONSTERDAMAGE_3d4: return 20;
case IP_CONST_MONSTERDAMAGE_3d6: return 21;
case IP_CONST_MONSTERDAMAGE_3d8: return 22;
case IP_CONST_MONSTERDAMAGE_3d10: return 23;
case IP_CONST_MONSTERDAMAGE_3d12: return 24;
case IP_CONST_MONSTERDAMAGE_3d20: return 25;
}
return 0;
}
int ConvMonsterDmg(int iMonsDmg)
{
switch(iMonsDmg)
{
case 1: return IP_CONST_MONSTERDAMAGE_1d4;
case 2: return IP_CONST_MONSTERDAMAGE_1d6;
case 3: return IP_CONST_MONSTERDAMAGE_1d8;
case 4: return IP_CONST_MONSTERDAMAGE_1d10;
case 5: return IP_CONST_MONSTERDAMAGE_1d12;
case 6: return IP_CONST_MONSTERDAMAGE_1d20;
case 10: return IP_CONST_MONSTERDAMAGE_2d4;
case 11: return IP_CONST_MONSTERDAMAGE_2d6;
case 12: return IP_CONST_MONSTERDAMAGE_2d8;
case 13: return IP_CONST_MONSTERDAMAGE_2d10;
case 14: return IP_CONST_MONSTERDAMAGE_2d12;
case 15: return IP_CONST_MONSTERDAMAGE_2d20;
case 20: return IP_CONST_MONSTERDAMAGE_3d4;
case 21: return IP_CONST_MONSTERDAMAGE_3d6;
case 22: return IP_CONST_MONSTERDAMAGE_3d8;
case 23: return IP_CONST_MONSTERDAMAGE_3d10;
case 24: return IP_CONST_MONSTERDAMAGE_3d12;
case 25: return IP_CONST_MONSTERDAMAGE_3d20;
}
return 0;
}
int MonsterDamage(object oItem)
{
int iBonus;
int iTemp;
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
if(GetItemPropertyType(ip) == ITEM_PROPERTY_MONSTER_DAMAGE)
{
iTemp = GetItemPropertyCostTableValue(ip);
iBonus = iTemp > iBonus ? iTemp : iBonus;
}
ip = GetNextItemProperty(oItem);
}
return iBonus;
}
int FeatIniDmg(object oItem)
{
itemproperty ip = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(ip))
{
if(GetItemPropertyType(ip) == ITEM_PROPERTY_BONUS_FEAT)
{
if(GetItemPropertySubType(ip) == IP_CONST_FEAT_WeapFocCreature)
return 1;
}
ip = GetNextItemProperty(oItem);
}
return 0;
}
void AddIniDmg(object oPC)
{
int bUnarmedDmg = GetHasFeat(FEAT_INCREASE_DAMAGE1, oPC)
+ GetHasFeat(FEAT_INCREASE_DAMAGE2, oPC);
if(!bUnarmedDmg)
return;
object oCweapB = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oPC);
object oCweapL = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oPC);
object oCweapR = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oPC);
int iDmg;
int iConv;
int iStr = GetAbilityModifier(ABILITY_STRENGTH, oPC);
int iWis = GetAbilityModifier(ABILITY_WISDOM, oPC);
iWis = iWis > iStr ? iWis : 0;
/*if(GetHasFeat(FEAT_INTUITIVE_ATTACK, oPC))
{
SetCompositeBonusT(oCweapB,"",iWis,ITEM_PROPERTY_ATTACK_BONUS);
SetCompositeBonusT(oCweapL,"",iWis,ITEM_PROPERTY_ATTACK_BONUS);
SetCompositeBonusT(oCweapR,"",iWis,ITEM_PROPERTY_ATTACK_BONUS);
}
if (GetHasFeat(FEAT_RAVAGEGOLDENICE, oPC))
{
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_RAVAGEGOLDENICE,2),oCweapB,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_RAVAGEGOLDENICE,2),oCweapL,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_RAVAGEGOLDENICE,2),oCweapR,9999.0);
}*/
if ( oCweapB != OBJECT_INVALID && !FeatIniDmg(oCweapB))
{
iDmg = MonsterDamage(oCweapB);
iConv = DamageConv(iDmg) + bUnarmedDmg;
iConv = (iConv > 6 && iConv < 10) ? 6 : iConv;
iConv = (iConv > 15 && iConv < 20) ? 15 : iConv;
iConv = (iConv > 25) ? 25 : iConv;
iConv = ConvMonsterDmg(iConv);
TotalAndRemoveProperty(oCweapB,ITEM_PROPERTY_MONSTER_DAMAGE,-1);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyMonsterDamage(iConv),oCweapB);
//AddItemProperty(DURATION_TYPE_PERMANENT,PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature),oCweapB);
IPSafeAddItemProperty(oCweapB, PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
if ( oCweapL != OBJECT_INVALID && !FeatIniDmg(oCweapL))
{
iDmg = MonsterDamage(oCweapL);
iConv = DamageConv(iDmg) + bUnarmedDmg;
iConv = (iConv > 6 && iConv < 10) ? 6 : iConv;
iConv = (iConv > 15 && iConv < 20) ? 15 : iConv;
iConv = (iConv > 25) ? 25 : iConv;
iConv = ConvMonsterDmg(iConv);
TotalAndRemoveProperty(oCweapL,ITEM_PROPERTY_MONSTER_DAMAGE,-1);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyMonsterDamage(iConv),oCweapL);
//AddItemProperty(DURATION_TYPE_PERMANENT,PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature),oCweapL);
IPSafeAddItemProperty(oCweapL, PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
if ( oCweapR != OBJECT_INVALID && !FeatIniDmg(oCweapR))
{
iDmg = MonsterDamage(oCweapR);
iConv = DamageConv(iDmg) + bUnarmedDmg;
iConv = (iConv > 6 && iConv < 10) ? 6 : iConv;
iConv = (iConv > 15 && iConv < 20) ? 15 : iConv;
iConv = (iConv > 25) ? 25 : iConv;
iConv = ConvMonsterDmg(iConv);
TotalAndRemoveProperty(oCweapR,ITEM_PROPERTY_MONSTER_DAMAGE,-1);
AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyMonsterDamage(iConv),oCweapR);
//AddItemProperty(DURATION_TYPE_PERMANENT,PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature),oCweapR);
IPSafeAddItemProperty(oCweapR, PRCItemPropertyBonusFeat(IP_CONST_FEAT_WeapFocCreature), 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
}
void AddCriti(object oPC,object oSkin,int ip_feat_crit,int nFeat)
{
// Do not add multiple instances of the same bonus feat iprop, it lags the game
AddSkinFeat(nFeat, ip_feat_crit, oSkin, oPC);
}
void ImpCrit(object oPC,object oSkin)
{
if(GetHasFeat(FEAT_WEAPON_FOCUS_BASTARD_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_BASTARD_SWORD, FEAT_IMPROVED_CRITICAL_BASTARD_SWORD);
if(GetHasFeat(FEAT_WEAPON_FOCUS_BATTLE_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_BATTLE_AXE, FEAT_IMPROVED_CRITICAL_BATTLE_AXE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_CLUB, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_CLUB, FEAT_IMPROVED_CRITICAL_CLUB);
if(GetHasFeat(FEAT_WEAPON_FOCUS_DAGGER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DAGGER, FEAT_IMPROVED_CRITICAL_DAGGER);
if(GetHasFeat(FEAT_WEAPON_FOCUS_DART, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DART, FEAT_IMPROVED_CRITICAL_DART);
if(GetHasFeat(FEAT_WEAPON_FOCUS_DIRE_MACE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DIRE_MACE, FEAT_IMPROVED_CRITICAL_DIRE_MACE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_DOUBLE_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DOUBLE_AXE, FEAT_IMPROVED_CRITICAL_DOUBLE_AXE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_DWAXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_DWAXE, FEAT_IMPROVED_CRITICAL_DWAXE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_GREAT_AXE, FEAT_IMPROVED_CRITICAL_GREAT_AXE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_GREAT_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_GREAT_SWORD, FEAT_IMPROVED_CRITICAL_GREAT_SWORD);
if(GetHasFeat(FEAT_WEAPON_FOCUS_HALBERD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HALBERD, FEAT_IMPROVED_CRITICAL_HALBERD);
if(GetHasFeat(FEAT_WEAPON_FOCUS_HAND_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HAND_AXE, FEAT_IMPROVED_CRITICAL_HAND_AXE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_CROSSBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HEAVY_CROSSBOW, FEAT_IMPROVED_CRITICAL_HEAVY_CROSSBOW);
if(GetHasFeat(FEAT_WEAPON_FOCUS_HEAVY_FLAIL, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_HEAVY_FLAIL, FEAT_IMPROVED_CRITICAL_HEAVY_FLAIL);
if(GetHasFeat(FEAT_WEAPON_FOCUS_KAMA, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_KAMA, FEAT_IMPROVED_CRITICAL_KAMA);
if(GetHasFeat(FEAT_WEAPON_FOCUS_KATANA, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_KATANA, FEAT_IMPROVED_CRITICAL_KATANA);
if(GetHasFeat(FEAT_WEAPON_FOCUS_KUKRI, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_KUKRI, FEAT_IMPROVED_CRITICAL_KUKRI);
if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_CROSSBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_CROSSBOW, FEAT_IMPROVED_CRITICAL_LIGHT_CROSSBOW);
if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_FLAIL, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_FLAIL, FEAT_IMPROVED_CRITICAL_LIGHT_FLAIL);
if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_HAMMER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_HAMMER, FEAT_IMPROVED_CRITICAL_LIGHT_HAMMER);
if(GetHasFeat(FEAT_WEAPON_FOCUS_LIGHT_MACE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LIGHT_MACE, FEAT_IMPROVED_CRITICAL_LIGHT_MACE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_LONG_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LONG_SWORD, FEAT_IMPROVED_CRITICAL_LONG_SWORD);
if(GetHasFeat(FEAT_WEAPON_FOCUS_LONGBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_LONGBOW, FEAT_IMPROVED_CRITICAL_LONGBOW);
if(GetHasFeat(FEAT_WEAPON_FOCUS_MORNING_STAR, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_MORNING_STAR, FEAT_IMPROVED_CRITICAL_MORNING_STAR);
if(GetHasFeat(FEAT_WEAPON_FOCUS_RAPIER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_RAPIER, FEAT_IMPROVED_CRITICAL_RAPIER);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SCIMITAR, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SCIMITAR, FEAT_IMPROVED_CRITICAL_SCIMITAR);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SCYTHE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SCYTHE, FEAT_IMPROVED_CRITICAL_SCYTHE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SHORT_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SHORT_SWORD, FEAT_IMPROVED_CRITICAL_SHORT_SWORD);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SHORTBOW, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SHORTBOW, FEAT_IMPROVED_CRITICAL_SHORTBOW);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SHURIKEN, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SHURIKEN, FEAT_IMPROVED_CRITICAL_SHURIKEN);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SICKLE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SICKLE, FEAT_IMPROVED_CRITICAL_SICKLE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SLING, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SLING, FEAT_IMPROVED_CRITICAL_SLING);
if(GetHasFeat(FEAT_WEAPON_FOCUS_SPEAR, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_SPEAR, FEAT_IMPROVED_CRITICAL_SPEAR);
if(GetHasFeat(FEAT_WEAPON_FOCUS_STAFF, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_STAFF, FEAT_IMPROVED_CRITICAL_STAFF);
if(GetHasFeat(FEAT_WEAPON_FOCUS_THROWING_AXE, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_THROWING_AXE, FEAT_IMPROVED_CRITICAL_THROWING_AXE);
if(GetHasFeat(FEAT_WEAPON_FOCUS_TWO_BLADED_SWORD, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_TWO_BLADED_SWORD, FEAT_IMPROVED_CRITICAL_TWO_BLADED_SWORD);
if(GetHasFeat(FEAT_WEAPON_FOCUS_WAR_HAMMER, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_WAR_HAMMER, FEAT_IMPROVED_CRITICAL_WAR_HAMMER);
if(GetHasFeat(FEAT_WEAPON_FOCUS_WHIP, oPC)) AddCriti(oPC, oSkin, IP_CONST_FEAT_IMPROVED_CRITICAL_WHIP, FEAT_IMPROVED_CRITICAL_WHIP);
}
////////////////End Soul Inc//////////////////
////////////////Begin Martial Strike//////////////////
void MartialStrike()
{
object oItem;
object oPC = OBJECT_SELF;
int iEquip=GetLocalInt(oPC,"ONEQUIP");
int iType;
if (iEquip==2)
{
if (!GetHasFeat(FEAT_HOLY_MARTIAL_STRIKE)) return;
oItem=GetItemLastEquipped();
iType= GetBaseItemType(oItem);
switch (iType)
{
case BASE_ITEM_BOLT:
case BASE_ITEM_BULLET:
case BASE_ITEM_ARROW:
iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND));
break;
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LONGBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS);
break;
case BASE_ITEM_LIGHTCROSSBOW:
case BASE_ITEM_HEAVYCROSSBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS);
break;
case BASE_ITEM_SLING:
oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS);
break;
}
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_HOLY),oItem,9999.0);
SetLocalInt(oItem,"MartialStrik",1);
}
else if (iEquip==1)
{
oItem=GetItemLastUnequipped();
iType= GetBaseItemType(oItem);
switch (iType)
{
case BASE_ITEM_BOLT:
case BASE_ITEM_BULLET:
case BASE_ITEM_ARROW:
iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND));
break;
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LONGBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS);
break;
case BASE_ITEM_LIGHTCROSSBOW:
case BASE_ITEM_HEAVYCROSSBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS);
break;
case BASE_ITEM_SLING:
oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS);
break;
}
if ( GetLocalInt(oItem,"MartialStrik"))
{
RemoveSpecificProperty(oItem,ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP,IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGEBONUS_2d6, 1,"",IP_CONST_DAMAGETYPE_DIVINE,DURATION_TYPE_TEMPORARY);
RemoveSpecificProperty(oItem,ITEM_PROPERTY_VISUALEFFECT,ITEM_VISUAL_HOLY,-1,1,"",-1,DURATION_TYPE_TEMPORARY);
DeleteLocalInt(oItem,"MartialStrik");
}
}
else
{
if (!GetHasFeat(FEAT_HOLY_MARTIAL_STRIKE)) return;
oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
iType= GetBaseItemType(oItem);
switch (iType)
{
case BASE_ITEM_BOLT:
case BASE_ITEM_BULLET:
case BASE_ITEM_ARROW:
iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND));
break;
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LONGBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS);
break;
case BASE_ITEM_LIGHTCROSSBOW:
case BASE_ITEM_HEAVYCROSSBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS);
break;
case BASE_ITEM_SLING:
oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS);
break;
}
if (!GetLocalInt(oItem,"MartialStrik"))
{
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_HOLY),oItem,9999.0);
SetLocalInt(oItem,"MartialStrik",1);
}
oItem=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
iType= GetBaseItemType(oItem);
if ( !GetLocalInt(oItem,"MartialStrik"))
{
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_EVIL,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_HOLY),oItem,9999.0);
SetLocalInt(oItem,"MartialStrik",1);
}
}
}
void UnholyStrike()
{
object oItem;
object oPC = OBJECT_SELF;
int iEquip=GetLocalInt(oPC,"ONEQUIP");
int iType;
if (iEquip==2)
{
if (!GetHasFeat(FEAT_UNHOLY_STRIKE)) return;
oItem=GetItemLastEquipped();
iType= GetBaseItemType(oItem);
switch (iType)
{
case BASE_ITEM_BOLT:
case BASE_ITEM_BULLET:
case BASE_ITEM_ARROW:
iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND));
break;
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LONGBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS);
break;
case BASE_ITEM_LIGHTCROSSBOW:
case BASE_ITEM_HEAVYCROSSBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS);
break;
case BASE_ITEM_SLING:
oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS);
break;
}
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_EVIL),oItem,9999.0);
SetLocalInt(oItem,"UnholyStrik",1);
}
else if (iEquip==1)
{
oItem=GetItemLastUnequipped();
iType= GetBaseItemType(oItem);
switch (iType)
{
case BASE_ITEM_BOLT:
case BASE_ITEM_BULLET:
case BASE_ITEM_ARROW:
iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND));
break;
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LONGBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS);
break;
case BASE_ITEM_LIGHTCROSSBOW:
case BASE_ITEM_HEAVYCROSSBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS);
break;
case BASE_ITEM_SLING:
oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS);
break;
}
if ( GetLocalInt(oItem,"UnholyStrik"))
{
RemoveSpecificProperty(oItem,ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP,IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGEBONUS_2d6, 1,"",IP_CONST_DAMAGETYPE_DIVINE,DURATION_TYPE_TEMPORARY);
RemoveSpecificProperty(oItem,ITEM_PROPERTY_VISUALEFFECT,ITEM_VISUAL_EVIL,-1,1,"",-1,DURATION_TYPE_TEMPORARY);
DeleteLocalInt(oItem,"UnholyStrik");
}
}
else
{
if (!GetHasFeat(FEAT_UNHOLY_STRIKE)) return;
oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oPC);
iType= GetBaseItemType(oItem);
switch (iType)
{
case BASE_ITEM_BOLT:
case BASE_ITEM_BULLET:
case BASE_ITEM_ARROW:
iType=GetBaseItemType(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND));
break;
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LONGBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_ARROWS);
break;
case BASE_ITEM_LIGHTCROSSBOW:
case BASE_ITEM_HEAVYCROSSBOW:
oItem=GetItemInSlot(INVENTORY_SLOT_BOLTS);
break;
case BASE_ITEM_SLING:
oItem=GetItemInSlot(INVENTORY_SLOT_BULLETS);
break;
}
if (!GetLocalInt(oItem,"UnholyStrik"))
{
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_EVIL),oItem,9999.0);
SetLocalInt(oItem,"UnholyStrik",1);
}
oItem=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oPC);
iType= GetBaseItemType(oItem);
if ( !GetLocalInt(oItem,"UnholyStrik"))
{
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyDamageBonusVsAlign(IP_CONST_ALIGNMENTGROUP_GOOD,IP_CONST_DAMAGETYPE_DIVINE,IP_CONST_DAMAGEBONUS_2d6),oItem,9999.0);
AddItemProperty(DURATION_TYPE_TEMPORARY,ItemPropertyVisualEffect(ITEM_VISUAL_EVIL),oItem,9999.0);
SetLocalInt(oItem,"UnholyStrik",1);
}
}
}
////////////////End Martial Strike//////////////////
////////////////Begin Soldier of Light Spells//////////////////
/* As far as I can tell, not used at all - Ornedan
void spellsCureMod(int nCasterLvl ,int nDamage, int nMaxExtraDamage, int nMaximized, int vfx_impactHurt, int vfx_impactHeal, int nSpellID)
{
//Declare major variables
object oTarget = PRCGetSpellTargetObject();
int nHeal;
int nMetaMagic = PRCGetMetaMagicFeat();
effect eVis = EffectVisualEffect(vfx_impactHurt);
effect eVis2 = EffectVisualEffect(vfx_impactHeal);
effect eHeal, eDam;
int nExtraDamage = nCasterLvl; // * figure out the bonus damage
if (nExtraDamage > nMaxExtraDamage)
{
nExtraDamage = nMaxExtraDamage;
}
// * if low or normal difficulty is treated as MAXIMIZED
if(GetIsPC(oTarget) && GetGameDifficulty() < GAME_DIFFICULTY_CORE_RULES)
{
nDamage = nMaximized + nExtraDamage;
}
else
{
nDamage = nDamage + nExtraDamage;
}
//Make metamagic checks
int iBlastFaith = BlastInfidelOrFaithHeal(OBJECT_SELF, oTarget, DAMAGE_TYPE_POSITIVE, TRUE);
if (nMetaMagic & METAMAGIC_MAXIMIZE || iBlastFaith)
{
nDamage = nMaximized + nExtraDamage;
// * if low or normal difficulty then MAXMIZED is doubled.
if(GetIsPC(OBJECT_SELF) && GetGameDifficulty() < GAME_DIFFICULTY_CORE_RULES)
{
nDamage = nDamage + nExtraDamage;
}
}
if (nMetaMagic & METAMAGIC_EMPOWER || GetHasFeat(FEAT_HEALING_DOMAIN_POWER))
{
nDamage = nDamage + (nDamage/2);
}
if (MyPRCGetRacialType(oTarget) != RACIAL_TYPE_UNDEAD)
{
//Figure out the amount of damage to heal
nHeal = nDamage;
//Set the heal effect
eHeal = EffectHeal(nHeal);
//Apply heal effect and VFX impact
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget);
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpellID, FALSE));
}
//Check that the target is undead
else
{
int nTouch = PRCDoMeleeTouchAttack(oTarget);;
if (nTouch > 0)
{
if(!GetIsReactionTypeFriendly(oTarget))
{
//Fire cast spell at event for the specified target
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpellID));
if (!PRCDoResistSpell(OBJECT_SELF, oTarget,nCasterLvl+add_spl_pen(OBJECT_SELF)))
{
eDam = EffectDamage(nDamage,DAMAGE_TYPE_NEGATIVE);
//Apply the VFX impact and effects
DelayCommand(1.0, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
}
}
}
}
*/
////////////////End Soldier of Light Spells//////////////////
////////////////Begin Master Harper Instruments//////////////////
void ActiveModeCIMM(object oTarget)
{
if(!GetLocalInt(oTarget,"use_CIMM") )
{
string sScript = GetModuleOverrideSpellscript();
if (sScript != "mh_spell_at_inst")
{
SetLocalString(OBJECT_SELF,"temp_spell_at_inst",sScript);
SetLocalString(OBJECT_SELF, "PRC_OVERRIDE_SPELLSCRIPT", "mh_spell_at_inst");
}
SetLocalInt(OBJECT_SELF,"nb_spell_at_inst",GetLocalInt(OBJECT_SELF,"nb_spell_at_inst")+1);
FloatingTextStrRefOnCreature(16825240,oTarget);
SetLocalInt(oTarget,"use_CIMM",TRUE);
}
}
void UnactiveModeCIMM(object oTarget)
{
if(GetLocalInt(oTarget,"use_CIMM") )
{
string sScript = GetModuleOverrideSpellscript();
SetLocalInt(OBJECT_SELF,"nb_spell_at_inst",GetLocalInt(OBJECT_SELF,"nb_spell_at_inst")-1);
if (sScript == "mh_spell_at_inst" && GetLocalInt(OBJECT_SELF,"nb_spell_at_inst") == 0)
{
SetLocalString(OBJECT_SELF, "PRC_OVERRIDE_SPELLSCRIPT", GetLocalString(OBJECT_SELF,"temp_spell_at_inst"));
GetLocalString(OBJECT_SELF,"temp_spell_at_inst");
SetLocalString(OBJECT_SELF,"temp_spell_at_inst","");
}
FloatingTextStrRefOnCreature(16825241,oTarget);
SetLocalInt(oTarget,"use_CIMM",FALSE);
}
}
////////////////End Master Harper Instruments//////////////////
////////////////Begin Minstrel of the Edge//////////////////
// Goes a bit further than RemoveSpellEffects -- makes sure to remove ALL effects
// made by the Singer+Song.
void RemoveSongEffects(int iSong, object oCaster, object oTarget)
{
effect eCheck = GetFirstEffect(oTarget);
while (GetIsEffectValid(eCheck))
{
if (GetEffectCreator(eCheck) == oCaster && GetEffectSpellId(eCheck) == iSong)
RemoveEffect(oTarget, eCheck);
eCheck = GetNextEffect(oTarget);
}
}
// Stores a Song recipient to the PC as a local variable, and creates a list by using
// an index variable.
void StoreSongRecipient(object oRecipient, object oSinger, int iSongID, int iDuration = 0)
{
int iSlot = GetLocalInt(oSinger, "SONG_SLOT");
int iIndex = GetLocalInt(oSinger, "SONG_INDEX_" + IntToString(iSlot)) + 1;
string sIndex = "SONG_INDEX_" + IntToString(iSlot);
string sRecip = "SONG_RECIPIENT_" + IntToString(iIndex) + "_" + IntToString(iSlot);
string sSong = "SONG_IN_USE_" + IntToString(iSlot);
// Store the recipient into the current used slot
SetLocalObject(oSinger, sRecip, oRecipient);
// Store the song information
SetLocalInt(oSinger, sSong, iSongID);
// Store the index of creatures we're on
SetLocalInt(oSinger, sIndex, iIndex);
}
// Removes all effects given by the previous song from all creatures who recieved it.
// Now allows for two "slots", which means you can perform two songs at a time.
void RemoveOldSongEffects(object oSinger, int iSongID)
{
object oCreature;
int iSlotNow = GetLocalInt(oSinger, "SONG_SLOT");
int iSlot;
int iNumRecip;
int iSongInUse;
int iIndex;
string sIndex;
string sRecip;
string sSong;
if (GetHasFeat(FEAT_MINSTREL_GREATER_MINSTREL_SONG, oSinger))
{
// If you use the same song twice in a row you
// should deal with the same slot again...
if (GetLocalInt(oSinger, "SONG_IN_USE_" + IntToString(iSlotNow)) == iSongID)
iSlot = iSlotNow;
// Otherwise, we should toggle between slot "1" and slot "0"
else
iSlot = (iSlotNow == 1) ? 0 : 1;
}
else
{
iSlot = 0;
}
// Save the toggle we're on for later.
SetLocalInt(oSinger, "SONG_SLOT", iSlot);
// Find the proper variable names based on slot
sIndex = "SONG_INDEX_" + IntToString(iSlot);
sSong = "SONG_IN_USE_" + IntToString(iSlot);
// Store the local variables into script variables
iNumRecip = GetLocalInt(oSinger, sIndex);
iSongInUse = GetLocalInt(oSinger, sSong);
// Reset the local variables
SetLocalInt(oSinger, sIndex, 0);
SetLocalInt(oSinger, sSong, 0);
// Removes any effects from the caster first
RemoveSongEffects(iSongInUse, oSinger, oSinger);
// Removes any effects from the recipients
for (iIndex = 1 ; iIndex <= iNumRecip ; iIndex++)
{
sRecip = "SONG_RECIPIENT_" + IntToString(iIndex) + "_" + IntToString(iSlot);
oCreature = GetLocalObject(oSinger, sRecip);
RemoveSongEffects(iSongInUse, oSinger, oCreature);
}
}
////////////////End Minstrel of the Edge//////////////////
////////////////Begin Arcane Duelist//////////////////
void FlurryEffects(object oPC)
{
effect Effect1 = EffectModifyAttacks(1);
effect Effect2 = EffectAttackDecrease(2, ATTACK_BONUS_MISC);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, Effect1, oPC, RoundsToSeconds(10));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, Effect2, oPC, RoundsToSeconds(10));
}
void CheckCombatDexAttack(object oPC)
{
//object oPC = GetLocalObject(OBJECT_SELF, "PC_IN_COMBAT_WITH_DEXATTACK_ON");
int iCombat = GetIsInCombat(oPC);
object oWeapon = GetLocalObject(oPC, "CHOSEN_WEAPON");
if(iCombat == TRUE && GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC) == oWeapon)
{
DelayCommand(6.0, CheckCombatDexAttack(oPC));
}
else
{
FloatingTextStringOnCreature("Dexterous Attack Mode Deactivated", oPC, FALSE);
effect eEffects = GetFirstEffect(oPC);
while (GetIsEffectValid(eEffects))
{
if (GetEffectType(eEffects) == EFFECT_TYPE_ATTACK_INCREASE && GetEffectSpellId(eEffects) == 1761) // dextrous attack
{
RemoveEffect(oPC, eEffects);
}
eEffects = GetNextEffect(oPC);
}
DeleteLocalObject(OBJECT_SELF, "PC_IN_COMBAT_WITH_DEXATTACK_ON");
}
}
void SPMakeAttack(object oTarget, object oImage)
{
int iDead = GetIsDead(oTarget);
if(iDead == FALSE)
{
PrintString("TARGET AINT DEAD");
DelayCommand(6.0, SPMakeAttack(oTarget, oImage));
AssignCommand(oImage, ActionAttack(oTarget, FALSE));
}
if(iDead == TRUE)
{
PrintString("TARGET BE DEAD AS A DOORNAIL");
DestroyObject(oImage, 0.0);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3), GetLocation(oImage), 0.0);
}
}
////////////////End Arcane Duelist//////////////////
////////////////Begin Corpsecrafter//////////////
void CorpseCrafter(object oPC, object oSummon)
{
// Hijacking this function because it's already in the right places
if (GetLevelByClass(CLASS_TYPE_DREAD_NECROMANCER, oPC) >= 8)
{
if (DEBUG) DoDebug("Corpsecrafter: Dread Necro");
int nHD = GetHitDice(oSummon);
effect eHP = EffectTemporaryHitpoints(nHD * 2);
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
effect eDex = EffectAbilityIncrease(ABILITY_DEXTERITY, 4);
eHP = SupernaturalEffect(eHP);
eStr = SupernaturalEffect(EffectLinkEffects(eStr, eDex));
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eHP, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon);
}
if (GetHasFeat(FEAT_CORPSECRAFTER, oPC))
{
if (DEBUG) DoDebug("Corpsecrafter: Corpsecrafter");
int nHD = GetHitDice(oSummon);
effect eHP = EffectTemporaryHitpoints(nHD * 2);
effect eStr = EffectAbilityIncrease(ABILITY_STRENGTH, 4);
eHP = SupernaturalEffect(eHP);
eStr = SupernaturalEffect(eStr);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eHP, oSummon);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eStr, oSummon);
}
if (GetHasFeat(FEAT_BOLSTER_RESISTANCE, oPC))
{
if (DEBUG) DoDebug("Corpsecrafter: Bolster Resistance");
effect eTurn = EffectTurnResistanceIncrease(4);
eTurn = SupernaturalEffect(eTurn);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eTurn, oSummon);
}
if (GetHasFeat(FEAT_DEADLY_CHILL, oPC))
{
if (DEBUG) DoDebug("Corpsecrafter: Deadly Chill");
effect eChill = EffectDamageIncrease(DAMAGE_BONUS_1d6, DAMAGE_TYPE_COLD);
eChill = SupernaturalEffect(eChill);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eChill, oSummon);
}
if (GetHasFeat(FEAT_HARDENED_FLESH, oPC))
{
if (DEBUG) DoDebug("Corpsecrafter: Hardened Flesh");
effect eAC = EffectACIncrease(2);
eAC = SupernaturalEffect(eAC);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eAC, oSummon);
}
if (GetHasFeat(FEAT_NIMBLE_BONES, oPC))
{
if (DEBUG) DoDebug("Corpsecrafter: Nimble Bones");
object oSkin = GetPCSkin(oPC);
itemproperty iInit = PRCItemPropertyBonusFeat(IP_CONST_FEAT_IMPROVED_INIT);
//AddItemProperty(DURATION_TYPE_PERMANENT, iInit, oSkin);
IPSafeAddItemProperty(oSkin, iInit, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
// Speed boost, average speed is 30 feet, so a 10 foot boost is a 33% boost
effect eSpeed = EffectMovementSpeedIncrease(33);
eSpeed = SupernaturalEffect(eSpeed);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSpeed, oSummon);
}
if (GetHasFeat(FEAT_DESTRUCTION_RETRIBUTION, oPC))
{
if (DEBUG) DoDebug("Corpsecrafter: Destruction Retribution");
SetLocalInt(oSummon, "DestructionRetribution", TRUE);
}
}
////////////////Begin Ninja//////////////
void Ninja_DecrementKi (object oPC, int iExcept = -1)
{
if (iExcept != FEAT_KI_POWER)
DecrementRemainingFeatUses(oPC, FEAT_KI_POWER);
if (iExcept != FEAT_GHOST_STEP)
DecrementRemainingFeatUses(oPC, FEAT_GHOST_STEP);
if (iExcept != FEAT_GHOST_STRIKE)
DecrementRemainingFeatUses(oPC, FEAT_GHOST_STRIKE);
if (iExcept != FEAT_GHOST_WALK)
DecrementRemainingFeatUses(oPC, FEAT_GHOST_WALK);
if (iExcept != FEAT_KI_DODGE)
DecrementRemainingFeatUses(oPC, FEAT_KI_DODGE);
// for testing only
SetLocalInt(oPC, "prc_ninja_ki", GetLocalInt(oPC, "prc_ninja_ki") - 1);
ExecuteScript("prc_ninjca", oPC);
}
int Ninja_AbilitiesEnabled (object oPC)
{
object oLefthand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
if (GetBaseAC(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) > 0 ||
GetBaseItemType(oLefthand) == BASE_ITEM_SMALLSHIELD ||
GetBaseItemType(oLefthand) == BASE_ITEM_LARGESHIELD ||
GetBaseItemType(oLefthand) == BASE_ITEM_TOWERSHIELD)
return FALSE;
// all Ki powers will not function when encumbered
if (GetIsEncumbered(oPC))
return FALSE;
return TRUE;
}
////////////////End Ninja//////////////
////////////////Begin Virtuoso//////////////
//Decrements the daily uses of Virtuoso Performance by the
// correct amount, returns FALSE if there are insufficient
// uses remaining to use the current feat
int VirtuosoPerformanceDecrement(object oPC, int nSpellID)
{
int nDecrement = 0;
int nDifference = 1122; //hack, difference in number between feat and spell 2da lines
switch(nSpellID)
{
case SPELL_VIRTUOSO_SUSTAINING_SONG:
case SPELL_VIRTUOSO_CALUMNY:
case SPELL_VIRTUOSO_GREATER_CALUMNY: nDecrement = 1; break;
case SPELL_VIRTUOSO_MINDBENDING_MELODY:
case SPELL_VIRTUOSO_MAGICAL_MELODY:
case SPELL_VIRTUOSO_REVEALING_MELODY: nDecrement = 2; break;
case SPELL_VIRTUOSO_SHARP_NOTE:
case SPELL_VIRTUOSO_JARRING_SONG:
case SPELL_VIRTUOSO_SONG_OF_FURY: nDecrement = 3; break;
}
if(!nDecrement) return FALSE; //sanity check
int nUses = GetPersistantLocalInt(oPC, "Virtuoso_Performance_Uses");
if(nUses >= nDecrement)
{
SetPersistantLocalInt(oPC, "Virtuoso_Performance_Uses", nUses - nDecrement);
int nFeat, nDec;
for(nFeat = FEAT_VIRTUOSO_SUSTAINING_SONG; nFeat <= FEAT_VIRTUOSO_PERFORMANCE; nFeat++)
{
nDec = nDecrement;
if(nFeat == (nSpellID + nDifference))
nDec--; //already decremented once by being used
for(; nDec > 0; nDec--)
DecrementRemainingFeatUses(oPC, nFeat);
}
return TRUE;
}
else
{ //refund feat use :P
IncrementRemainingFeatUses(oPC, nSpellID + nDifference);
return FALSE;
}
}
////////////////End Virtuoso//////////////
///////////////Archmage & Heirophant SLAs ///////////
void DoArchmageHeirophantSLA(object oPC, object oTarget, location lTarget, int nSLAID)
{
int nSLAFeatID = -1; //feat ID of the SLA in use
int nSLASpellID = -1;//spell ID of the SLA in use NOT THE SPELL BEING CAST
//get the SLAFeatID
int SLA_ID;
switch(SLA_ID)
{
case 1: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_1; break;
case 2: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_2; break;
case 3: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_3; break;
case 4: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_4; break;
case 5: nSLAFeatID = FEAT_SPELL_LIKE_ABILITY_5; break;
}
//get the spellID of the spell your trying to cast
//+1 offset for unassigned
int nSpellID = GetPersistantLocalInt(oPC, "PRC_SLA_SpellID_"+IntToString(nSLAID))-1;
//test if already stored
if(nSpellID == -1)
{
//not stored
FloatingTextStringOnCreature("This SLA has not been stored yet\nThe next spell you cast will be assigned to this SLA", oPC);
SetLocalInt(oPC, "PRC_SLA_Store", nSLAID);
DelayCommand(18.0,
DeleteLocalInt(oPC, "PRC_SLA_Store"));
return;
}
else
{
//stored, recast it
int nSpellClass = GetPersistantLocalInt(oPC, "PRC_SLA_Class_"+IntToString(nSLAID));
int nMetamagic = GetPersistantLocalInt(oPC, "PRC_SLA_Meta_"+IntToString(nSLAID));
int nSpellLevel = PRCGetSpellLevelForClass(nSpellID, nSpellClass);
int nBaseDC = 10 + nSpellLevel + GetDCAbilityModForClass(nSpellClass, oPC);
//since this is targetted using a generic feat,
//make sure were within range and target is valid for this spell
//get current distance
/*string sRange = Get2DACache("spells", "Range", nSpellID);
float fDist;
if(GetIsObjectValid(oTarget))
fDist = GetDistanceToObject(oTarget);
else
fDist = GetDistanceBetweenLocations(GetLocation(oPC), lTarget);
//check distance is allowed
if(fDist < 0.0
|| (sRange == "T" && fDist > 2.25)
|| (sRange == "S" && fDist > 8.0 )
|| (sRange == "M" && fDist > 20.0 )
|| (sRange == "L" && fDist > 40.0 )
)
{
//out of range
FloatingTextStringOnCreature("You are out of range", oPC);
//replace the useage
IncrementRemainingFeatUses(oPC, nSLAFeatID);
//end the script
return;
}*/
//check object type
int nTargetType = HexToInt(Get2DACache("spells", "TargetType", nSpellID));
/*
# 0x01 = 1 = Self
# 0x02 = 2 = Creature
# 0x04 = 4 = Area/Ground
# 0x08 = 8 = Items
# 0x10 = 16 = Doors
# 0x20 = 32 = Placeables
*/
int nCaster = nTargetType & 1;
int nCreature = nTargetType & 2;
int nLocation = nTargetType & 4;
int nItem = nTargetType & 8;
int nDoor = nTargetType & 16;
int nPlaceable = nTargetType & 32;
int nTargetValid = TRUE;
//test targetting self
if(oTarget == OBJECT_SELF)
{
if(!nCaster)
{
nTargetValid = FALSE;
FloatingTextStringOnCreature("You cannot target yourself", oPC);
}
}
//test targetting others
else if(GetIsObjectValid(oTarget))
{
switch(GetObjectType(oTarget))
{
case OBJECT_TYPE_CREATURE:
if(!nCreature)
{
nTargetValid = FALSE;
FloatingTextStringOnCreature("You cannot target creatures", oPC);
}
break;
case OBJECT_TYPE_ITEM:
if(!nItem)
{
nTargetValid = FALSE;
FloatingTextStringOnCreature("You cannot target items", oPC);
}
break;
case OBJECT_TYPE_DOOR:
if(!nDoor)
{
nTargetValid = FALSE;
FloatingTextStringOnCreature("You cannot target doors", oPC);
}
break;
case OBJECT_TYPE_PLACEABLE:
if(!nPlaceable)
{
nTargetValid = FALSE;
FloatingTextStringOnCreature("You cannot target placeables", oPC);
}
break;
}
}
//test if can target a location
else if(GetIsObjectValid(GetAreaFromLocation(lTarget)))
{
if(!nLocation)
{
nTargetValid = FALSE;
FloatingTextStringOnCreature("You cannot target locations", oPC);
}
}
//target was not valid, abort
if(!nTargetValid)
{
//replace the useage
IncrementRemainingFeatUses(oPC, nSLAFeatID);
//end the script
return;
}
//actually cast it at this point
//note that these are instant-spells, so we have to add the animation part too
/*if(GetIsObjectValid(oTarget))
ActionCastFakeSpellAtObject(nSpellID, oTarget);
else
ActionCastFakeSpellAtLocation(nSpellID, lTarget);*/
ActionDoCommand(ActionCastSpell(nSpellID, 0, nBaseDC, 0, nMetamagic, nSpellClass, 0, 0, OBJECT_INVALID, FALSE));
}
}
/////////////// End Archmage & Heirophant SLAs ///////////
////////////////////////Alienist//////////////////////////
int GetPhobia(object oPC)
{
int nPhobia = GetPersistantLocalInt(oPC, "Alienist_Phobia");
if(nPhobia < 1)
{
nPhobia = Random(16) + 1;
SetPersistantLocalInt(oPC, "Alienist_Phobia", nPhobia);
}
return nPhobia;
}
int GetPhobiaRace(int nPhobia)
{
switch(nPhobia)
{
case 1: return RACIAL_TYPE_ABERRATION;
case 2: return RACIAL_TYPE_ANIMAL;
case 3: return RACIAL_TYPE_BEAST;
case 4: return RACIAL_TYPE_CONSTRUCT;
case 5: return RACIAL_TYPE_DRAGON;
case 6: return RACIAL_TYPE_HUMANOID_GOBLINOID;
case 7: return RACIAL_TYPE_HUMANOID_MONSTROUS;
case 8: return RACIAL_TYPE_HUMANOID_ORC;
case 9: return RACIAL_TYPE_HUMANOID_REPTILIAN;
case 10: return RACIAL_TYPE_ELEMENTAL;
case 11: return RACIAL_TYPE_FEY;
case 12: return RACIAL_TYPE_GIANT;
case 13: return RACIAL_TYPE_MAGICAL_BEAST;
case 14: return RACIAL_TYPE_SHAPECHANGER;
case 15: return RACIAL_TYPE_UNDEAD;
case 16: return RACIAL_TYPE_VERMIN;
}
return -1;//error
}
int GetPhobiaFeat(int nPhobia)
{
switch(nPhobia)
{
case 1: return IP_CONST_PHOBIA_ABERRATION;
case 2: return IP_CONST_PHOBIA_ANIMAL;
case 3: return IP_CONST_PHOBIA_BEAST;
case 4: return IP_CONST_PHOBIA_CONSTRUCT;
case 5: return IP_CONST_PHOBIA_DRAGON;
case 6: return IP_CONST_PHOBIA_GOBLINOID;
case 7: return IP_CONST_PHOBIA_MONSTROUS;
case 8: return IP_CONST_PHOBIA_ORC;
case 9: return IP_CONST_PHOBIA_REPTILIAN;
case 10: return IP_CONST_PHOBIA_ELEMENTAL;
case 11: return IP_CONST_PHOBIA_FEY;
case 12: return IP_CONST_PHOBIA_GIANT;
case 13: return IP_CONST_PHOBIA_MAGICAL_BEAST;
case 14: return IP_CONST_PHOBIA_SHAPECHANGER;
case 15: return IP_CONST_PHOBIA_UNDEAD;
case 16: return IP_CONST_PHOBIA_VERMIN;
}
return -1;//error
}
/////////////////////DragonSong Lyrist////////////////////////
void RemoveOldSongs(object oPC)
{
if(GetHasSpellEffect(SPELL_DSL_SONG_STRENGTH, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_STRENGTH);
if(GetHasSpellEffect(SPELL_DSL_SONG_COMPULSION, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_COMPULSION);
if(GetHasSpellEffect(SPELL_DSL_SONG_SPEED, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_SPEED);
if(GetHasSpellEffect(SPELL_DSL_SONG_FEAR, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_FEAR);
if(GetHasSpellEffect(SPELL_DSL_SONG_HEALING, oPC)) PRCRemoveEffectsFromSpell(oPC, SPELL_DSL_SONG_HEALING);
}
// Eldritch Theurge class requires arcane spellcasting and eldritch blast.
// If a character is an Eldritch Theruge we know that she must have levels in Warlock
// since in NWN character can have max 3 classes. We also know that Eldritch Theurge
// is at positon 3 (unless player is cheating).
// So we just need to check the third class.
int GetETArcaneClass(object oPC)
{
int nClass = GetPrimaryArcaneClass(oPC);
/* int nClass = GetClassByPosition(1, oPC);
if(nClass == CLASS_TYPE_WARLOCK)
nClass = GetClassByPosition(2, oPC); */
return nClass;
}