2025/08/24 Update

Updated for PRC8 updates.
This commit is contained in:
Jaysyn904
2025-08-24 19:29:55 -04:00
parent 0bb3bbb7cd
commit 5a8786086c
53 changed files with 4373 additions and 1186 deletions

View File

@@ -228,10 +228,18 @@ description = "PRC8 version of D1-2 Descent Into the Depths of the Earth."
filter = "x2_inc_spellhook.nss"
filter = "x3_inc_horse.nss"
filter = "prc_inc_string.nss"
filter = "prc_inc_string.nss"
filter = "prc_nui_sc_inc.nss"
filter = "prc_nui_scd_inc.nss"
filter = "prc_nui_consts.nss"
filter = "nw_inc_nui"
filter = "prc_nui_sb_inc.nss"
filter = "prc_nui_sbd_inc.nss"
filter = "prc_nui_lv_inc.nss"
filter = "prc_nui_com_inc.nss"
filter = "nw_inc_nui.nss"
filter = "inc_infusion.nss"
filter = "nw_inc_gff.nss"
filter = "prc_inc_json.nss"
filter = "xchst_inc.nss"
[target.rules]

View File

@@ -0,0 +1,104 @@
// HCR v3.2.0 - Removed Wild Magic include and function. Added spell hook code.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_GrRestore
//::////////////////////////////////////////////////////////////////////////////
/*
Removes all negative effects of a temporary nature and all permanent effects
of a supernatural nature from the character. Does not remove the effects
relating to Mind-Affecting spells or movement alteration. Heals target for
5d8 + 1 point per caster level.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan. 7, 2002
//::////////////////////////////////////////////////////////////////////////////
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
// Returns TRUE if eEff was created by a supernatural force and can't be
// dispelled by spells.
int GetIsSupernaturalCurse(effect eEff);
//::////////////////////////////////////////////////////////////////////////////
void main()
{
/*
Spellcast Hook Code. Added 2003-06-23 by GeorgZ. If you want to make changes
to all spells, check x2_inc_spellhook.nss to find out more.
*/
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// End of Spell Cast Hook.
// Search for negative effects.
int nType;
int nSubType;
object oTarget = GetSpellTargetObject();
effect eBad = GetFirstEffect(oTarget);
while (GetIsEffectValid(eBad))
{
nType = GetEffectType(eBad);
if (nType == EFFECT_TYPE_ABILITY_DECREASE ||
nType == EFFECT_TYPE_AC_DECREASE ||
nType == EFFECT_TYPE_ATTACK_DECREASE ||
nType == EFFECT_TYPE_DAMAGE_DECREASE ||
nType == EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE ||
nType == EFFECT_TYPE_SAVING_THROW_DECREASE ||
nType == EFFECT_TYPE_SPELL_RESISTANCE_DECREASE ||
nType == EFFECT_TYPE_SKILL_DECREASE ||
nType == EFFECT_TYPE_BLINDNESS ||
nType == EFFECT_TYPE_DEAF ||
nType == EFFECT_TYPE_CURSE ||
nType == EFFECT_TYPE_DISEASE ||
nType == EFFECT_TYPE_POISON ||
nType == EFFECT_TYPE_PARALYZE ||
nType == EFFECT_TYPE_CHARMED ||
nType == EFFECT_TYPE_DOMINATED ||
nType == EFFECT_TYPE_DAZED ||
nType == EFFECT_TYPE_CONFUSED ||
nType == EFFECT_TYPE_FRIGHTENED ||
nType == EFFECT_TYPE_NEGATIVELEVEL ||
nType == EFFECT_TYPE_PARALYZE ||
nType == EFFECT_TYPE_SLOW ||
nType == EFFECT_TYPE_STUNNED)
{
// Remove effect if it is negative.
nSubType = GetEffectSubType(eBad);
if (nSubType != SUBTYPE_EXTRAORDINARY &&
!GetIsSupernaturalCurse(eBad))
{ RemoveEffect(oTarget, eBad); }
}
eBad = GetNextEffect(oTarget);
}
// Only heal if target is not undead.
if (GetRacialType(oTarget) != RACIAL_TYPE_UNDEAD)
{
int nHeal;
int nMHP = GetMaxHitPoints(oTarget);
int nCHP = GetCurrentHitPoints(oTarget);
if (nCHP < 0)
{ nHeal = (abs(nCHP) + nMHP); }
else
{ nHeal = (nMHP - nCHP); }
effect eHeal = EffectHeal(nHeal);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
}
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_GREATER_RESTORATION, FALSE));
// Apply the visual effect.
effect eVisual = EffectVisualEffect(VFX_IMP_RESTORATION_GREATER);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisual, oTarget);
}
//::////////////////////////////////////////////////////////////////////////////
int GetIsSupernaturalCurse(effect eEff)
{
object oCreator = GetEffectCreator(eEff);
if (GetTag(oCreator) == "q6e_ShaorisFellTemple")
{ return TRUE; }
return FALSE;
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,85 @@
// HCR v3.2.0 - Removed Wild Magic. Added spell hook and HOTU code.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_Heal
//::////////////////////////////////////////////////////////////////////////////
/*
Heals the target to full unless they are undead. If undead, they are reduced
to 1d4 HP.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 12, 2001
//:: Updated On: Aug 1, 2001 - Preston W.
//::////////////////////////////////////////////////////////////////////////////
#include "NW_I0_SPELLS"
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
void main()
{
/*
Spellcast Hook Code. Added 2003-06-23 by GeorgZ. If you want to make changes
to all spells, check x2_inc_spellhook.nss to find out more.
*/
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// End of Spell Cast Hook.
// Check to see if the target is an undead.
object oTarget = GetSpellTargetObject();
int nCHP = GetCurrentHitPoints(oTarget);
if (GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD)
{
if (!GetIsReactionTypeFriendly(oTarget))
{
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_HEAL));
// Make a touch attack.
if (TouchAttackMelee(oTarget) > 0)
{
// Make SR check.
if (!MyResistSpell(OBJECT_SELF, oTarget))
{
// Determine the amount of damage to inflict.
int nModify;
int nMetaMagic = GetMetaMagicFeat();
if (nMetaMagic == METAMAGIC_MAXIMIZE)
{ nModify = 1; }
else
{ nModify = d4(); }
int nDam = (nCHP - nModify);
// Set the damage visual and effect.
effect eVis1 = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
effect eKill = EffectDamage(nDam, DAMAGE_TYPE_POSITIVE);
// Apply the damage visual and effect.
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis1, oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eKill, oTarget);
}
}
}
}
else
{
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_HEAL, FALSE));
// Figure out how much to heal.
int nHeal;
int nMHP = GetMaxHitPoints(oTarget);
if (nCHP < 0)
{ nHeal = (abs(nCHP) + nMHP); }
else
{ nHeal = (nMHP - nCHP); }
// Set the heal visual and effect.
effect eVis2 = EffectVisualEffect(VFX_IMP_HEALING_X);
effect eHeal = EffectHeal(nHeal);
// Apply the heal visual and effect.
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
}
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,85 @@
// HCR v3.2.0 - Added Burn Torch time to computed duration.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_Light
//::////////////////////////////////////////////////////////////////////////////
/*
Applies a light source to the target for 1 hour per level.
XP2
- If cast on an item, item will get temporary property "light" for the
duration of the spell. Brightness on an item is lower than on the continual
light version.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 15, 2001
//:: Updated On: 2003-06-05 - Added XP2 cast on item code - Georg Z.
//::////////////////////////////////////////////////////////////////////////////
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// Declare major variables.
object oTarget = GetSpellTargetObject();
int nDuration = GetCasterLevel(OBJECT_SELF);
int nMetaMagic = GetMetaMagicFeat();
float fDuration;
// Handle spell cast on item....
if (GetObjectType(oTarget) == OBJECT_TYPE_ITEM && ! CIGetIsCraftFeatBaseItem(oTarget))
{
// Do not allow casting on unequippable items.
if (!IPGetIsItemEquipable(oTarget))
{
FloatingTextStrRefOnCreature(83326,OBJECT_SELF);
return;
}
// Remove previous casting of light.
itemproperty ip = ItemPropertyLight(IP_CONST_LIGHTBRIGHTNESS_NORMAL, IP_CONST_LIGHTCOLOR_WHITE);
if (GetItemHasItemProperty(oTarget, ITEM_PROPERTY_LIGHT))
{ IPRemoveMatchingItemProperties(oTarget, ITEM_PROPERTY_LIGHT, DURATION_TYPE_TEMPORARY); }
// Enter Metamagic conditions.
if (nMetaMagic == METAMAGIC_EXTEND)
{ nDuration = (nDuration*2); }
// Determine duration.
float fBurn = IntToFloat(GetLocalInt(GetModule(), "BURNTORCH"));
if (fBurn > 0.0)
{ fDuration = ((fBurn*HoursToSeconds(nDuration))/6.0); }
else
{ fDuration = HoursToSeconds(nDuration); }
// Apply the item property.
AddItemProperty(DURATION_TYPE_TEMPORARY, ip, oTarget, fDuration);
}
else
{
effect eVis = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20);
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
effect eLink = EffectLinkEffects(eVis, eDur);
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_LIGHT, FALSE));
// Enter Metamagic conditions.
if (nMetaMagic == METAMAGIC_EXTEND)
{ nDuration = (nDuration*2); }
// Determine duration.
float fBurn = IntToFloat(GetLocalInt(GetModule(), "BURNTORCH"));
if (fBurn > 0.0)
{ fDuration = ((fBurn*HoursToSeconds(nDuration))/6.0); }
else
{ fDuration = HoursToSeconds(nDuration); }
// Apply the VFX impact and effects.
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration);
}
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,101 @@
// HCR v3.2.0 - Removed Wild Magic include and function. Added spell hook code.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_MasHeal
//::////////////////////////////////////////////////////////////////////////////
/*
Heals all friendly targets within 10ft to full unless they are undead. If
undead they are reduced to 1d4 HP.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 11, 2001
//::////////////////////////////////////////////////////////////////////////////
#include "NW_I0_SPELLS"
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// Declare major variables.
float fDelay;
effect eKill;
effect eHeal;
effect eVis1 = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
effect eVis2 = EffectVisualEffect(VFX_IMP_HEALING_G);
int nMHP, nCHP, nHeal, nDam, nMod;
int nMetaMagic = GetMetaMagicFeat();
// Apply VFX area impact.
effect eStrike = EffectVisualEffect(VFX_FNF_LOS_HOLY_10);
location lLoc = GetSpellTargetLocation();
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eStrike, lLoc);
// Get first target in spell area.
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLoc);
while (GetIsObjectValid(oTarget))
{
fDelay = GetRandomDelay();
nCHP = GetCurrentHitPoints(oTarget);
// Check to see if the target is an undead.
if (GetRacialType(oTarget) == RACIAL_TYPE_UNDEAD && !GetIsReactionTypeFriendly(oTarget))
{
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_MASS_HEAL));
// Make a touch attack.
if (TouchAttackRanged(oTarget) > 0)
{
if (!GetIsReactionTypeFriendly(oTarget))
{
// Make an SR check.
if (!MyResistSpell(OBJECT_SELF, oTarget, fDelay))
{
// Detemine the damage to inflict to the undead.
if (nMetaMagic == METAMAGIC_MAXIMIZE)
{ nMod = 1; }
else
{ nMod = d4(); }
nDam = (nCHP - nMod);
// Set the damage effect.
eKill = EffectDamage(nDam, DAMAGE_TYPE_POSITIVE);
// Apply the damage visual and effect.
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis1, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eKill, oTarget));
}
}
}
}
else
{
// Make a faction check
if (GetIsFriend(oTarget) && GetRacialType(oTarget) != RACIAL_TYPE_UNDEAD)
{
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_MASS_HEAL, FALSE));
// Figure out how much to heal.
nMHP = GetMaxHitPoints(oTarget);
if (nCHP < 0)
{ nHeal = (abs(nCHP) + nMHP); }
else
{ nHeal = (nMHP - nCHP); }
// Set the heal effect.
eHeal = EffectHeal(nHeal);
// Apply the heal visual and effect.
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget));
DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget));
}
}
// Get next target in the spell area.
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lLoc);
}
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,279 @@
// HCR v3.2.0 - Added Death System code and cleaned up. Thanks Sunjammer.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_RaisDead
//::////////////////////////////////////////////////////////////////////////////
/*
Spell script to bring a PC or an NPC back to life with one health.
In HCR, death has many variants:
----------------------------------
- Death, Limbo: PC dies and is in due course transferred to limbo. In their
place a static Corpse NPC, an "invisible" DeathCorpse placeable and an PCT
(Player Corpse Token) item are created. A caster can use the DeathCorpse
to revive the PC. Currently if the caster tries to revive a PC before
they are transferred to limbo they will be informed that this is not
possible. The DeathCorpse can be used to revive a PC who is off-line.
- Death, No Limbo: PC dies and remains where they fell. At their location
the same 3 components are created (Corpse, DeathCorpse and PCT). A caster
can use the DeathCorpse to revive the PC or cast directly onto the PC. The
DeathCorpse can be used to revive a PC who is off-line.
- No Death, No Limbo: PC dies and remains where they fell. They have the
option to respawn however if they choose to wait for help a caster can
cast directly onto the PC to revive them.
- NPC: NPC dies and remains where they fell (depending on other options). A
Caster can cast directly onto the NPC to revive them.
Issues Unresolved @ 3.2.0
-------------------------
- NOTFUGUE is used to prevent a PC from being transfered to fugue while in
the process of being revived. The flag is checked by a delayed function
in hc_on_play_death which otherwise transfers the PC to fugue. However as
noted above MOVING pre-empts all attempts to revive a PC who has not yet
been transfered to Fugue. NOTFUGUE appears to have been rendered
redundant.
Original BW Notes
-----------------
When cast on placeables, you get a default error message.
* You can specify a different message in X2_L_RESURRECT_SPELL_MSG_RESREF
* You can turn off the message by setting the variable to -1
*/
//::////////////////////////////////////////////////////////////////////////////
#include "hc_inc"
#include "hc_inc_dcorpse"
#include "hc_inc_remeff"
#include "hc_inc_rezpen"
#include "hc_text_activate"
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
void TakeHPs(object oTarget)
{
int nDam = (GetCurrentHitPoints(oTarget) - 1);
effect eDam = EffectDamage(nDam);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
}
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (X2PreSpellCastCode() == FALSE)
return;
object oCaster = OBJECT_SELF;
object oTarget = GetSpellTargetObject();
object oCreature;
// Get system being used, oMod courtesy of hc_inc.
int nUsingLimbo = GetLocalInt(oMod, "LIMBO");
int nUsingPersist = GetLocalInt(oMod, "PERSIST");
//int nUsingCorpses = GetLocalInt(oMod, "NPCCORPSE");
int nUsingRezPenalty = GetLocalInt(oMod, "REZPENALTY");
int nUsingDeath = GetLocalInt(oMod, "DEATHSYSTEM");
// Cast at Death Corpse flag.
int nCastAtDC = FALSE;
// -------------------------------------------------------------------------
// Part 1: Find the creature to revive.
// -------------------------------------------------------------------------
if (GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{
// Target is a PC or an NPC and hence the creature to revive.
oCreature = oTarget;
}
else if (GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE)
{
// Target is a DeathCorpse (requires Death System) or other placeable.
if (nUsingDeath && GetTag(oTarget) == "DeathCorpse")
{
// Valid: get creature to revive and raise cast at DC flag.
oCreature = GetLocalObject(oTarget, "Owner");
nCastAtDC = TRUE;
}
else
{
// Invalid: send "can't revive that" message to caster and abort.
int nStrRef = GetLocalInt(oTarget, "X2_L_RESURRECT_SPELL_MSG_RESREF");
if (nStrRef == 0)
{
nStrRef = 83861;
}
if (nStrRef != -1)
{
// Inform caster that they cannot revive this object.
FloatingTextStrRefOnCreature(nStrRef, oCaster);
}
return;
}
}
else
{
// Target is invalid or an invalid type: abort.
return;
}
// Pre-emptive abort if MOVING to LIMBO (see above).
if (nUsingLimbo && GetLocalInt(oCreature, "MOVING"))
{
SendMessageToPC(oCaster, NOTRAISE);
return;
}
// -------------------------------------------------------------------------
// Part 2: Revive the creature.
// -------------------------------------------------------------------------
int nIsPC = GetIsPC(oCreature);
// Raise/lower NOTFUGUE flag according to location (see above).
if (nUsingLimbo && GetTag(GetArea(oCreature)) == "FuguePlane")
DeleteLocalInt(oCreature, "NOTFUGUE");
else
SetLocalInt(oCreature, "NOTFUGUE", TRUE);
// Visual revival.
effect eVFX = EffectVisualEffect(VFX_IMP_RAISE_DEAD);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVFX, GetLocation(oTarget));
// Actual revival.
if (nCastAtDC && GetIsObjectValid(oCreature) == FALSE)
{
// ---------------------------------------------------------------------
// Off-line revival can only occur when casting at a DeathCorpse.
// ---------------------------------------------------------------------
string sID = GetLocalString(oTarget, "Pkey");
// Inform caster, store revival location.
SendMessageToPC(oCaster, NOTONLINE);
SetPersistentLocation(oMod, "RESLOC" + sID, GetLocation(oCaster));
// Revive the off-line PC.
if (GetIsDM(oCaster))
{
// DM provides a True Resserection.
if (nUsingPersist)
SetCampaignInt("HCRPC" + sID, "PlayerState", PWS_PLAYER_STATE_RESTRUE);
else
SetPersistentInt(oMod, "PlayerState" + sID, PWS_PLAYER_STATE_RESTRUE);
}
else
{
// PC/NPC provides a Resserection.
if (nUsingPersist)
SetCampaignInt("HCRPC" + sID, "PlayerState", PWS_PLAYER_STATE_RESURRECTED);
else
SetPersistentInt(oMod, "PlayerState" + sID, PWS_PLAYER_STATE_RESURRECTED);
}
return;
}
else
{
// ---------------------------------------------------------------------
// On-line revival can occur when casting at a DeathCorpse or at a dead
// PC or NPC with various combinations of systems and targets.
// ---------------------------------------------------------------------
// 1: PC, nUsingDeath, nUsingLimbo, nCastAtDC
// - PC in fugue (MOVING)
// - manually jump to DC
// - existing Heal, RemEff & Ress (hc_on_play_death)
// - existing kill body, DC & PCT (hc_fugue_exit)
// - existing player state change (hc_fugue_exit)
// 2: PC, nUsingDeath, nCastAtDC
// - PC is anywhere, DC is target
// - manually jump to DC
// - manually kill body, DC & PCT
// - manually player state change
// - manually Heal, RemEff & Ress
// 3: PC, nUsingDeath
// - PC (wait for help) is target
// - manually kill body, DC & PCT
// - manually player state change
// - manually Heal, RemEff & Ress
// 4: PC
// - PC (wait for help) is target
// - manually Heal, RemEff & Ress
// 5: NPC
// - NPC is target
// - manually Heal, RemEff & Ress
// ---------------------------------------------------------------------
string sID = GetPlayerID(oCreature);
// Fire cast spell at event for the specified creature.
SignalEvent(oCreature, EventSpellCastAt(oCaster, SPELL_RESURRECTION, FALSE));
// Start reviving.
if (nIsPC && nUsingDeath && nUsingLimbo && nCastAtDC)
{
// 1: Requires a jump to the DeathCorpse, everything else is done.
AssignCommand(oCreature, JumpToObject(oTarget));
}
else
{
// 2-3: Require the body, DeathCorpse and PCT to be destoyed
// and for the PC's player state to be updated.
if (nIsPC && nUsingDeath)
{
// 2: Requires a jump to the DeathCorpse.
if (nCastAtDC)
AssignCommand(oCreature, JumpToObject(oTarget));
// Destroy the cloned NPC corpse.
DelayCommand(0.5, DestroyCorpse(oCreature));
// Destroy DeathCorpse.
DelayCommand(0.6, DestroyObject(oTarget));
// Destoy the PlayerCorpseToken.
object oPCT = GetLocalObject(oMod, "PlayerCorpse" + sID);
DestroyObject(oPCT);
// Set PC's player state as alive.
SPS(oCreature, PWS_PLAYER_STATE_ALIVE);
}
effect eRess = EffectResurrection();
int nHeal = (abs(GetCurrentHitPoints(oCreature)) + GetMaxHitPoints(oCreature));
effect eHeal = EffectHeal(nHeal);
// 2-5: Require revival, healing and removal of effects.
ApplyEffectToObject(DURATION_TYPE_INSTANT, eRess, oCreature);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oCreature);
RemoveEffects(oCreature);
}
}
// -------------------------------------------------------------------------
// Part 3: Post-revival common stuff and clean up.
// -------------------------------------------------------------------------
// Apply RezPenalty if appropriate.
if (nIsPC && nUsingRezPenalty && GetIsDM(oCaster) == FALSE)
DelayCommand(3.0, hcRezPenalty(oCreature));
// Reset hitpoints to 1.
DelayCommand(3.5, TakeHPs(oCreature));
// Force any nearby hostiles to attack.
DelayCommand(5.0, ExecuteScript("hc_attackpc" , oCreature));
// Lower NOTFUGUE flag.
DeleteLocalInt(oCreature, "NOTFUGUE");
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,269 @@
// HCR v3.2.0 - Added Death System code and cleaned up. Thanks Sunjammer.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_Ressurec
//::////////////////////////////////////////////////////////////////////////////
/*
Spell script to bring a PC or an NPC back to life with full health.
In HCR, death has many variants:
----------------------------------
- Death, Limbo: PC dies and is in due course transferred to limbo. In their
place a static Corpse NPC, an "invisible" DeathCorpse placeable and an PCT
(Player Corpse Token) item are created. A caster can use the DeathCorpse
to revive the PC. Currently if the caster tries to revive a PC before
they are transferred to limbo they will be informed that this is not
possible. The DeathCorpse can be used to revive a PC who is off-line.
- Death, No Limbo: PC dies and remains where they fell. At their location
the same 3 components are created (Corpse, DeathCorpse and PCT). A caster
can use the DeathCorpse to revive the PC or cast directly onto the PC. The
DeathCorpse can be used to revive a PC who is off-line.
- No Death, No Limbo: PC dies and remains where they fell. They have the
option to respawn however if they choose to wait for help a caster can
cast directly onto the PC to revive them.
- NPC: NPC dies and remains where they fell (depending on other options). A
Caster can cast directly onto the NPC to revive them.
Issues Unresolved @ 3.2.0
-------------------------
- NOTFUGUE is used to prevent a PC from being transfered to fugue while in
the process of being revived. The flag is checked by a delayed function
in hc_on_play_death which otherwise transfers the PC to fugue. However as
noted above MOVING pre-empts all attempts to revive a PC who has not yet
been transfered to Fugue. NOTFUGUE appears to have been rendered
redundant.
Original BW Notes
-----------------
When cast on placeables, you get a default error message.
* You can specify a different message in X2_L_RESURRECT_SPELL_MSG_RESREF
* You can turn off the message by setting the variable to -1
*/
//::////////////////////////////////////////////////////////////////////////////
#include "hc_inc"
#include "hc_inc_dcorpse"
#include "hc_inc_remeff"
#include "hc_inc_rezpen"
#include "hc_text_activate"
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (X2PreSpellCastCode() == FALSE)
return;
object oCaster = OBJECT_SELF;
object oTarget = GetSpellTargetObject();
object oCreature;
// Get system being used, oMod courtesy of hc_inc.
int nUsingLimbo = GetLocalInt(oMod, "LIMBO");
int nUsingPersist = GetLocalInt(oMod, "PERSIST");
//int nUsingCorpses = GetLocalInt(oMod, "NPCCORPSE");
int nUsingRezPenalty = GetLocalInt(oMod, "REZPENALTY");
int nUsingDeath = GetLocalInt(oMod, "DEATHSYSTEM");
// Cast at Death Corpse flag.
int nCastAtDC = FALSE;
// -------------------------------------------------------------------------
// Part 1: Find the creature to revive.
// -------------------------------------------------------------------------
if (GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
{
// Target is a PC or an NPC and hence the creature to revive.
oCreature = oTarget;
}
else if (GetObjectType(oTarget) == OBJECT_TYPE_PLACEABLE)
{
// Target is a DeathCorpse (requires Death System) or other placeable.
if (nUsingDeath && GetTag(oTarget) == "DeathCorpse")
{
// Valid: get creature to revive and raise cast at DC flag.
oCreature = GetLocalObject(oTarget, "Owner");
nCastAtDC = TRUE;
}
else
{
// Invalid: send "can't revive that" message to caster and abort.
int nStrRef = GetLocalInt(oTarget, "X2_L_RESURRECT_SPELL_MSG_RESREF");
if (nStrRef == 0)
{
nStrRef = 83861;
}
if (nStrRef != -1)
{
// Inform caster that they cannot revive this object.
FloatingTextStrRefOnCreature(nStrRef, oCaster);
}
return;
}
}
else
{
// Target is invalid or an invalid type: abort.
return;
}
// Pre-emptive abort if MOVING to LIMBO (see above).
if (nUsingLimbo && GetLocalInt(oCreature, "MOVING"))
{
SendMessageToPC(oCaster, NOTRAISE);
return;
}
// -------------------------------------------------------------------------
// Part 2: Revive the creature.
// -------------------------------------------------------------------------
int nIsPC = GetIsPC(oCreature);
// Raise/lower NOTFUGUE flag according to location (see above).
if (nUsingLimbo && GetTag(GetArea(oCreature)) == "FuguePlane")
DeleteLocalInt(oCreature, "NOTFUGUE");
else
SetLocalInt(oCreature, "NOTFUGUE", TRUE);
// Visual revival.
effect eVFX = EffectVisualEffect(VFX_IMP_RAISE_DEAD);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVFX, GetLocation(oTarget));
// Actual revival.
if (nCastAtDC && GetIsObjectValid(oCreature) == FALSE)
{
// ---------------------------------------------------------------------
// Off-line revival can only occur when casting at a DeathCorpse.
// ---------------------------------------------------------------------
string sID = GetLocalString(oTarget, "Pkey");
// Inform caster, store revival location.
SendMessageToPC(oCaster, NOTONLINE);
SetPersistentLocation(oMod, "RESLOC" + sID, GetLocation(oCaster));
// Revive the off-line PC.
if (GetIsDM(oCaster))
{
// DM provides a True Resserection.
if (nUsingPersist)
SetCampaignInt("HCRPC" + sID, "PlayerState", PWS_PLAYER_STATE_RESTRUE);
else
SetPersistentInt(oMod, "PlayerState" + sID, PWS_PLAYER_STATE_RESTRUE);
}
else
{
// PC/NPC provides a Resserection.
if (nUsingPersist)
SetCampaignInt("HCRPC" + sID, "PlayerState", PWS_PLAYER_STATE_RESURRECTED);
else
SetPersistentInt(oMod, "PlayerState" + sID, PWS_PLAYER_STATE_RESURRECTED);
}
return;
}
else
{
// ---------------------------------------------------------------------
// On-line revival can occur when casting at a DeathCorpse or at a dead
// PC or NPC with various combinations of systems and targets.
// ---------------------------------------------------------------------
// 1: PC, nUsingDeath, nUsingLimbo, nCastAtDC
// - PC in fugue (MOVING)
// - manually jump to DC
// - existing Heal, RemEff & Ress (hc_on_play_death)
// - existing kill body, DC & PCT (hc_fugue_exit)
// - existing player state change (hc_fugue_exit)
// 2: PC, nUsingDeath, nCastAtDC
// - PC is anywhere, DC is target
// - manually jump to DC
// - manually kill body, DC & PCT
// - manually player state change
// - manually Heal, RemEff & Ress
// 3: PC, nUsingDeath
// - PC (wait for help) is target
// - manually kill body, DC & PCT
// - manually player state change
// - manually Heal, RemEff & Ress
// 4: PC
// - PC (wait for help) is target
// - manually Heal, RemEff & Ress
// 5: NPC
// - NPC is target
// - manually Heal, RemEff & Ress
// ---------------------------------------------------------------------
string sID = GetPlayerID(oCreature);
// Fire cast spell at event for the specified creature.
SignalEvent(oCreature, EventSpellCastAt(oCaster, SPELL_RESURRECTION, FALSE));
// Start reviving.
if (nIsPC && nUsingDeath && nUsingLimbo && nCastAtDC)
{
// 1: Requires a jump to the DeathCorpse, everything else is done.
AssignCommand(oCreature, JumpToObject(oTarget));
}
else
{
// 2-3: Require the body, DeathCorpse and PCT to be destoyed
// and for the PC's player state to be updated.
if (nIsPC && nUsingDeath)
{
// 2: Requires a jump to the DeathCorpse.
if (nCastAtDC)
AssignCommand(oCreature, JumpToObject(oTarget));
// Destroy the cloned NPC corpse.
DelayCommand(0.5, DestroyCorpse(oCreature));
// Destroy DeathCorpse.
DelayCommand(0.6, DestroyObject(oTarget));
// Destoy the PlayerCorpseToken.
object oPCT = GetLocalObject(oMod, "PlayerCorpse" + sID);
DestroyObject(oPCT);
// Set PC's player state as alive.
SPS(oCreature, PWS_PLAYER_STATE_ALIVE);
}
effect eRess = EffectResurrection();
int nHeal = (abs(GetCurrentHitPoints(oCreature)) + GetMaxHitPoints(oCreature));
effect eHeal = EffectHeal(nHeal);
// 2-5: Require revival, healing and removal of effects.
ApplyEffectToObject(DURATION_TYPE_INSTANT, eRess, oCreature);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oCreature);
RemoveEffects(oCreature);
}
}
// -------------------------------------------------------------------------
// Part 3: Post-revival common stuff and clean up.
// -------------------------------------------------------------------------
// Apply RezPenalty if appropriate.
if (nIsPC && nUsingRezPenalty && GetIsDM(oCaster) == FALSE)
DelayCommand(3.0, hcRezPenalty(oCreature));
// Force any nearby hostiles to attack.
DelayCommand(5.0, ExecuteScript("hc_attackpc" , oCreature));
// Lower NOTFUGUE flag.
DeleteLocalInt(oCreature, "NOTFUGUE");
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,70 @@
// HCR v3.2.0 - Removed Wild Magic include and function. Added spell hook code.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_Restore
//::////////////////////////////////////////////////////////////////////////////
/*
Removes all negative effects unless they come from Poison, Disease or Curses.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 7, 2002
//::////////////////////////////////////////////////////////////////////////////
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
// Returns TRUE if eEff was created by a supernatural force and can't be
// dispelled by spells.
int GetIsSupernaturalCurse(effect eEff);
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// Search for negative effects.
int nType;
int nSubType;
object oTarget = GetSpellTargetObject();
effect eBad = GetFirstEffect(oTarget);
while (GetIsEffectValid(eBad))
{
nType = GetEffectType(eBad);
if (nType == EFFECT_TYPE_ABILITY_DECREASE ||
nType == EFFECT_TYPE_AC_DECREASE ||
nType == EFFECT_TYPE_ATTACK_DECREASE ||
nType == EFFECT_TYPE_DAMAGE_DECREASE ||
nType == EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE ||
nType == EFFECT_TYPE_SAVING_THROW_DECREASE ||
nType == EFFECT_TYPE_SPELL_RESISTANCE_DECREASE ||
nType == EFFECT_TYPE_SKILL_DECREASE ||
nType == EFFECT_TYPE_BLINDNESS ||
nType == EFFECT_TYPE_DEAF ||
nType == EFFECT_TYPE_PARALYZE ||
nType == EFFECT_TYPE_NEGATIVELEVEL)
{
// Remove effect if it is negative.
nSubType = GetEffectSubType(eBad);
if (nSubType != SUBTYPE_EXTRAORDINARY &&
!GetIsSupernaturalCurse(eBad))
{ RemoveEffect(oTarget, eBad); }
}
eBad = GetNextEffect(oTarget);
}
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_RESTORATION, FALSE));
// Apply visual effect.
effect eVisual = EffectVisualEffect(VFX_IMP_RESTORATION);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisual, oTarget);
}
//::////////////////////////////////////////////////////////////////////////////
int GetIsSupernaturalCurse(effect eEff)
{
object oCreator = GetEffectCreator(eEff);
if (GetTag(oCreator) == "q6e_ShaorisFellTemple")
{ return TRUE; }
return FALSE;
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,246 @@
// HCR v3.2.0 -
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_Summon
//::////////////////////////////////////////////////////////////////////////////
/*
Carries out the summoning of the appropriate creature for the Summon Monster
Series of spells 1 to 9.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Jan 8, 2002
//::////////////////////////////////////////////////////////////////////////////
#include "hc_inc_summon"
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
//
effect GetSummonEffect(int nSpellID);
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// Determine base duration.
object oMod = GetModule();
int nLevel = GetCasterLevel(OBJECT_SELF);
int nSummon = GetLocalInt(oMod, "SUMMONTIME");
int nDuration;
if (nSummon > 0)
{ nDuration = ((nLevel * nSummon) + 2); }
else
{ nDuration = 24; }
// Check for Meta-Magic extend.
int nMetaMagic = GetMetaMagicFeat();
if (nMetaMagic == METAMAGIC_EXTEND)
{ nDuration = (nDuration*2); }
// Apply the VFX impact and summon effect.
int nSpellID = GetSpellId();
effect eSummon = GetSummonEffect(nSpellID);
location lLoc = GetSpellTargetLocation();
float fDuration;
if (nSummon > 0)
{ fDuration = RoundsToSeconds(nDuration); }
else
{ fDuration = HoursToSeconds(nDuration); }
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSummon, lLoc, fDuration);
}
//::////////////////////////////////////////////////////////////////////////////
effect GetSummonEffect(int nSpellID)
{
int nFNF_Effect;
int nRoll = d3();
string sSummon;
if (GetHasFeat(FEAT_ANIMAL_DOMAIN_POWER))// WITH THE ANIMAL DOMAIN.
{
if (nSpellID == SPELL_SUMMON_CREATURE_I)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = pick_creature(2);
if (sSummon == "")
{ sSummon = "NW_S_BOARDIRE"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_II)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = pick_creature(3);
if (sSummon == "")
{ sSummon = "NW_S_WOLFDIRE"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_III)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = pick_creature(4);
if (sSummon == "")
{ sSummon = "NW_S_SPIDDIRE"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_IV)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
sSummon = pick_creature(5);
if (sSummon == "")
{ sSummon = "NW_S_beardire"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_V)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
sSummon = pick_creature(6);
if (sSummon == "")
{ sSummon = "NW_S_diretiger"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_VI)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
sSummon = pick_creature(7);
if (sSummon == "")
{
switch (nRoll)
{
case 1: sSummon = "NW_S_AIRHUGE"; break;
case 2: sSummon = "NW_S_WATERHUGE"; break;
case 3: sSummon = "NW_S_FIREHUGE"; break;
}
}
}
else if (nSpellID == SPELL_SUMMON_CREATURE_VII)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
sSummon = pick_creature(8);
if (sSummon == "")
{
switch (nRoll)
{
case 1: sSummon = "NW_S_AIRGREAT"; break;
case 2: sSummon = "NW_S_WATERGREAT"; break;
case 3: sSummon = "NW_S_FIREGREAT"; break;
}
}
}
else if (nSpellID == SPELL_SUMMON_CREATURE_VIII)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
sSummon = pick_creature(9);
if (sSummon == "")
{
switch (nRoll)
{
case 1: sSummon = "NW_S_AIRELDER"; break;
case 2: sSummon = "NW_S_WATERELDER"; break;
case 3: sSummon = "NW_S_FIREELDER"; break;
}
}
}
else if (nSpellID == SPELL_SUMMON_CREATURE_IX)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
sSummon = pick_creature(9);
if (sSummon == "")
{
switch (nRoll)
{
case 1: sSummon = "NW_S_AIRELDER"; break;
case 2: sSummon = "NW_S_WATERELDER"; break;
case 3: sSummon = "NW_S_FIREELDER"; break;
}
}
}
}
else// WITOUT THE ANIMAL DOMAIN.
{
if (nSpellID == SPELL_SUMMON_CREATURE_I)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = pick_creature(1);
if (sSummon == "")
{ sSummon = "NW_S_badgerdire"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_II)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = pick_creature(2);
if (sSummon == "")
{ sSummon = "NW_S_BOARDIRE"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_III)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_1;
sSummon = pick_creature(3);
if (sSummon == "")
{ sSummon = "NW_S_WOLFDIRE"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_IV)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
sSummon = pick_creature(4);
if (sSummon == "")
{ sSummon = "NW_S_SPIDDIRE"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_V)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
sSummon = pick_creature(5);
if (sSummon == "")
{ sSummon = "NW_S_beardire"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_VI)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_2;
sSummon = pick_creature(6);
if (sSummon == "")
{ sSummon = "NW_S_diretiger"; }
}
else if (nSpellID == SPELL_SUMMON_CREATURE_VII)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
sSummon = pick_creature(7);
if (sSummon == "")
{
switch (nRoll)
{
case 1: sSummon = "NW_S_AIRHUGE"; break;
case 2: sSummon = "NW_S_WATERHUGE"; break;
case 3: sSummon = "NW_S_FIREHUGE"; break;
}
}
}
else if (nSpellID == SPELL_SUMMON_CREATURE_VIII)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
sSummon = pick_creature(8);
if (sSummon == "")
{
switch (nRoll)
{
case 1: sSummon = "NW_S_AIRGREAT"; break;
case 2: sSummon = "NW_S_WATERGREAT"; break;
case 3: sSummon = "NW_S_FIREGREAT"; break;
}
}
}
else if (nSpellID == SPELL_SUMMON_CREATURE_IX)
{
nFNF_Effect = VFX_FNF_SUMMON_MONSTER_3;
sSummon = pick_creature(9);
if (sSummon == "")
{
switch (nRoll)
{
case 1: sSummon = "NW_S_AIRELDER"; break;
case 2: sSummon = "NW_S_WATERELDER"; break;
case 3: sSummon = "NW_S_FIREELDER"; break;
}
}
}
}
//effect eVis = EffectVisualEffect(nFNF_Effect);
//ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetSpellTargetLocation());
effect eSummonedMonster = EffectSummonCreature(sSummon, nFNF_Effect);
return eSummonedMonster;
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,82 @@
// HCR v3.2.0 -
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_SummShad
//::////////////////////////////////////////////////////////////////////////////
/*
Spell calls a powerful ally from the shadow plane to battle for the wizard.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 26, 2001
//::////////////////////////////////////////////////////////////////////////////
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
void HCR_RemoveSummonMonster(object oAC)
{
DestroyObject(oAC);
string sMsg = "The shadow returns to its home plane, it's ";
sMsg += "far too powerful for you to retain control.";
SendMessageToPC(OBJECT_SELF, sMsg);
}
//::////////////////////////////////////////////////////////////////////////////
void HCR_CheckSummonStrength()
{
object oAC = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
if (GetIsObjectValid(oAC))
{
int nAHD = GetHitDice(oAC);
int nMCL = GetCasterLevel(OBJECT_SELF);
if ((nAHD > (nMCL+4)))
{ HCR_RemoveSummonMonster(oAC); }
else if (nAHD > nMCL)
{
float fDelay = IntToFloat(240-((nAHD-nMCL)*60));
DelayCommand(fDelay, HCR_RemoveSummonMonster(oAC));
}
}
}
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// Declare major variables.
int nMetaMagic = GetMetaMagicFeat();
int nLvl = GetCasterLevel(OBJECT_SELF);
int nDur = nLvl;
// Check for Meta-Magic extend.
if (nMetaMagic == METAMAGIC_EXTEND)
{ nDur = (nDur*2); }
// Set the summoned undead to the appropriate template based on the caster level.
effect eSum;
if (nLvl <= 7)
{ eSum = EffectSummonCreature("NW_S_SHADOW", VFX_FNF_SUMMON_UNDEAD); }
else if ((nLvl >= 8) && (nLvl <= 10))
{ eSum = EffectSummonCreature("NW_S_SHADMASTIF", VFX_FNF_SUMMON_UNDEAD); }
else if ((nLvl >= 11) && (nLvl <= 14))
{ eSum = EffectSummonCreature("NW_S_SHFIEND", VFX_FNF_SUMMON_UNDEAD); }
else if ((nLvl >= 15))
{ eSum = EffectSummonCreature("NW_S_SHADLORD", VFX_FNF_SUMMON_UNDEAD); }
// Apply VFX impact and summon effect.
//effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD);
location lLoc = GetSpellTargetLocation();
float fDur = HoursToSeconds(nDur);
//ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lLoc);
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSum, lLoc, fDur);
// If real familiars are used, compare the hitdice of the summoned creature to
// the caster of this spell. If the hitdie is too high, remove the summoned
// creature from service. Note: This only effects PC's, not NPC's or DM's.
if (GetLocalInt(GetModule(), "REALFAM") == TRUE)
{
if (GetIsPC(OBJECT_SELF) &&
!GetIsDM(OBJECT_SELF) &&
!GetIsDMPossessed(OBJECT_SELF))
{ HCR_CheckSummonStrength(); }
}
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,72 @@
// HCR v3.2.0 -
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S0_SummShad02
//::////////////////////////////////////////////////////////////////////////////
/*
Spell calls a powerful ally from the shadow plane to battle for the wizard.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 26, 2001
//::////////////////////////////////////////////////////////////////////////////
#include "x2_inc_spellhook"
//::////////////////////////////////////////////////////////////////////////////
void HCR_RemoveSummonMonster(object oAC)
{
DestroyObject(oAC);
string sMsg = "The shadow returns to its home plane, it's ";
sMsg += "far too powerful for you to retain control.";
SendMessageToPC(OBJECT_SELF, sMsg);
}
//::////////////////////////////////////////////////////////////////////////////
void HCR_CheckSummonStrength()
{
object oAC = GetAssociate(ASSOCIATE_TYPE_SUMMONED);
if (GetIsObjectValid(oAC))
{
int nAHD = GetHitDice(oAC);
int nMCL = GetCasterLevel(OBJECT_SELF);
if ((nAHD > (nMCL+4)))
{ HCR_RemoveSummonMonster(oAC); }
else if (nAHD > nMCL)
{
float fDelay = IntToFloat(240-((nAHD-nMCL)*60));
DelayCommand(fDelay, HCR_RemoveSummonMonster(oAC));
}
}
}
//::////////////////////////////////////////////////////////////////////////////
void main()
{
// If code within the PreSpellCastHook reports FALSE, do not run this spell.
if (!X2PreSpellCastCode()) { return; }
// Set the summoned undead to the appropriate template based on the caster level.
effect eSum;
int nLvl = GetLevelByClass(CLASS_TYPE_CLERIC);
if (nLvl <= 7)
{ eSum = EffectSummonCreature("NW_S_SHADOW", VFX_FNF_SUMMON_UNDEAD); }
else if ((nLvl >= 8) && (nLvl <= 10))
{ eSum = EffectSummonCreature("NW_S_SHADMASTIF", VFX_FNF_SUMMON_UNDEAD); }
else if ((nLvl >= 11) && (nLvl <= 14))
{ eSum = EffectSummonCreature("NW_S_SHFIEND", VFX_FNF_SUMMON_UNDEAD); }
else if ((nLvl >= 15))
{ eSum = EffectSummonCreature("NW_S_SHADLORD", VFX_FNF_SUMMON_UNDEAD); }
// Apply VFX impact and summon effect.
location lLoc = GetSpellTargetLocation();
float fDur = HoursToSeconds(24);
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eSum, lLoc, fDur);
// If real familiars are used, compare the hitdice of the summoned creature to
// the caster of this spell. If the hitdie is too high, remove the summoned
// creature from service. Note: This only effects PC's, not NPC's or DM's.
if (GetLocalInt(GetModule(), "REALFAM") == TRUE)
{
if (GetIsPC(OBJECT_SELF) &&
!GetIsDM(OBJECT_SELF) &&
!GetIsDMPossessed(OBJECT_SELF))
{ HCR_CheckSummonStrength(); }
}
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,115 @@
// HCR v3.2.0 -
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S1_BarbRage
//::////////////////////////////////////////////////////////////////////////////
/*
The Str and Con of the Barbarian increases, Will Save are +2, AC -2. Greater
Rage starts at level 15.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 13, 2001
//::////////////////////////////////////////////////////////////////////////////
#include "x2_i0_spells"
#include "hc_inc"
//::////////////////////////////////////////////////////////////////////////////
// % movement rate decrease.
const int MOVE_PENALTY = 20;
//::////////////////////////////////////////////////////////////////////////////
void RageWearsOff(object oPC, effect eEffect)
{
int nCHP = GetCurrentHitPoints(oPC);
int nState = GPS(oPC);
if ((nState == PWS_PLAYER_STATE_DYING ||
nState == PWS_PLAYER_STATE_STABLE) && nCHP > -1)
{
effect eDam = EffectDamage(nCHP + 1);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oPC);
SPS(oPC, PWS_PLAYER_STATE_DYING);
ExecuteScript("hc_bleeding", oPC);
return;
}
if (GetIsInCombat(oPC))
{
if (!GetLocalInt(oPC, "RAGED"))
{
SendMessageToPC(oPC, "You are now fatigued because of raging.");
ApplyEffectToObject(DURATION_TYPE_INSTANT, SupernaturalEffect(eEffect), oPC);
SetLocalInt(oPC, "RAGED", TRUE);
}
}
else
{
RemoveEffect(oPC, eEffect);
DeleteLocalInt(oPC, "RAGED");
return;
}
DelayCommand(6.0, RageWearsOff(oPC, eEffect));
}
//::////////////////////////////////////////////////////////////////////////////
void main()
{
if (!GetHasFeatEffect(FEAT_BARBARIAN_RAGE))
{
//Declare major variables
int nLevel = GetLevelByClass(CLASS_TYPE_BARBARIAN);
int nIncrease;
int nSave;
if (nLevel < 15)
{
nIncrease = 4;
nSave = 2;
}
else
{
nIncrease = 6;
nSave = 3;
}
PlayVoiceChat(VOICE_CHAT_BATTLECRY1);
// Determine the duration by getting the con modifier after being modified.
int nCon = 3 + GetAbilityModifier(ABILITY_CONSTITUTION) + nIncrease;
effect eStr = EffectAbilityIncrease(ABILITY_CONSTITUTION, nIncrease);
effect eCon = EffectAbilityIncrease(ABILITY_STRENGTH, nIncrease);
effect eSave = EffectSavingThrowIncrease(SAVING_THROW_WILL, nSave);
effect eAC = EffectACDecrease(2, AC_DODGE_BONUS);
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
effect eLink = EffectLinkEffects(eCon, eStr);
eLink = EffectLinkEffects(eLink, eSave);
eLink = EffectLinkEffects(eLink, eAC);
eLink = EffectLinkEffects(eLink, eDur);
SignalEvent(OBJECT_SELF, EventSpellCastAt(OBJECT_SELF, SPELLABILITY_BARBARIAN_RAGE, FALSE));
//Make effect extraordinary
eLink = ExtraordinaryEffect(eLink);
if (nCon > 0)
{
//Apply the VFX impact and effects
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, OBJECT_SELF, RoundsToSeconds(nCon));
effect eVis = EffectVisualEffect(VFX_IMP_IMPROVE_ABILITY_SCORE);// Change to the Rage VFX.
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF);
// 2003-07-08, Georg: Rage Epic Feat Handling
CheckAndApplyEpicRageFeats(nCon);
// Add call for fatigue effects for when rage wears off.
effect eStrDec = EffectAbilityDecrease(ABILITY_STRENGTH, 2);
effect eDexDec = EffectAbilityDecrease(ABILITY_DEXTERITY, 2);
//effect eSlow = EffectSlow();
effect eSlow = EffectMovementSpeedDecrease(MOVE_PENALTY);
effect eEffect = EffectLinkEffects(eDexDec, eStrDec);
eEffect = EffectLinkEffects(eEffect, eSlow);
DelayCommand(RoundsToSeconds(nCon) + 1.0, RageWearsOff(OBJECT_SELF, eEffect));
}
}
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,53 @@
// HCR v3.2.0 - Re-Added fix by Jamos to use PHB caster level rule.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S2_AnimalCom
//::////////////////////////////////////////////////////////////////////////////
/*
This spell summons a Ranger's or Druid's Animal Companion.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept 27, 2001
//::////////////////////////////////////////////////////////////////////////////
void HCR_RemoveAnimalCompanion(object oAC)
{
AssignCommand(oAC, ClearAllActions(TRUE));
DestroyObject(oAC);
string sMsg = "The animal wanders off. It is too powerful for";
sMsg += " you to keep it's loyalty for a long period of time.";
SendMessageToPC(OBJECT_SELF, sMsg);
}
//::////////////////////////////////////////////////////////////////////////////
void HCR_CheckCompanionStrength()
{
object oAC = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION);
if (GetIsObjectValid(oAC))
{
int nMCL;
int nAHD = GetHitDice(oAC);
int nDCL = GetLevelByClass(CLASS_TYPE_DRUID);
int nRCL = (GetLevelByClass(CLASS_TYPE_RANGER)/2);
if (nRCL > nDCL)
{ nMCL = nRCL; }
else
{ nMCL = nDCL; }
if ((nAHD > (nMCL+4)) || (nAHD > (nMCL*2)))
{ HCR_RemoveAnimalCompanion(oAC); }
else if (nAHD > nMCL)
{
if (nMCL == 1 && (nAHD-nMCL == 1)) { return; }
float fDelay = IntToFloat(240-((nAHD-nMCL)*60));
DelayCommand(fDelay, HCR_RemoveAnimalCompanion(oAC));
}
}
}
//::////////////////////////////////////////////////////////////////////////////
void main()
{
SummonAnimalCompanion();
if (GetLocalInt(GetModule(), "REALFAM") == TRUE)
{ HCR_CheckCompanionStrength(); }
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,39 @@
// HCR v3.2.0 - Re-Added REALFAM code.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S2_Familiar
//::////////////////////////////////////////////////////////////////////////////
/*
This spell summons an Arcane caster's Familiar.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Sept 27, 2001
//::////////////////////////////////////////////////////////////////////////////
#include "HC_Inc"
//::////////////////////////////////////////////////////////////////////////////
void main()
{
object oMod = GetModule();
if (GetLocalInt(oMod, "REALFAM"))
{
if (GetIsPC(OBJECT_SELF) &&
!GetIsDM(OBJECT_SELF) &&
!GetIsDMPossessed(OBJECT_SELF))
{
string sID = GetPlayerID(OBJECT_SELF);
if (GetLocalInt(oMod, "FAMDIED" + sID))
{
if (GetGold(OBJECT_SELF) < 100)
{
string sMsg = "You need 100 gp's to pay for the materials.";
SendMessageToPC(OBJECT_SELF, sMsg);
return;
}
AssignCommand(OBJECT_SELF, TakeGoldFromCreature(100, OBJECT_SELF, TRUE));
DeleteLocalInt(oMod, "FAMDIED" + sID);
}
}
}
SummonFamiliar();
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,248 @@
// HCR v3.2.0 - Re-Added MATERCOMP code.
//::////////////////////////////////////////////////////////////////////////////
//:: FileName: NW_S2_TurnDead
//::////////////////////////////////////////////////////////////////////////////
/*
Checks domain powers and class to determine the proper turning abilities of
the casting character.
*/
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 2, 2001
//:: Updated On: Mar 5, 2003 - For Blackguards.
//:: Updated On: Jul 15, 2003 - Georg Zoeller
//:: Updated On: Jul 24, 2003 - For Planar Turning to include turn resistance hd.
//::////////////////////////////////////////////////////////////////////////////
void main()
{
if (GetLocalInt(GetModule(), "MATERCOMP") == TRUE)
{
object oComp = GetItemPossessedBy(OBJECT_SELF, "HolySymbol");
string sMsg1 = "You must possess a holy symbol to turn undead.";
string sMsg2 = "You must equip the holy symbol to turn undead.";
string sMsg3 = " does not have a holy symbol to turn the undead with.";
int bHasEquip = FALSE;
// Determine if using the Hench System or generic henchman.
object oMaster = GetLocalObject(OBJECT_SELF, "HS_REAL_MASTER");
if (!GetIsObjectValid(oMaster))
{ oMaster = GetMaster(); }
if (GetIsPC(OBJECT_SELF) &&
!GetIsDM(OBJECT_SELF) &&
!GetIsDMPossessed(OBJECT_SELF))
{
// It is a PC casting this spell.
if (!GetIsObjectValid(oComp))
{
SendMessageToPC(OBJECT_SELF, sMsg1);
ClearAllActions();
return;
}
else
{
int i;
for (i = 0; i < 14; i++)
{
if (GetTag(GetItemInSlot(i)) == "HolySymbol")
{ bHasEquip = TRUE; }
}
if (bHasEquip == FALSE)
{
SendMessageToPC(OBJECT_SELF, sMsg2);
ClearAllActions();
return;
}
}
}
else if (GetIsObjectValid(oMaster) &&
!GetIsPC(OBJECT_SELF) &&
GetIsPC(oMaster) &&
!GetIsDM(oMaster) &&
!GetIsDMPossessed(oMaster))
{
// It is a henchman casting this spell.
if (!GetIsObjectValid(oComp))
{
SendMessageToPC(oMaster, GetName(OBJECT_SELF) + sMsg3);
ClearAllActions();
return;
}
}
}
int nClericLevel = GetLevelByClass(CLASS_TYPE_CLERIC);
int nPaladinLevel = GetLevelByClass(CLASS_TYPE_PALADIN);
int nBlackguardlevel = GetLevelByClass(CLASS_TYPE_BLACKGUARD);
int nTotalLevel = GetHitDice(OBJECT_SELF);
int nTurnLevel = nClericLevel;
int nClassLevel = nClericLevel;
// GZ: Since paladin levels stack when turning, blackguard levels should stack
// as well, but not with the paladin levels (thus else if).
if ((nBlackguardlevel - 2) > 0 && (nBlackguardlevel > nPaladinLevel))
{
nClassLevel += (nBlackguardlevel - 2);
nTurnLevel += (nBlackguardlevel - 2);
}
else if ((nPaladinLevel - 2) > 0)
{
nClassLevel += (nPaladinLevel - 2);
nTurnLevel += (nPaladinLevel - 2);
}
// Flags for bonus turning types.
int nElemental = GetHasFeat(FEAT_AIR_DOMAIN_POWER) +
GetHasFeat(FEAT_EARTH_DOMAIN_POWER) +
GetHasFeat(FEAT_FIRE_DOMAIN_POWER) +
GetHasFeat(FEAT_WATER_DOMAIN_POWER);
int nVermin = GetHasFeat(FEAT_PLANT_DOMAIN_POWER);// + GetHasFeat(FEAT_ANIMAL_COMPANION);
int nConstructs = GetHasFeat(FEAT_DESTRUCTION_DOMAIN_POWER);
int nGoodOrEvilDomain = GetHasFeat(FEAT_GOOD_DOMAIN_POWER) +
GetHasFeat(FEAT_EVIL_DOMAIN_POWER);
int nPlanar = GetHasFeat(854);
// Flag for improved turning ability.
int nSun = GetHasFeat(FEAT_SUN_DOMAIN_POWER);
// Make a turning check roll, modify if have the Sun Domain.
int nChrMod = GetAbilityModifier(ABILITY_CHARISMA);
int nTurnCheck = (d20() + nChrMod);// The roll to apply to the max HD of undead that can be turned --> nTurnLevel.
int nTurnHD = (d6(2) + nChrMod + nClassLevel);// The number of HD of undead that can be turned.
if (nSun == TRUE)
{
nTurnCheck += d4();
nTurnHD += d6();
}
// Determine the maximum HD of the undead that can be turned.
if (nTurnCheck <= 0)
{ nTurnLevel -= 4; }
else if (nTurnCheck >= 1 && nTurnCheck <= 3)
{ nTurnLevel -= 3; }
else if (nTurnCheck >= 4 && nTurnCheck <= 6)
{ nTurnLevel -= 2; }
else if (nTurnCheck >= 7 && nTurnCheck <= 9)
{ nTurnLevel -= 1; }
else if (nTurnCheck >= 10 && nTurnCheck <= 12)
{
// Stays the same.
}
else if (nTurnCheck >= 13 && nTurnCheck <= 15)
{ nTurnLevel += 1; }
else if (nTurnCheck >= 16 && nTurnCheck <= 18)
{ nTurnLevel += 2; }
else if (nTurnCheck >= 19 && nTurnCheck <= 21)
{ nTurnLevel += 3; }
else if (nTurnCheck >= 22)
{ nTurnLevel += 4; }
// Gets all creatures in a 20m radius around the caster and turns them or not.
// If the creatures HD are 1/2 or less of the nClassLevel then the creature is
// destroyed.
int nCnt = 1;
int nHD, nRacial, nHDCount, bValid, nDamage;
nHDCount = 0;
effect eVis = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
effect eVisTurn = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR);
effect eDamage;
effect eTurned = EffectTurned();
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
effect eLink = EffectLinkEffects(eVisTurn, eTurned);
eLink = EffectLinkEffects(eLink, eDur);
effect eDeath = SupernaturalEffect(EffectDeath(TRUE));
effect eImpactVis = EffectVisualEffect(VFX_FNF_LOS_HOLY_30);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpactVis, GetLocation(OBJECT_SELF));
// Get nearest enemy within 20m. (60ft)
// Why are you using GetNearest instead of GetFirstObjectInShape?
object oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
while (GetIsObjectValid(oTarget) && nHDCount < nTurnHD && GetDistanceToObject(oTarget) <= 20.0)
{
if (!GetIsFriend(oTarget))
{
nRacial = GetRacialType(oTarget);
if (nRacial == RACIAL_TYPE_OUTSIDER )
{
// Planar turning decreases spell resistance against turning by 1/2.
if (nPlanar)
{ nHD = GetHitDice(oTarget) + (GetSpellResistance(oTarget)/2) + GetTurnResistanceHD(oTarget); }
else
{ nHD = GetHitDice(oTarget) + (GetSpellResistance(oTarget) + GetTurnResistanceHD(oTarget)); }
}
else// (full turn resistance)
{ nHD = GetHitDice(oTarget) + GetTurnResistanceHD(oTarget); }
if (nHD <= nTurnLevel && nHD <= (nTurnHD - nHDCount))
{
// Check the various domain turning types.
if (nRacial == RACIAL_TYPE_UNDEAD)
{ bValid = TRUE; }
else if (nRacial == RACIAL_TYPE_VERMIN && nVermin > 0)
{ bValid = TRUE; }
else if (nRacial == RACIAL_TYPE_ELEMENTAL && nElemental > 0)
{ bValid = TRUE; }
else if (nRacial == RACIAL_TYPE_CONSTRUCT && nConstructs > 0)
{
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELLABILITY_TURN_UNDEAD));
nDamage = d3(nTurnLevel);
eDamage = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
nHDCount += nHD;
}
else if (nRacial == RACIAL_TYPE_OUTSIDER && (nGoodOrEvilDomain+nPlanar > 0) )
{ bValid = TRUE; }
else if (GetIsObjectValid(GetItemPossessedBy(oTarget, "x2_gauntletlich")) == TRUE)
{
// * If wearing gauntlets of the lich, then target can be turned.
if (GetTag(GetItemInSlot(INVENTORY_SLOT_ARMS)) == "x2_gauntletlich")
{ bValid = TRUE; }
}
// Apply results of the turn.
if (bValid == TRUE)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
if (nPlanar > 0 && nRacial == RACIAL_TYPE_OUTSIDER)
{
effect ePlane = EffectVisualEffect(VFX_IMP_DIVINE_STRIKE_HOLY);
ApplyEffectToObject(DURATION_TYPE_INSTANT, ePlane, oTarget);
}
if ((nClassLevel/2) >= nHD)
{
if (nPlanar > 0 && nRacial == RACIAL_TYPE_OUTSIDER)
{
effect ePlane2 = EffectVisualEffect(VFX_IMP_UNSUMMON);
ApplyEffectToObject(DURATION_TYPE_INSTANT, ePlane2, oTarget);
}
//effect ePlane2 = EffectVisualEffect(VFX_IMP_DIVINE_STRIKE_HOLY);
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELLABILITY_TURN_UNDEAD));
// Destroy the target.
DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oTarget));
}
else
{
// Turn the target.
// Fire cast spell at event for the specified target.
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELLABILITY_TURN_UNDEAD));
AssignCommand(oTarget, ActionMoveAwayFromObject(OBJECT_SELF, TRUE));
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(nClassLevel + 5));
}
nHDCount += nHD;
}
}
bValid = FALSE;
}
nCnt++;
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, OBJECT_SELF, nCnt, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
}
}
//::////////////////////////////////////////////////////////////////////////////

