Author Topic: Morag needs therapy...  (Read 1324 times)

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Morag needs therapy...
« on: December 10, 2011, 01:15:32 am »


               It turns out that the final battle reveals that she doesn't like herself much. How do I know? Because she can be killed crossing the blade barrier-like thing that is guarding her protectors. The script that runs the blade barrier actually does a
GetIsReactionTypeFriendly()
so that it doesn't harm anyone friendly to Morag. I assume that the intent would be that it doesn't hurt her, either. But,
GetIsReactionTypeFriendly()
returns 0 when called on Morag herself, so she can be killed if she crosses it.

I figure the encounter probably wasn't tested quite enough with unassisted PCs who are casting long-range spells. Most meleers take down the barrier first to get to her and spellcasters using shorter range attacks would get closer to Morag so she wouldn't need to get closer to them, but my character was still far away when her AI (I tested both with Tony K's and with the default Bioware AI) wanted her to move closer to cast a spell. Next thing I knew, she was dead and the battle was over, even though I hadn't laid a (Bigby's) glove on her yet.

Not only a loss of the XP for killing her, but kind of anticlimax to win the big battle when the boss essentially trips and falls on her sword. Fortunately, it's an easy fix for anyone who wants to open the Toolset and edit Chapter 4. In the left-hand panel, expand Scripts and find m4blades and right-click to edit it.  Then paste the following over what's there, replacing the given script with this slightly modified one:


// m4blades.nss
// * custom blade barrier for wall of blades around Morag
// MrZork 2011/12/09: This was hitting Morag if she tried to cross the blade barrier.
// Modified conditional to check that the target isn't Morag herself.

void main()
    {
    //Declare major variables
    object oTarget = GetEnteringObject();
    object oMorag = GetObjectByTag("M4Q01D08MORA");
    effect eDam;
    effect eVis = EffectVisualEffect(VFX_COM_BLOOD_LRG_RED);

    if ((oTarget!=oMorag) && (!GetIsReactionTypeFriendly(oTarget, oMorag)))
        {
        //Roll Damage
        int nDamage = 150 + d100(1);
        eDam = EffectDamage(nDamage, DAMAGE_TYPE_SLASHING);
        //Apply damage and VFX
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
        }
    }

Hit Ctrl-S to save and recompile. The dialog at the bottom should say something like
12/9/2011 5:13:26 PM: 0 Errors. 'm4blades' compiled successfully
Close the script editor and save the module. Done. '<img'>
               
               

               


                     Modifié par MrZork, 10 décembre 2011 - 01:17 .
                     
                  


            

Legacy_HipMaestro

  • Hero Member
  • *****
  • Posts: 2849
  • Karma: +0/-0
Morag needs therapy...
« Reply #1 on: December 10, 2011, 04:23:32 am »


               Actually, I think Morag's a Chaotic schizo which means she is highly likely to betray her alter ego given the chance. '<img'>

Amazing to me that it took 11 years to fix this burp, but kudos for the effort.  I love the recompiles that don't involve every blessed module so this one will work out nicely. '<img'>

Since you are in the vicinity anyway perhaps you can explain why a few scrolls of Horrid Wilting can destroy all the protectors when they are all (except for the lessers one) supposed to be spawned in immune to magic, divine & negative damage (re:m4immunes.nss).  If you get the time...
               
               

               
            

Legacy_jmlzemaggo

  • Hero Member
  • *****
  • Posts: 1869
  • Karma: +0/-0
Morag needs therapy...
« Reply #2 on: December 10, 2011, 08:22:37 am »


               That's all so funny. Just as the title.
I let you two work this out. I wouldn't choose better madmen myself anyway to handle that job.
The only thing that's still missing with you MrZork being your signature, for fully belonging to the "Mad NWN Squad", like Hip and WebShaman.
Those signatures are already History. Legendary.
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Morag needs therapy...
« Reply #3 on: December 10, 2011, 09:51:04 pm »


               

HipMaestro wrote...
Since you are in the vicinity anyway perhaps you can explain why a few scrolls of Horrid Wilting can destroy all the protectors when they are all (except for the lessers one) supposed to be spawned in immune to magic, divine & negative damage (re:m4immunes.nss).  If you get the time...


Because they are given 100% vulnerability to magic, negative, and divine instead.
               
               

               
            

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Morag needs therapy...
« Reply #4 on: December 10, 2011, 10:41:18 pm »


               

HipMaestro wrote...

Since you are in the vicinity anyway
perhaps you can explain why a few scrolls of Horrid Wilting can destroy
all the protectors when they are all (except for the lessers one) supposed to be spawned in immune to magic, divine & negative damage (re:m4immunes.nss).  If you get the time...


Actually, if you pay close attention, you will notice that all of the other Protectors die more quickly from Horrid Wilting than the Protector against the Lessers. That is, one scroll or spell will often kill off all of them except her (where two will usually suffice), even though she is the only one who is supposed to be vulnerable to magic damage. Same is true of Isaac's, Sunburst, etc. I've always wondered about that, but never enough to look into it, until now.

The
m4immunes.nss
script is bugged to use
EffectDamageImmunity[i]Decrease[/i]()
instead of
EffectDamageImmunity[i]Increase[/i]()
. So, those Protectors that have it actually take 2x divine, negative, and magical damage.

Meanwhile, none of the protectors have the item Morag does that gives protection from magical damage.

In addition, though all the Protectors except the Protector Against the Lessers have protection from death magic, Horrid Wilting is not really death magic, at least inasmuch as immunity from death magic provides no immunity to Horrid Wilting.

While we're at it, all of the Protectors have immunity from Poison, including the one Protector Against Venom, who probably should not have it.

So, yeah, several things in that encounter are not the way they were probably intended.

[EDIT: I left my PC to check a few other things out and put together a CD rack and now I see that WhiZard has already noted the glitch in the immunities script.]
               
               

               


                     Modifié par MrZork, 10 décembre 2011 - 10:44 .
                     
                  


            

Legacy_HipMaestro

  • Hero Member
  • *****
  • Posts: 2849
  • Karma: +0/-0
Morag needs therapy...
« Reply #5 on: December 11, 2011, 12:32:41 am »


               Ahha!  "ImmunityDecrease" didn't make sense to me either as the commented title said it was supposed to make them invulnerable so I figured it was another case of covert Bioware circular scripting, hidden so a layman couldn't figure it out before his life expires on planet Earth.   Wrong!

But now it makes sense.  Thing is, I usually spam HW and the VFX in the battle area is so cloudy that I can't see what is happening until it is over,  Depending on where Morag is located among the AoE she often falls along with all the protectors.  If you haven't figured it out yet, reading the game log during an actual game gives me a headache... an agony I typically reserve for dedicated testing.

Thanks, guys!  Morag's not the only one who needs therapy, MrZ. '<img'>
               
               

               


                     Modifié par HipMaestro, 11 décembre 2011 - 12:35 .
                     
                  


            

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Morag needs therapy...
« Reply #6 on: December 11, 2011, 12:06:21 pm »


               HipMaestro, oddly enough, the immunities bug means that the Protector Against the Lessers usually survives longest versus a Horrid Wilting assault. When that happens (as has been typical on my plays through) Morag doesn't lose her level 9 and lower spell immunity until after that last Protector is gone. And, because of that, she and her remaining minions (the egg-sack spawns) are often at full health when I get around to them and I have had my hands pretty full with them. Now (with the fixed version), I am expecting that there may be a reload or two to finish this, since she will likely still have more of her immunities and more Protectors around to soak up Isaac's, empowered Firebrands, and so on. Though, at least the way I would approach her with a wizard PC, killing that Protector Against the Lessers will still be a priority and will open her biggest vulnerability.

One more thing, while I am in debug mode, so to speak. While updating the OnSpawn scripts for these protectors, I noticed another bug. The Protector Against the Storm isn't supposed to be immune from electrical attacks, but she is. I think that's the last obvious issue, but that area is a slightly more troubled than I would have thought.

Ideally, much of this would be best addressed by editing the area with the Toolset to remove or modify the items causing issues with those creatures. It can also be done via scripting, which might be easier and I guess also has the advantage that someone could plop the compiled script into their override when they start Chapter 4 and have the area work properly without having to use the Toolset. In addition to the blade barrier fix above, the script below, replacing
m4immunes.nss
should do the job with the Protectors

//::///////////////////////////////////////////////
//:: Name: M4Immunes.nss
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    This is the OnSpawn script for Morag's Protectors,
    except the Protector Against the Lessers.
   
    MrZork 2011/12/10: Modified to give appropriate
    Protectors immunity (rather than vulnerability)
    to magical, divine, and negative damage. Also
    modified to remove the immunity from poison that
    Morag's Venom protector gets from her helmet.
    Also removed immunity from electrical attacks
    from the Protector Against the Storm.
*/

// * all protectors are immune to magical damage, negative and divine
void main()
    {
    effect eImmunity = EffectDamageImmunityIncrease(DAMAGE_TYPE_MAGICAL,100);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eImmunity, OBJECT_SELF);

    eImmunity = EffectDamageImmunityIncrease(DAMAGE_TYPE_NEGATIVE,100);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eImmunity, OBJECT_SELF);

    eImmunity = EffectDamageImmunityIncrease(DAMAGE_TYPE_DIVINE,100);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eImmunity, OBJECT_SELF);
   
    if (GetTag(OBJECT_SELF)=="M4Q1D08_IMM_POIS")    // Protector Against Venom
        {
        object oItem = GetItemInSlot(INVENTORY_SLOT_HEAD,OBJECT_SELF);
        itemproperty ipPoison = GetFirstItemProperty(oItem);
        while (GetIsItemPropertyValid(ipPoison))
            {
            if (GetItemPropertyType(ipPoison)==ITEM_PROPERTY_IMMUNITY_MISCELLANEOUS)
                {
                if (GetItemPropertySubType(ipPoison)==3)    // from IPRP_IMMUNITY.2DA
                    {
                    RemoveItemProperty(oItem, ipPoison);
                    break;
                    }
                }
            ipPoison=GetNextItemProperty(oItem);
            }
        }
   
    if (GetTag(OBJECT_SELF)=="M4Q1D08_IMM_ELEC")    // Protector Against the Storm
        {
        object oItem = GetItemInSlot(INVENTORY_SLOT_BELT,OBJECT_SELF);
        if (GetIsObjectValid(oItem))
            {
            DestroyObject(oItem);
            }
        }
   
    }


