Author Topic: Making Placeables Resistant To Magic  (Read 298 times)

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Making Placeables Resistant To Magic
« on: November 27, 2011, 07:22:20 pm »


               I am trying to create a sequence in which a player or players must destroy 5 placeables. Each placeable destroyed will destroy a certain creature, and when all 5 placeables are destroyed, a gateway will open. The placeables have 10000 hit points, and the creatures are set to plot to make it more interesting. All of the scripts work fine.

The problem I am having is that anyone with umd and a few scrolls of wail of the banshee can destroy the placeables too quickly. I've tried raising the resistance and saves of the placeables, but that did not help at all. Making a script to make the placeables immune to all spells did not work either. Making area triggers to give spell failure has no effect on scrolls.

If anyone has a solution to make placeables resistant to magic, I would reallty appreciate it.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #1 on: November 27, 2011, 09:29:09 pm »


               Assuming you mean spell resistance, rather magic (damage) resistance, we use a variable set on the placeable, and checked in our spellscripts. If you haven't recoded your spells to a master include, though, you'll need a more practical solution. If it's just wail of the banshee that's giving you trouble, there's no reason for it to be targeting placeables that I can think of - easy spell script edit.

If, however, it's all spells, I would recommend putting a spell resistance effect on it when it's created, or when pcs enter the area. You can put all kinds of effects on placeables, though I can't guarantee all will work. Here's an example with damage immunities:


void AddPlaceableDefenses(object oSelf) {
    effect eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_BLUDGEONING, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_PIERCING, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_SLASHING, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_ACID, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_COLD, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_FIRE, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_SONIC, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_MAGICAL, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_POSITIVE, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_NEGATIVE, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageResistance(DAMAGE_TYPE_DIVINE, 20));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_SLASHING, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_BLUDGEONING, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_PIERCING, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_ACID, 100));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_COLD, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_ELECTRICAL, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_FIRE, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_SONIC, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_POSITIVE, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
    eEff = ExtraordinaryEffect(EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE, 50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oSelf);
}

And the snippet that applies it:

        object oBellyWay = GetWaypointByTag("h_wayserpentbelly");
        object oMuscle;
        if (!GetIsObjectValid(GetNearestObjectByTag("muscle1", oBellyWay))) {
            oMuscle = CreateObject(OBJECT_TYPE_PLACEABLE, "musclemass", GetLocation(GetWaypointByTag("h_waysbmuscle1")), FALSE, "muscle1");
            AddPlaceableDefenses(oMuscle);
        }
        if (!GetIsObjectValid(GetNearestObjectByTag("muscle2", oBellyWay))) {
            oMuscle = CreateObject(OBJECT_TYPE_PLACEABLE, "musclemass", GetLocation(GetWaypointByTag("h_waysbmuscle2")), FALSE, "muscle2");
            AddPlaceableDefenses(oMuscle);
        }
        if (!GetIsObjectValid(GetNearestObjectByTag("muscle3", oBellyWay))) {
            oMuscle = CreateObject(OBJECT_TYPE_PLACEABLE, "musclemass", GetLocation(GetWaypointByTag("h_waysbmuscle3")), FALSE, "muscle3");
            AddPlaceableDefenses(oMuscle);
        }

I don't see why you couldn't apply a spell resistance effect in the same way, though I don't remember why we do ours by variable - convenience, or possibly some other issue.

Funky
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #2 on: November 28, 2011, 03:19:01 am »


               Here is the script I used. It comes at the end of a conversation. It turns the creatures hostile, and then removes the plot flags from the placeables and adds the spellresistance. I'm not sure why the spell resistance doesn't work. Everything else works fine.