View File

@@ -36,7 +36,18 @@ string Get2DACache(string s2DA, string sColumn, int nRow)
s2DA = GetStringLowerCase(s2DA);
sColumn = GetStringLowerCase(sColumn);
/*//get the chest that contains the cache
string s = Get2DAString(s2DA, sColumn, nRow);
return s == "****" ? "" : s;
}
/*string Get2DACache(string s2DA, string sColumn, int nRow)
{
//lower case the 2da and column
s2DA = GetStringLowerCase(s2DA);
sColumn = GetStringLowerCase(sColumn);
//get the chest that contains the cache
object oCacheWP = GetObjectByTag("Bioware2DACache");
//if no chest, use HEARTOFCHAOS in limbo as a location to make a new one
if (!GetIsObjectValid(oCacheWP))
@@ -124,10 +135,10 @@ string Get2DACache(string s2DA, string sColumn, int nRow)
(s == "" ? "****" : s) ); // this sets the stored string to "****" if s is an empty string (else stores s)
if(DEBUG_GET2DACACHE) DoDebug("Get2DACache: Missing from cache: " + s2DA + "|" + sColumn + "|" + IntToString(nRow));
}
//if(DEBUG_GET2DACACHE) PrintString("Get2DACache: Returned value is '" + s + "'");*/
//if(DEBUG_GET2DACACHE) PrintString("Get2DACache: Returned value is '" + s + "'");
string s = Get2DAString(s2DA, sColumn, nRow);
return s == "****" ? "" : s;
}
}*/
string GetBiowareDBName()
{

View File

@@ -18,16 +18,100 @@
//////////////////////////////////////////////////
/* Include section */
//////////////////////////////////////////////////
#include "utl_i_sqlocals"
#include "inc_2dacache"
void PRC_BuildSpellIDIndex();
//////////////////////////////////////////////////
/* Function defintions */
//////////////////////////////////////////////////
/**
* Build the SpellID ? RealSpellID index for all classes
* Stores results directly in SQLite using utl_i_sqlocals.
*/
void PRC_BuildSpellIDIndex()
{
object oMod = GetModule();
int nRow;
int nFileEnd;
string s2DA;
string sSpellID, sRealSpellID;
int nSpellID, nRealSpellID;
int nIndex = 0;
while (nIndex <= 30)
{
switch(nIndex)
{
case 0: s2DA = "cls_psipw_psion"; break;
case 1: s2DA = "cls_psipw_psywar"; break;
case 2: s2DA = "cls_psipw_wilder"; break;
case 3: s2DA = "cls_psipw_foz"; break;
case 4: s2DA = "cls_psipw_warmnd"; break;
case 5: s2DA = "cls_true_utter"; break;
case 6: s2DA = "cls_move_crusdr"; break;
case 7: s2DA = "cls_move_swdsge"; break;
case 8: s2DA = "cls_move_warbld"; break;
case 9: s2DA = "cls_inv_dfa"; break;
case 10: s2DA = "cls_inv_drgshm"; break;
case 11: s2DA = "cls_inv_warlok"; break;
case 12: s2DA = "cls_spell_archv"; break;
case 13: s2DA = "cls_spell_bard"; break;
case 14: s2DA = "cls_spell_beguil"; break;
case 15: s2DA = "cls_spell_dnecro"; break;
case 16: s2DA = "cls_spell_duskbl"; break;
case 17: s2DA = "cls_spell_favsol"; break;
case 18: s2DA = "cls_spell_harper"; break;
case 19: s2DA = "cls_spell_hexbl"; break;
case 20: s2DA = "cls_spell_justww"; break;
case 21: s2DA = "cls_spell_sorc"; break;
case 22: s2DA = "cls_spell_schord"; break;
case 23: s2DA = "cls_spell_suel"; break;
case 24: s2DA = "cls_spell_vigil"; break;
case 25: s2DA = "cls_spell_wrmage"; break;
case 26: s2DA = "cls_spell_kngtwv"; break;
case 27: s2DA = "cls_psipw_psyrog"; break;
case 28: s2DA = "cls_myst_shdcst"; break;
case 29: s2DA = "cls_myst_shdsmt"; break;
case 30: s2DA = "cls_spell_sharss"; break;
}
nRow = 0;
nFileEnd = PRCGetDynamicFileEnd(s2DA);
while (nRow < nFileEnd)
{
sSpellID = Get2DACache(s2DA, "SpellID", nRow);
sRealSpellID = Get2DACache(s2DA, "RealSpellID", nRow);
if (sSpellID != "" && sSpellID != "****" && sRealSpellID != "" && sRealSpellID != "****")
{
nSpellID = StringToInt(sSpellID);
nRealSpellID = StringToInt(sRealSpellID);
string sKey = "PRC_GetRowFromSpellID_" + IntToString(nSpellID);
SetLocalInt(oMod, sKey, nRealSpellID);
if(DEBUG) DoDebug("PRC_BuildSpellIDIndex: Adding SpellID " + sSpellID + " -> RealSpellID " + sRealSpellID);
}
nRow++;
}
nIndex++;
}
if (DEBUG) DoDebug("PRC_BuildSpellIDIndex: SpellID -> RealSpellID index cached in SQLite.");
}
void Cache_Done()
{
WriteTimestampedLogEntry("2da caching complete");
// Build the persistent SpellID ? Row index mapping
PRC_BuildSpellIDIndex();
}
void Cache_Class_Feat(int nClass, int nRow = 0)
@@ -360,3 +444,5 @@ void Cache_2da_data()
Cache_Appearance();
}
//:: test void
//:: void main (){}