I think that covers everything obvious in that scene that is probably a bug. One other thing that I changed was to rewrite Morag's OnDeath script so that her minions that spawn during the fight don't automatically die when she does, though the PC can still escape via the teleports that spawn after Morag dies. Obviously, that's a design decision rather than a bug, but I modified
m4q1d08_moragdea.nss
as follows to make it so that (on Hard Core or harder) the PC can take down those minions, too (and get the XP for it).

// Morag OnDeath script m4q1d08_moragdea.nss
//* MOrag dies, says one last line and then explodes
#include "nw_i0_plot"

// * blows things up at end of game
void KillObject(object oToKill)
{
    effect eDamage = EffectDamage(1000);
    float fRandom = IntToFloat(Random(100)) * 0.001;
    DelayCommand(fRandom, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eDamage, oToKill));
}

void main()
{

    RewardXP("M4Q01_MAIN",100,GetLastKiller());
    AddJournalQuestEntry("M4Q01_MAIN",99,GetLastKiller());
    SetLocalInt(OBJECT_SELF,"NW_L_AMDEAD",10);
    ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectResurrection(), OBJECT_SELF);
    SetPlotFlag(OBJECT_SELF,TRUE);
    effect eVis = EffectVisualEffect(VFX_IMP_SUNSTRIKE);
    ApplyEffectAtLocation(DURATION_TYPE_PERMANENT, eVis, GetLocation(OBJECT_SELF));
    SpeakOneLinerConversation();
    SetPlotFlag(OBJECT_SELF,FALSE);

    ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_FNF_IMPLOSION), GetNearestObjectByTag("ThroneEvil1"));
    KillObject(GetNearestObjectByTag("M_FireWall_1"));
    KillObject(GetNearestObjectByTag("M_FireWall_2"));
    KillObject(GetNearestObjectByTag("M_FireWall_3"));
    KillObject(GetNearestObjectByTag("M_FireWall_4"));
    KillObject(GetNearestObjectByTag("ShaftofLightRed1"));
    KillObject(GetNearestObjectByTag("ShaftofLightRed2"));
    KillObject(GetNearestObjectByTag("ThroneEvil1"));


    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_FIRE"));
    KillObject(GetNearestObjectByTag("M4Q1D2_FIRE"));
    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_COLD"));
    KillObject(GetNearestObjectByTag("M4Q1D2_COLD"));
    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_OTHE"));
    KillObject(GetNearestObjectByTag("M4Q1D2_OTHE"));
    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_BLUN"));
    KillObject(GetNearestObjectByTag("M4Q1D2_BLUN"));
    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_PIER"));
    KillObject(GetNearestObjectByTag("M4Q1D2_PIER"));
    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_ELEC"));
    KillObject(GetNearestObjectByTag("M4Q1D2_ELEC"));
    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_SLAS"));
    KillObject(GetNearestObjectByTag("M4Q1D2_SLAS"));
    KillObject(GetNearestObjectByTag("M4Q1D08_IMM_POIS"));
    KillObject(GetNearestObjectByTag("M4Q1D2_POIS"));

    // MrZork 2011/12/09: Only kill these guys on the easier settings
    if (GetGameDifficulty() < GAME_DIFFICULTY_CORE_RULES)
        {
        KillObject(GetNearestObjectByTag("m4sac1"));
        KillObject(GetNearestObjectByTag("m4sac2"));
        KillObject(GetNearestObjectByTag("m4sac3"));
        KillObject(GetNearestObjectByTag("m4sac4"));

        KillObject(GetNearestObjectByTag("m4sac1_c"));
        KillObject(GetNearestObjectByTag("m4sac2_c"));
        KillObject(GetNearestObjectByTag("M4_MIN_HULK"));
        KillObject(GetNearestObjectByTag("M4_MIN_RENDER"));
        }

    DestroyObject(OBJECT_SELF, 1.0);


    // * all the post-plot stuff requires this to work
    SetLocalInt(GetModule(),"NW_G_MORAGDEAD", 10);

}


