Beholder Rays

Started by Ook, May 04, 2014, 02:23:12 AM

Previous topic - Next topic

AllMYBudgies

Unfortunately, I am something of a Beholder-Deathray fan and would welcome them staying just as they are.

I understand the frustrations people might feel regarding their death rays, especially in regards to lag related incidents, but as it stands I favour Beholders being something that nobody in their right mind should be actively going up against.

Knight Of Pentacles

Maybe make a new spell or new potion that grants temporary immunity to petrification?

Paha

That is not likely to happen either. It is a danger that is intended and part of the D&D world. There is no desire to make it less dangerous.

The Man

Freedom of Movement was modified to do this. What I said was accurate. That they are difficult to understand mechanically and thus bring fear is desirable. I am closing this thread because. Beholders being aberrant and dangerous = desirable. Everyone being an expert in fighting them = undesirable.

Kotenku

Somebody has already done exactly what this suggestion is asking for, as part of the fan-made 1.71 content patch.



//::///////////////////////////////////////////////
//:: x2_s1_beholdatt
//:: Beholder Attack Spell Logic
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*

    This spellscript is the core of the beholder's
    attack logic.

*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-08-28
//:://////////////////////////////////////////////
/*
Patch 1.71

- added G'Zhorb appearance to the list of appearances that can use antimagic eye (dispell)
- any custom creature with beholder antimagic cone will be also able to use antimagic eye
- targetting improved, script now handles multiple targets properly and ignore dead players
- randomization fixed, in some cases the script was trying to randomize rays fired on targets,
due to the bug this however never happened
*/

#include "x2_inc_beholder"

//1.71 private function
object GetNthRayTarget(object oEmergencyTarget, int nTh)
{
int n = 1;
int nEnemy;
object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_DOES_NOT_HAVE_SPELL_EFFECT,SPELL_ETHEREALNESS);
 while(GetIsObjectValid(oEnemy))
 {
  if(!GetIsDead(oEnemy))
  {
   if(++nEnemy >= nTh)
   {
   return oEnemy;
   }
  }
 oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,++n,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_DOES_NOT_HAVE_SPELL_EFFECT,SPELL_ETHEREALNESS);
 }
return oEmergencyTarget;
}

