Files
PRC8/nwn/nwnprc/trunk/newspellbook/inf_energy_alt.nss
Jaysyn904 038a4cf88d 2026/03/28
Added default level up package for Warblade.
Moment of Prescience should be an instant action.
Truespeak should be a class skill for Factotum.
Added Armor Enhancement, Lesser infusion.
Added Armor Enhancement infusion.
Added Armor Enhancement, Greater infusion
Added Resistance Item infusion.
Added Weapon Augmentation, Personal infusion.
Added Weapon Augmentation infusion.
Added Weapon Augmentation, Lesser infusion.
2026-03-28 23:39:46 -04:00

158 lines
7.3 KiB
Plaintext

// inf_energy_alt.nss
#include "prc_sp_func"
#include "prc_inc_spells"
#include "psi_inc_enrgypow"
#include "prc_craft_inc" // Add this for item property serialization
const int SPELL_ENERGY_ALTERATION_COLD = 9000;
const int SPELL_ENERGY_ALTERATION_ELEC = 9001;
const int SPELL_ENERGY_ALTERATION_FIRE = 9002;
const int SPELL_ENERGY_ALTERATION_SONIC = 9003;
// Forward declarations
void StoreOriginalProperties(object oItem);
void RestoreOriginalProperties(object oItem);
int ConvertDamageTypeToIPConst(int nDamageType);
// Convert DAMAGE_TYPE_* to IP_CONST_DAMAGETYPE_*
int ConvertDamageTypeToIPConst(int nDamageType)
{
switch(nDamageType)
{
case DAMAGE_TYPE_ACID: return IP_CONST_DAMAGETYPE_ACID;
case DAMAGE_TYPE_COLD: return IP_CONST_DAMAGETYPE_COLD;
case DAMAGE_TYPE_ELECTRICAL: return IP_CONST_DAMAGETYPE_ELECTRICAL;
case DAMAGE_TYPE_FIRE: return IP_CONST_DAMAGETYPE_FIRE;
case DAMAGE_TYPE_SONIC: return IP_CONST_DAMAGETYPE_SONIC;
default: return IP_CONST_DAMAGETYPE_ACID;
}
return IP_CONST_DAMAGETYPE_ACID; // Add explicit return for compiler
}
void ApplyEnergyAlteration(object oItem, int nSpellID, int nCasterLvl)
{
struct energy_adjustments enAdj = EvaluateEnergy(
nSpellID,
SPELL_ENERGY_ALTERATION_COLD,
SPELL_ENERGY_ALTERATION_ELEC,
SPELL_ENERGY_ALTERATION_FIRE,
SPELL_ENERGY_ALTERATION_SONIC
);
// Modify existing energy properties
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
int nType = GetItemPropertyType(ip);
// Replace damage bonus properties
if(nType == ITEM_PROPERTY_DAMAGE_BONUS)
{
int nDamageType = GetItemPropertySubType(ip);
if(nDamageType == DAMAGE_TYPE_ACID || nDamageType == DAMAGE_TYPE_COLD ||
nDamageType == DAMAGE_TYPE_ELECTRICAL || nDamageType == DAMAGE_TYPE_FIRE ||
nDamageType == DAMAGE_TYPE_SONIC)
{
RemoveItemProperty(oItem, ip);
itemproperty ipNew = ItemPropertyDamageBonus(enAdj.nDamageType, GetItemPropertyCostTableValue(ip));
AddItemProperty(DURATION_TYPE_TEMPORARY, ipNew, oItem, RoundsToSeconds(nCasterLvl * 10));
SetLocalInt(oItem, "EnergyAlter_Temp_" + IntToString(ITEM_PROPERTY_DAMAGE_BONUS), TRUE);
}
}
// Replace resistance properties
if(nType == ITEM_PROPERTY_DAMAGE_RESISTANCE)
{
int nResistType = GetItemPropertySubType(ip);
if(nResistType == IP_CONST_DAMAGETYPE_ACID || nResistType == IP_CONST_DAMAGETYPE_COLD ||
nResistType == IP_CONST_DAMAGETYPE_ELECTRICAL || nResistType == IP_CONST_DAMAGETYPE_FIRE ||
nResistType == IP_CONST_DAMAGETYPE_SONIC)
{
RemoveItemProperty(oItem, ip);
int nNewType = ConvertDamageTypeToIPConst(enAdj.nDamageType);
itemproperty ipNew = ItemPropertyDamageResistance(nNewType, GetItemPropertyCostTableValue(ip));
AddItemProperty(DURATION_TYPE_TEMPORARY, ipNew, oItem, RoundsToSeconds(nCasterLvl * 10));
SetLocalInt(oItem, "EnergyAlter_Temp_" + IntToString(ITEM_PROPERTY_DAMAGE_RESISTANCE), TRUE);
}
}
ip = GetNextItemProperty(oItem);
}
// Schedule restoration
DelayCommand(RoundsToSeconds(nCasterLvl * 10), RestoreOriginalProperties(oItem));
}
// Store original properties with PRC persistent backup
void StoreOriginalProperties(object oItem)
{
string sItemID = GetObjectUUID(oItem);
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
string sPropData = GetItemPropertyString(ip); // Use PRC's function
SetLocalString(oItem, "EnergyAlter_Original_" + IntToString(GetItemPropertyType(ip)), sPropData);
// PRC persistence for crash recovery
SetPersistantLocalString(oItem, "EnergyAlter_" + sItemID + "_" + IntToString(GetItemPropertyType(ip)), sPropData);
ip = GetNextItemProperty(oItem);
}
SetLocalInt(oItem, "EnergyAlter_Active", TRUE);
SetLocalString(oItem, "EnergyAlter_ItemID", sItemID);
}
// Restore properties with cleanup
void RestoreOriginalProperties(object oItem)
{
string sItemID = GetLocalString(oItem, "EnergyAlter_ItemID");
// Remove temporary properties
itemproperty ip = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ip))
{
if(GetLocalInt(oItem, "EnergyAlter_Temp_" + IntToString(GetItemPropertyType(ip))))
RemoveItemProperty(oItem, ip);
ip = GetNextItemProperty(oItem);
}
// Restore original properties
int nType;
for(nType = 0; nType < 100; nType++)
{
string sPropData = GetPersistantLocalString(oItem, "EnergyAlter_" + sItemID + "_" + IntToString(nType));
if(sPropData != "")
{
struct ipstruct ipData = GetIpStructFromString(sPropData);
itemproperty ipOriginal = ConstructIP(ipData.type, ipData.subtype, ipData.costtablevalue, ipData.param1value);
AddItemProperty(DURATION_TYPE_PERMANENT, ipOriginal, oItem);
}
}
// Cleanup - clear PRC persistent variables
DeletePersistantLocalString(oItem, "EnergyAlter_" + sItemID);
DeleteLocalInt(oItem, "EnergyAlter_Active");
}
void main()
{
if(!X2PreSpellCastCode()) return;
object oCaster = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
int nSpellID = PRCGetSpellId();
int nCasterLvl = PRCGetCasterLevel(oCaster);
// Material component validation (remove for testing)
// if(!GetIsObjectValid(GetItemPossessedBy(oCaster, "energy_alter_ointment")))
// {
// FloatingTextStringOnCreature("You need an alchemical ointment (50 gp) to cast this spell.", oCaster, FALSE);
// return;
// }
// DestroyObject(GetItemPossessedBy(oCaster, "energy_alter_ointment"));
// Store original properties and apply alteration
StoreOriginalProperties(oTarget);
ApplyEnergyAlteration(oTarget, nSpellID, nCasterLvl);
}