Post by FunkySwerve on Dec 22, 2006 7:36:40 GMT
Yup. Almost all our spells scale to 60. Not really within the scope of HGLL tech support, though - you should ask on the bioboards for scripting assitance. I'll post our version of flame weapon, but it's heavily modified to allow stacking with other onhit damage types, among other things. Short explanation - all onhit damage scripts run through the flame weapon onhit spell. One point of elemental damage of a certain type is added to inidicate the presence of a given onhit spell. Local ints indicate casterlevel of that spell.
Here's the flame weapon onhit spell script:
Again, this is pretty far from your run-of-the-mill flame weapon script, and may just confuse you. If you are more interested the general principle behind scaling spells up to level 60, it basically involves replacing certain bioware functions with your own, or adding in the calculations you want. You need to change the GetCasterLevel function, or add to it's result the number of legendary levels the caster has. Also, if you want legendary levels to affect penetration, you'll need a custom MyResistSpell function. I did this in HG by writing up custom functions, and putting them in an include. I then used a mass text editor (Notepad++) to open all the custom spell scripts, and insert the include under the copyrights for the various years, near the top of the scripts. I then did a find/replace for all the functions in those scripts I wanted to replace, replacing them with the custom functions from the include. If all that sounds fairly incolved, it was.
The most basic help I can offer is this: to get the caster's legendary levels, do this (taken from hgll_func_inc):
A level 50 character will have a lootable of 50, 41 a 41, and so on. If there are no legendary levels, the lootable will be under 41 (either 0 or 1, I forget), and the above function will return a 0. You can use this to get the casterlevel of the caster, and make changes to your spells accordingly, by adding the number of legendary levels to the standard casterlevel
HTH,
Funky
//::///////////////////////////////////////////////
//:: Flame Weapon
//:: X2_S0_FlmeWeap
//:: Copyright (c) 2001 Bioware Corp.
#include "fky_spells_inc"
//:://////////////////////////////////////////////
/*
Gives a melee weapon 1d4 fire damage +1 per caster
level to a maximum of +10.
*/
//:://////////////////////////////////////////////
//:: Created By: Andrew Nobbs
//:: Created On: Nov 29, 2002
//:://////////////////////////////////////////////
//:: Updated by Andrew Nobbs May 08, 2003
//:: 2003-07-07: Stacking Spell Pass, Georg Zoeller
//:: 2003-07-15: Complete Rewrite to make use of Item Property System
#include "nw_i0_spells"
#include "x2_i0_spells"
#include "x2_inc_spellhook"
#include "fky_pm_include"
void AddFlamingEffectToWeapon(object oTarget, float fDuration)
{
itemproperty bonusdamage = ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_FIRE,IP_CONST_DAMAGEBONUS_1);
// If the spell is cast again, any previous itemproperties matching are removed.
IPSafeAddItemProperty(oTarget, ItemPropertyOnHitCastSpell(124,1), fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oTarget, bonusdamage, fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
IPSafeAddItemProperty(oTarget, ItemPropertyVisualEffect(ITEM_VISUAL_FIRE), fDuration,X2_IP_ADDPROP_POLICY_REPLACE_EXISTING,FALSE,TRUE);
return;
}
void main()
{
/*
Spellcast Hook Code
Added 2003-07-07 by Georg Zoeller
If you want to make changes to all spells,
check x2_inc_spellhook.nss to find out more
*/
if (!X2PreSpellCastCode())
{
// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
return;
}
// End of Spell Cast Hook
//Declare major variables
effect eVis = EffectVisualEffect(VFX_IMP_PULSE_FIRE);
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
int nDuration = 2 * GetModCasterLevel(OBJECT_SELF);
int nMetaMagic = GetMetaMagicFeat();
//int nCasterLvl = GetModCasterLevel(OBJECT_SELF);
int nDam = GetModCasterLevel(OBJECT_SELF);
int nDama = nDam / 2;
//Limit nCasterLvl to 10, so it max out at +10 to the damage. - altered to max at 20
//if(nCasterLvl > 10)
//{
// nCasterLvl = 10;
//}
if(nDama > 20)
{
nDama = 20;
}
if (nMetaMagic == METAMAGIC_EXTEND)
{
nDuration = nDuration * 2; //Duration is +100%
}
object oMyWeapon = IPGetTargetedOrEquippedMeleeWeapon();
//added extra if statement to prevent casting on characters more than 6 levels below the caster's level
object oTarget = GetItemPossessor(oMyWeapon);
int nCaster = GetHitDice(OBJECT_SELF);
int nTarget = GetHitDice(oTarget);
int nDifference = nCaster - nTarget;
if (nDifference < 7 || GetIsPC(oTarget) == FALSE)
{
//end added scipt except the right bracket and else statement//////////
if(GetIsObjectValid(oMyWeapon) )
{
SignalEvent(GetItemPossessor(oMyWeapon), EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));
if (nDuration>0)
{
// haaaack: store caster level on item for the on hit spell to work properly
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, GetItemPossessor(oMyWeapon));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, GetItemPossessor(oMyWeapon), TurnsToSeconds(nDuration));
SetLocalInt(oMyWeapon, "FlameWeaponFire", nDama);
AddFlamingEffectToWeapon(oMyWeapon, TurnsToSeconds(nDuration));
}
return;
}
else
{
FloatingTextStrRefOnCreature(83615, OBJECT_SELF);
return;
}
//added rightbracket and else statement follow
}
else
{
FloatingTextStringOnCreature("You cannot cast flame weapon on a player more than 6 levels below your level.", OBJECT_SELF);
return;
}
}
Here's the flame weapon onhit spell script:
//::///////////////////////////////////////////////
//:: OnHit Firedamage
//:: x2_s3_flamgind
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
OnHit Castspell Fire Damage property for the
flaming weapon spell (x2_s0_flmeweap).
We need to use this property because we can not
add random elemental damage to a weapon in any
other way and implementation should be as close
as possible to the book.
*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-07-17
//:://////////////////////////////////////////////
#include "X0_I0_SPELLS"
void main()
{
//infogather
//object oPC = GetFirstPC();
//AssignCommand(oPC, SpeakString("GetSpellCastItem Name: " + GetName(GetSpellCastItem())));
//AssignCommand(oPC, SpeakString("OBJECT_SELF Name: " + GetName(OBJECT_SELF)));
//AssignCommand(oPC, SpeakString("GetSpellTargetObject Name: " + GetName(GetSpellTargetObject())));
//end infogather
// Get Caster Level
//int nLevel = GetCasterLevel(OBJECT_SELF);
// Assume minimum caster level if variable is not found
//if (nLevel== 0)
//{
// nLevel =1;
//}
int nAssAcid = FALSE;
int nFWFire = FALSE;
int WWSlash = FALSE;
int BGDeath = FALSE;
int nDarkFire = FALSE;
int nDeafClang = FALSE;
int nStaffMast = FALSE;
int nHolySword = FALSE;
int nDmg;
effect eDmg;
effect eVis;
object oWeapon = GetSpellCastItem();
object oTarget = GetSpellTargetObject();
int nValidTarget = GetIsObjectValid(oTarget);
itemproperty ipCheck = GetFirstItemProperty(oWeapon);
while (GetIsItemPropertyValid(ipCheck))
{
if (GetItemPropertyDurationType(ipCheck) == DURATION_TYPE_TEMPORARY)
{
if (GetItemPropertyType(ipCheck) == ITEM_PROPERTY_DAMAGE_BONUS)
{
if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_ACID) nAssAcid = TRUE;
else if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_FIRE) nFWFire = TRUE;
else if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_SLASHING) WWSlash = TRUE;
else if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_COLD) BGDeath = TRUE;
else if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_ELECTRICAL) nDarkFire = TRUE;
else if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_SONIC) nDeafClang = TRUE;
else if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_BLUDGEONING) nStaffMast = TRUE;
else if (GetItemPropertySubType(ipCheck) == IP_CONST_DAMAGETYPE_PIERCING) nHolySword = TRUE;
}
}
ipCheck = GetNextItemProperty(oWeapon);
}
if (nFWFire)
{
nDmg = d4() + GetLocalInt(oWeapon, "FlameWeaponFire");
eDmg = EffectDamage(nDmg,DAMAGE_TYPE_FIRE);
if (nValidTarget) ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
if (nDmg<10) // if we are doing below 10 point of damage, use small vfx
{
eVis =EffectVisualEffect(VFX_IMP_FLAME_S);
}
else
{
eVis =EffectVisualEffect(VFX_IMP_FLAME_M);
}
}
if (nDarkFire)
{
nDmg = d6() + GetLocalInt(oWeapon, "DarkFire");
eDmg = EffectDamage(nDmg,DAMAGE_TYPE_FIRE);
if (nValidTarget) ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
if (nDmg<10) // if we are doing below 10 point of damage, use small vfx
{
eVis =EffectVisualEffect(VFX_IMP_FLAME_S);
}
else
{
eVis =EffectVisualEffect(VFX_IMP_FLAME_M);
}
}
if (nDeafClang)
{
nDmg = d4() + GetLocalInt(oWeapon, "DeafClang");
eDmg = EffectDamage(nDmg,DAMAGE_TYPE_SONIC);
if (nValidTarget) ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
eVis =EffectVisualEffect(VFX_IMP_SONIC);
}
if (WWSlash)
{
nDmg = d4() + GetLocalInt(oWeapon, "WWSlash");
eDmg = EffectDamage(nDmg,DAMAGE_TYPE_SLASHING);
if (nValidTarget) ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
if (nDmg<10) // if we are doing below 10 point of damage, use small vfx
{
eVis =EffectVisualEffect(VFX_COM_BLOOD_SPARK_MEDIUM);
}
else
{
eVis =EffectVisualEffect(VFX_COM_BLOOD_SPARK_LARGE);
}
}
if (nAssAcid)
{
nDmg = d4() + GetLocalInt(oWeapon, "AssassinAcid");
eDmg = EffectDamage(nDmg,DAMAGE_TYPE_ACID);
if (nValidTarget) ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
if (nDmg<10) // if we are doing below 10 point of damage, use small vfx
{
eVis =EffectVisualEffect(VFX_IMP_ACID_S);
}
else
{
eVis =EffectVisualEffect(VFX_IMP_ACID_L);
}
}
if (BGDeath)
{
nDmg = d4() + GetLocalInt(oWeapon, "BGDeathKiss");
eDmg = EffectDamage(nDmg,DAMAGE_TYPE_COLD);
if (nValidTarget) ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
eVis =EffectVisualEffect(VFX_COM_HIT_FROST);
}
if (nStaffMast)
{
nDmg = d6() + GetLocalInt(oWeapon, "SMAmount");
eDmg = EffectDamage(nDmg, GetLocalInt(oWeapon, "SMType"));
if (nValidTarget) ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
eVis =EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY);
}
if(nHolySword)
{
if (nValidTarget && (GetAlignmentGoodEvil(oTarget) == ALIGNMENT_EVIL))
{
int nPallyLev = GetLevelByClass(CLASS_TYPE_PALADIN);
if (nPallyLev > 0)
{
nDmg = d6(2);
eDmg = EffectDamage(nDmg, DAMAGE_TYPE_DIVINE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oTarget);
object oRRing = GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oTarget);//added check to allow for antimords ring
object oLRing = GetItemInSlot(INVENTORY_SLOT_LEFTRING,oTarget);
if(GetTag(oRRing) != "rtygantimordsrin" &&
GetTag(oLRing) != "rtygantimordsrin")
{
spellsDispelMagic(oTarget, nPallyLev, EffectVisualEffect(VFX_IMP_BREACH), EffectVisualEffect(VFX_FNF_DISPEL));
}
}
}
}
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
}
Again, this is pretty far from your run-of-the-mill flame weapon script, and may just confuse you. If you are more interested the general principle behind scaling spells up to level 60, it basically involves replacing certain bioware functions with your own, or adding in the calculations you want. You need to change the GetCasterLevel function, or add to it's result the number of legendary levels the caster has. Also, if you want legendary levels to affect penetration, you'll need a custom MyResistSpell function. I did this in HG by writing up custom functions, and putting them in an include. I then used a mass text editor (Notepad++) to open all the custom spell scripts, and insert the include under the copyrights for the various years, near the top of the scripts. I then did a find/replace for all the functions in those scripts I wanted to replace, replacing them with the custom functions from the include. If all that sounds fairly incolved, it was.
The most basic help I can offer is this: to get the caster's legendary levels, do this (taken from hgll_func_inc):
int GetLL(object oChar = OBJECT_SELF)
{
int nLoot = GetLootable(oChar) - 40;
if (nLoot < 0) nLoot = 0;
return nLoot;
}
A level 50 character will have a lootable of 50, 41 a 41, and so on. If there are no legendary levels, the lootable will be under 41 (either 0 or 1, I forget), and the above function will return a 0. You can use this to get the casterlevel of the caster, and make changes to your spells accordingly, by adding the number of legendary levels to the standard casterlevel
HTH,
Funky