Aller au contenu

Photo

MySavingThrow Function - Immunity Question


  • Veuillez vous connecter pour répondre
47 réponses à ce sujet

#1
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi All,

EDIT: I believe this topic has now been answered and I make this post later on ....

OK, I have confirmed the following to date ..... for my hag gaze script called alb_hag_gaze, which is a simple rework of the normal death gaze script, and uses all the same resistance and save function checks.

1) If I call my script via ExecuteScript, then the immunity checks do not work when I wear an immunity to death item.

2) If I add the hag gaze to the spells.2da (say line 1713) and call this script using a line of code along the lines of: ActionCastSpellAtObject(1713, oPlayer, METAMAGIC_ANY, TRUE); then the immunity checks work.

Therefore, all I can conclude is that the immunity checks are made outside of scripting and if I design any new effects or spells that are not added to the spells.2da and thereafter called via normal spell calling methods, then I need to add trhe immunity checks manually. E.g. Creature AI scripts called via ExecuteScript require the extra checks adding.

ADDITIONAL INFO: The MySavingThrow functions do NOT check the immunity at this point. Immunity checks are hard-coded and only take place when condition 2 is met above. Using the same spell/effect scripts outside of condition 2 (when using ExecuteScript for example), will not allow the game to check for immunities.

Lance.

0 ------- 0

This is the original post that started this thread ....

Hi All,

I have noticed that the MySavingThrow function (on closer inspection) does not test for immunity very well. It says this in its description:

            /*
            If the spell is save immune then the link must be applied in order to get the true immunity
            to be resisted.  That is the reason for returing false and not true.  True blocks the
            application of effects.
            */

My concern is, however, that if a PC is immune to an effect (like death), then won't this simply mean the PC will always return as if failing their save, and, in this case, die?

I have noted that there a lot of uses of this function throughout the code. Can someone please put my mind at rest and confirm that immunity is checked/covered elsewhere in some other code (I cannot find it yet) ... or will I have to edit some code to fix these cases?

Thanks in advance.
Lance.

Modifié par Lance Botelle, 08 octobre 2011 - 08:22 .


#2
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
If you are immune, you cannot be harmed by such damage. Basically it's not broken at all. Well it is but it's not that which is the problem you are focusing on. If they are immune, the only issue is the message being sent to the player.

Saving throws completely block damage ( or they can do half, it varies ) but this is meaningless and send a message that the player saved.

Immunity allows you to take damage and ignore it, and when you take the damage you get a feedback message that you are immune. Yes this works fine.

However if you Save, and don't take damage, that means the player does not see any feedback about being immune and why would a player who is immune to something try to dodge. They do the superman bit when he's hit by bullets, he jumps in front of them. This makes feedback of a save not make sense, and you will see players complaining that their immunity is not working.

The goal is to make sure the player fails his save so it can be properly processed when the damage is applied and he can see a message that he is immmune instead of the save.

#3
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Hi Pain,

I tried a death immunity test, but this line of code failed to check against a Death Immunity caused by an amulet worn:

if(!MySavingThrow(SAVING_THROW_WILL, oTarget, 20, SAVING_THROW_TYPE_DEATH, OBJECT_SELF, fDelay))

Posted Image

Lance.

Modifié par Lance Botelle, 05 octobre 2011 - 06:18 .


#4
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
There is a parameter to effectdeath to ignore death immunity. This is there BECAUSE it's done at the engine level. Without that we used to have to remove any protection, or apply physical damage to the target to end up killing them.

I'd have to see what script is doing the above feedback to really respond, but i can say that applying the effectdeath to a target with the parameter to ignore immunity set to false, will be handled at the engine level and the target will get a message about not being affected. I think you need to look closer at what you are applying to the target, perhaps also test with death ward in place as there could be an issue with the item as well.

There are spells which don't work like this though - which sidestep death immunity like level drains and drowning and the like ( or my dm kill button ), for which you have to use that new parameter to effect death, apply enough damage, or the target will ignore them.

Note that i've redone all the "my" functions as part of the CSL, they are pretty much rubbish overall. But you don't want to change how that works, it's supposed to be like that or the feedback is wrong.

Modifié par painofdungeoneternal, 05 octobre 2011 - 08:22 .


#5
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

painofdungeoneternal wrote...

There is a parameter to effectdeath to ignore death immunity. This is there BECAUSE it's done at the engine level. Without that we used to have to remove any protection, or apply physical damage to the target to end up killing them.

I'd have to see what script is doing the above feedback to really respond, but i can say that applying the effectdeath to a target with the parameter to ignore immunity set to false, will be handled at the engine level and the target will get a message about not being affected. I think you need to look closer at what you are applying to the target, perhaps also test with death ward in place as there could be an issue with the item as well.

There are spells which don't work like this though - which sidestep death immunity like level drains and drowning and the like ( or my dm kill button ), for which you have to use that new parameter to effect death, apply enough damage, or the target will ignore them.

Note that i've redone all the "my" functions as part of the CSL, they are pretty much rubbish overall. But you don't want to change how that works, it's supposed to be like that or the feedback is wrong.


Hi Pain,