File diff suppressed because it is too large Load Diff

View File

@@ -47,77 +47,78 @@ const string MES_CONTINGENCIES_YES2 = "The contingencies must expire to allo
*/
//Primogenitors SpellID constants
const int SPELL_EPIC_A_STONE = 0;//4007;
const int SPELL_EPIC_ACHHEEL = 1;//4000;
const int SPELL_EPIC_AL_MART = 2;//4002;
const int SPELL_EPIC_ALLHOPE = 3;//4001;
const int SPELL_EPIC_ANARCHY = 4;//4003;
const int SPELL_EPIC_ANBLAST = 5;//4004;
const int SPELL_EPIC_ANBLIZZ = 6;//4005;
const int SPELL_EPIC_ARMY_UN = 7;//4006;
const int SPELL_EPIC_BATTLEB = 999;//4008;
const int SPELL_EPIC_CELCOUN = 8;//4009;
const int SPELL_EPIC_CHAMP_V = 9;//4010;
const int SPELL_EPIC_CON_RES =10;//4011;
const int SPELL_EPIC_CON_REU =11;//4012;
const int SPELL_EPIC_DEADEYE =12;//4013;
const int SPELL_EPIC_DIREWIN =13;//4015;
const int SPELL_EPIC_DREAMSC =14;//4017;
const int SPELL_EPIC_DRG_KNI =15;//4016;
const int SPELL_EPIC_DTHMARK =1000;//4014;
const int SPELL_EPIC_DULBLAD =16;//4018;
const int SPELL_EPIC_DWEO_TH =17;//4019;
const int SPELL_EPIC_ENSLAVE =18;//4020;
const int SPELL_EPIC_EP_M_AR =19;//4021;
const int SPELL_EPIC_EP_RPLS =20;//4022;
const int SPELL_EPIC_EP_SP_R =21;//4023;
const int SPELL_EPIC_EP_WARD =22;//4024;
const int SPELL_EPIC_ET_FREE =23;//4025;
const int SPELL_EPIC_FIEND_W =24;//4026;
const int SPELL_EPIC_FLEETNS =25;//4027;
const int SPELL_EPIC_GEMCAGE =26;//4028;
const int SPELL_EPIC_GODSMIT =27;//4029;
const int SPELL_EPIC_GR_RUIN =28;//4030;
const int SPELL_EPIC_GR_SP_RE=29;//4031;
const int SPELL_EPIC_GR_TIME =30;//4032;
const int SPELL_EPIC_HELBALL =31;//4034;
const int SPELL_EPIC_HELSEND =1001;//4033;
const int SPELL_EPIC_HERCALL =32;//4035;
const int SPELL_EPIC_HERCEMP =33;//4036;
const int SPELL_EPIC_IMPENET =34;//4037;
const int SPELL_EPIC_LEECH_F =35;//4038;
const int SPELL_EPIC_LEG_ART =1002;//4039;
const int SPELL_EPIC_LIFE_FT =1003;//4040;
const int SPELL_EPIC_MAGMA_B =36;//4041;
const int SPELL_EPIC_MASSPEN =37;//4042;
const int SPELL_EPIC_MORI = 38;//4043;
const int SPELL_EPIC_MUMDUST =39;//4044;
const int SPELL_EPIC_NAILSKY =40;//4045;
const int SPELL_EPIC_NIGHTSU =1004;//4046;
const int SPELL_EPIC_ORDER_R =41;//4047;
const int SPELL_EPIC_PATHS_B =42;//4048;
const int SPELL_EPIC_PEERPEN =43;//4049;
const int SPELL_EPIC_PESTIL = 44;//4050;
const int SPELL_EPIC_PIOUS_P =45;//4051;
const int SPELL_EPIC_PLANCEL =46;//4052;
const int SPELL_EPIC_PSION_S =47;//4053;
const int SPELL_EPIC_RAINFIR =48;//4054;
const int SPELL_EPIC_RISEN_R =1005;//4055;
const int SPELL_EPIC_RUINN = 49;//4056; //NON_STANDARD
const int SPELL_EPIC_SINGSUN =50;//4057;
const int SPELL_EPIC_SP_WORM =51;//4058;
const int SPELL_EPIC_STORM_M =52;//4059;
const int SPELL_EPIC_SUMABER =53;//4060;
const int SPELL_EPIC_SUP_DIS =54;//4061;
const int SPELL_EPIC_SYMRUST =1006;//4062;
const int SPELL_EPIC_THEWITH =55;//4063;
const int SPELL_EPIC_TOLO_KW =56;//4064;
const int SPELL_EPIC_TRANVIT =57;//4065;
const int SPELL_EPIC_TWINF = 58;//4066;
const int SPELL_EPIC_UNHOLYD =59;//4067;
const int SPELL_EPIC_UNIMPIN =60;//4068;
const int SPELL_EPIC_UNSEENW =61;//4069;
const int SPELL_EPIC_WHIP_SH =62;//4070;
const int SPELL_EPIC_A_STONE = 0;//4007;
const int SPELL_EPIC_ACHHEEL = 1;//4000;
const int SPELL_EPIC_AL_MART = 2;//4002;
const int SPELL_EPIC_ALLHOPE = 3;//4001;
const int SPELL_EPIC_ANARCHY = 4;//4003;
const int SPELL_EPIC_ANBLAST = 5;//4004;
const int SPELL_EPIC_ANBLIZZ = 6;//4005;
const int SPELL_EPIC_ARMY_UN = 7;//4006;
const int SPELL_EPIC_BATTLEB = 999;//4008;
const int SPELL_EPIC_CELCOUN = 8;//4009;
const int SPELL_EPIC_CHAMP_V = 9;//4010;
const int SPELL_EPIC_CON_RES = 10;//4011;
const int SPELL_EPIC_CON_REU = 11;//4012;
const int SPELL_EPIC_DEADEYE = 12;//4013;
const int SPELL_EPIC_DIREWIN = 13;//4015;
const int SPELL_EPIC_DREAMSC = 14;//4017;
const int SPELL_EPIC_DRG_KNI = 15;//4016;
const int SPELL_EPIC_DTHMARK = 1000;//4014;
const int SPELL_EPIC_DULBLAD = 16;//4018;
const int SPELL_EPIC_DWEO_TH = 17;//4019;
const int SPELL_EPIC_ENSLAVE = 18;//4020;
const int SPELL_EPIC_EP_M_AR = 19;//4021;
const int SPELL_EPIC_EP_RPLS = 20;//4022;
const int SPELL_EPIC_EP_SP_R = 21;//4023;
const int SPELL_EPIC_EP_WARD = 22;//4024;
const int SPELL_EPIC_ET_FREE = 23;//4025;
const int SPELL_EPIC_FIEND_W = 24;//4026;
const int SPELL_EPIC_FLEETNS = 25;//4027;
const int SPELL_EPIC_GEMCAGE = 26;//4028;
const int SPELL_EPIC_GODSMIT = 27;//4029;
const int SPELL_EPIC_GR_RUIN = 28;//4030;
const int SPELL_EPIC_GR_SP_RE = 29;//4031;
const int SPELL_EPIC_GR_TIME = 30;//4032;
const int SPELL_EPIC_HELBALL = 31;//4034;
const int SPELL_EPIC_HELSEND = 1001;//4033;
const int SPELL_EPIC_HERCALL = 32;//4035;
const int SPELL_EPIC_HERCEMP = 33;//4036;
const int SPELL_EPIC_IMPENET = 34;//4037;
const int SPELL_EPIC_LEECH_F = 35;//4038;
const int SPELL_EPIC_LEG_ART = 1002;//4039;
const int SPELL_EPIC_LIFE_FT = 1003;//4040;
const int SPELL_EPIC_MAGMA_B = 36;//4041;
const int SPELL_EPIC_MASSPEN = 37;//4042;
const int SPELL_EPIC_MORI = 38;//4043;
const int SPELL_EPIC_MUMDUST = 39;//4044;
const int SPELL_EPIC_NAILSKY = 40;//4045;
const int SPELL_EPIC_NIGHTSU = 1004;//4046;
const int SPELL_EPIC_ORDER_R = 41;//4047;
const int SPELL_EPIC_PATHS_B = 42;//4048;
const int SPELL_EPIC_PEERPEN = 43;//4049;
const int SPELL_EPIC_PESTIL = 44;//4050;
const int SPELL_EPIC_PIOUS_P = 45;//4051;
const int SPELL_EPIC_PLANCEL = 46;//4052;
const int SPELL_EPIC_PSION_S = 47;//4053;
const int SPELL_EPIC_RAINFIR = 48;//4054;
//const int SPELL_EPIC_RISEN_R =1005;//4055;
const int SPELL_EPIC_RISEN_R = 49;//4055;
const int SPELL_EPIC_RUINN = 50;//4056; //NON_STANDARD
const int SPELL_EPIC_SINGSUN = 51;//4057;
const int SPELL_EPIC_SP_WORM = 52;//4058;
const int SPELL_EPIC_STORM_M = 53;//4059;
const int SPELL_EPIC_SUMABER = 54;//4060;
const int SPELL_EPIC_SUP_DIS = 55;//4061;
const int SPELL_EPIC_SYMRUST = 1006;//4062;
const int SPELL_EPIC_THEWITH = 56;//4063;
const int SPELL_EPIC_TOLO_KW = 57;//4064;
const int SPELL_EPIC_TRANVIT = 58;//4065;
const int SPELL_EPIC_TWINF = 59;//4066;
const int SPELL_EPIC_UNHOLYD = 60;//4067;
const int SPELL_EPIC_UNIMPIN = 61;//4068;
const int SPELL_EPIC_UNSEENW = 62;//4069;
const int SPELL_EPIC_WHIP_SH = 63;//4070;
/*

View File

@@ -246,7 +246,7 @@ int GetSpellFromAbrev(string sAbrev)
sAbrev = GetStringLowerCase(sAbrev);
if(GetStringLeft(sAbrev, 8) == "epic_sp_")
sAbrev = GetStringRight(sAbrev, GetStringLength(sAbrev)-8);
if(DEBUG) DoDebug("sAbrew to check vs: " + sAbrev);
if(DEBUG) DoDebug("sAbrev to check vs: " + sAbrev);
int i = 0;
string sLabel = GetStringLowerCase(Get2DACache("epicspells", "LABEL", i));
while(sLabel != "")

View File

@@ -104,8 +104,81 @@ string GetAMSDefinitionFileName(int nClass);
//////////////////////////////////////////////////
/* Internal functions */
//////////////////////////////////////////////////
object _inc_lookups_GetCacheObject(string sTag)
{
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Looking for waypoint with tag: " + sTag);
object oWP = GetObjectByTag(sTag);
if(GetIsObjectValid(oWP))
{
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Found existing waypoint: " + sTag);
return oWP;
}
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Waypoint not found, creating new token...");
object oChest = GetObjectByTag("Bioware2DACache");
if(!GetIsObjectValid(oChest))
{
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Bioware2DACache object not found, creating near HEARTOFCHAOS...");
oChest = CreateObject(OBJECT_TYPE_CREATURE, "prc_2da_cache",
GetLocation(GetObjectByTag("HEARTOFCHAOS")), FALSE, "Bioware2DACache");
}
if(!GetIsObjectValid(oChest))
{
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Failed, creating Bioware2DACache at starting location...");
oChest = CreateObject(OBJECT_TYPE_CREATURE, "prc_2da_cache",
GetStartingLocation(), FALSE, "Bioware2DACache");
}
if(!GetIsObjectValid(oChest))
{
DoDebug("_inc_lookups_GetCacheObject: ERROR - Could not create Bioware2DACache!");
return OBJECT_INVALID;
}
int nContainer = 0;
string sContainerName = "Bio2DACacheTokenContainer_Lkup_";
object oContainer = GetObjectByTag(sContainerName + IntToString(nContainer));
if(GetIsObjectValid(oContainer))
{
nContainer = GetLocalInt(oContainer, "ContainerCount");
oContainer = GetObjectByTag(sContainerName + IntToString(nContainer));
if(GetLocalInt(oContainer, "NumTokensInside") >= 34)
{
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Container full, creating new container...");
oContainer = OBJECT_INVALID;
++nContainer;
}
}
if(!GetIsObjectValid(oContainer))
{
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Creating container: " + sContainerName + IntToString(nContainer));
oContainer = CreateObject(OBJECT_TYPE_ITEM, "nw_it_contain001", GetLocation(oChest), FALSE, sContainerName + IntToString(nContainer));
DestroyObject(oContainer);
oContainer = CopyObject(oContainer, GetLocation(oChest), oChest, sContainerName + IntToString(nContainer));
if(nContainer)
SetLocalInt(GetObjectByTag(sContainerName + "0"), "ContainerCount", nContainer);
}
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Creating token: " + sTag);
oWP = CreateItemOnObject("hidetoken", oContainer, 1, sTag);
SetLocalInt(oContainer, "NumTokensInside", GetLocalInt(oContainer, "NumTokensInside") + 1);
if(!GetIsObjectValid(oWP))
{
DoDebug("_inc_lookups_GetCacheObject: ERROR - Failed to create lookup storage token for " + sTag);
return OBJECT_INVALID;
}
if(DEBUG) DoDebug("_inc_lookups_GetCacheObject: Successfully created token: " + sTag);
return oWP;
}
/* object _inc_lookups_GetCacheObject(string sTag)
{
object oWP = GetObjectByTag(sTag);
if(!GetIsObjectValid(oWP))
@@ -171,6 +244,7 @@ object _inc_lookups_GetCacheObject(string sTag)
return oWP;
}
*/
void SetLkupStage(int nStage, object oModule, int nClass, string sFile)
{
@@ -242,7 +316,7 @@ void SetupLookupStage(object oMod, int n)
case 11: SetLkupStage(n, oMod, CLASS_TYPE_DRAGON_SHAMAN, "cls_inv_drgshm"); break;
case 12: SetLkupStage(n, oMod, CLASS_TYPE_WARLOCK, "cls_inv_warlok"); break;
case 13: SetLkupStage(n, oMod, CLASS_TYPE_ARCHIVIST, "cls_spell_archv"); break;
case 14: SetLkupStage(n, oMod, CLASS_TYPE_ASSASSIN, "cls_spell_asasin"); break;
//case 14: SetLkupStage(n, oMod, CLASS_TYPE_ASSASSIN, "cls_spell_asasin"); break;
case 15: SetLkupStage(n, oMod, CLASS_TYPE_BARD, "cls_spell_bard"); break;
case 16: SetLkupStage(n, oMod, CLASS_TYPE_BEGUILER, "cls_spell_beguil"); break;
case 17: SetLkupStage(n, oMod, CLASS_TYPE_DREAD_NECROMANCER, "cls_spell_dnecro"); break;
@@ -524,14 +598,50 @@ int GetClassFeatFromPower(int nPowerID, int nClass)
int SpellToSpellbookID(int nSpell)
{
// Fetch the lookup object
object oWP = GetObjectByTag("PRC_GetRowFromSpellID");
int nOutSpellID = GetLocalInt(oWP, /*"PRC_GetRowFromSpellID_" + */IntToString(nSpell));
// Sanity check for the object
if(oWP == OBJECT_INVALID)
{
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: Lookup object PRC_GetRowFromSpellID is INVALID!");
return -1;
}
else
{
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: Object valid: TRUE");
}
// Attempt to retrieve the local int for this spell
string sKey = IntToString(nSpell);
int nOutSpellID = GetLocalInt(oWP, sKey);
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: Looking up key: " + sKey);
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: Retrieved value: " + IntToString(nOutSpellID));
// Handle missing values
if(nOutSpellID == 0)
{
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: No value found for spell, returning -1");
nOutSpellID = -1;
//if(DEBUG) DoDebug("SpellToSpellbookID(" + IntToString(nSpell) + ", " + sFile + ") = " + IntToString(nOutSpellID));
}
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: Final nOutSpellID: " + IntToString(nOutSpellID));
return nOutSpellID;
}
/* int SpellToSpellbookID(int nSpell)
{
object oWP = GetObjectByTag("PRC_GetRowFromSpellID");
int nOutSpellID = GetLocalInt(oWP, /*"PRC_GetRowFromSpellID_" + *///IntToString(nSpell));
/* if(nOutSpellID == 0)
nOutSpellID = -1;
if(DEBUG) DoDebug("inc_lookup >> SpellToSpellbookID: (nSpell: " + IntToString(nSpell) + ") = nOutSpellID: " + IntToString(nOutSpellID));
return nOutSpellID;
} */
int RealSpellToSpellbookID(int nClass, int nSpell)
{
object oWP = GetObjectByTag("PRC_GetRowFromRealSpellID");

View File

@@ -8,7 +8,7 @@ Make cls_spcr_*.2da
Make blank cls_spell_*.2da
Add cls_spgn_*.2da to classes.2da
Add class entry in prc_classes.2da
Add the spellbook feat (#1999) to cls_feat_*.2da at the appropriate level
Add the spellbook feat (#1999) to cls_feat_*.2da at the appropriate level (not needed for NWN:EE)
Add class to PRCGetSpellSaveDC() in prc_add_spell_dc
Add class to GetSpellbookTypeForClass() below
Add class to GetAbilityScoreForClass() below
@@ -119,6 +119,7 @@ int GetSpellbookTypeForClass(int nClass)
switch(nClass)
{
case CLASS_TYPE_ARCHIVIST:
case CLASS_TYPE_ASSASSIN:
case CLASS_TYPE_BLACKGUARD:
case CLASS_TYPE_BLIGHTER:
case CLASS_TYPE_CLERIC:
@@ -141,7 +142,6 @@ int GetSpellbookTypeForClass(int nClass)
case CLASS_TYPE_VIGILANT:
case CLASS_TYPE_WIZARD:
return SPELLBOOK_TYPE_PREPARED;
case CLASS_TYPE_ASSASSIN:
case CLASS_TYPE_BARD:
case CLASS_TYPE_BEGUILER:
case CLASS_TYPE_CELEBRANT_SHARESS:
@@ -559,7 +559,7 @@ int bKnowsAllClassSpells(int nClass)
{
//case CLASS_TYPE_WIZARD:
case CLASS_TYPE_ARCHIVIST:
case CLASS_TYPE_ASSASSIN:
//case CLASS_TYPE_ASSASSIN:
case CLASS_TYPE_BARD:
case CLASS_TYPE_CELEBRANT_SHARESS:
case CLASS_TYPE_CULTIST_SHATTERED_PEAK:
@@ -580,7 +580,79 @@ int bKnowsAllClassSpells(int nClass)
return TRUE;
}
int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
{
// If the character doesn't have any spell slots available on for this level, it can't know any spells of that level either
if(!GetSlotCount(nLevel, nSpellLevel, GetAbilityScoreForClass(nClass, oPC), nClass))
{
if(DEBUG) DoDebug("GetSpellKnownMaxCount: No slots available for " + IntToString(nClass) + " level " + IntToString(nLevel) + " circle " + IntToString(nSpellLevel));
return 0;
}
int nKnown;
string sFile = Get2DACache("classes", "SpellKnownTable", nClass);
string sKnown = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1);
if(DEBUG)
{
DoDebug("GetSpellKnownMaxCount Details:");
DoDebug("- Class: " + IntToString(nClass));
DoDebug("- Passed Level: " + IntToString(nLevel));
DoDebug("- Base Class Level: " + IntToString(GetLevelByClass(nClass, oPC)));
DoDebug("- Effective Level: " + IntToString(GetSpellslotLevel(nClass, oPC)));
DoDebug("- Spell Level: " + IntToString(nSpellLevel));
DoDebug("- SpellKnownTable: " + sFile);
DoDebug("- MaxKnown from 2DA: " + sKnown);
}
if(sKnown == "")
{
nKnown = -1;
if(DEBUG) DoDebug("GetSpellKnownMaxCount: Problem getting known numbers");
}
else
nKnown = StringToInt(sKnown);
if(nKnown == -1)
return 0;
// COMPLETELY REWROTE THIS SECTION
// Bard and Sorcerer logic for prestige class advancement
if(nClass == CLASS_TYPE_SORCERER || nClass == CLASS_TYPE_BARD)
{
int baseClassLevel = GetLevelByClass(nClass, oPC);
int effectiveLevel = GetSpellslotLevel(nClass, oPC);
// Debug the values we're checking
if(DEBUG)
{
DoDebug("Spont caster check - Base level: " + IntToString(baseClassLevel) +
", Effective level: " + IntToString(effectiveLevel));
}
// If they have prestige class advancement OR special feats, they should get spells
if(effectiveLevel > baseClassLevel ||
GetHasFeat(FEAT_DRACONIC_GRACE, oPC) ||
GetHasFeat(FEAT_DRACONIC_BREATH, oPC))
{
// Allow them to get spells - do nothing here, return nKnown at the end
if(DEBUG) DoDebug("Spontaneous caster eligible for new spells");
}
else
{
// No advancement, no special feats - no new spells
if(DEBUG) DoDebug("Spontaneous caster NOT eligible for new spells");
return 0;
}
}
if(DEBUG) DoDebug("Final spell known count: " + IntToString(nKnown));
return nKnown;
}
/* int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
{
// If the character doesn't have any spell slots available on for this level, it can't know any spells of that level either
// @todo Check rules. There might be cases where this doesn't hold
@@ -588,22 +660,9 @@ int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
return 0;
int nKnown;
string sFile;
// Bioware casters use their classes.2da-specified tables
/*if( nClass == CLASS_TYPE_WIZARD
|| nClass == CLASS_TYPE_SORCERER
|| nClass == CLASS_TYPE_BARD
|| nClass == CLASS_TYPE_CLERIC
|| nClass == CLASS_TYPE_DRUID
|| nClass == CLASS_TYPE_PALADIN
|| nClass == CLASS_TYPE_RANGER)
{*/
sFile = Get2DACache("classes", "SpellKnownTable", nClass);
/*}
else
{
sFile = Get2DACache("classes", "FeatsTable", nClass);
sFile = "cls_spkn" + GetStringRight(sFile, GetStringLength(sFile) - 8); // Hardcoded the cls_ part. It's not as if any class uses some other prefix - Ornedan, 20061231
}*/
sFile = Get2DACache("classes", "SpellKnownTable", nClass);
string sKnown = Get2DACache(sFile, "SpellLevel" + IntToString(nSpellLevel), nLevel - 1);
if(DEBUG) DoDebug("GetSpellKnownMaxCount(" + IntToString(nLevel) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ", " + GetName(oPC) + ") = " + sKnown);
@@ -626,6 +685,7 @@ int GetSpellKnownMaxCount(int nLevel, int nSpellLevel, int nClass, object oPC)
}
return nKnown;
}
*/
int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass)
{
@@ -693,6 +753,44 @@ int GetSpellKnownCurrentCount(object oPC, int nSpellLevel, int nClass)
}
int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass)
{
// Get the lookup token created by MakeSpellbookLevelLoop()
string sTag = "SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel);
object oCache = GetObjectByTag(sTag);
if(!GetIsObjectValid(oCache))
{
if(DEBUG) DoDebug("GetSpellUnknownCurrentCount: " + sTag + " is not valid");
// Add code to create the missing lookup object
if(DEBUG) DoDebug("Attempting to create missing spell lookup token");
ExecuteScript("prc_create_spellb", oPC);
// Try again after creating it
oCache = GetObjectByTag(sTag);
if(!GetIsObjectValid(oCache))
{
if(DEBUG) DoDebug("Still couldn't create spell lookup token");
return 0;
}
else
{
if(DEBUG) DoDebug("Successfully created spell lookup token");
}
}
// Read the total number of spells on the given level and determine how many are already known
int nTotal = array_get_size(oCache, "Lkup");
int nKnown = GetSpellKnownCurrentCount(oPC, nSpellLevel, nClass);
int nUnknown = nTotal - nKnown;
if(DEBUG) DoDebug("GetSpellUnknownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ") = " + IntToString(nUnknown));
if(DEBUG) DoDebug(" Total spells in lookup: " + IntToString(nTotal) + ", Known spells: " + IntToString(nKnown));
return nUnknown;
}
/* int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass)
{
// Get the lookup token created by MakeSpellbookLevelLoop()
string sTag = "SpellLvl_" + IntToString(nClass) + "_Level_" + IntToString(nSpellLevel);
@@ -709,7 +807,7 @@ int GetSpellUnknownCurrentCount(object oPC, int nSpellLevel, int nClass)
if(DEBUG) DoDebug("GetSpellUnknownCurrentCount(" + GetName(oPC) + ", " + IntToString(nSpellLevel) + ", " + IntToString(nClass) + ") = " + IntToString(nUnknown));
return nUnknown;
}
} */
void AddSpellUse(object oPC, int nSpellbookID, int nClass, string sFile, string sArrayName, int nSpellbookType, object oSkin, int nFeatID, int nIPFeatID, string sIDX = "")
{
@@ -850,7 +948,7 @@ void SetupSpells(object oPC, int nClass)
int nAbility = GetAbilityScoreForClass(nClass, oPC);
int nSpellbookType = GetSpellbookTypeForClass(nClass);
if(DEBUG) DoDebug("SetupSpells\n"
if(DEBUG) DoDebug("SetupSpells()\n"
+ "nClass = " + IntToString(nClass) + "\n"
+ "nSpellslotLevel = " + IntToString(nLevel) + "\n"
+ "nAbility = " + IntToString(nAbility) + "\n"
@@ -1178,7 +1276,7 @@ void CastSpontaneousSpell(int nClass, int bInstantSpell = FALSE)
else if(GetLocalInt(OBJECT_SELF, "PRC_metamagic_state") == 1)
SetLocalInt(OBJECT_SELF, "MetamagicFeatAdjust", 0);
}
if (DEBUG) DoDebug("CastSpontaneousSpell(): nSpellLevel is: "+IntToString(nSpellLevel)+".");
CheckSpontSlots(nClass, nSpellID, nSpellLevel);
if(GetLocalInt(OBJECT_SELF, "NSB_Cast"))
ActionDoCommand(CheckSpontSlots(nClass, nSpellID, nSpellLevel, TRUE));
@@ -1330,6 +1428,8 @@ void NewSpellbookSpell(int nClass, int nSpellbookType, int nMetamagic = METAMAGI
string sFile = GetFileForClass(nClass);
int nSpellLevel = StringToInt(Get2DACache(sFile, "Level", nSpellbookID));
if (DEBUG) DoDebug("inc_newspellbook >> NewSpellbookSpell(): nSpellbookType is: "+IntToString(nSpellbookType)+".");
// Make sure the caster has uses of this spell remaining
// 2009-9-20: Add metamagic feat abilities. -N-S
@@ -1371,13 +1471,14 @@ void NewSpellbookSpell(int nClass, int nSpellbookType, int nMetamagic = METAMAGI
else if(nSpellLevel > 9)//now test the spell level
{
nMetamagic = METAMAGIC_NONE;
ActionDoCommand(SendMessageToPC(oPC, "Modified spell level is to high! Casting spell without metamagic"));
ActionDoCommand(SendMessageToPC(oPC, "Modified spell level is too high! Casting spell without metamagic"));
nSpellLevel = nSpellSlotLevel;
}
else if(GetLocalInt(oPC, "PRC_metamagic_state") == 1)
SetLocalInt(oPC, "MetamagicFeatAdjust", 0);
}
if (DEBUG) DoDebug("inc_newspellbook >> NewSpellbookSpell(): nSpellLevel is: "+IntToString(nSpellLevel)+".");
CheckSpontSlots(nClass, nSpellID, nSpellLevel);
if(GetLocalInt(oPC, "NSB_Cast"))
ActionDoCommand(CheckSpontSlots(nClass, nSpellID, nSpellLevel, TRUE));
@@ -1460,7 +1561,7 @@ void CheckPrepSlots(int nClass, int nSpellID, int nSpellbookID, int bIsAction =
{
DeleteLocalInt(OBJECT_SELF, "NSB_Cast");
int nCount = persistant_array_get_int(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass), nSpellbookID);
if(DEBUG) DoDebug("NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(nSpellbookID) + "] = " + IntToString(nCount));
if(DEBUG) DoDebug("NewSpellbookSpell >> CheckPrepSlots: NewSpellbookMem_" + IntToString(nClass) + "[SpellbookID: " + IntToString(nSpellbookID) + "] = " + IntToString(nCount));
if(nCount < 1)
{
string sSpellName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
@@ -1486,7 +1587,7 @@ void CheckSpontSlots(int nClass, int nSpellID, int nSpellSlotLevel, int bIsActio
{
DeleteLocalInt(OBJECT_SELF, "NSB_Cast");
int nCount = persistant_array_get_int(OBJECT_SELF, "NewSpellbookMem_" + IntToString(nClass), nSpellSlotLevel);
if(DEBUG) DoDebug("NewSpellbookSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(nSpellSlotLevel) + "] = " + IntToString(nCount));
if(DEBUG) DoDebug("NewSpellbookSpell >> CheckSpontSlots: NewSpellbookMem_" + IntToString(nClass) + "[SpellSlotLevel: " + IntToString(nSpellSlotLevel) + "] = " + IntToString(nCount));
if(nCount < 1)
{
// "You have no castings of spells of level " + IntToString(nSpellLevel) + " remaining"

View File

@@ -720,7 +720,7 @@ void SetDefaultFileEnds()
SetPRCSwitch("PRC_FILE_END_polymorph", 155);
SetPRCSwitch("PRC_FILE_END_portraits", 1300);
SetPRCSwitch("PRC_FILE_END_prc_craft_alchem", 37);
SetPRCSwitch("PRC_FILE_END_prc_craft_gen_it", 204);
SetPRCSwitch("PRC_FILE_END_prc_craft_gen_it", 253);
SetPRCSwitch("PRC_FILE_END_prc_craft_poison", 62);
SetPRCSwitch("PRC_FILE_END_prc_domains", 59);
SetPRCSwitch("PRC_FILE_END_prc_familiar", 10);
@@ -1069,14 +1069,16 @@ void CreateSwitchNameArray()
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_ROD_CASTER_LEVEL);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFT_STAFF_CASTER_LEVEL);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_BASE_ITEMS);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_BREWPOTION_MAXLEVEL);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_BREWPOTION_COSTMODIFIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_SCRIBESCROLL_COSTMODIFIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_CRAFTWAND_MAXLEVEL);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), X2_CI_CRAFTWAND_COSTMODIFIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_BREWPOTION_MAXLEVEL);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_BREWPOTION_COSTMODIFIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_SCRIBESCROLL_COSTMODIFIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CRAFTWAND_MAXLEVEL);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CRAFTWAND_COSTMODIFIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_X2_CREATEINFUSION_COSTMODIFIER);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_ARBITRARY);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_COST_SCALE);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CRAFTING_TIME_SCALE);
array_set_string(oWP, "Switch_Name", array_get_size(oWP, "Switch_Name"), PRC_CREATE_INFUSION_CASTER_LEVEL);
//spells