void main()
{
    int nApp = GetAppearanceType(OBJECT_SELF);
    object oTarget = GetSpellTargetObject();
    // Only if we are beholders and not beholder mages
 /*
    //* GZ: cut whole immunity thing because it was causing too much trouble
     if (nApp == 472 ||nApp == 401 || nApp == 403)
    {
        CloseAntiMagicEye(oTarget);
    }
  */

    // need that to make them not drop out of combat
    SignalEvent(oTarget,EventSpellCastAt(OBJECT_SELF,GetSpellId()));

    struct beholder_target_struct stTargets = GetRayTargets(oTarget);
    int nRay;
    if (stTargets.nCount ==0)
    {
        //emergency fallback
            BehDoFireBeam(BEHOLDER_RAY_SLOW,oTarget);
            BehDoFireBeam(BEHOLDER_RAY_DEATH,oTarget);
            BehDoFireBeam(BEHOLDER_RAY_FEAR,oTarget);
            BehDoFireBeam(BEHOLDER_RAY_TK,oTarget);
    }
    else if (stTargets.nCount ==1) // AI for only one target
    {
        if (d2()==1)
        {
            BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget1);
            if (d2()==1)
                BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
        }
        else
        {
            BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
            if (d2()==1)
                BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget1);
        }
        if (d3()==1)
        {
            BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget2);
        }
    }
    else if (stTargets.nCount ==2)
    {
        if (d2()==1)
        {
            BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget2);
            if (d2()==1)
                BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget2);
        }
        else
        {
            BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
            if (d2()==1)
                BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget2);
        }
    }
    else if (stTargets.nCount ==3)
    {
       if (d2()==1)
       {
            BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget1);
            if (d2()==1)
                BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget3);
            BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget3);
            BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget2);
       }
       else
       {
            BehDoFireBeam(BEHOLDER_RAY_DEATH,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_SLOW,stTargets.oTarget3);
            BehDoFireBeam(BEHOLDER_RAY_FEAR,stTargets.oTarget1);
            if (d2()==1)
                BehDoFireBeam(BEHOLDER_RAY_WOUND,stTargets.oTarget2);
            BehDoFireBeam(BEHOLDER_RAY_TK,stTargets.oTarget1);
            BehDoFireBeam(BEHOLDER_RAY_PETRI,stTargets.oTarget3);
            BehDoFireBeam(BEHOLDER_RAY_CHARM,stTargets.oTarget1);
       }
    }
    else
    {
        BehDoFireBeam(BEHOLDER_RAY_DEATH,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
        BehDoFireBeam(BEHOLDER_RAY_SLOW,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
        BehDoFireBeam(BEHOLDER_RAY_FEAR,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
        BehDoFireBeam(BEHOLDER_RAY_WOUND,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
        BehDoFireBeam(BEHOLDER_RAY_TK,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
        BehDoFireBeam(BEHOLDER_RAY_PETRI,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
        BehDoFireBeam(BEHOLDER_RAY_CHARM,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
        BehDoFireBeam(BEHOLDER_RAY_WOUND,GetNthRayTarget(oTarget,Random(stTargets.nCount)+1));
    }

    // Only if we are beholders and not beholder mages
    if (nApp == 472 || nApp == 401 || nApp == 403 || nApp == 299 || GetHasSpell(727))
    {                                              //GZhorb or any custom beholder with antimagic cone
        OpenAntiMagicEye(oTarget);
    }
}
//::///////////////////////////////////////////////
//:: Beholder AI and Attack Include
//:: x2_inc_beholder
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*

    Include file for several beholder functions

*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: August, 2003
//:://////////////////////////////////////////////
/*
Patch 1.71

- targetting routine rewritten from scratch to work better in multiplayer
- fear ray now gives fear not damage
- missed rays will be visible now
*/

#include "x0_i0_spells"

const int BEHOLDER_RAY_DEATH = 1;
const int BEHOLDER_RAY_TK = 2;
const int BEHOLDER_RAY_PETRI= 3;
const int BEHOLDER_RAY_CHARM = 4;
const int BEHOLDER_RAY_SLOW = 5;
const int BEHOLDER_RAY_WOUND = 6;
const int BEHOLDER_RAY_FEAR = 7;

struct beholder_target_struct
{
        object oTarget1;
        int nRating1;
        object oTarget2;
        int nRating2;
        object oTarget3;
        int nRating3;
        int nCount;
};



int   GetAntiMagicRayMakesSense ( object oTarget );
void  OpenAntiMagicEye          ( object oTarget );
void  CloseAntiMagicEye         ( object oTarget );
int   BehGetTargetThreatRating  ( object oTarget );
int   BehDetermineHasEffect     ( int nRay, object oCreature );
void  BehDoFireBeam             ( int nRay, object oTarget );

struct beholder_target_struct GetRayTargets ( object oTarget );

int GetAntiMagicRayMakesSense(object oTarget)
{
    int bRet = TRUE;
    int nType;

    effect eTest = GetFirstEffect(oTarget);

    if (!GetIsEffectValid(eTest))
    {
      int nMag = GetLevelByClass(CLASS_TYPE_WIZARD,oTarget) + GetLevelByClass(CLASS_TYPE_SORCERER,oTarget) + GetLevelByClass(CLASS_TYPE_BARD,oTarget) + GetLevelByClass(CLASS_TYPE_RANGER,oTarget) + GetLevelByClass(CLASS_TYPE_PALADIN,oTarget);
      // at least 3 levels of magic user classes... we better use anti magic anyway
      if (nMag < 4)
      {
        bRet = FALSE;
      }
    }
    else
    {
        while (GetIsEffectValid(eTest) && bRet == TRUE )
        {
            nType = GetEffectType(eTest);
            if (nType == EFFECT_TYPE_STUNNED || nType == EFFECT_TYPE_PARALYZE  ||
                nType == EFFECT_TYPE_SLEEP || nType == EFFECT_TYPE_PETRIFY  ||
                nType == EFFECT_TYPE_CHARMED  || nType == EFFECT_TYPE_CONFUSED ||
                nType == EFFECT_TYPE_FRIGHTENED || nType == EFFECT_TYPE_SLOW )
            {
                bRet = FALSE;
            }

            eTest = GetNextEffect(oTarget);
        }
    }

    if (GetHasSpellEffect(727,oTarget)) // already antimagic
    {
        bRet = FALSE;
    }

    return bRet;
}


void OpenAntiMagicEye (object oTarget)
{
   if (GetAntiMagicRayMakesSense(oTarget))
   {
        ActionCastSpellAtObject(727 , GetSpellTargetObject(),METAMAGIC_ANY,TRUE,0, PROJECTILE_PATH_TYPE_DEFAULT,TRUE);
   }
}

// being a badass beholder, we close our antimagic eye only to attack with our eye rays
// and then reopen it...
void CloseAntiMagicEye(object oTarget)
{
    RemoveSpellEffects (727,OBJECT_SELF,oTarget);
}


// stacking protection
int BehDetermineHasEffect(int nRay, object oCreature)
{
  switch (nRay)
  {
      case BEHOLDER_RAY_FEAR :      if (GetHasEffect(EFFECT_TYPE_FRIGHTENED,oCreature))
                                        return TRUE;

      case BEHOLDER_RAY_DEATH :     if (GetIsDead(oCreature))
                                        return TRUE;

      case BEHOLDER_RAY_CHARM:      if (GetHasEffect(EFFECT_TYPE_CHARMED,oCreature))
                                        return TRUE;

      case BEHOLDER_RAY_SLOW:       if (GetHasEffect(EFFECT_TYPE_SLOW,oCreature))
                                        return TRUE;

      case BEHOLDER_RAY_PETRI:      if (GetHasEffect(EFFECT_TYPE_PETRIFY,oCreature))
                                        return TRUE;
  }
    return FALSE;
}


int BehGetTargetThreatRating(object oTarget)
{
    if (oTarget == OBJECT_INVALID)
    {
        return 0;
    }

    int nRet = 20;

    if (GetDistanceBetween(oTarget,OBJECT_SELF) <5.0f)
    {
        nRet += 3;
    }

    nRet += (GetHitDice(oTarget)-GetHitDice(OBJECT_SELF) /2);

    if (GetPlotFlag(oTarget)) //
    {
        nRet -= 6 ;
    }

    if (GetMaster(oTarget)!= OBJECT_INVALID)
    {
        nRet -= 4;
    }

    if (GetHasEffect(EFFECT_TYPE_PETRIFY,oTarget))
    {
        nRet -=10;
    }

    if (GetIsDead(oTarget))
    {
        nRet = 0;
    }

    return nRet;

}

struct beholder_target_struct GetRayTargets(object oTarget)
{
    struct beholder_target_struct stRet;
    int nTh = 1;

    object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_DOES_NOT_HAVE_SPELL_EFFECT,SPELL_ETHEREALNESS);
     while(GetIsObjectValid(oEnemy))
     {
      if(!GetIsDead(oEnemy))
      {
      stRet.nCount+= 1;
       switch(stRet.nCount)
       {
           case 1:
           stRet.oTarget1 = oEnemy;
           stRet.nRating1 = BehGetTargetThreatRating(oEnemy);
           break;
           case 2:
           stRet.oTarget2 = oEnemy;
           stRet.nRating2 = BehGetTargetThreatRating(oEnemy);
           break;
           case 3:
           stRet.oTarget3 = oEnemy;
           stRet.nRating3 = BehGetTargetThreatRating(oEnemy);
           break;
       }
      }
     oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,++nTh,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_DOES_NOT_HAVE_SPELL_EFFECT,SPELL_ETHEREALNESS);
     }
    return stRet;
}


void BehDoFireBeam(int nRay, object oTarget)
{
    // don't use a ray if the target already has that effect
    if (BehDetermineHasEffect(nRay,oTarget))
    {
        return;
    }

    int bHit   = TouchAttackRanged(oTarget,FALSE)>0;
    int nProj;
    switch (nRay)
    {
        case BEHOLDER_RAY_DEATH: nProj = 776;
                            break;
        case BEHOLDER_RAY_TK:    nProj = 777;
                            break;
        case BEHOLDER_RAY_PETRI: nProj = 778;
                            break;
        case BEHOLDER_RAY_CHARM: nProj = 779;
                            break;
        case BEHOLDER_RAY_SLOW:  nProj = 780;
                            break;
        case BEHOLDER_RAY_WOUND: nProj = 783;
                            break;
        case BEHOLDER_RAY_FEAR:  nProj = 784;//1.71: spell constant corrected
                            break;
    }

    if (bHit)
    {
         ActionCastSpellAtObject(nProj,oTarget,METAMAGIC_ANY,TRUE,0,PROJECTILE_PATH_TYPE_DEFAULT,TRUE);
    }
        else
    {
        location lFail = GetLocation(oTarget);
        vector vFail = GetPositionFromLocation(lFail);

        if (GetDistanceBetween(OBJECT_SELF,oTarget) > 6.0f)
        {

           vFail.x += IntToFloat(Random(3)) - 1.5;
           vFail.y += IntToFloat(Random(3)) - 1.5;
           vFail.z += IntToFloat(Random(2));
           lFail = Location(GetArea(oTarget),vFail,0.0f);

        }
        //----------------------------------------------------------------------
        // if we are fairly near, calculating a location could cause us to
        // spin, so we use the same location all the time
        //----------------------------------------------------------------------
        else
        {
              vFail.z += 0.8;
              vFail.y += 0.2;
              vFail.x -= 0.2;
        }
        //1.71: changed to real spell as fake spells cannot be cast instantly
        ActionCastSpellAtLocation(nProj,lFail,METAMAGIC_ANY,TRUE,PROJECTILE_PATH_TYPE_DEFAULT,TRUE);
    }
}
//::///////////////////////////////////////////////
//:: Beholder Ray Attacks
//:: x2_s2_beholdray
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Implementation for the new version of the
    beholder rays, using projectiles instead of
    rays
*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-09-16
//:://////////////////////////////////////////////
/*
Patch 1.71

- added proper saving throw type into death, charm and fear bolt
- protected against action cancel
*/

#include "x0_i0_spells"

void DoBeholderPetrify(int nPower, object oSource, object oTarget, int nSpellID);

void main()
{
    int     nSpell = GetSpellId();
    object  oTarget = GetSpellTargetObject();
    if(!GetIsObjectValid(oTarget))
    {
        return;//ray missed
    }
    int     nSave, bSave, nSaveType = SAVING_THROW_TYPE_NONE;
    int     nSaveDC = 15;
    float   fDelay  = 0.0;  //old -- GetSpellEffectDelay(GetLocation(oTarget),OBJECT_SELF);
    effect  e1, eLink, eVis, eDur;

    switch (nSpell)
    {
        case 776:
                                  nSave = SAVING_THROW_FORT;      //BEHOLDER_RAY_DEATH
                                  nSaveType = SAVING_THROW_TYPE_DEATH;
                                  break;
        case 777:
                                  nSave = SAVING_THROW_WILL;     //BEHOLDER_RAY_TK
                                  break;
        case 778:                                              //BEHOLDER_RAY_PETRI
                                  nSave = SAVING_THROW_FORT;
                                  break;
        case 779:                                                   // BEHOLDER_RAY_CHARM
                                  nSave = SAVING_THROW_WILL;
                                  nSaveType = SAVING_THROW_TYPE_MIND_SPELLS;
                                  break;
        case 780:                                                   //BEHOLDER_RAY_SLOW
                                  nSave = SAVING_THROW_WILL;
                                  break;
        case 783:
                                  nSave = SAVING_THROW_FORT;        //BEHOLDER_RAY_WOUND
                                  break;
        case 784:                                                   // BEHOLDER_RAY_FEAR
                                  nSave = SAVING_THROW_WILL;
                                  nSaveType = SAVING_THROW_TYPE_FEAR;
                                  break;
        case 785:
        case 786:
        case 787:
    }

    SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, nSpell, TRUE));

    if(!MySavingThrow(nSave, oTarget, nSaveDC, nSaveType, OBJECT_SELF, fDelay))
    {

      switch (nSpell)
      {
          case 776:                e1 = EffectDeath(TRUE);
                                   eVis = EffectVisualEffect(VFX_IMP_DEATH);
                                   eLink = EffectLinkEffects(e1,eVis);
                                   ApplyEffectToObject(DURATION_TYPE_INSTANT,eLink,oTarget);
                                   break;
          case 777:                e1 = ExtraordinaryEffect(EffectKnockdown());
                                   eVis = EffectVisualEffect(VFX_IMP_STUN);
                                   ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
                                   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,6.0);
                                   break;
          // Petrify for one round per SaveDC
          case 778:                eVis = EffectVisualEffect(VFX_IMP_POLYMORPH);
                                   ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
                                   DoBeholderPetrify(nSaveDC,OBJECT_SELF,oTarget,nSpell);
                                   break;
          case 779:                e1 = EffectCharmed();
                                   eVis = EffectVisualEffect(VFX_IMP_CHARM);
                                   ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
                                   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,24.0);
                                   break;
          case 780:                e1 = EffectSlow();
                                   eVis = EffectVisualEffect(VFX_IMP_SLOW);
                                   ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
                                   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,RoundsToSeconds(6));
                                   break;
          case 783:                e1 = EffectDamage(d8(2)+10);
                                   eVis = EffectVisualEffect(VFX_COM_BLOOD_REG_RED);
                                   ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
                                   ApplyEffectToObject(DURATION_TYPE_INSTANT,e1,oTarget);
                                   break;
          case 784:                e1 = EffectFrightened();
                                   //eVis = EffectVisualEffect(VFX_IMP_FEAR_S); //invalid vfx
                                   eDur = EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR);
                                   e1 = EffectLinkEffects(eDur,e1);
                                   //ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oTarget);
                                   ApplyEffectToObject(DURATION_TYPE_TEMPORARY,e1,oTarget,RoundsToSeconds(1+d4()));
                                   break;
       }

    }
    else
    {
        switch (nSpell)
        {
               case 776:         e1 = EffectDamage(d6(3)+13);
                                 eVis = EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY);
                                 eLink = EffectLinkEffects(e1,eVis);
                                 ApplyEffectToObject(DURATION_TYPE_INSTANT,eLink,oTarget);
        }
    }
}

