Aller au contenu

Photo

Point Blank Area of Effect (PBAoE)


  • Veuillez vous connecter pour répondre
3 réponses à ce sujet

#1
Retpircs Wols

Retpircs Wols
  • Members
  • 18 messages
Hello Scripters,

I have a strange problem with and PBAoE spell and I feel like I am barely missing something.simple.  First, I replaced the eldritch blast file nw_s0_ieldblast with the following:

//Made by Retpircs Wols; heavily "borrowed" from NWN Official - "Crushing Despair" and "Fireball"

#include "NW_I0_SPELLS"
#include "x2_inc_spellhook"
void main()
{
/*
  Spellcast Hook Code
  Added 2003-06-20 by Georg
  If you want to make changes to all spells,
  check x2_inc_spellhook.nss to find out more
*/
    if (!X2PreSpellCastCode())
    {
    // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
        return;
    }
// End of Spell Cast Hook


//SpellCode

    object oCaster = OBJECT_SELF;                        //get caster

    int nLevel = GetLevelByclass(class_TYPE_WARLOCK);    //get Warlock Level
    //GetCasterLevel(OBJECT_SELF);
        //Limit Caster level for the purposes of damage
        if (nLevel > 10)
        {
            nLevel = 10;
        }   
    int nChar = GetAbilityScore(oCaster, ABILITY_CHARISMA);    //get Charisma score
    int nDC = 5 + nChar;                                    //make the DC the baddie needs to pass (beat charisma)
    effect eEffect;                                            //effect variable
   
//////////////////VISUALS: On CASTER
// effect eVis = EffectVisualEffect(VFX_HIT_CURE_AOE); 
//  effect eVis = EffectVisualEffect(VFX_HIT_AOE_ELDRITCH); REALLY IMPRESSIVE
//   effect eVis = EffectVisualEffect(VFX_HIT_AOE_EVOCATION); not bad
//  effect eVis = EffectVisualEffect(VFX_HIT_AOE_DIVINATION); POSSIBLE 
// effect eVis = EffectVisualEffect(VFX_FEAT_TURN_UNDEAD);
effect eVis = EffectVisualEffect(VFX_INVOCATION_BRIMSTONE_DOOM);        //cannot get good visuals
  ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
//////////////////END VISUALS for Caster   

   
    /////////////////////////////////////RUN huge hit - d2 * (charisma/3) + (War. Level/2)
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
    while(GetIsObjectValid(oTarget))         //while loop for valid critter targets
        {
        if(!GetIsReactionTypeFriendly(oTarget) == TRUE)    //make sure it is a baddie
                {
                //attempt a Will Save at 15 + Char Mod
                if (WillSave(oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS) == 0)   
                {       
                eEffect = EffectDamage(d2(nChar/3)+ (nLevel/2), DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget);
               
                //visuals Necro
                    effect eVis = EffectVisualEffect(VFX_HIT_SPELL_NECROMANCY);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
                }        //stop baddie if               
           }           //end of do - grab next critter
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
        } // End of Collosal
       
       
    /////////////////////////////////////RUN Large hit - 4d * (charisma/3) + (War. Level/2)

    oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
    while(GetIsObjectValid(oTarget))
        {
        if(!GetIsReactionTypeFriendly(oTarget) == TRUE)
                {
                //attempt a Will Save at 15 + Char Mod
                if (WillSave(oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS) == 0)   
                {       
                eEffect = EffectDamage(d4(nChar/3)+ (nLevel/2), DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget);
               
                //visuals Necro
                    effect eVis = EffectVisualEffect(VFX_HIT_SPELL_NECROMANCY);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
                }
               
           }         
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
        } // End of Medium       
       
       
    /////////////////////////////////////RUN Small hit - 6d * (charisma/3) + (War. Level/2)

    oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
    while(GetIsObjectValid(oTarget))
        {
        if(!GetIsReactionTypeFriendly(oTarget) == TRUE)
                {
                //attempt a Will Save at 15 + Char Mod
                if (WillSave(oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS) == 0)   
                {       
                eEffect = EffectDamage(d6(nChar/3)+ (nLevel/2), DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget);
               
                //visuals Necro
                    effect eVis = EffectVisualEffect(VFX_HIT_SPELL_NECROMANCY);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
                }
               
           }         
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
        } // End of Small               
       
}

