Further file organization
Further file organization
This commit is contained in:
441
nwn/nwnprc/trunk/scripts/prc_reservefeat.nss
Normal file
441
nwn/nwnprc/trunk/scripts/prc_reservefeat.nss
Normal file
@@ -0,0 +1,441 @@
|
||||
//Reserve Feat Script
|
||||
//prc_reservefeat
|
||||
//by ebonfowl 5/5/2022
|
||||
//Dedicated to Edgar, the real ebonfowl
|
||||
|
||||
//Lookup constants
|
||||
//Domains
|
||||
const string RESERVESPELL_DOMAIN_DESTRUCTION = "destruc";
|
||||
const string RESERVESPELL_DOMAIN_DEATH = "dethdom";
|
||||
const string RESERVESPELL_DOMAIN_WAR = "wardom";
|
||||
|
||||
//Descriptors
|
||||
const string RESERVESPELL_DESCRIPTOR_ACID = "acid";
|
||||
const string RESERVESPELL_DESCRIPTOR_AIR = "air";
|
||||
const string RESERVESPELL_DESCRIPTOR_COLD = "cold";
|
||||
const string RESERVESPELL_DESCRIPTOR_DARKNESS = "darknes";
|
||||
const string RESERVESPELL_DESCRIPTOR_EARTH = "earth";
|
||||
const string RESERVESPELL_DESCRIPTOR_ELECTRICITY = "electri";
|
||||
const string RESERVESPELL_DESCRIPTOR_FIRE = "fire";
|
||||
const string RESERVESPELL_DESCRIPTOR_FORCE = "force";
|
||||
const string RESERVESPELL_DESCRIPTOR_GLAMER = "glamer";
|
||||
const string RESERVESPELL_DESCRIPTOR_HEALING = "healing";
|
||||
const string RESERVESPELL_DESCRIPTOR_LIGHT = "light";
|
||||
const string RESERVESPELL_DESCRIPTOR_POLYMORPH = "polymor";
|
||||
const string RESERVESPELL_DESCRIPTOR_SONIC = "sonic";
|
||||
const string RESERVESPELL_DESCRIPTOR_SUMMONING = "summon";
|
||||
const string RESERVESPELL_DESCRIPTOR_TELEPORTATION = "teleprt";
|
||||
const string RESERVESPELL_DESCRIPTOR_WATER = "water";
|
||||
|
||||
//Schools
|
||||
const string RESERVESPELL_SCHOOL_ABJURATION = "abjurat";
|
||||
const string RESERVESPELL_SCHOOL_ENCHANTMENT = "enchant";
|
||||
const string RESERVESPELL_SCHOOL_NECROMANCY = "necro";
|
||||
|
||||
|
||||
//Includes
|
||||
#include "prc_feat_const"
|
||||
#include "prc_x2_itemprop"
|
||||
#include "psi_inc_psifunc"
|
||||
|
||||
//ebonfowl: this function is not currently used, but I am leaving it in just in case
|
||||
/*
|
||||
int GetHighestSpellAvailable(object oPC)
|
||||
{
|
||||
//This will loop all the spells and return the highest level available to cast
|
||||
string sFile = "prc_all"; //May need to rename
|
||||
|
||||
int i;
|
||||
int nSpellID;
|
||||
int nNewSpellLevel;
|
||||
int nSpellLevel = 0;
|
||||
|
||||
string sSpellLabel;
|
||||
|
||||
for (i = 0; i < 500; i++) // Adjust max i to reflect something close to the highest row number in the 2das
|
||||
{
|
||||
nSpellID = StringToInt(Get2DACache(sFile, "SpellID", i));
|
||||
sSpellLabel = Get2DACache(sFile, "Label", i);
|
||||
if(sSpellLabel != "") // Non-blank row
|
||||
{
|
||||
if(PRCGetHasSpell(nSpellID, oPC))
|
||||
{
|
||||
nNewSpellLevel = StringToInt(Get2DACache(sFile, "Innate", i));
|
||||
if (nNewSpellLevel > nSpellLevel) nSpellLevel = nNewSpellLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nSpellLevel;
|
||||
}
|
||||
*/
|
||||
|
||||
int GetHighestSpellAvailableBySchool(object oPC, string sSchool)
|
||||
{
|
||||
//This will loop all spells fpr a given school and return the highest level available to cast
|
||||
string sFile = "prc_desc_" + sSchool;
|
||||
|
||||
int i;
|
||||
int nSpellID;
|
||||
int nNewSpellLevel;
|
||||
int nSpellLevel = 0;
|
||||
|
||||
string sSpellLabel;
|
||||
|
||||
for (i = 0; i < 126; i++) // Adjust max i to reflect something close to the highest row number in the 2das
|
||||
{
|
||||
nSpellID = StringToInt(Get2DACache(sFile, "SpellID", i));
|
||||
sSpellLabel = Get2DACache(sFile, "Label", i);
|
||||
if(sSpellLabel != "") // Non-blank row
|
||||
{
|
||||
if(PRCGetHasSpell(nSpellID, oPC))
|
||||
{
|
||||
nNewSpellLevel = StringToInt(Get2DACache(sFile, "Innate", i));
|
||||
if (nNewSpellLevel > nSpellLevel) nSpellLevel = nNewSpellLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nSpellLevel;
|
||||
}
|
||||
|
||||
int GetHighestDomainSpellAvailable(object oPC, string sDomain) //This will loop all domain spells for a given doamain and return the highest level available to cast
|
||||
{
|
||||
string sFile = "prc_desc_" + sDomain;
|
||||
|
||||
int i;
|
||||
int nSpellID;
|
||||
int nNewSpellLevel;
|
||||
int nSpellLevel = 0;
|
||||
|
||||
string sSpellLabel;
|
||||
|
||||
for (i = 0; i < 12; i++) // Adjust max i to reflect something close to the highest row number in the 2das
|
||||
{
|
||||
nSpellID = StringToInt(Get2DACache(sFile, "SpellID", i));
|
||||
sSpellLabel = Get2DACache(sFile, "Label", i);
|
||||
if(sSpellLabel != "") // Non-blank row
|
||||
{
|
||||
if(PRCGetHasSpell(nSpellID, oPC))
|
||||
{
|
||||
nNewSpellLevel = StringToInt(Get2DACache(sFile, "Innate", i));
|
||||
if (nNewSpellLevel > nSpellLevel) nSpellLevel = nNewSpellLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nSpellLevel;
|
||||
}
|
||||
|
||||
int GetHighestSpellAvailableByDescriptor(object oPC, string sDescriptor)
|
||||
{
|
||||
//This will loop all spells fpr a given descriptor and return the highest level available to cast
|
||||
string sFile = "prc_desc_" + sDescriptor;
|
||||
|
||||
int i;
|
||||
int nSpellID;
|
||||
int nNewSpellLevel;
|
||||
int nSpellLevel = 0;
|
||||
|
||||
string sSpellLabel;
|
||||
|
||||
for (i = 0; i < 125; i++) // Adjust max i to reflect something close to the highest row number in the 2das
|
||||
{
|
||||
nSpellID = StringToInt(Get2DACache(sFile, "SpellID", i));
|
||||
sSpellLabel = Get2DACache(sFile, "Label", i);
|
||||
if(sSpellLabel != "") // Non-blank row
|
||||
{
|
||||
if(PRCGetHasSpell(nSpellID, oPC))
|
||||
{
|
||||
nNewSpellLevel = StringToInt(Get2DACache(sFile, "Innate", i));
|
||||
if (nNewSpellLevel > nSpellLevel) nSpellLevel = nNewSpellLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nSpellLevel;
|
||||
}
|
||||
|
||||
void UpdateReserveFeats(object oPC) //This will check for each reserve feat, call the function to set the bonus, then set the bonus
|
||||
{
|
||||
object oWeapon, oOffHand;
|
||||
|
||||
int nBonus;
|
||||
int nDamage;
|
||||
|
||||
effect eEffect;
|
||||
effect eCheckEffect;
|
||||
|
||||
string sTag;
|
||||
|
||||
//Holy Warrior
|
||||
if (GetHasFeat(FEAT_HOLY_WARRIOR, oPC)) //Update constant when feat constant is made
|
||||
{
|
||||
nBonus = GetHighestDomainSpellAvailable(oPC, RESERVESPELL_DOMAIN_WAR);
|
||||
nDamage = IPGetDamageBonusConstantFromNumber(nBonus);
|
||||
oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||||
oOffHand = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
|
||||
eEffect = EffectDamageIncrease(nDamage, DAMAGE_TYPE_SLASHING);
|
||||
eEffect = TagEffect(eEffect, "HolyWarriorBonus");
|
||||
eEffect = SupernaturalEffect(eEffect);
|
||||
eCheckEffect = GetFirstEffect(oPC);
|
||||
|
||||
while (GetIsEffectValid(eCheckEffect))
|
||||
{
|
||||
if (GetEffectTag(eCheckEffect) == "HolyWarriorBonus")
|
||||
{
|
||||
RemoveEffect(oPC, eCheckEffect);
|
||||
}
|
||||
eCheckEffect = GetNextEffect(oPC);
|
||||
}
|
||||
|
||||
if (IPGetIsMeleeWeapon(oWeapon) ||
|
||||
IPGetIsMeleeWeapon(oOffHand) ||
|
||||
GetWeaponRanged(oWeapon) ||
|
||||
GetWeaponRanged(oOffHand))
|
||||
{
|
||||
if (nBonus > 3) ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oPC);
|
||||
}
|
||||
}
|
||||
|
||||
//Mystic Backlash
|
||||
if (GetHasFeat(FEAT_MYSTIC_BACKLASH, oPC)) //Update constant when feat constant is made
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableBySchool(oPC, RESERVESPELL_SCHOOL_ABJURATION);
|
||||
DeleteLocalInt(oPC, "MysticBacklashBonus");
|
||||
|
||||
if (nBonus > 4) SetLocalInt(oPC, "MysticBacklashBonus", nBonus);
|
||||
}
|
||||
|
||||
//Acidic Splatter
|
||||
if(GetHasFeat(FEAT_ACIDIC_SPLATTER, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_ACID);
|
||||
DeleteLocalInt(oPC, "AcidicSplatterBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "AcidicSplatterBonus", nBonus);
|
||||
}
|
||||
|
||||
//Fiery Burst
|
||||
if(GetHasFeat(FEAT_FIERY_BURST, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_FIRE);
|
||||
DeleteLocalInt(oPC, "FieryBurstBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "FieryBurstBonus", nBonus);
|
||||
}
|
||||
|
||||
//Storm Bolt
|
||||
if(GetHasFeat(FEAT_STORM_BOLT, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_ELECTRICITY);
|
||||
DeleteLocalInt(oPC, "StormBoltBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "StormBoltBonus", nBonus);
|
||||
}
|
||||
|
||||
//Winter's Blast
|
||||
if(GetHasFeat(FEAT_WINTERS_BLAST, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_COLD);
|
||||
DeleteLocalInt(oPC, "WintersBlastBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "WintersBlastBonus", nBonus);
|
||||
}
|
||||
|
||||
//Clap of Thunder
|
||||
if(GetHasFeat(FEAT_CLAP_OF_THUNDER, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_SONIC);
|
||||
DeleteLocalInt(oPC, "ClapOfThunderBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "ClapOfThunderBonus", nBonus);
|
||||
}
|
||||
|
||||
//Sickening Grasp
|
||||
if (GetHasFeat(FEAT_SICKENING_GRASP, oPC)) //Update constant when feat constant is made
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableBySchool(oPC, RESERVESPELL_SCHOOL_NECROMANCY);
|
||||
DeleteLocalInt(oPC, "SickeningGraspBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "SickeningGraspBonus", nBonus);
|
||||
}
|
||||
|
||||
//Touch of Healing
|
||||
if(GetHasFeat(FEAT_TOUCH_OF_HEALING, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_HEALING);
|
||||
DeleteLocalInt(oPC, "TouchOfHealingBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "TouchOfHealingBonus", nBonus);
|
||||
}
|
||||
|
||||
//Dimensional Jaunt
|
||||
if(GetHasFeat(FEAT_DIMENSIONAL_JAUNT, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_TELEPORTATION);
|
||||
DeleteLocalInt(oPC, "DimensionalJauntBonus");
|
||||
|
||||
if (nBonus > 3) SetLocalInt(oPC, "DimensionalJauntBonus", nBonus);
|
||||
}
|
||||
|
||||
//Clutch of Earth
|
||||
if(GetHasFeat(FEAT_CLUTCH_OF_EARTH, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_EARTH);
|
||||
DeleteLocalInt(oPC, "ClutchOfEarthBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "ClutchOfEarthBonus", nBonus);
|
||||
}
|
||||
|
||||
//Borne Aloft
|
||||
if(GetHasFeat(FEAT_BORNE_ALOFT, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_AIR);
|
||||
DeleteLocalInt(oPC, "BorneAloftBonus");
|
||||
|
||||
if (nBonus > 4) SetLocalInt(oPC, "BorneAloftBonus", nBonus);
|
||||
}
|
||||
|
||||
//Protective Ward
|
||||
if (GetHasFeat(FEAT_PROTECTIVE_WARD, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableBySchool(oPC, RESERVESPELL_SCHOOL_ABJURATION);
|
||||
DeleteLocalInt(oPC, "ProtectiveWardBonus");
|
||||
|
||||
if (nBonus > 0) SetLocalInt(oPC, "ProtectiveWardBonus", nBonus);
|
||||
}
|
||||
|
||||
//Shadow Veil
|
||||
if(GetHasFeat(FEAT_SHADOW_VEIL, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_DARKNESS);
|
||||
DeleteLocalInt(oPC, "ShadowVeilBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "ShadowVeilBonus", nBonus);
|
||||
}
|
||||
|
||||
//Sunlight Eyes
|
||||
if(GetHasFeat(FEAT_SUNLIGHT_EYES, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_LIGHT);
|
||||
DeleteLocalInt(oPC, "SunlightEyesBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "SunlightEyesBonus", nBonus);
|
||||
}
|
||||
|
||||
//Touch of Distraction
|
||||
if (GetHasFeat(FEAT_TOUCH_OF_DISTRACTION, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableBySchool(oPC, RESERVESPELL_SCHOOL_ENCHANTMENT);
|
||||
DeleteLocalInt(oPC, "TouchOfDistractionBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "TouchOfDistractionBonus", nBonus);
|
||||
}
|
||||
|
||||
//Umbral Shroud
|
||||
if(GetHasFeat(FEAT_UMBRAL_SHROUD, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_DARKNESS);
|
||||
DeleteLocalInt(oPC, "UmbralShroudBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "UmbralShroudBonus", nBonus);
|
||||
}
|
||||
|
||||
//Charnel Miasma
|
||||
if(GetHasFeat(FEAT_CHARNEL_MIASMA, oPC))
|
||||
{
|
||||
nBonus = GetHighestDomainSpellAvailable(oPC, RESERVESPELL_DOMAIN_DEATH);
|
||||
DeleteLocalInt(oPC, "CharnelMiasmaBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "CharnelMiasmaBonus", nBonus);
|
||||
}
|
||||
|
||||
//Drowning Glance
|
||||
if(GetHasFeat(FEAT_DROWNING_GLANCE, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_WATER);
|
||||
DeleteLocalInt(oPC, "DrowningGlanceBonus");
|
||||
|
||||
if (nBonus > 3) SetLocalInt(oPC, "DrowningGlanceBonus", nBonus);
|
||||
}
|
||||
|
||||
//Invisible Needle
|
||||
if(GetHasFeat(FEAT_INVISIBLE_NEEDLE, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_FORCE);
|
||||
DeleteLocalInt(oPC, "InvisibleNeedleBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "InvisibleNeedleBonus", nBonus);
|
||||
}
|
||||
|
||||
//Summon Elemental
|
||||
if(GetHasFeat(FEAT_SUMMON_ELEMENTAL, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_SUMMONING);
|
||||
DeleteLocalInt(oPC, "SummonElementalBonus");
|
||||
|
||||
if (nBonus > 3) SetLocalInt(oPC, "SummonElementalBonus", nBonus);
|
||||
}
|
||||
|
||||
//Dimensional Reach
|
||||
if(GetHasFeat(FEAT_DIMENSIONAL_REACH, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_SUMMONING);
|
||||
DeleteLocalInt(oPC, "DimensionalReachBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "DimensionalReachBonus", nBonus);
|
||||
}
|
||||
|
||||
//Hurricane Breath
|
||||
if(GetHasFeat(FEAT_HURRICANE_BREATH, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_AIR);
|
||||
DeleteLocalInt(oPC, "HurricaneBreathBonus");
|
||||
|
||||
if (nBonus > 1) SetLocalInt(oPC, "HurricaneBreathBonus", nBonus);
|
||||
}
|
||||
|
||||
//Minor Shapeshift
|
||||
if(GetHasFeat(FEAT_MINOR_SHAPESHIFT, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_POLYMORPH);
|
||||
DeleteLocalInt(oPC, "MinorShapeshiftBonus");
|
||||
|
||||
if (nBonus > 3) SetLocalInt(oPC, "MinorShapeshiftBonus", nBonus);
|
||||
}
|
||||
|
||||
//Face-Changer
|
||||
if(GetHasFeat(FEAT_FACECHANGER, oPC))
|
||||
{
|
||||
nBonus = GetHighestSpellAvailableByDescriptor(oPC, RESERVESPELL_DESCRIPTOR_GLAMER);
|
||||
DeleteLocalInt(oPC, "FaceChangerBonus");
|
||||
|
||||
if (nBonus > 2) SetLocalInt(oPC, "FaceChangerBonus", nBonus);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
if(!GetLocalInt(oPC, "ReserveFeatsRunning"))
|
||||
{
|
||||
SetLocalInt(oPC, "ReserveFeatsRunning", TRUE);
|
||||
|
||||
//Hook this script into event system so it runs on hooked events
|
||||
AddEventScript(oPC, EVENT_ONACTIVATEITEM, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONACQUIREITEM, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONCLIENTENTER, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONCLIENTLEAVE, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONPLAYERLEVELDOWN, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONPLAYERLEVELUP, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONPLAYERRESPAWN, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONPLAYEREQUIPITEM, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONPLAYERUNEQUIPITEM, "prc_reservefeat", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONUNAQUIREITEM, "prc_reservefeat", TRUE, FALSE);
|
||||
|
||||
//Update the feat bonuses
|
||||
UpdateReserveFeats(oPC);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateReserveFeats(oPC);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user