#include "nw_i0_generic"
void main()
{
    effect eVFX;
    effect eEffect;
    object oTarget;
    object oSelf = OBJECT_SELF;
    // Get the PC who is in this conversation.
    object oPC = GetPCSpeaker();
    // Make "sot_IngelBoss2" dislike the PC more.
    oTarget = GetObjectByTag("sot_IngelBoss2");
    ChangeToStandardFaction(oTarget, STANDARD_FACTION_HOSTILE);
    SetIsTemporaryEnemy(oPC, oTarget);
    AssignCommand(oTarget, ActionAttack(oPC));
    AssignCommand(oTarget, DetermineCombatRound(oPC));
    // Make "sot_ChlorBoss2" dislike the PC more.
    oTarget = GetObjectByTag("sot_ChlorBoss2");
    ChangeToStandardFaction(oTarget, STANDARD_FACTION_HOSTILE);
    SetIsTemporaryEnemy(oPC, oTarget);
    AssignCommand(oTarget, ActionAttack(oPC));
    AssignCommand(oTarget, DetermineCombatRound(oPC));
    // Make "sot_AbaziBoss2" dislike the PC more.
    oTarget = GetObjectByTag("sot_AbaziBoss2");
    ChangeToStandardFaction(oTarget, STANDARD_FACTION_HOSTILE);
    SetIsTemporaryEnemy(oPC, oTarget);
    AssignCommand(oTarget, ActionAttack(oPC));
    AssignCommand(oTarget, DetermineCombatRound(oPC));
    // Make "sot_CasarBoss2" dislike the PC more.
    oTarget = GetObjectByTag("sot_CasarBoss2");
    ChangeToStandardFaction(oTarget, STANDARD_FACTION_HOSTILE);
    SetIsTemporaryEnemy(oPC, oTarget);
    AssignCommand(oTarget, ActionAttack(oPC));
    AssignCommand(oTarget, DetermineCombatRound(oPC));
    // Make "sot_TchazBoss2" dislike the PC more.
    oTarget = GetObjectByTag("sot_TchazBoss2");
    ChangeToStandardFaction(oTarget, STANDARD_FACTION_HOSTILE);
    SetIsTemporaryEnemy(oPC, oTarget);
    AssignCommand(oTarget, ActionAttack(oPC));
    AssignCommand(oTarget, DetermineCombatRound(oPC));
    // Alter "sot_IngelStat".
    oTarget = GetObjectByTag("sot_IngelStat");
    SetPlotFlag(oTarget, FALSE);
    eEffect = SupernaturalEffect(EffectSpellResistanceIncrease(50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    // Alter "sot_ChlorStat".
    oTarget = GetObjectByTag("sot_ChlorStat");
    SetPlotFlag(oTarget, FALSE);
    eEffect = SupernaturalEffect(EffectSpellResistanceIncrease(50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    // Alter "sot_AbaziStat".
    oTarget = GetObjectByTag("sot_AbaziStat");
    SetPlotFlag(oTarget, FALSE);
    eEffect = SupernaturalEffect(EffectSpellResistanceIncrease(50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    // Alter "sot_CasarStat".
    oTarget = GetObjectByTag("sot_CasarStat");
    SetPlotFlag(oTarget, FALSE);
    eEffect = SupernaturalEffect(EffectSpellResistanceIncrease(50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    // Alter "sot_TchazStat".
    oTarget = GetObjectByTag("sot_TchazStat");
    SetPlotFlag(oTarget, FALSE);
    eEffect = SupernaturalEffect(EffectSpellResistanceIncrease(50));
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    // Destroy an object (not fully effective until this script ends).
    eVFX = EffectVisualEffect(VFX_IMP_UNSUMMON);
    ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oSelf);
    DestroyObject(oSelf, 3.0);
}


I looked at your scripts, but I'm not sure where you got the GetPlaceableDefenses function. I couldn't find it, so I imagine it must need to include another script.

Mostly what I want is to remove the death spells being cast from scrolls. There are a few different death spells that work on placeables. Banshee, destruction, implosion, and harm, to name a few. I like to give help to pure mages, and not to fighters with one rogue level for umd.

I tried looking at the spell scripts, but I could not figure out how to fix them.

I'll see what I can do with your script sometime tomorrow. Thank you for your help.  'Image
               
               

               


                     Modifié par Sadira of Tyr, 28 novembre 2011 - 03:31 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #3 on: November 28, 2011, 09:15:12 am »


               The script I posted won't do anything yours doesn't - I just wasn't sure what you'd tried already. If that SRIncrease function isn't working, then you do indeed need to use a var-based setup like ours. Here's the core spell resistance function, but you would have to do a ton of groundwork in order to implement it into your spells (including editing all spells you want it to handle resistance for):


int GetSpellResisted (struct SpellInfo si, object oTarget=OBJECT_INVALID, float fDelay=0.0, int bSROnly=FALSE) {
    int nSR = 0, nResisted = 0, nRoll = 0;

    if (!GetIsObjectValid(oTarget))
        oTarget = si.target;
    if (!GetIsObjectValid(oTarget))
        return 0;

    if (GetObjectType(oTarget) == OBJECT_TYPE_CREATURE)
        nSR = GetSpellResistance(oTarget);
    else
        nSR = GetLocalInt(oTarget, "SR");


    if (nSR > 0 && GetHasSpellImmunity(SPELL_SPELL_RESISTANCE, oTarget)) {
        nSR -= GetLocalInt(oTarget, "TauntResult");
        if (nSR < 1)
            nSR = 1;
    }


    if (nSR > 0 && si.sp >= 0 && !GetFactionEqual(si.caster, oTarget)) {
        nRoll = d20(1);

        if (si.sp + nRoll < nSR)
            nResisted = 1;
    }

    if (nResisted == 0) {
        if (bSROnly) {
            if (bSROnly == 2 && GetHasSpellImmunity(si.id, oTarget))
                nResisted = 2;
        } else {
            switch (ResistSpell(si.caster, oTarget)) {
                case 2:  /* globe or spell immunity */
                    nResisted = 2;
                    break;
                case 3:  /* spell mantle */
                    if (si.sp >= 0)
                        nResisted = 3;
                    break;
            }
        }
    }

    if (!nResisted) {
        if (nRoll > 0)
            SendSpellResistanceMessage(si.caster, oTarget, nRoll, si.sp, nSR, fDelay);

        return 0;
    }

    if (GetObjectType(oTarget) == OBJECT_TYPE_CREATURE) {
        effect eVis;

        switch (nResisted) {
            case 2:
                nSR  = -2;
                eVis = EffectVisualEffect(VFX_IMP_GLOBE_USE);
                break;
            case 3:
                nSR  = -3;
                eVis = EffectVisualEffect(VFX_IMP_SPELL_MANTLE_USE);
                break;
            default:
                eVis = EffectVisualEffect(VFX_IMP_MAGIC_RESISTANCE_USE);
                break;
        }

        DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
    }

    if (nRoll > 0 || nSR < -1)
        SendSpellResistanceMessage(si.caster, oTarget, nRoll, si.sp, nSR, fDelay);

    return nResisted;
}

Funky
               
               

               
            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #4 on: November 28, 2011, 11:31:20 am »


               I'm pretty certain that EffectSpellResistance only works on creatures. Hence the reason why FS used variables and EffectDamageResistance and EffectDamageImmunityIncrease.

Nice function by the way, FS...

Since its only a small number of spells you list as having trouble with, why not just edit them so that they do not effect placeables?
               
               

               


                     Modifié par Pstemarie, 28 novembre 2011 - 11:32 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #5 on: November 28, 2011, 08:37:19 pm »


               Thanks, but that's almost entirely acaos' work - he rewrote our spells from the ground up, in order to make them easily editable en masse. Very handy for stuff like this, but an enormous time investment up front, which is likely not terribly appealing for many builders. I know Shad has put in the time to wire up spells in his patch, so it's conceivable it can handle something like this for you - might want to ask him.

I tend to agree with Pstemarie about modding individual spells here. The trick is catching them all, including less prominent ones like crumble.

You might also try a Supernatural Death Immunity effect to ward against things like implosion, in order to save you editing the death spells, though again I'm not sure precisely what rules apply to placeables there, since it's been so long since we used standard functions in our spellscripts.

Funky
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #6 on: November 28, 2011, 10:47:53 pm »


               I haven't tried anything yet, but I'm thing of trying to make them immune to death spells and negative energy. I'm not sure if it would stop implosion though.

The reason I haven't edited the spell scripts, is that I haven't edited spells before, and I'm not sure how to change them. I looked at the script for wail of the banshee, and I wasn't sure what needed to be done to fix it.

Thank you for your suggestions. 'Image
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #7 on: November 28, 2011, 11:47:48 pm »


               The best way to accomplish this is via spellhook.

check the GetSpellId against insta-death ones and block them

However if the immunity against death works, then it should be fine. Implosion by default doesnt affect placeables, so are you sure that it can be used against your placeables to destroy them?
               
               

               


                     Modifié par ShaDoOoW, 29 novembre 2011 - 12:34 .
                     
                  


            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #8 on: November 29, 2011, 12:39:49 am »


               Well, I tried all the death spells, and the only ones that affected placeables, were wail of the banshee, destruction, and harm. I tried adding the effects immune to death spells and immune to negative energy to the placeables. The death immunity did not work, but the negative energy immunity did work. The harm scroll did show 9998 damage, but it did not affect the placeable, since it took many many more hits to destroy it. So now the problem is just banshee and destruction.

I'm not sure what you mean by the spell hooks. Do you mean to not allow these spells in the whole area, or just from being cast at the placeables?
               
               

               


                     Modifié par Sadira of Tyr, 29 novembre 2011 - 12:43 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #9 on: November 29, 2011, 12:46:37 am »


               tutorial to spellhook

or edit manually those spells you have problem with and remove "|OBJECT_TYPE_PLACEABLE" from them and compile
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #10 on: November 29, 2011, 10:51:23 am »


               Well, I guess editing the two spells would be the best idea. However when I checked the scripts nw_s0_destruc and nw_s0_wailbansh, I couldn't find any mention of placables as targets.

I looked at the tutorial about spellhooks, but that is betyond my scripting skills unfortunately.

Oh well, thanks for helping.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #11 on: November 29, 2011, 11:30:35 am »


               I see. Try this:

nw_s0_destruc

//::///////////////////////////////////////////////
//:: Destruction
//:: NW_S0_Destruc
//:: Copyright © 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    The target creature is destroyed if it fails a
    Fort save, otherwise it takes 10d6 damage.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Aug 13, 2001
//:://////////////////////////////////////////////

#include "NW_I0_SPELLS"   
#include "x2_inc_spellhook"

void main()
{

/*
  Spellcast Hook Code
  Added 2003-06-23 by GeorgZ
  If you want to make changes to all spells,
  check x2_inc_spellhook.nss to find out more
 
*/

    if (!X2PreSpellCastCode())
    {
    // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
        return;
    }

// End of Spell Cast Hook


    //Declare major variables
    object oTarget = GetSpellTargetObject();
    int nMetaMagic = GetMetaMagicFeat();
    int nDamage;
    effect eDeath = EffectDeath();
    effect eDam;
    effect eVis = EffectVisualEffect(234);
    if(GetObjectType(oTarget) != OBJECT_TYPE_PLACEABLE && !GetIsReactionTypeFriendly(oTarget))
    {
        //Fire cast spell at event for the specified target
        SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_DESTRUCTION));
        //Make SR check
        if(!MyResistSpell(OBJECT_SELF, oTarget))
        {
            //Make a saving throw check
            if(!/*Fort Save*/ MySavingThrow(SAVING_THROW_FORT, oTarget, GetSpellSaveDC()))
            {
                //Apply the VFX impact and effects
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDeath, oTarget);
            }
            else
            {
                nDamage = d6(10);
                //Enter Metamagic conditions
                if (nMetaMagic == METAMAGIC_MAXIMIZE)
                {
                    nDamage = 60;//Damage is at max
                }
                else if (nMetaMagic == METAMAGIC_EMPOWER)
                {
                    nDamage = nDamage + (nDamage/2); //Damage/Healing is +50%
                }
                //Set damage effect
                eDam = EffectDamage(nDamage, DAMAGE_TYPE_DIVINE);
                ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
            }
            //Apply VFX impact
            ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
        }
    }
}


The wail of banshee should affect placeables by default as far as I know, are you sure with the issue? If so post your spellscript of banshee code.
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Making Placeables Resistant To Magic
« Reply #12 on: November 30, 2011, 01:04:25 am »


               Well I tried your destruction spell and it worked. I figured out what you did, and I tried it on the banshee script, and it worked. I am so happy now.

A big thank you to all of you for helping me with this.

Thank you.   'Image