This turns a Warlock into a potent, though fragile, hand grenade.

I then tried to turn it into a monk "spell" from an item.  First, I made my "activate item" script:

*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-07-16
//:://////////////////////////////////////////////

#include "x2_inc_switches"
void main()
{

    object oUser    = GetItemActivator();  //PC that activated the item
    object oItem = GetItemActivated();    // Get item activated
    object oTarget  = GetItemActivatedTarget();  //Get target of activated item
    string sItemTag = GetTag(GetItemActivated()); //Get tag of activated item

     if (GetModuleSwitchValue(MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS) == TRUE)
     {
        SetUserDefinedItemEventNumber(X2_ITEM_EVENT_ACTIVATE);
        int nRet =   ExecuteScriptAndReturnInt(GetUserDefinedItemEventScriptName(oItem),OBJECT_SELF);
        if (nRet == X2_EXECUTE_SCRIPT_END)
        {
           return;
        }

     }
        
         //if Soulfire is used
         if (sItemTag == "monk_soulfire")
    {
        ExecuteScript("s_soulfire_monk", oTarget);
        return;
    }
   
           //if Way of Wind is used
         if (sItemTag == "monk_w_wind")
    {
        ExecuteScript("s_monk_wind", oUser);
        return;
    }
}  //end script

This is for the item tagged monk_soulfire, a Unique Power item.  The other item is a Unique Power Self Only which works perfectly.

I then re-worked the PBAoE script to take into account monk levels and wisdom (instead of Warlock levels and charisma):

//name: s_soulfire_monk

//Made by Retpircs Wols; heavily "borrowed" from NWN Official - "Crushing Despair" and "Fireball"

#include "NW_I0_SPELLS"
#include "x2_inc_spellhook"
void main()
{
/*
  Spellcast Hook Code
  Added 2003-06-20 by Georg
  If you want to make changes to all spells,
  check x2_inc_spellhook.nss to find out more
*/
    if (!X2PreSpellCastCode())
    {
    // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
        return;
    }
// End of Spell Cast Hook


//SpellCode

    object oCaster = OBJECT_SELF;                        //get caster

    int nLevel = GetLevelByclass(class_TYPE_MONK);    //get monk Level
    //GetCasterLevel(OBJECT_SELF);
        //Limit Caster level for the purposes of damage
        if (nLevel > 10)
        {
            nLevel = 10;
        }   
    int nChar = GetAbilityScore(oCaster, ABILITY_WISDOM);    //get Wisdom score
    int nDC = 5 + nChar;                                    //make the DC the baddie needs to pass (beat wisdom)
    effect eEffect;                                            //effect variable
   
//////////////////VISUALS: On CASTER
// effect eVis = EffectVisualEffect(VFX_HIT_CURE_AOE); 
//  effect eVis = EffectVisualEffect(VFX_HIT_AOE_ELDRITCH); REALLY IMPRESSIVE
//   effect eVis = EffectVisualEffect(VFX_HIT_AOE_EVOCATION); not bad
//  effect eVis = EffectVisualEffect(VFX_HIT_AOE_DIVINATION); POSSIBLE 
// effect eVis = EffectVisualEffect(VFX_FEAT_TURN_UNDEAD);
effect eVis = EffectVisualEffect(VFX_INVOCATION_BRIMSTONE_DOOM);        //cannot get good visuals
  ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oCaster);