I took a standard Amulet of Health and added the "Immunity: Miscellaneous: Death Magic" property. I then have the following script (used via a creature AI script, but any other object can be set up to test if you like) - I have kept all the debug code in place - NOTE: THIS SCRIPT HAS MY FIX IN IT, BUT you should be able to test the same script with it removed (if you see what I mean). If I don't have the GetIsImmune check in place, then the PC will die if they fail the saving throw even with the amulet on. Also EffectDeath should not be ignoring immunity by default as far as I can see.:

[nwscript]// HAG EVIL EYE (DEATH/MADNESS GAZE) x 3 / DAY
#include "X0_I0_SPELLS"
void main()
{
 
SendMessageToPC(GetFirstPC(FALSE), "HAG EYE FIRED");
if(GZCanNotUseGazeAttackCheck(OBJECT_SELF)){return;}
 
 // DECLARE VARIABLES   
 location lSelf = GetLocation(OBJECT_SELF);
 
 // LOCATE A SINGLE GAZED ENEMY TARGET 
 object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, 20.0, lSelf, TRUE);
 
 while(oTarget != OBJECT_INVALID)
    {
        string sFMName = GetName(oTarget) + "_EYE"; // DIFFER FROM HORRIFIC SIGHT  
  
  if(GetIsEnemy(oTarget) && GetLocalInt(OBJECT_SELF, sFMName) == 0)
        {           
   SetLocalInt(OBJECT_SELF, sFMName, 1);
   SendMessageToPC(oTarget, "<<< HAG USES EVIL EYE ON " + GetStringUpperCase(GetName(oTarget)) + " >>>");
   
   // IMMUNITY CHECK
   SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELLABILITY_GAZE_DEATH));           
   int Immune = 0; if(GetIsImmune(oTarget, IMMUNITY_TYPE_DEATH, OBJECT_SELF)){Immune = 1;}
   
   //DEATH CHANCE FIRST           
            float fDelay = GetDistanceBetween(OBJECT_SELF, oTarget)/20;
           
   if(!MySavingThrow(SAVING_THROW_WILL, oTarget, 20, SAVING_THROW_TYPE_DEATH, OBJECT_SELF, fDelay))
   {   
    if(Immune == 1){SendMessageToPC(GetFirstPC(FALSE), "IMMUNE TO HAG EYE DEATH EFFECT");}
    
    if(Immune == 0 && d100() < 26)
             {               
     //Apply the VFX impact and effects
     effect eGaze = EffectDeath();
        effect eVis = EffectVisualEffect(VFX_IMP_DEATH);
                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eGaze, oTarget));
             }
    
    // IF SAVE DEATH, THEN MAD
    else
    {
     SendMessageToPC(GetFirstPC(FALSE), "MADNESS");
     effect eMadness = EffectCurse(0,3,0,3,3,3);
     eMadness = SupernaturalEffect(eMadness);
     effect eVis = EffectVisualEffect(VFX_IMP_CONFUSION_S);
     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eMadness, oTarget));    
    }
   }
        }
       
  // ONLY ONE VALID TARGET PER GAZE
        else{oTarget = GetNextObjectInShape(SHAPE_SPHERE, 20.0, lSelf, TRUE);}
    } 
}[/nwscript]

My main concern, however, is that the function in question will return as if failing instead of giving an immune response. Therefore, to give the correct immune response (if the item immunity is also being ignored) needs to come before the check in most cases. In this case, the Hag's Eys effect has a secondary effect for those that do not die, so the coding is a little different.

EDIT: The GetIsImmune function can confirm the PC is immune, but the game fails to prevent the PC from dying with the default EffectDeath function applied to them if not checked for and prevented. Do you know where and how the NWN2 is now supposed to check for immunity? (I just reread your post and you said engine level.)

EDIT 2: I just did a test with the DEATH WARD spell and the PC still dies using this function as a saving test. The game does not appear to check for immunities (Death at any rate) and so a failed save is causing a death effect, even though the PC has immunity to death on them (item or spell) and the EffectDeath function is left at default not to ignore immunity. Posted Image

Lance.

Modifié par Lance Botelle, 05 octobre 2011 - 10:26 .


#6
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
Try the deathward spell instead of an item ( and actually test with no items ), see if it is working the same way. Try testing with a valid spell like finger of death, and edit it so it applies effectdeath() to the target with nothing else going on. What you are describing is contrary to all the testing and experience i've had, which tells me that effectdeath is not very good at killing targets.

Immunity items are not really something i give to players, so not sure on that - kind of negates the need for entire classes if you have items for every immunity you can imagine. I know certain items by default end up disabling immunity entirely ( some damage reduction/resistance for example at one time disabled the palemaster critical hit immunity, seemed like when this happened it short circuited a lot of engine code somehow, not even mentioning spell resistance )

Also invalid spells tend to bypass everything, especially cleric domain spells.

I do know that effectdeath() is not going to kill folks who are immune to death, unless that parameter is set to true - i am not sure if this is 100% true all the time, but i know that when i want effectdeath() to kill those immune, it seems reluctant to do so forcing me to apply getmaxhps in damage along with the regular effect ( at least until they added the parameter ). Immunity is deeper in.

