Author Topic: Blackguard: Aura of Despair, uniquepower Aura  (Read 354 times)

Legacy_SKIPPNUTTZ

  • Full Member
  • ***
  • Posts: 148
  • Karma: +0/-0
Blackguard: Aura of Despair, uniquepower Aura
« on: November 21, 2011, 09:38:15 pm »


               Recently I created a custom ability for blackguards based off the original Aura of Despair. (This was originally started from a package I got off of the nwvault, which i modified a LOT) This is a unique power script, called inside the module OnActivateItem event. What I did was write a variable on the casters, BG_PENALTY with the value of the saving throw decrease, based off his current xp. This seemed to be a little more efficient than having to perform all this logic every time a creature entered the aura. The saving throw decrease is a flat 2 for all BG's unless they have 22 BG lvls or more, in which case the -2 aura will gain extra progression based off how much xp the caster has over lvl 40. (eg. for my lvl 210 [8 fighter 25 BG 7 WM] , it is -7 saving throws)


A few issues that I have run into, and would like some help/advice debugging them:

1.) The mobile aoe bug. This aura will only work randomly, and about half the time it seems, since once a player moves the aura seems to get left behind. Well known bug for all of bioware's mobile AOES (battletide, etc.) There is a fix for them on the nwvault but it seems this fix seems to rely on Spell IDs to work, which this obviously does not have.
2.) When creatures leave the aura as a result of a dibilitating effect, such as fear/daze/etc., the OnExit script doesnt seem to fire. Really dont know if there is an efficient way to counter this, it seems to be an error in the game engine itself.
3.) The anti-stacking protection I used, is pulled out of the spell Acid Fog. On our server we only allow casters to have a single instance of each persistent aoe active at a time. So I figured this would fit in fine with this custom spell. It seems to work fine, but open to suggestions. At first I just wrote a variable on the caster saying "you have this aura already", but that would require me to remove that variable in the Death/Rest events too if the duration of the spell had not been exceeded. So I scratched that idea as it seemed really sloppy.

Everything appears to work as intended except for #1 and #2 above.

EDIT: no idea why i didnt link these effects '<img'>

-----

    //Blackguard: Aura of Despair   
    object oItem = GetItemActivated();
    string sTag = GetTag( oItem );
    if ( sTag == "skip_dispair_ca" )
    {

        effect eImpact = EffectVisualEffect(VFX_FNF_LOS_EVIL_20);
        effect eAura = ExtraordinaryEffect(EffectVisualEffect(VFX_DUR_PROTECTION_EVIL_MAJOR));
        effect eAOE =             ExtraordinaryEffect(EffectAreaOfEffect(AOE_MOB_CIRCEVIL,"skip_despairentr","","skip_despairexit"));
        int nLvl = GetLevelByclass(class_TYPE_BLACKGUARD,oPC);
        effect eShield = ExtraordinaryEffect(EffectDamageShield(nLvl * 2,DAMAGE_BONUS_2d6, DAMAGE_TYPE_NEGATIVE));

        // 1 round per BG lvl with post lvl 40 duration increase
        int nDuration = Level40PlusMagicBuff(nLvl, OBJECT_SELF);

        //Remove the previous cast (Anti-Stacking protection)
        object oPrevious = GetLocalObject( GetModule( ), GetName( OBJECT_SELF ) + "_DESPAIR" );
        if ( GetIsObjectValid( oPrevious ))
        {
        DestroyObject( oPrevious );
        }

        //Error for Non-Blackguards
        if(nLvl < 3)
        {
         FloatingTextStringOnCreature("You must have at least 3 Blackguard levels to use this special ability...",oPC);
        }


        //check if is blackguard lvl3 at least
        if (nLvl >= 3 && nLvl <=21)
        {
        SetLocalInt(OBJECT_SELF, "BG_PENALTY", 2);
        }

        //check if is blackguard lvl 22 at least, and apply extra bonus progression for post 40 lvls
        else if (nLvl >= 22)
        {
        SetLocalInt(OBJECT_SELF, "BG_PENALTY", Level40PlusMagicBuff(2, OBJECT_SELF));
        }

        //Apply the visual effects and the Aura
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, GetLocation(OBJECT_SELF));
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAOE, OBJECT_SELF, RoundsToSeconds(nDuration));
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eShield, OBJECT_SELF, RoundsToSeconds(nDuration));
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAura, OBJECT_SELF, RoundsToSeconds(nDuration));


        DelayCommand(0.1, SendMessageToPC(oPC, "Aura of Despair: -" + IntToString(GetLocalInt(oPC, "BG_PENALTY"))));


        //WIP: Anti-Stacking protection
        int nCount = 1;
        object oEffect = GetNearestObjectToLocation( OBJECT_TYPE_AREA_OF_EFFECT, GetSpellTargetLocation(), nCount );

        while ( GetIsObjectValid( oEffect ))
        {
            //I dont understand this particular line, this system was pulled out of Acid Fog, to make sure players can only cast 1 cloud at a time.
            if ( GetLocalInt( oEffect, PF_AOE_SAVEDC ) == 0 )
            {
              SetLocalObject( GetModule( ), GetName( OBJECT_SELF ) + "_DESPAIR", oEffect );
              break;
            }
            else
            {
              oEffect = GetNearestObjectToLocation( OBJECT_TYPE_AREA_OF_EFFECT, lTarget, ++nCount );
            }
        }

      return;
    }