[EDIT: Sorry, I am not sure how to get the social boards to reliably preserve spacing and returns.]
               
               

               


                     Modifié par MrZork, 11 décembre 2011 - 12:32 .
                     
                  


            

Legacy_HipMaestro

  • Hero Member
  • *****
  • Posts: 2849
  • Karma: +0/-0
Morag needs therapy...
« Reply #7 on: December 11, 2011, 01:24:35 pm »


               

MrZork wrote...
Sorry, I am not sure how to get the social boards to reliably preserve spacing and returns.

There is no way but the mouse 'n finger method.  The BSN boards are the funkiest I have ever pasted into and that is web-wide.  The
CODE
format helps some, but figure on removing lots of whitespace and linebreaks when you do pasting here.  The only other way is to post lengthy text on another more paste-friendly site and just furnish a link here.  *a tear comes to his eye as he remembers care-free moments and places*

In any case...

Nice work, amigo!  A long-overdue scrubbing was sorely needed. '<img'>
               
               

               
            

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Morag needs therapy...
« Reply #8 on: December 11, 2011, 01:40:15 pm »


               Thanks, Hip. :-)

BTW, I still can't get this board to show code properly. But, thanks to the Generic Syntax Hilighter (GeSHi), I can at least post links to the scripts where they can be seen (and, more importantly, copied and pasted from) in more readable form.
  script: m4blades.nss (compiled version: m4blades.ncs)
  script: m4immunes.nss (compiled version: m4immunes.ncs)
  script: m4q1d08_moragdea.nss (compiled version: m4q1d08_moragdea.ncs)