I also know saving throws should fail if the target is immune, and give no feedback.

I also know myspellresist should return immunity or not, which is how MOST of the spells do this, but effectdeath() is going to usually not work on targets who are immune to death magic even without dealing with it in script. If you trace out spell resistance, it has a value it returns when the target is immune, and will then block the effect.

The engine will have areas which are just wonky, and really the best way to handle is just code it so it's not using the engine at all. I do this a lot. When in doubt, do it yourself - no question then how it work. Eventually you find some outlier case where things don't work as they should, at which point removing the engine entirely is required. The CSL library project started very small, but keeps growing as i find more issues in how things work - might be helpful to look at how i did my functions to replace mysavingthrow.

I think i have examples of similar logic, yes it gets very complicated. I actually developed some functions which store the fact if you saved or not, so you can deal with things like mettle and features from tome of battle, but this was driven by trying to move more such logic into the saving throw function as it was too hard to follow if it's in every spell. I then pass the constant value returned if it's full, partial or none, to other functions which can return partial damage, full damage, or no damage based on that save, and just reading the spell description i can apply effects based on if it's full, partial or none.

Note that the following will always return partial unless you have mettle.

//Make SR check
			if (!HkResistSpell(OBJECT_SELF, oTarget))
			{
				
				int iAdjustedDamage = HkIsDamageSaveAdjusted(SAVING_THROW_FORT, SAVING_THROW_METHOD_FORPARTIALDAMAGE, oTarget, HkGetSpellSaveDC(oCaster, oTarget), iSaveType, oCaster );
				if ( iAdjustedDamage >= SAVING_THROW_ADJUSTED_FULLDAMAGE )
				{
					HkApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oTarget);
				}
				else if ( iAdjustedDamage >= SAVING_THROW_ADJUSTED_PARTIALDAMAGE ) // partial damage is full hit point damage
				{
					//Roll damage
					iDamage = HkApplyMetamagicVariableMods(d6(3), 6 * 3)+ iSpellPower;
					//Set damage effect
					eDam = HkEffectDamage(iDamage, iDamageType);
					//Apply damage effect and VFX impact
					HkApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget);	
				}
				HkApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); // play the impact effect regardless of save
			}


#7
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages
Duplicate post

Modifié par Lance Botelle, 05 octobre 2011 - 11:02 .


#8
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

painofdungeoneternal wrote...

Try the deathward spell instead of an item ( and actually test with no items ), see if it is working the same way. Try testing with a valid spell like finger of death, and edit it so it applies effectdeath() to the target with nothing else going on. What you are describing is contrary to all the testing and experience i've had, which tells me that effectdeath is not very good at killing targets.<SNIP>


Hi Pain,

Thanks for your response again. I did test it with Death Ward spell as well, and the PC still died.
I think I may be forced to use the MyResistSpell function *before* the MySavingThrow function to ensure a immunity check is made first. I will check this later though, as it's bed time here now. ;) Finger of Death uses this function check prior to the saving throw check, which suggests it is needed when checking for immunities now.

However, if this does work (immunity checks OK), then I believe there may be a number of scripts that do not have the MyResistSpell function in place, which means editing a few more scripts to ensure immunity checks are made OK.

I took my lead for this script from nw_s1_gazedeath, which is just one example of the function missing (if proven to be required). Unless we are to assume that some death effects cannot be made immune to?

Anyway, I will test the script again later with the MyResistSpell function in place and look at editing all thoise scripts with it missing - which will lead me back to my first post questions - Is anybody aware of other scripts that fail to respond correctly to immunities - i.e. Have the MyResistSpell function missing!

Lance.

#9
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
I'd say the biggest thing i did for CSL was just go thru, find an issue, and then make sure all of the scripts have the same correction. My hunch is that a lot of the scripts won't have this going on, and you have to go thru with a search tool to find them. Feedback about known issues tends to be random, and the only way to root out the entire issue is to examine all of the scripts.

The spell you are using, is a monster feat, those are nowhere near as well done as the actual spells. I don't think mine is any different.

However that function does 4 jobs
spell resistance
mantles
immunities general
immunitiy to a specific spell or school
( and i dropped in spell turning as well )

Adding myresistspell to some spells ( like the ones that do acid damage, or that conjure real effects and spell resistance do not ignore ) will cause how the game works to be incorrect. I've created 4 separate functions inside of hkresistspell which allow you to just check for immunity, you probably want to handle it that way instead of doing a full spell resistance check ( which also removes any spell resistance as a side effect ).

#10
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

painofdungeoneternal wrote...

I'd say the biggest thing i did for CSL was just go thru, find an issue, and then make sure all of the scripts have the same correction. My hunch is that a lot of the scripts won't have this going on, and you have to go thru with a search tool to find them. Feedback about known issues tends to be random, and the only way to root out the entire issue is to examine all of the scripts.

The spell you are using, is a monster feat, those are nowhere near as well done as the actual spells. I don't think mine is any different.

However that function does 4 jobs
spell resistance
mantles
immunities general
immunitiy to a specific spell or school
( and i dropped in spell turning as well )