This is the OnEnter script for the aura:
-----

#include "NW_I0_SPELLS"
#include "x0_i0_spells"
#include "x2_inc_spellhook"

void main()
{
    //Declare major variables
    object oTarget = GetEnteringObject();
    object oBG = GetAreaOfEffectCreator();
    effect eDur = EffectVisualEffect(VFX_DUR_AURA_PULSE_RED_BLACK);
    int nPenalty = GetLocalInt(oBG, "BG_PENALTY");
    effect eDespair = EffectSavingThrowDecrease(SAVING_THROW_ALL, nPenalty, SAVING_THROW_TYPE_ALL);
    effect eLink = ExtraordinaryEffect(EffectLinkEffects(eDur, eDespair));


    //if(GetIsEnemy(oTarget, oBG))
    if(spellsIsTarget(oTarget, SPELL_TARGET_SELECTIVEHOSTILE, oBG))
        {
        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget);
        }
}


This is the OnExit script for the aura:
-----

void main()
{

    //Declare major variables
    //Get the object that is exiting the AOE
    object oTarget = GetExitingObject();
    effect ePenalty;

        //Search through the valid effects on the target.
        ePenalty = GetFirstEffect(oTarget);

        while (GetEffectDurationType(ePenalty) == DURATION_TYPE_PERMANENT && GetIsEffectValid(ePenalty) && GetEffectType(ePenalty) == EFFECT_TYPE_SAVING_THROW_DECREASE )
        {
            if (GetEffectCreator(ePenalty) == GetAreaOfEffectCreator())
            {

                    RemoveEffect(oTarget, ePenalty);
                    //bValid = TRUE;

            }
            //Get next effect on the target
            ePenalty = GetNextEffect(oTarget);
        }

}


Thanks in advance, I know this code is probably really ugly to some of you '<img'> But hey Im a noob scripter and just having fun learning.
               
               

               


                     Modifié par SKIPPNUTTZ, 21 novembre 2011 - 10:28 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Blackguard: Aura of Despair, uniquepower Aura
« Reply #1 on: November 22, 2011, 07:09:48 am »


               1) the aoe mobile bug has two parts, the first part is that mobile AOE disappear once her owner leave it (which shouldnt be possible, but due to the second issue it is) - there is no really perfect working fix for this issue on vault, Rabidness take has glitch that causes two AOEs of the same Id destroyed when they met each other. My patch offers solution that works perfectly, but even my solution cannot fix issue 2 which is that mobile AOE doesn't move in certains heavy CPU  impact modules and they only jump (in best case, or they doesnt move at all). My code makes it seems the AOE moves and the owner never loses benefits, but the real AOE stays on place anyway. There is nothing you could do about this, AOEs cannot perform JumpTo action.
The spell Id is however needed in my solution as well, since your AOE has id of -1 you will have to assign the effects to the AOE and then check effectcreator.

2) it fires, but your OnExit script is wrong

void main()
{

    //Declare major variables
    //Get the object that is exiting the AOE
    object oTarget = GetExitingObject();
    effect ePenalty;

        //Search through the valid effects on the target.
        ePenalty = GetFirstEffect(oTarget);

        while (GetIsEffectValid(ePenalty) )
        {
            if (GetEffectDurationType(ePenalty) == DURATION_TYPE_PERMANENT && GetEffectType(ePenalty) == EFFECT_TYPE_SAVING_THROW_DECREASE && GetEffectCreator(ePenalty) == GetAreaOfEffectCreator())
            {

                    RemoveEffect(oTarget, ePenalty);
                    //bValid = TRUE;

            }
            //Get next effect on the target
            ePenalty = GetNextEffect(oTarget);
        }

}