And last, hgs_gen_posneg itself - sorry for all the split posts.
#include "hg_inc"
#include "ac_spell_inc"
const int ENERGY_RANK_HARM = -6;
const int ENERGY_RANK_INF_CRIT = -5;
const int ENERGY_RANK_INF_SER = -4;
const int ENERGY_RANK_INF_MOD = -3;
const int ENERGY_RANK_INF_LIGHT = -2;
const int ENERGY_RANK_INF_MINOR = -1;
const int ENERGY_RANK_INVALID = 0;
const int ENERGY_RANK_CURE_MINOR = 1;
const int ENERGY_RANK_CURE_LIGHT = 2;
const int ENERGY_RANK_CURE_MOD = 3;
const int ENERGY_RANK_CURE_SER = 4;
const int ENERGY_RANK_CURE_CRIT = 5;
const int ENERGY_RANK_HEAL = 6;
void ApplyEnergyVisual (object oTarget, int nRank, int nClass, float fDelay) {
int nVis = -1, nSnd = -1;
if (GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD) {
switch (nRank) {
case ENERGY_RANK_HARM: nVis = CEPVFX_IMP_HARM_YELLOW; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_CRIT: nVis = VFX_IMP_SUNSTRIKE; nSnd = -1; break;
case ENERGY_RANK_INF_SER: nVis = VFX_IMP_SUNSTRIKE; nSnd = -1; break;
case ENERGY_RANK_INF_MOD: nVis = VFX_IMP_SUNSTRIKE; nSnd = -1; break;
case ENERGY_RANK_INF_LIGHT: nVis = VFX_IMP_SUNSTRIKE; nSnd = -1; break;
case ENERGY_RANK_INF_MINOR: nVis = VFX_IMP_SUNSTRIKE; nSnd = -1; break;
case ENERGY_RANK_CURE_MINOR: nVis = CEPVFX_IMP_HEALING_S_ORANGE; nSnd = CEPSFX_IMP_HEALING_S; break;
case ENERGY_RANK_CURE_LIGHT: nVis = CEPVFX_IMP_HEALING_S_ORANGE; nSnd = CEPSFX_IMP_HEALING_S; break;
case ENERGY_RANK_CURE_MOD: nVis = CEPVFX_IMP_HEALING_M_ORANGE; nSnd = CEPSFX_IMP_HEALING_M; break;
case ENERGY_RANK_CURE_SER: nVis = CEPVFX_IMP_HEALING_L_ORANGE; nSnd = CEPSFX_IMP_HEALING_L; break;
case ENERGY_RANK_CURE_CRIT: nVis = CEPVFX_IMP_HEALING_G_ORANGE; nSnd = CEPSFX_IMP_HEALING_G; break;
case ENERGY_RANK_HEAL: nVis = PRCVFX_IMP_HEALING_X_UNDEAD; nSnd = -1; break;
default: return;
}
} else if (GetRacialType(oTarget) == RACIAL_TYPE_CONSTRUCT) {
switch (nRank) {
case ENERGY_RANK_HARM: nVis = VFX_IMP_HARM; nSnd = -1; break;
case ENERGY_RANK_INF_CRIT: nVis = PRCVFX_IMP_INFLICT_G; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_SER: nVis = PRCVFX_IMP_INFLICT_L; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MOD: nVis = PRCVFX_IMP_INFLICT_M; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_LIGHT: nVis = PRCVFX_IMP_INFLICT_S; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MINOR: nVis = VFX_IMP_HEAD_EVIL; nSnd = -1; break;
case ENERGY_RANK_CURE_MINOR: nVis = CEPVFX_IMP_HEALING_S_PURPLE; nSnd = CEPSFX_IMP_HEALING_S; break;
case ENERGY_RANK_CURE_LIGHT: nVis = CEPVFX_IMP_HEALING_S_PURPLE; nSnd = CEPSFX_IMP_HEALING_S; break;
case ENERGY_RANK_CURE_MOD: nVis = CEPVFX_IMP_HEALING_M_PURPLE; nSnd = CEPSFX_IMP_HEALING_M; break;
case ENERGY_RANK_CURE_SER: nVis = CEPVFX_IMP_HEALING_L_PURPLE; nSnd = CEPSFX_IMP_HEALING_L; break;
case ENERGY_RANK_CURE_CRIT: nVis = CEPVFX_IMP_HEALING_G_PURPLE; nSnd = CEPSFX_IMP_HEALING_G; break;
case ENERGY_RANK_HEAL: nVis = CEPVFX_IMP_HEALING_X_PURPLE; nSnd = CEPSFX_IMP_HEALING_X; break;
default: return;
}
} else if (GetRacialType(oTarget) == RACIAL_TYPE_PLANT || nClass == CLASS_TYPE_DRUID) {
switch (nRank) {
case ENERGY_RANK_HARM: nVis = CEPVFX_IMP_HARM_ORANGE; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_CRIT: nVis = PRCVFX_IMP_INFLICT_G; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_SER: nVis = PRCVFX_IMP_INFLICT_L; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MOD: nVis = PRCVFX_IMP_INFLICT_M; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_LIGHT: nVis = PRCVFX_IMP_INFLICT_S; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MINOR: nVis = VFX_IMP_HEAD_EVIL; nSnd = -1; break;
case ENERGY_RANK_CURE_MINOR: nVis = VFX_IMP_HEAD_HEAL; nSnd = -1; break;
case ENERGY_RANK_CURE_LIGHT: nVis = CEPVFX_IMP_HEALING_S_GREEN; nSnd = CEPSFX_IMP_HEALING_S; break;
case ENERGY_RANK_CURE_MOD: nVis = CEPVFX_IMP_HEALING_M_GREEN; nSnd = CEPSFX_IMP_HEALING_M; break;
case ENERGY_RANK_CURE_SER: nVis = CEPVFX_IMP_HEALING_L_GREEN; nSnd = CEPSFX_IMP_HEALING_L; break;
case ENERGY_RANK_CURE_CRIT: nVis = CEPVFX_IMP_HEALING_G_GREEN; nSnd = CEPSFX_IMP_HEALING_G; break;
case ENERGY_RANK_HEAL: nVis = CEPVFX_IMP_HEALING_X_GREEN; nSnd = CEPSFX_IMP_HEALING_X; break;
default: return;
}
} else if (nClass == CLASS_TYPE_CLERIC) {
switch (nRank) {
case ENERGY_RANK_HARM: nVis = VFX_IMP_HARM; nSnd = -1; break;
case ENERGY_RANK_INF_CRIT: nVis = PRCVFX_IMP_INFLICT_G; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_SER: nVis = PRCVFX_IMP_INFLICT_L; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MOD: nVis = PRCVFX_IMP_INFLICT_M; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_LIGHT: nVis = PRCVFX_IMP_INFLICT_S; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MINOR: nVis = VFX_IMP_HEAD_EVIL; nSnd = -1; break;
case ENERGY_RANK_CURE_MINOR: nVis = VFX_IMP_HEAD_HEAL; nSnd = -1; break;
case ENERGY_RANK_CURE_LIGHT: nVis = CEPVFX_IMP_HEALING_S_BLUE; nSnd = CEPSFX_IMP_HEALING_S; break;
case ENERGY_RANK_CURE_MOD: nVis = CEPVFX_IMP_HEALING_M_BLUE; nSnd = CEPSFX_IMP_HEALING_M; break;
case ENERGY_RANK_CURE_SER: nVis = CEPVFX_IMP_HEALING_L_BLUE; nSnd = CEPSFX_IMP_HEALING_L; break;
case ENERGY_RANK_CURE_CRIT: nVis = CEPVFX_IMP_HEALING_G_BLUE; nSnd = CEPSFX_IMP_HEALING_G; break;
case ENERGY_RANK_HEAL: nVis = CEPVFX_IMP_HEALING_X_BLUE; nSnd = CEPSFX_IMP_HEALING_X; break;
default: return;
}
} else if (nClass == CLASS_TYPE_BARD) {
switch (nRank) {
case ENERGY_RANK_HARM: nVis = VFX_IMP_HARM; nSnd = -1; break;
case ENERGY_RANK_INF_CRIT: nVis = PRCVFX_IMP_INFLICT_G; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_SER: nVis = PRCVFX_IMP_INFLICT_L; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MOD: nVis = PRCVFX_IMP_INFLICT_M; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_LIGHT: nVis = PRCVFX_IMP_INFLICT_S; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MINOR: nVis = VFX_IMP_HEAD_EVIL; nSnd = -1; break;
case ENERGY_RANK_CURE_MINOR: nVis = VFX_IMP_HEAD_HEAL; nSnd = -1; break;
case ENERGY_RANK_CURE_LIGHT: nVis = CEPVFX_IMP_HEALING_S_CYAN; nSnd = CEPSFX_IMP_HEALING_S; break;
case ENERGY_RANK_CURE_MOD: nVis = CEPVFX_IMP_HEALING_M_CYAN; nSnd = CEPSFX_IMP_HEALING_M; break;
case ENERGY_RANK_CURE_SER: nVis = CEPVFX_IMP_HEALING_L_CYAN; nSnd = CEPSFX_IMP_HEALING_L; break;
case ENERGY_RANK_CURE_CRIT: nVis = CEPVFX_IMP_HEALING_G_CYAN; nSnd = CEPSFX_IMP_HEALING_G; break;
case ENERGY_RANK_HEAL: nVis = CEPVFX_IMP_HEALING_X_CYAN; nSnd = CEPSFX_IMP_HEALING_X; break;
default: return;
}
} else {
switch (nRank) {
case ENERGY_RANK_HARM: nVis = VFX_IMP_HARM; nSnd = -1; break;
case ENERGY_RANK_INF_CRIT: nVis = PRCVFX_IMP_INFLICT_G; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_SER: nVis = PRCVFX_IMP_INFLICT_L; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MOD: nVis = PRCVFX_IMP_INFLICT_M; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_LIGHT: nVis = PRCVFX_IMP_INFLICT_S; nSnd = CEPSFX_IMP_HARM; break;
case ENERGY_RANK_INF_MINOR: nVis = VFX_IMP_HEAD_EVIL; nSnd = -1; break;
case ENERGY_RANK_CURE_MINOR: nVis = VFX_IMP_HEAD_HEAL; nSnd = -1; break;
case ENERGY_RANK_CURE_LIGHT: nVis = VFX_IMP_HEALING_S; nSnd = -1; break;
case ENERGY_RANK_CURE_MOD: nVis = VFX_IMP_HEALING_M; nSnd = -1; break;
case ENERGY_RANK_CURE_SER: nVis = VFX_IMP_HEALING_L; nSnd = -1; break;
case ENERGY_RANK_CURE_CRIT: nVis = VFX_IMP_HEALING_G; nSnd = -1; break;
case ENERGY_RANK_HEAL: nVis = VFX_IMP_HEALING_X; nSnd = -1; break;
default: return;
}
}
if (nSnd >= 0)
DelayCommand(fDelay, ApplyVisualToObject(nSnd, oTarget));
DelayCommand(fDelay, ApplyVisualToObject(nVis, oTarget));
}
void main() {
struct SpellInfo si = GetSpellInfo();
if (si.id < 0)
return;
if (GetLocalInt(si.item, "Unlimited") > 0 &&
GetLocalInt(si.item, "Unlimited") == GetBaseItemType(si.item)) {
string sSourceTag = GetLocalString(si.item, "UnlimitedSourceTag");
if (sSourceTag != "" && !GetIsObjectValid(GetItemPossessedBy(si.caster, sSourceTag))) {
SetPlotFlag(si.item, FALSE);
DestroyObject(si.item);
} else
SetItemStackSize(si.item, 99);
if (GetLocalInt(si.item, "UnlimitedSelfOnly") && si.target != si.caster) {
FloatingTextStringOnCreature("You can only use this item on yourself!", si.caster, FALSE);
return;
}
SetItemCursedFlag(si.item, TRUE);
}
int nHeal = GetSkillRank(SKILL_HEAL, OBJECT_SELF);
if (nHeal < 4)
nHeal = 4;
else if (GetIsObjectValid(si.item) && nHeal > 20 && (nHeal > si.clevel * 2))
nHeal = si.clevel * 2;
int nDice = 0, nBonus = 0, nSides = 8, nRank = 0, nFocus = GetCasterSpellFocus(si.school);
int nAmount, nRace, nHealRace = -1, nHarmRace = -1, nSaveType = -1, nDamType = DAMAGE_TYPE_POSITIVE;
float fDelay, fRadius = 0.0;
switch (si.id) {
case SPELLABILITY_BG_INFLICT_SERIOUS_WOUNDS:
FloatingTextStringOnCreature("Please use the Flame Weapon spell from your Blackguard spellbook.", si.caster, FALSE);
return;
case SPELLABILITY_BG_INFLICT_CRITICAL_WOUNDS:
FloatingTextStringOnCreature("Please use the Bestow Curse spell from your Blackguard spellbook.", si.caster, FALSE);
return;
case SPELL_CURE_MINOR_WOUNDS:
nRank = ENERGY_RANK_CURE_MINOR;
nDice = 1;
nSides = 1;
nBonus = nHeal - 1;
si.id = SPELL_CURE_MINOR_WOUNDS;
break;
case HGSPELL_MASS_CURE_LIGHT_WOUNDS:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_CURE_LIGHT_WOUNDS:
nRank = ENERGY_RANK_CURE_LIGHT;
nDice = nHeal / 4;
nBonus = (si.clevel > 5 ? 5 : si.clevel);
si.id = SPELL_CURE_LIGHT_WOUNDS;
break;
case SPELL_HEALING_CIRCLE:
case HGSPELL_MASS_CURE_MODERATE_WOUNDS:
fRadius = (si.id == SPELL_HEALING_CIRCLE ? RADIUS_SIZE_LARGE : RADIUS_SIZE_MEDIUM);
case SPELL_CURE_MODERATE_WOUNDS:
nRank = ENERGY_RANK_CURE_MOD;
nDice = nHeal / 2;
nBonus = (si.clevel > 10 ? 10 : si.clevel);
si.id = SPELL_CURE_MODERATE_WOUNDS;
break;
case HGSPELL_MASS_CURE_SERIOUS_WOUNDS:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_CURE_SERIOUS_WOUNDS:
nRank = ENERGY_RANK_CURE_SER;
nDice = (nHeal * 3) / 4;
nBonus = (si.clevel > 15 ? 15 : si.clevel);
si.id = SPELL_CURE_SERIOUS_WOUNDS;
if (GetLocalInt(si.caster, "HER_PICKUP")) {
if (!GetIsDead(si.target)) {
effect eEff;
int nRemoved = 0;
for (eEff = GetFirstEffect(si.target); GetIsEffectValid(eEff); eEff = GetNextEffect(si.target)) {
if (GetEffectTrueType(eEff) == EFFECT_TRUETYPE_KNOCKDOWN) {
nRemoved++;
RemoveEffect(si.target, eEff);
}
}
if (nRemoved > 0) {
effect eImmob = ExtraordinaryEffect(EffectCutsceneImmobilize());
eImmob = EffectLinkEffects(eImmob, EffectVisualEffect(PRCVFX_DUR_AIR1));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eImmob, si.target, 2.0);
}
}
DeleteLocalInt(si.caster, "HER_PICKUP");
return;
}
break;
case HGSPELL_MASS_CURE_CRITICAL_WOUNDS:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_CURE_CRITICAL_WOUNDS:
nRank = ENERGY_RANK_CURE_CRIT;
nDice = nHeal;
nBonus = (si.clevel > 20 ? 20 : si.clevel);
si.id = SPELL_CURE_CRITICAL_WOUNDS;
break;
case SPELL_MASS_HEAL:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_HEAL:
nRank = ENERGY_RANK_HEAL;
si.id = SPELL_HEAL;
if (GetLocalInt(GetArea(si.caster), "SkillBasedHeal")) {
nDice = nHeal * 2;
nBonus = 200;
} else
nDice = -1;
break;
case SPELL_INFLICT_MINOR_WOUNDS:
nRank = ENERGY_RANK_CURE_MINOR;
nDice = 1;
nSides = 1;
nBonus = nHeal - 1;
nDamType = DAMAGE_TYPE_NEGATIVE;
si.id = SPELL_INFLICT_MINOR_WOUNDS;
break;
case HGSPELL_MASS_INFLICT_LIGHT_WOUNDS:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_INFLICT_LIGHT_WOUNDS:
nRank = ENERGY_RANK_CURE_LIGHT;
nDice = nHeal / 4;
nBonus = (si.clevel > 5 ? 5 : si.clevel);
nDamType = DAMAGE_TYPE_NEGATIVE;
si.id = SPELL_INFLICT_LIGHT_WOUNDS;
break;
case HGSPELL_MASS_INFLICT_MODERATE_WOUNDS:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_INFLICT_MODERATE_WOUNDS:
nRank = ENERGY_RANK_CURE_MOD;
nDice = nHeal / 2;
nBonus = (si.clevel > 10 ? 10 : si.clevel);
nDamType = DAMAGE_TYPE_NEGATIVE;
si.id = SPELL_INFLICT_MODERATE_WOUNDS;
break;
case HGSPELL_MASS_INFLICT_SERIOUS_WOUNDS:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_INFLICT_SERIOUS_WOUNDS:
nRank = ENERGY_RANK_CURE_SER;
nDice = (nHeal * 3) / 4;
nBonus = (si.clevel > 15 ? 15 : si.clevel);
nDamType = DAMAGE_TYPE_NEGATIVE;
si.id = SPELL_INFLICT_SERIOUS_WOUNDS;
break;
case HGSPELL_MASS_INFLICT_CRITICAL_WOUNDS:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_INFLICT_CRITICAL_WOUNDS:
nRank = ENERGY_RANK_CURE_CRIT;
nDice = nHeal;
nBonus = (si.clevel > 20 ? 20 : si.clevel);
nDamType = DAMAGE_TYPE_NEGATIVE;
si.id = SPELL_INFLICT_CRITICAL_WOUNDS;
break;
case HGSPELL_MASS_HARM:
fRadius = RADIUS_SIZE_MEDIUM;
case SPELL_HARM:
case 759: /* Undead Self Harm */
nRank = ENERGY_RANK_HEAL;
nDamType = DAMAGE_TYPE_NEGATIVE;
si.id = SPELL_HARM;
if (GetLocalInt(GetArea(si.caster), "SkillBasedHeal")) {
nDice = nHeal * 2;
nBonus = 200;
} else
nDice = -1;
break;
default:
FloatingTextStringOnCreature("An invalid pos/neg spell #" + IntToString(si.id) + " was cast. Please inform a DM.", si.caster);
return;
}
if (nHealRace < 0 && nHarmRace < 0 && nSaveType < 0) {
if (nDamType == DAMAGE_TYPE_POSITIVE) {
nHealRace = RACIAL_TYPE_ALL;
nHarmRace = RACIAL_TYPE_UNDEAD;
nSaveType = SAVING_THROW_TYPE_POSITIVE;
} else {
nHealRace = RACIAL_TYPE_UNDEAD;
nHarmRace = RACIAL_TYPE_ALL;
nSaveType = SAVING_THROW_TYPE_NEGATIVE;
}
}
if (si.class == CLASS_TYPE_CLERIC && nHealRace == RACIAL_TYPE_ALL && GetHasFeat(FEAT_HEALING_DOMAIN_POWER, si.caster))
nDice = (nDice * 3) / 2;
if (!GetIsObjectValid(si.item) && si.class == CLASS_TYPE_CLERIC && nFocus > 1)
nFocus = (nFocus - 1) * 2;
else
nFocus = 0;
if (fRadius > 0.0) {
if (si.id == SPELL_HEALING_CIRCLE)
ApplyVisualAtLocation(VFX_FNF_LOS_HOLY_20, si.loc);
else if (nDamType == DAMAGE_TYPE_NEGATIVE)
ApplyVisualAtLocation(VFX_FNF_LOS_EVIL_10, si.loc);
else if (si.class == CLASS_TYPE_DRUID)
ApplyVisualAtLocation(HGVFX_FNF_LOS_GREEN_10, si.loc);
else
ApplyVisualAtLocation(VFX_FNF_LOS_HOLY_10, si.loc);
si.target = GetFirstObjectInShape(SHAPE_SPHERE, fRadius, si.loc, TRUE);
}
while (GetIsObjectValid(si.target)) {
nRace = GetRacialType(si.target);
fDelay = GetSpellEffectDelay(si.loc, si.target);
if (nRace == RACIAL_TYPE_UNDEAD && GetLocalInt(si.target, "HealType") == DAMAGE_TYPE_POSITIVE)
nRace = RACIAL_TYPE_HUMAN;
if (GetIsSpellTarget(si, si.target, TARGET_TYPE_ALLY) || nRace == nHealRace || GetLocalInt(si.target, "AllowHeal")) {
if (GetSpellBuffLevel(si, si.target) > 0) {
if (nRace != nHarmRace &&
(nHealRace == RACIAL_TYPE_ALL || nRace == nHealRace) &&
!GetIsQuasiclass(QUASICLASS_ACCURSED_PARIAH, si.target)) {
SignalEvent(si.target, EventSpellCastAt(si.caster, si.id, FALSE));
if (nDice < 0) {
if (GetLocalInt(si.target, "SkillBasedHeal"))
nAmount = MetaPower(si, GetSkillRank(SKILL_HEAL, si.caster) * 2, 8, 200);
else
nAmount = GetMaxHitPoints(si.target);
} else if (nSides > 1) {
if (si.clevel > 40)
nAmount = MetaPower(si, nDice, nSides + 4, nBonus);
else if (si.clevel > 20)
nAmount = MetaPower(si, nDice, nSides + 2, nBonus);
else
nAmount = MetaPower(si, nDice, nSides, nBonus);
} else
nAmount = MetaPower(si, nDice, nSides, nBonus);
effect eHeal = EffectHeal(nAmount);
ApplyEnergyVisual(si.target, nRank, si.class, fDelay);
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, si.target));
}
/* Heal can heal persistent wounds at CL41+ */
if (si.id == SPELL_HEAL) {
if (GetLocalInt(si.target, "PersistentWound")) {
if (si.clevel > 40) {
DeleteLocalInt(si.target, "PersistentWound");
RemoveEffectsFromSpell(HGEFFECT_PERSISTENT_WOUND, si.target);
FloatingTextStringOnCreature("Your wound closes!", si.target, FALSE);
} else
FloatingTextStringOnCreature("The Heal spell was too weak to close the wound!", si.target, FALSE);
}
}
}
} else if (nRace == nHarmRace || nHarmRace == RACIAL_TYPE_ALL) {
int bTouch;
if (fRadius > 0.0) {
si.dc += nFocus;
bTouch = !GetSpellSaved(si, SAVING_THROW_REFLEX, si.target, nSaveType, fDelay);
si.dc -= nFocus;
} else
bTouch = TouchAttackMelee(si.target);
SignalEvent(si.target, EventSpellCastAt(si.caster, si.id));
if (bTouch > 0 && !GetSpellResisted(si, si.target, fDelay)) {
if (nDice >= 0) {
nAmount = MetaPower(si, nDice, nSides, nBonus);
if (bTouch == 2)
nAmount *= 2;
if (GetSpellSaved(si, SAVING_THROW_WILL, si.target, nSaveType, fDelay))
nAmount /= 2;
} else if (GetObjectType(si.target) == OBJECT_TYPE_CREATURE) {
if (GetLocalInt(si.target, "SkillBasedHarm"))
nAmount = MetaPower(si, GetSkillRank(SKILL_HEAL, si.caster) * 2, 8, 200);
else
nAmount = GetCurrentHitPoints(si.target) - d4();
} else
nAmount = 0;
if (nAmount > 0) {
effect eDam = EffectDamage(nAmount, nDamType);
if (GetIsPC(si.caster))
MinLocalInt(si.target, "AttackerLevel", GetHitDiceIncludingLLs(si.caster));
ApplyEnergyVisual(si.target, -nRank, si.class, fDelay);
DelayCommand(fDelay + 1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, si.target));
}
}
}
if (fRadius > 0.0)
si.target = GetNextObjectInShape(SHAPE_SPHERE, fRadius, si.loc, TRUE);
else
si.target = OBJECT_INVALID;
}
}
LMK if you have questions.
Funky