NWNDS/nwnds_module/lib_psionic.nss
Jaysyn904 de24f81734 Added NWN Dark Sun module contents
Added NWN Dark Sun module contents.
2021-07-12 21:24:46 -04:00

1302 lines
46 KiB
Plaintext

//void main() {}
const int PSIONIC_DISCIPLINE_PSYCHOKINESIS = 1;
const int PSIONIC_DISCIPLINE_PSYCHOMETABOLISM = 2;
const int PSIONIC_DISCIPLINE_PSYCHOPORTATION = 3;
const int PSIONIC_DISCIPLINE_TELEPATHY = 4;
const int PSIONIC_DISCIPLINE_CLAIRSENTIENCE = 5;
const int PSIONIC_DISCIPLINE_METAPSIONICS = 6;
const int FEAT_PSIONIC_DETONATE = 1200;
const int FEAT_PSIONIC_DISINTEGRATE = 1201;
const int FEAT_PSIONIC_PROJECT_FORCE = 1202;
const int FEAT_PSIONIC_TELEKINESIS = 1203;
const int FEAT_PSIONIC_ANIMATE_SHADOW = 1204;
const int FEAT_PSIONIC_BALLISTIC_ATTACK = 1205;
const int FEAT_PSIONIC_MOLECULAR_AGITATION = 1206;
const int FEAT_PSIONIC_COMPLETE_HEALING = 1207;
const int FEAT_PSIONIC_DEATH_FIELD = 1208;
const int FEAT_PSIONIC_LIFE_DRAINING = 1209;
const int FEAT_PSIONIC_METAMORPHOSIS = 1210;
const int FEAT_PSIONIC_DISPLACEMENT = 1211;
const int FEAT_PSIONIC_ADRENALINE_CONTROL = 1212;
const int FEAT_PSIONIC_BIOFEEDBACK = 1213;
const int FEAT_PSIONIC_CELL_ADJUSTMENT = 1214;
const int FEAT_PSIONIC_CHAMELEON_POWER = 1215;
const int FEAT_PSIONIC_ECTOPLASMIC_FORM = 1216;
const int FEAT_PSIONIC_ENHANCED_STRENGTH = 1217;
const int FEAT_PSIONIC_FLESH_ARMOR = 1218;
const int FEAT_PSIONIC_LEND_HEALTH = 1219;
const int FEAT_PSIONIC_REGENERATE = 1220;
const int FEAT_PSIONIC_ACCELERATE = 1221;
const int FEAT_PSIONIC_CAUSE_SLEEP = 1222;
const int FEAT_PSIONIC_PHOTOSYNTHESIS = 1223;
const int FEAT_PSIONIC_STRENGTH_OF_LAND = 1224;
const int FEAT_PSIONIC_BANISHMENT = 1225;
const int FEAT_PSIONIC_SUMMON_PLANAR_CREATURE = 1226;
const int FEAT_PSIONIC_SUMMON_PLANAR_ENERGY = 1227;
const int FEAT_PSIONIC_DIMENSION_DOOR = 1228;
const int FEAT_PSIONIC_TIME_SHIFT = 1229;
const int FEAT_PSIONIC_DOMINATION = 1230;
const int FEAT_PSIONIC_CONTACT = 1231;
const int FEAT_PSIONIC_MIND_WHIPE = 1232;
const int FEAT_PSIONIC_MASS_DOMINATION = 1233;
const int FEAT_PSIONIC_HALLUCINATIONS = 1234;
const int FEAT_PSIONIC_ATTRACTION = 1235;
const int FEAT_PSIONIC_AVERSION = 1236;
const int FEAT_PSIONIC_DAYDREAM = 1237;
const int FEAT_PSIONIC_INFLICT_PAIN = 1238;
const int FEAT_PSIONIC_SENSORY_SUPPRESSION = 1239;
const int FEAT_PSIONIC_SUPPRESS_FEAR = 1240;
const int FEAT_PSIONIC_MIND_THRUST = 1241;
const int FEAT_PSIONIC_EGO_WHIP = 1242;
const int FEAT_PSIONIC_ID_INSINUATION = 1243;
const int FEAT_PSIONIC_PSIONIC_BLAST = 1244;
const int FEAT_PSIONIC_PSYCHIC_CRUSH = 1245;
const int FEAT_PSIONIC_INTELLECT_FORTRESS = 1246;
const int FEAT_PSIONIC_MENTAL_BARRIER = 1247;
const int FEAT_PSIONIC_MIND_BLANK = 1248;
const int FEAT_PSIONIC_THOUGHT_SHIELD = 1249;
const int FEAT_PSIONIC_TOWER_OF_IRON_WILL = 1250;
const int FEAT_PSIONIC_TRUE_SIGHT = 1251;
const int FEAT_PSIONIC_COMBAT_MIND = 1252;
const int FEAT_PSIONIC_DANGER_SENSE = 1253;
const int FEAT_PSIONIC_SEE_INVISIBILITY = 1254;
const int FEAT_PSIONIC_CLAIRVOYANCE_CLAIRAUDIENCE = 1255;
const int FEAT_PSIONIC_PSYCHIC_CLONE = 1256;
const int FEAT_PSIONIC_ULTRABLAST = 1257;
const int FEAT_PSIONIC_CANNIBALIZE = 1258;
const int FEAT_PSIONIC_PSYCHIC_DRAIN = 1259;
const int FEAT_PSIONIC_RECEPTACLE = 1260;
const int FEAT_PSIONIC_STASIS_FIELD = 1261;
const int FEAT_PSIONIC_WRENCH = 1262;
const int FEAT_PSIONIC_PSIONIC_VAMPIRISM = 1263;
const int FEAT_PSIONIC_PSIONIC_RESIDUE = 1264;
const int FEAT_PSIONIC_PSP_CHECK = 1265;
const int FEAT_PSIONIC_CATFALL = 1358;
const int FEAT_PSIONIC_ESP = 1359;
const int FEAT_PSIONIC_MIND_BLAST = 1360;
const int FEAT_PSIONIC_OBJECT_READING = 1361;
const int FEAT_PSIONIC_CONTROL_LIGHT = 1362;
const int FEAT_PSIONIC_CONTROL_WIND = 1363;
const int FEAT_PSIONIC_PSYCHIC_SURGERY = 1364;
const int FEAT_PSIONIC_TELEPORT = 1365;
const int FEAT_PSIONIC_CONVOCATION = 1366;
const int FEAT_PSIONIC_GROUP_TELEPORT = 1367;
const int FEAT_PSIONIC_CHEMICAL_SIMULATION = 1368;
const int FEAT_PSIONIC_CRISIS_OF_LIFE = 1369;
const int FEAT_PSIONIC_TRANSFORMATION = 1370;
const int FEAT_PSIONIC_INERTIAL_BARRIER = 1371;
const int FEAT_PSIONIC_MEGAKINESIS = 1372;
const int FEAT_PSIONIC_MASS_CONTACT = 1373;
const int FEAT_PSIONIC_COSMIC_AWARENESS = 1374;
const int FEAT_PSIONIC_EMPOWER = 1375;
const int FEAT_PSIONIC_PSYCHIC_BLADE = 1376;
const int FEAT_EXPANSIVE_MIND_1 = 1300;
const int FEAT_EXPANSIVE_MIND_2 = 1301;
const int FEAT_EXPANSIVE_MIND_3 = 1302;
const int FEAT_EXPANSIVE_MIND_4 = 1303;
const int FEAT_EXPANSIVE_MIND_5 = 1304;
const int FEAT_EPIC_EXPANSIVE_MIND_1 = 1305;
const int FEAT_EPIC_EXPANSIVE_MIND_2 = 1306;
const int FEAT_EPIC_EXPANSIVE_MIND_3 = 1307;
const int FEAT_EPIC_EXPANSIVE_MIND_4 = 1308;
const int FEAT_EPIC_EXPANSIVE_MIND_5 = 1309;
const int FEAT_PSYCHOKINESIS_EXPERTISE_1 = 1310;
const int FEAT_PSYCHOKINESIS_EXPERTISE_2 = 1311;
const int FEAT_PSYCHOMETABOLISM_EXPERTISE_1 = 1312;
const int FEAT_PSYCHOMETABILISM_EXPERTISE_2 = 1313;
const int FEAT_PSYCHOPORTATION_EXPERTISE_1 = 1314;
const int FEAT_PSYCHOPORTATION_EXPERTISE_2 = 1315;
const int FEAT_TELEPATHY_EXPERTISE_1 = 1316;
const int FEAT_TELEPATHY_EXPERTISE_2 = 1317;
const int FEAT_CLAIRSENTIENCE_EXPERTISE_1 = 1318;
const int FEAT_CLAIRSENTIENCE_EXPERTISE_2 = 1319;
const int FEAT_METAPSIONICS_EXPERTISE_1 = 1320;
const int FEAT_METAPSIONICS_EXPERTISE_2 = 1321;
const int FEAT_EPIC_PSYCHOKINESIS_EXPERTISE_1 = 1322;
const int FEAT_EPIC_PSYCHOKINESIS_EXPERTISE_2 = 1323;
const int FEAT_EPIC_PSYCHOMETABOLISM_EXPERTISE_1 = 1324;
const int FEAT_EPIC_PSYCHOMETABOLISM_EXPERTISE_2 = 1325;
const int FEAT_EPIC_PSYCHOPORTATION_EXPERTISE_1 = 1326;
const int FEAT_EPIC_PSYCHOPORTATION_EXPERTISE_2 = 1327;
const int FEAT_EPIC_TELEPATHY_EXPERTISE_1 = 1328;
const int FEAT_EPIC_TELEPATHY_EXPERTISE_2 = 1329;
const int FEAT_EPIC_CLAIRSENTIENCE_EXPERTISE_1 = 1330;
const int FEAT_EPIC_CLAIRSENTIENCE_EXPERTISE_2 = 1331;
const int FEAT_EPIC_METAPSIONICS_EXPERTISE_1 = 1332;
const int FEAT_EPIC_METAPSIONICS_EXPERTISE_2 = 1333;
const int FEAT_PSYCHOKINESIS_FOCUS_1 = 1334;
const int FEAT_PSYCHOKINESIS_FOCUS_2 = 1335;
const int FEAT_PSYCHOMETABOLISM_FOCUS_1 = 1336;
const int FEAT_PSYCHOMETABOLISM_FOCUS_2 = 1337;
const int FEAT_PSYCHOPORTATION_FOCUS_1 = 1338;
const int FEAT_PSYCHOPORTATION_FOCUS_2 = 1339;
const int FEAT_TELEPATHY_FOCUS_1 = 1340;
const int FEAT_TELEPATHY_FOCUS_2 = 1341;
const int FEAT_CLAIRSENTIENCE_FOCUS_1 = 1342;
const int FEAT_CLAIRSENTIENCE_FOCUS_2 = 1343;
const int FEAT_METAPSIONICS_FOCUS_1 = 1344;
const int FEAT_METAPSIONICS_FOCUS_2 = 1345;
const int FEAT_EPIC_PSYCHOKINESIS_FOCUS_1 = 1346;
const int FEAT_EPIC_PSYCHOKINESIS_FOCUS_2 = 1347;
const int FEAT_EPIC_PSYCHOMETABOLISM_FOCUS_1 = 1348;
const int FEAT_EPIC_PSYCHOMETABOLISM_FOCUS_2 = 1349;
const int FEAT_EPIC_PSYCHOPORTATION_FOCUS_1 = 1350;
const int FEAT_EPIC_PSYCHOPORTATION_FOCUS_2 = 1351;
const int FEAT_EPIC_TELEPATHY_FOCUS_1 = 1352;
const int FEAT_EPIC_TELEPATHY_FOCUS_2 = 1353;
const int FEAT_EPIC_CLAIRSENTIENCE_FOCUS_1 = 1354;
const int FEAT_EPIC_CLAIRSENTIENCE_FOCUS_2 = 1355;
const int FEAT_EPIC_METAPSIONICS_FOCUS_1 = 1356;
const int FEAT_EPIC_METAPSIONICS_FOCUS_2 = 1357;
const int FEAT_PSYCHOKINESIS_SPECIALTY = 1377;
const int FEAT_PSYCHOMETABOLISM_SPECIALTY = 1378;
const int FEAT_PSYCHOPORTATION_SPECIALTY = 1379;
const int FEAT_TELEPATHY_SPECIALTY = 1380;
const int FEAT_CLAIRSENTIENCE_SPECIALTY = 1381;
const int FEAT_METAPSIONICS_SPECIALTY = 1382;
const int FEAT_EPIC_PSYCHOKINESIS_SPECIALTY = 1383;
const int FEAT_EPIC_PSYCHOMETABOLISM_SPECIALTY = 1384;
const int FEAT_EPIC_PSYCHOPORTATION_SPECIALTY = 1385;
const int FEAT_EPIC_TELEPATHY_SPECIALTY = 1386;
const int FEAT_EPIC_CLAIRSENTIENCE_SPECIALTY = 1387;
const int FEAT_EPIC_METAPSIONICS_SPECIALTY = 1388;
const int SPELL_PSIONIC_DETONATE = 1000;
const int SPELL_PSIONIC_DISINTEGRATE = 1001;
const int SPELL_PSIONIC_PROJECT_FORCE = 1002;
const int SPELL_PSIONIC_TELEKINESIS = 1003;
const int SPELL_PSIONIC_ANIMATE_SHADOW = 1004;
const int SPELL_PSIONIC_BALLISTIC_ATTACK = 1005;
const int SPELL_PSIONIC_MOLECULAR_AGITATION = 1006;
const int SPELL_PSIONIC_COMPLETE_HEALING = 1007;
const int SPELL_PSIONIC_DEATH_FIELD = 1008;
const int SPELL_PSIONIC_LIFE_DRAINING = 1009;
const int SPELL_PSIONIC_METAMORPHOSIS = 1010;
const int SPELL_PSIONIC_DISPLACEMENT = 1011;
const int SPELL_PSIONIC_ADRENALINE_CONTROL = 1012;
const int SPELL_PSIONIC_BIOFEEDBACK = 1013;
const int SPELL_PSIONIC_CELL_ADJUSTMENT = 1014;
const int SPELL_PSIONIC_CHAMELEON_POWER = 1015;
const int SPELL_PSIONIC_ECTOPLASMIC_FORM = 1016;
const int SPELL_PSIONIC_ENHANCED_STRENGTH = 1017;
const int SPELL_PSIONIC_FLESH_ARMOR = 1018;
const int SPELL_PSIONIC_LEND_HEALTH = 1019;
const int SPELL_PSIONIC_REGENERATE = 1020;
const int SPELL_PSIONIC_ACCELERATE = 1021;
const int SPELL_PSIONIC_CAUSE_SLEEP = 1022;
const int SPELL_PSIONIC_PHOTOSYNTHESIS = 1023;
const int SPELL_PSIONIC_STRENGTH_OF_LAND = 1024;
const int SPELL_PSIONIC_BANISHMENT = 1025;
const int SPELL_PSIONIC_SUMMON_PLANAR_CREATURE = 1026;
const int SPELL_PSIONIC_SUMMON_PLANAR_ENERGY = 1027;
const int SPELL_PSIONIC_DIMENSION_DOOR = 1028;
const int SPELL_PSIONIC_TIME_SHIFT = 1029;
const int SPELL_PSIONIC_DOMINATION = 1030;
const int SPELL_PSIONIC_CONTACT = 1031;
const int SPELL_PSIONIC_MIND_WHIPE = 1032;
const int SPELL_PSIONIC_MASS_DOMINATION = 1033;
const int SPELL_PSIONIC_HALLUCINATIONS = 1034;
const int SPELL_PSIONIC_ATTRACTION = 1035;
const int SPELL_PSIONIC_AVERSION = 1036;
const int SPELL_PSIONIC_DAYDREAM = 1037;
const int SPELL_PSIONIC_INFLICT_PAIN = 1038;
const int SPELL_PSIONIC_SENSORY_SUPPRESSION = 1039;
const int SPELL_PSIONIC_SUPPRESS_FEAR = 1040;
const int SPELL_PSIONIC_MIND_THRUST = 1041;
const int SPELL_PSIONIC_EGO_WHIP = 1042;
const int SPELL_PSIONIC_ID_INSINUATION = 1043;
const int SPELL_PSIONIC_PSIONIC_BLAST = 1044;
const int SPELL_PSIONIC_PSYCHIC_CRUSH = 1045;
const int SPELL_PSIONIC_INTELLECT_FORTRESS = 1046;
const int SPELL_PSIONIC_MENTAL_BARRIER = 1047;
const int SPELL_PSIONIC_MIND_BLANK = 1048;
const int SPELL_PSIONIC_THOUGHT_SHIELD = 1049;
const int SPELL_PSIONIC_TOWER_OF_IRON_WILL = 1050;
const int SPELL_PSIONIC_TRUE_SIGHT = 1051;
const int SPELL_PSIONIC_COMBAT_MIND = 1052;
const int SPELL_PSIONIC_DANGER_SENSE = 1053;
const int SPELL_PSIONIC_SEE_INVISIBILITY = 1054;
const int SPELL_PSIONIC_CLAIRVOYANCE_CLAIRAUDIENCE = 1055;
const int SPELL_PSIONIC_PSYCHIC_CLONE = 1056;
const int SPELL_PSIONIC_ULTRABLAST = 1057;
const int SPELL_PSIONIC_CANNIBALIZE = 1058;
const int SPELL_PSIONIC_PSYCHIC_DRAIN = 1059;
const int SPELL_PSIONIC_RECEPTACLE = 1060;
const int SPELL_PSIONIC_STASIS_FIELD = 1061;
const int SPELL_PSIONIC_WRENCH = 1062;
const int SPELL_PSIONIC_PSIONIC_VAMPIRISM = 1063;
const int SPELL_PSIONIC_PSIONIC_RESIDUE = 1064;
const int SPELL_PSIONIC_CATFALL = 1079;
const int SPELL_PSIONIC_ESP = 1080;
const int SPELL_PSIONIC_MIND_BLAST = 1081;
const int SPELL_PSIONIC_OBJECT_READING = 1082;
const int SPELL_PSIONIC_CONTROL_LIGHT = 1083;
const int SPELL_PSIONIC_CONTROL_WIND = 1086;
const int SPELL_PSIONIC_PSYCHIC_SURGERY = 1087;
const int SPELL_PSIONIC_TELEPORT = 1088;
const int SPELL_PSIONIC_CONVOCATION = 1089;
const int SPELL_PSIONIC_GROUP_TELEPORT = 1090;
const int SPELL_PSIONIC_CHEMICAL_SIMULATION = 1091;
const int SPELL_PSIONIC_CRISIS_OF_LIFE = 1092;
const int SPELL_PSIONIC_TRANSFORMATION = 1093;
const int SPELL_PSIONIC_INERTIAL_BARRIER = 1094;
const int SPELL_PSIONIC_MEGAKINESIS = 1095;
const int SPELL_PSIONIC_MASS_CONTACT = 1096;
const int SPELL_PSIONIC_COSMIC_AWARENESS = 1097;
const int SPELL_PSIONIC_EMPOWER = 1098;
const int SPELL_PSIONIC_PSYCHIC_BLADE = 1099;
const int PSIONIC_ENH_NONE = 0x0000;
const int PSIONIC_ENH_MAGNIFY = 0x0001;
const int PSIONIC_ENH_PROLONG = 0x0010;
const int PSIONIC_ENH_HARNESS_SUBCONSCIOUS = 0x0100;
const int PSIONIC_ENH_MEDITATIVE_FOCUS = 0x1000;
const int AOE_PSIONIC_DEATH_FIELD = 154;
const int AOE_PSIONIC_INTELLECT_FORTRESS = 121;
const int CLASS_TYPE_PSIONICIST = 44;
//This is an ugly kludge to make expertise work with GetEnhancedEffect().
//It's necessary because effects are reported as ints not floats.
const int EFFECT_SCALING_FACTOR=10;
//Makes sure psp totals and max are reported accurately.
//is necessary because of a lack of levelling up and login checks.
void PSPCheck(object oPC=OBJECT_SELF);
//Does the power score rolling and PSP checking.
//Not to be confused with PSPCheck which just verifies accuracy.
//Returns TRUE if there are no problems.
//Returns FALSE if there is a power check failure
//or there aren't enough PSPs available.
int PowerCheck(object oPC, int nCost, int nPowerScore, int nFeatID, int bSuppressSpam=FALSE);
//returns the Discipline ID (PSIONIC_DISCIPLINE_*) from nFeat.
//Note, nFeat must be one of FEAT_PSIONIC_*
//return value on error: -1
int GetDiscipline(int nFeatID);
//returns nCost modified by any appropriate expertise feats.
//Note, nFeat must be one of FEAT_PSIONIC_*
//return value on error is nCost, unmodified.
int GetModifiedPSPCost(int nCost, int nFeatID);
//returns nPowerScore modified by any appropriate focus feats.
//Note, nFeat must be one of FEAT_PSIONIC_*
//return value on error is nPowerScore, unmodified.
int GetModifiedPowerScore(int nPowerScore, int nFeatID);
//removes the effects of a specific power from oTarg.
//is used to prevent stacking of powers that shouldn't.
void RemoveEffectsFrom(object oTarg, int nSpellID);
//returns the current PSPs of oPC
//may be innacurate if PSPCheck hasn't been called first
int GetPSP(object oPC);
//returns the maximum PSPs of oPC
//may be innacurate if PSPCheck hasn't been called first
int GetMaxPSP(object oPC);
//sets the PSPs of oPC to nPSP
void SetPSP(object oPC, int nPSP);
//sets the maximum PSPs of oPC to nMaxPSP
//used internally, should not be used elsewhere.
void SetMaxPSP(object oPC, int nMaxPSP);
//Psionic spellhooking
//returns TRUE if the psionic can continue, returns FALSE otherwise
//edit lib_ps_spellhook to make changes.
int PsionicSpellHook(object oPC, int nFeatID);
//Returns oPC's effective Psionicist level when using
//the power associated with nFeatID.
//If nFeatID is not specified, or if no specialty feats are
//possessed by oPC then oPC's actual psionic level is returned.
int GetEffectivePsionicLevel(object oPC, int nFeatID=0);
//returns the location that oPC has set as his teleport anchor
location GetTeleportAnchor(object oPC=OBJECT_SELF);
//sets lHere as oPC's teleport anchor
void SetTeleportAnchor(location lHere, object oPC=OBJECT_SELF);
//returns the current time, in seconds.
int GetRealTime();
//returns TRUE if oItem is a weapon-type
int GetIsWeapon(object oItem);
//Enable any psionic enhancement powers used by oPC
//returns a multiplier to the base cost
//should only be called within PowerCheck(), not in other scripts
int ProcessEnhancements(object oPC, int nFeatID);
//Activate the enhancement nEnh where nEnh is one of PSIONIC_ENH_*
//it will take effect with the next power used
void SetEnhancement(object oPC, int nEnh);
//return nDur modified by Enhancement: Prolong, if applicable
//returns nDur, unmodified otherwise
//Note: should only be called AFTER PowerCheck()
int GetEnhancedDuration(int nDur);
//Return nEff modified by Enhancement: Magnify, if applicable
//returns nEff, unmodified otherwise
//Note: should only be called AFTER PowerCheck()
int GetEnhancedEffect(int nEff, int nFeatID=0);
//Return nPS modified by Enhancement: Meditative Focus, if applicable
//returns nPS, unmodified otherwise
int GetEnhancedPowerScore(int nPS);
//copy the enhancement flags from the caller to oTarget
//used primarily when creating persistent area effects.
void TransferEnhancements(object oTarget);
//sets off the trap, if any, on oTarget
void TriggerTrap(object oTarget);
/*************************************************************
*
* Implementations
*
**************************************************************/
void PSPCheck(object oPC=OBJECT_SELF)
{
int nPSPTotal=GetMaxPSP(oPC);
int nPSP=GetPSP(oPC);
int nPsionicistLevel=GetLevelByClass(CLASS_TYPE_PSIONICIST, oPC); // Check for Psionicist Class
int nWis=GetAbilityScore(oPC, ABILITY_WISDOM);
int nCon=GetAbilityScore(oPC, ABILITY_CONSTITUTION);
int nInt=GetAbilityScore(oPC, ABILITY_INTELLIGENCE);
int nPSPMax=(nWis-5)*2;
if (nPsionicistLevel>1)
{
if (nWis>15) nPSPMax=nPSPMax+((nWis-5)*(nPsionicistLevel-1));
else nPSPMax=nPSPMax+(10*(nPsionicistLevel-1));
}
if (nCon>15) nPSPMax=nPSPMax+(nCon-15);
if (nInt>15) nPSPMax=nPSPMax+(nInt-15);
if (GetHasFeat(FEAT_EPIC_EXPANSIVE_MIND_5, oPC)) nPSPMax=nPSPMax+200;
else if (GetHasFeat(FEAT_EPIC_EXPANSIVE_MIND_4, oPC)) nPSPMax=nPSPMax+100;
else if (GetHasFeat(FEAT_EPIC_EXPANSIVE_MIND_3, oPC)) nPSPMax=nPSPMax+160;
else if (GetHasFeat(FEAT_EPIC_EXPANSIVE_MIND_2, oPC)) nPSPMax=nPSPMax+140;
else if (GetHasFeat(FEAT_EPIC_EXPANSIVE_MIND_1, oPC)) nPSPMax=nPSPMax+120;
else if (GetHasFeat(FEAT_EXPANSIVE_MIND_5, oPC)) nPSPMax=nPSPMax+100;
else if (GetHasFeat(FEAT_EXPANSIVE_MIND_4, oPC)) nPSPMax=nPSPMax+80;
else if (GetHasFeat(FEAT_EXPANSIVE_MIND_3, oPC)) nPSPMax=nPSPMax+60;
else if (GetHasFeat(FEAT_EXPANSIVE_MIND_2, oPC)) nPSPMax=nPSPMax+40;
else if (GetHasFeat(FEAT_EXPANSIVE_MIND_1, oPC)) nPSPMax=nPSPMax+20;
if (nPSPTotal!=nPSPMax)
{
SetMaxPSP(oPC, nPSPMax);
SetPSP(oPC, nPSP+nPSPMax-nPSPTotal);
}
}
int PowerCheck(object oPC, int nCost, int nPowerScore, int nFeatID, int bSuppressSpam=FALSE)
{
//pre-spell hooking
//to use edit lib_ps_spellhook
if (!PsionicSpellHook(oPC, nFeatID))
return FALSE;
//end pre-spell hooking
PSPCheck(oPC);
int nPSP=GetPSP(oPC);
int nMult=ProcessEnhancements(oPC, nFeatID);
int nRoll=d20();
nCost*=nMult;
if (nFeatID!=FEAT_PSIONIC_RECEPTACLE)
nCost=GetModifiedPSPCost(nCost, nFeatID);
nPowerScore=GetModifiedPowerScore(nPowerScore, nFeatID);
if (nPSP<nCost)
{
FloatingTextStringOnCreature("Not enough PSPs.", oPC, FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(292), oPC);
return FALSE;
}
if ( nPowerScore<100 && nRoll!=1 &&
(nPowerScore+GetSkillRank(SKILL_CONCENTRATION, oPC)/5< nRoll
|| nRoll==20))
{
FloatingTextStringOnCreature("Power Check Failure", oPC, FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(292), oPC);
nPSP=nPSP-(nCost/2);
SetPSP(oPC, nPSP);
SendMessageToPC(oPC, "Remaining Psionic Strength Points: "+IntToString(nPSP));
return FALSE;
}
nPSP=nPSP-nCost;
SetPSP(oPC, nPSP);
if (!bSuppressSpam)
SendMessageToPC(oPC, "Remaining Psionic Strength Points: "+IntToString(nPSP));
return TRUE;
}
int GetDiscipline(int nFeatID)
{
int nDisc=-1;
if ((nFeatID>=3100 && nFeatID<=3106) || (nFeatID>=4862 && nFeatID<=4863) || (nFeatID>=4871 && nFeatID<=4872)) nDisc=1;
else if ((nFeatID>=3107 && nFeatID<=3124) || (nFeatID==4858) || (nFeatID>=4868 && nFeatID<=4870)) nDisc=2;
else if (nFeatID>=3125 && nFeatID<=3129 || (nFeatID>=4865 && nFeatID<=4867)) nDisc=3;
else if ((nFeatID>=3130 && nFeatID<=3150) || (nFeatID>=4859 && nFeatID<=4860) || (nFeatID==4873)) nDisc=4;
else if ((nFeatID>=3151 && nFeatID<=3155) || (nFeatID==4861) || (nFeatID>=4874)) nDisc=5;
else if ((nFeatID>=3156 && nFeatID<=3164) || (nFeatID==4864) || (nFeatID>=4875 && nFeatID<=4876)) nDisc=6;
return nDisc;
}
int GetModifiedPSPCost(int nCost, int nFeatID)
{
int nDisc=GetDiscipline(nFeatID);
if (nDisc==-1) return nCost;
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOKINESIS)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOKINESIS_EXPERTISE_2))
nCost=nCost - 2*nCost/5;
else if (GetHasFeat(FEAT_EPIC_PSYCHOKINESIS_EXPERTISE_1))
nCost=nCost - 3*nCost/10;
else if (GetHasFeat(FEAT_PSYCHOKINESIS_EXPERTISE_2))
nCost=nCost - nCost/5;
else if (GetHasFeat(FEAT_PSYCHOKINESIS_EXPERTISE_1))
nCost=nCost - nCost/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOMETABOLISM)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOMETABOLISM_EXPERTISE_2))
nCost=nCost - 2*nCost/5;
else if (GetHasFeat(FEAT_EPIC_PSYCHOMETABOLISM_EXPERTISE_1))
nCost=nCost - 3*nCost/10;
else if (GetHasFeat(FEAT_PSYCHOMETABILISM_EXPERTISE_2))
nCost=nCost - nCost/5;
else if (GetHasFeat(FEAT_PSYCHOMETABOLISM_EXPERTISE_1))
nCost=nCost - nCost/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOPORTATION)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOPORTATION_EXPERTISE_2))
nCost=nCost - 2*nCost/5;
else if (GetHasFeat(FEAT_EPIC_PSYCHOPORTATION_EXPERTISE_1))
nCost=nCost - 3*nCost/10;
else if (GetHasFeat(FEAT_PSYCHOPORTATION_EXPERTISE_2))
nCost=nCost - nCost/5;
else if (GetHasFeat(FEAT_PSYCHOPORTATION_EXPERTISE_1))
nCost=nCost - nCost/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_TELEPATHY)
{
if (GetHasFeat(FEAT_EPIC_TELEPATHY_EXPERTISE_2))
nCost=nCost - 2*nCost/5;
else if (GetHasFeat(FEAT_EPIC_TELEPATHY_EXPERTISE_1))
nCost=nCost - 3*nCost/10;
else if (GetHasFeat(FEAT_TELEPATHY_EXPERTISE_2))
nCost=nCost - nCost/5;
else if (GetHasFeat(FEAT_TELEPATHY_EXPERTISE_1))
nCost=nCost - nCost/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_CLAIRSENTIENCE)
{
if (GetHasFeat(FEAT_EPIC_CLAIRSENTIENCE_EXPERTISE_2))
nCost=nCost - 2*nCost/5;
else if (GetHasFeat(FEAT_EPIC_CLAIRSENTIENCE_EXPERTISE_1))
nCost=nCost - 3*nCost/10;
else if (GetHasFeat(FEAT_CLAIRSENTIENCE_EXPERTISE_2))
nCost=nCost - nCost/5;
else if (GetHasFeat(FEAT_CLAIRSENTIENCE_EXPERTISE_1))
nCost=nCost - nCost/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_METAPSIONICS)
{
if (GetHasFeat(FEAT_EPIC_METAPSIONICS_EXPERTISE_2))
nCost=nCost - 2*nCost/5;
else if (GetHasFeat(FEAT_EPIC_METAPSIONICS_EXPERTISE_1))
nCost=nCost - 3*nCost/10;
else if (GetHasFeat(FEAT_METAPSIONICS_EXPERTISE_2))
nCost=nCost - nCost/5;
else if (GetHasFeat(FEAT_METAPSIONICS_EXPERTISE_1))
nCost=nCost - nCost/10;
}
return nCost;
}
int GetModifiedPowerScore(int nPowerScore, int nFeatID)
{
int nDisc=GetDiscipline(nFeatID);
if (nDisc==-1) return nPowerScore;
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOKINESIS)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOKINESIS_FOCUS_2))
nPowerScore=nPowerScore+8;
else if (GetHasFeat(FEAT_EPIC_PSYCHOKINESIS_FOCUS_1))
nPowerScore=nPowerScore+6;
else if (GetHasFeat(FEAT_PSYCHOKINESIS_FOCUS_2))
nPowerScore=nPowerScore+4;
else if (GetHasFeat(FEAT_PSYCHOKINESIS_FOCUS_1))
nPowerScore=nPowerScore+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOMETABOLISM)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOMETABOLISM_FOCUS_2))
nPowerScore=nPowerScore+8;
else if (GetHasFeat(FEAT_EPIC_PSYCHOMETABOLISM_FOCUS_1))
nPowerScore=nPowerScore+6;
else if (GetHasFeat(FEAT_PSYCHOMETABOLISM_FOCUS_2))
nPowerScore=nPowerScore+4;
else if (GetHasFeat(FEAT_PSYCHOMETABOLISM_FOCUS_1))
nPowerScore=nPowerScore+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOPORTATION)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOPORTATION_FOCUS_2))
nPowerScore=nPowerScore+8;
else if (GetHasFeat(FEAT_EPIC_PSYCHOPORTATION_FOCUS_1))
nPowerScore=nPowerScore+6;
else if (GetHasFeat(FEAT_PSYCHOPORTATION_FOCUS_2))
nPowerScore=nPowerScore+4;
else if (GetHasFeat(FEAT_PSYCHOPORTATION_FOCUS_1))
nPowerScore=nPowerScore+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_TELEPATHY)
{
if (GetHasFeat(FEAT_EPIC_TELEPATHY_FOCUS_2))
nPowerScore=nPowerScore+8;
else if (GetHasFeat(FEAT_EPIC_TELEPATHY_FOCUS_1))
nPowerScore=nPowerScore+6;
else if (GetHasFeat(FEAT_TELEPATHY_FOCUS_2))
nPowerScore=nPowerScore+4;
else if (GetHasFeat(FEAT_TELEPATHY_FOCUS_1))
nPowerScore=nPowerScore+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_CLAIRSENTIENCE)
{
if (GetHasFeat(FEAT_EPIC_CLAIRSENTIENCE_FOCUS_2))
nPowerScore=nPowerScore+8;
else if (GetHasFeat(FEAT_EPIC_CLAIRSENTIENCE_FOCUS_1))
nPowerScore=nPowerScore+6;
else if (GetHasFeat(FEAT_CLAIRSENTIENCE_FOCUS_2))
nPowerScore=nPowerScore+4;
else if (GetHasFeat(FEAT_CLAIRSENTIENCE_FOCUS_1))
nPowerScore=nPowerScore+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_METAPSIONICS)
{
if (GetHasFeat(FEAT_EPIC_METAPSIONICS_FOCUS_2))
nPowerScore=nPowerScore+8;
else if (GetHasFeat(FEAT_EPIC_METAPSIONICS_FOCUS_1))
nPowerScore=nPowerScore+6;
else if (GetHasFeat(FEAT_METAPSIONICS_FOCUS_2))
nPowerScore=nPowerScore+4;
else if (GetHasFeat(FEAT_METAPSIONICS_FOCUS_1))
nPowerScore=nPowerScore+2;
}
return GetEnhancedPowerScore(nPowerScore);
}
void RemoveEffectsFrom(object oTarg, int nSpellID)
{
effect eEff=GetFirstEffect(oTarg);
while(GetIsEffectValid(eEff))
{
if(GetEffectSpellId(eEff)==nSpellID)
RemoveEffect(oTarg, eEff);
eEff=GetNextEffect(oTarg);
}
}
int GetPSP(object oPC)
{
int nPSP;
if(GetIsPC(oPC))
nPSP=GetLocalInt(GetModule(), GetPCPlayerName(oPC)+GetName(oPC)+"PSP");
else
nPSP=GetLocalInt(oPC, "PSP");
return nPSP;
}
int GetMaxPSP(object oPC)
{
int nMaxPSP;
if(GetIsPC(oPC))
nMaxPSP=GetLocalInt(GetModule(), GetPCPlayerName(oPC)+GetName(oPC)+"PSPMax");
else
nMaxPSP=GetLocalInt(oPC, "PSPMax");
return nMaxPSP;
}
void SetPSP(object oPC, int nPSP)
{
if(GetIsPC(oPC))
SetLocalInt(GetModule(), GetPCPlayerName(oPC)+GetName(oPC)+"PSP", nPSP);
else
SetLocalInt(oPC, "PSP", nPSP);
}
void SetMaxPSP(object oPC, int nMaxPSP)
{
if(GetIsPC(oPC))
SetLocalInt(GetModule(), GetPCPlayerName(oPC)+GetName(oPC)+"PSPMax", nMaxPSP);
else
SetLocalInt(oPC, "PSPMax", nMaxPSP);
}
int PsionicSpellHook(object oPC, int nFeatID)
{
int bRet;
SetLocalObject(GetModule(), "Ps_Player", oPC);
SetLocalInt(GetModule(), "Ps_FeatID", nFeatID);
SetLocalInt(GetModule(), "Ps_HookReturn", TRUE);
ExecuteScript("lib_ps_spellhook", GetModule());
bRet=GetLocalInt(GetModule(), "Ps_HookReturn");
DeleteLocalInt(GetModule(), "Ps_HookReturn");
return bRet;
}
int GetEffectivePsionicLevel(object oPC, int nFeatID=0)
{
int nLevel=GetLevelByClass(CLASS_TYPE_PSIONICIST, oPC);
int nDisc=GetDiscipline(nFeatID);
if (nDisc==-1) return nLevel;
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOKINESIS)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOKINESIS_SPECIALTY))
nLevel=nLevel+4;
else if (GetHasFeat(FEAT_PSYCHOKINESIS_SPECIALTY))
nLevel=nLevel+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOMETABOLISM)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOMETABOLISM_SPECIALTY))
nLevel=nLevel+4;
else if (GetHasFeat(FEAT_PSYCHOMETABOLISM_SPECIALTY))
nLevel=nLevel+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOPORTATION)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOPORTATION_SPECIALTY))
nLevel=nLevel+4;
else if (GetHasFeat(FEAT_PSYCHOPORTATION_SPECIALTY))
nLevel=nLevel+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_TELEPATHY)
{
if (GetHasFeat(FEAT_EPIC_TELEPATHY_SPECIALTY))
nLevel=nLevel+4;
else if (GetHasFeat(FEAT_TELEPATHY_SPECIALTY))
nLevel=nLevel+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_CLAIRSENTIENCE)
{
if (GetHasFeat(FEAT_EPIC_CLAIRSENTIENCE_SPECIALTY))
nLevel=nLevel+4;
else if (GetHasFeat(FEAT_CLAIRSENTIENCE_SPECIALTY))
nLevel=nLevel+2;
}
else if (nDisc==PSIONIC_DISCIPLINE_METAPSIONICS)
{
if (GetHasFeat(FEAT_EPIC_METAPSIONICS_SPECIALTY))
nLevel=nLevel+4;
else if (GetHasFeat(FEAT_METAPSIONICS_SPECIALTY))
nLevel=nLevel+2;
}
return nLevel;
}
location GetTeleportAnchor(object oPC=OBJECT_SELF)
{
location lLoc=GetLocalLocation(oPC, "PS_TeleportAnchor");
return lLoc;
}
void SetTeleportAnchor(location lHere, object oPC=OBJECT_SELF)
{
SetLocalLocation(oPC, "PS_TeleportAnchor", lHere);
}
int GetRealTime()
{
int SecondsPerMinute=60;
int MinutesPerHour=FloatToInt(HoursToSeconds(1)/60.0);
int HoursPerDay=24;
int DaysPerMonth=28;
int MonthsPerYear=12;
int SecondsPerYear=MonthsPerYear*DaysPerMonth*HoursPerDay*MinutesPerHour*SecondsPerMinute;
int SecondsPerMonth=DaysPerMonth*HoursPerDay*MinutesPerHour*SecondsPerMinute;
int SecondsPerDay=HoursPerDay*MinutesPerHour*SecondsPerMinute;
int SecondsPerHour=MinutesPerHour*SecondsPerMinute;
//reduces the year to prevent overflow errors
return (GetCalendarYear()-1000)*SecondsPerYear + GetCalendarMonth()*SecondsPerMonth
+ GetCalendarDay()*SecondsPerDay + GetTimeHour()*SecondsPerHour
+GetTimeMinute()*SecondsPerMinute + GetTimeSecond();
}
int GetIsWeapon(object oItem)
{
//returns TRUE if oItem is a slashing or piercing weapon
int nItem = GetBaseItemType(oItem);
if( (nItem == BASE_ITEM_BASTARDSWORD)
|| (nItem == BASE_ITEM_BATTLEAXE)
|| (nItem == BASE_ITEM_DOUBLEAXE)
|| (nItem == BASE_ITEM_GREATAXE)
|| (nItem == BASE_ITEM_GREATSWORD)
|| (nItem == BASE_ITEM_HALBERD)
|| (nItem == BASE_ITEM_HANDAXE)
|| (nItem == BASE_ITEM_KAMA)
|| (nItem == BASE_ITEM_KATANA)
|| (nItem == BASE_ITEM_KUKRI)
|| (nItem == BASE_ITEM_LONGSWORD)
|| (nItem == BASE_ITEM_SCIMITAR)
|| (nItem == BASE_ITEM_SCYTHE)
|| (nItem == BASE_ITEM_SICKLE)
|| (nItem == BASE_ITEM_TWOBLADEDSWORD)
|| (nItem == BASE_ITEM_DWARVENWARAXE)
|| (nItem == BASE_ITEM_THROWINGAXE)
|| (nItem == BASE_ITEM_WHIP)
|| (nItem == BASE_ITEM_ARROW)
|| (nItem == BASE_ITEM_DAGGER)
|| (nItem == BASE_ITEM_DART)
|| (nItem == BASE_ITEM_RAPIER)
|| (nItem == BASE_ITEM_SHORTSPEAR)
|| (nItem == BASE_ITEM_SHORTSWORD)
|| (nItem == BASE_ITEM_SHURIKEN)
|| (nItem == BASE_ITEM_BULLET)
|| (nItem == BASE_ITEM_BOLT)
|| (nItem == BASE_ITEM_CLUB)
|| (nItem == BASE_ITEM_DIREMACE)
|| (nItem == BASE_ITEM_HEAVYCROSSBOW)
|| (nItem == BASE_ITEM_HEAVYFLAIL)
|| (nItem == BASE_ITEM_LIGHTCROSSBOW)
|| (nItem == BASE_ITEM_LIGHTFLAIL)
|| (nItem == BASE_ITEM_LIGHTHAMMER)
|| (nItem == BASE_ITEM_LIGHTMACE)
|| (nItem == BASE_ITEM_LONGBOW)
|| (nItem == BASE_ITEM_MORNINGSTAR)
|| (nItem == BASE_ITEM_QUARTERSTAFF)
|| (nItem == BASE_ITEM_SHORTBOW)
|| (nItem == BASE_ITEM_SLING)
|| (nItem == BASE_ITEM_WARHAMMER)
|| (nItem == BASE_ITEM_GLOVES)
)
{
return TRUE;
}
else return FALSE;
}
int ProcessEnhancements(object oPC, int nFeatID)
{
int nFlags=GetLocalInt(oPC, "PsionEnhFlags");
int nMult=1;
SetLocalInt(oPC, "PsionMagnify", FALSE);
SetLocalInt(oPC, "PsionProlong", FALSE);
SetLocalInt(oPC, "PsionFocus", FALSE);
SetLocalInt(oPC, "PsionHarness", FALSE);
if((nFlags & PSIONIC_ENH_MAGNIFY) > 0)
{
if(nFeatID==FEAT_PSIONIC_BALLISTIC_ATTACK
|| nFeatID==FEAT_PSIONIC_PROJECT_FORCE
|| nFeatID==FEAT_PSIONIC_MOLECULAR_AGITATION
|| nFeatID==FEAT_PSIONIC_ADRENALINE_CONTROL
|| nFeatID==FEAT_PSIONIC_DEATH_FIELD
|| nFeatID==FEAT_PSIONIC_LIFE_DRAINING
|| nFeatID==FEAT_PSIONIC_CELL_ADJUSTMENT
|| nFeatID==FEAT_PSIONIC_CHAMELEON_POWER
|| nFeatID==FEAT_PSIONIC_REGENERATE
|| nFeatID==FEAT_PSIONIC_PHOTOSYNTHESIS
|| nFeatID==FEAT_PSIONIC_STRENGTH_OF_LAND
|| nFeatID==FEAT_PSIONIC_SUMMON_PLANAR_ENERGY
|| nFeatID==FEAT_PSIONIC_CONTACT
|| nFeatID==FEAT_PSIONIC_MIND_WHIPE
|| nFeatID==FEAT_PSIONIC_INFLICT_PAIN
|| nFeatID==FEAT_PSIONIC_EGO_WHIP
|| nFeatID==FEAT_PSIONIC_INTELLECT_FORTRESS
|| nFeatID==FEAT_PSIONIC_MENTAL_BARRIER
|| nFeatID==FEAT_PSIONIC_COMBAT_MIND
|| nFeatID==FEAT_PSIONIC_CLAIRVOYANCE_CLAIRAUDIENCE
|| nFeatID==FEAT_PSIONIC_PSIONIC_VAMPIRISM
|| nFeatID==FEAT_PSIONIC_CATFALL
|| nFeatID==FEAT_PSIONIC_ESP
|| nFeatID==FEAT_PSIONIC_OBJECT_READING
|| nFeatID==FEAT_PSIONIC_CHEMICAL_SIMULATION
|| nFeatID==FEAT_PSIONIC_MASS_CONTACT)
{
SetLocalInt(oPC, "PsionMagnify", TRUE);
nMult+=2;
}
}
if((nFlags & PSIONIC_ENH_PROLONG) > 0)
{
if(nFeatID==FEAT_PSIONIC_DEATH_FIELD
|| nFeatID==FEAT_PSIONIC_TELEKINESIS
|| (nFeatID>=3110 && nFeatID<=3113)
|| (nFeatID>=3115 && nFeatID<=3110)
|| (nFeatID>=3120 && nFeatID<=3125)
|| (nFeatID>=3129 && nFeatID<=3131)
|| nFeatID==FEAT_PSIONIC_MASS_DOMINATION
|| (nFeatID>=3135 && nFeatID<=3156)
|| nFeatID==FEAT_PSIONIC_STASIS_FIELD
|| (nFeatID>=4858 && nFeatID<=4862)
|| (nFeatID>=4870 && nFeatID<=4876))
{
SetLocalInt(oPC, "PsionProlong", TRUE);
nMult+=2;
}
}
if((nFlags & PSIONIC_ENH_MEDITATIVE_FOCUS) > 0)
{
SetLocalInt(oPC, "PsionFocus", TRUE);
nMult+=1;
}
if((nFlags & PSIONIC_ENH_HARNESS_SUBCONSCIOUS) > 0)
{
SetLocalInt(oPC, "PsionHarness", TRUE);
nMult=0;
}
SetLocalInt(oPC, "PsionEnhFlags", PSIONIC_ENH_NONE);
return nMult;
}
void SetEnhancement(object oPC, int nEnh)
{
int nFlags=GetLocalInt(oPC, "PsionEnhFlags");
if(nEnh==PSIONIC_ENH_NONE) SetLocalInt(oPC, "PsionEnhFlags", PSIONIC_ENH_NONE);
else SetLocalInt(oPC, "PsionEnhFlags", nFlags|nEnh );
}
int GetEnhancedDuration(int nDur)
{
if(GetLocalInt(OBJECT_SELF, "PsionProlong")) nDur*=2;
return nDur;
}
int GetEnhancedEffect(int nEff, int nFeatID=0)
{
object oPC=(GetObjectType(OBJECT_SELF)==OBJECT_TYPE_AREA_OF_EFFECT)
? GetAreaOfEffectCreator() : OBJECT_SELF;
int nDisc=GetDiscipline(nFeatID);
if(GetLocalInt(OBJECT_SELF, "PsionMagnify")) nEff*=2;
if (nDisc==-1) return nEff;
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOKINESIS)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOKINESIS_EXPERTISE_2, oPC))
nEff=(nEff*7)/5;
else if (GetHasFeat(FEAT_EPIC_PSYCHOKINESIS_EXPERTISE_1, oPC))
nEff=(nEff*13)/10;
else if (GetHasFeat(FEAT_PSYCHOKINESIS_EXPERTISE_2, oPC))
nEff=(nEff*6)/5;
else if (GetHasFeat(FEAT_PSYCHOKINESIS_EXPERTISE_1, oPC))
nEff=(nEff*11)/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOMETABOLISM)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOMETABOLISM_EXPERTISE_2, oPC))
nEff=(nEff*7)/5;
else if (GetHasFeat(FEAT_EPIC_PSYCHOMETABOLISM_EXPERTISE_1, oPC))
nEff=(nEff*13)/10;
else if (GetHasFeat(FEAT_PSYCHOMETABILISM_EXPERTISE_2, oPC))
nEff=(nEff*6)/5;
else if (GetHasFeat(FEAT_PSYCHOMETABOLISM_EXPERTISE_1, oPC))
nEff=(nEff*11)/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_PSYCHOPORTATION)
{
if (GetHasFeat(FEAT_EPIC_PSYCHOPORTATION_EXPERTISE_2, oPC))
nEff=(nEff*7)/5;
else if (GetHasFeat(FEAT_EPIC_PSYCHOPORTATION_EXPERTISE_1, oPC))
nEff=(nEff*13)/10;
else if (GetHasFeat(FEAT_PSYCHOPORTATION_EXPERTISE_2, oPC))
nEff=(nEff*6)/5;
else if (GetHasFeat(FEAT_PSYCHOPORTATION_EXPERTISE_1, oPC))
nEff=(nEff*11)/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_TELEPATHY)
{
if (GetHasFeat(FEAT_EPIC_TELEPATHY_EXPERTISE_2, oPC))
nEff=(nEff*7)/5;
else if (GetHasFeat(FEAT_EPIC_TELEPATHY_EXPERTISE_1, oPC))
nEff=(nEff*13)/10;
else if (GetHasFeat(FEAT_TELEPATHY_EXPERTISE_2, oPC))
nEff=(nEff*6)/5;
else if (GetHasFeat(FEAT_TELEPATHY_EXPERTISE_1, oPC))
nEff=(nEff*11)/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_CLAIRSENTIENCE)
{
if (GetHasFeat(FEAT_EPIC_CLAIRSENTIENCE_EXPERTISE_2, oPC))
nEff=(nEff*7)/5;
else if (GetHasFeat(FEAT_EPIC_CLAIRSENTIENCE_EXPERTISE_1, oPC))
nEff=(nEff*13)/10;
else if (GetHasFeat(FEAT_CLAIRSENTIENCE_EXPERTISE_2, oPC))
nEff=(nEff*6)/5;
else if (GetHasFeat(FEAT_CLAIRSENTIENCE_EXPERTISE_1, oPC))
nEff=(nEff*11)/10;
}
else if (nDisc==PSIONIC_DISCIPLINE_METAPSIONICS)
{
if (GetHasFeat(FEAT_EPIC_METAPSIONICS_EXPERTISE_2, oPC))
nEff=(nEff*7)/5;
else if (GetHasFeat(FEAT_EPIC_METAPSIONICS_EXPERTISE_1, oPC))
nEff=(nEff*13)/10;
else if (GetHasFeat(FEAT_METAPSIONICS_EXPERTISE_2, oPC))
nEff=(nEff*6)/5;
else if (GetHasFeat(FEAT_METAPSIONICS_EXPERTISE_1, oPC))
nEff=(nEff*11)/10;
}
return nEff;
}
int GetEnhancedPowerScore(int nPS)
{
if(GetLocalInt(OBJECT_SELF, "PsionFocus")) nPS=100;
return nPS;
}
void TransferEnhancements(object oTarget)
{
SetLocalInt(oTarget, "PsionMagnify", GetLocalInt(OBJECT_SELF, "PsionMagnify"));
SetLocalInt(oTarget, "PsionProlong", GetLocalInt(OBJECT_SELF, "PsionProlong"));
SetLocalInt(oTarget, "PsionFocus", GetLocalInt(OBJECT_SELF, "PsionFocus"));
SetLocalInt(oTarget, "PsionHarness", GetLocalInt(OBJECT_SELF, "PsionHarness"));
}
void TriggerTrap(object oTarget)
{
int nType;
effect eVis;
if(!GetIsTrapped(oTarget)) return;
nType=GetTrapBaseType(oTarget);
if(nType<=3) //spike trap
{
eVis = EffectVisualEffect(253);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oTarget));
}
else if(nType<=7) //holy trap
{
eVis = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oTarget));
}
else if(nType<=11) //tangle trap
{
//largely copied from nw_t1_tang*
int nDuration = 3+(nType-8);
location lTarget = GetLocation(oTarget);
effect eSlow = EffectSlow();
eVis = EffectVisualEffect(VFX_IMP_SLOW);
//Find first target in the size
object oTrapTarget = GetFirstObjectInShape(SHAPE_SPHERE, (nType<10?RADIUS_SIZE_SMALL:RADIUS_SIZE_MEDIUM), lTarget);
//Cycle through the objects in the radius
while (GetIsObjectValid(oTrapTarget))
{
if(!ReflexSave(oTrapTarget, 20+5*(nType-8), SAVING_THROW_TYPE_TRAP, oTarget))
{
//Apply slow effect and visual effect
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTrapTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSlow, oTrapTarget, RoundsToSeconds(nDuration));
}
//Get next target in the shape.
oTrapTarget = GetNextObjectInShape(SHAPE_SPHERE, (nType<10?RADIUS_SIZE_SMALL:RADIUS_SIZE_MEDIUM), lTarget);
}
}
else if(nType<=15) //acid trap
{
eVis = EffectVisualEffect(VFX_IMP_ACID_S);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oTarget));
}
else if(nType<=19 || nType==45) //fire trap
{
//largely copied from nw_t1_fire*
location lTarget = GetLocation(oTarget);
int nDamage;
eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
effect eDam;
int nSaveDC = nType==45 ? 33 : 17+3*(nType-16);
//Get first object in the target area
object oTrapTarget = GetFirstObjectInShape(SHAPE_SPHERE, (nType<10?RADIUS_SIZE_SMALL:RADIUS_SIZE_MEDIUM), lTarget);
//Cycle through the target area until all object have been targeted
while(GetIsObjectValid(oTrapTarget))
{
if(!GetIsReactionTypeFriendly(oTrapTarget))
{
//Roll damage
nDamage = d6(nType==16?5:(nType==17?8:(nType==10?15:(nType==19?25:50))));
//Adjust the trap damage based on the feats of the target
if(!ReflexSave(oTrapTarget, nSaveDC, SAVING_THROW_TYPE_TRAP, oTarget))
{
if (GetHasFeat(FEAT_IMPROVED_EVASION, oTrapTarget))
{
nDamage /= 2;
}
}
else if (GetHasFeat(FEAT_EVASION, oTrapTarget) || GetHasFeat(FEAT_IMPROVED_EVASION, oTrapTarget))
{
nDamage = 0;
}
else
{
nDamage /= 2;
}
if (nDamage > 0)
{
//Set the damage effect
eDam = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTrapTarget);
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTrapTarget));
}
}
//Get next target in shape
oTrapTarget = GetNextObjectInShape(SHAPE_SPHERE, (nType<10?RADIUS_SIZE_SMALL:RADIUS_SIZE_MEDIUM), lTarget);
}
}
else if(nType<=23 || nType==44) //electrical trap
{
//largely copied from nw_i0_spells
object oTrapTarget;
effect eLightning = EffectBeam(VFX_BEAM_LIGHTNING, oTarget, BODY_NODE_CHEST);
int nDamage = d6(nType==20?8:(nType==21?15:(nType==22?20:(nType==23?30:60))));
int nSecondary= nType==44 ? 6 : 3+(nType-20);
effect eDam;
effect eVis = EffectVisualEffect(VFX_IMP_LIGHTNING_S);
location lTarget = GetLocation(oTarget);
int nSaveDC = nType==20?19:(nType==21?22:(nType==22?26:(nType==23?28:35)));
int nCount = 0;
oTrapTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lTarget);
while (GetIsObjectValid(oTrapTarget) && nCount <= nSecondary)
{
if(!GetIsReactionTypeFriendly(oTarget))
{
//check to see that the original target is not hit again.
if(oTrapTarget != oTarget)
{
//Adjust the trap damage based on the feats of the target
if(!ReflexSave(oTrapTarget, nSaveDC, SAVING_THROW_TYPE_ELECTRICITY))
{
if (GetHasFeat(FEAT_IMPROVED_EVASION, oTrapTarget))
{
nDamage /= 2;
}
}
else if (GetHasFeat(FEAT_EVASION, oTrapTarget) || GetHasFeat(FEAT_IMPROVED_EVASION, oTrapTarget))
{
nDamage = 0;
}
else
{
nDamage /= 2;
}
if (nDamage > 0)
{
//Set the damage effect
eDam = EffectDamage(nDamage, DAMAGE_TYPE_ELECTRICAL);
//Apply the VFX impact and damage effect
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTrapTarget));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTrapTarget);
//Connect the lightning stream from one target to another.
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLightning, oTrapTarget, 0.75);
//Set the last target as the new start for the lightning stream
eLightning = EffectBeam(VFX_BEAM_LIGHTNING, oTrapTarget, BODY_NODE_CHEST);
}
}
//Reset the damage
nDamage = d6(nType==20?8:(nType==21?15:(nType==22?20:(nType==23?30:60))));
//Increment the count
nCount++;
}
//Get next target in the shape.
oTrapTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, lTarget);
}
}
else if(nType<=27) //gas trap
{
string sScript=(nType==24?"NW_T1_GasMinoC1":(nType==25?"NW_T1_GasAvgC1"
:(nType==25?"NW_T1_GasStrC1":"NW_T1_GasDeadC1")));
eVis=EffectAreaOfEffect(AOE_PER_FOGACID, sScript, "****", "****");
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eVis, GetLocation(oTarget), RoundsToSeconds(2));
}
else if(nType<=31 || nType==46) //cold trap
{
eVis = EffectVisualEffect(VFX_IMP_FROST_S);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
else if(nType<=35) //negative trap
{
eVis = EffectVisualEffect(VFX_IMP_REDUCE_ABILITY_SCORE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
else if(nType<=39 || nType==47) //sonic trap
{
//largely copied from nw_t1_sonc*
object oTrapTarget;
int nDamage;
effect eDam;
effect eStun = EffectStunned();
effect eFNF = EffectVisualEffect(VFX_FNF_SOUND_BURST);
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DISABLED);
effect eLink = EffectLinkEffects(eStun, eMind);
int nSaveDC = (nType==47?30:(11+3*(nType-36)));
location lTarget=GetLocation(oTarget);
//effect eDam;
//Apply the FNF to the spell location
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFNF, lTarget);
//Get the first target in the spell area
oTrapTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, GetLocation(GetEnteringObject()));
while (GetIsObjectValid(oTrapTarget))
{
//Roll damage
nDamage = (nType==36?0:d4(nType==37?3:(nType==38?5:(nType==39?8:40))));
//Make a Will roll to avoid being stunned
if(WillSave(oTrapTarget, nSaveDC, SAVING_THROW_TYPE_TRAP))
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTrapTarget, RoundsToSeconds(nType-35));
}
//Apply the VFX impact and damage effect
if(nDamage>0)
{
eDam = EffectDamage(nDamage, DAMAGE_TYPE_SONIC);
DelayCommand(0.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam,oTrapTarget));
}
//Get the next target in the spell area
oTrapTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget);
}
}
else if(nType<=43)
{
eVis = EffectVisualEffect(VFX_IMP_ACID_S);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
SetTrapDisabled(oTarget);
}