View File

@@ -1182,7 +1182,7 @@ int GetMaxEssentiaCapacityFeat(object oMeldshaper)
// Don't allow more than they have
if (nMax > GetTotalUsableEssentia(oMeldshaper)) nMax = GetTotalUsableEssentia(oMeldshaper);
//if (DEBUG) DoDebug("GetMaxEssentiaCapacityFeat: nHD "+IntToString(nHD)+" nMax "+IntToString(nMax));
if(DEBUG) DoDebug("GetMaxEssentiaCapacityFeat: nHD "+IntToString(nHD)+" nMax "+IntToString(nMax));
return nMax;
}

File diff suppressed because it is too large Load Diff

View File

@@ -513,6 +513,8 @@ int PRCGetSpellSaveDC(int nSpellID = -1, int nSchool = -1, object oCaster = OBJE
if(nClass == CLASS_TYPE_BARD)
nDC += StringToInt(Get2DACache("Spells", "Bard", nSpellID));
else if(nClass == CLASS_TYPE_ASSASSIN)
nDC += StringToInt(Get2DACache("Spells", "Assassin", nSpellID));
else if(nClass == CLASS_TYPE_CLERIC || nClass == CLASS_TYPE_UR_PRIEST || nClass == CLASS_TYPE_OCULAR)
nDC += StringToInt(Get2DACache("Spells", "Cleric", nSpellID));
else if(nClass == CLASS_TYPE_DRUID)

View File

@@ -143,7 +143,7 @@ const int CLASS_TYPE_MASTER_HARPER = 176;
const int CLASS_TYPE_FRE_BERSERKER = 177;
const int CLASS_TYPE_TEMPEST = 178;
const int CLASS_TYPE_FOE_HUNTER = 179;
//:: Free = 180
const int CLASS_TYPE_VERDANT_LORD = 180;
const int CLASS_TYPE_ORC_WARLORD = 181;
const int CLASS_TYPE_THRALL_OF_GRAZZT_A = 182;
const int CLASS_TYPE_NECROCARNATE = 183;
@@ -162,7 +162,7 @@ const int CLASS_TYPE_MASTER_OF_NINE = 195;
const int CLASS_TYPE_ETERNAL_BLADE = 196;
const int CLASS_TYPE_SHADOW_SUN_NINJA = 197;
const int CLASS_TYPE_WITCHBORN_BINDER = 198;
const int CLASS_TYPE_BAELNORN = 199;
const int CLASS_TYPE_LION_OF_TALISID = 199;
const int CLASS_TYPE_DISCIPLE_OF_MEPH = 200;
const int CLASS_TYPE_SOUL_EATER = 201;
const int CLASS_TYPE_HENSHIN_MYSTIC = 202;
@@ -236,6 +236,7 @@ const int CLASS_TYPE_WITCH = -1;
const int CLASS_TYPE_TEMPLAR = -1;
const int CLASS_TYPE_MYSTIC = -1;
const int CLASS_TYPE_NOBLE = -1;
const int CLASS_TYPE_BAELNORN = -2;
//void main (){}

View File

@@ -75,6 +75,13 @@ void DeathlessFrenzyCheck(object oTarget);
// * PRC Version of a Bioware function to disable include loops
void PRCRemoveSpellEffects(int nSpell_ID, object oCaster, object oTarget);
/**
* Target is immune to gaze attacks
*
* @return the Dazzle effect
*/
effect EffectGazeImmune();
/**
* Dazzles the target: -1 Attack, Search, Spot, and VFX
*
@@ -583,7 +590,8 @@ effect PRCEffectHeal(int nHP, object oTarget)
return EffectHeal(nHP);
}
effect EffectAbilityBasedSkillIncrease(int iAbility, int iIncrease = 1){
effect EffectAbilityBasedSkillIncrease(int iAbility, int iIncrease = 1)
{
effect eReturn;
switch(iAbility)
{
@@ -639,7 +647,8 @@ effect EffectAbilityBasedSkillIncrease(int iAbility, int iIncrease = 1){
return eReturn;
}
effect EffectAbilityBasedSkillDecrease(int iAbility, int iDecrease = 1){
effect EffectAbilityBasedSkillDecrease(int iAbility, int iDecrease = 1)
{
effect eReturn;
switch(iAbility)
{
@@ -695,7 +704,8 @@ effect EffectAbilityBasedSkillDecrease(int iAbility, int iDecrease = 1){
return eReturn;
}
effect EffectDamageImmunityAll(){
effect EffectDamageImmunityAll()
{
effect eReturn = EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, 100);
eReturn = EffectLinkEffects(eReturn, EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, 100));
eReturn = EffectLinkEffects(eReturn, EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, 100));
@@ -712,7 +722,8 @@ effect EffectDamageImmunityAll(){
return eReturn;
}
effect EffectImmunityMiscAll(){
effect EffectImmunityMiscAll()
{
effect eReturn = EffectImmunity(IMMUNITY_TYPE_ABILITY_DECREASE);
eReturn = EffectLinkEffects(eReturn, EffectImmunity(IMMUNITY_TYPE_BLINDNESS));
eReturn = EffectLinkEffects(eReturn, EffectImmunity(IMMUNITY_TYPE_DEAFNESS));
@@ -732,6 +743,31 @@ effect EffectImmunityMiscAll(){
return eReturn;
}
//:: Immunity to all gaze attacks
effect EffectGazeImmune()
{
effect eBlank;
effect eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_CHARM);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_CONFUSION);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DAZE);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DEATH);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_CHAOS);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_EVIL);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_GOOD);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DESTROY_LAW);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DOMINATE);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_DOOM);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_FEAR);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_PARALYSIS);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_PETRIFY);
eReturn = EffectSpellImmunity(SPELLABILITY_GAZE_STUNNED);
eReturn = TagEffect(eReturn, "PRCGazeImmune");
return eReturn;
}
int GetIsShaken(object oTarget)
{
effect eEffect = GetFirstEffect(oTarget);
@@ -747,4 +783,7 @@ int GetIsShaken(object oTarget)
eEffect = GetNextEffect(oTarget);
}
return FALSE;
}
}
//:: Test void
//:: void main() {}

View File

@@ -152,6 +152,9 @@ const int FEAT_EPIC_DIAMOND_DRAGON = 25115;
const int FEAT_EPIC_CRUSADER = 25116;
const int FEAT_EPIC_SWORDSAGE = 25117;
const int FEAT_EPIC_WARBLADE = 25118;
const int FEAT_EPIC_LION_OF_TALISID = 25600;
const int FEAT_EPIC_VERDANT_LORD = 25618;
//:: Vile Martial Strike Expansion
const int FEAT_VILE_MARTIAL_EAGLE_CLAW = 24800;
@@ -195,6 +198,28 @@ const int FEAT_CHARMING_THE_ARROW = 25998;
//:: Skill Based Feats
const int FEAT_JUMP = 2884;
//:: Lion of Talisid
const int FEAT_LOT_LIONS_COURAGE = 25614;
const int FEAT_LOT_LIONS_POUNCE = 25615;
const int FEAT_LOT_LIONS_SWIFTNESS = 25616;
const int FEAT_LOT_LEONALS_ROAR = 25617;
//::: Verdant Lord
const int FEAT_VL_EXPERT_INFUSION = 25634;
const int FEAT_VL_SUN_SUSTENANCE = 25635;
const int FEAT_VL_SPONTANEITY = 25636;
const int FEAT_VL_PLANT_FACILITY = 25637;
const int FEAT_VL_WILD_SHAPE_TREANT = 25638;
const int FEAT_VL_ANIMATE_TREE = 25639;
const int FEAT_VL_GAEAS_EMBRACE = 25640;
//:: Masters of the Wild feats
const int FEAT_CREATE_INFUSION = 25960;
const int FEAT_MAGICAL_ARTISAN_CREATE_INFUSION = 25961;
const int FEAT_PLANT_DEFIANCE = 25992;
const int FEAT_PLANT_CONTROL = 25993;
//:: Racial Feats
const int FEAT_WEMIC_JUMP_8 = 4518;
const int FEAT_URDINNIR_STONESKIN = 4644;
@@ -782,6 +807,9 @@ const int FEAT_SUEL_IGNORE_SPELL_FAILURE = 2398;
const int FEAT_SUEL_EXTENDED_SPELL = 2399;
const int FEAT_SUEL_DISPELLING_STRIKE = 2400;
//:: Druid
const int FEAT_SPONT_SUMMON = 2372;
//Passive Feats
const int FEAT_ETERNAL_FREEDOM = 4298;
const int FEAT_INTUITIVE_ATTACK = 3166;
@@ -1538,18 +1566,19 @@ const int FEAT_SELVETARMS_BLESSING = 2447;
const int FEAT_RANGER_DUAL = 374;
const int FEAT_CAMOUFLAGE = 4486;
//Exalted Feat
const int FEAT_SAC_VOW = 3388;
const int FEAT_VOW_OBED = 3389;
const int FEAT_EXALTED_TURNING = 3168;
const int FEAT_HAND_HEALER = 3167;
const int FEAT_NIMBUSLIGHT = 3165;
const int FEAT_HOLYRADIANCE = 3164;
const int FEAT_STIGMATA = 3163;
const int FEAT_SERVHEAVEN = 3355;
const int FEAT_RANGED_SMITE = 3356;
const int FEAT_VOW_PURITY = 5360;
const int FEAT_VOWOFPOVERTY = 26002;
//:: Exalted Feats
const int FEAT_SAC_VOW = 3388;
const int FEAT_VOW_OBED = 3389;
const int FEAT_EXALTED_TURNING = 3168;
const int FEAT_HAND_HEALER = 3167;
const int FEAT_NIMBUSLIGHT = 3165;
const int FEAT_HOLYRADIANCE = 3164;
const int FEAT_STIGMATA = 3163;
const int FEAT_SERVHEAVEN = 3355;
const int FEAT_RANGED_SMITE = 3356;
const int FEAT_VOW_PURITY = 5360;
const int FEAT_VOWOFPOVERTY = 26002;
const int FEAT_FAV_COMPANIONS = 25994;
//Vile Feat
const int FEAT_LICHLOVED = 3395;
@@ -3189,6 +3218,8 @@ const int FEAT_ETHEREAL = 4167;
const int FEAT_TEMPLATE_ARCHLICH_MARKER = 22700;
const int FEAT_TEMPLATE_ARCHLICH_TURN_UNDEAD = 22701;
const int FEAT_TEMPLATE_BAELNORN_MARKER = 22708;
const int FEAT_TEMPLATE_CELESTIAL_SMITE_EVIL = 22601;
const int FEAT_TEMPLATE_CELESTIAL_MARKER = 22602;
const int FEAT_TEMPLATE_FIENDISH_SMITE_GOOD = 22603;
@@ -3933,6 +3964,8 @@ const int FEAT_OPPORTUNISTIC_PIETY_HEAL = 5358;
const int FEAT_OPPORTUNISTIC_PIETY_TURN = 5359;
// Combat Maneuver Feats
const int FEAT_CM_CHARGE = 2823;
const int FEAT_CM_GRAPPLE = 3414;
const int FEAT_CURLING_WAVE_STRIKE = 2809;
const int FEAT_SIDESTEP_CHARGE = 3505;
const int FEAT_POWERFUL_CHARGE = 3506;
@@ -6203,6 +6236,38 @@ const int FEAT_SHINING_BLADE_SPELLCASTING_VASSAL = 19587;
const int FEAT_SWIFT_WING_SPELLCASTING_VASSAL = 19588;
const int FEAT_WARPRIEST_SPELLCASTING_VASSAL = 19589;
//:: Lion of Talisid marker feats
const int FEAT_LION_OF_TALISID_SPELLCASTING_ARCHIVIST = 25601;
const int FEAT_LION_OF_TALISID_SPELLCASTING_CLERIC = 25602;
const int FEAT_LION_OF_TALISID_SPELLCASTING_DRUID = 25603;
const int FEAT_LION_OF_TALISID_SPELLCASTING_FAVOURED_SOUL = 25604;
const int FEAT_LION_OF_TALISID_SPELLCASTING_HEALER = 25605;
const int FEAT_LION_OF_TALISID_SPELLCASTING_JOWAW = 25606;
const int FEAT_LION_OF_TALISID_SPELLCASTING_KOTMC = 25607;
const int FEAT_LION_OF_TALISID_SPELLCASTING_NENTYAR_HUNTER = 25608;
const int FEAT_LION_OF_TALISID_SPELLCASTING_RANGER = 25609;
const int FEAT_LION_OF_TALISID_SPELLCASTING_OASHAMAN = 25610;
const int FEAT_LION_OF_TALISID_SPELLCASTING_SOHEI = 25611;
const int FEAT_LION_OF_TALISID_SPELLCASTING_SOL = 25612;
const int FEAT_LION_OF_TALISID_SPELLCASTING_SPSHAMAN = 25613;
//:: Verdant Lord marker feats
const int FEAT_VERDANT_LORD_SPELLCASTING_ARCHIVIST = 25619;
const int FEAT_VERDANT_LORD_SPELLCASTING_CLERIC = 25620;
const int FEAT_VERDANT_LORD_SPELLCASTING_DRUID = 25621;
const int FEAT_VERDANT_LORD_SPELLCASTING_FAVOURED_SOUL = 25622;
const int FEAT_VERDANT_LORD_SPELLCASTING_HEALER = 25623;
const int FEAT_VERDANT_LORD_SPELLCASTING_JOWAW = 25624;
const int FEAT_VERDANT_LORD_SPELLCASTING_KOTC = 25625;
const int FEAT_VERDANT_LORD_SPELLCASTING_KOTMC = 25626;
const int FEAT_VERDANT_LORD_SPELLCASTING_NENTYAR_HUNTER = 25627;
const int FEAT_VERDANT_LORD_SPELLCASTING_PALADIN = 25628;
const int FEAT_VERDANT_LORD_SPELLCASTING_RANGER = 25629;
const int FEAT_VERDANT_LORD_SPELLCASTING_OASHAMAN = 25630;
const int FEAT_VERDANT_LORD_SPELLCASTING_SOHEI = 25631;
const int FEAT_VERDANT_LORD_SPELLCASTING_SOL = 25632;
const int FEAT_VERDANT_LORD_SPELLCASTING_SPSHAMAN = 25633;
//:: No spellcasting or invoking marker feats
const int FEAT_ASMODEUS_SPELLCASTING_NONE = 19590;
const int FEAT_TIAMAT_SPELLCASTING_NONE = 19591;

View File

@@ -1148,8 +1148,8 @@ int GetArcanePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if(GetHasFeat(FEAT_DIABOLIST_SPELLCASTING_ASSASSIN, oCaster))
nArcane += GetLevelByClass(CLASS_TYPE_DIABOLIST, oCaster);
if(GetHasFeat(FEAT_DHEART_SPELLCASTING_ASSASSIN, oCaster))
nArcane += GetLevelByClass(CLASS_TYPE_DRAGONHEART_MAGE, oCaster);
//if(GetHasFeat(FEAT_DHEART_SPELLCASTING_ASSASSIN, oCaster))
//nArcane += GetLevelByClass(CLASS_TYPE_DRAGONHEART_MAGE, oCaster);
if(GetHasFeat(FEAT_EKNIGHT_SPELLCASTING_ASSASSIN, oCaster))
nArcane += GetLevelByClass(CLASS_TYPE_ELDRITCH_KNIGHT, oCaster);
@@ -3822,6 +3822,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_ARCHIVIST, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_ARCHIVIST, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_ARCHIVIST, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
@@ -4148,7 +4151,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_CLERIC, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_CLERIC, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_CLERIC, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
@@ -4258,7 +4264,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_DRUID, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_DRUID, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_DRUID, oCaster))
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
@@ -4370,10 +4379,13 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_FAVOURED_SOUL, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_FAVOURED_SOUL, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_FAVOURED_SOUL, oCaster))
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_FAVOURED_SOUL, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
if(GetHasFeat(FEAT_MORNINGLORD_SPELLCASTING_FAVOURED_SOUL, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MORNINGLORD, oCaster);
@@ -4479,6 +4491,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_HEALER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_HEALER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_HEALER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
@@ -4586,6 +4601,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_JUSTICEWW, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_JOWAW, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_JUSTICEWW, oCaster))
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
@@ -4796,6 +4814,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_KOTMC, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_KNIGHT_MIDDLECIRCLE, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
@@ -4901,7 +4922,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster); */
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_NENTYAR_HUNTER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_NENTYAR_HUNTER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_NENTYAR_HUNTER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */
@@ -5212,7 +5236,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster); */
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_RANGER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_RANGER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
if(GetHasFeat(FEAT_MORNINGLORD_SPELLCASTING_RANGER, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MORNINGLORD, oCaster);
@@ -5316,7 +5343,10 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
nDivine += GetLevelByClass(CLASS_TYPE_HIEROPHANT, oCaster);
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_OASHAMAN, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_OASHAMAN, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_SHAMAN, oCaster);
if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_OASHAMAN, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
@@ -5529,6 +5559,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_SOHEI, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_SOHEI, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
// if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_SOHEI, oCaster))
// nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster);
@@ -5636,6 +5669,9 @@ int GetDivinePRCLevels(object oCaster, int nCastingClass = CLASS_TYPE_INVALID)
if(GetHasFeat(FEAT_HOSPITALER_SPELLCASTING_SOL, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_HOSPITALER, oCaster);
if(GetHasFeat(FEAT_LION_OF_TALISID_SPELLCASTING_SOL, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_LION_OF_TALISID, oCaster);
/* if(GetHasFeat(FEAT_MASTER_OF_SHROUDS_SPELLCASTING_SOL, oCaster))
nDivine += GetLevelByClass(CLASS_TYPE_MASTER_OF_SHROUDS, oCaster); */

View File

@@ -1206,6 +1206,7 @@ int GetIsDoubleSidedWeaponType(int iWeaponType)
return ( iWeaponType == BASE_ITEM_DIREMACE
|| iWeaponType == BASE_ITEM_DOUBLEAXE
|| iWeaponType == BASE_ITEM_TWOBLADEDSWORD
|| iWeaponType == BASE_ITEM_DOUBLE_SCIMITAR
);
}

View File

@@ -1140,6 +1140,9 @@ void DoCharge(object oPC, object oTarget, int nDoAttack = TRUE, int nGenerateAoO
nPounce = TRUE;
if (GetHasSpellEffect(VESTIGE_CHUPOCLOPS, oPC) && GetLocalInt(oPC, "ExploitVestige") != VESTIGE_CHUPOCLOPS_POUNCE)
nPounce = TRUE;
//:: Lion of Talisid
if(GetHasFeat(FEAT_LOT_LIONS_POUNCE, oPC))
nPounce = TRUE;
// Checks for a White Raven Stance
// If it exists, +1 damage/initiator level
@@ -2312,7 +2315,10 @@ void DoShieldCharge(object oPC, object oTarget, int nSlam = FALSE)
if(GetLevelByClass(CLASS_TYPE_CELEBRANT_SHARESS, oPC) >= 5)
nPounce = TRUE;
if(GetRacialType(oPC) == RACIAL_TYPE_MARRUSAULT)
nPounce = TRUE;
nPounce = TRUE;
//:: Lion of Talisid
if(GetHasFeat(FEAT_LOT_LIONS_POUNCE, oPC))
nPounce = TRUE;
// Checks for a White Raven Stance
// If it exists, +1 damage/initiator level

View File

@@ -462,7 +462,7 @@ int PRCGetSpellLevelForClass(int nSpell, int nClass)
return nSpellLevel;
}
// returns the spelllevel of nSpell as it can be cast by oCreature
// returns the spell circle level of nSpell as it can be cast by oCreature
int PRCGetSpellLevel(object oCreature, int nSpell)
{
/*if (!PRCGetHasSpell(nSpell, oCreature))
@@ -605,7 +605,7 @@ int PRCGetHasSpell(int nRealSpellID, object oCreature = OBJECT_SELF)
if(nSpellbookType == SPELLBOOK_TYPE_PREPARED)
{
nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), j);
if(DEBUG) DoDebug("PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
if(DEBUG) DoDebug("prc_inc_core >> PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
if(nCount > 0)
{
nUses += nCount;
@@ -615,7 +615,7 @@ int PRCGetHasSpell(int nRealSpellID, object oCreature = OBJECT_SELF)
{
nSpellLevel = StringToInt(Get2DACache(sFile, "Level", j));
nCount = persistant_array_get_int(oCreature, "NewSpellbookMem_" + IntToString(nClass), nSpellLevel);
if(DEBUG) DoDebug("PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
if(DEBUG) DoDebug("prc_inc_core >> PRCGetHasSpell: NewSpellbookMem_" + IntToString(nClass) + "[" + IntToString(j) + "] = " + IntToString(nCount));
if(nCount > 0)
{
nUses += nCount;

View File

@@ -795,7 +795,7 @@ int GetWeaponSize(object oWeapon)
case BASE_ITEM_GREATAXE:
case BASE_ITEM_HEAVYFLAIL:
case BASE_ITEM_QUARTERSTAFF:
case BASE_ITEM_MAGICSTAFF:
//case BASE_ITEM_MAGICSTAFF:
case BASE_ITEM_SCYTHE:
case BASE_ITEM_SHORTSPEAR:
case BASE_ITEM_ELVEN_COURTBLADE:
@@ -832,7 +832,7 @@ int PRCLargeWeaponCheck(int iBaseType, int nSize)
case BASE_ITEM_GREATAXE:
case BASE_ITEM_HEAVYFLAIL:
case BASE_ITEM_QUARTERSTAFF:
case BASE_ITEM_MAGICSTAFF:
//case BASE_ITEM_MAGICSTAFF:
case BASE_ITEM_SCYTHE:
case BASE_ITEM_SHORTSPEAR:
case BASE_ITEM_ELVEN_COURTBLADE:

View File

@@ -108,8 +108,8 @@ void SetupCharacterData(object oPC)
case CLASS_TYPE_ALIENIST: sScript = "prc_alienist"; break;
case CLASS_TYPE_ARCANE_DUELIST: sScript = "prc_arcduel"; break;
case CLASS_TYPE_ARCHIVIST: sScript = "prc_archivist"; iData |= 0x01; break;
case CLASS_TYPE_ASSASSIN: iData |= 0x03; break;
case CLASS_TYPE_BAELNORN: sScript = "prc_baelnorn"; break;
case CLASS_TYPE_ASSASSIN: break;
//case CLASS_TYPE_BAELNORN: sScript = "prc_baelnorn"; break;
case CLASS_TYPE_BARD: iData |= 0x07; break;
case CLASS_TYPE_BATTLESMITH: sScript = "prc_battlesmith"; break;
case CLASS_TYPE_BEGUILER: iData |= 0x03; break;
@@ -121,7 +121,7 @@ void SetupCharacterData(object oPC)
case CLASS_TYPE_BLIGHTLORD: sScript = "prc_blightlord"; break;
case CLASS_TYPE_BLOODCLAW_MASTER: sScript = "tob_bloodclaw"; break;
case CLASS_TYPE_BONDED_SUMMONNER: sScript = "prc_bondedsumm"; break;
case CLASS_TYPE_CELEBRANT_SHARESS: iData |= 0x03; break;
case CLASS_TYPE_CELEBRANT_SHARESS: iData |= 0x07; break;
case CLASS_TYPE_CHILD_OF_NIGHT: sScript = "shd_childnight"; break;
case CLASS_TYPE_COC: sScript = "prc_coc"; break;
case CLASS_TYPE_COMBAT_MEDIC: sScript = "prc_cbtmed"; break;
@@ -180,6 +180,7 @@ void SetupCharacterData(object oPC)
case CLASS_TYPE_LASHER: sScript = "prc_lasher"; break;
case CLASS_TYPE_LEGENDARY_DREADNOUGHT: sScript = "prc_legendread"; break;
case CLASS_TYPE_LICH: sScript = "pnp_lich_level"; break;
case CLASS_TYPE_LION_OF_TALISID: sScript = "prc_lot"; break;
case CLASS_TYPE_MAGEKILLER: sScript = "prc_magekill"; break;
case CLASS_TYPE_MASTER_HARPER: sScript = "prc_masterh"; break;
case CLASS_TYPE_MASTER_OF_NINE: sScript = "tob_masterofnine"; break;
@@ -245,6 +246,7 @@ void SetupCharacterData(object oPC)
case CLASS_TYPE_TOTEM_RAGER: sScript = "moi_totemrager"; break;
case CLASS_TYPE_TRUENAMER: sScript = "true_truenamer"; iData |= 0x01; break;
case CLASS_TYPE_VASSAL: sScript = "prc_vassal"; break;
case CLASS_TYPE_VERDANT_LORD: sScript = "prc_verdantlord"; break;
case CLASS_TYPE_VIGILANT: sScript = "prc_vigilant"; break;
case CLASS_TYPE_WARBLADE: sScript = "tob_warblade"; iData |= 0x01; break;
case CLASS_TYPE_WARCHIEF: sScript = "prc_warchief"; break;
@@ -2264,6 +2266,8 @@ void FeatSpecialUsePerDay(object oPC)
FeatUsePerDay(oPC, FEAT_FM_FOREST_DOMINION, ABILITY_CHARISMA, 3);
FeatUsePerDay(oPC, FEAT_SOD_DEATH_TOUCH, -1, (GetLevelByClass(CLASS_TYPE_SLAYER_OF_DOMIEL, oPC)+4)/4);
FeatUsePerDay(oPC, FEAT_SUEL_DISPELLING_STRIKE, -1, (GetLevelByClass(CLASS_TYPE_SUEL_ARCHANAMACH, oPC) + 2) / 4);
FeatUsePerDay(oPC, FEAT_PLANT_CONTROL, ABILITY_CHARISMA, 3);
FeatUsePerDay(oPC, FEAT_PLANT_DEFIANCE, ABILITY_CHARISMA, 3);
FeatDiabolist(oPC);
FeatAlaghar(oPC);
ShadowShieldUses(oPC);

View File

@@ -16,26 +16,28 @@ const int MATERIAL_TYPE_UNKNOWN = 0;
const int MATERIAL_TYPE_BONE = 1;
const int MATERIAL_TYPE_CERAMIC = 2;
const int MATERIAL_TYPE_CRYSTAL = 3;
const int MATERIAL_TYPE_FABRIC = 4;
const int MATERIAL_TYPE_FIBER = 4;
const int MATERIAL_TYPE_LEATHER = 5;
const int MATERIAL_TYPE_METAL = 6;
const int MATERIAL_TYPE_PAPER = 7;
const int MATERIAL_TYPE_ROPE = 8;
const int MATERIAL_TYPE_STONE = 9;
const int MATERIAL_TYPE_WOOD = 10;
const int MATERIAL_TYPE_BOTANICAL = 11;
const string MATERIAL_TYPE_NAME_INVALID = "";
const string MATERIAL_TYPE_NAME_UNKNOWN = "Unknown";
const string MATERIAL_TYPE_NAME_BONE = "Bone";
const string MATERIAL_TYPE_NAME_CERAMIC = "Ceramic";
const string MATERIAL_TYPE_NAME_CRYSTAL = "Crystal";
const string MATERIAL_TYPE_NAME_FABRIC = "Fabric";
const string MATERIAL_TYPE_NAME_FIBER = "Fiber";
const string MATERIAL_TYPE_NAME_LEATHER = "Leather";
const string MATERIAL_TYPE_NAME_METAL = "Metal";
const string MATERIAL_TYPE_NAME_PAPER = "Paper";
const string MATERIAL_TYPE_NAME_ROPE = "Rope";
const string MATERIAL_TYPE_NAME_STONE = "Stone";
const string MATERIAL_TYPE_NAME_WOOD = "Wood";
const string MATERIAL_TYPE_NAME_BOTANICAL = "Bontanical";
//:: Material Itemproperty Constants
//::////////////////////////////////////////////////////////////////////////////////
@@ -163,7 +165,8 @@ const int IP_MATERIAL_OBSIDIAN = 140;
const int IP_MATERIAL_BAMBOO = 141;
const int IP_MATERIAL_POTTERY = 142;
const int IP_MATERIAL_GLASSTEEL = 143;
const int IP_NUM_MATERIALS = 143;
const int IP_MATERIAL_HERB = 144;
const int IP_NUM_MATERIALS = 144;
const string IP_MATERIAL_NAME_INVALID = "";
const string IP_MATERIAL_NAME_UNKNOWN = "Unknown";
@@ -288,6 +291,7 @@ const string IP_MATERIAL_NAME_OBSIDIAN = "Obsidian";
const string IP_MATERIAL_NAME_BAMBOO = "Bamboo";
const string IP_MATERIAL_NAME_POTTERY = "Pottery";
const string IP_MATERIAL_NAME_GLASSTEEL = "Glassteel";
const string IP_MATERIAL_NAME_HERB = "Herbs";
//::///////////////////////////////////////////////////////////////
// GetMaterialName( int iMaterialType, int bLowerCase = FALSE)
@@ -428,6 +432,7 @@ string GetMaterialName( int iMaterialType, int bLowerCase = FALSE)
case IP_MATERIAL_BAMBOO: sName = IP_MATERIAL_NAME_BAMBOO; break;
case IP_MATERIAL_POTTERY: sName = IP_MATERIAL_NAME_POTTERY; break;
case IP_MATERIAL_GLASSTEEL: sName = IP_MATERIAL_NAME_GLASSTEEL; break;
case IP_MATERIAL_HERB: sName = IP_MATERIAL_NAME_HERB; break;
default: return "";
}
@@ -573,6 +578,7 @@ int GetIPMaterial( string sMaterialName)
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_BAMBOO)) return IP_MATERIAL_BAMBOO;
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_POTTERY)) return IP_MATERIAL_POTTERY;
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_GLASSTEEL)) return IP_MATERIAL_GLASSTEEL;
else if( sMaterialName == GetStringUpperCase(IP_MATERIAL_NAME_HERB)) return IP_MATERIAL_HERB;
return IP_MATERIAL_INVALID;
}
@@ -806,6 +812,9 @@ int GetMaterialType(int nMaterial)
|| nMaterial == IP_MATERIAL_DRAKE_IVORY )
return MATERIAL_TYPE_BONE;
else if ( nMaterial == IP_MATERIAL_HERB )
return MATERIAL_TYPE_BOTANICAL;
else if ( nMaterial == IP_MATERIAL_ELUKIAN_CLAY
|| nMaterial == IP_MATERIAL_POTTERY )
return MATERIAL_TYPE_CERAMIC;
@@ -814,7 +823,7 @@ int GetMaterialType(int nMaterial)
|| nMaterial == IP_MATERIAL_COTTON
|| nMaterial == IP_MATERIAL_SILK
|| nMaterial == IP_MATERIAL_WOOL )
return MATERIAL_TYPE_FABRIC;
return MATERIAL_TYPE_FIBER;
else if ( nMaterial == IP_MATERIAL_GEM
|| nMaterial == IP_MATERIAL_GEM_ALEXANDRITE

View File

@@ -808,7 +808,24 @@ int GetIsOnHitCastSpell(object oSpellTarget = OBJECT_INVALID, object oSpellCastI
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is armor; attacker = "+GetName(oAttacker)+", defender = "+GetName(oDefender));
}
// is the spell type item a weapon?
else if (iWeaponType == StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType)))
int nWT = StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType));
if (nWT > 0)
{
if (oSpellTarget == OBJECT_INVALID)
oSpellTarget = PRCGetSpellTargetObject(oSpellOrigin);
oAttacker = oSpellOrigin;
oDefender = oSpellTarget;
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is weapon [WT="+IntToString(nWT)+"]; attacker="+GetName(oAttacker)+", defender="+GetName(oDefender));
}
else
{
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is neither weapon nor armor; returning FALSE");
return FALSE;
}
/* else if (iWeaponType == StringToInt(Get2DACache("baseitems", "WeaponType", iBaseType)))
{
// determine the target, if not already given
if (oSpellTarget == OBJECT_INVALID)
@@ -823,7 +840,7 @@ int GetIsOnHitCastSpell(object oSpellTarget = OBJECT_INVALID, object oSpellCastI
{
if (DEBUG) DoDebug("GetIsOnHitCastSpell: item "+GetName(oSpellCastItem)+" is neither weapon nor armor; returning FALSE");
return FALSE;
}
} */
// the spell origin must possess the item that cast the spell (at least for the aurora engine, in prc_inc_combat that may differ)

View File

@@ -115,11 +115,11 @@ int PerformJump(object oPC, location lLoc, int bDoKnockDown = TRUE)
iBonus = 4;
}
}
/*if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC))
if (GetHasSpellEffect(MOVE_TC_LEAPING_DRAGON, oPC))
{
bIsRunningJump = TRUE;
iBonus = 10;
} */
//iBonus = 10; //:: This is granted in the stance.
}
// PnP rules are height * 6 for run and height * 2 for jump.
// I can't get height so that is assumed to be 6.
// Changed maxed jump distance because the NwN distance is rather short
@@ -374,6 +374,12 @@ int PRCIsFlying(object oCreature)
if(GetRacialType(oCreature) == RACIAL_TYPE_GLOURA)
bFlying = TRUE;
if(GetRacialType(oCreature) == RACIAL_TYPE_AVARIEL)
bFlying = TRUE;
if(GetRacialType(oCreature) == RACIAL_TYPE_FEYRI)
bFlying = TRUE;
if(GetRacialType(oCreature) == RACIAL_TYPE_SPIRETOPDRAGON)
bFlying = TRUE;

