I've been bouncing around between projects on my mod lately, fleshing out the rumour system I use being one project on the go, the other being a change in the spell data collection routine I use, switching to a struct based retrieval system.
Obviously, I'm not the first to go about this method for it, but after setting it up and starting to switch over the spell scripts to take advantage of it, I really can't see why Bioware didn't impliment spell data and combat data structs for easy retrieval to begin with. It's so much easier coding spells when you have everything you need handy in one function call, and saves having to assign the same few common variables each and every time.
The bitwize GetMetaMagic(); with item level override routine I'd posted before became part of it, as did a wrapper routine for item caster level override allowance.
The spell script changes are taking a bit, but it lets me clean up the code more as I convert them to use this system.
These are the components to it: (Spell school is the only part I added that I'm still not entirely sure was necessary, but a cached 2da read is near instant anyways so it's not really an issue efficiency wise.)
//// MetaMagic check that filters out the item exploit.
int FB_GetMetaMagicFeat();
int FB_GetMetaMagicFeat()
{
object oItem = GetSpellCastItem();
if (GetIsObjectValid (oItem))
{
return GetLocalInt (oItem, "FB_ITEM_METAMAGIC_FEAT");
}
int nMetaMagic = GetMetaMagicFeat();
// add only if not already present.
if (GetHasFeat (FEAT_DEITY_AUTOMATIC_EMPOWER)) nMetaMagic |= METAMAGIC_EMPOWER;
if (GetHasFeat (FEAT_DEITY_AUTOMATIC_EXTEND)) nMetaMagic |= METAMAGIC_EXTEND;
if (GetHasFeat (FEAT_DEITY_AUTOMATIC_MAXIMIZE)) nMetaMagic |= METAMAGIC_MAXIMIZE;
return nMetaMagic;
}
//// Spell caster level check to allow spell level to be set on items.
int FB_GetCasterLevel (object oCaster = OBJECT_SELF);
int FB_GetCasterLevel (object oCaster = OBJECT_SELF)
{
object oItem = GetSpellCastItem();
int nLevel;
if (GetIsObjectValid (oItem))
{
nLevel = GetLocalInt (oItem, "FB_ITEM_SPELL_LEVEL");
}
if (nLevel) return nLevel;
else return GetCasterLevel (oCaster);
}
And the main routine:
//// Spell stats
struct FB_SpellData {int Spell;
int Casterclass;
int CasterLevel;
int SpellLevel;
int MetaMagic;
int DC;
string SpellSchool;
object oTarget;
location lTarget;};
//// Based on: struct SpellData {int Spell;
//// int Casterclass;
//// int CasterLevel;
//// int SpellLevel;
//// int MetaMagic;
//// int DC
//// string SpellSchool;};
//// object oTarget;
//// location lTarget;};
struct FB_SpellData FB_GetSpellData (object oCaster = OBJECT_SELF);
//// (6/10/2012) Failed Bard.
struct FB_SpellData FB_GetSpellData (object oCaster = OBJECT_SELF)
{
struct FB_SpellData SpellData;
object oItem = GetSpellCastItem();
// Spell ID - The row number in spells.2da
SpellData.Spell = GetSpellId();
// Caster class, used internally for determining spell cast level.
SpellData.Casterclass = GetLastSpellCastclass();
// Caster level with item level override check.
SpellData.CasterLevel = FB_GetCasterLevel (OBJECT_SELF);
// Spell Saving Throw DC
SpellData.DC = GetSpellSaveDC();
// Spell level, determined based on caster class and a 2da read.
string sclass;
switch (SpellData.Casterclass)
{
case class_TYPE_BARD: sclass = "Bard"; break;
case class_TYPE_CLERIC: sclass = "Cleric"; break;
case class_TYPE_DRUID: sclass = "Druid"; break;
case class_TYPE_PALADIN: sclass = "Paladin"; break;
case class_TYPE_RANGER: sclass = "Ranger"; break;
// these two share one.
case class_TYPE_SORCERER:
case class_TYPE_WIZARD: sclass = "Wiz_Sorc"; break;
default: sclass = "Innate";
}
SpellData.SpellLevel = StringToInt (Get2DAString ("spells", sclass, SpellData.Spell));
// Expanded metamagic check with item exploit fix and allowance for automatic
// versions of maximized, empowered, and extended feats.
SpellData.MetaMagic = FB_GetMetaMagicFeat();
// Spell school, determined based on 2da read
SpellData.SpellSchool = Get2DAString ("spells", "School", SpellData.Spell);
// Standard target object and location.
SpellData.oTarget = GetSpellTargetObject();
SpellData.lTarget = GetSpellTargetLocation();
return SpellData;
}
It's unfortunate that all the "class" mentions are messed up by the formatting here.
Anyways, is there any commonly accessed spell information that I missed? It's easy enough to add into a struct (though much harder to remove parts once they're being used in scripts), if I need to. If anyone notices anything that could be done more efficiently that'd be a help as well. I'm getting better, but I still have a ways to go with some of my code.
Modifié par Failed.Bard, 13 juin 2012 - 03:00 .