void DoBeholderPetrify(int nPower, object oSource, object oTarget, int nSpellID)
{
    // * exit if creature is immune to petrification
    if(spellsIsImmuneToPetrification(oTarget))
    {
        //engine workaround for immunity feedback
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSpellImmunity(nSpellID), oTarget, 0.01);
    }
    if(MyResistSpell(oSource,oTarget) > 0)
    {
        return;
    }
    float fDifficulty = 0.0;
    int bShowPopup = FALSE;
    effect ePetrify = EffectPetrify();
    // * calculate Duration based on difficulty settings
    switch(GetGameDifficulty())
    {
        case GAME_DIFFICULTY_VERY_EASY:
        nPower = nPower/2;
        case GAME_DIFFICULTY_EASY:
        case GAME_DIFFICULTY_NORMAL:
            fDifficulty = RoundsToSeconds(nPower < 1 ? 1 : nPower); // One Round per hit-die or caster level
        break;
        case GAME_DIFFICULTY_CORE_RULES:
        case GAME_DIFFICULTY_DIFFICULT:
            bShowPopup = TRUE;
        break;
    }

    effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE);
    effect eLink = EffectLinkEffects(eDur, ePetrify);

    // Do a fortitude save check
//    if(!MySavingThrow(SAVING_THROW_FORT, oTarget, nFortSaveDC, SAVING_THROW_TYPE_NONE, oSource))
    {
        // Save failed; apply paralyze effect and VFX impact
        /// * The duration is permanent against NPCs but only temporary against PCs
        if(GetIsPC(oTarget))
        {
            if(bShowPopup)
            {
                // * under hardcore rules or higher, this is an instant death
                ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget);
                DelayCommand(2.75, PopUpDeathGUIPanel(oTarget, FALSE , TRUE, 40579));
                // if in hardcore, treat the player as an NPC
                //bIsPC = FALSE;
                //fDifficulty = TurnsToSeconds(nPower); // One turn per hit-die
            }
            else
            {
                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDifficulty);
            }
        }
        else
        {
            ApplyEffectToObject(DURATION_TYPE_PERMANENT, eLink, oTarget);
            //----------------------------------------------------------
            // GZ: Fix for henchmen statues haunting you when changing
            //     areas. Henchmen are now kicked from the party if
            //     petrified.
            //----------------------------------------------------------
            if (GetAssociateType(oTarget) == ASSOCIATE_TYPE_HENCHMAN)
            {
                FireHenchman(GetMaster(oTarget),oTarget);
            }
        }
        // April 2003: Clearing actions to kick them out of conversation when petrified
        AssignCommand(oTarget, ClearAllActions(TRUE));
    }
}

Paha

Without looking through and making all comparisons, it could force far wider changes than just doing what they have, but yeah. Suggestion has already been heard.

I might even find myself checking the scripts over at some point and testing if it's possible to make changes and additions without conflicting with our own systems.

I can promise you this. If it happens, it'll be somewhere on the end side of the summer months. It is not gonna get changed anytime soon.