View File

@@ -20,6 +20,11 @@
/* Function prototypes */
//////////////////////////////////////////////////
//:: Calculates total Shield AC bonuses from all sources
int GetTotalShieldACBonus(object oCreature);
//:: Handles psuedo-Foritifcation
void DoFortification(object oPC = OBJECT_SELF, int nFortification = 25);
@@ -376,6 +381,36 @@ const int TYPE_DIVINE = -2;
/* Function definitions */
//////////////////////////////////////////////////
// Returns TRUE if nSpellID is a subradial spell, FALSE otherwise
int GetIsSubradialSpell(int nSpellID)
{
string sMaster = Get2DAString("spells", "Master", nSpellID);
// A subradial will have a numeric master ID here, not ****
if (sMaster != "****")
{
return TRUE;
}
return FALSE;
}
// Returns the masterspell SpellID for a subradial spell.
int GetMasterSpellFromSubradial(int nSpellID)
{
string sMaster = Get2DAString("spells", "Master", nSpellID);
if (sMaster != "****")
{
return StringToInt(sMaster);
}
return -1; // No master
}
int GetPrCAdjustedClassLevel(int nClass, object oCaster = OBJECT_SELF)
{
int iTemp;
@@ -412,7 +447,9 @@ int GetPrCAdjustedCasterLevelByType(int nClassType, object oCaster = OBJECT_SELF
{
int nClassLvl;
int nClass1, nClass2, nClass3, nClass4, nClass5, nClass6, nClass7, nClass8;
int nClass1Lvl, nClass2Lvl, nClass3Lvl, nClass4Lvl, nClass5Lvl, nClass6Lvl, nClass7Lvl, nClass8Lvl;
int nClass1Lvl = 0, nClass2Lvl = 0, nClass3Lvl = 0, nClass4Lvl = 0,
nClass5Lvl = 0, nClass6Lvl = 0, nClass7Lvl = 0, nClass8Lvl = 0;
nClass1 = GetClassByPosition(1, oCaster);
nClass2 = GetClassByPosition(2, oCaster);
@@ -2223,6 +2260,78 @@ int GetControlledCelestialTotalHD(object oPC = OBJECT_SELF)
return nTotalHD;
}
//:: Calculates total Shield AC bonuses from all sources
int GetTotalShieldACBonus(object oCreature)
{
int nShieldBonus = 0;
object oItem;
// Check left hand for shield
oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oCreature);
if (GetIsObjectValid(oItem))
{
int nBaseItem = GetBaseItemType(oItem);
if (nBaseItem == BASE_ITEM_SMALLSHIELD ||
nBaseItem == BASE_ITEM_LARGESHIELD ||
nBaseItem == BASE_ITEM_TOWERSHIELD)
{
nShieldBonus += GetItemACValue(oItem);
if(DEBUG) DoDebug("prc_inc_spells >> GetTotalShieldACBonus: Found Shield AC, bonus = " + IntToString(nShieldBonus)+".");
}
}
// Check creature weapon slots for shield AC bonus
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oCreature);
if (GetIsObjectValid(oItem))
nShieldBonus += GetItemACValue(oItem);
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oCreature);
if (GetIsObjectValid(oItem))
nShieldBonus += GetItemACValue(oItem);
oItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oCreature);
if (GetIsObjectValid(oItem))
nShieldBonus += GetItemACValue(oItem);
// Add shield AC bonuses from magical effects
effect eEffect = GetFirstEffect(oCreature);
while (GetIsEffectValid(eEffect))
{
int nACType = GetEffectInteger(eEffect, 0);
int nACAmount = GetEffectInteger(eEffect, 1);
if(GetEffectType(eEffect) == EFFECT_TYPE_AC_INCREASE && nACType == AC_SHIELD_ENCHANTMENT_BONUS)
{
if(DEBUG) DoDebug("prc_inc_spells >> GetTotalShieldACBonus: Found Shield AC effect, bonus = " + IntToString(nACAmount)+".");
nShieldBonus += nACAmount;
}
eEffect = GetNextEffect(oCreature);
}
return nShieldBonus;
}
// Add shield AC bonuses from magical effects
/* effect eEffect = GetFirstEffect(oCreature);
while (GetIsEffectValid(eEffect))
{
if (GetEffectType(eEffect) == EFFECT_TYPE_AC_INCREASE &&
GetEffectInteger(eEffect, 1) == AC_SHIELD_ENCHANTMENT_BONUS)
{
int nMod = GetEffectInteger(eEffect, 0);
int nType = GetEffectInteger(eEffect, 1);
nShieldBonus += GetEffectInteger(eEffect, 0);
string s = "Found AC effect: bonus = " + IntToString(nMod) + ", type = " + IntToString(nType);
SendMessageToPC(GetFirstPC(), s);
}
eEffect = GetNextEffect(oCreature);
}
return nShieldBonus;
}*/
//
//:: Handles psuedo-Foritifcation
void DoFortification(object oPC = OBJECT_SELF, int nFortification = 25)
{
@@ -2275,7 +2384,7 @@ void DoFortification(object oPC = OBJECT_SELF, int nFortification = 25)
IPSafeAddItemProperty(oHide, ItemPropertyImmunityMisc(IP_CONST_IMMUNITYMISC_BACKSTAB));
}
}
//
// wrapper for DecrementRemainingSpellUses, works for newspellbook 'fake' spells too
// should also find and decrement metamagics for newspellbooks

