Further file organization
Further file organization
This commit is contained in:
527
nwn/nwnprc/trunk/include/prc_spellf_inc.nss
Normal file
527
nwn/nwnprc/trunk/include/prc_spellf_inc.nss
Normal file
@@ -0,0 +1,527 @@
|
||||
/*
|
||||
|
||||
prc_spellf_inc.nss - Spellfire functions
|
||||
|
||||
|
||||
|
||||
By: Flaming_Sword
|
||||
Created: February 15, 2006
|
||||
Modified: February 15, 2006
|
||||
|
||||
Naming conventions:
|
||||
nExpend <-> GetPersistantLocalInt(oPC, "SpellfireLevelExpend");
|
||||
nStored <-> GetPersistantLocalInt(oPC, "SpellfireLevelStored");
|
||||
|
||||
*/
|
||||
|
||||
//#include "inc_utility"
|
||||
//#include "prc_alterations"
|
||||
#include "prc_inc_sp_tch"
|
||||
#include "prcsp_engine"
|
||||
//int CheckSpellfire(object oCaster, object oTarget, int bFriendly = FALSE);
|
||||
|
||||
//Spellfire Functions
|
||||
|
||||
//Verifies levels to expend, returns new levels to expend
|
||||
int SpellfireVerifyExpend(object oPC, int nExpend, int nStored)
|
||||
{
|
||||
int nCON = GetAbilityScore(oPC, ABILITY_CONSTITUTION);
|
||||
|
||||
//sanity check, at least 1, capped by CON and stored
|
||||
if(nExpend < 1)
|
||||
{
|
||||
nExpend = 1;
|
||||
SetPersistantLocalInt(oPC, "SpellfireLevelExpend", nExpend);
|
||||
}
|
||||
if(nExpend > nCON) nExpend = nCON; //in case CON has changed
|
||||
if(nExpend > nStored) nExpend = nStored; //can't spend more than you've got
|
||||
|
||||
return nExpend;
|
||||
}
|
||||
|
||||
//Adjusts the number of spellfire levels expended
|
||||
//in the next use of spellfire
|
||||
void AdjustSpellfire(object oPC, int nAdjust)
|
||||
{
|
||||
int nExpend = GetPersistantLocalInt(oPC, "SpellfireLevelExpend");
|
||||
nExpend += nAdjust;
|
||||
if(nExpend < 1) nExpend = 1; //at least 1
|
||||
SetPersistantLocalInt(oPC, "SpellfireLevelExpend", nExpend);
|
||||
SendMessageToPC(oPC, "Spellfire levels to expend: " + IntToString(nExpend));
|
||||
}
|
||||
|
||||
//Sets flag to change quickselects a la psionics
|
||||
void SpellfireQuickselectChange(object oPC)
|
||||
{
|
||||
SetLocalInt(oPC, "Spellfire_Quickselect_Change", 1); //set flag
|
||||
SendMessageToPC(oPC, "Select a quickselect to store the current setting");
|
||||
DelayCommand(10.0, DeleteLocalInt(oPC, "Spellfire_Quickselect_Change")); //auto-delete
|
||||
}
|
||||
|
||||
//Sets or changes quickselects
|
||||
void SpellfireQuickselect(object oPC, int nSpellID)
|
||||
{
|
||||
int nExpend;
|
||||
if(GetLocalInt(oPC, "Spellfire_Quickselect_Change"))
|
||||
{
|
||||
nExpend = GetPersistantLocalInt(oPC, "SpellfireLevelExpend");
|
||||
SetPersistantLocalInt(oPC, "Spellfire_Quickselect_" + IntToString(nSpellID), nExpend);
|
||||
SendMessageToPC(oPC, "Quickselect " + IntToString(nSpellID - SPELL_SPELLFIRE_QUICKSELECT_1 + 1) + " set to " + IntToString(nExpend));
|
||||
DeleteLocalInt(oPC, "Spellfire_Quickselect_Change");
|
||||
}
|
||||
else
|
||||
{
|
||||
nExpend = GetPersistantLocalInt(oPC, "Spellfire_Quickselect_" + IntToString(nSpellID));
|
||||
SetPersistantLocalInt(oPC, "SpellfireLevelExpend", nExpend);
|
||||
SendMessageToPC(oPC, "Spellfire levels to expend: " + IntToString(nExpend));
|
||||
}
|
||||
}
|
||||
|
||||
//Expends spellfire and returns the new value
|
||||
int ExpendSpellfire(object oPC)
|
||||
{
|
||||
int nStored = GetPersistantLocalInt(oPC, "SpellfireLevelStored");
|
||||
if(!nStored) return 0;
|
||||
int nExpend = GetPersistantLocalInt(oPC, "SpellfireLevelExpend");
|
||||
|
||||
nExpend = SpellfireVerifyExpend(oPC, nExpend, nStored);
|
||||
|
||||
nStored -= nExpend;
|
||||
SetPersistantLocalInt(oPC, "SpellfireLevelStored", nStored);
|
||||
return nExpend;
|
||||
}
|
||||
|
||||
//Applies spellfire damage to target
|
||||
void SpellfireDamage(object oCaster, object oTarget, int nRoll, int nDamage, int bMaelstrom = FALSE)
|
||||
{
|
||||
if(bMaelstrom)
|
||||
{
|
||||
//nDamage += ApplySpellBetrayalStrikeDamage(oTarget, oCaster);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, PRCEffectDamage(oTarget, nDamage / 2, DAMAGE_TYPE_MAGICAL), oTarget);
|
||||
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(nDamage - (nDamage / 2), DAMAGE_TYPE_FIRE), oTarget);
|
||||
}
|
||||
else
|
||||
ApplyTouchAttackDamage(oCaster, oTarget, nRoll, nDamage, DAMAGE_TYPE_MAGICAL, DAMAGE_TYPE_FIRE);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SPELLF_FLAME), oTarget);
|
||||
}
|
||||
|
||||
//Spellfire attack roll -> damage
|
||||
void SpellfireAttackRoll(object oCaster, object oTarget, int nExpend, int iMod = 0, int nDC = 20, int bBeam = FALSE, int bMaelstrom = FALSE)
|
||||
{
|
||||
int nRoll, nDamage;
|
||||
|
||||
//Account for Energy Draconic Aura
|
||||
if (GetLocalInt(oCaster, "FireEnergyAura") > 0)
|
||||
{
|
||||
nDC += GetLocalInt(oCaster, "FireEnergyAura");
|
||||
}
|
||||
|
||||
//Weapon Focus (spellfire) applies to spellfire only
|
||||
if(GetHasFeat(FEAT_WEAPON_FOCUS_SPELLFIRE, oCaster)) iMod++;
|
||||
if(GetHasFeat(FEAT_EPIC_WEAPON_FOCUS_SPELLFIRE, oCaster)) iMod += 2;
|
||||
|
||||
if(oCaster == oTarget) //yeah, like you could miss with a touch attack on yourself
|
||||
{
|
||||
nRoll = 1;
|
||||
nDamage = d6(nExpend);
|
||||
}
|
||||
else
|
||||
{
|
||||
nRoll = bMaelstrom ? 1 : GetAttackRoll(oTarget, oCaster, GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oCaster), 0, 0, iMod, TRUE, 0.0, TRUE);
|
||||
nDamage = PRCGetReflexAdjustedDamage(d6(nExpend), oTarget, nDC, SAVING_THROW_TYPE_NONE, oCaster);
|
||||
}
|
||||
if(bBeam)
|
||||
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_SPELLFIRE, oCaster, BODY_NODE_HAND, !nRoll), oTarget, 1.2 /*+ (0.5 * IntToFloat(nAttacks))*/);
|
||||
if(nRoll && nDamage)
|
||||
SpellfireDamage(oCaster, oTarget, nRoll, nDamage, bMaelstrom);
|
||||
}
|
||||
|
||||
//Hits target with spellfire, implements rapid blast
|
||||
void SpellfireAttack(object oCaster, object oTarget, int bBeam, int nAttacks = 1)
|
||||
{
|
||||
if(!GetPersistantLocalInt(oCaster, "SpellfireLevelStored"))
|
||||
{
|
||||
SendMessageToPC(oCaster, "You have no more stored spellfire levels");
|
||||
return;
|
||||
}
|
||||
int nLevel = GetLevelByClass(CLASS_TYPE_SPELLFIRE, oCaster);
|
||||
if(nAttacks > ((nLevel / 4) + 1))
|
||||
{
|
||||
SendMessageToPC(oCaster, "You do not have enough Spellfire Channeler levels use this feat");
|
||||
return;
|
||||
}
|
||||
int iMod = 0;
|
||||
int i;
|
||||
//looping attacks
|
||||
//SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_SPELLFIRE, oCaster, BODY_NODE_HAND, !nRoll), oTarget, 1.2 + (0.5 * IntToFloat(nAttacks)));
|
||||
SignalEvent(oTarget, EventSpellCastAt(oCaster, SPELL_SPELLFIRE_ATTACK));
|
||||
for(i = 0; i < nAttacks; i++)
|
||||
DelayCommand(0.5 * IntToFloat(i), SpellfireAttackRoll(oCaster, oTarget, ExpendSpellfire(oCaster), iMod - (2 * i), 20, bBeam));
|
||||
//longer effect for more blasts
|
||||
DelayCommand(0.1, SendMessageToPC(oCaster, "Spellfire levels stored: " + IntToString(GetPersistantLocalInt(oCaster, "SpellfireLevelStored"))));
|
||||
}
|
||||
|
||||
//Heals target
|
||||
void SpellfireHeal(object oCaster, object oTarget)
|
||||
{
|
||||
if(!GetPersistantLocalInt(oCaster, "SpellfireLevelStored"))
|
||||
{
|
||||
SendMessageToPC(oCaster, "You have no more stored spellfire levels");
|
||||
return;
|
||||
}
|
||||
int nExpend = ExpendSpellfire(oCaster);
|
||||
int nHeal = 2 * nExpend;
|
||||
if(GetHasFeat(FEAT_SPELLFIRE_IMPROVED_HEALING, oCaster))
|
||||
nHeal = d4(nExpend) + nExpend;
|
||||
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(nHeal), oTarget);
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_SPELLF_HEAL), oTarget);
|
||||
DelayCommand(0.1, SendMessageToPC(oCaster, "Spellfire levels stored: " + IntToString(GetPersistantLocalInt(oCaster, "SpellfireLevelStored"))));
|
||||
}
|
||||
|
||||
//Maelstrom of fire
|
||||
void SpellfireMaelstrom(object oCaster)
|
||||
{
|
||||
if(!GetPersistantLocalInt(oCaster, "SpellfireLevelStored"))
|
||||
{
|
||||
SendMessageToPC(oCaster, "You have no more stored spellfire levels");
|
||||
return;
|
||||
}
|
||||
int nLevel = GetLevelByClass(CLASS_TYPE_SPELLFIRE, oCaster);
|
||||
int nCHA = GetAbilityModifier(ABILITY_CHARISMA, oCaster);
|
||||
int nDC = 10 + nLevel + nCHA;
|
||||
|
||||
//Account for Energy Draconic Aura
|
||||
if (GetLocalInt(oCaster, "FireEnergyAura") > 0)
|
||||
{
|
||||
nDC += GetLocalInt(oCaster, "FireEnergyAura");
|
||||
}
|
||||
|
||||
//expend once, hit multiple targets
|
||||
int nExpend = ExpendSpellfire(oCaster);
|
||||
float fDelay;
|
||||
location lTarget = GetLocation(oCaster);
|
||||
effect eExplode = EffectVisualEffect(VFX_FNF_SPELLF_EXP);
|
||||
//KABOOM!
|
||||
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eExplode, lTarget);
|
||||
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
||||
while(GetIsObjectValid(oTarget))
|
||||
{
|
||||
if(spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||
{ //ripped off fireball
|
||||
SignalEvent(oTarget, EventSpellCastAt(oCaster, SPELL_SPELLFIRE_MAELSTROM));
|
||||
//Get the distance between the explosion and the target to calculate delay
|
||||
fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget)) / 20;
|
||||
DelayCommand(fDelay, SpellfireAttackRoll(oCaster, oTarget, nExpend, 0, nDC, FALSE, TRUE));
|
||||
}
|
||||
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lTarget, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
||||
}
|
||||
}
|
||||
|
||||
//Returns the caster level of an item with the cast spell property
|
||||
int GetItemCasterLevelFromCastSpell(object oItem, itemproperty ip)
|
||||
{
|
||||
int nCostTableValue = GetItemPropertyCostTableValue(ip);
|
||||
int nSubtype = GetItemPropertySubType(ip);
|
||||
int nCasterLevel = StringToInt(Get2DACache("iprp_spells", "CasterLvl", nSubtype));
|
||||
|
||||
itemproperty ip2 = GetFirstItemProperty(oItem);
|
||||
while(GetIsItemPropertyValid(ip2))
|
||||
{
|
||||
if(GetItemPropertyType(ip2) == ITEM_PROPERTY_CAST_SPELL_CASTER_LEVEL &&
|
||||
//temporary caster level? i think not.
|
||||
GetItemPropertyDurationType(ip2) == DURATION_TYPE_PERMANENT &&
|
||||
GetItemPropertySubType(ip2) == nSubtype)
|
||||
{
|
||||
int nNewCasterLevel = GetItemPropertyCostTableValue(ip2); //caster level property
|
||||
if(nNewCasterLevel > nCasterLevel) nCasterLevel = nNewCasterLevel;
|
||||
break;
|
||||
}
|
||||
ip2 = GetNextItemProperty(oItem);
|
||||
}
|
||||
return nCasterLevel;
|
||||
}
|
||||
|
||||
//Returns TRUE if an item is drained
|
||||
int SpellfireDrainItem(object oPC, object oItem, int bCharged = TRUE, int bSingleUse = TRUE)
|
||||
{
|
||||
if(GetIsObjectValid(oItem) && GetIsMagicItem(oItem))
|
||||
{ //drain charged item
|
||||
if(bCharged) //because big compound if statements are messy
|
||||
{
|
||||
int nBase = GetBaseItemType(oItem);
|
||||
int nExpend = GetPersistantLocalInt(oPC, "SpellfireLevelExpend");
|
||||
if(nExpend < 1)
|
||||
{
|
||||
nExpend = 1;
|
||||
SetPersistantLocalInt(oPC, "SpellfireLevelExpend", nExpend);
|
||||
}
|
||||
int nStored = GetPersistantLocalInt(oPC, "SpellfireLevelStored");
|
||||
int nCap = SpellfireMax(oPC) - nStored;
|
||||
itemproperty ip;
|
||||
int nSubType;
|
||||
int nStack = GetItemStackSize(oItem);
|
||||
int nCharges = GetItemCharges(oItem);
|
||||
if(nCharges) //charged item
|
||||
{
|
||||
nExpend = min(min(nCharges, nCap), nExpend); //capped by charges and capacity
|
||||
SetItemCharges(oItem, nCharges - nExpend); //will destroy item if all charges drained
|
||||
AddSpellfireLevels(oPC, nExpend); //adds 1 level/charge
|
||||
return TRUE;
|
||||
}
|
||||
ip = GetFirstItemProperty(oItem);
|
||||
while(GetIsItemPropertyValid(ip)) //single use item
|
||||
{
|
||||
if(GetItemPropertyType(ip) == ITEM_PROPERTY_CAST_SPELL &&
|
||||
GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT &&
|
||||
GetItemPropertyCostTableValue(ip) == IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE)
|
||||
{
|
||||
if(DEBUG)
|
||||
{
|
||||
DoDebug("SpellfireDrainItem(): nBase = " + IntToString(nBase), oPC);
|
||||
DoDebug("SpellfireDrainItem(): nStack = " + IntToString(nStack), oPC);
|
||||
DoDebug("SpellfireDrainItem(): nCap = " + IntToString(nCap), oPC);
|
||||
DoDebug("SpellfireDrainItem(): nExpend = " + IntToString(nExpend), oPC);
|
||||
}
|
||||
nSubType = GetItemPropertySubType(ip);
|
||||
//hardcoded filter
|
||||
if(!(
|
||||
(nSubType >= 329 && nSubType <= 344) ||
|
||||
(nSubType == 359) ||
|
||||
(nSubType >= 400 && nSubType <= 409) ||
|
||||
(nSubType >= 411 && nSubType <= 446) ||
|
||||
(nSubType >= 490 && nSubType <= 500) ||
|
||||
(nSubType == 513) ||
|
||||
(nSubType >= 521 && nSubType <= 537) ||
|
||||
(nSubType >= 750 && nSubType <= 851) ||
|
||||
(nSubType >= 1201)
|
||||
))
|
||||
{
|
||||
|
||||
if((nBase == BASE_ITEM_POTIONS) ||
|
||||
(nBase == BASE_ITEM_SCROLL) ||
|
||||
(nBase == BASE_ITEM_SPELLSCROLL) ||
|
||||
(nBase == BASE_ITEM_BLANK_POTION) ||
|
||||
(nBase == BASE_ITEM_BLANK_SCROLL) ||
|
||||
(nBase == BASE_ITEM_ENCHANTED_POTION) ||
|
||||
(nBase == BASE_ITEM_ENCHANTED_SCROLL)
|
||||
)
|
||||
{
|
||||
nExpend = min(min(nStack, nCap), nExpend); //capped by charges and capacity
|
||||
if(nExpend == nStack)
|
||||
DestroyObject(oItem);
|
||||
else
|
||||
SetItemStackSize(oItem, nStack - nExpend); //modifies stack size as scrolls/potions are used up
|
||||
AddSpellfireLevels(oPC, nExpend); //adds 1 level/charge
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveItemProperty(oItem, ip); //just removes the cast spell property
|
||||
AddSpellfireLevels(oPC, 1); //adds 1 level
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
ip = GetNextItemProperty(oItem);
|
||||
}
|
||||
}
|
||||
else //drain permanent item
|
||||
{
|
||||
itemproperty ip = GetFirstItemProperty(oItem);
|
||||
int nCostTableValue = GetItemPropertyCostTableValue(ip);
|
||||
while(GetIsItemPropertyValid(ip))
|
||||
{
|
||||
if(GetItemPropertyType(ip) == ITEM_PROPERTY_CAST_SPELL &&
|
||||
GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT &&
|
||||
nCostTableValue >= IP_CONST_CASTSPELL_NUMUSES_0_CHARGES_PER_USE)
|
||||
{
|
||||
nCostTableValue = GetItemPropertyCostTableValue(ip);
|
||||
int nSubtype = GetItemPropertySubType(ip);
|
||||
int nLevel = GetItemCasterLevelFromCastSpell(oItem, ip) / 2;
|
||||
RemoveItemProperty(oItem, ip); //just removes the cast spell property
|
||||
AddSpellfireLevels(oPC, nLevel); //adds half the caster level
|
||||
|
||||
DelayCommand(HoursToSeconds(24), //reapplying property
|
||||
IPSafeAddItemProperty(oItem,
|
||||
ItemPropertyCastSpell(nSubtype, nCostTableValue),
|
||||
0.0,
|
||||
X2_IP_ADDPROP_POLICY_KEEP_EXISTING));
|
||||
return 1;
|
||||
}
|
||||
ip = GetNextItemProperty(oItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Returns "'s" if sName has no s at the end, otherwise "'"
|
||||
string Name_s(string sName = "")
|
||||
{
|
||||
return (GetStringRight(sName, 1) == "s") ? "'" : "'s";
|
||||
}
|
||||
|
||||
//Finds an item to drain, favours equipped items
|
||||
//WARNING: This will loop through every item property on every item
|
||||
// until the right conditions are met
|
||||
void SpellfireDrain(object oPC, object oTarget, int bCharged = TRUE, int bExemptCreatureItems = TRUE, int bSingleUse = TRUE)
|
||||
{
|
||||
object oItem;
|
||||
int nObjectType = GetObjectType(oTarget);
|
||||
string sMessage_oPC = "";
|
||||
string sMessage_oTarget = "";
|
||||
string sName_oPC = GetName(oPC);
|
||||
string sName_oTarget = GetName(oTarget);
|
||||
int bFound = 0;
|
||||
|
||||
if(nObjectType == OBJECT_TYPE_ITEM)
|
||||
{
|
||||
oItem = oTarget;
|
||||
int nBase = GetBaseItemType(oItem);
|
||||
if(GetPRCSwitch(PRC_SPELLFIRE_DISALLOW_DRAIN_SCROLL_POTION) &&
|
||||
((nBase == BASE_ITEM_POTIONS) ||
|
||||
(nBase == BASE_ITEM_SCROLL) ||
|
||||
(nBase == BASE_ITEM_BLANK_POTION) ||
|
||||
(nBase == BASE_ITEM_BLANK_SCROLL)
|
||||
)
|
||||
)
|
||||
{
|
||||
sMessage_oPC = "Draining charges from scrolls and potions is not allowed";
|
||||
}
|
||||
else if(SpellfireDrainItem(oPC, oItem, bCharged))
|
||||
{
|
||||
bFound = 1;
|
||||
sMessage_oPC = "You drained " + sName_oTarget;
|
||||
}
|
||||
}
|
||||
else if(nObjectType == OBJECT_TYPE_CREATURE)
|
||||
{
|
||||
if(!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, 10, SAVING_THROW_TYPE_NONE, oPC))
|
||||
{
|
||||
//creature items exempt
|
||||
int nSlotMax = bExemptCreatureItems ? INVENTORY_SLOT_CWEAPON_L : NUM_INVENTORY_SLOTS;
|
||||
//int nCharges = 0;
|
||||
int i;
|
||||
for(i = 0; i < nSlotMax; i++)
|
||||
{
|
||||
oItem = GetItemInSlot(i, oTarget);
|
||||
if(SpellfireDrainItem(oPC, oItem, bCharged))
|
||||
{
|
||||
bFound = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
oItem = GetFirstItemInInventory(oTarget);
|
||||
if(bFound != 1)
|
||||
{
|
||||
while(GetIsObjectValid(oItem))
|
||||
{
|
||||
if(SpellfireDrainItem(oPC, oItem, bCharged))
|
||||
{
|
||||
bFound = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//search function
|
||||
if(bFound)
|
||||
{
|
||||
sMessage_oPC = "You drained " + GetName(oItem) + " from " + sName_oTarget;
|
||||
//sMessage_oTarget = sName_oPC + " drained " + GetName(oItem) " from you";
|
||||
}
|
||||
else
|
||||
{
|
||||
sMessage_oPC = "You tried to drain one of " + sName_oTarget + Name_s(sName_oTarget) + " items, but failed";
|
||||
sMessage_oTarget = sName_oPC + " tried to drain one of your items, but failed";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sMessage_oPC = sName_oTarget + " resisted your attempt to drain one of <his/her> items";
|
||||
sMessage_oTarget = "You resisted " + sName_oPC + Name_s(sName_oPC) + " attempt to drain one of your items";
|
||||
}
|
||||
}
|
||||
else if(DEBUG)
|
||||
DoDebug("SpellfireDrain(): Invalid target object", oPC);
|
||||
|
||||
if(bFound && !bCharged)
|
||||
{
|
||||
string s24 = " for 24 hours";
|
||||
sMessage_oPC += s24;
|
||||
sMessage_oTarget += s24;
|
||||
}
|
||||
|
||||
if(GetIsPC(oPC) && sMessage_oPC != "") SendMessageToPC(oPC, sMessage_oPC);
|
||||
if(GetIsPC(oTarget) && sMessage_oTarget != "") SendMessageToPC(oTarget, sMessage_oTarget);
|
||||
}
|
||||
|
||||
//Toggles a flag
|
||||
void SpellfireToggleAbsorbFriendly(object oPC)
|
||||
{
|
||||
if(GetLocalInt(oPC, "SpellfireAbsorbFriendly"))
|
||||
{
|
||||
DeleteLocalInt(oPC, "SpellfireAbsorbFriendly");
|
||||
FloatingTextStringOnCreature("*Absorb Friendly Spells Off*", oPC);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLocalInt(oPC, "SpellfireAbsorbFriendly", 1);
|
||||
FloatingTextStringOnCreature("*Absorb Friendly Spells On*", oPC);
|
||||
}
|
||||
}
|
||||
|
||||
//Charges items
|
||||
void SpellfireChargeItem(object oPC, object oItem)
|
||||
{
|
||||
int nObjectType = GetObjectType(oItem);
|
||||
if(nObjectType == OBJECT_TYPE_ITEM)
|
||||
{
|
||||
int nExpend = ExpendSpellfire(oPC);
|
||||
int nCharges = GetItemCharges(oItem);
|
||||
int nNewCharges = nExpend + nCharges;
|
||||
if(nNewCharges > 50)
|
||||
{
|
||||
AddSpellfireLevels(oPC, nNewCharges - 50);
|
||||
nNewCharges = 50;
|
||||
}
|
||||
SetItemCharges(oItem, nCharges + nExpend);
|
||||
//Assuming 50 is the maximum
|
||||
//refunding excess charges
|
||||
}
|
||||
else if(DEBUG)
|
||||
DoDebug("SpellfireChargeItem(): Invalid target object", oPC);
|
||||
}
|
||||
|
||||
//Applies Crown of Fire effects. Other effects are implemented
|
||||
//through heartbeat and onhit scripts
|
||||
void SpellfireCrown(object oPC)
|
||||
{
|
||||
if(GetLocalInt(oPC, "SpellfireCrown"))
|
||||
{
|
||||
DeleteLocalInt(oPC, "SpellfireCrown");
|
||||
PRCRemoveEffectsFromSpell(oPC, SPELL_SPELLFIRE_CROWN);
|
||||
FloatingTextStringOnCreature("*Crown of Fire Deactivated*", oPC);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetPersistantLocalInt(oPC, "SpellfireLevelStored") < 10)
|
||||
{
|
||||
SendMessageToPC(oPC, "You do not have enough stored spellfire levels");
|
||||
return;
|
||||
}
|
||||
SetLocalInt(oPC, "SpellfireCrown", 1);
|
||||
effect eDmgred = EffectDamageReduction(10, DAMAGE_POWER_PLUS_ONE);
|
||||
effect eResist = EffectSpellResistanceIncrease(32);
|
||||
effect eCrown = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_POSITIVE);
|
||||
effect eFlame = EffectVisualEffect(VFX_DUR_ELEMENTAL_SHIELD);
|
||||
effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20);
|
||||
effect eLink = EffectLinkEffects(eDmgred, eResist);
|
||||
eLink = EffectLinkEffects(eLink, eCrown);
|
||||
eLink = EffectLinkEffects(eLink, eFlame);
|
||||
eLink = EffectLinkEffects(eLink, eLight);
|
||||
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oPC);
|
||||
FloatingTextStringOnCreature("*Crown of Fire Activated*", oPC);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user