EFUPW Forums

Main Forums => Suggestions => Topic started by: Ook on May 04, 2014, 02:23:12 AM

Title: Beholder Rays
Post by: Ook on May 04, 2014, 02:23:12 AM
I've noticed the unfortunate tendency of beholders to target a single person in a crowd and blast them with six save rays in one round. While certainly very effective it doesn't really strike me as intended behavior that beholders are able to target every ray they have on one person all at once.

It would feel a lot more fair if the rays were spread out over the crowd of people if there are multiple targets available.
Title:
Post by: Stranger on May 04, 2014, 03:02:58 AM
[hide="Misleading Information"]During my recent visit to Chabzash, they were being randomly distributed among every enemy in range. Someone correct me if I'm wrong; I don't know what the AI looks like.

"Random" can pile on the hurt, however. It's not unheard of for a scythe-wielding NPC to critically hit and more than once.

...and if none of your friends are in targeting range...[/hide]
Title:
Post by: Black-Forest on May 04, 2014, 03:07:53 AM
Likewise it'd be nice if Saves vs. Death applied to the Beholder rays. Last I heard from someone who died to one, their +4 vs. death belt didn't work when hit with a Beholder's fort save or die.
Title:
Post by: Kotenku on May 04, 2014, 06:29:09 AM
It'd really be nice if beholder rays were somehow re-worked entirely, because it's long been an issue that they are buggy as hell.
Title:
Post by: Paha on May 04, 2014, 06:49:33 AM
They work as made in engine as far as I know. Not something we can easily change as it's probably quite bit hardcoded.

They are special attacks that target a small area and may hit one to three enemies, are touch attack based and will have dc 15 on any saving throw, and as they are not magic or such, they are not treated as something where saving throws vs. something will work against.

They are immensively dangerous. There is no easy immunity against the death ray either.
Title:
Post by: Damien on May 04, 2014, 01:44:30 PM
The death rays definitely need a change tbh, adding in vs death would be great. It is also near to never true that the rays split between 1-3 targets and the big problem with touch attacks is they are affected by lag. I've already died multiple times in the past to beholders standing there while I hit them then suddenly gunning off 12 rays in a single round. There is also another bug where sometimes beholders shoot two of those unblockable magic damage rays in one round, with ray doing a max 60 damage iirc.
Title:
Post by: John Doe on May 04, 2014, 03:35:38 PM
Check out the nwn wikia and search for Beholders, there is an elaborate article on the way the beholder special attack functions.
Title:
Post by: Knight Of Pentacles on May 04, 2014, 03:36:55 PM
Their rays are magical.  The beholder absorbs ambient magic from an area and projects it outward.  Hence the dead magic zones.
Title:
Post by: Gippy on May 04, 2014, 03:52:59 PM
Beholder attacks are touch attacks.

Beholder attacks take into effect spellcraft & saves vs spells.

I say this in that both those methods allow for various counters to beholders.

Move along! They are the great roulette wheels of the forgotten realms.
Title:
Post by: Mass Transit on May 04, 2014, 07:47:30 PM
Not -all- beholder attacks are touch attacks, The ones listed here (//%22http://nwn.wikia.com/wiki/Beholder_special_attacks%22) are not touch attacks, which are the ones this thread was made about. Additionally, not every type of ray takes into account spellcraft/spell saves. That being said, if there was a way to remove or fix the fear ray, which is broken and uses the wounding ray, it would be nice as beholders already dish out a ton of damage.
Title:
Post by: Paha on May 04, 2014, 08:03:05 PM
"Each ray uses a ranged touch attack to see if it hits. All saving throws have a DC of 15."
Title:
Post by: Mass Transit on May 04, 2014, 08:14:07 PM
These are rolls that I have never witnessed in the only means I have, the combat log.
Title:
Post by: Disco on May 04, 2014, 08:52:28 PM
Beholders are DANGEROUS. but it is defenatly possibly to kill them. Yes it hurts when all the rays hit you.
But do we really want to make them LESS dangerous? In that case we could also make drow sentry commanders crit less, or make orog warlords without insane ac, or.... The list is long.
The best part about fighting beholders is the thrill of knowing that you may be dead the next time it looks at you.
Title:
Post by: Ook on May 04, 2014, 09:10:52 PM
Quote from: Disco;386103Beholders are DANGEROUS. but it is defenatly possibly to kill them. Yes it hurts when all the rays hit you.
But do we really want to make them LESS dangerous? In that case we could also make drow sentry commanders crit less, or make orog warlords without insane ac, or.... The list is long.
The best part about fighting beholders is the thrill of knowing that you may be dead the next time it looks at you.

Well, all it does right now is encourage people not to fight them unless they have enough saves to be completely immune.

Where if you could mitigate some of the risk by staying in a crowd so you only had to make one save in a round as opposed to six then it might encourage more people to try their luck. Nobody's saying anything about removing the save or die attacks.
Title:
Post by: Disco on May 04, 2014, 09:26:19 PM
I see your point Ook. But I kinda like that most people avoide the beholders like the plague. They SHOULD be feared.
Title:
Post by: Paha on May 04, 2014, 09:51:58 PM
They indeed should be feared.

This really is unlikely to change, as for one it would require, most likely, quite a bit of trickery and what we'd at most would change and check is not something that would make this any less dangerous or easier for people, hence I doubt there would be any less feedback.

Someone might look at it as a side project over time, who knows.

I know I won't. My list is booked for the rest of the year.
Title:
Post by: AllMYBudgies on May 05, 2014, 07:21:49 AM
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.
Title:
Post by: Knight Of Pentacles on May 05, 2014, 07:28:03 AM
Maybe make a new spell or new potion that grants temporary immunity to petrification?
Title:
Post by: Paha on May 05, 2014, 07:59:33 AM
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.
Title:
Post by: The Man on May 05, 2014, 01:23:28 PM
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.
Title:
Post by: Kotenku on May 18, 2014, 10:16:26 PM
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));
    }
}
Title:
Post by: Paha on May 18, 2014, 10:52:55 PM
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.