View File

@@ -70,6 +70,8 @@
43 PRC_CRAFTING_BASE_ITEMS int 1
44 PRC_XP_USE_SIMPLE_LA int 1
45 PRC_XP_USE_SIMPLE_RACIAL_HD int 1
46 PRC_CREATE_INFUSION_CASTER_LEVEL int 1
47 PRC_CREATE_INFUSION_OPTIONAL_HERBS int 0
*/
/* This variable MUST be updated with every new version of the PRC!!! */
@@ -1952,6 +1954,18 @@ const string PRC_CRAFT_ROD_CASTER_LEVEL = "PRC_CRAFT_ROD_CASTER_LEVE
*/
const string PRC_CRAFT_STAFF_CASTER_LEVEL = "PRC_CRAFT_STAFF_CASTER_LEVEL";
/*
* As above, except it applies to herbal infusions
*/
const string PRC_CREATE_INFUSION_CASTER_LEVEL = "PRC_CREATE_INFUSION_CASTER_LEVEL";
/*
* Builder's Option: Enables the optional PnP herbs for creating infusions.
* Each herb is keyed to a spell circle level & spell school as shown on pg. 33
* of the Master's of the Wild sourcebook.
*/
const string PRC_CREATE_INFUSION_OPTIONAL_HERBS = "PRC_CREATE_INFUSION_OPTIONAL_HERBS";
/*
* Characters with a crafting feat always have the appropriate base item in their inventory
*/
@@ -1961,45 +1975,52 @@ const string PRC_CRAFTING_BASE_ITEMS = "PRC_CRAFTING_BASE_ITEMS";
* Max level of spells brewed into potions
* defaults to 3
*/
const string X2_CI_BREWPOTION_MAXLEVEL = "X2_CI_BREWPOTION_MAXLEVEL";
//const string X2_CI_BREWPOTION_MAXLEVEL = "X2_CI_BREWPOTION_MAXLEVEL";
const string PRC_X2_BREWPOTION_MAXLEVEL = "PRC_X2_BREWPOTION_MAXLEVEL";
/*
* cost modifier of spells brewed into poitions
* defaults to 50
*/
const string X2_CI_BREWPOTION_COSTMODIFIER = "X2_CI_BREWPOTION_COSTMODIFIER";
const string PRC_X2_BREWPOTION_COSTMODIFIER = "PRC_X2_BREWPOTION_COSTMODIFIER";
/*
* cost modifier of spells scribed into scrolls
* defaults to 25
*/
const string X2_CI_SCRIBESCROLL_COSTMODIFIER = "X2_CI_SCRIBESCROLL_COSTMODIFIER";
const string PRC_X2_SCRIBESCROLL_COSTMODIFIER = "PRC_X2_SCRIBESCROLL_COSTMODIFIER";
/*
* cost modifier of spells infused into herbs
* defaults to 25
*/
const string PRC_X2_CREATEINFUSION_COSTMODIFIER = "PRC_X2_CREATEINFUSION_COSTMODIFIER";
/*
* Max level of spells crafted into wands
* defaults to 4
*/
const string X2_CI_CRAFTWAND_MAXLEVEL = "X2_CI_CRAFTWAND_MAXLEVEL";
const string PRC_X2_CRAFTWAND_MAXLEVEL = "PRC_X2_CRAFTWAND_MAXLEVEL";
/*
* cost modifier of spells crafted into wands
* defaults to 750
*/
const string X2_CI_CRAFTWAND_COSTMODIFIER = "X2_CI_CRAFTWAND_COSTMODIFIER";
const string PRC_X2_CRAFTWAND_COSTMODIFIER = "PRC_X2_CRAFTWAND_COSTMODIFIER";
/*
* cost modifier of spells crafted into rods
* note that adding a second spell costs 75% and 3 or more costs 50%
* defaults to 750
*/
const string X2_CI_CRAFTROD_COSTMODIFIER = "X2_CI_CRAFTROD_COSTMODIFIER";
const string PRC_X2_CRAFTROD_COSTMODIFIER = "PRC_X2_CRAFTROD_COSTMODIFIER";
/*
* cost modifier of spells crafted into staffs
* note that adding a second spell costs 75% and 3 or more costs 50%
* defaults to 750
*/
const string X2_CI_CRAFTSTAFF_COSTMODIFIER = "X2_CI_CRAFTSTAFF_COSTMODIFIER";
const string PRC_X2_CRAFTSTAFF_COSTMODIFIER = "PRC_X2_CRAFTSTAFF_COSTMODIFIER";
/**
* Allows the use of arbitrary itemproperties and uses NWN item costs

View File

@@ -14,17 +14,6 @@
/* Function prototypes */
//////////////////////////////////////////////////
//gets the number of class levels that count for turning
int GetTurningClassLevel(object oCaster = OBJECT_SELF, int nTurnType = SPELL_TURN_UNDEAD);
@@ -191,6 +180,20 @@ int GetIsTurnOrRebuke(object oTarget, int nTurnType, int nTargetRace)
break;
}
case SPELL_PLANT_DEFIANCE:
{
if(nTargetRace == RACIAL_TYPE_PLANT)
nReturn = ACTION_TURN;
break;
}
case SPELL_PLANT_CONTROL:
{
if(nTargetRace == RACIAL_TYPE_PLANT)
nReturn = ACTION_REBUKE;
break;
}
case SPELL_TURN_PLANT:
{
// Plant domain rebukes or commands plants
@@ -383,6 +386,13 @@ int GetTurningClassLevel(object oCaster = OBJECT_SELF, int nTurnType = SPELL_TUR
if (nTurnType == SPELL_OPPORTUNISTIC_PIETY_TURN)
return GetLevelByClass(CLASS_TYPE_FACTOTUM, oCaster);
if (nTurnType == SPELL_PLANT_DEFIANCE || nTurnType == SPELL_PLANT_CONTROL)
{
int nDivineLvl = GetPrCAdjustedCasterLevelByType(TYPE_DIVINE, oCaster);
return nDivineLvl;
}
//Baelnorn & Archlich adds all class levels.
if(GetLevelByClass(CLASS_TYPE_BAELNORN, oCaster) || GetHasFeat(FEAT_TEMPLATE_ARCHLICH_MARKER, oCaster)) //:: Archlich

View File

@@ -40,13 +40,31 @@ int IsProficient(object oPC, int nBaseItem)
case BASE_ITEM_CLUB:
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_CLUB, oPC);
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_CLUB, oPC);
case BASE_ITEM_HEAVYCROSSBOW:
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_HEAVY_XBOW, oPC);
case BASE_ITEM_LIGHTCROSSBOW:
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_LIGHT_XBOW, oPC);
case BASE_ITEM_DAGGER:
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DAGGER, oPC);
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DAGGER, oPC);
case BASE_ITEM_LONGSWORD:
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_MARTIAL, oPC)
@@ -152,12 +170,14 @@ int IsProficient(object oPC, int nBaseItem)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_ROGUE, oPC);
case BASE_ITEM_QUARTERSTAFF:
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF, oPC)
||GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC);
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC);
case BASE_ITEM_MAGICSTAFF:
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
return GetHasFeat(FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF, oPC)
||GetHasFeat(FEAT_WEAPON_PROFICIENCY_SIMPLE, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_DRUID, oPC)
|| GetHasFeat(FEAT_WEAPON_PROFICIENCY_WIZARD, oPC);
@@ -300,167 +320,185 @@ int GetWeaponProfFeatByType(int nBaseType)
{
switch(nBaseType)
{
case BASE_ITEM_SHORTSWORD:
return FEAT_WEAPON_PROFICIENCY_SHORTSWORD;
case BASE_ITEM_CLUB:
return FEAT_WEAPON_PROFICIENCY_CLUB;
case BASE_ITEM_QUARTERSTAFF:
return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF;
case BASE_ITEM_LONGSWORD:
return FEAT_WEAPON_PROFICIENCY_LONGSWORD;
case BASE_ITEM_MAGICSTAFF:
return FEAT_WEAPON_PROFICIENCY_QUARTERSTAFF;
case BASE_ITEM_DAGGER:
return FEAT_WEAPON_PROFICIENCY_DAGGER;
case BASE_ITEM_BATTLEAXE:
return FEAT_WEAPON_PROFICIENCY_BATTLEAXE;
case BASE_ITEM_HEAVYCROSSBOW:
return FEAT_WEAPON_PROFICIENCY_HEAVY_XBOW;
case BASE_ITEM_BASTARDSWORD:
return FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD;
case BASE_ITEM_LIGHTCROSSBOW:
return FEAT_WEAPON_PROFICIENCY_LIGHT_XBOW;
case BASE_ITEM_SHORTSWORD:
return FEAT_WEAPON_PROFICIENCY_SHORTSWORD;
case BASE_ITEM_LIGHTFLAIL:
return FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL;
case BASE_ITEM_LONGSWORD:
return FEAT_WEAPON_PROFICIENCY_LONGSWORD;
case BASE_ITEM_WARHAMMER:
return FEAT_WEAPON_PROFICIENCY_WARHAMMER;
case BASE_ITEM_BATTLEAXE:
return FEAT_WEAPON_PROFICIENCY_BATTLEAXE;
case BASE_ITEM_LONGBOW:
return FEAT_WEAPON_PROFICIENCY_LONGBOW;
case BASE_ITEM_BASTARDSWORD:
return FEAT_WEAPON_PROFICIENCY_BASTARD_SWORD;
case BASE_ITEM_LIGHTMACE:
return FEAT_WEAPON_PROFICIENCY_LIGHT_MACE;
case BASE_ITEM_LIGHTFLAIL:
return FEAT_WEAPON_PROFICIENCY_LIGHT_FLAIL;
case BASE_ITEM_HALBERD:
return FEAT_WEAPON_PROFICIENCY_HALBERD;
case BASE_ITEM_WARHAMMER:
return FEAT_WEAPON_PROFICIENCY_WARHAMMER;
case BASE_ITEM_SHORTBOW:
case BASE_ITEM_LONGBOW:
return FEAT_WEAPON_PROFICIENCY_LONGBOW;
case BASE_ITEM_LIGHTMACE:
return FEAT_WEAPON_PROFICIENCY_LIGHT_MACE;
case BASE_ITEM_HALBERD:
return FEAT_WEAPON_PROFICIENCY_HALBERD;
case BASE_ITEM_SHORTBOW:
return FEAT_WEAPON_PROFICIENCY_SHORTBOW;
case BASE_ITEM_TWOBLADEDSWORD:
case BASE_ITEM_TWOBLADEDSWORD:
return FEAT_WEAPON_PROFICIENCY_TWO_BLADED_SWORD;
case BASE_ITEM_GREATSWORD:
case BASE_ITEM_GREATSWORD:
return FEAT_WEAPON_PROFICIENCY_GREATSWORD;
case BASE_ITEM_GREATAXE:
case BASE_ITEM_GREATAXE:
return FEAT_WEAPON_PROFICIENCY_GREATAXE;
case BASE_ITEM_DART:
case BASE_ITEM_DART:
return FEAT_WEAPON_PROFICIENCY_DART;
case BASE_ITEM_DIREMACE:
case BASE_ITEM_DIREMACE:
return FEAT_WEAPON_PROFICIENCY_DIRE_MACE;
case BASE_ITEM_DOUBLEAXE:
case BASE_ITEM_DOUBLEAXE:
return FEAT_WEAPON_PROFICIENCY_DOUBLE_AXE;
case BASE_ITEM_HEAVYFLAIL:
case BASE_ITEM_HEAVYFLAIL:
return FEAT_WEAPON_PROFICIENCY_HEAVY_FLAIL;
case BASE_ITEM_LIGHTHAMMER:
case BASE_ITEM_LIGHTHAMMER:
return FEAT_WEAPON_PROFICIENCY_LIGHT_HAMMER;
case BASE_ITEM_HANDAXE:
case BASE_ITEM_HANDAXE:
return FEAT_WEAPON_PROFICIENCY_HANDAXE;
case BASE_ITEM_KAMA:
case BASE_ITEM_KAMA:
return FEAT_WEAPON_PROFICIENCY_KAMA;
case BASE_ITEM_KATANA:
case BASE_ITEM_KATANA:
return FEAT_WEAPON_PROFICIENCY_KATANA;
case BASE_ITEM_KUKRI:
case BASE_ITEM_KUKRI:
return FEAT_WEAPON_PROFICIENCY_KUKRI;
case BASE_ITEM_MORNINGSTAR:
case BASE_ITEM_MORNINGSTAR:
return FEAT_WEAPON_PROFICIENCY_MORNINGSTAR;
case BASE_ITEM_RAPIER:
case BASE_ITEM_RAPIER:
return FEAT_WEAPON_PROFICIENCY_RAPIER;
case BASE_ITEM_SCIMITAR:
case BASE_ITEM_SCIMITAR:
return FEAT_WEAPON_PROFICIENCY_SCIMITAR;
case BASE_ITEM_SCYTHE:
case BASE_ITEM_SCYTHE:
return FEAT_WEAPON_PROFICIENCY_SCYTHE;
case BASE_ITEM_SHORTSPEAR:
case BASE_ITEM_SHORTSPEAR:
return FEAT_WEAPON_PROFICIENCY_SHORTSPEAR;
case BASE_ITEM_SHURIKEN:
case BASE_ITEM_SHURIKEN:
return FEAT_WEAPON_PROFICIENCY_SHURIKEN;
case BASE_ITEM_SICKLE:
case BASE_ITEM_SICKLE:
return FEAT_WEAPON_PROFICIENCY_SICKLE;
case BASE_ITEM_SLING:
case BASE_ITEM_SLING:
return FEAT_WEAPON_PROFICIENCY_SLING;
case BASE_ITEM_THROWINGAXE:
case BASE_ITEM_THROWINGAXE:
return FEAT_WEAPON_PROFICIENCY_THROWING_AXE;
case BASE_ITEM_CSLASHWEAPON:
case BASE_ITEM_CSLASHWEAPON:
return FEAT_WEAPON_PROFICIENCY_CREATURE;
case BASE_ITEM_CPIERCWEAPON:
case BASE_ITEM_CPIERCWEAPON:
return FEAT_WEAPON_PROFICIENCY_CREATURE;
case BASE_ITEM_CBLUDGWEAPON:
case BASE_ITEM_CBLUDGWEAPON:
return FEAT_WEAPON_PROFICIENCY_CREATURE;
case BASE_ITEM_CSLSHPRCWEAP:
case BASE_ITEM_CSLSHPRCWEAP:
return FEAT_WEAPON_PROFICIENCY_CREATURE;
case BASE_ITEM_TRIDENT:
case BASE_ITEM_TRIDENT:
return FEAT_WEAPON_PROFICIENCY_TRIDENT;
case BASE_ITEM_DWARVENWARAXE:
case BASE_ITEM_DWARVENWARAXE:
return FEAT_WEAPON_PROFICIENCY_DWARVEN_WARAXE;
case BASE_ITEM_WHIP:
case BASE_ITEM_WHIP:
return FEAT_WEAPON_PROFICIENCY_WHIP;
case BASE_ITEM_ELVEN_LIGHTBLADE:
case BASE_ITEM_ELVEN_LIGHTBLADE:
return FEAT_WEAPON_PROFICIENCY_ELVEN_LIGHTBLADE;
case BASE_ITEM_ELVEN_THINBLADE:
case BASE_ITEM_ELVEN_THINBLADE:
return FEAT_WEAPON_PROFICIENCY_ELVEN_THINBLADE;
case BASE_ITEM_ELVEN_COURTBLADE:
case BASE_ITEM_ELVEN_COURTBLADE:
return FEAT_WEAPON_PROFICIENCY_ELVEN_COURTBLADE;
case BASE_ITEM_HEAVY_PICK:
case BASE_ITEM_HEAVY_PICK:
return FEAT_WEAPON_PROFICIENCY_HEAVY_PICK;
case BASE_ITEM_LIGHT_PICK:
case BASE_ITEM_LIGHT_PICK:
return FEAT_WEAPON_PROFICIENCY_LIGHT_PICK;
case BASE_ITEM_SAI:
case BASE_ITEM_SAI:
return FEAT_WEAPON_PROFICIENCY_SAI;
case BASE_ITEM_NUNCHAKU:
case BASE_ITEM_NUNCHAKU:
return FEAT_WEAPON_PROFICIENCY_NUNCHAKU;
case BASE_ITEM_FALCHION:
case BASE_ITEM_FALCHION:
return FEAT_WEAPON_PROFICIENCY_FALCHION;
case BASE_ITEM_SAP:
case BASE_ITEM_SAP:
return FEAT_WEAPON_PROFICIENCY_SAP;
case BASE_ITEM_KATAR:
case BASE_ITEM_KATAR:
return FEAT_WEAPON_PROFICIENCY_KATAR;
case BASE_ITEM_HEAVY_MACE:
case BASE_ITEM_HEAVY_MACE:
return FEAT_WEAPON_PROFICIENCY_HEAVY_MACE;
case BASE_ITEM_MAUL:
case BASE_ITEM_MAUL:
return FEAT_WEAPON_PROFICIENCY_MAUL;
case BASE_ITEM_DOUBLE_SCIMITAR:
case BASE_ITEM_DOUBLE_SCIMITAR:
return FEAT_WEAPON_PROFICIENCY_DOUBLE_SCIMITAR;
case BASE_ITEM_GOAD:
case BASE_ITEM_GOAD:
return FEAT_WEAPON_PROFICIENCY_GOAD;
case BASE_ITEM_EAGLE_CLAW:
case BASE_ITEM_EAGLE_CLAW:
return FEAT_WEAPON_PROFICIENCY_EAGLE_CLAW;
default:
return FEAT_WEAPON_PROFICIENCY_SIMPLE;
default:
return FEAT_WEAPON_PROFICIENCY_SIMPLE;
}
return 0;

View File

@@ -1206,11 +1206,12 @@ const int IP_CONST_FEAT_REGENERATION_5 = 24820;
const int IP_CONST_FEAT_SCENT = 24821;
const int IP_CONST_FEAT_GIANT_RACIAL_TYPE = 24822;
const int IP_CONST_FEAT_TEMPLATE_ARCHLICH_MARKER = 16401; //:: Archlich
const int IP_CONST_FEAT_TEMPLATE_TURN_UNDEAD = 16402;
const int IP_CONST_FEAT_TEMPLATE_PROJECTION = 24823;
const int IP_CONST_FEAT_TEMPLATE_END_PROJECTION = 24824;
const int IP_CONST_FEAT_TEMPLATE_ANIMATE_DEAD = 24825;
const int IP_CONST_FEAT_TEMPLATE_ARCHLICH_MARKER = 16401; //:: Archlich
const int IP_CONST_FEAT_TEMPLATE_TURN_UNDEAD = 16402;
const int IP_CONST_FEAT_TEMPLATE_BAELNORN_MARKER = 16409; //:: Baelnorn
const int IP_CONST_FEAT_TEMPLATE_PROJECTION = 24823;
const int IP_CONST_FEAT_TEMPLATE_END_PROJECTION = 24824;
const int IP_CONST_FEAT_TEMPLATE_ANIMATE_DEAD = 24825;
const int IP_CONST_FEAT_TEMPLATE_SAINT_SLA_BLESS = 16403; //:: Saint
//const int IP_CONST_FEAT_TEMPLATE_SAINT_SLA_GUIDANCE = 16404;
const int IP_CONST_FEAT_TEMPLATE_SAINT_SLA_RESISTANCE = 16405;

View File

@@ -29,6 +29,10 @@ const int BASE_ITEM_CRAFTED_STAFF = 201;
const int BASE_ITEM_ELVEN_LIGHTBLADE = 202;
const int BASE_ITEM_ELVEN_THINBLADE = 203;
const int BASE_ITEM_ELVEN_COURTBLADE = 204;
const int BASE_ITEM_CRAFT_SCEPTER = 249;
const int BASE_ITEM_MAGIC_SCEPTER = 250;
const int BASE_ITEM_MUNDANE_HERB = 252;
const int BASE_ITEM_INFUSED_HERB = 253;
//:://////////////////////////////////////////////
//:: Player Health Const

View File

@@ -782,7 +782,7 @@ int IsClassAllowedToUseLevelUpNUI(int nClass)
return TRUE;
if (nClass == CLASS_TYPE_ARCHIVIST)
return TRUE;
return TRUE;
return FALSE;
}
@@ -1566,6 +1566,10 @@ void FinishLevelUp(int nClass, object oPC=OBJECT_SELF)
int nLevel = GetLevelByClass(nClass, oPC);
SetPersistantLocalInt(oPC, "LastSpellGainLevel", nLevel);
}
if (GetIsBladeMagicClass(nClass))
{
DeletePersistantLocalInt(oPC, "AllowedDisciplines");
}
ClearLevelUpNUICaches(nClass, oPC);
}
@@ -3334,3 +3338,5 @@ json GetArchivistNewSpellsList(object oPC=OBJECT_SELF)
SetLocalJson(oPC, NUI_LEVEL_UP_ARCHIVIST_NEW_SPELLS_LIST_VAR, retValue);
return retValue;
}
//:: void main(){}

