PRC8/nwn/nwnprc/trunk/scripts/prc_uni_shift.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

128 lines
4.9 KiB
Plaintext

//:://////////////////////////////////////////////
//:: prc_uni_shift
//:: Universal class script for classes that allow shifting
//:: (to prevent having to duplicate and install a script like this for each such class)
//:://////////////////////////////////////////////
#include "prc_inc_shifting"
#include "prc_spell_const"
#include "prc_inc_onhit"
const string SCRIPT_NAME = "prc_uni_shift";
const string SHIFTER_LEVELLING_ARRAY = "PRC_Shifter_Levelling_Array";
const string SHIFTER_SHAPE_LEARNED_LEVEL = "PRC_Shifter_AutoGranted";
void HandleShapeLearning(object oPC)
{
if (GetLevelByClass(CLASS_TYPE_PNP_SHIFTER, oPC))
{
if(!persistant_array_exists(oPC, SHIFTER_LEVELLING_ARRAY))
persistant_array_create(oPC, SHIFTER_LEVELLING_ARRAY);
int nLearnedLevel = GetPersistantLocalInt(oPC, SHIFTER_SHAPE_LEARNED_LEVEL);
int nShifterLevel = GetLevelByClass(CLASS_TYPE_PNP_SHIFTER, oPC);
int nCharacteLevel = GetHitDice(oPC);
int i;
for(i = nLearnedLevel; i < nShifterLevel; i++)
persistant_array_set_int(oPC, SHIFTER_LEVELLING_ARRAY, i, nCharacteLevel - (nShifterLevel-1-i));
}
}
void AddEvents(object oPC)
{
if (AddEventScript(oPC, EVENT_ONPLAYERLEVELUP, SCRIPT_NAME, TRUE, FALSE))
{
//If we're just adding the level up script, run the level-up function to let it "catch up" if necessary:
//the level-up event hook may not be called for Shifter level 1 because the PC isn't a Shifter until
//after the level-up for that level has been completed.
HandleShapeLearning(oPC);
}
AddEventScript(oPC, EVENT_ONPLAYERLEVELDOWN, SCRIPT_NAME, TRUE, FALSE);
AddEventScript(oPC, EVENT_ONHIT, SCRIPT_NAME, TRUE, FALSE);
}
void HandleEquip(object oPC, object oEquippedItem)
{
int bAddOnHitUniquePower = FALSE;
if (oEquippedItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC))
bAddOnHitUniquePower = TRUE;
else if (oEquippedItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC))
bAddOnHitUniquePower = TRUE;
else if (oEquippedItem == GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oPC))
bAddOnHitUniquePower = TRUE;
else if (oEquippedItem == GetItemInSlot(INVENTORY_SLOT_ARMS, oPC))
{
//Gloves or bracers (this doesn't actually work for bracers, however:
//apparently you can't add an OnHit: Cast Spell property to bracers)
bAddOnHitUniquePower = TRUE;
}
else if (oEquippedItem == GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC))
bAddOnHitUniquePower = TRUE;
if (bAddOnHitUniquePower && !GetLocalInt(oPC, "prc_uni_shift_suppress_onhit"))
Add_OnHitUniquePower(oEquippedItem, SCRIPT_NAME);
}
void HandleUnequip(object oPC, object oUnequippedItem)
{
//Just call the remove function. If we haven't added, the signature check will prevent the remove.
Remove_OnHitUniquePower(oUnequippedItem, SCRIPT_NAME);
}
void HandleOnHit(object oPC, object oItem, object oTarget)
{
//Fire all OnHit properties on creature items and skin
//(normally just the first will fire)
//NOTE: this event only fires for items to which the shifting code
//has added the item property On Hit Cast Spell: Unique Power
if (GetLocalInt(oItem, PRC_CUSTOM_ONHIT_SIGNATURE + SCRIPT_NAME))
{
if (GetLevelByClass(CLASS_TYPE_SOUL_EATER, oPC) && oItem != GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC))
{
SetLocalInt(oItem, "PRC_SOULEATER_ONHIT_ENERGYDRAIN", TRUE);
DelayCommand(0.0f, DeleteLocalInt(oItem, "PRC_SOULEATER_ONHIT_ENERGYDRAIN"));
CastSpellAtObject(SPELL_SE_ENERGY_DRAIN, oTarget, METAMAGIC_NONE, 0, 0, 0, oItem, oPC);
}
ApplyAllOnHitCastSpellsOnItemExcludingSubType(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, oTarget, oItem, oPC);
//NOTE: may not work correctly with spells not converted to use PRC functions (as detailed in prc_inc_onhit.nss)?
}
}
void HandleDefault(object oPC)
{
AddEvents(oPC);
if(GetLocalInt(oPC,"ONEQUIP")) //2 = equip, 1 = unequip
{
if (GetLocalInt(oPC,"ONEQUIP") == 2)
HandleEquip(oPC, GetItemLastEquipped());
else if (GetLocalInt(oPC,"ONEQUIP") == 1)
HandleUnequip(oPC, GetItemLastUnequipped());
}
else if(GetLocalInt(oPC,"ONREST"))
{
HandleShapeLearning(oPC); //Do this on resting in case it fails to fire where it should for some reason
HandleApplyShiftEffects(oPC);
}
HandleTrueShape(oPC);
HandleApplyShiftTemplate(oPC);
}
void main()
{
int nEvent = GetRunningEvent();
if(nEvent == FALSE) //We aren't being called from any event, instead from EvalPRCFeats
HandleDefault(OBJECT_SELF);
else if(nEvent == EVENT_ONPLAYERLEVELUP)
HandleShapeLearning(GetPCLevellingUp());
else if(nEvent == EVENT_ONPLAYERLEVELDOWN)
HandleShapeLearning(OBJECT_SELF);
else if(nEvent == EVENT_ONHIT)
HandleOnHit(OBJECT_SELF, PRCGetSpellCastItem(), PRCGetSpellTargetObject());
}