Compare commits
4 Commits
main
...
feature/mo
Author | SHA1 | Date | |
---|---|---|---|
|
e1acdf8f91 | ||
|
ee7bcb4271 | ||
|
8156e17759 | ||
|
14cc43add1 |
19400
Content/spells.2da
Normal file
19400
Content/spells.2da
Normal file
File diff suppressed because it is too large
Load Diff
31
Content/spells/Spell_Creation_Guidelines.md
Normal file
31
Content/spells/Spell_Creation_Guidelines.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Spell Creation Guidelines for WizardryEE
|
||||||
|
|
||||||
|
## 1. File Structure and Metadata
|
||||||
|
- Uniform comment block at the top (Spell Name, Filename, Copyright, Creation/Modification Dates)
|
||||||
|
- Include necessary `prc_` header files (e.g., `prc_inc_spells`)
|
||||||
|
|
||||||
|
## 2. Spell Logic and Effects
|
||||||
|
- **Damage Spells**:
|
||||||
|
- Complex damage calculations with metamagic support
|
||||||
|
- Example: `nw_s0_icestorm.nss`
|
||||||
|
- **Buff/Debuff Spells**:
|
||||||
|
- Temporary skill/attribute modifications
|
||||||
|
- Example: `nw_s0_identify.nss`
|
||||||
|
- **Aura/Permanent Effects**:
|
||||||
|
- AOE implementations with disable/re-enable support
|
||||||
|
- Example: `nw_s1_aurablind.nss`
|
||||||
|
|
||||||
|
## 3. Essential Functions and Variables
|
||||||
|
- `PRCGetCasterLevel(OBJECT_SELF)`
|
||||||
|
- `SetLocalInt`/`DeleteLocalInt` for `X2_L_LAST_SPELLSCHOOL_VAR`
|
||||||
|
- `EffectVisualEffect`, `PRCEffectDamage`, `EffectLinkEffects`
|
||||||
|
|
||||||
|
## 4. Customization Tips
|
||||||
|
- Review `/Notes/spells` for examples
|
||||||
|
- Test metamagic interactions
|
||||||
|
- Ensure spell school consistency
|
||||||
|
|
||||||
|
## 5. Future Spell Customization Template
|
||||||
|
```nss
|
||||||
|
// TO DO: Customize Based on Guidelines Above
|
||||||
|
// ...
|
72
Content/spells/badi.nss
Normal file
72
Content/spells/badi.nss
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Badi (Death)
|
||||||
|
//:: badi.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to kill a monster.
|
||||||
|
Level 5 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Priest attack spell that targets
|
||||||
|
one monster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Attempt instant death on a monster
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// 4. Calculate save DC based on caster level
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_CLERIC, oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 5; // Minimum level 5 for this spell
|
||||||
|
int nDC = 10 + nCasterLevel;
|
||||||
|
|
||||||
|
// 5. Create the death effect
|
||||||
|
effect eDeath = EffectDeath();
|
||||||
|
effect eVis = EffectVisualEffect(45); // Death visual effect
|
||||||
|
|
||||||
|
// 6. Apply the effects
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 24)); // Death spell ID
|
||||||
|
|
||||||
|
// Allow saving throw to resist
|
||||||
|
if (!FortitudeSave(oTarget, nDC, 3)) // 3 = Death saving throw type
|
||||||
|
{
|
||||||
|
// Apply the visual and death effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oTarget);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("BADI: " + GetName(oTarget) + " is killed!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify resistance
|
||||||
|
FloatingTextStringOnCreature(GetName(oTarget) + " resisted death!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("BADI: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
61
Content/spells/badial.nss
Normal file
61
Content/spells/badial.nss
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Badial (More Hurt)
|
||||||
|
//:: badial.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 2d8 (2-16) points of damage to a monster.
|
||||||
|
Level 4 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 4 Priest attack spell that targets
|
||||||
|
one monster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 2d8 damage to a monster
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// 4. Calculate damage
|
||||||
|
int nDamage = d8(2); // 2d8 damage
|
||||||
|
|
||||||
|
// 5. Create the damage effect
|
||||||
|
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_NEGATIVE);
|
||||||
|
effect eVis = EffectVisualEffect(40); // Negative energy visual effect
|
||||||
|
|
||||||
|
// 6. Apply the effects
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 25)); // Inflict Moderate Wounds spell ID
|
||||||
|
|
||||||
|
// Apply the visual and damage effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||||
|
|
||||||
|
// 7. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("BADIAL: Dealt " + IntToString(nDamage) + " damage to " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("BADIAL: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
61
Content/spells/badialma.nss
Normal file
61
Content/spells/badialma.nss
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Badialma (Great Hurt)
|
||||||
|
//:: badialma.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 3d8 (3-24) points of damage to a monster.
|
||||||
|
Level 5 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Priest attack spell that targets
|
||||||
|
one monster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 3d8 damage to a monster
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// 4. Calculate damage
|
||||||
|
int nDamage = d8(3); // 3d8 damage
|
||||||
|
|
||||||
|
// 5. Create the damage effect
|
||||||
|
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_NEGATIVE);
|
||||||
|
effect eVis = EffectVisualEffect(40); // Negative energy visual effect
|
||||||
|
|
||||||
|
// 6. Apply the effects
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 26)); // Inflict Serious Wounds spell ID
|
||||||
|
|
||||||
|
// Apply the visual and damage effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||||
|
|
||||||
|
// 7. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("BADIALMA: Dealt " + IntToString(nDamage) + " damage to " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("BADIALMA: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
87
Content/spells/badios.nss
Normal file
87
Content/spells/badios.nss
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Badios (Harm)
|
||||||
|
//:: badios.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 1d8 (1-8) points of damage to a monster.
|
||||||
|
Level 1 Priest spell.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 1d8 negative energy damage to a monster
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_NECROMANCY);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nDamage;
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY);
|
||||||
|
effect eDam;
|
||||||
|
|
||||||
|
// Get the spell target
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
|
||||||
|
// Verify the target is a hostile creature
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nCasterLevel + SPGetPenetr()))
|
||||||
|
{
|
||||||
|
// Roll damage - 1d8 negative energy damage
|
||||||
|
nDamage = d8(1);
|
||||||
|
|
||||||
|
// Resolve metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
{
|
||||||
|
nDamage = 8; // Maximum damage
|
||||||
|
}
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
{
|
||||||
|
nDamage = nDamage + (nDamage / 2); // +50% damage
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, 1);
|
||||||
|
|
||||||
|
// Set the damage effect
|
||||||
|
eDam = PRCEffectDamage(oTarget, nDamage, DAMAGE_TYPE_NEGATIVE);
|
||||||
|
|
||||||
|
// Apply the VFX impact and damage effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
PRCBonusDamage(oTarget);
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("BADIOS: " + IntToString(nDamage) + " negative energy damage to " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("BADIOS: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
121
Content/spells/bamatu.nss
Normal file
121
Content/spells/bamatu.nss
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Bamatu (Prayer)
|
||||||
|
//:: bamatu.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of all party members by 4
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 3 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 3 Priest support spell that targets
|
||||||
|
the entire party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_sp_func"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Haste effect for all party members
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_TRANSMUTATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Ensure minimum caster level
|
||||||
|
if (nCasterLevel < 3) nCasterLevel = 3; // Minimum level 3 for this spell
|
||||||
|
|
||||||
|
// Calculate duration (based on caster level)
|
||||||
|
int nDuration = nCasterLevel;
|
||||||
|
float fDuration = RoundsToSeconds(nDuration);
|
||||||
|
|
||||||
|
// Check for Extend Spell metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the haste effect
|
||||||
|
effect eHaste = EffectHaste();
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_HASTE);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
effect eLink = EffectLinkEffects(eHaste, eDur);
|
||||||
|
|
||||||
|
// Apply the area effect
|
||||||
|
location lCaster = GetLocation(oCaster);
|
||||||
|
float fRange = FeetToMeters(50.0);
|
||||||
|
|
||||||
|
// Apply visual effect at caster location
|
||||||
|
effect eImpact = EffectVisualEffect(VFX_FNF_LOS_HOLY_30);
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lCaster);
|
||||||
|
|
||||||
|
// Get the first target in the radius around the caster
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, fRange, lCaster);
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Only affect friendly targets
|
||||||
|
if (GetIsReactionTypeFriendly(oTarget) || GetFactionEqual(oTarget))
|
||||||
|
{
|
||||||
|
// Remove any existing haste or similar effects
|
||||||
|
if (GetHasSpellEffect(SPELL_EXPEDITIOUS_RETREAT, oTarget))
|
||||||
|
{
|
||||||
|
PRCRemoveSpellEffects(SPELL_EXPEDITIOUS_RETREAT, oCaster, oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetHasSpellEffect(SPELL_HASTE, oTarget))
|
||||||
|
{
|
||||||
|
PRCRemoveSpellEffects(SPELL_HASTE, oCaster, oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetHasSpellEffect(SPELL_MASS_HASTE, oTarget))
|
||||||
|
{
|
||||||
|
PRCRemoveSpellEffects(SPELL_MASS_HASTE, oCaster, oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire spell cast at event for target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Apply random delay for visual effect
|
||||||
|
float fDelay = PRCGetRandomDelay(0.4, 1.1);
|
||||||
|
|
||||||
|
// Apply the effects
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, GetSpellId(), nCasterLevel));
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next target in the specified area around the caster
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, fRange, lCaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("BAMATU: Hasted " + IntToString(nAffected) + " allies for " + IntToString(nDuration) + " rounds!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("BAMATU: No allies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
91
Content/spells/calfo.nss
Normal file
91
Content/spells/calfo.nss
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Calfo (X-ray Vision)
|
||||||
|
//:: calfo.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Determines the type of trap on a chest with 95% accuracy.
|
||||||
|
Level 2 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 2 Priest field spell that targets
|
||||||
|
the caster, allowing them to identify traps.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Identify traps on chests
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Calculate duration (based on caster level)
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_CLERIC, oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 2; // Minimum level 2 for this spell
|
||||||
|
float fDuration = TurnsToSeconds(nCasterLevel); // Lasts for turns equal to caster level
|
||||||
|
|
||||||
|
// 3. Create the trap detection effect
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_MAGICAL_VISION);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_MAGICAL_SIGHT);
|
||||||
|
|
||||||
|
// 4. Apply to the caster
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, oCaster, fDuration);
|
||||||
|
|
||||||
|
// 5. Identify traps in the area
|
||||||
|
object oArea = GetArea(oCaster);
|
||||||
|
object oChest = GetFirstObjectInArea(oArea);
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oChest))
|
||||||
|
{
|
||||||
|
// If the object is a chest/container
|
||||||
|
if (GetObjectType(oChest) == OBJECT_TYPE_PLACEABLE &&
|
||||||
|
GetStringLeft(GetResRef(oChest), 5) == "chest")
|
||||||
|
{
|
||||||
|
// Check if it's trapped
|
||||||
|
if (GetTrapDetectedBy(oChest, oCaster) || GetIsTrapped(oChest))
|
||||||
|
{
|
||||||
|
// 95% chance to correctly identify
|
||||||
|
if (Random(100) < 95)
|
||||||
|
{
|
||||||
|
// Determine trap type based on local variables or tags
|
||||||
|
string sTrapName = "Unknown Trap";
|
||||||
|
|
||||||
|
// Example trap detection logic - would be customized for actual implementation
|
||||||
|
if (GetLocalInt(oChest, "TRAP_POISON") == 1)
|
||||||
|
sTrapName = "Poison Needle";
|
||||||
|
else if (GetLocalInt(oChest, "TRAP_FIRE") == 1)
|
||||||
|
sTrapName = "Fire Trap";
|
||||||
|
else if (GetLocalInt(oChest, "TRAP_ACID") == 1)
|
||||||
|
sTrapName = "Acid Trap";
|
||||||
|
else if (GetLocalInt(oChest, "TRAP_SHOCK") == 1)
|
||||||
|
sTrapName = "Shock Trap";
|
||||||
|
else if (GetLocalInt(oChest, "TRAP_GAS") == 1)
|
||||||
|
sTrapName = "Gas Trap";
|
||||||
|
else if (GetLocalInt(oChest, "TRAP_EXPLOSIVE") == 1)
|
||||||
|
sTrapName = "Explosive Runes";
|
||||||
|
else if (GetLocalInt(oChest, "TRAP_ALARM") == 1)
|
||||||
|
sTrapName = "Alarm";
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("Trap Detected: " + sTrapName, oCaster, TRUE);
|
||||||
|
|
||||||
|
// Mark as detected
|
||||||
|
SetTrapDetectedBy(oChest, oCaster);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 5% chance to misidentify
|
||||||
|
FloatingTextStringOnCreature("Trap Detection Failed", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oChest = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
}
|
150
Content/spells/dalto.nss
Normal file
150
Content/spells/dalto.nss
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Dalto (Blizzard)
|
||||||
|
//:: dalto.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 6d6 (6-36) points of cold damage to a
|
||||||
|
monster group.
|
||||||
|
Level 4 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 4 Mage attack spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_inc_sp_tch"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 6d6 acid damage to a monster group
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
|
||||||
|
// Get the elemental damage type (default to acid)
|
||||||
|
int EleDmg = ChangedElementalDamage(oCaster, DAMAGE_TYPE_ACID);
|
||||||
|
|
||||||
|
// Create the acid arrow visual effect
|
||||||
|
effect eArrow = EffectVisualEffect(VFX_DUR_MIRV_ACID);
|
||||||
|
|
||||||
|
// Apply the arrow visual effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eArrow, oTarget);
|
||||||
|
|
||||||
|
// Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && !GetIsReactionTypeFriendly(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make a ranged touch attack
|
||||||
|
int iAttackRoll = PRCDoRangedTouchAttack(oTarget);
|
||||||
|
|
||||||
|
if (iAttackRoll > 0)
|
||||||
|
{
|
||||||
|
// Calculate delay based on distance
|
||||||
|
float fDelay = GetDistanceToObject(oTarget) / 25.0f;
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay))
|
||||||
|
{
|
||||||
|
// Setup VFX
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_ACID_L);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
||||||
|
|
||||||
|
// Set the VFX to be non dispelable, because the acid is not magic
|
||||||
|
eDur = ExtraordinaryEffect(eDur);
|
||||||
|
|
||||||
|
// Calculate damage - 6d6 acid damage
|
||||||
|
int nDamage = d6(6);
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
nDamage = 36; // 6 * 6 = 36 (maximum damage)
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
nDamage += nDamage / 2; // +50% damage
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, 6);
|
||||||
|
|
||||||
|
// Apply the VFX and damage
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
DelayCommand(fDelay, ApplyTouchAttackDamage(oCaster, oTarget, iAttackRoll, nDamage, EleDmg));
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
DelayCommand(fDelay, PRCBonusDamage(oTarget));
|
||||||
|
|
||||||
|
// Notify damage
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature("DALTO: " + IntToString(nDamage) + " acid damage to " + GetName(oTarget), oCaster, TRUE));
|
||||||
|
|
||||||
|
// Create a lingering acid effect for 2 rounds
|
||||||
|
int nDuration = 2;
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
nDuration *= 2;
|
||||||
|
|
||||||
|
// Apply lingering acid effect
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, oTarget, RoundsToSeconds(nDuration), FALSE));
|
||||||
|
|
||||||
|
// Calculate secondary damage for lingering effect
|
||||||
|
int nSecondaryDamage = d6(3); // Half damage for lingering effect
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
nSecondaryDamage = 18; // 3 * 6 = 18 (maximum damage)
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
nSecondaryDamage += nSecondaryDamage / 2; // +50% damage
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nSecondaryDamage += SpellDamagePerDice(oCaster, 3);
|
||||||
|
|
||||||
|
// Apply lingering damage after 6 seconds
|
||||||
|
effect eSecondaryVis = EffectVisualEffect(VFX_IMP_ACID_S);
|
||||||
|
effect eSecondaryDam = PRCEffectDamage(oTarget, nSecondaryDamage, EleDmg);
|
||||||
|
eSecondaryDam = EffectLinkEffects(eSecondaryVis, eSecondaryDam);
|
||||||
|
|
||||||
|
DelayCommand(fDelay + 6.0f, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eSecondaryDam, oTarget));
|
||||||
|
DelayCommand(fDelay + 6.0f, FloatingTextStringOnCreature("DALTO: " + IntToString(nSecondaryDamage) + " lingering acid damage to " + GetName(oTarget), oCaster, TRUE));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Indicate Failure
|
||||||
|
effect eSmoke = EffectVisualEffect(VFX_IMP_REFLEX_SAVE_THROW_USE);
|
||||||
|
DelayCommand(fDelay + 0.1f, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSmoke, oTarget));
|
||||||
|
|
||||||
|
// Notify resistance
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature("DALTO: " + GetName(oTarget) + " resisted the spell!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify miss
|
||||||
|
FloatingTextStringOnCreature("DALTO: Missed " + GetName(oTarget) + "!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("DALTO: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
160
Content/spells/di.nss
Normal file
160
Content/spells/di.nss
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Di (Life)
|
||||||
|
//:: di.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to resurrect a dead party member.
|
||||||
|
If successful, the dead character is revived with
|
||||||
|
only 1 hit point and decreased Vitality.
|
||||||
|
If failed, the dead character is turned to ashes.
|
||||||
|
Level 5 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Priest healing/field spell that
|
||||||
|
targets one character.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Attempt to resurrect a dead character
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Check if target is valid
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Notify if no target selected
|
||||||
|
FloatingTextStringOnCreature("DI: No target selected", oCaster, TRUE);
|
||||||
|
PRCSetSchool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if target is dead
|
||||||
|
if (!GetIsDead(oTarget))
|
||||||
|
{
|
||||||
|
// Notify if target is not dead
|
||||||
|
FloatingTextStringOnCreature("DI: Target must be dead", oCaster, TRUE);
|
||||||
|
PRCSetSchool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if target is ashes
|
||||||
|
if (GetLocalInt(oTarget, "CONDITION_ASHES") == 1)
|
||||||
|
{
|
||||||
|
// Notify if target is already ashes
|
||||||
|
FloatingTextStringOnCreature("DI: Target must not be ashes", oCaster, TRUE);
|
||||||
|
PRCSetSchool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate resurrection chance based on caster level
|
||||||
|
int nChance = 50 + (nCasterLevel * 5); // Base 50% + 5% per level
|
||||||
|
|
||||||
|
// Apply metamagic effects
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
{
|
||||||
|
nChance = 95; // Maximum chance with Maximize (still allow for failure)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
{
|
||||||
|
nChance += nChance / 2; // +50% chance with Empower
|
||||||
|
if (nChance > 95) nChance = 95; // Cap at 95%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Create the resurrection effects
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_RAISE_DEAD);
|
||||||
|
effect eHeal = PRCEffectHeal(1, oTarget); // Heal 1 HP
|
||||||
|
|
||||||
|
// Attempt resurrection
|
||||||
|
if (d100() <= nChance)
|
||||||
|
{
|
||||||
|
// Success
|
||||||
|
// Apply resurrection effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
|
||||||
|
// Remove all effects
|
||||||
|
effect eEffect = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eEffect))
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eEffect);
|
||||||
|
eEffect = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply resurrection and healing effects
|
||||||
|
effect eResurrect = EffectResurrection();
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eResurrect, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
|
||||||
|
|
||||||
|
// Decrease Vitality (using Constitution as an analog)
|
||||||
|
effect eConDecrease = EffectAbilityDecrease(ABILITY_CONSTITUTION, 1);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_PERMANENT, eConDecrease, oTarget);
|
||||||
|
|
||||||
|
// Apply protection effect (as a bonus for resurrection)
|
||||||
|
effect eAC = EffectACIncrease(2, AC_DEFLECTION_BONUS);
|
||||||
|
effect eSave = EffectSavingThrowIncrease(SAVING_THROW_ALL, 2);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_PROTECTION_GOOD_MINOR);
|
||||||
|
effect eDur2 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eSave, eAC);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur2);
|
||||||
|
|
||||||
|
// Calculate duration (1 hour per caster level)
|
||||||
|
int nDuration = nCasterLevel;
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
nDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the protection effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, HoursToSeconds(nDuration), TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// Remove custom condition flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_DEAD");
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("DI: " + GetName(oTarget) + " has been resurrected!", oCaster, TRUE);
|
||||||
|
FloatingTextStringOnCreature("Vitality decreased by 1", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Failure - Turn to ashes
|
||||||
|
// Apply visual effect for failure
|
||||||
|
effect eFailVis = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eFailVis, oTarget);
|
||||||
|
|
||||||
|
// Set ashes condition
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_DEAD");
|
||||||
|
SetLocalInt(oTarget, "CONDITION_ASHES", 1);
|
||||||
|
|
||||||
|
// Notify failure
|
||||||
|
FloatingTextStringOnCreature("DI: " + GetName(oTarget) + " has been turned to ashes!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
61
Content/spells/dial.nss
Normal file
61
Content/spells/dial.nss
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Dial (More Heal)
|
||||||
|
//:: dial.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Restores 2d8 (2-16) hit points to a party member.
|
||||||
|
Level 4 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 4 Priest healing spell that targets
|
||||||
|
one character.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Heal 2d8 hit points
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, target self
|
||||||
|
oTarget = oCaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is a party member
|
||||||
|
if (GetIsObjectValid(oTarget) && !GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// 4. Calculate healing
|
||||||
|
int nHeal = d8(2); // 2d8 healing
|
||||||
|
|
||||||
|
// 5. Create the healing effect
|
||||||
|
effect eHeal = EffectHeal(nHeal);
|
||||||
|
effect eVis = EffectVisualEffect(14); // Healing visual effect
|
||||||
|
|
||||||
|
// 6. Apply the effects
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 15, FALSE)); // Cure Moderate Wounds spell ID
|
||||||
|
|
||||||
|
// Apply the visual and healing effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
|
||||||
|
|
||||||
|
// 7. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("DIAL: Healed " + IntToString(nHeal) + " hit points for " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("DIAL: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
104
Content/spells/dialko.nss
Normal file
104
Content/spells/dialko.nss
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Dialko (Softness)
|
||||||
|
//:: dialko.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Cures paralysis and sleep for a party member.
|
||||||
|
Level 3 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 3 Priest healing spell that targets
|
||||||
|
one character.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Cure paralysis and sleep
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
|
||||||
|
// Create the visual effect
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
|
||||||
|
// Check if target is valid
|
||||||
|
if (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Check for sleep and paralysis effects
|
||||||
|
int bCured = FALSE;
|
||||||
|
|
||||||
|
// Remove sleep effects
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_SLEEP, oTarget))
|
||||||
|
{
|
||||||
|
// Remove sleep effect
|
||||||
|
effect eSleep = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eSleep))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eSleep) == EFFECT_TYPE_SLEEP)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eSleep);
|
||||||
|
bCured = TRUE;
|
||||||
|
}
|
||||||
|
eSleep = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove paralysis effects
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_PARALYZE, oTarget))
|
||||||
|
{
|
||||||
|
// Remove paralysis effect
|
||||||
|
effect eParalyze = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eParalyze))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eParalyze) == EFFECT_TYPE_PARALYZE)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eParalyze);
|
||||||
|
bCured = TRUE;
|
||||||
|
}
|
||||||
|
eParalyze = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply visual effect if any conditions were cured
|
||||||
|
if (bCured)
|
||||||
|
{
|
||||||
|
// Apply the visual healing effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("DIALKO: " + GetName(oTarget) + " is cured of paralysis and sleep!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify that target is not affected
|
||||||
|
FloatingTextStringOnCreature("DIALKO: " + GetName(oTarget) + " is not affected by paralysis or sleep.", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("DIALKO: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
61
Content/spells/dialma.nss
Normal file
61
Content/spells/dialma.nss
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Dialma (Great Heal)
|
||||||
|
//:: dialma.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Restores 3d8 (3-24) hit points to a party member.
|
||||||
|
Level 5 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Priest healing spell that targets
|
||||||
|
one character.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Heal 3d8 hit points
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, target self
|
||||||
|
oTarget = oCaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is a party member
|
||||||
|
if (GetIsObjectValid(oTarget) && !GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// 4. Calculate healing
|
||||||
|
int nHeal = d8(3); // 3d8 healing
|
||||||
|
|
||||||
|
// 5. Create the healing effect
|
||||||
|
effect eHeal = EffectHeal(nHeal);
|
||||||
|
effect eVis = EffectVisualEffect(14); // Healing visual effect
|
||||||
|
|
||||||
|
// 6. Apply the effects
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 16, FALSE)); // Cure Serious Wounds spell ID
|
||||||
|
|
||||||
|
// Apply the visual and healing effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
|
||||||
|
|
||||||
|
// 7. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("DIALMA: Healed " + IntToString(nHeal) + " hit points for " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("DIALMA: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
132
Content/spells/dilto.nss
Normal file
132
Content/spells/dilto.nss
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Dilto (Darkness)
|
||||||
|
//:: dilto.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Increases the armor class of a monster group by 2
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 2 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 2 Mage disable spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Cone of cold damage to enemies
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
int nDamage;
|
||||||
|
float fDelay;
|
||||||
|
|
||||||
|
// Limit caster level for damage purposes
|
||||||
|
if (nCasterLevel > 10)
|
||||||
|
{
|
||||||
|
nCasterLevel = 10; // Cap at 10d6 damage
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the target location
|
||||||
|
location lTargetLocation = PRCGetSpellTargetLocation();
|
||||||
|
|
||||||
|
// Create the cone effect
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FROST_L);
|
||||||
|
|
||||||
|
// Get the elemental damage type (default to cold)
|
||||||
|
int EleDmg = ChangedElementalDamage(oCaster, DAMAGE_TYPE_COLD);
|
||||||
|
|
||||||
|
// Declare the spell shape, size and the location
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPELLCONE, 11.0, lTargetLocation, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
||||||
|
|
||||||
|
// Track affected targets
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Cycle through the targets within the spell shape
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Get the distance between the target and caster to delay the application of effects
|
||||||
|
fDelay = GetDistanceBetween(oCaster, oTarget)/20.0;
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay) && (oTarget != oCaster))
|
||||||
|
{
|
||||||
|
// Calculate damage - 1d6 per caster level (max 10d6)
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
{
|
||||||
|
nDamage = 6 * nCasterLevel; // Maximum damage
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nDamage = d6(nCasterLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
{
|
||||||
|
nDamage += nDamage / 2; // +50% damage
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, nCasterLevel);
|
||||||
|
|
||||||
|
// Adjust damage according to Reflex Save, Evasion or Improved Evasion
|
||||||
|
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, PRCGetSaveDC(oTarget, oCaster), SAVING_THROW_TYPE_COLD);
|
||||||
|
|
||||||
|
if (nDamage > 0)
|
||||||
|
{
|
||||||
|
// Create the damage effect
|
||||||
|
effect eCold = PRCEffectDamage(oTarget, nDamage, EleDmg);
|
||||||
|
|
||||||
|
// Apply delayed effects
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eCold, oTarget));
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
PRCBonusDamage(oTarget);
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the next target within the spell shape
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPELLCONE, 11.0, lTargetLocation, TRUE, OBJECT_TYPE_CREATURE | OBJECT_TYPE_DOOR | OBJECT_TYPE_PLACEABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("DILTO: Cold damage to " + IntToString(nAffected) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("DILTO: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
83
Content/spells/dios.nss
Normal file
83
Content/spells/dios.nss
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Dios (Heal)
|
||||||
|
//:: dios.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Restores 1d8 (1-8) hit points to a party member.
|
||||||
|
Level 1 Priest spell.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Heal 1d8 hit points
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nHeal;
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_HEALING_S);
|
||||||
|
effect eHeal;
|
||||||
|
|
||||||
|
// Get the spell target
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
|
||||||
|
// Verify the target is a friendly creature
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Roll healing
|
||||||
|
nHeal = d8(1);
|
||||||
|
|
||||||
|
// Resolve metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
{
|
||||||
|
nHeal = 8; // Maximum healing
|
||||||
|
}
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
{
|
||||||
|
nHeal = nHeal + (nHeal / 2); // +50% healing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply bonus healing if the caster has Augment Healing feat
|
||||||
|
if (GetHasFeat(FEAT_AUGMENT_HEALING, oCaster))
|
||||||
|
{
|
||||||
|
nHeal += 2; // +2 per spell level (level 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the healing effect
|
||||||
|
eHeal = PRCEffectHeal(nHeal, oTarget);
|
||||||
|
|
||||||
|
// Apply the VFX impact and healing effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("DIOS: " + IntToString(nHeal) + " hit points restored to " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("DIOS: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
106
Content/spells/dumapic.nss
Normal file
106
Content/spells/dumapic.nss
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Dumapic (Clarity)
|
||||||
|
//:: dumapic.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Identifies the location of the party in the dungeon.
|
||||||
|
Level 1 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 1 Mage field spell that helps
|
||||||
|
with dungeon navigation.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Show party location and increase Lore skill
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_DIVINATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Calculate skill bonus and duration
|
||||||
|
int nBonus = 10 + nCasterLevel;
|
||||||
|
int nDuration = 2; // 2 rounds
|
||||||
|
|
||||||
|
// Check for Extend Spell metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
nDuration = 4; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the lore skill increase effect
|
||||||
|
effect eLore = EffectSkillIncrease(SKILL_LORE, nBonus);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_MAGICAL_VISION);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eLore, eDur);
|
||||||
|
|
||||||
|
// Make sure the spell has not already been applied
|
||||||
|
if (!GetHasSpellEffect(SPELL_IDENTIFY, oCaster) && !GetHasSpellEffect(SPELL_LEGEND_LORE, oCaster))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oCaster, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Apply the effects
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oCaster, RoundsToSeconds(nDuration), TRUE, -1, nCasterLevel);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current dungeon information
|
||||||
|
object oArea = GetArea(oCaster);
|
||||||
|
int nLevel = GetLocalInt(oArea, "DUNGEON_LEVEL");
|
||||||
|
vector vPos = GetPosition(oCaster);
|
||||||
|
|
||||||
|
// Convert position to grid coordinates (assuming 10-foot squares)
|
||||||
|
int nGridX = FloatToInt(vPos.x / 10.0);
|
||||||
|
int nGridY = FloatToInt(vPos.y / 10.0);
|
||||||
|
|
||||||
|
// Get facing direction
|
||||||
|
float fFacing = GetFacing(oCaster);
|
||||||
|
string sFacing = "";
|
||||||
|
|
||||||
|
// Convert facing angle to cardinal direction
|
||||||
|
if (fFacing >= 315.0 || fFacing < 45.0) sFacing = "North";
|
||||||
|
else if (fFacing >= 45.0 && fFacing < 135.0) sFacing = "East";
|
||||||
|
else if (fFacing >= 135.0 && fFacing < 225.0) sFacing = "South";
|
||||||
|
else sFacing = "West";
|
||||||
|
|
||||||
|
// Build location description
|
||||||
|
string sLocation = "DUMAPIC: Location Information\n";
|
||||||
|
sLocation += "Level: " + IntToString(nLevel) + "\n";
|
||||||
|
sLocation += "Position: " + IntToString(nGridX) + " East, " +
|
||||||
|
IntToString(nGridY) + " North\n";
|
||||||
|
sLocation += "Facing: " + sFacing;
|
||||||
|
|
||||||
|
// Check for special areas
|
||||||
|
if (GetLocalInt(oArea, "IS_DARKNESS_ZONE"))
|
||||||
|
sLocation += "\nIn Darkness Zone";
|
||||||
|
if (GetLocalInt(oArea, "IS_ANTIMAGIC_ZONE"))
|
||||||
|
sLocation += "\nIn Anti-Magic Zone";
|
||||||
|
if (GetLocalInt(oArea, "IS_TRAP_ZONE"))
|
||||||
|
sLocation += "\nDanger: Trap Zone";
|
||||||
|
|
||||||
|
// Display the location information
|
||||||
|
FloatingTextStringOnCreature(sLocation, oCaster, FALSE);
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
87
Content/spells/halito.nss
Normal file
87
Content/spells/halito.nss
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Halito (Little Fire)
|
||||||
|
//:: halito.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 1d8 (1-8) points of fire damage to a monster.
|
||||||
|
Level 1 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 1 Mage attack spell that targets
|
||||||
|
one monster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 1d8 fire damage
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr))
|
||||||
|
{
|
||||||
|
// 4. Calculate damage
|
||||||
|
int nDamage = d8(1); // 1d8 fire damage
|
||||||
|
|
||||||
|
// Apply metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
nDamage = 8; // Maximum damage
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
nDamage += nDamage / 2; // +50% damage
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, 1);
|
||||||
|
|
||||||
|
// 5. Create the damage effect
|
||||||
|
effect eDamage = PRCEffectDamage(oTarget, nDamage, DAMAGE_TYPE_FIRE);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_S);
|
||||||
|
|
||||||
|
// 6. Apply the effects
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
PRCBonusDamage(oTarget);
|
||||||
|
|
||||||
|
// 7. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("HALITO: " + IntToString(nDamage) + " fire damage to " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("HALITO: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
146
Content/spells/haman.nss
Normal file
146
Content/spells/haman.nss
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Haman (Change)
|
||||||
|
//:: haman.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Has random effects and drains the caster one
|
||||||
|
experience level.
|
||||||
|
Level 6 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Mage support/disable spell with
|
||||||
|
random effects. Requires caster level 13+.
|
||||||
|
|
||||||
|
Possible effects:
|
||||||
|
- Augmented magic: party spells cause more damage
|
||||||
|
- Cure party: cures all conditions
|
||||||
|
- Heal party: MADI on all members
|
||||||
|
- Silence enemies: all monsters silenced
|
||||||
|
- Teleport enemies: monsters teleported away
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Random effects with level drain
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_WIZARD, oCaster);
|
||||||
|
|
||||||
|
// Declare variables used in switch cases
|
||||||
|
object oMember;
|
||||||
|
object oArea;
|
||||||
|
object oTarget;
|
||||||
|
effect eHeal;
|
||||||
|
effect eSilence;
|
||||||
|
effect eTeleport;
|
||||||
|
|
||||||
|
// 2. Check minimum level requirement
|
||||||
|
if (nCasterLevel < 13)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("HAMAN requires level 13+ to cast!", oCaster, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Apply level drain to caster
|
||||||
|
effect eDrain = EffectNegativeLevel(1);
|
||||||
|
effect eVis = EffectVisualEffect(47); // Negative energy visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDrain, oCaster);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
|
||||||
|
|
||||||
|
// 4. Roll for random effect
|
||||||
|
int nEffect = Random(5); // 0-4 for five possible effects
|
||||||
|
|
||||||
|
// 5. Apply the random effect
|
||||||
|
switch(nEffect)
|
||||||
|
{
|
||||||
|
case 0: // Augmented magic
|
||||||
|
{
|
||||||
|
SetLocalInt(oCaster, "SPELL_DAMAGE_BONUS", 2);
|
||||||
|
FloatingTextStringOnCreature("HAMAN: Party spells enhanced!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1: // Cure party
|
||||||
|
{
|
||||||
|
oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Remove negative conditions
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_PARALYZED");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_POISONED");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_SLEEPING");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_SILENCED");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_FEARED");
|
||||||
|
|
||||||
|
// Visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(14), oMember);
|
||||||
|
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("HAMAN: Party conditions cured!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2: // Heal party
|
||||||
|
{
|
||||||
|
oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Full heal
|
||||||
|
eHeal = EffectHeal(GetMaxHitPoints(oMember));
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oMember);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(14), oMember);
|
||||||
|
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("HAMAN: Party fully healed!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3: // Silence enemies
|
||||||
|
{
|
||||||
|
oArea = GetArea(oCaster);
|
||||||
|
oTarget = GetFirstObjectInArea(oArea);
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if (GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
eSilence = EffectSilence();
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSilence, oTarget);
|
||||||
|
SetLocalInt(oTarget, "CONDITION_SILENCED", 1);
|
||||||
|
}
|
||||||
|
oTarget = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("HAMAN: All enemies silenced!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 4: // Teleport enemies
|
||||||
|
{
|
||||||
|
oArea = GetArea(oCaster);
|
||||||
|
oTarget = GetFirstObjectInArea(oArea);
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if (GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
eTeleport = EffectVisualEffect(46); // Teleport visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eTeleport, oTarget);
|
||||||
|
SetLocalInt(oTarget, "TELEPORTED_AWAY", 1);
|
||||||
|
}
|
||||||
|
oTarget = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("HAMAN: All enemies teleported away!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify level drain
|
||||||
|
FloatingTextStringOnCreature("Lost one experience level!", oCaster, TRUE);
|
||||||
|
}
|
149
Content/spells/kadorto.nss
Normal file
149
Content/spells/kadorto.nss
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Kadorto (Resurrection)
|
||||||
|
//:: kadorto.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to resurrect a dead party member, even if
|
||||||
|
they've been turned to ashes. If successful, they
|
||||||
|
are revived with all hit points. If failed, they
|
||||||
|
are permanently lost.
|
||||||
|
Level 7 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 7 Priest healing/field spell that
|
||||||
|
targets one character.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
#include "inc_dispel"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Attempt to resurrect a dead character
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Check if target is valid
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Notify if no target selected
|
||||||
|
FloatingTextStringOnCreature("KADORTO: No target selected", oCaster, TRUE);
|
||||||
|
PRCSetSchool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if target is dead
|
||||||
|
if (!GetIsDead(oTarget))
|
||||||
|
{
|
||||||
|
// Check for custom "ashes" condition
|
||||||
|
int bIsAshes = GetLocalInt(oTarget, "CONDITION_ASHES");
|
||||||
|
|
||||||
|
if (!bIsAshes)
|
||||||
|
{
|
||||||
|
// Notify if target is not dead
|
||||||
|
FloatingTextStringOnCreature("KADORTO: Target must be dead or ashes", oCaster, TRUE);
|
||||||
|
PRCSetSchool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate resurrection chance based on caster level
|
||||||
|
int nChance = 60 + (nCasterLevel * 5); // Base 60% + 5% per level
|
||||||
|
|
||||||
|
// Reduce chance if target is ashes
|
||||||
|
if (GetLocalInt(oTarget, "CONDITION_ASHES") == 1)
|
||||||
|
{
|
||||||
|
nChance -= 20; // 20% penalty for ashes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply metamagic effects
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
{
|
||||||
|
nChance = 100; // Guaranteed success with Maximize
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
{
|
||||||
|
nChance += nChance / 2; // +50% chance with Empower
|
||||||
|
if (nChance > 100) nChance = 100; // Cap at 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Create the resurrection effects
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_RAISE_DEAD);
|
||||||
|
effect eHeal = PRCEffectHeal(GetMaxHitPoints(oTarget), oTarget); // Full heal
|
||||||
|
|
||||||
|
// Attempt resurrection
|
||||||
|
if (d100() <= nChance)
|
||||||
|
{
|
||||||
|
// Success
|
||||||
|
// Apply resurrection effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
|
||||||
|
// Remove all effects
|
||||||
|
effect eAllEffects = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eAllEffects))
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eAllEffects);
|
||||||
|
eAllEffects = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply visual effect for condition removal
|
||||||
|
effect eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove custom condition flags
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_DEAD");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_ASHES");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_PARALYZED");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_POISONED");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_SLEEPING");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_SILENCED");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_BLINDED");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_CONFUSED");
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_DISEASED");
|
||||||
|
|
||||||
|
// Apply resurrection and healing effects
|
||||||
|
effect eResurrect = EffectResurrection();
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eResurrect, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("KADORTO: " + GetName(oTarget) + " has been resurrected!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Failure - Character is permanently lost
|
||||||
|
// Apply visual effect for failure
|
||||||
|
effect eFailVis = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eFailVis, oTarget);
|
||||||
|
|
||||||
|
// Mark as permanently lost
|
||||||
|
SetLocalInt(oTarget, "PERMANENTLY_LOST", 1);
|
||||||
|
|
||||||
|
// Notify failure
|
||||||
|
FloatingTextStringOnCreature("KADORTO: " + GetName(oTarget) + " has been permanently lost!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
109
Content/spells/kalki.nss
Normal file
109
Content/spells/kalki.nss
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Kalki (Blessings)
|
||||||
|
//:: kalki.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of all party members by 1
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 1 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 1 Priest support spell that targets
|
||||||
|
the entire party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Improve AC and attack rolls for all party members
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_ENCHANTMENT);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Calculate duration (based on caster level)
|
||||||
|
float fDuration = TurnsToSeconds(nCasterLevel); // 1 turn per level
|
||||||
|
|
||||||
|
// Check for Extend Spell metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create visual effects
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_HEAD_HOLY);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Create the blessing effects
|
||||||
|
effect eAC = EffectACIncrease(1, AC_DEFLECTION_BONUS); // Improve AC by 1
|
||||||
|
effect eAttack = EffectAttackIncrease(1); // +1 to attack rolls
|
||||||
|
effect eSave = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_FEAR); // +1 to saves vs fear
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eAC, eAttack);
|
||||||
|
eLink = EffectLinkEffects(eLink, eSave);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur);
|
||||||
|
|
||||||
|
// Apply the area effect
|
||||||
|
location lCaster = GetLocation(oCaster);
|
||||||
|
float fRange = FeetToMeters(50.0);
|
||||||
|
|
||||||
|
// Apply visual effect at caster location
|
||||||
|
effect eImpact = EffectVisualEffect(VFX_FNF_LOS_HOLY_30);
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lCaster);
|
||||||
|
|
||||||
|
// Get the first target in the radius around the caster
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, fRange, lCaster);
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Only affect friendly targets
|
||||||
|
if (GetIsReactionTypeFriendly(oTarget) || GetFactionEqual(oTarget))
|
||||||
|
{
|
||||||
|
// Fire spell cast at event for target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Apply random delay for visual effect
|
||||||
|
float fDelay = PRCGetRandomDelay(0.4, 1.1);
|
||||||
|
|
||||||
|
// Apply the effects
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, GetSpellId(), nCasterLevel));
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next target in the specified area around the caster
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, fRange, lCaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("KALKI: Blessed " + IntToString(nAffected) + " allies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("KALKI: No allies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
94
Content/spells/kandi.nss
Normal file
94
Content/spells/kandi.nss
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Kandi (Locate Soul)
|
||||||
|
//:: kandi.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Identifies the location of missing/dead party members
|
||||||
|
in the dungeon.
|
||||||
|
Level 5 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Priest field spell that helps
|
||||||
|
locate lost party members.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Locate missing/dead party members
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Create the divination effect
|
||||||
|
effect eVis = EffectVisualEffect(14); // Divination visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
|
||||||
|
|
||||||
|
// 3. Get current dungeon level and coordinates
|
||||||
|
int nCurrentLevel = GetLocalInt(GetArea(oCaster), "DUNGEON_LEVEL");
|
||||||
|
vector vCurrentPos = GetPosition(oCaster);
|
||||||
|
|
||||||
|
// 4. Search for missing party members
|
||||||
|
object oMember = GetFirstPC();
|
||||||
|
int nFound = 0;
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Check if member is dead or missing
|
||||||
|
if (GetLocalInt(oMember, "CONDITION_DEAD") == 1 ||
|
||||||
|
GetLocalInt(oMember, "CONDITION_ASHES") == 1 ||
|
||||||
|
GetLocalInt(oMember, "CONDITION_MISSING") == 1)
|
||||||
|
{
|
||||||
|
nFound++;
|
||||||
|
|
||||||
|
// Get member's last known location
|
||||||
|
int nMemberLevel = GetLocalInt(oMember, "LAST_KNOWN_LEVEL");
|
||||||
|
vector vMemberPos = Vector(
|
||||||
|
GetLocalFloat(oMember, "LAST_KNOWN_X"),
|
||||||
|
GetLocalFloat(oMember, "LAST_KNOWN_Y"),
|
||||||
|
GetLocalFloat(oMember, "LAST_KNOWN_Z")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calculate relative direction and distance
|
||||||
|
float fDist = GetDistanceBetweenLocations(
|
||||||
|
Location(GetArea(oCaster), vCurrentPos, 0.0),
|
||||||
|
Location(GetArea(oCaster), vMemberPos, 0.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
string sDirection = "";
|
||||||
|
if (vMemberPos.x > vCurrentPos.x) sDirection += "east";
|
||||||
|
else if (vMemberPos.x < vCurrentPos.x) sDirection += "west";
|
||||||
|
if (vMemberPos.y > vCurrentPos.y) sDirection += "north";
|
||||||
|
else if (vMemberPos.y < vCurrentPos.y) sDirection += "south";
|
||||||
|
|
||||||
|
// Build location description
|
||||||
|
string sStatus = GetLocalInt(oMember, "CONDITION_DEAD") == 1 ? "dead" :
|
||||||
|
GetLocalInt(oMember, "CONDITION_ASHES") == 1 ? "ashes" : "missing";
|
||||||
|
|
||||||
|
string sLocation = GetName(oMember) + " (" + sStatus + ") is ";
|
||||||
|
if (nMemberLevel != nCurrentLevel)
|
||||||
|
{
|
||||||
|
sLocation += IntToString(abs(nMemberLevel - nCurrentLevel)) + " level";
|
||||||
|
sLocation += nMemberLevel > nCurrentLevel ? " below" : " above";
|
||||||
|
sLocation += ", ";
|
||||||
|
}
|
||||||
|
sLocation += IntToString(FloatToInt(fDist)) + " steps " + sDirection;
|
||||||
|
|
||||||
|
// Display the location information
|
||||||
|
FloatingTextStringOnCreature(sLocation, oCaster, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Notify if no one was found
|
||||||
|
if (nFound == 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("KANDI: No missing or dead party members found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
202
Content/spells/katino.nss
Normal file
202
Content/spells/katino.nss
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Katino (Bad Air)
|
||||||
|
//:: katino.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to put to sleep a monster group.
|
||||||
|
Level 1 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 1 Mage disable spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Put monster group to sleep
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_ENCHANTMENT);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
|
||||||
|
// Calculate HD affected (4 + d4 in standard sleep spell)
|
||||||
|
int nHD = 4 + d4();
|
||||||
|
|
||||||
|
// Apply metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
{
|
||||||
|
nHD = 8; // Maximum HD affected
|
||||||
|
}
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
{
|
||||||
|
nHD = nHD + (nHD / 2); // +50% HD affected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate duration
|
||||||
|
int nDuration = 3 + nCasterLevel;
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
nDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the visual effect
|
||||||
|
effect eImpact = EffectVisualEffect(VFX_FNF_SLEEP);
|
||||||
|
|
||||||
|
// Apply the visual effect at the target location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, PRCGetSpellTargetLocation());
|
||||||
|
|
||||||
|
// Create the sleep effects
|
||||||
|
effect eSleep = EffectSleep();
|
||||||
|
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_NEGATIVE);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_SLEEP);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eSleep, eMind);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur);
|
||||||
|
|
||||||
|
// Create a unique local variable name for this casting
|
||||||
|
string sSpellLocal = "WIZARDRY_SPELL_KATINO_" + ObjectToString(oCaster);
|
||||||
|
|
||||||
|
// Get the first target in the spell area
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, PRCGetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
|
||||||
|
// Variables for the HD tracking loop
|
||||||
|
object oLowest;
|
||||||
|
int bContinueLoop = TRUE;
|
||||||
|
int nLow;
|
||||||
|
int nMax = 9; // Maximum HD creature affected
|
||||||
|
int nCurrentHD;
|
||||||
|
int bAlreadyAffected;
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Process targets in order of lowest HD first until we run out of HD to affect
|
||||||
|
while ((nHD > 0) && (bContinueLoop))
|
||||||
|
{
|
||||||
|
nLow = nMax;
|
||||||
|
bContinueLoop = FALSE;
|
||||||
|
|
||||||
|
// Get the first creature in the spell area
|
||||||
|
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, PRCGetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Check if target is valid (hostile, not construct, not undead)
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster) &&
|
||||||
|
MyPRCGetRacialType(oTarget) != RACIAL_TYPE_CONSTRUCT &&
|
||||||
|
MyPRCGetRacialType(oTarget) != RACIAL_TYPE_UNDEAD)
|
||||||
|
{
|
||||||
|
// Check if already affected by this casting
|
||||||
|
bAlreadyAffected = GetLocalInt(oTarget, sSpellLocal);
|
||||||
|
|
||||||
|
if (!bAlreadyAffected)
|
||||||
|
{
|
||||||
|
// Get the current HD of the target
|
||||||
|
nCurrentHD = GetHitDice(oTarget);
|
||||||
|
|
||||||
|
// Find the lowest HD creature that can be affected
|
||||||
|
if (nCurrentHD < nLow && nCurrentHD <= nHD && nCurrentHD < 5)
|
||||||
|
{
|
||||||
|
nLow = nCurrentHD;
|
||||||
|
oLowest = oTarget;
|
||||||
|
bContinueLoop = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next target in the shape
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, PRCGetSpellTargetLocation(), TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the lowest HD creature found
|
||||||
|
if (GetIsObjectValid(oLowest))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the target
|
||||||
|
SignalEvent(oLowest, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oLowest, nPenetr))
|
||||||
|
{
|
||||||
|
// Make Will save
|
||||||
|
if (!PRCMySavingThrow(SAVING_THROW_WILL, oLowest, PRCGetSaveDC(oLowest, oCaster), SAVING_THROW_TYPE_MIND_SPELLS))
|
||||||
|
{
|
||||||
|
// Check for sleep immunity
|
||||||
|
if (GetIsImmune(oLowest, IMMUNITY_TYPE_SLEEP) == FALSE)
|
||||||
|
{
|
||||||
|
// Apply the sleep effect with visual
|
||||||
|
effect eLink2 = EffectLinkEffects(eLink, eVis);
|
||||||
|
int nScaledDuration = PRCGetScaledDuration(nDuration, oLowest);
|
||||||
|
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink2, oLowest, RoundsToSeconds(nScaledDuration), TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// Set sleep condition flag
|
||||||
|
SetLocalInt(oLowest, "CONDITION_SLEEPING", 1);
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature(GetName(oLowest) + " falls asleep!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Apply just the sleep effect for the immunity message
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSleep, oLowest, RoundsToSeconds(nDuration), TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// Notify immunity
|
||||||
|
FloatingTextStringOnCreature(GetName(oLowest) + " is immune to sleep!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify save
|
||||||
|
FloatingTextStringOnCreature(GetName(oLowest) + " resisted sleep!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify SR
|
||||||
|
FloatingTextStringOnCreature(GetName(oLowest) + " has spell resistance!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark this creature as processed for this casting
|
||||||
|
SetLocalInt(oLowest, sSpellLocal, TRUE);
|
||||||
|
DelayCommand(0.5, DeleteLocalInt(oLowest, sSpellLocal));
|
||||||
|
|
||||||
|
// Remove the HD of the creature from the total
|
||||||
|
nHD = nHD - GetHitDice(oLowest);
|
||||||
|
oLowest = OBJECT_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("KATINO: Put " + IntToString(nAffected) + " enemies to sleep!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("KATINO: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
127
Content/spells/lahalito.nss
Normal file
127
Content/spells/lahalito.nss
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Lahalito (Torch)
|
||||||
|
//:: lahalito.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 6d6 (6-36) points of fire damage to a
|
||||||
|
monster group.
|
||||||
|
Level 4 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 4 Mage attack spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 6d6 fire damage to a monster group
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
int nDamage;
|
||||||
|
float fDelay;
|
||||||
|
|
||||||
|
// Get the target location
|
||||||
|
location lTarget = PRCGetSpellTargetLocation();
|
||||||
|
|
||||||
|
// Create the fire storm visual effect
|
||||||
|
effect eFireStorm = EffectVisualEffect(VFX_FNF_FIRESTORM);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
|
||||||
|
|
||||||
|
// Get the elemental damage type (default to fire)
|
||||||
|
int EleDmg = ChangedElementalDamage(oCaster, DAMAGE_TYPE_FIRE);
|
||||||
|
|
||||||
|
// Apply the fire storm visual effect at the location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eFireStorm, lTarget);
|
||||||
|
|
||||||
|
// Declare the spell shape, size and the location
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
|
||||||
|
// Track affected targets
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Cycle through the targets within the spell shape
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Get the distance between the explosion and the target to calculate delay
|
||||||
|
fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay))
|
||||||
|
{
|
||||||
|
// Calculate damage - 6d6 fire damage
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
nDamage = 36; // 6 * 6 = 36 (maximum damage)
|
||||||
|
else
|
||||||
|
nDamage = d6(6);
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
nDamage += nDamage / 2; // +50% damage
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, 6);
|
||||||
|
|
||||||
|
// Adjust the damage based on the Reflex Save, Evasion and Improved Evasion
|
||||||
|
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, PRCGetSaveDC(oTarget, oCaster), SAVING_THROW_TYPE_FIRE);
|
||||||
|
|
||||||
|
if (nDamage > 0)
|
||||||
|
{
|
||||||
|
// Set the damage effect
|
||||||
|
effect eDam = PRCEffectDamage(oTarget, nDamage, EleDmg);
|
||||||
|
|
||||||
|
// Apply effects to the currently selected target
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
PRCBonusDamage(oTarget);
|
||||||
|
|
||||||
|
// Notify damage
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature("LAHALITO: " + IntToString(nDamage) + " fire damage to " + GetName(oTarget), oCaster, TRUE));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the next target within the spell shape
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("LAHALITO: Hit " + IntToString(nAffected) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("LAHALITO: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
113
Content/spells/lakanito.nss
Normal file
113
Content/spells/lakanito.nss
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Lakanito (Suffocation)
|
||||||
|
//:: lakanito.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Kills a monster group. May be resisted at rate of
|
||||||
|
6% per monster hit point die.
|
||||||
|
Level 6 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Mage attack spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Kill monster group with HP-based resistance
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target monster group
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// Get the faction/group of the target
|
||||||
|
object oFaction = GetFactionLeader(oTarget);
|
||||||
|
|
||||||
|
// Create suffocation visual effect at the target location
|
||||||
|
location lTarget = GetLocation(oTarget);
|
||||||
|
effect eSuffocateVis = EffectVisualEffect(47); // Death visual effect
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eSuffocateVis, lTarget);
|
||||||
|
|
||||||
|
// Apply to all members of the faction/group
|
||||||
|
object oMember = GetFirstFactionMember(oFaction);
|
||||||
|
int nAffected = 0;
|
||||||
|
int nResisted = 0;
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Only affect enemies
|
||||||
|
if (GetIsEnemy(oMember, oCaster))
|
||||||
|
{
|
||||||
|
// Calculate resistance chance based on hit dice
|
||||||
|
int nHitDice = GetHitDice(oMember);
|
||||||
|
int nResistChance = nHitDice * 6; // 6% per hit die
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oMember, EventSpellCastAt(oCaster, 39)); // Death spell ID
|
||||||
|
|
||||||
|
// Check if monster resists
|
||||||
|
if (Random(100) < nResistChance)
|
||||||
|
{
|
||||||
|
// Monster resisted
|
||||||
|
FloatingTextStringOnCreature(GetName(oMember) + " resisted suffocation!", oCaster, TRUE);
|
||||||
|
nResisted++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create the death effect
|
||||||
|
effect eDeath = EffectDeath();
|
||||||
|
effect eVis = EffectVisualEffect(45); // Death visual effect
|
||||||
|
|
||||||
|
// Apply the visual and death effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oMember);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oMember);
|
||||||
|
|
||||||
|
// Notify kill
|
||||||
|
FloatingTextStringOnCreature(GetName(oMember) + " is suffocated!", oCaster, TRUE);
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next faction member
|
||||||
|
oMember = GetNextFactionMember(oFaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0 || nResisted > 0)
|
||||||
|
{
|
||||||
|
string sResult = "LAKANITO: ";
|
||||||
|
if (nAffected > 0)
|
||||||
|
sResult += IntToString(nAffected) + " killed";
|
||||||
|
if (nAffected > 0 && nResisted > 0)
|
||||||
|
sResult += ", ";
|
||||||
|
if (nResisted > 0)
|
||||||
|
sResult += IntToString(nResisted) + " resisted";
|
||||||
|
FloatingTextStringOnCreature(sResult, oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("LAKANITO: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("LAKANITO: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
88
Content/spells/latumapic.nss
Normal file
88
Content/spells/latumapic.nss
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Latumapic (Identification)
|
||||||
|
//:: latumapic.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Identifies a monster group.
|
||||||
|
Level 3 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 3 Priest disable spell that targets
|
||||||
|
a monster group, revealing their true identity.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Identify a monster group
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target monster group
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Create the identification effect
|
||||||
|
effect eVis = EffectVisualEffect(14); // Identification visual effect
|
||||||
|
|
||||||
|
// 4. Apply to all monsters in the group
|
||||||
|
if (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Get the faction/group of the target
|
||||||
|
object oFaction = GetFactionLeader(oTarget);
|
||||||
|
|
||||||
|
// Apply to all members of the faction/group
|
||||||
|
object oMember = GetFirstFactionMember(oFaction);
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Only affect enemies
|
||||||
|
if (GetIsEnemy(oMember, oCaster))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oMember, EventSpellCastAt(oCaster, 32, FALSE)); // Identify spell ID
|
||||||
|
|
||||||
|
// Apply the visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oMember);
|
||||||
|
|
||||||
|
// Mark as identified
|
||||||
|
SetLocalInt(oMember, "IDENTIFIED", 1);
|
||||||
|
|
||||||
|
// Get monster information
|
||||||
|
string sName = GetName(oMember);
|
||||||
|
int nLevel = GetHitDice(oMember);
|
||||||
|
int nHP = GetCurrentHitPoints(oMember);
|
||||||
|
int nMaxHP = GetMaxHitPoints(oMember);
|
||||||
|
|
||||||
|
// Display monster information to the caster
|
||||||
|
string sInfo = sName + " (Level " + IntToString(nLevel) + ")\n";
|
||||||
|
sInfo += "HP: " + IntToString(nHP) + "/" + IntToString(nMaxHP) + "\n";
|
||||||
|
|
||||||
|
// Add special abilities or resistances if any
|
||||||
|
if (GetLocalInt(oMember, "ABILITY_UNDEAD") == 1)
|
||||||
|
sInfo += "Undead\n";
|
||||||
|
if (GetLocalInt(oMember, "ABILITY_SPELLCASTER") == 1)
|
||||||
|
sInfo += "Spellcaster\n";
|
||||||
|
if (GetLocalInt(oMember, "RESISTANCE_FIRE") == 1)
|
||||||
|
sInfo += "Fire Resistant\n";
|
||||||
|
if (GetLocalInt(oMember, "RESISTANCE_COLD") == 1)
|
||||||
|
sInfo += "Cold Resistant\n";
|
||||||
|
|
||||||
|
// Display the information
|
||||||
|
FloatingTextStringOnCreature(sInfo, oCaster, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next faction member
|
||||||
|
oMember = GetNextFactionMember(oFaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
91
Content/spells/latumofis.nss
Normal file
91
Content/spells/latumofis.nss
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Latumofis (Cure Poison)
|
||||||
|
//:: latumofis.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Cures poison for a party member.
|
||||||
|
Level 4 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 4 Priest healing spell that targets
|
||||||
|
one character.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Cure poison
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
|
||||||
|
// Check if target is valid
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, target self
|
||||||
|
oTarget = oCaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if target is valid and is a party member
|
||||||
|
if (GetIsObjectValid(oTarget) && spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Create the visual effects
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
|
||||||
|
// Check if target is poisoned
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_POISON, oTarget) || GetLocalInt(oTarget, "CONDITION_POISONED") == 1)
|
||||||
|
{
|
||||||
|
// Remove poison effects
|
||||||
|
effect ePoison = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(ePoison))
|
||||||
|
{
|
||||||
|
if (GetEffectType(ePoison) == EFFECT_TYPE_POISON)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, ePoison);
|
||||||
|
}
|
||||||
|
ePoison = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the poison condition flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_POISONED");
|
||||||
|
|
||||||
|
// Apply the visual effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("LATUMOFIS: Cured poison for " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if target is not poisoned
|
||||||
|
FloatingTextStringOnCreature(GetName(oTarget) + " is not poisoned.", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("LATUMOFIS: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
81
Content/spells/litokan.nss
Normal file
81
Content/spells/litokan.nss
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Litokan (Flame Tower)
|
||||||
|
//:: litokan.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 3d8 (3-24) points of fire damage to a
|
||||||
|
monster group.
|
||||||
|
Level 5 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Priest attack spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 3d8 fire damage to a monster group
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target monster group
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// Get the faction/group of the target
|
||||||
|
object oFaction = GetFactionLeader(oTarget);
|
||||||
|
|
||||||
|
// Apply to all members of the faction/group
|
||||||
|
object oMember = GetFirstFactionMember(oFaction);
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Only affect enemies
|
||||||
|
if (GetIsEnemy(oMember, oCaster))
|
||||||
|
{
|
||||||
|
// Calculate damage
|
||||||
|
int nDamage = d8(3); // 3d8 fire damage
|
||||||
|
|
||||||
|
// Create the damage effect
|
||||||
|
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_FIRE);
|
||||||
|
effect eVis = EffectVisualEffect(44); // Fire visual effect
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oMember, EventSpellCastAt(oCaster, 31)); // Fireball spell ID
|
||||||
|
|
||||||
|
// Apply the visual and damage effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oMember);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oMember);
|
||||||
|
|
||||||
|
// Notify damage
|
||||||
|
FloatingTextStringOnCreature("LITOKAN: " + IntToString(nDamage) + " fire damage to " + GetName(oMember), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next faction member
|
||||||
|
oMember = GetNextFactionMember(oFaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("LITOKAN: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the flame tower visual effect at the target location
|
||||||
|
location lTarget = GetLocation(oTarget);
|
||||||
|
effect eTower = EffectVisualEffect(43); // Column of fire visual effect
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eTower, lTarget);
|
||||||
|
}
|
70
Content/spells/loktofeit.nss
Normal file
70
Content/spells/loktofeit.nss
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Loktofeit (Recall)
|
||||||
|
//:: loktofeit.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes all party members to be transported back to
|
||||||
|
town, minus all of their equipment and most of
|
||||||
|
their gold.
|
||||||
|
Level 6 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Priest field spell that affects
|
||||||
|
the entire party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Transport party to town
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Create the teleport effect
|
||||||
|
effect eVis = EffectVisualEffect(46); // Teleport visual effect
|
||||||
|
|
||||||
|
// 3. Process each party member
|
||||||
|
object oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Apply visual effect before teleport
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oMember);
|
||||||
|
|
||||||
|
// Remove equipment
|
||||||
|
object oItem = GetFirstItemInInventory(oMember);
|
||||||
|
while (GetIsObjectValid(oItem))
|
||||||
|
{
|
||||||
|
// Remove the item
|
||||||
|
DestroyObject(oItem);
|
||||||
|
oItem = GetNextItemInInventory(oMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove most gold (leave 10%)
|
||||||
|
int nGold = GetGold(oMember);
|
||||||
|
int nGoldToKeep = nGold / 10; // Keep 10%
|
||||||
|
TakeGoldFromCreature(nGold, oMember, TRUE);
|
||||||
|
GiveGoldToCreature(oMember, nGoldToKeep);
|
||||||
|
|
||||||
|
// Set location to town
|
||||||
|
location lTown = GetLocation(GetWaypointByTag("WP_TOWN_ENTRANCE"));
|
||||||
|
|
||||||
|
// Teleport to town
|
||||||
|
AssignCommand(oMember, JumpToLocation(lTown));
|
||||||
|
|
||||||
|
// Notify the player
|
||||||
|
string sLostGold = IntToString(nGold - nGoldToKeep);
|
||||||
|
FloatingTextStringOnCreature("Lost " + sLostGold + " gold and all equipment!", oMember, TRUE);
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
FloatingTextStringOnCreature("LOKTOFEIT: Party recalled to town!", oCaster, TRUE);
|
||||||
|
}
|
109
Content/spells/lomilwa.nss
Normal file
109
Content/spells/lomilwa.nss
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Lomilwa (More Light)
|
||||||
|
//:: lomilwa.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
More powerful MILWA spell that lasts for the entire
|
||||||
|
expedition, but is terminated in darkness areas.
|
||||||
|
Level 3 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 3 Priest field/support spell that
|
||||||
|
targets the party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_sp_func"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Create stronger light and reveal secret doors with enhanced Search bonus
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// 1. Get caster and target information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
|
||||||
|
// 2. Calculate duration (based on caster level)
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
if (nCasterLevel < 3) nCasterLevel = 3; // Minimum level 3 for this spell
|
||||||
|
|
||||||
|
// Duration is fixed at 24 hours (entire expedition)
|
||||||
|
float fDuration = HoursToSeconds(24);
|
||||||
|
|
||||||
|
// Check for Extend Spell metamagic
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Create the light effect and enhanced Search skill bonus
|
||||||
|
// Using a stronger light effect (similar to daylight spell)
|
||||||
|
effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20); // Stronger light visual effect
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_HEAD_HOLY); // Cast visual effect
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Add enhanced Search skill bonus (better than MILWA)
|
||||||
|
effect eSearch = EffectSkillIncrease(SKILL_SEARCH, 20);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eLight, eSearch);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur);
|
||||||
|
|
||||||
|
// 4. Remove any existing light effects from the MILWA spell
|
||||||
|
if (GetLocalInt(oTarget, "MILWA_ACTIVE") == 1)
|
||||||
|
{
|
||||||
|
// Remove the MILWA effect by applying a new effect
|
||||||
|
// The game engine will handle removing the previous effect
|
||||||
|
DeleteLocalInt(oTarget, "MILWA_ACTIVE");
|
||||||
|
|
||||||
|
// Remove existing effects from MILWA
|
||||||
|
RemoveEffectsFromSpell(oTarget, SPELL_LIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Apply to the target (light follows the party)
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// 6. Set the LOMILWA flag
|
||||||
|
SetLocalInt(oTarget, "LOMILWA_ACTIVE", 1);
|
||||||
|
|
||||||
|
// 7. Reveal secret doors in the area with enhanced effect
|
||||||
|
object oArea = GetArea(oTarget);
|
||||||
|
object oDoor = GetFirstObjectInArea(oArea);
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oDoor))
|
||||||
|
{
|
||||||
|
// If the object is a secret door
|
||||||
|
if (GetObjectType(oDoor) == OBJECT_TYPE_DOOR && GetLocalInt(oDoor, "SECRET_DOOR"))
|
||||||
|
{
|
||||||
|
// Make it visible/discoverable
|
||||||
|
SetLocalInt(oDoor, "REVEALED", TRUE);
|
||||||
|
|
||||||
|
// Visual effect at door location (stronger than MILWA)
|
||||||
|
location lDoor = GetLocation(oDoor);
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_DISPEL_GREATER), lDoor);
|
||||||
|
}
|
||||||
|
|
||||||
|
oDoor = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("LOMILWA: Enhanced light spell active for 24 hours!", oTarget, TRUE);
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
80
Content/spells/lorto.nss
Normal file
80
Content/spells/lorto.nss
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Lorto (Blades)
|
||||||
|
//:: lorto.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 6d6 (6-36) points of damage to a monster group.
|
||||||
|
Level 6 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Priest attack spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 6d6 damage to a monster group
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target monster group
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// Get the faction/group of the target
|
||||||
|
object oFaction = GetFactionLeader(oTarget);
|
||||||
|
|
||||||
|
// Create the blade storm visual effect at the target location
|
||||||
|
location lTarget = GetLocation(oTarget);
|
||||||
|
effect eStorm = EffectVisualEffect(41); // Blade storm visual effect
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eStorm, lTarget);
|
||||||
|
|
||||||
|
// Apply to all members of the faction/group
|
||||||
|
object oMember = GetFirstFactionMember(oFaction);
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Only affect enemies
|
||||||
|
if (GetIsEnemy(oMember, oCaster))
|
||||||
|
{
|
||||||
|
// Calculate damage
|
||||||
|
int nDamage = d6(6); // 6d6 damage
|
||||||
|
|
||||||
|
// Create the damage effect
|
||||||
|
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_SLASHING);
|
||||||
|
effect eVis = EffectVisualEffect(42); // Blade impact visual effect
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oMember, EventSpellCastAt(oCaster, 35)); // Blade Barrier spell ID
|
||||||
|
|
||||||
|
// Apply the visual and damage effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oMember);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oMember);
|
||||||
|
|
||||||
|
// Notify damage
|
||||||
|
FloatingTextStringOnCreature("LORTO: " + IntToString(nDamage) + " blade damage to " + GetName(oMember), oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next faction member
|
||||||
|
oMember = GetNextFactionMember(oFaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("LORTO: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
86
Content/spells/mabadi.nss
Normal file
86
Content/spells/mabadi.nss
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Mabadi (Harming)
|
||||||
|
//:: mabadi.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes all but 1d8 (1-8) hit points to be removed
|
||||||
|
from a monster.
|
||||||
|
Level 6 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Priest attack spell that targets
|
||||||
|
one monster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Remove all but 1d8 HP from a monster
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// 4. Calculate save DC based on caster level
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_CLERIC, oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 6; // Minimum level 6 for this spell
|
||||||
|
int nDC = 10 + nCasterLevel;
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 27)); // Harm spell ID
|
||||||
|
|
||||||
|
// Allow saving throw to resist
|
||||||
|
if (!FortitudeSave(oTarget, nDC, 3)) // 3 = Death/Harm saving throw type
|
||||||
|
{
|
||||||
|
// 5. Calculate remaining HP
|
||||||
|
int nCurrentHP = GetCurrentHitPoints(oTarget);
|
||||||
|
int nRemainingHP = d8(1); // 1d8 HP will remain
|
||||||
|
int nDamage = nCurrentHP - nRemainingHP;
|
||||||
|
|
||||||
|
if (nDamage > 0) // Only apply if we're actually reducing HP
|
||||||
|
{
|
||||||
|
// 6. Create the damage effect
|
||||||
|
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_NEGATIVE);
|
||||||
|
effect eVis = EffectVisualEffect(40); // Negative energy visual effect
|
||||||
|
|
||||||
|
// 7. Apply the effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||||
|
|
||||||
|
// 8. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("MABADI: " + GetName(oTarget) + " reduced to " +
|
||||||
|
IntToString(nRemainingHP) + " hit points!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Target already has very low HP
|
||||||
|
FloatingTextStringOnCreature("MABADI: " + GetName(oTarget) + " already near death!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify resistance
|
||||||
|
FloatingTextStringOnCreature(GetName(oTarget) + " resisted the harming!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("MABADI: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
87
Content/spells/madalto.nss
Normal file
87
Content/spells/madalto.nss
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Madalto (Frost)
|
||||||
|
//:: madalto.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 8d8 (8-64) points of cold damage to a
|
||||||
|
monster group.
|
||||||
|
Level 5 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Mage attack spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 8d8 acid damage to a monster group with lingering effect
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Get the target location
|
||||||
|
location lTarget = PRCGetSpellTargetLocation();
|
||||||
|
|
||||||
|
// Calculate duration (based on caster level)
|
||||||
|
int nDuration = nCasterLevel / 2;
|
||||||
|
if (nDuration < 1) nDuration = 1;
|
||||||
|
|
||||||
|
// Check for Extend Spell metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
nDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the acid fog visual effect
|
||||||
|
effect eAOE = EffectAreaOfEffect(AOE_PER_FOGACID);
|
||||||
|
effect eImpact = EffectVisualEffect(VFX_FNF_GAS_EXPLOSION_ACID);
|
||||||
|
|
||||||
|
// Apply the visual effect at the location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lTarget);
|
||||||
|
|
||||||
|
// Create an instance of the AOE Object using the Apply Effect function
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, lTarget, RoundsToSeconds(nDuration));
|
||||||
|
|
||||||
|
// Get the AOE object and set its properties
|
||||||
|
object oAoE = GetAreaOfEffectObject(lTarget, "VFX_PER_FOGACID");
|
||||||
|
|
||||||
|
// Set the damage type (default to acid)
|
||||||
|
int EleDmg = ChangedElementalDamage(oCaster, DAMAGE_TYPE_ACID);
|
||||||
|
|
||||||
|
// Set the AOE properties
|
||||||
|
SetAllAoEInts(SPELL_ACID_FOG, oAoE, PRCGetSaveDC(OBJECT_INVALID, oCaster), 0, nCasterLevel);
|
||||||
|
SetLocalInt(oAoE, "Acid_Fog_Damage", EleDmg);
|
||||||
|
|
||||||
|
// Set custom damage for MADALTO (8d8 instead of standard 2d6)
|
||||||
|
SetLocalInt(oAoE, "MADALTO_DAMAGE", 1);
|
||||||
|
|
||||||
|
// Store the metamagic information for the AOE script to use
|
||||||
|
SetLocalInt(oAoE, "METAMAGIC_MAXIMIZE", CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE));
|
||||||
|
SetLocalInt(oAoE, "METAMAGIC_EMPOWER", CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER));
|
||||||
|
|
||||||
|
// Store the caster for the AOE script to use
|
||||||
|
SetLocalObject(oAoE, "CASTER", oCaster);
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("MADALTO: Acid fog created for " + IntToString(nDuration) + " rounds!", oCaster, TRUE);
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
228
Content/spells/madi.nss
Normal file
228
Content/spells/madi.nss
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Madi (Healing)
|
||||||
|
//:: madi.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Restores all hit points and cures all conditions
|
||||||
|
except death for a party member.
|
||||||
|
Level 6 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Priest healing spell that targets
|
||||||
|
one character.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Full heal and cure conditions
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
|
||||||
|
// Check if target is valid and is a party member
|
||||||
|
if (GetIsObjectValid(oTarget) && spellsIsTarget(oTarget, SPELL_TARGET_ALLALLIES, oCaster))
|
||||||
|
{
|
||||||
|
// Check if target is dead
|
||||||
|
if (GetIsDead(oTarget))
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MADI cannot cure death. Use DI or KADORTO instead.", oCaster, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Create the healing effects
|
||||||
|
effect eHeal = PRCEffectHeal(GetMaxHitPoints(oTarget), oTarget); // Full heal
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_HEALING_G); // Major healing visual effect
|
||||||
|
|
||||||
|
// Create the condition removal effects
|
||||||
|
effect eRemove;
|
||||||
|
|
||||||
|
// Remove paralysis
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_PARALYZE, oTarget))
|
||||||
|
{
|
||||||
|
eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove the effect
|
||||||
|
effect eParalyze = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eParalyze))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eParalyze) == EFFECT_TYPE_PARALYZE)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eParalyze);
|
||||||
|
}
|
||||||
|
eParalyze = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_PARALYZED");
|
||||||
|
FloatingTextStringOnCreature("Paralysis cured!", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove poison
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_POISON, oTarget))
|
||||||
|
{
|
||||||
|
eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove the effect
|
||||||
|
effect ePoison = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(ePoison))
|
||||||
|
{
|
||||||
|
if (GetEffectType(ePoison) == EFFECT_TYPE_POISON)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, ePoison);
|
||||||
|
}
|
||||||
|
ePoison = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_POISONED");
|
||||||
|
FloatingTextStringOnCreature("Poison cured!", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove sleep
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_SLEEP, oTarget))
|
||||||
|
{
|
||||||
|
eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove the effect
|
||||||
|
effect eSleep = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eSleep))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eSleep) == EFFECT_TYPE_SLEEP)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eSleep);
|
||||||
|
}
|
||||||
|
eSleep = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_SLEEPING");
|
||||||
|
FloatingTextStringOnCreature("Sleep removed!", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove disease
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_DISEASE, oTarget))
|
||||||
|
{
|
||||||
|
eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove the effect
|
||||||
|
effect eDisease = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eDisease))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eDisease) == EFFECT_TYPE_DISEASE)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eDisease);
|
||||||
|
}
|
||||||
|
eDisease = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_DISEASED");
|
||||||
|
FloatingTextStringOnCreature("Disease cured!", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove blindness
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_BLINDNESS, oTarget))
|
||||||
|
{
|
||||||
|
eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove the effect
|
||||||
|
effect eBlind = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eBlind))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eBlind) == EFFECT_TYPE_BLINDNESS)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eBlind);
|
||||||
|
}
|
||||||
|
eBlind = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_BLINDED");
|
||||||
|
FloatingTextStringOnCreature("Blindness cured!", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove confusion
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_CONFUSED, oTarget))
|
||||||
|
{
|
||||||
|
eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove the effect
|
||||||
|
effect eConfused = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eConfused))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eConfused) == EFFECT_TYPE_CONFUSED)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eConfused);
|
||||||
|
}
|
||||||
|
eConfused = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_CONFUSED");
|
||||||
|
FloatingTextStringOnCreature("Confusion cured!", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove silence
|
||||||
|
if (GetHasEffect(EFFECT_TYPE_SILENCE, oTarget))
|
||||||
|
{
|
||||||
|
eRemove = EffectVisualEffect(VFX_IMP_REMOVE_CONDITION);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eRemove, oTarget);
|
||||||
|
|
||||||
|
// Remove the effect
|
||||||
|
effect eSilence = GetFirstEffect(oTarget);
|
||||||
|
while (GetIsEffectValid(eSilence))
|
||||||
|
{
|
||||||
|
if (GetEffectType(eSilence) == EFFECT_TYPE_SILENCE)
|
||||||
|
{
|
||||||
|
RemoveEffect(oTarget, eSilence);
|
||||||
|
}
|
||||||
|
eSilence = GetNextEffect(oTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the flag
|
||||||
|
DeleteLocalInt(oTarget, "CONDITION_SILENCED");
|
||||||
|
FloatingTextStringOnCreature("Silence removed!", oTarget, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the healing effects last
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget);
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("MADI: " + GetName(oTarget) + " fully healed and cured!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("MADI: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
124
Content/spells/mahalito.nss
Normal file
124
Content/spells/mahalito.nss
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Mahalito (Big Fire)
|
||||||
|
//:: mahalito.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 4d6 (4-24) points of fire damage to a
|
||||||
|
monster group.
|
||||||
|
Level 3 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 3 Mage attack spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 4d6 fire damage to a monster group
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
int nDamage;
|
||||||
|
float fDelay;
|
||||||
|
|
||||||
|
// Get the target location
|
||||||
|
location lTarget = PRCGetSpellTargetLocation();
|
||||||
|
|
||||||
|
// Create the fireball explosion at the location
|
||||||
|
effect eExplode = EffectVisualEffect(VFX_FNF_FIREBALL);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
|
||||||
|
|
||||||
|
// Apply the fireball explosion at the location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eExplode, lTarget);
|
||||||
|
|
||||||
|
// Declare the spell shape, size and the location
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
|
||||||
|
// Track affected targets
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Cycle through the targets within the spell shape
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Get the distance between the explosion and the target to calculate delay
|
||||||
|
fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay))
|
||||||
|
{
|
||||||
|
// Calculate damage - 4d6 fire damage
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
nDamage = 24; // 4 * 6 = 24 (maximum damage)
|
||||||
|
else
|
||||||
|
nDamage = d6(4);
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
nDamage += nDamage / 2; // +50% damage
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, 4);
|
||||||
|
|
||||||
|
// Adjust the damage based on the Reflex Save, Evasion and Improved Evasion
|
||||||
|
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, PRCGetSaveDC(oTarget, oCaster), SAVING_THROW_TYPE_FIRE);
|
||||||
|
|
||||||
|
if (nDamage > 0)
|
||||||
|
{
|
||||||
|
// Set the damage effect
|
||||||
|
effect eDam = PRCEffectDamage(oTarget, nDamage, DAMAGE_TYPE_FIRE);
|
||||||
|
|
||||||
|
// Apply effects to the currently selected target
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
PRCBonusDamage(oTarget);
|
||||||
|
|
||||||
|
// Notify damage
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature("MAHALITO: " + IntToString(nDamage) + " fire damage to " + GetName(oTarget), oCaster, TRUE));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the next target within the spell shape
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAHALITO: Hit " + IntToString(nAffected) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAHALITO: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
187
Content/spells/mahaman.nss
Normal file
187
Content/spells/mahaman.nss
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Mahaman (Great Change)
|
||||||
|
//:: mahaman.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Has random effects with more options than HAMAN.
|
||||||
|
Drains the caster one experience level and is
|
||||||
|
forgotten when cast.
|
||||||
|
Level 7 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 7 Mage support/disable spell with
|
||||||
|
enhanced random effects. Requires caster level 13+.
|
||||||
|
|
||||||
|
Possible effects:
|
||||||
|
- Augmented magic: party spells cause more damage
|
||||||
|
- Cure party: cures all conditions
|
||||||
|
- Heal party: MADI on all members
|
||||||
|
- Protect party: -20 AC for all members
|
||||||
|
- Raise the dead: DI on all dead members
|
||||||
|
- Silence enemies: all monsters silenced
|
||||||
|
- Teleport enemies: monsters teleported away
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Enhanced random effects with level drain
|
||||||
|
|
||||||
|
// Declare variables used in switch cases
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oMember;
|
||||||
|
object oArea;
|
||||||
|
object oTarget;
|
||||||
|
effect eHeal;
|
||||||
|
effect eSilence;
|
||||||
|
effect eTeleport;
|
||||||
|
effect eProtect;
|
||||||
|
|
||||||
|
// Check minimum level requirement
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_WIZARD, oCaster);
|
||||||
|
if (nCasterLevel < 13)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN requires level 13+ to cast!", oCaster, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply level drain to caster
|
||||||
|
effect eDrain = EffectNegativeLevel(1);
|
||||||
|
effect eVis = EffectVisualEffect(47); // Negative energy visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDrain, oCaster);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
|
||||||
|
|
||||||
|
// Remove spell from memory
|
||||||
|
SetLocalInt(oCaster, "SPELL_MAHAMAN_FORGOTTEN", 1);
|
||||||
|
|
||||||
|
// Roll for random effect
|
||||||
|
int nEffect = Random(7); // 0-6 for seven possible effects
|
||||||
|
|
||||||
|
// Apply the random effect
|
||||||
|
switch(nEffect)
|
||||||
|
{
|
||||||
|
case 0: // Augmented magic
|
||||||
|
{
|
||||||
|
SetLocalInt(oCaster, "SPELL_DAMAGE_BONUS", 4); // Enhanced bonus
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN: Party spells greatly enhanced!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1: // Cure party
|
||||||
|
{
|
||||||
|
oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Remove negative conditions
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_PARALYZED");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_POISONED");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_SLEEPING");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_SILENCED");
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_FEARED");
|
||||||
|
|
||||||
|
// Visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(14), oMember);
|
||||||
|
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN: Party conditions cured!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2: // Heal party
|
||||||
|
{
|
||||||
|
oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Full heal
|
||||||
|
eHeal = EffectHeal(GetMaxHitPoints(oMember));
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oMember);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(14), oMember);
|
||||||
|
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN: Party fully healed!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3: // Protect party
|
||||||
|
{
|
||||||
|
oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Major AC reduction
|
||||||
|
eProtect = EffectACDecrease(20);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eProtect, oMember, RoundsToSeconds(nCasterLevel));
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(21), oMember);
|
||||||
|
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN: Party heavily protected!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 4: // Raise the dead
|
||||||
|
{
|
||||||
|
oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
if (GetLocalInt(oMember, "CONDITION_DEAD") == 1)
|
||||||
|
{
|
||||||
|
// Resurrect with 1 HP
|
||||||
|
DeleteLocalInt(oMember, "CONDITION_DEAD");
|
||||||
|
eHeal = EffectHeal(1);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(14), oMember);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oMember);
|
||||||
|
}
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN: Dead party members resurrected!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5: // Silence enemies
|
||||||
|
{
|
||||||
|
oArea = GetArea(oCaster);
|
||||||
|
oTarget = GetFirstObjectInArea(oArea);
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if (GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
eSilence = EffectSilence();
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eSilence, oTarget);
|
||||||
|
SetLocalInt(oTarget, "CONDITION_SILENCED", 1);
|
||||||
|
}
|
||||||
|
oTarget = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN: All enemies silenced!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 6: // Teleport enemies
|
||||||
|
{
|
||||||
|
oArea = GetArea(oCaster);
|
||||||
|
oTarget = GetFirstObjectInArea(oArea);
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
if (GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
eTeleport = EffectVisualEffect(46); // Teleport visual effect
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eTeleport, oTarget);
|
||||||
|
SetLocalInt(oTarget, "TELEPORTED_AWAY", 1);
|
||||||
|
}
|
||||||
|
oTarget = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN: All enemies teleported away!", oCaster, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify level drain and spell loss
|
||||||
|
FloatingTextStringOnCreature("Lost one experience level!", oCaster, TRUE);
|
||||||
|
FloatingTextStringOnCreature("MAHAMAN spell forgotten!", oCaster, TRUE);
|
||||||
|
}
|
84
Content/spells/makanito.nss
Normal file
84
Content/spells/makanito.nss
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Makanito (Deadly Air)
|
||||||
|
//:: makanito.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Kills all monsters with 7 or fewer hit point dice.
|
||||||
|
Level 5 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Mage attack spell that targets
|
||||||
|
all monsters.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Kill all weak monsters
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Create the deadly air visual effect
|
||||||
|
effect eDeadlyAir = EffectVisualEffect(47); // Death visual effect
|
||||||
|
location lCaster = GetLocation(oCaster);
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eDeadlyAir, lCaster);
|
||||||
|
|
||||||
|
// 3. Get all creatures in the area
|
||||||
|
object oArea = GetArea(oCaster);
|
||||||
|
object oTarget = GetFirstObjectInArea(oArea);
|
||||||
|
int nKilled = 0;
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Check if target is a valid enemy
|
||||||
|
if (GetIsEnemy(oTarget, oCaster) &&
|
||||||
|
GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
|
||||||
|
{
|
||||||
|
// Get creature's hit dice
|
||||||
|
int nHitDice = GetHitDice(oTarget);
|
||||||
|
|
||||||
|
// Check if creature is weak enough to be affected
|
||||||
|
if (nHitDice <= 7)
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 39)); // Death spell ID
|
||||||
|
|
||||||
|
// Create the death effect
|
||||||
|
effect eDeath = EffectDeath();
|
||||||
|
effect eVis = EffectVisualEffect(45); // Death visual effect
|
||||||
|
|
||||||
|
// Apply the visual and death effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oTarget);
|
||||||
|
|
||||||
|
// Notify kill
|
||||||
|
FloatingTextStringOnCreature("MAKANITO: " + GetName(oTarget) + " is killed!", oCaster, TRUE);
|
||||||
|
nKilled++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify too strong
|
||||||
|
FloatingTextStringOnCreature(GetName(oTarget) + " is too powerful!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next target in area
|
||||||
|
oTarget = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nKilled > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAKANITO: Killed " + IntToString(nKilled) + " weak enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAKANITO: No enemies were weak enough to affect", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
79
Content/spells/malikto.nss
Normal file
79
Content/spells/malikto.nss
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Malikto (Word of Death)
|
||||||
|
//:: malikto.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 12d6 (12-72) points of damage to all monsters.
|
||||||
|
Level 7 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 7 Priest attack spell that targets
|
||||||
|
all monsters.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 12d6 damage to all monsters
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Create the word of death visual effect
|
||||||
|
effect eWordVis = EffectVisualEffect(47); // Global death effect
|
||||||
|
location lCaster = GetLocation(oCaster);
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eWordVis, lCaster);
|
||||||
|
|
||||||
|
// 3. Get all enemies in the area
|
||||||
|
object oArea = GetArea(oCaster);
|
||||||
|
object oTarget = GetFirstObjectInArea(oArea);
|
||||||
|
int nEnemiesHit = 0;
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Check if target is a valid enemy
|
||||||
|
// Consider target alive if they're not marked as dead or permanently lost
|
||||||
|
if (GetIsEnemy(oTarget, oCaster) &&
|
||||||
|
GetObjectType(oTarget) == OBJECT_TYPE_CREATURE &&
|
||||||
|
!GetLocalInt(oTarget, "CONDITION_DEAD") &&
|
||||||
|
!GetLocalInt(oTarget, "PERMANENTLY_LOST"))
|
||||||
|
{
|
||||||
|
// Calculate damage
|
||||||
|
int nDamage = d6(12); // 12d6 damage
|
||||||
|
|
||||||
|
// Create the damage effect
|
||||||
|
effect eDamage = EffectDamage(nDamage, DAMAGE_TYPE_NEGATIVE);
|
||||||
|
effect eVis = EffectVisualEffect(40); // Negative energy visual effect
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 39)); // Word of Death spell ID
|
||||||
|
|
||||||
|
// Apply the visual and damage effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget);
|
||||||
|
|
||||||
|
// Notify damage
|
||||||
|
FloatingTextStringOnCreature("MALIKTO: " + IntToString(nDamage) + " damage to " + GetName(oTarget), oCaster, TRUE);
|
||||||
|
|
||||||
|
nEnemiesHit++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next target in area
|
||||||
|
oTarget = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nEnemiesHit > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MALIKTO: Hit " + IntToString(nEnemiesHit) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MALIKTO: No enemies found in range", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
197
Content/spells/malor.nss
Normal file
197
Content/spells/malor.nss
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Malor (Apport)
|
||||||
|
//:: malor.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Teleports the party to a random location in combat,
|
||||||
|
or to a selected dungeon level and location when
|
||||||
|
used in camp. If a party teleports into stone it
|
||||||
|
is lost forever, so the spell is best used in
|
||||||
|
conjunction with DUMAPIC.
|
||||||
|
Level 7 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 7 Mage field/support spell that
|
||||||
|
affects the entire party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Teleport party
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_CONJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Check if in combat
|
||||||
|
int bInCombat = GetLocalInt(oCaster, "IN_COMBAT");
|
||||||
|
|
||||||
|
// Create teleport visual effects
|
||||||
|
effect eVis = EffectVisualEffect(VFX_FNF_TELEPORT_OUT);
|
||||||
|
effect eVis2 = EffectVisualEffect(VFX_FNF_TELEPORT_IN);
|
||||||
|
|
||||||
|
if (bInCombat)
|
||||||
|
{
|
||||||
|
// Random teleport during combat
|
||||||
|
|
||||||
|
// Get current area
|
||||||
|
object oArea = GetArea(oCaster);
|
||||||
|
|
||||||
|
// Generate random coordinates within the area
|
||||||
|
float fAreaWidth = 100.0; // Example area size
|
||||||
|
float fAreaHeight = 100.0;
|
||||||
|
vector vNewPos;
|
||||||
|
vNewPos.x = IntToFloat(Random(FloatToInt(fAreaWidth)));
|
||||||
|
vNewPos.y = IntToFloat(Random(FloatToInt(fAreaHeight)));
|
||||||
|
vNewPos.z = 0.0;
|
||||||
|
location lNewLoc = Location(oArea, vNewPos, 0.0);
|
||||||
|
|
||||||
|
// Roll for teleport mishap (5% chance)
|
||||||
|
int nMishapRoll = d100();
|
||||||
|
|
||||||
|
if (nMishapRoll <= 5)
|
||||||
|
{
|
||||||
|
// Teleport mishap - party is lost
|
||||||
|
// Apply teleport out effect at caster location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Get all party members
|
||||||
|
object oMember = GetFirstFactionMember(oCaster, TRUE);
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Mark as permanently lost
|
||||||
|
SetLocalInt(oMember, "PERMANENTLY_LOST", 1);
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oMember = GetNextFactionMember(oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify mishap
|
||||||
|
FloatingTextStringOnCreature("MALOR: Party teleported into solid matter and was lost forever!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Successful teleport
|
||||||
|
// Apply teleport out effect at caster location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Apply teleport in effect at destination
|
||||||
|
DelayCommand(1.0f, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis2, lNewLoc));
|
||||||
|
|
||||||
|
// Get all party members
|
||||||
|
object oMember = GetFirstFactionMember(oCaster, TRUE);
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Teleport to new location
|
||||||
|
DelayCommand(1.0f, AssignCommand(oMember, JumpToLocation(lNewLoc)));
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oMember = GetNextFactionMember(oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("MALOR: Party teleported to random location!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Targeted teleport during camp
|
||||||
|
|
||||||
|
// Get target level and coordinates from user input
|
||||||
|
int nTargetLevel = GetLocalInt(oCaster, "TELEPORT_TARGET_LEVEL");
|
||||||
|
float fTargetX = GetLocalFloat(oCaster, "TELEPORT_TARGET_X");
|
||||||
|
float fTargetY = GetLocalFloat(oCaster, "TELEPORT_TARGET_Y");
|
||||||
|
|
||||||
|
// If no target level is set, use the current level
|
||||||
|
if (nTargetLevel == 0)
|
||||||
|
{
|
||||||
|
nTargetLevel = GetLocalInt(GetArea(oCaster), "DUNGEON_LEVEL");
|
||||||
|
|
||||||
|
// If still no level, default to level 1
|
||||||
|
if (nTargetLevel == 0)
|
||||||
|
nTargetLevel = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create target location
|
||||||
|
object oTargetArea = GetObjectByTag("DUNGEON_LEVEL_" + IntToString(nTargetLevel));
|
||||||
|
|
||||||
|
// If target area doesn't exist, use current area
|
||||||
|
if (!GetIsObjectValid(oTargetArea))
|
||||||
|
oTargetArea = GetArea(oCaster);
|
||||||
|
|
||||||
|
vector vTargetPos;
|
||||||
|
vTargetPos.x = fTargetX;
|
||||||
|
vTargetPos.y = fTargetY;
|
||||||
|
vTargetPos.z = 0.0;
|
||||||
|
location lTargetLoc = Location(oTargetArea, vTargetPos, 0.0);
|
||||||
|
|
||||||
|
// Roll for teleport mishap (5% chance)
|
||||||
|
int nMishapRoll = d100();
|
||||||
|
|
||||||
|
if (nMishapRoll <= 5)
|
||||||
|
{
|
||||||
|
// Teleport mishap - party is lost
|
||||||
|
// Apply teleport out effect at caster location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Get all party members
|
||||||
|
object oMember = GetFirstFactionMember(oCaster, TRUE);
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Mark as permanently lost
|
||||||
|
SetLocalInt(oMember, "PERMANENTLY_LOST", 1);
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oMember = GetNextFactionMember(oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify mishap
|
||||||
|
FloatingTextStringOnCreature("MALOR: Party teleported into solid matter and was lost forever!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Successful teleport
|
||||||
|
// Apply teleport out effect at caster location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Apply teleport in effect at destination
|
||||||
|
DelayCommand(1.0f, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis2, lTargetLoc));
|
||||||
|
|
||||||
|
// Get all party members
|
||||||
|
object oMember = GetFirstFactionMember(oCaster, TRUE);
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Teleport to target location
|
||||||
|
DelayCommand(1.0f, AssignCommand(oMember, JumpToLocation(lTargetLoc)));
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oMember = GetNextFactionMember(oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("MALOR: Party teleported to level " +
|
||||||
|
IntToString(nTargetLevel) + " at (" +
|
||||||
|
FloatToString(fTargetX, 0, 0) + "," +
|
||||||
|
FloatToString(fTargetY, 0, 0) + ")!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
140
Content/spells/mamorlis.nss
Normal file
140
Content/spells/mamorlis.nss
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Mamorlis (Terror)
|
||||||
|
//:: mamorlis.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to frighten and disperse all monsters.
|
||||||
|
Level 5 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 5 Mage disable spell that targets
|
||||||
|
all monsters.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Frighten and disperse all monsters
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_NECROMANCY);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
float fDuration = RoundsToSeconds(nCasterLevel);
|
||||||
|
float fDelay;
|
||||||
|
|
||||||
|
// Make sure caster level is at least 5
|
||||||
|
if (nCasterLevel < 5)
|
||||||
|
nCasterLevel = 5; // Minimum level 5 for this spell
|
||||||
|
|
||||||
|
// Check for metamagic extend
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the fear effects
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FEAR_S);
|
||||||
|
effect eFear = EffectFrightened();
|
||||||
|
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR);
|
||||||
|
effect eImpact = EffectVisualEffect(VFX_FNF_HOWL_MIND);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
||||||
|
|
||||||
|
// Link the fear and mind effects
|
||||||
|
effect eLink = EffectLinkEffects(eFear, eMind);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur);
|
||||||
|
|
||||||
|
// Apply Impact at the caster location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Get first object in the spell area (colossal radius - entire area)
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Track affected targets
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Cycle through the targets within the spell shape
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Check if target is valid (hostile)
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Random delay for visual effect
|
||||||
|
fDelay = PRCGetRandomDelay();
|
||||||
|
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay))
|
||||||
|
{
|
||||||
|
// Make Will save with a -2 penalty (more powerful than regular fear)
|
||||||
|
if (!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, PRCGetSaveDC(oTarget, oCaster) + 2, SAVING_THROW_TYPE_FEAR, oCaster, fDelay))
|
||||||
|
{
|
||||||
|
// Check for immunity to fear
|
||||||
|
if (!GetIsImmune(oTarget, IMMUNITY_TYPE_FEAR))
|
||||||
|
{
|
||||||
|
// Apply the fear effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, -1, nCasterLevel);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
|
||||||
|
// Set fear condition flag
|
||||||
|
SetLocalInt(oTarget, "CONDITION_FEARED", 1);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " is terrified!", oCaster, TRUE));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify immunity
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " is immune to fear!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify save
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " resisted terror!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify SR
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " has spell resistance!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next target in the shape
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oCaster));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAMORLIS: Terrified " + IntToString(nAffected) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAMORLIS: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
139
Content/spells/manifo.nss
Normal file
139
Content/spells/manifo.nss
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Manifo (Statue)
|
||||||
|
//:: manifo.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to paralyze a monster group.
|
||||||
|
Level 2 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 2 Priest disable spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Paralyze a group of monsters
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_ENCHANTMENT);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
|
||||||
|
// Make sure duration does not equal 0
|
||||||
|
if (nCasterLevel < 1)
|
||||||
|
nCasterLevel = 2; // Minimum level 2 for this spell
|
||||||
|
|
||||||
|
// Calculate duration
|
||||||
|
int nDuration = nCasterLevel;
|
||||||
|
|
||||||
|
// Check Extend metamagic feat
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
nDuration *= 2; // Duration is +100%
|
||||||
|
|
||||||
|
// Create the paralysis effects
|
||||||
|
effect eParalyze = EffectParalyze();
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_HOLD_PERSON);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
||||||
|
effect eDur2 = EffectVisualEffect(VFX_DUR_PARALYZED);
|
||||||
|
effect eDur3 = EffectVisualEffect(VFX_DUR_PARALYZE_HOLD);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eDur2, eDur);
|
||||||
|
eLink = EffectLinkEffects(eLink, eParalyze);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur3);
|
||||||
|
|
||||||
|
// Get the target location
|
||||||
|
location lTarget = GetLocation(oTarget);
|
||||||
|
|
||||||
|
// Declare the spell shape, size and the location
|
||||||
|
object oAffected = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
|
||||||
|
// Track affected targets
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Cycle through the targets within the spell shape
|
||||||
|
while (GetIsObjectValid(oAffected))
|
||||||
|
{
|
||||||
|
// Check if target is valid (hostile)
|
||||||
|
if (spellsIsTarget(oAffected, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oAffected, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oAffected, nPenetr))
|
||||||
|
{
|
||||||
|
// Make Will save
|
||||||
|
if (!PRCMySavingThrow(SAVING_THROW_WILL, oAffected, PRCGetSaveDC(oAffected, oCaster)))
|
||||||
|
{
|
||||||
|
// Check for immunity to paralysis
|
||||||
|
if (!GetIsImmune(oAffected, IMMUNITY_TYPE_PARALYSIS))
|
||||||
|
{
|
||||||
|
// Apply the paralysis effect
|
||||||
|
int nScaledDuration = PRCGetScaledDuration(nDuration, oAffected);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oAffected, RoundsToSeconds(nScaledDuration), TRUE, -1, nCasterLevel);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oAffected);
|
||||||
|
|
||||||
|
// Set paralysis condition flag
|
||||||
|
SetLocalInt(oAffected, "CONDITION_PARALYZED", 1);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature(GetName(oAffected) + " is paralyzed!", oCaster, TRUE);
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify immunity
|
||||||
|
FloatingTextStringOnCreature(GetName(oAffected) + " is immune to paralysis!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify save
|
||||||
|
FloatingTextStringOnCreature(GetName(oAffected) + " resisted paralysis!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify SR
|
||||||
|
FloatingTextStringOnCreature(GetName(oAffected) + " has spell resistance!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next target in the shape
|
||||||
|
oAffected = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MANIFO: Paralyzed " + IntToString(nAffected) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MANIFO: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
97
Content/spells/maporfic.nss
Normal file
97
Content/spells/maporfic.nss
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Maporfic (Big Shield)
|
||||||
|
//:: maporfic.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of all party members by 2
|
||||||
|
for the entire expedition.
|
||||||
|
Level 4 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 4 Priest support spell that targets
|
||||||
|
the entire party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Reduce AC of all party members by 2 for the entire expedition
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_ABJURATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Calculate duration (fixed at 24 hours for expedition)
|
||||||
|
int nDuration = 24; // 24 hours
|
||||||
|
|
||||||
|
// Create the AC improvement effect (lower AC is better in D&D)
|
||||||
|
effect eAC = EffectACIncrease(2, AC_SHIELD_ENCHANTMENT_BONUS);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_AC_BONUS);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eAC, eDur);
|
||||||
|
|
||||||
|
// Get the first party member
|
||||||
|
object oPartyMember = GetFirstFactionMember(oCaster, TRUE);
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Apply to all party members
|
||||||
|
while (GetIsObjectValid(oPartyMember))
|
||||||
|
{
|
||||||
|
// Remove any existing PORFIC effects
|
||||||
|
if (GetLocalInt(oPartyMember, "PORFIC_ACTIVE") == 1)
|
||||||
|
{
|
||||||
|
// Remove the effect using the PRC framework
|
||||||
|
PRCRemoveEffectsFromSpell(oPartyMember, SPELL_MAGE_ARMOR);
|
||||||
|
DeleteLocalInt(oPartyMember, "PORFIC_ACTIVE");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oPartyMember, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Apply the effects
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPartyMember);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oPartyMember, HoursToSeconds(nDuration), TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// Set the MAPORFIC flag
|
||||||
|
SetLocalInt(oPartyMember, "MAPORFIC_ACTIVE", 1);
|
||||||
|
|
||||||
|
// Notify the target
|
||||||
|
FloatingTextStringOnCreature("MAPORFIC: AC improved by 2 for 24 hours", oPartyMember, TRUE);
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oPartyMember = GetNextFactionMember(oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAPORFIC: Protected " + IntToString(nAffected) + " party members!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MAPORFIC: No party members affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
79
Content/spells/masopic.nss
Normal file
79
Content/spells/masopic.nss
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Masopic (Big Glass)
|
||||||
|
//:: masopic.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of all party members by 4
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 6 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Mage support spell that targets
|
||||||
|
the entire party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Reduce party's AC by 4
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Calculate duration (based on caster level)
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_WIZARD, oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 6; // Minimum level 6 for this spell
|
||||||
|
float fDuration = RoundsToSeconds(nCasterLevel); // Lasts for rounds equal to caster level
|
||||||
|
|
||||||
|
// 3. Remove any existing MOGREF/SOPIC effects
|
||||||
|
object oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
if (GetLocalInt(oMember, "MOGREF_ACTIVE") == 1)
|
||||||
|
{
|
||||||
|
DeleteLocalInt(oMember, "MOGREF_ACTIVE");
|
||||||
|
// The game engine would handle removing the effect
|
||||||
|
}
|
||||||
|
if (GetLocalInt(oMember, "SOPIC_ACTIVE") == 1)
|
||||||
|
{
|
||||||
|
DeleteLocalInt(oMember, "SOPIC_ACTIVE");
|
||||||
|
// The game engine would handle removing the effect
|
||||||
|
}
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Create the AC reduction effect
|
||||||
|
effect eAC = EffectACDecrease(4); // Reduce AC by 4 (lower AC is better)
|
||||||
|
effect eVis = EffectVisualEffect(21); // Shield visual effect
|
||||||
|
effect eDur = EffectVisualEffect(14); // Duration visual effect
|
||||||
|
effect eLink = EffectLinkEffects(eAC, eDur);
|
||||||
|
|
||||||
|
// 5. Apply to all party members
|
||||||
|
oMember = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oMember))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oMember, EventSpellCastAt(oCaster, 58, FALSE)); // Mage Armor spell ID
|
||||||
|
|
||||||
|
// Apply the visual and AC effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oMember);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oMember, fDuration);
|
||||||
|
|
||||||
|
// Set the MASOPIC flag
|
||||||
|
SetLocalInt(oMember, "MASOPIC_ACTIVE", 1);
|
||||||
|
|
||||||
|
// Notify the target
|
||||||
|
FloatingTextStringOnCreature("AC reduced by 4", oMember, TRUE);
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oMember = GetNextPC();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Final notification
|
||||||
|
FloatingTextStringOnCreature("MASOPIC: Party AC reduced by 4", oCaster, TRUE);
|
||||||
|
}
|
56
Content/spells/matu.nss
Normal file
56
Content/spells/matu.nss
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Matu (Blessing)
|
||||||
|
//:: matu.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of all party members by 2
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 2 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 2 Priest support spell that targets
|
||||||
|
the entire party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Reduce AC of all party members by 2
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Calculate duration (based on caster level)
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_CLERIC, oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 2; // Minimum level 2 for this spell
|
||||||
|
float fDuration = RoundsToSeconds(nCasterLevel); // Lasts for rounds equal to caster level
|
||||||
|
|
||||||
|
// 3. Create the AC reduction effect
|
||||||
|
effect eAC = EffectACDecrease(2); // Reduce AC by 2 (lower AC is better)
|
||||||
|
effect eVis = EffectVisualEffect(21); // Generic blessing visual effect
|
||||||
|
effect eDur = EffectVisualEffect(14); // Duration visual effect
|
||||||
|
effect eLink = EffectLinkEffects(eAC, eDur);
|
||||||
|
|
||||||
|
// 4. Apply to all party members
|
||||||
|
object oTarget = GetFirstPC();
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 7, FALSE)); // Bless spell ID
|
||||||
|
|
||||||
|
// Apply the VFX impact and effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration);
|
||||||
|
|
||||||
|
// Notify the target
|
||||||
|
FloatingTextStringOnCreature("Blessed: AC reduced by 2", oTarget, TRUE);
|
||||||
|
|
||||||
|
// Get next party member
|
||||||
|
oTarget = GetNextPC();
|
||||||
|
}
|
||||||
|
}
|
99
Content/spells/milwa.nss
Normal file
99
Content/spells/milwa.nss
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Milwa (Light)
|
||||||
|
//:: milwa.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Summons a softly glowing light that increases vision
|
||||||
|
and reveals secret doors.
|
||||||
|
Level 1 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 1 Priest field/support spell that
|
||||||
|
targets the party.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_sp_func"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Create light and reveal secret doors with Search bonus
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// 1. Get caster and target information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
|
||||||
|
// 2. Calculate duration (based on caster level)
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 1;
|
||||||
|
|
||||||
|
// Duration is hours equal to caster level
|
||||||
|
float fDuration = HoursToSeconds(nCasterLevel);
|
||||||
|
|
||||||
|
// Check for Extend Spell metamagic
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Create the light effect and Search skill bonus
|
||||||
|
effect eLight = EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_HEAD_HOLY);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Add Search skill bonus (similar to extrathf.nss but only for Search)
|
||||||
|
effect eSearch = EffectSkillIncrease(SKILL_SEARCH, 10);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eLight, eSearch);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur);
|
||||||
|
|
||||||
|
// 4. Apply to the caster (light follows the party)
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// 5. Reveal secret doors in the area
|
||||||
|
// This would typically involve a search check or revealing
|
||||||
|
// hidden objects in the area around the party
|
||||||
|
object oArea = GetArea(oTarget);
|
||||||
|
object oDoor = GetFirstObjectInArea(oArea);
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oDoor))
|
||||||
|
{
|
||||||
|
// If the object is a secret door
|
||||||
|
if (GetObjectType(oDoor) == OBJECT_TYPE_DOOR && GetLocalInt(oDoor, "SECRET_DOOR"))
|
||||||
|
{
|
||||||
|
// Make it visible/discoverable
|
||||||
|
SetLocalInt(oDoor, "REVEALED", TRUE);
|
||||||
|
|
||||||
|
// Visual effect at door location
|
||||||
|
location lDoor = GetLocation(oDoor);
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_DISPEL), lDoor);
|
||||||
|
}
|
||||||
|
|
||||||
|
oDoor = GetNextObjectInArea(oArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set flag to indicate MILWA is active
|
||||||
|
SetLocalInt(oTarget, "MILWA_ACTIVE", 1);
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("MILWA: Light spell active!", oTarget, TRUE);
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
68
Content/spells/mogref.nss
Normal file
68
Content/spells/mogref.nss
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Mogref (Body Iron)
|
||||||
|
//:: mogref.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of the caster by 2
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 1 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 1 Mage support spell that targets
|
||||||
|
the caster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Improve caster's AC by 2
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_TRANSMUTATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
|
||||||
|
// Calculate duration (rounds equal to caster level)
|
||||||
|
int nDuration = nCasterLevel;
|
||||||
|
|
||||||
|
// Apply metamagic
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
nDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the AC improvement effect (lower AC is better in D&D)
|
||||||
|
effect eAC = EffectACIncrease(2, AC_NATURAL_BONUS);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_AC_BONUS);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eAC, eDur);
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oCaster, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Apply the effects
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oCaster, RoundsToSeconds(nDuration), TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// Notify the caster
|
||||||
|
FloatingTextStringOnCreature("MOGREF: AC improved by 2 for " + IntToString(nDuration) + " rounds", oCaster, TRUE);
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
147
Content/spells/molito.nss
Normal file
147
Content/spells/molito.nss
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Molito (Spark Storm)
|
||||||
|
//:: molito.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 3d6 (3-18) points of damage to half of a
|
||||||
|
monster group.
|
||||||
|
Level 3 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 3 Mage attack spell that targets
|
||||||
|
half of a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal 3d6 damage to half of a monster group
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
int nDamage;
|
||||||
|
float fDelay;
|
||||||
|
|
||||||
|
// Get the target location
|
||||||
|
location lTarget = PRCGetSpellTargetLocation();
|
||||||
|
|
||||||
|
// Create the incendiary cloud visual effect
|
||||||
|
effect eImpact = EffectVisualEffect(VFX_FNF_INCENDIARY);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_S);
|
||||||
|
|
||||||
|
// Get the elemental damage type (default to electrical)
|
||||||
|
int EleDmg = ChangedElementalDamage(oCaster, DAMAGE_TYPE_ELECTRICAL);
|
||||||
|
|
||||||
|
// Apply the visual effect at the location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lTarget);
|
||||||
|
|
||||||
|
// Declare the spell shape, size and the location
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
|
||||||
|
// Count total enemies in the area
|
||||||
|
int nTotalEnemies = 0;
|
||||||
|
object oCounter = oTarget;
|
||||||
|
|
||||||
|
while (GetIsObjectValid(oCounter))
|
||||||
|
{
|
||||||
|
if (spellsIsTarget(oCounter, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
nTotalEnemies++;
|
||||||
|
}
|
||||||
|
oCounter = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate how many to affect (half, rounded up)
|
||||||
|
int nToAffect = (nTotalEnemies + 1) / 2;
|
||||||
|
|
||||||
|
// Reset target for actual damage application
|
||||||
|
oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
|
||||||
|
// Track affected targets
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Cycle through the targets within the spell shape
|
||||||
|
while (GetIsObjectValid(oTarget) && nAffected < nToAffect)
|
||||||
|
{
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Get the distance between the explosion and the target to calculate delay
|
||||||
|
fDelay = GetDistanceBetweenLocations(lTarget, GetLocation(oTarget))/20;
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay))
|
||||||
|
{
|
||||||
|
// Calculate damage - 3d6 electrical damage
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
nDamage = 18; // 3 * 6 = 18 (maximum damage)
|
||||||
|
else
|
||||||
|
nDamage = d6(3);
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
nDamage += nDamage / 2; // +50% damage
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, 3);
|
||||||
|
|
||||||
|
// Adjust the damage based on the Reflex Save, Evasion and Improved Evasion
|
||||||
|
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, PRCGetSaveDC(oTarget, oCaster), SAVING_THROW_TYPE_ELECTRICITY);
|
||||||
|
|
||||||
|
if (nDamage > 0)
|
||||||
|
{
|
||||||
|
// Set the damage effect
|
||||||
|
effect eDam = PRCEffectDamage(oTarget, nDamage, EleDmg);
|
||||||
|
|
||||||
|
// Apply effects to the currently selected target
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
PRCBonusDamage(oTarget);
|
||||||
|
|
||||||
|
// Notify damage
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature("MOLITO: " + IntToString(nDamage) + " spark damage to " + GetName(oTarget), oCaster, TRUE));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the next target within the spell shape
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_MEDIUM, lTarget, TRUE, OBJECT_TYPE_CREATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MOLITO: Hit " + IntToString(nAffected) + " out of " +
|
||||||
|
IntToString(nTotalEnemies) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MOLITO: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
113
Content/spells/montino.nss
Normal file
113
Content/spells/montino.nss
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Montino (Still Air)
|
||||||
|
//:: montino.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to silence a monster group, making it
|
||||||
|
impossible for them to cast spells.
|
||||||
|
Level 2 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 2 Priest disable spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Silence a group of monsters
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_ILLUSION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
|
||||||
|
// Make sure duration does not equal 0
|
||||||
|
if (nCasterLevel < 1)
|
||||||
|
nCasterLevel = 2; // Minimum level 2 for this spell
|
||||||
|
|
||||||
|
// Calculate duration
|
||||||
|
float fDuration = RoundsToSeconds(nCasterLevel);
|
||||||
|
|
||||||
|
// Check Extend metamagic feat
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
|
||||||
|
// Create the silence area effect
|
||||||
|
int nAoE = AOE_MOB_SILENCE;
|
||||||
|
|
||||||
|
// Check if target is valid
|
||||||
|
if (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If target is hostile, require SR and saving throw
|
||||||
|
if (!GetIsFriend(oTarget))
|
||||||
|
{
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Check spell resistance
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr))
|
||||||
|
{
|
||||||
|
// Check saving throw
|
||||||
|
if (!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, PRCGetSaveDC(oTarget, oCaster)))
|
||||||
|
{
|
||||||
|
// Create an instance of the AOE Object using the Apply Effect function
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectAreaOfEffect(nAoE), oTarget, fDuration);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("MONTINO: " + GetName(oTarget) + " is silenced!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify saving throw success
|
||||||
|
FloatingTextStringOnCreature("MONTINO: " + GetName(oTarget) + " resisted silence!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify spell resistance
|
||||||
|
FloatingTextStringOnCreature("MONTINO: " + GetName(oTarget) + " has spell resistance!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If target is friendly, no SR or saving throw
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
|
||||||
|
// Create an instance of the AOE Object using the Apply Effect function
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectAreaOfEffect(nAoE), oTarget, fDuration);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("MONTINO: " + GetName(oTarget) + " is surrounded by silence!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Area Of Effect object
|
||||||
|
object oAoE = GetAreaOfEffectObject(GetLocation(oTarget), "VFX_MOB_SILENCE");
|
||||||
|
SetAllAoEInts(SPELL_SILENCE, oAoE, PRCGetSaveDC(OBJECT_INVALID, oCaster), 0, nCasterLevel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("MONTINO: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
140
Content/spells/morlis.nss
Normal file
140
Content/spells/morlis.nss
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Morlis (Fear)
|
||||||
|
//:: morlis.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Attempts to frighten and disperse a monster group.
|
||||||
|
Level 4 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 4 Mage disable spell that targets
|
||||||
|
a monster group.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Frighten and disperse a monster group
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_NECROMANCY);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
float fDuration = RoundsToSeconds(nCasterLevel);
|
||||||
|
float fDelay;
|
||||||
|
|
||||||
|
// Make sure caster level is at least 4
|
||||||
|
if (nCasterLevel < 4)
|
||||||
|
nCasterLevel = 4; // Minimum level 4 for this spell
|
||||||
|
|
||||||
|
// Check for metamagic extend
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the fear effects
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FEAR_S);
|
||||||
|
effect eFear = EffectFrightened();
|
||||||
|
effect eMind = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR);
|
||||||
|
effect eImpact = EffectVisualEffect(VFX_FNF_LOS_NORMAL_20);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
|
||||||
|
|
||||||
|
// Link the fear and mind effects
|
||||||
|
effect eLink = EffectLinkEffects(eFear, eMind);
|
||||||
|
eLink = EffectLinkEffects(eLink, eDur);
|
||||||
|
|
||||||
|
// Apply Impact at the target location
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, PRCGetSpellTargetLocation());
|
||||||
|
|
||||||
|
// Get first target in the spell area
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, PRCGetSpellTargetLocation(), TRUE);
|
||||||
|
|
||||||
|
// Track affected targets
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Cycle through the targets within the spell shape
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Check if target is valid (hostile)
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster))
|
||||||
|
{
|
||||||
|
// Random delay for visual effect
|
||||||
|
fDelay = PRCGetRandomDelay();
|
||||||
|
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay))
|
||||||
|
{
|
||||||
|
// Make Will save
|
||||||
|
if (!PRCMySavingThrow(SAVING_THROW_WILL, oTarget, PRCGetSaveDC(oTarget, oCaster), SAVING_THROW_TYPE_FEAR, oCaster, fDelay))
|
||||||
|
{
|
||||||
|
// Check for immunity to fear
|
||||||
|
if (!GetIsImmune(oTarget, IMMUNITY_TYPE_FEAR))
|
||||||
|
{
|
||||||
|
// Apply the fear effect
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, -1, nCasterLevel);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
|
||||||
|
// Set fear condition flag
|
||||||
|
SetLocalInt(oTarget, "CONDITION_FEARED", 1);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " is frightened!", oCaster, TRUE));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify immunity
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " is immune to fear!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify save
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " resisted fear!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify SR
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " has spell resistance!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next target in the shape
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, PRCGetSpellTargetLocation(), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MORLIS: Frightened " + IntToString(nAffected) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("MORLIS: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
39
Content/spells/nw_sX_example.nss
Normal file
39
Content/spells/nw_sX_example.nss
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Example Spell
|
||||||
|
//:: NW_SX_Example.nss
|
||||||
|
//:: Copyright (c) 2025 User Project
|
||||||
|
//::///////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
TODO: Describe spell effect here
|
||||||
|
(e.g., "Deals XdY [TYPE] damage to all targets in a [SHAPE] area.")
|
||||||
|
*/
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
|
||||||
|
SetLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR", SPELL_SCHOOL_[TO_BE_DEFINED]); // e.g., EVOCATION, DIVINATION
|
||||||
|
|
||||||
|
if (!X2PreSpellCastCode())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// End of Spell Cast Hook
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int CasterLvl = PRCGetCasterLevel(OBJECT_SELF);
|
||||||
|
// TODO: Define spell-specific variables here (e.g., damage types, skill boosts)
|
||||||
|
|
||||||
|
// TODO: Implement spell logic here, using examples from nw_s0_icestorm.nss and nw_s0_identify.nss as guides
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Example Placeholder for Visual and Damage Effects
|
||||||
|
effect eExampleVis = EffectVisualEffect(VFX_[TO_BE_DEFINED]); // Choose appropriate VFX
|
||||||
|
effect eExampleDam = PRCEffectDamage(OBJECT_TARGET, [DAMAGE_VALUE], [DAMAGE_TYPE]);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eExampleVis, OBJECT_TARGET);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eExampleDam, OBJECT_TARGET);
|
||||||
|
|
||||||
|
DeleteLocalInt(OBJECT_SELF, "X2_L_LAST_SPELLSCHOOL_VAR");
|
||||||
|
}
|
70
Content/spells/porfic.nss
Normal file
70
Content/spells/porfic.nss
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Porfic (Shield)
|
||||||
|
//:: porfic.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of the caster by 4
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 1 Priest spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 1 Priest support spell that targets
|
||||||
|
the caster only.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_sp_func"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Reduce AC of caster by 4 (improve AC)
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_ABJURATION);
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
object oTarget = PRCGetSpellTargetObject();
|
||||||
|
|
||||||
|
// 2. Calculate duration (based on caster level)
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 1;
|
||||||
|
|
||||||
|
// Duration is hours equal to caster level (combat duration in Wizardry)
|
||||||
|
float fDuration = HoursToSeconds(nCasterLevel);
|
||||||
|
|
||||||
|
// Check for Extend Spell metamagic
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EXTEND))
|
||||||
|
{
|
||||||
|
fDuration *= 2; // Duration is +100%
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Create the AC improvement effect (in NWN, lower AC is better, so we use AC increase)
|
||||||
|
effect eAC = EffectACIncrease(4, AC_ARMOUR_ENCHANTMENT_BONUS);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_AC_BONUS);
|
||||||
|
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||||||
|
|
||||||
|
// Link the effects
|
||||||
|
effect eLink = EffectLinkEffects(eAC, eDur);
|
||||||
|
|
||||||
|
// 4. Apply to the target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId(), FALSE));
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
SPApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDuration, TRUE, -1, nCasterLevel);
|
||||||
|
|
||||||
|
// 5. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("PORFIC: AC improved by 4 for " + FloatToString(fDuration / 3600.0, 1, 1) + " hours", oTarget, TRUE);
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
61
Content/spells/sopic.nss
Normal file
61
Content/spells/sopic.nss
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Sopic (Glass)
|
||||||
|
//:: sopic.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Reduces the armor class of the caster by 4
|
||||||
|
for the duration of the combat.
|
||||||
|
Level 2 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 2 Mage support spell that targets
|
||||||
|
the caster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Reduce caster's AC by 4
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Calculate duration (based on caster level)
|
||||||
|
int nCasterLevel = GetLevelByClass(CLASS_TYPE_WIZARD, oCaster);
|
||||||
|
if (nCasterLevel < 1) nCasterLevel = 2; // Minimum level 2 for this spell
|
||||||
|
float fDuration = RoundsToSeconds(nCasterLevel); // Lasts for rounds equal to caster level
|
||||||
|
|
||||||
|
// 3. Remove any existing MOGREF effects
|
||||||
|
// This would typically involve removing any existing shield effects
|
||||||
|
// from the MOGREF spell
|
||||||
|
if (GetLocalInt(oCaster, "MOGREF_ACTIVE") == 1)
|
||||||
|
{
|
||||||
|
DeleteLocalInt(oCaster, "MOGREF_ACTIVE");
|
||||||
|
// The game engine would handle removing the effect
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Create the AC reduction effect
|
||||||
|
effect eAC = EffectACDecrease(4); // Reduce AC by 4 (lower AC is better)
|
||||||
|
effect eVis = EffectVisualEffect(21); // Shield visual effect
|
||||||
|
effect eDur = EffectVisualEffect(14); // Duration visual effect
|
||||||
|
effect eLink = EffectLinkEffects(eAC, eDur);
|
||||||
|
|
||||||
|
// 5. Apply to the caster
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oCaster, EventSpellCastAt(oCaster, 58, FALSE)); // Mage Armor spell ID
|
||||||
|
|
||||||
|
// Apply the visual and AC effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oCaster, fDuration);
|
||||||
|
|
||||||
|
// Set the SOPIC flag
|
||||||
|
SetLocalInt(oCaster, "SOPIC_ACTIVE", 1);
|
||||||
|
|
||||||
|
// 6. Notify the caster
|
||||||
|
FloatingTextStringOnCreature("SOPIC: AC reduced by 4", oCaster, TRUE);
|
||||||
|
}
|
136
Content/spells/tiltowait.nss
Normal file
136
Content/spells/tiltowait.nss
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Tiltowait (Explosion)
|
||||||
|
//:: tiltowait.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Causes 10d15 (10-150) points of damage to all
|
||||||
|
monsters.
|
||||||
|
Level 7 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 7 Mage attack spell that targets
|
||||||
|
all monsters.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "prc_inc_spells"
|
||||||
|
#include "prc_add_spell_dc"
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Deal massive damage to all monsters
|
||||||
|
|
||||||
|
// Spellcast Hook Code
|
||||||
|
if (!X2PreSpellCastCode()) return;
|
||||||
|
|
||||||
|
// Set spell school for proper record keeping
|
||||||
|
PRCSetSchool(SPELL_SCHOOL_EVOCATION);
|
||||||
|
|
||||||
|
// Declare major variables
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
int nCasterLevel = PRCGetCasterLevel(oCaster);
|
||||||
|
int nMetaMagic = PRCGetMetaMagicFeat();
|
||||||
|
int nPenetr = nCasterLevel + SPGetPenetr();
|
||||||
|
int nDamage;
|
||||||
|
float fDelay;
|
||||||
|
int nAffected = 0;
|
||||||
|
|
||||||
|
// Get the elemental damage type (default to fire)
|
||||||
|
int EleDmg = ChangedElementalDamage(oCaster, DAMAGE_TYPE_FIRE);
|
||||||
|
|
||||||
|
// Create the meteor swarm visual effect
|
||||||
|
effect eMeteor = EffectVisualEffect(VFX_FNF_METEOR_SWARM);
|
||||||
|
effect eVis = EffectVisualEffect(VFX_IMP_FLAME_M);
|
||||||
|
|
||||||
|
// Apply the meteor swarm VFX area impact
|
||||||
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eMeteor, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Get first object in the spell area (colossal radius - entire area)
|
||||||
|
object oTarget = MyFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oCaster));
|
||||||
|
|
||||||
|
// Process all targets in the area
|
||||||
|
while (GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// Check if target is a valid enemy
|
||||||
|
if (spellsIsTarget(oTarget, SPELL_TARGET_STANDARDHOSTILE, oCaster) && oTarget != oCaster)
|
||||||
|
{
|
||||||
|
// Random delay for visual effect
|
||||||
|
fDelay = PRCGetRandomDelay();
|
||||||
|
|
||||||
|
// Fire cast spell at event for the specified target
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, GetSpellId()));
|
||||||
|
|
||||||
|
// Make SR check
|
||||||
|
if (!PRCDoResistSpell(oCaster, oTarget, nPenetr, fDelay))
|
||||||
|
{
|
||||||
|
// Calculate damage - 10d15 (custom die size for TILTOWAIT)
|
||||||
|
// Implemented as 30d5 for similar effect with standard dice
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_MAXIMIZE))
|
||||||
|
{
|
||||||
|
nDamage = 150; // 10 * 15 = 150 (maximum damage)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Simulate 10d15 using 30d5
|
||||||
|
nDamage = d6(30) * 5 / 6; // Approximately 10d15
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckMetaMagic(nMetaMagic, METAMAGIC_EMPOWER))
|
||||||
|
{
|
||||||
|
nDamage += nDamage / 2; // +50% damage
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add bonus damage per die
|
||||||
|
nDamage += SpellDamagePerDice(oCaster, 30);
|
||||||
|
|
||||||
|
// Adjust the damage based on the Reflex Save, Evasion and Improved Evasion
|
||||||
|
nDamage = PRCGetReflexAdjustedDamage(nDamage, oTarget, PRCGetSaveDC(oTarget, oCaster), SAVING_THROW_TYPE_FIRE);
|
||||||
|
|
||||||
|
if (nDamage > 0)
|
||||||
|
{
|
||||||
|
// Set the damage effect
|
||||||
|
effect eFire = PRCEffectDamage(oTarget, nDamage, EleDmg);
|
||||||
|
|
||||||
|
// Apply damage effect and VFX impact with delay
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eFire, oTarget));
|
||||||
|
DelayCommand(fDelay, SPApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
|
||||||
|
|
||||||
|
// Apply any bonus damage effects
|
||||||
|
PRCBonusDamage(oTarget);
|
||||||
|
|
||||||
|
// Notify damage with delay
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature("TILTOWAIT: " + IntToString(nDamage) + " damage to " + GetName(oTarget), oCaster, TRUE));
|
||||||
|
|
||||||
|
// Increment affected count
|
||||||
|
nAffected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify resistance
|
||||||
|
DelayCommand(fDelay, FloatingTextStringOnCreature(GetName(oTarget) + " resisted TILTOWAIT!", oCaster, TRUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next target in the spell area
|
||||||
|
oTarget = MyNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(oCaster));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final notification
|
||||||
|
if (nAffected > 0)
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("TILTOWAIT: Hit " + IntToString(nAffected) + " enemies!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatingTextStringOnCreature("TILTOWAIT: No enemies affected", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up spell school variable
|
||||||
|
PRCSetSchool();
|
||||||
|
}
|
68
Content/spells/zilwan.nss
Normal file
68
Content/spells/zilwan.nss
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//::///////////////////////////////////////////////
|
||||||
|
//:: Zilwan (Dispel)
|
||||||
|
//:: zilwan.nss
|
||||||
|
//:: Copyright (c) 2025 WizardryEE Project
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Kills an undead monster.
|
||||||
|
Level 6 Mage spell.
|
||||||
|
|
||||||
|
In Wizardry: Proving Grounds of the Mad Overlord,
|
||||||
|
this is a Level 6 Mage attack spell that targets
|
||||||
|
one undead monster.
|
||||||
|
*/
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
//:: Created By: WizardryEE Project
|
||||||
|
//:: Created On: April 26, 2025
|
||||||
|
//:://////////////////////////////////////////////
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Spell implementation for WizardryEE
|
||||||
|
// Core functionality: Kill an undead monster
|
||||||
|
|
||||||
|
// 1. Get caster information
|
||||||
|
object oCaster = OBJECT_SELF;
|
||||||
|
|
||||||
|
// 2. Get the target
|
||||||
|
object oTarget = GetSpellTargetObject();
|
||||||
|
if (!GetIsObjectValid(oTarget))
|
||||||
|
{
|
||||||
|
// If no specific target, get the nearest enemy
|
||||||
|
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oCaster, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Check if target is valid and is an enemy
|
||||||
|
if (GetIsObjectValid(oTarget) && GetIsEnemy(oTarget, oCaster))
|
||||||
|
{
|
||||||
|
// 4. Check if target is undead
|
||||||
|
int bIsUndead = GetLocalInt(oTarget, "ABILITY_UNDEAD");
|
||||||
|
|
||||||
|
if (bIsUndead)
|
||||||
|
{
|
||||||
|
// Create the dispel effects
|
||||||
|
effect eDeath = EffectDeath();
|
||||||
|
effect eVis = EffectVisualEffect(47); // Holy/Dispel visual effect
|
||||||
|
|
||||||
|
// Signal spell cast at event
|
||||||
|
SignalEvent(oTarget, EventSpellCastAt(oCaster, 40)); // Destroy Undead spell ID
|
||||||
|
|
||||||
|
// Apply the visual and death effects
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
|
||||||
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oTarget);
|
||||||
|
|
||||||
|
// Notify success
|
||||||
|
FloatingTextStringOnCreature("ZILWAN: " + GetName(oTarget) + " is destroyed!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify target is not undead
|
||||||
|
FloatingTextStringOnCreature("ZILWAN: " + GetName(oTarget) + " is not undead!", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Notify if no valid target
|
||||||
|
FloatingTextStringOnCreature("ZILWAN: No valid target found", oCaster, TRUE);
|
||||||
|
}
|
||||||
|
}
|
1
Module/utc/attack_dog.json
Normal file
1
Module/utc/attack_dog.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/bishop.json
Normal file
1
Module/utc/bishop.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/bishop_lvl_8.json
Normal file
1
Module/utc/bishop_lvl_8.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/bleeb.json
Normal file
1
Module/utc/bleeb.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/boring_beetle.json
Normal file
1
Module/utc/boring_beetle.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/bubbly_slime.json
Normal file
1
Module/utc/bubbly_slime.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/bushwacker.json
Normal file
1
Module/utc/bushwacker.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/capybara.json
Normal file
1
Module/utc/capybara.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/chimera.json
Normal file
1
Module/utc/chimera.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/coyote.json
Normal file
1
Module/utc/coyote.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/creeping_coin.json
Normal file
1
Module/utc/creeping_coin.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/creeping_crud.json
Normal file
1
Module/utc/creeping_crud.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/daimyo_major.json
Normal file
1
Module/utc/daimyo_major.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/daimyo_minor.json
Normal file
1
Module/utc/daimyo_minor.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/demon_greater.json
Normal file
1
Module/utc/demon_greater.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/demon_lesser.json
Normal file
1
Module/utc/demon_lesser.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/dragon_fire.json
Normal file
1
Module/utc/dragon_fire.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/dragon_fly.json
Normal file
1
Module/utc/dragon_fly.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/dragon_gas.json
Normal file
1
Module/utc/dragon_gas.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/dragon_puppy.json
Normal file
1
Module/utc/dragon_puppy.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/dragon_zombie.json
Normal file
1
Module/utc/dragon_zombie.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/fighter_lvl_10.json
Normal file
1
Module/utc/fighter_lvl_10.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/fighter_lvl_7.json
Normal file
1
Module/utc/fighter_lvl_7.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/fighter_lvl_8.json
Normal file
1
Module/utc/fighter_lvl_8.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/flack.json
Normal file
1
Module/utc/flack.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/gargoyle.json
Normal file
1
Module/utc/gargoyle.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/gas_cloud.json
Normal file
1
Module/utc/gas_cloud.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/gaze_hound.json
Normal file
1
Module/utc/gaze_hound.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/giant_earth.json
Normal file
1
Module/utc/giant_earth.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/giant_fire.json
Normal file
1
Module/utc/giant_fire.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/giant_frost.json
Normal file
1
Module/utc/giant_frost.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/giant_poison.json
Normal file
1
Module/utc/giant_poison.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/giant_toad.json
Normal file
1
Module/utc/giant_toad.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/gorgon.json
Normal file
1
Module/utc/gorgon.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/grave_mist.json
Normal file
1
Module/utc/grave_mist.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/hatamoto.json
Normal file
1
Module/utc/hatamoto.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/high_master.json
Normal file
1
Module/utc/high_master.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/highwayman.json
Normal file
1
Module/utc/highwayman.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/killer_wolf.json
Normal file
1
Module/utc/killer_wolf.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/kobold.json
Normal file
1
Module/utc/kobold.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/lifestealer.json
Normal file
1
Module/utc/lifestealer.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/maelific.json
Normal file
1
Module/utc/maelific.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/mage_arch.json
Normal file
1
Module/utc/mage_arch.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/mage_lvl_1.json
Normal file
1
Module/utc/mage_lvl_1.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/mage_lvl_10.json
Normal file
1
Module/utc/mage_lvl_10.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/mage_lvl_5.json
Normal file
1
Module/utc/mage_lvl_5.json
Normal file
File diff suppressed because one or more lines are too long
1
Module/utc/mage_lvl_7.json
Normal file
1
Module/utc/mage_lvl_7.json
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user