View File

@@ -387,8 +387,7 @@ int IsClassAllowedToUseNUISpellbook(object oPlayer, int nClass)
return TRUE;
// Arcane Spont
if (nClass == CLASS_TYPE_ASSASSIN
|| nClass == CLASS_TYPE_BEGUILER
if (nClass == CLASS_TYPE_BEGUILER
|| nClass == CLASS_TYPE_CELEBRANT_SHARESS
|| nClass == CLASS_TYPE_DREAD_NECROMANCER
|| nClass == CLASS_TYPE_DUSKBLADE
@@ -506,8 +505,7 @@ int CanClassUseMetamagicFeats(int nClass)
// I don't want to spend the time looping through each class's
// feat 2da so this is the list of all classes that are allowed to use the
// Spellbook NUI and can use Metamagic
return (nClass == CLASS_TYPE_ASSASSIN
|| nClass == CLASS_TYPE_BARD
return (nClass == CLASS_TYPE_BARD
|| nClass == CLASS_TYPE_SORCERER
|| nClass == CLASS_TYPE_BEGUILER
|| nClass == CLASS_TYPE_DREAD_NECROMANCER
@@ -527,7 +525,6 @@ int CanClassUseSuddenMetamagicFeats(int nClass)
// Spellbook NUI and can use Sudden Metamagic
return (nClass == CLASS_TYPE_SHADOWLORD
|| nClass == CLASS_TYPE_ARCHIVIST
|| nClass == CLASS_TYPE_ASSASSIN
|| nClass == CLASS_TYPE_BARD
|| nClass == CLASS_TYPE_BEGUILER
|| nClass == CLASS_TYPE_DREAD_NECROMANCER
@@ -845,4 +842,4 @@ int IsSpellbookNUIOpen(object oPC)
}
return FALSE;
}
}

View File

@@ -22,6 +22,9 @@ const int SPELL_BCM_RENDING_CLAWS = 17997;
//:: Complete Warrior
const int SPELL_RANGED_DISARM = 3493;
//:: Tome of Battle
const int SPELL_TOB_SNAP_KICK = 3794;
//marshal
const int SPELL_MINAUR_DEMFORT = 3500;
const int SPELL_MINAUR_FORCEWILL = 3501;
@@ -1289,6 +1292,69 @@ const int SPELL_SUMMON_CREATURE_IX_WATER = 3200;
//:: Player's Handbook Spells
const int SPELL_SPIRITUAL_WEAPON = 17249;
const int SPELL_SUMMON_NATURES_ALLY_1 = 17000;
const int SPELL_SUMMON_NATURES_ALLY_1_DIREBADGER = 17001;
const int SPELL_SUMMON_NATURES_ALLY_1_DIRERAT = 17002;
const int SPELL_SUMMON_NATURES_ALLY_1_DOG = 17003;
const int SPELL_SUMMON_NATURES_ALLY_1_HAWK = 17004;
const int SPELL_SUMMON_NATURES_ALLY_1_TINY_VIPER = 17005;
const int SPELL_SUMMON_NATURES_ALLY_2 = 17010;
const int SPELL_SUMMON_NATURES_ALLY_2_DIREBOAR = 17011;
const int SPELL_SUMMON_NATURES_ALLY_2_COOSHEE = 17012;
const int SPELL_SUMMON_NATURES_ALLY_2_WOLF = 17013;
const int SPELL_SUMMON_NATURES_ALLY_2_SMALL_VIPER = 17014;
const int SPELL_SUMMON_NATURES_ALLY_2_BLACKBEAR = 17015;
const int SPELL_SUMMON_NATURES_ALLY_3 = 17020;
const int SPELL_SUMMON_NATURES_ALLY_3_BROWNBEAR = 17021;
const int SPELL_SUMMON_NATURES_ALLY_3_DIREWOLK = 17022;
const int SPELL_SUMMON_NATURES_ALLY_3_LARGE_VIPER = 17023;
const int SPELL_SUMMON_NATURES_ALLY_3_LEOPARD = 17024;
const int SPELL_SUMMON_NATURES_ALLY_3_SATYR = 17025;
const int SPELL_SUMMON_NATURES_ALLY_4 = 17030;
const int SPELL_SUMMON_NATURES_ALLY_4_LION = 17031;
const int SPELL_SUMMON_NATURES_ALLY_4_POLAR_BEAR = 17032;
const int SPELL_SUMMON_NATURES_ALLY_4_DIRE_SPIDER = 17033;
const int SPELL_SUMMON_NATURES_ALLY_4_HUGE_VIPER = 17034;
const int SPELL_SUMMON_NATURES_ALLY_4_WEREBOAR = 17035;
const int SPELL_SUMMON_NATURES_ALLY_5 = 17040;
const int SPELL_SUMMON_NATURES_ALLY_5_MED_AIR = 17041;
const int SPELL_SUMMON_NATURES_ALLY_5_MED_EARTH = 17042;
const int SPELL_SUMMON_NATURES_ALLY_5_MED_FIRE = 17043;
const int SPELL_SUMMON_NATURES_ALLY_5_MED_WATER = 17044;
const int SPELL_SUMMON_NATURES_ALLY_5_DIRE_BEAR = 17045;
const int SPELL_SUMMON_NATURES_ALLY_6 = 17050;
const int SPELL_SUMMON_NATURES_ALLY_6_LG_AIR = 17051;
const int SPELL_SUMMON_NATURES_ALLY_6_LG_EARTH = 17052;
const int SPELL_SUMMON_NATURES_ALLY_6_LG_FIRE = 17053;
const int SPELL_SUMMON_NATURES_ALLY_6_LG_WATER = 17054;
const int SPELL_SUMMON_NATURES_ALLY_6_DIRETIGER = 17055;
const int SPELL_SUMMON_NATURES_ALLY_7 = 17060;
const int SPELL_SUMMON_NATURES_ALLY_7_BULETTE = 17061;
const int SPELL_SUMMON_NATURES_ALLY_7_INVSTALKER = 17062;
const int SPELL_SUMMON_NATURES_ALLY_7_PIXIE = 17063;
const int SPELL_SUMMON_NATURES_ALLY_7_GORGON = 17064;
const int SPELL_SUMMON_NATURES_ALLY_7_MANTICORE = 17065;
const int SPELL_SUMMON_NATURES_ALLY_8 = 17070;
const int SPELL_SUMMON_NATURES_ALLY_8_GR_AIR = 17071;
const int SPELL_SUMMON_NATURES_ALLY_8_GR_EARTH = 17072;
const int SPELL_SUMMON_NATURES_ALLY_8_GR_FIRE = 17073;
const int SPELL_SUMMON_NATURES_ALLY_8_GR_WATER = 17074;
const int SPELL_SUMMON_NATURES_ALLY_8_NYMPH = 17075;
const int SPELL_SUMMON_NATURES_ALLY_9 = 17080;
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_AIR = 17081;
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_EARTH = 17082;
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_FIRE = 17083;
const int SPELL_SUMMON_NATURES_ALLY_9_ELD_WATER = 17084;
const int SPELL_SUMMON_NATURES_ALLY_9_ARANEA = 17085;
//:: Player's Handbook II Spells
const int SPELL_CHASING_PERFECTION = 2479;
@@ -1297,12 +1363,34 @@ const int SPELL_SPIRIT_WORM = 17248;
const int SPELL_FORCE_MISSILES = 2480;
//:: Masters of the Wild Spells
const int SPELL_FORESTFOLD = 17090;
const int SPELL_CREEPING_COLD = 17091;
const int SPELL_GREATER_CREEPING_COLD = 17092;
const int SPELL_CONTROL_PLANTS = 17237;
const int SPELL_ADRENALINE_SURGE = 17238;
const int SPELL_INVULNERABILITY_TO_ELEMENTS = 17239;
const int SPELL_REGEN_RING = 17241;
const int SPELL_REGEN_CIRCLE = 17242;
const int SPELL_REGEN_LIGHT_WOUNDS = 17243;
const int SPELL_REGEN_MODERATE_WOUNDS = 17244;
const int SPELL_REGEN_SERIOUS_WOUNDS = 17245;
const int SPELL_REGEN_CRITICAL_WOUNDS = 17246;
const int SPELL_SPEED_WIND = 17247;
const int SPELL_TORTISE_SHELL = 17250;
const int SPELL_TORTISE_SHELL = 17250;
//:: Book of Exalted Deeds Spells
const int SPELL_LEONALS_ROAR = 17240;
//:: Master of the Wild Feats
const int SPELL_VL_WILD_SHAPE_TREANT = 17989;
const int SPELL_VL_ANIMATE_TREE = 17990;
const int SPELL_PLANT_DEFIANCE = 17991;
const int SPELL_PLANT_CONTROL = 17992;
//:: Book of Exalted Deeds Feats
const int SPELL_FOT_LEONALS_ROAR = 17993;
const int SPELL_FOT_LIONS_SWIFTNESS = 17994;
const int SPELL_FAVORED_OF_THE_COMPANIONS = 17995;
//x
const int SPELL_TENSERS_FLOATING_DISK = 3849;

View File

@@ -299,6 +299,7 @@ int SpellfireDrainItem(object oPC, object oItem, int bCharged = TRUE, int bSingl
{
if((nBase == BASE_ITEM_POTIONS) ||
(nBase == BASE_ITEM_INFUSED_HERB) ||
(nBase == BASE_ITEM_SCROLL) ||
(nBase == BASE_ITEM_SPELLSCROLL) ||
(nBase == BASE_ITEM_BLANK_POTION) ||
@@ -382,6 +383,7 @@ void SpellfireDrain(object oPC, object oTarget, int bCharged = TRUE, int bExempt
if(GetPRCSwitch(PRC_SPELLFIRE_DISALLOW_DRAIN_SCROLL_POTION) &&
((nBase == BASE_ITEM_POTIONS) ||
(nBase == BASE_ITEM_SCROLL) ||
(nBase == BASE_ITEM_INFUSED_HERB) ||
(nBase == BASE_ITEM_BLANK_POTION) ||
(nBase == BASE_ITEM_BLANK_SCROLL)
)
@@ -525,3 +527,4 @@ void SpellfireCrown(object oPC)
}
}
//:: void main() {}

View File

@@ -18,6 +18,7 @@ const int TEMPLATE_CURST = 26;
const int TEMPLATE_GRAVETOUCHED_GHOUL = 29;
const int TEMPLATE_CRYPTSPAWN = 30;
const int TEMPLATE_ARCHLICH = 99;
const int TEMPLATE_BAELNORN = 100;
const int TEMPLATE_LICH = 101;
const int TEMPLATE_DEMILICH = 102;
const int TEMPLATE_NECROPOLITAN = 105;

View File

@@ -13,7 +13,7 @@
//:: Created On: 2003-05-09
//:: Last Updated On: 2003-10-14
//:://////////////////////////////////////////////
#include "prc_x2_itemprop"
struct craft_struct
{
@@ -44,22 +44,24 @@ const string X2_CI_CRAFTSKILL_CONV ="x2_p_craftskills";
/* moved to be code switches
const int X2_CI_BREWPOTION_MAXLEVEL = 3; // Max Level for potions
const int X2_CI_BREWPOTION_COSTMODIFIER = 50; // gp Brew Potion XPCost Modifier
const int PRC_X2_BREWPOTION_COSTMODIFIER = 50; // gp Brew Potion XPCost Modifier
// Scribe Scroll related constants
const int X2_CI_SCRIBESCROLL_COSTMODIFIER = 25; // Scribescroll Cost Modifier
const int PRC_X2_SCRIBESCROLL_COSTMODIFIER = 25; // Scribescroll Cost Modifier
// Craft Wand related constants
const int X2_CI_CRAFTWAND_MAXLEVEL = 4;
const int X2_CI_CRAFTWAND_COSTMODIFIER = 750;
const int PRC_X2_CRAFTWAND_MAXLEVEL = 4;
const int PRC_X2_CRAFTWAND_COSTMODIFIER = 750;
*/
const int X2_CI_BREWPOTION_FEAT_ID = 944; // Brew Potion feat simulation
const int X2_CI_SCRIBESCROLL_FEAT_ID = 945;
const int X2_CI_CRAFTWAND_FEAT_ID = 946;
const int X2_CI_CRAFTROD_FEAT_ID = 2927;
const int X2_CI_CRAFTROD_EPIC_FEAT_ID = 3490;
const int X2_CI_CRAFTSTAFF_FEAT_ID = 2928;
const int X2_CI_CRAFTSTAFF_EPIC_FEAT_ID = 3491;
const int X2_CI_BREWPOTION_FEAT_ID = 944; // Brew Potion feat simulation
const int X2_CI_SCRIBESCROLL_FEAT_ID = 945;
const int X2_CI_CRAFTWAND_FEAT_ID = 946;
const int X2_CI_CRAFTROD_FEAT_ID = 2927;
const int X2_CI_CRAFTROD_EPIC_FEAT_ID = 3490;
const int X2_CI_CRAFTSTAFF_FEAT_ID = 2928;
const int X2_CI_CRAFTSTAFF_EPIC_FEAT_ID = 3491;
const int X2_CI_CREATEINFUSION_FEAT_ID = 25960;
const string X2_CI_BREWPOTION_NEWITEM_RESREF = "x2_it_pcpotion"; // ResRef for new potion item
const string X2_CI_SCRIBESCROLL_NEWITEM_RESREF = "x2_it_pcscroll"; // ResRef for new scroll item
const string X2_CI_CRAFTWAND_NEWITEM_RESREF = "x2_it_pcwand";
@@ -185,6 +187,17 @@ int CheckAlternativeCrafting(object oPC, int nSpell, struct craft_cost_struct co
// Returns the maximum of caster level used and other effective levels from emulating spells
int GetAlternativeCasterLevel(object oPC, int nLevel);
// -----------------------------------------------------------------------------
// Create and Return an herbal infusion with an item property
// matching nSpellID.
// -----------------------------------------------------------------------------
object CICreateInfusion(object oCreator, int nSpellID);
// -----------------------------------------------------------------------------
// Returns TRUE if the player successfully performed Create Infusion
// -----------------------------------------------------------------------------
int CICraftCheckCreateInfusion(object oSpellTarget, object oCaster, int nID = 0);
//////////////////////////////////////////////////
/* Include section */
//////////////////////////////////////////////////
@@ -194,6 +207,7 @@ int GetAlternativeCasterLevel(object oPC, int nLevel);
#include "prc_inc_newip"
#include "prc_inc_spells"
#include "prc_add_spell_dc"
#include "inc_infusion"
//////////////////////////////////////////////////
/* Function definitions */
@@ -261,7 +275,8 @@ int CIGetIsCraftFeatBaseItem(object oItem)
nBt == BASE_ITEM_BLANK_SCROLL ||
nBt == BASE_ITEM_BLANK_WAND ||
nBt == BASE_ITEM_CRAFTED_ROD ||
nBt == BASE_ITEM_CRAFTED_STAFF)
nBt == BASE_ITEM_CRAFTED_STAFF ||
nBt == BASE_ITEM_MUNDANE_HERB)
return TRUE;
else
return FALSE;
@@ -453,11 +468,158 @@ object CICraftCraftWand(object oCreator, int nSpellID )
// -----------------------------------------------------------------------------
// Georg, 2003-06-12
// Create and Return a magic wand with an item property
// matching nSpellID. Charges are set to d20 + casterlevel
// capped at 50 max
// Create and Return a magic scroll with an item property
// matching nSpellID.
// -----------------------------------------------------------------------------
object CICraftScribeScroll(object oCreator, int nSpellID)
{
if (DEBUG) DoDebug("CICraftScribeScroll: Enter (nSpellID=" + IntToString(nSpellID) + ")");
// Keep original and compute one-step master (if subradial)
int nSpellOriginal = nSpellID;
int nSpellMaster = nSpellOriginal;
if (GetIsSubradialSpell(nSpellOriginal))
{
nSpellMaster = GetMasterSpellFromSubradial(nSpellOriginal);
if (DEBUG) DoDebug("CICraftScribeScroll: subradial detected original=" + IntToString(nSpellOriginal) + " master=" + IntToString(nSpellMaster));
}
// Prefer iprp mapping for the original, fallback to master
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellOriginal);
int nSpellUsedForIP = nSpellOriginal;
if (nPropID < 0)
{
if (DEBUG) DoDebug("CICraftScribeScroll: no iprp for original " + IntToString(nSpellOriginal) + ", trying master " + IntToString(nSpellMaster));
nPropID = IPGetIPConstCastSpellFromSpellID(nSpellMaster);
nSpellUsedForIP = nSpellMaster;
}
// If neither original nor master has an iprp row, we can still try templates,
// but most templates expect a matching iprp. Bail out now if nothing found.
if (nPropID < 0)
{
if (DEBUG) DoDebug("CICraftScribeScroll: no iprp_spells entry for original/master -> aborting");
FloatingTextStringOnCreature("This spell cannot be scribed (no item property mapping).", oCreator, FALSE);
return OBJECT_INVALID;
}
if (DEBUG) DoDebug("CICraftScribeScroll: using spell " + IntToString(nSpellUsedForIP) + " (iprp row " + IntToString(nPropID) + ") for item property");
// Material component check (based on resolved iprp row)
string sMat = GetMaterialComponentTag(nPropID);
if (sMat != "")
{
object oMat = GetItemPossessedBy(oCreator, sMat);
if (oMat == OBJECT_INVALID)
{
FloatingTextStrRefOnCreature(83374, oCreator); // Missing material component
return OBJECT_INVALID;
}
else
{
DestroyObject(oMat);
}
}
// Resolve class and scroll template
int nClass = PRCGetLastSpellCastClass();
string sClass = "";
switch (nClass)
{
case CLASS_TYPE_WIZARD:
case CLASS_TYPE_SORCERER: sClass = "Wiz_Sorc"; break;
case CLASS_TYPE_CLERIC:
case CLASS_TYPE_UR_PRIEST: sClass = "Cleric"; break;
case CLASS_TYPE_PALADIN: sClass = "Paladin"; break;
case CLASS_TYPE_DRUID:
case CLASS_TYPE_BLIGHTER: sClass = "Druid"; break;
case CLASS_TYPE_RANGER: sClass = "Ranger"; break;
case CLASS_TYPE_BARD: sClass = "Bard"; break;
case CLASS_TYPE_ASSASSIN: sClass = "Assassin"; break;
}
object oTarget = OBJECT_INVALID;
string sResRef = "";
// Try to find a class-specific scroll template.
if (sClass != "")
{
// Try original first (so if you made a subradial-specific template it will be used)
sResRef = Get2DACache(X2_CI_2DA_SCROLLS, sClass, nSpellOriginal);
if (sResRef == "")
{
// fallback to the spell that matched an iprp row (master or original)
sResRef = Get2DACache(X2_CI_2DA_SCROLLS, sClass, nSpellUsedForIP);
}
if (sResRef != "")
{
oTarget = CreateItemOnObject(sResRef, oCreator);
if (DEBUG) DoDebug("CICraftScribeScroll: created template " + sResRef + " for class " + sClass);
// Ensure template uses the correct cast-spell property: replace the template's cast-spell IP with ours
if (oTarget != OBJECT_INVALID)
{
itemproperty ipIter = GetFirstItemProperty(oTarget);
while (GetIsItemPropertyValid(ipIter))
{
if (GetItemPropertyType(ipIter) == ITEM_PROPERTY_CAST_SPELL)
{
RemoveItemProperty(oTarget, ipIter);
break;
}
ipIter = GetNextItemProperty(oTarget);
}
itemproperty ipSpell = ItemPropertyCastSpell(nPropID, IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE);
AddItemProperty(DURATION_TYPE_PERMANENT, ipSpell, oTarget);
}
}
}
// If no template or sClass was empty, create generic scroll and add itemprop.
if (oTarget == OBJECT_INVALID)
{
sResRef = "craft_scroll";
oTarget = CreateItemOnObject(sResRef, oCreator);
if (oTarget == OBJECT_INVALID)
{
WriteTimestampedLogEntry("CICraftScribeScroll: failed to create craft_scroll template.");
return OBJECT_INVALID;
}
// Remove existing default IP and add correct one
itemproperty ipFirst = GetFirstItemProperty(oTarget);
if (GetIsItemPropertyValid(ipFirst))
RemoveItemProperty(oTarget, ipFirst);
itemproperty ipSpell = ItemPropertyCastSpell(nPropID, IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE);
AddItemProperty(DURATION_TYPE_PERMANENT, ipSpell, oTarget);
}
// Add PRC metadata (use the same spell that matched the iprp row so metadata and IP line up)
if (GetPRCSwitch(PRC_SCRIBE_SCROLL_CASTER_LEVEL))
{
int nCasterLevel = GetAlternativeCasterLevel(oCreator, PRCGetCasterLevel(oCreator));
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpellUsedForIP, nCasterLevel);
AddItemProperty(DURATION_TYPE_PERMANENT, ipLevel, oTarget);
itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpellUsedForIP, PRCGetMetaMagicFeat());
AddItemProperty(DURATION_TYPE_PERMANENT, ipMeta, oTarget);
int nDC = PRCGetSpellSaveDC(nSpellUsedForIP, GetSpellSchool(nSpellUsedForIP), OBJECT_SELF);
itemproperty ipDC = ItemPropertyCastSpellDC(nSpellUsedForIP, nDC);
AddItemProperty(DURATION_TYPE_PERMANENT, ipDC, oTarget);
}
if (oTarget == OBJECT_INVALID)
{
WriteTimestampedLogEntry("prc_x2_craft::CICraftScribeScroll failed - Resref: " + sResRef + " Class: " + sClass + "(" + IntToString(nClass) + ") " + " SpellID " + IntToString(nSpellID));
return OBJECT_INVALID;
}
if (DEBUG) DoDebug("CICraftScribeScroll: Success - created scroll " + sResRef + " for spell " + IntToString(nSpellUsedForIP));
return oTarget;
}
/* object CICraftScribeScroll(object oCreator, int nSpellID)
{
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellID);
object oTarget;
@@ -491,6 +653,7 @@ object CICraftScribeScroll(object oCreator, int nSpellID)
break;
case CLASS_TYPE_CLERIC:
case CLASS_TYPE_UR_PRIEST:
case CLASS_TYPE_OCULAR:
sClass = "Cleric";
break;
case CLASS_TYPE_PALADIN:
@@ -506,6 +669,9 @@ object CICraftScribeScroll(object oCreator, int nSpellID)
case CLASS_TYPE_BARD:
sClass = "Bard";
break;
case CLASS_TYPE_ASSASSIN:
sClass = "Assassin";
break;
}
string sResRef;
if (sClass != "")
@@ -542,7 +708,7 @@ object CICraftScribeScroll(object oCreator, int nSpellID)
}
return oTarget;
}
*/
// -----------------------------------------------------------------------------
// Returns TRUE if the player used the last spell to brew a potion
// -----------------------------------------------------------------------------
@@ -593,7 +759,7 @@ These dont work as IPs since they are hardcoded */
// -------------------------------------------------------------------------
// check if spell is below maxlevel for brew potions
// -------------------------------------------------------------------------
int nPotionMaxLevel = GetPRCSwitch(X2_CI_BREWPOTION_MAXLEVEL);
int nPotionMaxLevel = GetPRCSwitch(PRC_X2_BREWPOTION_MAXLEVEL);
if(nPotionMaxLevel == 0)
nPotionMaxLevel = 3;
@@ -624,7 +790,7 @@ These dont work as IPs since they are hardcoded */
// -------------------------------------------------------------------------
// XP/GP Cost Calculation
// -------------------------------------------------------------------------
int nCostModifier = GetPRCSwitch(X2_CI_BREWPOTION_COSTMODIFIER);
int nCostModifier = GetPRCSwitch(PRC_X2_BREWPOTION_COSTMODIFIER);
if(nCostModifier == 0)
nCostModifier = 50;
int nCost = CIGetCraftGPCost(nLevel, nCostModifier, PRC_BREW_POTION_CASTER_LEVEL);
@@ -728,7 +894,7 @@ int CICraftCheckScribeScroll(object oSpellTarget, object oCaster, int nID = 0)
// XP/GP Cost Calculation
// -------------------------------------------------------------------------
int nLevel = CIGetSpellInnateLevel(nID,TRUE);
int nCostModifier = GetPRCSwitch(X2_CI_SCRIBESCROLL_COSTMODIFIER);
int nCostModifier = GetPRCSwitch(PRC_X2_SCRIBESCROLL_COSTMODIFIER);
if(nCostModifier == 0)
nCostModifier = 25;
int nCost = CIGetCraftGPCost(nLevel, nCostModifier, PRC_SCRIBE_SCROLL_CASTER_LEVEL);
@@ -884,7 +1050,7 @@ These dont work as IPs since they are hardcoded */
// -------------------------------------------------------------------------
// check if spell is below maxlevel for craft want
// -------------------------------------------------------------------------
int nMaxLevel = GetPRCSwitch(X2_CI_CRAFTWAND_MAXLEVEL);
int nMaxLevel = GetPRCSwitch(PRC_X2_CRAFTWAND_MAXLEVEL);
if(nMaxLevel == 0)
nMaxLevel = 4;
if (nLevel > nMaxLevel)
@@ -896,7 +1062,7 @@ These dont work as IPs since they are hardcoded */
// -------------------------------------------------------------------------
// XP/GP Cost Calculation
// -------------------------------------------------------------------------
int nCostMod = GetPRCSwitch(X2_CI_CRAFTWAND_COSTMODIFIER);
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTWAND_COSTMODIFIER);
if(nCostMod == 0)
nCostMod = 750;
int nCost = CIGetCraftGPCost(nLevel, nCostMod, PRC_CRAFT_WAND_CASTER_LEVEL);
@@ -1027,7 +1193,7 @@ int CICraftCheckCraftStaff(object oSpellTarget, object oCaster, int nSpellID = 0
These dont work as IPs since they are hardcoded */
}
}
int nCostMod = GetPRCSwitch(X2_CI_CRAFTSTAFF_COSTMODIFIER);
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTSTAFF_COSTMODIFIER);
if(!nCostMod) nCostMod = 750;
int nLvlRow = IPGetIPConstCastSpellFromSpellID(nSpellID);
int nCLevel = StringToInt(Get2DACache("iprp_spells","CasterLvl",nLvlRow));
@@ -1175,7 +1341,7 @@ int CICraftCheckCraftRod(object oSpellTarget, object oCaster, int nSpellID = 0)
These dont work as IPs since they are hardcoded */
}
}
int nCostMod = GetPRCSwitch(X2_CI_CRAFTROD_COSTMODIFIER);
int nCostMod = GetPRCSwitch(PRC_X2_CRAFTROD_COSTMODIFIER);
if(!nCostMod) nCostMod = 750;
int nLvlRow = IPGetIPConstCastSpellFromSpellID(nSpellID);
int nCLevel = StringToInt(Get2DACache("iprp_spells","CasterLvl",nLvlRow));
@@ -1544,7 +1710,7 @@ int AttuneGem(object oTarget = OBJECT_INVALID, object oCaster = OBJECT_INVALID,
// No point scribing Gems from items, and its not allowed.
if (oItem != OBJECT_INVALID)
{
FloatingTextStringOnCreature("You cannot scribe a Gem from an item.", oCaster, FALSE);
FloatingTextStringOnCreature("You cannot attune a Gem from an item.", oCaster, FALSE);
return TRUE;
}
// oTarget here should be the gem. If it's not, fail.
@@ -1951,7 +2117,13 @@ int CIGetSpellWasUsedForItemCreation(object oSpellTarget)
// -------------------------------------------------
nRet = CICraftCheckCraftStaff(oSpellTarget,oCaster);
break;
case BASE_ITEM_MUNDANE_HERB :
// -------------------------------------------------
// Create Infusion
// -------------------------------------------------
nRet = CICraftCheckCreateInfusion(oSpellTarget,oCaster);
break;
// you could add more crafting basetypes here....
}
@@ -2740,6 +2912,11 @@ int GetMagicalArtisanFeat(int nCraftingFeat)
nReturn = FEAT_MAGICAL_ARTISAN_CRAFT_SKULL_TALISMAN;
break;
}
case FEAT_CREATE_INFUSION:
{
nReturn = FEAT_MAGICAL_ARTISAN_CREATE_INFUSION;
break;
}
default:
{
if(DEBUG) DoDebug("GetMagicalArtisanFeat: invalid crafting feat");
@@ -2941,6 +3118,304 @@ int GetAlternativeCasterLevel(object oPC, int nLevel)
return nLevel;
}
// -----------------------------------------------------------------------------
// Returns TRUE if the player successfully performed Create Infusion
// -----------------------------------------------------------------------------
int CICraftCheckCreateInfusion(object oSpellTarget, object oCaster, int nID = 0)
{
if (nID == 0) nID = PRCGetSpellId();
int bIsSubradial = GetIsSubradialSpell(nID);
if(bIsSubradial)
{
nID = GetMasterSpellFromSubradial(nID);
}
// -------------------------------------------------------------------------
// Check if the caster has the Create Infusion feat
// -------------------------------------------------------------------------
if (!GetHasFeat(FEAT_CREATE_INFUSION, oCaster))
{
FloatingTextStrRefOnCreature(40487, oCaster); // Missing feat
return TRUE;
}
// -------------------------------------------------------------------------
// Divine spellcasters only
// -------------------------------------------------------------------------
int nClass = PRCGetLastSpellCastClass();
if (!GetIsDivineClass(nClass))
{
FloatingTextStringOnCreature("Only divine casters can create infusions.", oCaster, FALSE);
return TRUE;
}
// -------------------------------------------------------------------------
// Check if spell is restricted for Create Infusion
// -------------------------------------------------------------------------
if (CIGetIsSpellRestrictedFromCraftFeat(nID, X2_CI_CREATEINFUSION_FEAT_ID))
{
FloatingTextStrRefOnCreature(83451, oCaster); // Spell not allowed
return TRUE;
}
// -------------------------------------------------------------------------
// Optional PnP Herb check
// -------------------------------------------------------------------------
int bPnPHerbs = GetPRCSwitch(PRC_CREATE_INFUSION_OPTIONAL_HERBS);
if(bPnPHerbs)
{
int nSpellschool = GetSpellSchool(nID);
int nHerbSchool = GetHerbsSpellSchool(oSpellTarget);
int nSpellLevel = PRCGetSpellLevelForClass(nID, nClass);
int nHerbLevel = GetHerbsInfusionSpellLevel(oSpellTarget);
if(nSpellschool != nHerbSchool)
{
// Herb is for wrong spellschool
FloatingTextStringOnCreature("This herb isn't appropriate for this spell school", oCaster);
return TRUE;
}
if(nSpellLevel > nHerbLevel)
{
// Herb spell circle level too low
FloatingTextStringOnCreature("This herb isn't appropriate for this spell level", oCaster);
return TRUE;
}
}
// -------------------------------------------------------------------------
// XP/GP Cost Calculation
// -------------------------------------------------------------------------
int nLevel = CIGetSpellInnateLevel(nID, TRUE);
int nCostModifier = GetPRCSwitch(PRC_X2_CREATEINFUSION_COSTMODIFIER);
if (nCostModifier == 0)
nCostModifier = 25;
int nCost = CIGetCraftGPCost(nLevel, nCostModifier, PRC_CREATE_INFUSION_CASTER_LEVEL);
struct craft_cost_struct costs = GetModifiedCostsFromBase(nCost, oCaster, FEAT_CREATE_INFUSION, FALSE);
// Adjust level for metamagic
if (GetPRCSwitch(PRC_CREATE_INFUSION_CASTER_LEVEL))
{
int nMetaMagic = PRCGetMetaMagicFeat();
switch(nMetaMagic)
{
case METAMAGIC_EMPOWER: nLevel += 2; break;
case METAMAGIC_EXTEND: nLevel += 1; break;
case METAMAGIC_MAXIMIZE: nLevel += 3; break;
// Unsupported metamagic IPs not added
}
}
// -------------------------------------------------------------------------
// Check Gold
// -------------------------------------------------------------------------
if (!GetHasGPToSpend(oCaster, costs.nGoldCost))
{
FloatingTextStrRefOnCreature(3786, oCaster); // Not enough gold
return TRUE;
}
// -------------------------------------------------------------------------
// Check XP
// -------------------------------------------------------------------------
if (!GetHasXPToSpend(oCaster, costs.nXPCost))
{
FloatingTextStrRefOnCreature(3785, oCaster); // Not enough XP
return TRUE;
}
// -------------------------------------------------------------------------
// Check alternative spell emulation requirements
// -------------------------------------------------------------------------
if (!CheckAlternativeCrafting(oCaster, nID, costs))
{
FloatingTextStringOnCreature("*Crafting failed!*", oCaster, FALSE);
return TRUE;
}
// -------------------------------------------------------------------------
// Create the infused herb item
// -------------------------------------------------------------------------
object oInfusion = CICreateInfusion(oCaster, nID);
if (GetIsObjectValid(oInfusion))
{
// Get the spell's display name from spells.2da via TLK
int nNameStrRef = StringToInt(Get2DAString("spells", "Name", nID));
string sSpellName = GetStringByStrRef(nNameStrRef);
// Rename the item
string sNewName = "Infusion of " + sSpellName;
SetName(oInfusion, sNewName);
// Post-creation actions
SetIdentified(oInfusion, TRUE);
ActionPlayAnimation(ANIMATION_FIREFORGET_READ, 1.0);
SpendXP(oCaster, costs.nXPCost);
SpendGP(oCaster, costs.nGoldCost);
DestroyObject(oSpellTarget);
FloatingTextStrRefOnCreature(8502, oCaster); // Item creation successful
if (!costs.nTimeCost) costs.nTimeCost = 1;
AdvanceTimeForPlayer(oCaster, RoundsToSeconds(costs.nTimeCost));
return TRUE;
}
else
{
FloatingTextStringOnCreature("Infusion creation failed", oCaster); // Item creation failed
FloatingTextStrRefOnCreature(76417, oCaster); // Item creation failed
return TRUE;
}
/* // -------------------------------------------------------------------------
// Create the infused herb item
// -------------------------------------------------------------------------
object oInfusion = CICreateInfusion(oCaster, nID);
if (GetIsObjectValid(oInfusion))
{
SetIdentified(oInfusion, TRUE);
ActionPlayAnimation(ANIMATION_FIREFORGET_READ, 1.0);
SpendXP(oCaster, costs.nXPCost);
SpendGP(oCaster, costs.nGoldCost);
DestroyObject(oSpellTarget);
FloatingTextStrRefOnCreature(8502, oCaster); // Item creation successful
if (!costs.nTimeCost) costs.nTimeCost = 1;
AdvanceTimeForPlayer(oCaster, RoundsToSeconds(costs.nTimeCost));
return TRUE;
}
else
{
FloatingTextStringOnCreature("Infusion creation failed", oCaster); // Item creation failed
FloatingTextStrRefOnCreature(76417, oCaster); // Item creation failed
return TRUE;
} */
return FALSE;
}
// -----------------------------------------------------------------------------
// Create and return an herbal infusion with an item property matching nSpellID
// -----------------------------------------------------------------------------
object CICreateInfusion(object oCreator, int nSpellID)
{
if (DEBUG) DoDebug("prc_x2_craft >> CICreateInfusion: Entering function");
// Keep the original spell id the engine gave us (may be a subradial)
int nSpellOriginal = nSpellID;
// Compute the master (one-step) if this is a subradial. Keep original intact.
int nSpellMaster = nSpellOriginal;
if (GetIsSubradialSpell(nSpellOriginal))
{
nSpellMaster = GetMasterSpellFromSubradial(nSpellOriginal);
if (DEBUG) DoDebug("CICreateInfusion: detected subradial " + IntToString(nSpellOriginal) + " master -> " + IntToString(nSpellMaster));
}
// Try to find an iprp_spells row for the original subradial first (preferred).
int nPropID = IPGetIPConstCastSpellFromSpellID(nSpellOriginal);
int nSpellUsedForIP = nSpellOriginal;
// If not found for original, fall back to the master/base spell.
if (nPropID < 0)
{
if (DEBUG) DoDebug("CICreateInfusion: no iprp row for original " + IntToString(nSpellOriginal) + ", trying master " + IntToString(nSpellMaster));
nPropID = IPGetIPConstCastSpellFromSpellID(nSpellMaster);
nSpellUsedForIP = nSpellMaster;
}
// If still invalid, bail out with a helpful message
if (nPropID < 0)
{
if (DEBUG) DoDebug("CICreateInfusion: No iprp_spells entry for either original " + IntToString(nSpellOriginal) + " or master " + IntToString(nSpellMaster));
FloatingTextStringOnCreature("This spell cannot be infused (no item property mapping).", oCreator, FALSE);
return OBJECT_INVALID;
}
if (DEBUG) DoDebug("CICreateInfusion: using spell " + IntToString(nSpellUsedForIP) + " (iprp row " + IntToString(nPropID) + ") for item property");
// Optional: check for material component (use the resolved iprp row)
string sMat = GetMaterialComponentTag(nPropID);
if (sMat != "")
{
object oMat = GetItemPossessedBy(oCreator, sMat);
if (oMat == OBJECT_INVALID)
{
FloatingTextStrRefOnCreature(83374, oCreator); // Missing material component
return OBJECT_INVALID;
}
else
{
DestroyObject(oMat);
}
}
// Only allow divine spellcasters
int nClass = PRCGetLastSpellCastClass();
if (!GetIsDivineClass(nClass))
{
FloatingTextStringOnCreature("Only divine casters can use Create Infusion.", oCreator, FALSE);
return OBJECT_INVALID;
}
// Create base infusion item (herb)
string sResRef = "prc_infusion_000";
object oTarget = CreateItemOnObject(sResRef, oCreator);
if (oTarget == OBJECT_INVALID)
{
WriteTimestampedLogEntry("Create Infusion failed: couldn't create item with resref " + sResRef);
return OBJECT_INVALID;
}
// Confirm that the item is a herb
int nBaseItem = GetBaseItemType(oTarget);
if (nBaseItem != BASE_ITEM_INFUSED_HERB)
{
FloatingTextStringOnCreature("Only herbs may be infused.", oCreator, FALSE);
DestroyObject(oTarget);
return OBJECT_INVALID;
}
// Remove all non-material item properties from the herb
itemproperty ipRemove = GetFirstItemProperty(oTarget);
while (GetIsItemPropertyValid(ipRemove))
{
itemproperty ipNext = GetNextItemProperty(oTarget);
if (GetItemPropertyType(ipRemove) != ITEM_PROPERTY_MATERIAL)
RemoveItemProperty(oTarget, ipRemove);
ipRemove = ipNext;
}
// Add the cast-spell itemproperty using the iprp row we resolved
itemproperty ipSpell = ItemPropertyCastSpell(nPropID, IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE);
AddItemProperty(DURATION_TYPE_PERMANENT, ipSpell, oTarget);
// Optional PRC casting metadata: use the SAME spell id that matched the iprp row
// so caster level/DC/meta line up with the actual cast property on the item.
if (GetPRCSwitch(PRC_CREATE_INFUSION_CASTER_LEVEL))
{
int nCasterLevel = GetAlternativeCasterLevel(oCreator, PRCGetCasterLevel(oCreator));
// nSpellUsedForIP is either original (if that had an iprp row) or the master (fallback)
itemproperty ipLevel = ItemPropertyCastSpellCasterLevel(nSpellUsedForIP, nCasterLevel);
AddItemProperty(DURATION_TYPE_PERMANENT, ipLevel, oTarget);
itemproperty ipMeta = ItemPropertyCastSpellMetamagic(nSpellUsedForIP, PRCGetMetaMagicFeat());
AddItemProperty(DURATION_TYPE_PERMANENT, ipMeta, oTarget);
int nDC = PRCGetSpellSaveDC(nSpellUsedForIP, GetSpellSchool(nSpellUsedForIP), OBJECT_SELF);
itemproperty ipDC = ItemPropertyCastSpellDC(nSpellUsedForIP, nDC);
AddItemProperty(DURATION_TYPE_PERMANENT, ipDC, oTarget);
}
return oTarget;
}
// Test main
//void main(){}
// void main(){}