Adding myresistspell to some spells ( like the ones that do acid damage, or that conjure real effects and spell resistance do not ignore ) will cause how the game works to be incorrect. I've created 4 separate functions inside of hkresistspell which allow you to just check for immunity, you probably want to handle it that way instead of doing a full spell resistance check ( which also removes any spell resistance as a side effect ).


Hi Pain,

I hear what you are saying about the MyResistSpell function ... in that it checks more than just immunities and may prevent some actual effects from working that still should.

In that case, I may just stick to editing individual scripts as I come across them - and just add a simple if immune check.

I do like the idea of your functions, but it would involve adding a few include libraries I guess and familiarising myself with them - and then making sure everything else worked that I have already done. I could have used them about four years ago. Posted Image 

I do appreciate the fact that you are very well attuned to the script errors though and always respect the answers you unravel. It makes me feel  as though I am not alone in this kind of thing. Posted Image Please let me know if you discover anything else with respects to creature/spell immunities that may need addressing. I now kow I have to consder the gaze effects, but there are bound to be others.

Many Thanks.
Lance.

#11
kevL

kevL
  • Members
  • 4 052 messages
Lance,

try it using a Scarab of Greater Protection.

It has Immunity: Miscellaneous: Death Magic (among others). I say because i just loaded up a hezrou, gave it Gaze, Death (#253, SPELLABILITY_GAZE_DEATH), gave it a special combat AI script to chain cast at PC (set the DC up to 30* too, to make sure my Paladin 15 had some failed saves). And sure enough, got the failed save message immediately followed by Immunity to Death Magic message.

as advertised ( i don't believe i have anything special in Override concerning this )


* NW_S1_GazeDeath, spellscript

Modifié par kevL, 07 octobre 2011 - 09:35 .


#12
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages

Lance Botelle wrote...
I do like the idea of your functions, but it would involve adding a few include libraries I guess and familiarising myself with them - and then making sure everything else worked that I have already done. I could have used them 


Suggest downloading, and reading the relevant functions i've written. Would save you a lot of time discussing this, and you probably would notice many issues you've not even considered yet. A discussion like this is just not a good means for me to pass on my experience, most of which you'd notice by studying my code, just like i study the code of others. Posts like this are great for a beginners, but what is being discussed are not beginner issues. ( there is a point at which a beginner starts being dangerous actually  :) )

My work does not have to be used directly, it's very valuable if you just use it as a reference, or if you steal particular lines as needed for what you are doing. ( What i have is  a full library stack, other scripters have developed their own of similar size and it does not make sense to replace theirs with mine, and it sounds like you want to invent your own entire stack so you know how it all works. Just whatever you do, DO NOT ASSUME ANY CODE THAT SHIPS WITH THE GAME WORKS AS DESCRIBED, make your own library and rewrite all of it you need instead of just including it. ).

#13
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

kevL wrote...

Lance,

try it using a Scarab of Greater Protection.

It has Immunity: Miscellaneous: Death Magic (among others). I say because i just loaded up a hezrou, gave it Gaze, Death (#253, SPELLABILITY_GAZE_DEATH), gave it a special combat AI script to chain cast at PC (set the DC up to 30* too, to make sure my Paladin 15 had some failed saves). And sure enough, got the failed save message immediately followed by Immunity to Death Magic message.

as advertised ( i don't believe i have anything special in Override concerning this )


* NW_S1_GazeDeath, spellscript


Hi KevL,

Thanks for this example. I will check this myself and try to figure out where the check is made. It may well have something to do with the Immunity column in the spells.2da then. Although, I am sure that said immune to "negative" rather than "death". Maybe (in this case), "death" is a subset of "negative"?

Lance.


painofdungeoneternal wrote...

Suggest downloading, and reading the relevant functions i've written. Would save you a lot of time discussing this, and you probably would notice many issues you've not even considered yet. A discussion like this is just not a good means for me to pass on my experience, most of which you'd notice by studying my code, just like i study the code of others. Posts like this are great for a beginners, but what is being discussed are not beginner issues. ( there is a point at which a beginner starts being dangerous actually :) )

My work does not have to be used directly, it's very valuable if you just use it as a reference, or if you steal particular lines as needed for what you are doing. ( What i have is a full library stack, other scripters have developed their own of similar size and it does not make sense to replace theirs with mine, and it sounds like you want to invent your own entire stack so you know how it all works. Just whatever you do, DO NOT ASSUME ANY CODE THAT SHIPS WITH THE GAME WORKS AS DESCRIBED, make your own library and rewrite all of it you need instead of just including it. ).


Hi Pain,

I take your point. I suppose I was hoping more of the OC code worked better than it perhaps does. Although, I should realise from my own experiences and a fair amount of rewrite already that this will probably not be the case. And as you say, there are probably quite a few other points I have not yet considered. It's almost too scary to contemplate! Posted Image

Maybe I will try to check out your libraries again ... although it may be too unsettling to discover what you have already unraveled. It might freeze my work with despair! Posted Image

Lance.

#14
kevL

kevL
  • Members
  • 4 052 messages

Lance Botelle wrote...

It may well have something to do with the Immunity column in the spells.2da then. Although, I am sure that said immune to "negative" rather than "death". Maybe (in this case), "death" is a subset of "negative"?

uhm, i doubt it. In fact when i first saw "Negative" I went Aha! thinking that be the culprit you're experiencing .. I'd just like to see that column implemented somehow because it seems both useful and accessible.

here are some other thoughts i had, how useful they are is up to the reader (it bounces off something MasterChanger said in General):

- the odd thing is, (in nwscript.nss) there are ~20 SAVING_THROW_TYPE_* constants but ~30 IMMUNITY_TYPE_* constants, and many don't match up :\\

for example, there is IMMUNITY_TYPE_KNOCKDOWN, but no corresponding constant for when a Save is being made (in a hypothetical Knockdown script)


maybe this is something we can use to decide when a spellscript routine needs to have that extra bit of code to check for immunity

Ie, if there is a SAVING_THROW_TYPE_DEATH (which there is ..) then Can it be relied on in the MySavingThrow function to check for IMMUNITY_TYPE_DEATH ?

#15
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

kevL wrote...

Lance Botelle wrote...

It may well have something to do with the Immunity column in the spells.2da then. Although, I am sure that said immune to "negative" rather than "death". Maybe (in this case), "death" is a subset of "negative"?

uhm, i doubt it. In fact when i first saw "Negative" I went Aha! thinking that be the culprit you're experiencing .. I'd just like to see that column implemented somehow because it seems both useful and accessible.

here are some other thoughts i had, how useful they are is up to the reader (it bounces off something MasterChanger said in General):

- the odd thing is, (in nwscript.nss) there are ~20 SAVING_THROW_TYPE_* constants but ~30 IMMUNITY_TYPE_* constants, and many don't match up :

for example, there is IMMUNITY_TYPE_KNOCKDOWN, but no corresponding constant for when a Save is being made (in a hypothetical Knockdown script)


maybe this is something we can use to decide when a spellscript routine needs to have that extra bit of code to check for immunity

Ie, if there is a SAVING_THROW_TYPE_DEATH (which there is ..) then Can it be relied on in the MySavingThrow function to check for IMMUNITY_TYPE_DEATH ?


Hi KevL

COPIED FROM ANOTHER POST

EDIT: The following assumptions I made here are wrong. I leave them in for continuity of reading only. The IMMUNITYTYPE column played no part in the result. See later posts.

It seems that item immunities are determined by the spells.2da rather than through scripts!

There are obviously some hard coded aspects for testing immunity as determined by the IMMUNITYTYPE column in the spells.2da. I was totally unaware of thsi aspect, which was pointed out to me by KevL. In other words, when a spell (or effect like Death Gaze) is cast, there is a reference in the spells.2da that checks to see if the PC has a form of immunity on them and then gives immunity feedback accordingly.

My only confusion at this stage is what differntiates between being immune to "negative" effects and "death" effects. Is "death" a subset of the "negative" effects?

If this was known already, then sorry to have taken up so much of people's time in my ignorance. Posted Image

The bottom line is then, for me to add an effect or spell and ensure it works against immunity checks, I need to add the spell/effect as a line in the spells.2da and add an immunity value!

Did you know this is how it worked?

Do you know the difference between the "negaive" and "death" values for the spells.2da?

Many thanks.

Lance.

EDIT: At least, this is how it seems to work to me, as I cannot see anything in the NW_S1_GazeDeath script that checks for immunity .. and my own script, which is based on this script, fails to check for immunity, whereas, this official script (that has a spells.2da row with IMMUNITY TYPE column) does work!

Modifié par Lance Botelle, 08 octobre 2011 - 07:58 .


#16
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
Those developers had unlimited budgets and unlimited time to make everything perfect, and never rushed anything to get it to ship, it just is not reasonable for an amateur to do something better than those professionals, right?. Yeah that sounds like most game developers.

There is an assumption that if it's done officially it's better, when in fact it just means it's done well enough for the Atari QA people to not notice there is an issue. Perhaps they deleted the forums just to hide all the posts from users describing things those QA people somehow missed, or they did not want people to notice how much of the finished game was helped by Grinning Fool, Skywing, Rpgplayer1, TonyK, Kaedrin, and numerous detailed bug reports which included line numbers the devs should edit to fix the issues.

I think this is true with some games, where you have for the most part young kids who don't really try to do things right, but that is not the case in this community.

You will be far less frustrated if you avoid those 1000 files of largely undocumented libraries that come with the OC in the long run, and work with the wider community where they've already solved/simplified issues which you can use as a base to build on top of. Great as a learning exercise, but not the most effective in getting things done, and not an example i'd want anyone to follow if they are learning.

#17
mogromon

mogromon
  • Members
  • 41 messages
uhmmm, i've doing some tests with darkness, originally it did a resistspell(OBJECT_SELF,oTarget) check, but since OBJECT_SELF if used by AoE script means the object is the AoE it wasnt used correctly so i changed to oCreator and made some tests. In my spells.2da the ItemImmunity column for Darkness is set to 0 (so would think that no item is gonna make immune to that spell) and ImmunityType is set to ****. The point is if using oCreator and not using another spell (since it deletes the previous spell info, but there are workarounds for this) the player is immune to darkness if using Helm of Darkness (check before doing the changes and didnt work) so i dont think this colums are totally valid. You should stick to what pain said and use another checks. As far as i can tell Resistspell is a pretty good function for spell resist (using Reeron fix so it doesnt dissapear), spell absorption and specific spell immunity. It has some mistkes but a lot of them are fixed by community members.

Note: Immune to darkness means you dont get the concealmente effect, so fixing that in dakrness doesnt have a practical use, but i did it for testing purposes.

#18
kevL

kevL
  • Members
  • 4 052 messages
Lance

( *without wanting to get beat down by the programmer's stick* )

Maybe the reason your custom script doesn't check for immunity is because it isn't denoted as a "spellscript" - is this possible? Ie. that it is not necessarily a/the savingThrow function exclusively that makes the immunity check, but the fact your custom script has not been identified by Spells.2da ...

ps. I don't trust the ImmunityType column at all (for now).


Pain,
i've got CSL unzipped and look at it occasionally, but Lance is also right .. it's intimidating ;|


Like, a two-thousand headed hydra,

Edit insert -> should we be relying on a MyResist function to do immunity checks, instead?



pps. mogro, Tks for the heads-up. /sigh

Modifié par kevL, 08 octobre 2011 - 08:56 .


#19
BartjeD

BartjeD
  • Members
  • 249 messages
I've written a replacement function that completely replaces the stock NWN2 spell resisting function and I found that works pretty well. Just needed to work in an alternative way to deal with spell absorption effects and immunities because it doesn't check for them unless the native SR function is used.

You could do the same with a saving throw function except you probably need to make a list of spells with the "death" descriptor to check against. Effects aren't given an Effect Type until applied so it's not really possible to check through an effect applying wrapper function and just not apply the effect if you are immune.

For the new saving throw check you'd have to recompile all spells to use it but I think you're doing that now anyway.

#20
kevL

kevL
  • Members
  • 4 052 messages
yep. thanks for the tips, BD.

if it comes to it, I'll be taking a long hard look through CSL (because ultimately i believe it solves these issues, whatever those actually are!)


but yeh, good idea & will keep in mind .. *toss to Lance et al.*

#21
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
Perhaps you should just look at this -> documentation instead of the unzipped files. Then go ahead and delete ALL the folders except the folder CSLLibrary as the rest are just implementation scripts. Those are just there if you want to use my spell scripts.

It describes where files are, and includes a search function as well, dependencies, and you can click on any function and get it's documentation. The fact i've written descriptions on most of the functions, including the core game functions, well often i am just copy pasting answers from my documentation into the forums here.

You have to consider what you are comparing this to. This project is aimed at fixing NWN2 as a whole, it's not aimed at doing some trivial little project to implement one stand alone feature. It's goal is to make the spells, feats, and the worlds work better, and replace thousands of bugs in the game, and in fact replace the 1000 strands of spaghetti includes, with a single simpler system with some synergy which also ends up using less CPU.

Remember my library is doing the same job as the scripts that come with the game. That much larger library of scripts is not easy to find functions in, are not organized, poorly documented, include functions that were designed for baldurs gate, NWN1 and older games. The way things include every time you include a single file you can actually be including 500 files with a strong chance of a recursive include. There are major crash inducing bugs in them as well which are almost impossible to diagnose - it can take a few weeks to sort out each issue.

Sure it's different, everything new requires learning. However eventually you will realize that the scripts provided with the game do not work and you either need to use something like the CSL or rewrite all of the includes yourself. For the most part finding a function in CSL and using it, is not that much different than using the core game includes.

#22
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

mogromon wrote...

uhmmm, i've doing some tests with darkness, originally it did a resistspell(OBJECT_SELF,oTarget) check, but since OBJECT_SELF if used by AoE script means the object is the AoE it wasnt used correctly so i changed to oCreator and made some tests. In my spells.2da the ItemImmunity column for Darkness is set to 0 (so would think that no item is gonna make immune to that spell) and ImmunityType is set to ****. The point is if using oCreator and not using another spell (since it deletes the previous spell info, but there are workarounds for this) the player is immune to darkness if using Helm of Darkness (check before doing the changes and didnt work) so i dont think this colums are totally valid. You should stick to what pain said and use another checks. As far as i can tell Resistspell is a pretty good function for spell resist (using Reeron fix so it doesnt dissapear), spell absorption and specific spell immunity. It has some mistkes but a lot of them are fixed by community members.

Note: Immune to darkness means you dont get the concealmente effect, so fixing that in dakrness doesnt have a practical use, but i did it for testing purposes.


Hi mogromon,

I recall there was a problem with the darkness spell, which had a fix to see if you were wearing the Helm of Darkness. As Pain would indicate, it was very much a "quick fix" solution. However, I am not sure if this can be "fixed" any other way because I have the impression that the code outside of our hands has an error in it with respect to the Darkness immunity check. (There may even be others, but I have not checked every spell immunity that can be placed on an item.) However, I am also under the impression that individual spell immunity is handled differently from "effect" immunity, like death as an example. For instance, the IMMUNITYTYPE column only appears to accept effect type immunities and not individual spell types. And I believe the ITEMIMMUNITY means that the IMMUNITYTYPE can be placed on an item. So, you cannot add an immunity to darkness (an individual spell) neither allow it to either add to an item or not in the first place.

Maybe the reason your custom script doesn't check for immunity is because it isn't denoted as a "spellscript" - is this possible? Ie. that it is not necessarily a/the savingThrow function exclusively that makes the immunity check, but the fact your custom script has not been identified by Spells.2da ...

ps. I don't trust the ImmunityType column at all (for now).

LATER POST: if it comes to it, I'll be taking a long hard look through CSL (because ultimately i believe it solves these issues, whatever those actually are!)


Hi KevL,

Anything is possible at the moment. Posted Image Later on I am going to test my current theory (that the spell has to be defined in the spells.2da with the IMMUNITYTYPE column having a value of "Negative" to see if the spell is thereafter checked for immnunity items. If that works, then "great", if not, then I am back to having to either "patch" every spell I make with my own checks or different functions ... or maybe try opening the "Tome of Pain", both literally and metaphorically ... as it's Pain's great CSL and not something I really want to do unless I really have to.

Don't misunderstand me, I think the work is truly excellent, but it would take me some time to start to get my head around what he has done. As you say in another post, it is somewhat "intimidating". Posted Image Like you, however, the days are drawing closer when I may well have to try to take a closer look at Pain's CSL.


BartjeD wrote...

I've written a replacement function that completely replaces the stock NWN2 spell resisting function and I found that works pretty well. Just needed to work in an alternative way to deal with spell absorption effects and immunities because it doesn't check for them unless the native SR function is used.

You could do the same with a saving throw function except you probably need to make a list of spells with the "death" descriptor to check against. Effects aren't given an Effect Type until applied so it's not really possible to check through an effect applying wrapper function and just not apply the effect if you are immune.

For the new saving throw check you'd have to recompile all spells to use it but I think you're doing that now anyway.


Hi BartjeD ,

It may well be my problem that the script providing the death gaze is in a wrapper - I am going to try a few things first. Also, have you seen Pain's massive CSL project? - it covers the sort of thing you mention.

painofdungeoneternal wrote...

Perhaps you should just look at this -> documentation instead of the unzipped files. Then go ahead and delete ALL the folders except the folder CSLLibrary as the rest are just implementation scripts. Those are just there if you want to use my spell scripts.

It describes where files are, and includes a search function as well, dependencies, and you can click on any function and get it's documentation. The fact i've written descriptions on most of the functions, including the core game functions, well often i am just copy pasting answers from my documentation into the forums here.

You have to consider what you are comparing this to. This project is aimed at fixing NWN2 as a whole, it's not aimed at doing some trivial little project to implement one stand alone feature. It's goal is to make the spells, feats, and the worlds work better, and replace thousands of bugs in the game, and in fact replace the 1000 strands of spaghetti includes, with a single simpler system with some synergy which also ends up using less CPU.

Remember my library is doing the same job as the scripts that come with the game. That much larger library of scripts is not easy to find functions in, are not organized, poorly documented, include functions that were designed for baldurs gate, NWN1 and older games. The way things include every time you include a single file you can actually be including 500 files with a strong chance of a recursive include. There are major crash inducing bugs in them as well which are almost impossible to diagnose - it can take a few weeks to sort out each issue.

Sure it's different, everything new requires learning. However eventually you will realize that the scripts provided with the game do not work and you either need to use something like the CSL or rewrite all of the includes yourself. For the most part finding a function in CSL and using it, is not that much different than using the core game includes.


Hi Pain,

From my own experiences with Obsidian code, I do truly appreciate what your project involves and is aimed at. Posted Image And it is still always in my mind to look and use. Part of my problem is knowing which bits are required to do what I need to do. (I would obviously like to use all of it at some point.) Your page layout is also a little complicated to me at the moment. (I'm not a programmer, but a hobbyist who likes to dabble in programming. Posted Image)

As you say, to get to grips with your CSL would require me to spend some time trying to understand your "approach" and how you have set it out. For instance, I thought there would simply be a page that listed the include files, which if clicked on, would show them in the standard NWN format, which I could copy and paste into an include within my own module, and thereafer use the functions it included (assuming they did not require links to other includes you have written). Currently, while I can see many useful bits of code, I do not really understand how to implement them as easy as I just explained. Posted Image

And I was concerned that I would be asking you too many "stupid" questions to resolve something that might appear an easy fix. Posted Image Basically, I have a great deal of respect for what you are doing, and did not want to compromise your presentation (which may be how its supposed to be done) by asking you to put together a "dummies" version. If, however, what I said makes any sense, and you appreciate what I am trying to say about making your code more accessible (by making it easier to recognise how it fits with my own needs), then I would jump at the chance. Posted Image

It needs a "user friendly" front end on your website to make it more accessible to the hobbyist programmers. I would be more than willing to go through this with you (via email communications, diagrams, etc), if you wanted to consider helping out in that way. By doing so, I am sure you would reach a larger target audience willing to implement it straight away! Bear in mind that I may not even be describing myself correctly, but there must be a difference because I understand (basically) scripting with NWN as it currently stands, but am thrown regarding easy implementation when I visit your site.

If you do want to consider this, let me know and maybe we can work something out - not just for me, but for others who also find your work too intimidating to consider at the moment. Posted Image

Lance.

Modifié par Lance Botelle, 08 octobre 2011 - 11:39 .


#23
BartjeD

BartjeD
  • Members
  • 249 messages

It may well be my problem that the script providing the death gaze is in a wrapper - I am going to try a few things first. Also, have you seen Pain's massive CSL project? - it covers the sort of thing you mention.


Hey Lance,

Yes I've seen Pain's work and its really well done but Last time I saw it that package was still using the default NWN2 SR function to handle Spell Absorption and Spell Immunity.

I didn't want to rely on the stock function anymore and do double checks, e.a. check for an effect to see if it's there and then run a function (stock SR function) that checks for an effect AGAIN and only then does happen something with it. That's a waste of computation power by running two loops instead of one.

On top of that the stock NWN2 function insists on sending it's own messages and will do a full SR check while my custom function already does that. The results are not identical so the player would get two divergent messages: one from the new SR checking function saying he resisted and one from the old one that errenously thought he had not resisted. (the stock NWN2 SR check is really weird - it often diverges from the expected result)

We've got this mechanic running on BGTSCC right now and it's more reliable than the stock function. Basically it's almost like pain's script except it doesn't use the stock function at all anymore. Plus we don't get those annoying double messages - just for that alone it's worth it because players get confused over those things and it looks sloppy.

----
For the Death Immunity I've read that multiple people have reported something like this - it may be related to only the item property immunity because Death spells do seem to get stoppped by other spells. Though that might be immunity to necromancy as well.

I think if you use immunity Necromancy it will work as intended but it might be simpler to just code in an Immunity check for  "death" into the spell / gaze itself.
Coding it in like that also means you won't have to mess with recompiling all the spell scripts. (unless you're already doing that)

Modifié par BartjeD, 08 octobre 2011 - 12:56 .


#24
Lance Botelle

Lance Botelle
  • Members
  • 1 480 messages

BartjeD wrote...

Hey Lance,

<SNIP>

We've got this mechanic running on BGTSCC right now and it's more reliable than the stock function. Basically it's almost like pain's script except it doesn't use the stock function at all anymore. Plus we don't get those annoying double messages - just for that alone it's worth it because players get confused over those things and it looks sloppy.

----
For the Death Immunity I've read that multiple people have reported something like this - it may be related to only the item property immunity because Death spells do seem to get stoppped by other spells. Though that might be immunity to necromancy as well.

I think if you use immunity Necromancy it will work as intended but it might be simpler to just code in an Immunity check for  "death" into the spell / gaze itself.
Coding it in like that also means you won't have to mess with recompiling all the spell scripts. (unless you're already doing that)


Hi BartjeD,

Is your BGTSCC code available for viewing?

Coding directly into the gaze script itself is probably the way I will do it. I have one more theory to test first.. Posted Image

Lance.

#25
BartjeD

BartjeD
  • Members
  • 249 messages
This is the code that deals with the Spell Immunity and Spell Absorption effects. (decrease levels left etc..)
I think this is what you need but I can also PM you the entire function if you want. (it might bloat the page)

http://pastebin.com/VbL3Lk97 - probably copy this into a script from the raw paste so it'll read better :)

You'll notice what I'm doing with the loop here, reading out the structure of the applied effects and using that as data for the function to see what should happen. This doesn't work for items though because items don't apply an effect on the player that will be returned this way (immunity: death or immunity: magic missile) - Instead you need to work around that as you can see at the bottom by detecting an item property on an equipped item.

Using the same kind of loop I can change an effect that is applied through an effect applying wrapper function. So I can tell it to switch damage cold to damage type fire, or not to apply to friendly target, or don't kill anyone or apply half damage as fire and half as cold etc.. Endless possibilities and it means I won't have to recode every spell with all these options. I can just do that through the effect applying wrapper instead from a central location.

We have that code currently online as well but the feats to use it still need to be added into the 2da, such as a mage's damage substitution or a High Arcana ability that allows you to not hurt friendlies that are in your spells and AOE's.
It's also quite a pickle to balance because a Frost Mage has the ability to ignore resistances with his Cold Spells but if he was to take Damage Subsitution Cold then he could suddenly be doing cold damage with a lot of spells (flame arrow etc..) which would then logically also have to ignore all resistances.


----
If you're interested I've also coded a Counterspelling system using the spell hook which works real neat. It allows both PC's and NPC's to do exactly as described in standard PnP for counterspelling. You can even counter dispels with other dispel spells. :lol:
It's also tested and online already but again - the feats to use it still need to be added. Much balance considerations to make on that. (Mastery Counterspelling for example turns back all counterspelled spells - that could be murderous)

Modifié par BartjeD, 08 octobre 2011 - 01:45 .