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.
158 lines
7.3 KiB
Plaintext
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);
|
|
} |