View File

@@ -768,7 +768,6 @@ int IPGetIsBludgeoningWeapon(object oItem)
// ----------------------------------------------------------------------------
// Return the IP_CONST_CASTSPELL_* ID matching to the SPELL_* constant given
// in nSPELL_ID.
// This uses Get2DAstring, so it is slow. Avoid using in loops!
// returns -1 if there is no matching property for a spell
// ----------------------------------------------------------------------------
int IPGetIPConstCastSpellFromSpellID(int nSpellID)
@@ -1883,7 +1882,7 @@ int IPDamageConstant(int nDamBon)
case 49: nIPBonus = IP_CONST_DAMAGEBONUS_49; break;
case 50: nIPBonus = IP_CONST_DAMAGEBONUS_50; break;
}
if (nDamBon > 20) nIPBonus = IP_CONST_DAMAGEBONUS_50;
if (nDamBon > 50) nIPBonus = IP_CONST_DAMAGEBONUS_50;
return nIPBonus;
}

View File

@@ -236,12 +236,12 @@ int GetShadowcasterLevel(object oShadow = OBJECT_SELF, int nSpecificClass = CLAS
// For when you want to assign the caster level.
if(nLevel)
{
if(DEBUG) SendMessageToPC(oShadow, "GetShadowcasterLevel(): Forced-level shadowcasting at level " + IntToString(nLevel));
if(DEBUG) DoDebug("GetShadowcasterLevel(): Forced-level shadowcasting at level " + IntToString(nLevel));
//DelayCommand(1.0, DeleteLocalInt(oShadow, PRC_CASTERLEVEL_OVERRIDE));
return nLevel + nAdjust;
}
if (DEBUG) FloatingTextStringOnCreature("GetShadowcasterLevel: "+GetName(oShadow)+" is a "+IntToString(nSpecificClass), oShadow);
if (DEBUG) DoDebug("GetShadowcasterLevel: "+GetName(oShadow)+" is a "+IntToString(nSpecificClass), oShadow);
// The function user needs to know the character's Shadowcaster level in a specific class
// instead of whatever the character last shadowcast a mystery as
if(nSpecificClass != CLASS_TYPE_INVALID)
@@ -288,7 +288,7 @@ int GetShadowcasterLevel(object oShadow = OBJECT_SELF, int nSpecificClass = CLAS
nLevel -= 4;
}
if(DEBUG) FloatingTextStringOnCreature("Shadowcaster Level: " + IntToString(nLevel), oShadow, FALSE);
if(DEBUG) DoDebug("Shadowcaster Level: " + IntToString(nLevel));
return nLevel + nAdjust;
}

View File

@@ -144,8 +144,103 @@ int PRCGetUserSpecificSpellScriptFinished();
#include "pnp_shft_main"
#include "inc_dynconv"
#include "inc_npc"
#include "inc_infusion"
int Spontaneity(object oCaster, int nCastingClass, int nSpellID, int nSpellLevel)
{
if(GetLocalInt(oCaster, "PRC_SpontRegen"))
{
DeleteLocalInt(oCaster, "PRC_SpontRegen");
int nMetamagic = GetMetaMagicFeat();//we need bioware metamagic here
nSpellLevel = PRCGetSpellLevelForClass(nSpellID, nCastingClass);
nSpellLevel += GetMetaMagicSpellLevelAdjustment(nMetamagic);
int nRegenSpell;
if(nCastingClass == CLASS_TYPE_DRUID)
{
switch(nSpellLevel)
{
case 0: return TRUE;
case 1: nRegenSpell = SPELL_REGEN_LIGHT_WOUNDS; break;
case 2: nRegenSpell = SPELL_REGEN_MODERATE_WOUNDS; break;
case 3: nRegenSpell = SPELL_REGEN_RING; break;
case 4: nRegenSpell = SPELL_REGEN_SERIOUS_WOUNDS; break;
case 5: nRegenSpell = SPELL_REGEN_CRITICAL_WOUNDS; break;
case 6: nRegenSpell = SPELL_REGEN_CIRCLE; break;
case 7: nRegenSpell = SPELL_REGEN_CIRCLE; break;
case 8: nRegenSpell = SPELL_REGEN_CIRCLE; break;
case 9: nRegenSpell = SPELL_REGENERATE; break;
}
ActionCastSpell(nRegenSpell, 0, 0, 0, METAMAGIC_NONE, CLASS_TYPE_DRUID);
}
else
{
switch(nSpellLevel)
{
case 0: return TRUE;
case 1: nRegenSpell = SPELL_REGEN_LIGHT_WOUNDS; break;
case 2: nRegenSpell = SPELL_REGEN_LIGHT_WOUNDS; break;
case 3: nRegenSpell = SPELL_REGEN_MODERATE_WOUNDS; break;
case 4: nRegenSpell = SPELL_REGEN_MODERATE_WOUNDS; break;
case 5: nRegenSpell = SPELL_REGEN_SERIOUS_WOUNDS; break;
case 6: nRegenSpell = SPELL_REGEN_CRITICAL_WOUNDS; break;
case 7: nRegenSpell = SPELL_REGENERATE; break;
case 8: nRegenSpell = SPELL_REGENERATE; break;
case 9: nRegenSpell = SPELL_REGENERATE; break;
}
ActionCastSpell(nRegenSpell, 0, 0, 0, METAMAGIC_NONE, nCastingClass);
}
//Don't cast original spell
return FALSE;
}
return TRUE;
}
int DruidSpontSummon(object oCaster, int nCastingClass, int nSpellID, int nSpellLevel)
{
if(nCastingClass != CLASS_TYPE_DRUID)
return TRUE;
if(GetLocalInt(oCaster, "PRC_SpontSummon"))
{
DeleteLocalInt(oCaster, "PRC_SpontSummon");
int nMetamagic = GetMetaMagicFeat();//we need bioware metamagic here
int nSpellLevel = PRCGetSpellLevelForClass(nSpellID, CLASS_TYPE_DRUID);
nSpellLevel += GetMetaMagicSpellLevelAdjustment(nMetamagic);
int nSummonSpell;
switch(nSpellLevel)
{
case 0: return TRUE;
case 1: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_1; break;
case 2: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_2; break;
case 3: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_3; break;
case 4: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_4; break;
case 5: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_5; break;
case 6: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_6; break;
case 7: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_7; break;
case 8: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_8; break;
case 9: nSummonSpell = SPELL_SUMMON_NATURES_ALLY_9; break;
}
//:: All SNA spells are subradial spells
SetLocalInt(oCaster, "DomainOrigSpell", nSummonSpell);
SetLocalInt(oCaster, "DomainCastLevel", nSpellLevel);
SetLocalInt(oCaster, "DomainCastClass", CLASS_TYPE_DRUID);
StartDynamicConversation("prc_domain_conv", oCaster, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oCaster);
//Don't cast original spell
return FALSE;
}
return TRUE;
}
/* int DruidSpontSummon(object oCaster, int nCastingClass, int nSpellID, int nSpellLevel)
{
if(nCastingClass != CLASS_TYPE_DRUID)
return TRUE;
@@ -191,6 +286,8 @@ int DruidSpontSummon(object oCaster, int nCastingClass, int nSpellID, int nSpell
return TRUE;
}
*/
int ArcaneSpellFailure(object oCaster, int nCastingClass, int nSpellLevel, int nMetamagic, string sComponents)
{
if(!GetIsArcaneClass(nCastingClass))
@@ -904,7 +1001,8 @@ int ShifterCasting(object oCaster, object oSpellCastItem, int nSpellLevel, int n
{
// Potion drinking is not restricted
if(GetBaseItemType(oSpellCastItem) == BASE_ITEM_ENCHANTED_POTION
|| GetBaseItemType(oSpellCastItem) == BASE_ITEM_POTIONS)
|| GetBaseItemType(oSpellCastItem) == BASE_ITEM_POTIONS
|| GetBaseItemType(oSpellCastItem) == BASE_ITEM_INFUSED_HERB)
return TRUE;
//OnHit properties on equipped items not restricted
@@ -3257,8 +3355,13 @@ int X2PreSpellCastCode2()
SendMessageToPC(oCaster, "Combat Expertise only works with attack actions.");
nContinue = FALSE;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Run Infusion use check
//---------------------------------------------------------------------------
if(nContinue)
nContinue = DoInfusionUseChecks(oCaster, oSpellCastItem, nSpellID);
//---------------------------------------------------------------------------
// Run Spelldance perform check
//---------------------------------------------------------------------------
if(nContinue)
@@ -3399,6 +3502,12 @@ int X2PreSpellCastCode2()
if (nContinue)
nContinue = SpellAlignmentRestrictions(oCaster, nSpellID, nCastingClass);
//---------------------------------------------------------------------------
// Verdant Lord Spontaneous Regernate
//---------------------------------------------------------------------------
if(nContinue)
Spontaneity(oCaster, nCastingClass, nSpellID, nSpellLevel);
//---------------------------------------------------------------------------
// Druid spontaneous summoning
//---------------------------------------------------------------------------