Files
Anphillia_PRC8/_module/nss/umdcheckonscroll.nss
Jaysyn904 28cdb617b3 Initial commit
Adding all of the current content for Anphillia Unlimited.
2024-01-04 07:49:38 -05:00

436 lines
15 KiB
Plaintext

//------------------------------------------------------------------------------
/*
Use Magic Device Check.
Simple use magic device check to prevent abuse of
the engine level implementation of use magic device
This function is not supposed to mirror the 3E use
magic device mechanics.
Returns TRUE if the Spell is allowed to be
cast, either because the character is allowed
to cast it or he has won the required UMD check
returns TRUE if
... spell not cast by an item
... item is not a scroll (may be extended)
... caster has levels in wiz, bard, sorc
... caster is no rogue and has no UMD skill
... caster has memorized this spell
... the property corresponding to the spell does not exist (2da inconsistency)
... a UMD check against 25+InnateLevel of the spell is won
Note: I am not using the effective level of the spell for DC calculation but
instead the lowest possible effective level. This is by design to allow
rogues to use most low level scrolls in the game (i.e. light scrolls have
an effective level 5 but a lowest effective level of 1 and we want low level
rogues to cast these spells..)
Setting a Local Interger called X2_SWITCH_CLASSIC_UMD (TRUE) on the Module
will result in this function to return TRUE all the time
User's can change this default implementation by modifing this file
*/
//------------------------------------------------------------------------------
#include "x2_inc_switches"
#include "x2_inc_itemprop"
int X2_UMD()
{
// if (GetModuleSwitchValue(MODULE_SWITCH_ENABLE_UMD_SCROLLS) == FALSE)
// {
// return TRUE;
// }
object oItem = GetSpellCastItem();
object oPC = GetItemPossessor(oItem);
string sPC = GetName(oPC);
//SpeakString("The item possesors name is "+sPC,TALKVOLUME_TALK);
// Spell not cast from an item, exit
if (!GetIsObjectValid(oItem))
{
return TRUE; // Spell not cast by item, UMD not required
}
// -------------------------------------------------------------------------
// Only Scrolls are subject to our default UMD Check
// -------------------------------------------------------------------------
int nBase = GetBaseItemType(oItem);
if ( nBase != BASE_ITEM_SPELLSCROLL)
{
return TRUE; // spell not cast from a scroll
}
// -------------------------------------------------------------------------
// Ignore scrolls that have no use limitations (i.e. raise dead)
// -------------------------------------------------------------------------
if (!IPGetHasUseLimitation(oItem))
{
return TRUE;
}
object oCaster = OBJECT_SELF;
/*
// -------------------------------------------------------------------------
// Wizards and Sorcerors are supposed to cast scrolls via spellcraft
// -------------------------------------------------------------------------
if (GetLevelByClass(CLASS_TYPE_WIZARD,oCaster) >0 ||GetLevelByClass(CLASS_TYPE_SORCERER,oCaster) >0 || nBard>0)
{
// -------------------------------------------------------------------------
// We only punish rogues, so other classes cast for free :)
// -------------------------------------------------------------------------
return TRUE;
}
// -------------------------------------------------------------------------
// If the caster used the item and has no UMD Skill and is not a rogue
// thus we assume he must be allowed to use it because the engine
// prevents people that are not capable of using an item from using it....
// -------------------------------------------------------------------------
if (!GetHasSkill(SKILL_USE_MAGIC_DEVICE, oCaster) && (GetLevelByClass(CLASS_TYPE_ROGUE,oCaster) ==0 ) && (GetLevelByClass(CLASS_TYPE_ASSASSIN,oCaster) ==0 ) && (GetLevelByClass(CLASS_TYPE_SHADOWDANCER,oCaster) ==0 ))
{
// ---------------------------------------------------------------------
//SpeakString("I have no UMD, thus I can cast the spell... ");
// ---------------------------------------------------------------------
return TRUE;
}
*/
//Deleneated the following Baragg
// -------------------------------------------------------------------------
// If scroll class restrictions match caster class,
// then there is no need for UMD check
// -------------------------------------------------------------------------
// itemproperty ipRestriction = GetFirstItemProperty(oItem);
// while (GetIsItemPropertyValid(ipRestriction))
// {
// if (GetItemPropertyType(ipRestriction) == ITEM_PROPERTY_USE_LIMITATION_CLASS)
// {
// if ((GetItemPropertySubType(ipRestriction) == IP_CONST_CLASS_WIZARD && GetLevelByClass(CLASS_TYPE_WIZARD, oCaster) > 0) ||
// (GetItemPropertySubType(ipRestriction) == IP_CONST_CLASS_SORCERER && GetLevelByClass(CLASS_TYPE_SORCERER, oCaster) > 0) ||
// (GetItemPropertySubType(ipRestriction) == IP_CONST_CLASS_BARD && GetLevelByClass(CLASS_TYPE_BARD, oCaster) > 0) ||
// (GetItemPropertySubType(ipRestriction) == IP_CONST_CLASS_CLERIC && (GetLevelByClass(CLASS_TYPE_CLERIC, oCaster) > 0 || GetLevelByClass(CLASS_TYPE_FAVORED_SOUL, oCaster) > 0)) ||
// (GetItemPropertySubType(ipRestriction) == IP_CONST_CLASS_DRUID && (GetLevelByClass(CLASS_TYPE_DRUID, oCaster) > 0 || GetLevelByClass(CLASS_TYPE_SPIRIT_SHAMAN, oCaster) > 0)) ||
// (GetItemPropertySubType(ipRestriction) == IP_CONST_CLASS_PALADIN && GetLevelByClass(CLASS_TYPE_PALADIN, oCaster) > 0) ||
// (GetItemPropertySubType(ipRestriction) == IP_CONST_CLASS_RANGER && GetLevelByClass(CLASS_TYPE_RANGER, oCaster) > 0))
// {
// return TRUE;
// }
// }
// ipRestriction = GetNextItemProperty(oItem);
// }
int nSpellID = GetSpellId();
// -------------------------------------------------------------------------
// if we knew that spell we could also cast it from an item (may be redundant)
// -------------------------------------------------------------------------
if(GetHasSpell(nSpellID)>0)
{
//SpeakString("I have memorized this spell, I must be able to cast it without UMD ");
return TRUE;
}
string sPropID = Get2DAString("des_crft_spells","IPRP_SpellIndex",nSpellID);
// -------------------------------------------------------------------------
//I am using des_crft_spells.2da Innate Level column here, not (as would be correct)
//the IPPR_Spells.2da InnateLvl column, because some of the scrolls in
//the game (i.e. light) would not be useable (DC 30+)
// -------------------------------------------------------------------------
int nInnateLevel = StringToInt(Get2DAString("des_crft_spells","Level",nSpellID));
int nSkill = SKILL_USE_MAGIC_DEVICE;
string sInnateLevel = Get2DAString("des_crft_spells","Level",nSpellID);
//SpeakString("The scrolls innatelevel is "+sInnateLevel,TALKVOLUME_TALK);
string sSpellID = IntToString(nSpellID);
//SpeakString("Spell Id number is "+sSpellID,TALKVOLUME_TALK);
int nPropID = StringToInt(sPropID);
if (nPropID == 0)
{
// SpeakString("***X2UseMagicDevice (Warning): Found no property matching SpellID "+ IntToString(nSpellID));
return TRUE;
}
//The following by Baragg
//blah 4-23-08
int nWiz, nPrst, nRngr, nPally, nDrud, nSorc, nBard, nArcane, nDivine, nPlyrArc, nPlyrDiv, nRog, nAss, nShad;
//Establish the caster classes/level/ and weather or not they are arcane
//or divine casters. Also establish the Roguely types
nRog = GetLevelByClass(CLASS_TYPE_ROGUE, oPC);
if(nRog > 0){nRog = 1;}
string sRog = IntToString(nRog);
nBard = GetLevelByClass(CLASS_TYPE_BARD,oPC);
if(nBard > 0){nPlyrArc = 1;}
string sBard = IntToString(nBard);
if(nBard > 0){nRog = 1;}
nWiz = GetLevelByClass(CLASS_TYPE_WIZARD,oPC);
if(nWiz > 0){nPlyrArc = 1;}
string sWiz = IntToString(nWiz);
nPrst = GetLevelByClass(CLASS_TYPE_CLERIC,oPC);
if(nPrst > 0){nPlyrDiv = 1;}
string sPrst = IntToString(nPrst);
nRngr = GetLevelByClass(CLASS_TYPE_RANGER,oPC);
if(nRngr > 0){nPlyrDiv = 1;}
string sRngr = IntToString(nRngr);
nPally = GetLevelByClass(CLASS_TYPE_PALADIN,oPC);
if(nPally > 0){nPlyrDiv = 1;}
string sPally = IntToString(nPally);
nDrud = GetLevelByClass(CLASS_TYPE_DRUID,oPC);
if(nDrud > 0){nPlyrDiv = 1;}
string sDrud = IntToString(nDrud);
nSorc = GetLevelByClass(CLASS_TYPE_SORCERER,oPC);
if(nSorc > 0){nPlyrArc = 1;}
string sSorc = IntToString(nSorc);
// SpeakString("Player Rogue level is "+sRog,TALKVOLUME_TALK);
// SpeakString("Player Bard level is "+sBard,TALKVOLUME_TALK);
// SpeakString("Player Wizard level is "+sWiz,TALKVOLUME_TALK);
// SpeakString("Player Cleric level is "+sPrst,TALKVOLUME_TALK);
// SpeakString("Player Ranger level is "+sRngr,TALKVOLUME_TALK);
// SpeakString("Player Paladin level is "+sPally,TALKVOLUME_TALK);
// SpeakString("Player Druid level is "+sDrud,TALKVOLUME_TALK);
// SpeakString("Player Sorcerer level is "+sSorc,TALKVOLUME_TALK);
//Establish weather or not the scroll has divine or arcane restrictions
//then set an interger indicating which
itemproperty ipRestriction1 = GetFirstItemProperty(oItem);
while (GetIsItemPropertyValid(ipRestriction1))
{
if (GetItemPropertySubType(ipRestriction1) == IP_CONST_CLASS_WIZARD)
{
nArcane = 1;
}
if (GetItemPropertySubType(ipRestriction1) == IP_CONST_CLASS_BARD)
{
nArcane = 1;
}
if (GetItemPropertySubType(ipRestriction1) == IP_CONST_CLASS_SORCERER)
{
nArcane = 1;
}
if (GetItemPropertySubType(ipRestriction1) == IP_CONST_CLASS_CLERIC)
{
nDivine = 1;
}
if (GetItemPropertySubType(ipRestriction1) == IP_CONST_CLASS_RANGER)
{
nDivine = 1;
}
if (GetItemPropertySubType(ipRestriction1) == IP_CONST_CLASS_PALADIN)
{
nDivine = 1;
}
if (GetItemPropertySubType(ipRestriction1) == IP_CONST_CLASS_DRUID)
{
nDivine = 1;
}
ipRestriction1 = GetNextItemProperty(oItem);
}
string sArcane = IntToString(nArcane);
string sDivine = IntToString(nDivine);
string sPlyrArc = IntToString(nPlyrArc);
string sPlyrDiv = IntToString(nPlyrDiv);
// SpeakString("Player Arcane set to "+sPlyrArc,TALKVOLUME_TALK);
// SpeakString("Player Divine set to "+sPlyrDiv,TALKVOLUME_TALK);
// SpeakString("Arcane set to "+sArcane, TALKVOLUME_TALK);
// SpeakString("Divine set to "+sDivine, TALKVOLUME_TALK);
//This should be where the arcane scrolls get compared to arcanetype
//casterlevels
if(nArcane == 1)
{
if(nPlyrArc == 1)
{
if(nBard >= nInnateLevel)
{
if(!nInnateLevel < 7)
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;;
}
else if(nInnateLevel < 7)
{
return TRUE;
}
}
if(!nWiz >= nInnateLevel)
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;
}
else if(nWiz >= nInnateLevel)
{
return TRUE;
}
if(!nSorc >= nInnateLevel)
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;
}
else if(nSorc >= nInnateLevel)
{
return TRUE;
}
}
}
//This is where divine scrolls get compared to divinetype casterlevels
if(nDivine == 1)
{
if(nPlyrDiv == 1)
{
if(!nPrst >= nInnateLevel)
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;
}
else if(nPrst >= nInnateLevel)
{
return TRUE;
}
if(!nDrud >= nInnateLevel)
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;;
}
else if(nDrud >= nInnateLevel)
{
return TRUE;
}
if(nRngr >= nInnateLevel)
{
if(!nInnateLevel <5)
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;
}
else if(nInnateLevel < 5)
{
return TRUE;
}
}
if(nPally >= nInnateLevel)
{
if(!nInnateLevel <5)
{
return FALSE;
}
else if(nInnateLevel < 5)
{
return TRUE;
}
}
}
}
//This By Mohobie sets the interger for comparison later
int iDC;
if (nInnateLevel <= 2)
{
iDC = 0;
}
else if (nInnateLevel == 3)
{
iDC = 15;
}
else if (nInnateLevel == 4)
{
iDC = 25;
}
else if (nInnateLevel == 5)
{
iDC = 35;
}
else if (nInnateLevel == 6)
{
iDC = 45;
}
else if (nInnateLevel == 7)
{
iDC = 55;
}
else if (nInnateLevel == 8)
{
iDC = 65;
}
else if (nInnateLevel == 9)
{
iDC = 75;
}
// -------------------------------------------------------------------------
// Base DC for casting a spell from a scroll is 25+SpellLevel
// We do not have a way to check for misshaps here but GetIsSkillSuccessful
/// does not return the required information
// -------------------------------------------------------------------------
// SM update is 20+ iDC
int nUMD = GetIsSkillSuccessful(oCaster,nSkill, 20+iDC);
if(nRog == 1)
{
if(nUMD == TRUE)
{
return TRUE;
}
else
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;
}
}
else
{
effect ePuff = EffectVisualEffect(-1);
ApplyEffectToObject(DURATION_TYPE_INSTANT,ePuff,oCaster);
return FALSE;
}
}
void main()
{
//--------------------------------------------------------------------------
// Reset
//--------------------------------------------------------------------------
if (GetLocalInt(GetModule(),"X2_L_STOP_EXPERTISE_ABUSE") == TRUE)
{
SetActionMode(OBJECT_SELF,ACTION_MODE_EXPERTISE,FALSE);
SetActionMode(OBJECT_SELF,ACTION_MODE_IMPROVED_EXPERTISE,FALSE);
}
//--------------------------------------------------------------------------
// Do use magic device check
//--------------------------------------------------------------------------
int nRet = X2_UMD();
SetExecutedScriptReturnValue (nRet);
}