261 lines
9.4 KiB
Plaintext
261 lines
9.4 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: Magic descriptors and subschools include
|
|
//:: prc_inc_descrptr
|
|
//::///////////////////////////////////////////////
|
|
/** @file prc_inc_descrptr
|
|
A set of constants and functions for managing
|
|
spell's / power's / other stuffs's descriptors
|
|
and sub{school|discipline|whatever}s.
|
|
|
|
The functions SetDescriptor() and SetSubschool()
|
|
should be called at the beginning of the
|
|
spellscript, before spellhook or equivalent.
|
|
|
|
The values are stored on the module object and
|
|
are automatically cleaned up after script
|
|
execution terminates (ie, DelayCommand(0.0f)).
|
|
This is a potential gotcha, as the descriptor
|
|
and subschool data will no longer be available
|
|
during the spell's delayed operations. An
|
|
ugly workaround would be to set the descriptor
|
|
values again in such cases.
|
|
If you come up with an elegant solution, please
|
|
try to generalise it and change this as needed.
|
|
|
|
|
|
@author Ornedan
|
|
@date Created - 2006.06.30
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:://////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Constants */
|
|
//////////////////////////////////////////////////
|
|
|
|
// The descriptor and subschool constants are bit flags for easy combination and lookup
|
|
const int DESCRIPTOR_ACID = 0x00001;
|
|
const int DESCRIPTOR_AIR = 0x00002;
|
|
const int DESCRIPTOR_CHAOTIC = 0x00004;
|
|
const int DESCRIPTOR_COLD = 0x00008;
|
|
const int DESCRIPTOR_DARKNESS = 0x00010;
|
|
const int DESCRIPTOR_DEATH = 0x00020;
|
|
const int DESCRIPTOR_EARTH = 0x00040;
|
|
const int DESCRIPTOR_ELECTRICITY = 0x00080;
|
|
const int DESCRIPTOR_EVIL = 0x00100;
|
|
const int DESCRIPTOR_FEAR = 0x00200;
|
|
const int DESCRIPTOR_FIRE = 0x00400;
|
|
const int DESCRIPTOR_FORCE = 0x00800;
|
|
const int DESCRIPTOR_GOOD = 0x01000;
|
|
const int DESCRIPTOR_LANGUAGEDEPENDENT = 0x02000;
|
|
const int DESCRIPTOR_LAWFUL = 0x04000;
|
|
const int DESCRIPTOR_LIGHT = 0x08000;
|
|
const int DESCRIPTOR_MINDAFFECTING = 0x10000;
|
|
const int DESCRIPTOR_SONIC = 0x20000;
|
|
const int DESCRIPTOR_WATER = 0x40000;
|
|
// update if any of elemental descriptors change!
|
|
// int DESCRIPTOR_ELEMENTAL = DESCRIPTOR_ACID | DESCRIPTOR_COLD | DESCRIPTOR_ELECTRICITY | DESCRIPTOR_FIRE | DESCRIPTOR_SONIC;
|
|
const int DESCRIPTOR_ELEMENTAL = 0x20489;
|
|
|
|
const int SUBSCHOOL_CALLING = 0x00001;
|
|
const int SUBSCHOOL_CHARM = 0x00002;
|
|
const int SUBSCHOOL_COMPULSION = 0x00004;
|
|
const int SUBSCHOOL_CREATION = 0x00008;
|
|
const int SUBSCHOOL_FIGMENT = 0x00010;
|
|
const int SUBSCHOOL_GLAMER = 0x00020;
|
|
const int SUBSCHOOL_HEALING = 0x00040;
|
|
const int SUBSCHOOL_PATTERN = 0x00080;
|
|
const int SUBSCHOOL_PHANTASM = 0x00100;
|
|
const int SUBSCHOOL_POLYMORPH = 0x00200;
|
|
const int SUBSCHOOL_SCRYING = 0x00400;
|
|
const int SUBSCHOOL_SHADOW = 0x00800;
|
|
const int SUBSCHOOL_SUMMONING = 0x01000;
|
|
const int SUBSCHOOL_TELEPORTATION = 0x02000;
|
|
|
|
const string PRC_DESCRIPTOR = "PRC_Descriptor";
|
|
const string PRC_SUBSCHOOL = "PRC_Subschool";
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function prototypes */
|
|
//////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Sets the descriptor of currently being cast spell / power / whatever
|
|
* to be the given value. This should be called before spellhook / powerhook
|
|
* / whateverhook.
|
|
*
|
|
* If the magic in question has multiple descriptors, they should be OR'd together.
|
|
* For example, Phantasmal Killer would call the function thus:
|
|
* SetDescriptor(DESCRIPTOR_FEAR | DESCRIPTOR_MINDAFFECTING);
|
|
*
|
|
* This will override values set in prc_spells.2da
|
|
*
|
|
* @param nfDescriptorFlags The descriptors of a spell / power / X being currently used
|
|
*/
|
|
void SetDescriptor(int nfDescriptorFlags, object oPC = OBJECT_SELF);
|
|
|
|
/**
|
|
* Sets the subschool / subdiscipline / subwhatever of currently being cast
|
|
* spell / power / whatever to be the given value. This should be called before
|
|
* spellhook / powerhook / whateverhook.
|
|
*
|
|
* If the magic in question has multiple subschools, they should be OR'd together.
|
|
* For example, Mislead would call the function thus:
|
|
* SetDescriptor(SUBSCHOOL_FIGMENT | SUBSCHOOL_GLAMER);
|
|
*
|
|
* This will override values set in prc_spells.2da
|
|
*
|
|
* @param nfSubschoolFlags The subschools of a spell / power / X being currently used
|
|
*/
|
|
void SetSubschool(int nfSubschoolFlags, object oPC = OBJECT_SELF);
|
|
|
|
/**
|
|
* Tests whether a magic being currently used has the given descriptor.
|
|
*
|
|
* NOTE: Multiple descriptors may be tested for at once. If so, the return value
|
|
* will be true only if all the descriptors tested for are present. Doing so is
|
|
* technically a misuse of this function.
|
|
*
|
|
*
|
|
* @param nSpellID row number of tested spell in spells.2da
|
|
* @param nDescriptorFlag The descriptor to test for
|
|
* @return TRUE if the magic being used has the given descriptor(s), FALSE otherwise
|
|
*/
|
|
int GetHasDescriptor(int nSpellID, int nDescriptorFlag);
|
|
|
|
/**
|
|
* Returns TRUE if given spell has one of the elemental descriptors
|
|
* (acid, cold, electricity, fire or sonic)
|
|
*
|
|
* @param nSpellID row number of tested spell in spells.2da
|
|
* @return ID of elemental descriptor or FALSE
|
|
*/
|
|
int GetIsElementalSpell(int nSpellID, int nDescriptor = -1);
|
|
|
|
/**
|
|
* Tests whether a magic being currently used is of the given subschool.
|
|
*
|
|
* NOTE: Multiple subschools may be tested for at once. If so, the return value
|
|
* will be true only if all the subschools tested for are present. Doing so is
|
|
* technically a misuse of this function.
|
|
*
|
|
*
|
|
* @param nSpellID row number of tested spell in spells.2da
|
|
* @param nDescriptorFlag The subschool to test for
|
|
* @return TRUE if the magic being used is of the given subschool(s), FALSE otherwise
|
|
*/
|
|
int GetIsOfSubschool(int nSpellID, int nSubschoolFlag);
|
|
|
|
/**
|
|
* Returns an integer value containing the bitflags of descriptors set in prc_spells.2da
|
|
* for a given SpellID
|
|
*
|
|
* @param nSpellID row number of tested spell in spells.2da
|
|
* @return The converted raw integer value from prc_spells.2da
|
|
*/
|
|
int GetDescriptorFlags(int nSpellID);
|
|
|
|
/**
|
|
* Returns an integer value containing the bitflags of subschools set in prc_spells.2da
|
|
* for a given SpellID
|
|
*
|
|
* @param nSpellID row number of tested spell in spells.2da
|
|
* @return The converted raw integer value from prc_spells.2da
|
|
*/
|
|
int GetSubschoolFlags(int nSpellID);
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Includes */
|
|
//////////////////////////////////////////////////
|
|
|
|
#include "inc_2dacache" // already has access via inc_utility
|
|
//#include "inc_utility"
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Function definitions */
|
|
//////////////////////////////////////////////////
|
|
|
|
void SetDescriptor(int nfDescriptorFlags, object oPC = OBJECT_SELF)
|
|
{
|
|
// Store the value
|
|
SetLocalInt(oPC, PRC_DESCRIPTOR, nfDescriptorFlags);
|
|
|
|
// Queue cleanup. No duplicacy checks, this function is not particularly likely to be called more than once anyway
|
|
DelayCommand(0.0f, DeleteLocalInt(oPC, PRC_DESCRIPTOR));
|
|
}
|
|
|
|
void SetSubschool(int nfSubschoolFlags, object oPC = OBJECT_SELF)
|
|
{
|
|
// Store the value
|
|
SetLocalInt(oPC, PRC_SUBSCHOOL, nfSubschoolFlags);
|
|
|
|
// Queue cleanup. No duplicacy checks, this function is not particularly likely to be called more than once anyway
|
|
DelayCommand(0.0f, DeleteLocalInt(oPC, PRC_SUBSCHOOL));
|
|
}
|
|
|
|
int GetHasDescriptor(int nSpellID, int nDescriptorFlag)
|
|
{
|
|
//check for descriptor override
|
|
int nDescriptor = GetLocalInt(OBJECT_SELF, PRC_DESCRIPTOR);
|
|
if(!nDescriptor)
|
|
nDescriptor = GetDescriptorFlags(nSpellID);
|
|
|
|
if(nDescriptorFlag & DESCRIPTOR_ELEMENTAL)
|
|
{
|
|
return nDescriptorFlag & GetIsElementalSpell(nSpellID, nDescriptor);
|
|
}
|
|
|
|
return nDescriptor & nDescriptorFlag;
|
|
}
|
|
|
|
int GetIsElementalSpell(int nSpellID, int nDescriptor = -1)
|
|
{
|
|
if(nDescriptor == -1)
|
|
{
|
|
//check for descriptor override
|
|
nDescriptor = GetLocalInt(OBJECT_SELF, PRC_DESCRIPTOR);
|
|
if(!nDescriptor)
|
|
nDescriptor = GetDescriptorFlags(nSpellID);
|
|
}
|
|
|
|
int nMastery = GetLocalInt(OBJECT_SELF, "archmage_mastery_elements");
|
|
|
|
//mastery of elements is active
|
|
if(nMastery)
|
|
{
|
|
switch(nMastery)
|
|
{
|
|
case DAMAGE_TYPE_ACID: return DESCRIPTOR_ACID;
|
|
case DAMAGE_TYPE_COLD: return DESCRIPTOR_COLD;
|
|
case DAMAGE_TYPE_ELECTRICAL: return DESCRIPTOR_ELECTRICITY;
|
|
case DAMAGE_TYPE_FIRE: return DESCRIPTOR_FIRE;
|
|
case DAMAGE_TYPE_SONIC: return DESCRIPTOR_SONIC;
|
|
}
|
|
}
|
|
|
|
return nDescriptor & DESCRIPTOR_ELEMENTAL;
|
|
}
|
|
|
|
int GetIsOfSubschool(int nSpellID, int nSubschoolFlag)
|
|
{
|
|
//check for subschool override
|
|
int nSubschool = GetLocalInt(OBJECT_SELF, PRC_SUBSCHOOL);
|
|
if(!nSubschool)
|
|
nSubschool = GetSubschoolFlags(nSpellID);
|
|
return (nSubschool & nSubschoolFlag);
|
|
}
|
|
|
|
int GetDescriptorFlags(int nSpellID)
|
|
{
|
|
return HexToInt(Get2DACache("prc_spells", "Descriptor", nSpellID));
|
|
}
|
|
|
|
int GetSubschoolFlags(int nSpellID)
|
|
{
|
|
return HexToInt(Get2DACache("prc_spells", "Subschool", nSpellID));
|
|
}
|
|
|
|
// Test main
|
|
//void main(){}
|