//////////////////END VISUALS for Caster   

   
    /////////////////////////////////////RUN huge hit - d2 * (charisma/3) + (War. Level/2)
    object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_HUGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
    while(GetIsObjectValid(oTarget))         //while loop for valid critter targets
        {
        if(!GetIsReactionTypeFriendly(oTarget) == TRUE)    //make sure it is a baddie
                {
                //attempt a Will Save at 15 + Char Mod
                if (WillSave(oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS) == 0)   
                {       
                eEffect = EffectDamage(d2(nChar/3)+ (nLevel/2), DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget);
               
                //visuals Necro
                    effect eVis = EffectVisualEffect(VFX_HIT_SPELL_NECROMANCY);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
                }        //stop baddie if               
           }           //end of do - grab next critter
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_COLOSSAL, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
        } // End of Collosal
       
       
    /////////////////////////////////////RUN Large hit - 4d * (charisma/3) + (War. Level/2)

    oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
    while(GetIsObjectValid(oTarget))
        {
        if(!GetIsReactionTypeFriendly(oTarget) == TRUE)
                {
                //attempt a Will Save at 15 + Char Mod
                if (WillSave(oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS) == 0)   
                {       
                eEffect = EffectDamage(d4(nChar/3)+ (nLevel/2), DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget);
               
                //visuals Necro
                    effect eVis = EffectVisualEffect(VFX_HIT_SPELL_NECROMANCY);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
                }
               
           }         
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
        } // End of Medium       
       
       
    /////////////////////////////////////RUN Small hit - 6d * (charisma/3) + (War. Level/2)

    oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
    while(GetIsObjectValid(oTarget))
        {
        if(!GetIsReactionTypeFriendly(oTarget) == TRUE)
                {
                //attempt a Will Save at 15 + Char Mod
                if (WillSave(oTarget, nDC, SAVING_THROW_TYPE_MIND_SPELLS) == 0)   
                {       
                eEffect = EffectDamage(d6(nChar/3)+ (nLevel/2), DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget);
               
                //visuals Necro
                    effect eVis = EffectVisualEffect(VFX_HIT_SPELL_NECROMANCY);
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
                }
               
           }         
        oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
        } // End of Small               
       
} //end of script

It gets the pretty visual effects, but does no damage at all to anything.  Not sure what I missed.  Could anyone help me out?  I would hugely apreciate it,

#2
kevL

kevL
  • Members
  • 4 075 messages
well,

in the 'huge hit', i notice the radius changes from _HUGE to _COLOSSAL

but i don't think that's why its not doing damage; uhm, be careful of rounding errors re. / d2(nChar/3) + (nLevel/2) /


note also, if unintended, that those who are caught by the small hit are also caught by the large and huge hits. There's a lot of looping going on ... you could make temp variables of some nature to exclude those already damaged. Lastly, try putting
ApplyEffectToObject()
inside a DelayComand(0.1f, ... );

that causes the line to run just after the script and often causes happy effects,

#3
Retpircs Wols

Retpircs Wols
  • Members
  • 18 messages
Thank you for the catch. It had initially been colossal, and I apparently only changed the first get to huge.

I started to wonder about the rounding errors... can you force it to use a whole number? Also, can you get the wisdom bonus instead of the wisdom stat? I would not have to divide it at all then.

#4
kevL

kevL
  • Members
  • 4 075 messages
here's the bonus function:

// Returns the ability modifier for the specified ability
// Get oCreature's ability modifier for nAbility.
// - nAbility: ABILITY_*
// - oCreature
int GetAbilityModifier(int nAbility, object oCreature=OBJECT_SELF);



you can put in little checks like,

int iDam1 = nChar/3;
if (iDam1 < 1) iDam1 = 1;

int iDam2 = nLevel/2;
if (iDam2 < 1) iDam2 = 1;


int iDam = d6(iDam1) + iDam2;


and/or an overall check for damage before applying effects:

if (iDam)
{
eEffect = EffectDamage(iDam, DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget);
}


(include or exclude the eVis as you see appropriate) What i said above is just to give the general idea; fortunately there's no potential for divide by 0, but that would be handled in much the same way. Back to not giving damage, i find it hard to believe it's a rounding error ... the guy'd havta have a Chr < 3 and a level < 2, to get zeros


But try breaking out the damage_integer onto its own line, pass it into eEffect along with a DelayCommand wrapper