I've included links to the compiled versions as well, since it may useful to our Mac-using friends.
               
               

               
            

Legacy_MrZork

  • Hero Member
  • *****
  • Posts: 1643
  • Karma: +0/-0
Morag needs therapy...
« Reply #9 on: December 11, 2011, 02:01:09 pm »


               BTW,

jmlzemaggo wrote...

The only thing that's still missing with you MrZork being your signature, for fully belonging to the "Mad NWN Squad", like Hip and WebShaman.
Those signatures are already History. Legendary.


I can't claim any noteworthy insanity yet, but the very tiny site I put together for hosting little files like the ones above has little random slogans, all products of my fevered brain. (There are a couple dozen in all; I wrote a script to choose them randomly when the page is loaded or reloaded.)
               
               

               


                     Modifié par MrZork, 11 décembre 2011 - 02:07 .
                     
                  


            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Morag needs therapy...
« Reply #10 on: December 12, 2011, 12:26:37 am »


               

MrZork wrote...

I can't claim any noteworthy insanity yet, but the very tiny site I put together for hosting little files like the ones above has little random slogans, all products of my fevered brain. (There are a couple dozen in all; I wrote a script to choose them randomly when the page is loaded or reloaded.)

Translating UFO sightings from Braille since 1949


Loved this one
               
               

               
            

Legacy_jmlzemaggo

  • Hero Member
  • *****
  • Posts: 1869
  • Karma: +0/-0
Morag needs therapy...
« Reply #11 on: December 12, 2011, 04:00:48 am »


               

MrZork wrote...
I can't claim any noteworthy insanity yet, but the very tiny site I put together... 

Yes you can. Insane enough for me. 
It took me a few seconds to realise I had to reload that very page... ':wizard:'
Is that insanity enough? 
               
               

               
            

Legacy_Bayz

  • Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
Morag needs therapy...
« Reply #12 on: December 16, 2011, 02:14:58 pm »


               Well it is Forgotten Realms, where drow don't like to be drow and turn good, orcs don't like to be orcs and turn neutral, the list goes on...

That's why I like duergar, nobody likes them so they can be just nasty dwarven ****s that...*reads 4e* ohh well **** that too...