GamerRick Posted August 6, 2022 Share Posted August 6, 2022 (edited) I would like to make any LGHT (Light) spells dispel NEYE (Night-eye) spells and vice versa. Same with WABR (Waterbreathing) and WAWA (Waterwalking). I tried to add them to each other's "Counter Effects", but cannot figure out how to actually do that in the MagicEffect editor pop-up. Is that possible? Would this make the spell dispel the spell that is in the list of Counter Effects? Another way may be to add a script to each MagicEffect that makes it dispel the other with (player.dispel NEYE). Is it possible to add a script to the four effects I want to change to dispel their counter effect? Or, a third way, is that I write a quest script that keeps track of when those spells are active on the player and dispels one when the other is detected. I know how to do this one, but can't stop thinking there has to be a simpler way. This was really easy to do in Skyrim BTW. Thanks!! Edited August 6, 2022 by GamerRick Link to comment Share on other sites More sharing options...
RomanR Posted August 7, 2022 Share Posted August 7, 2022 I too couldn't edit Counter Effects tab and even wiki doesn't mention it, so I think it's not editable by normal means. I have an idea of two things: 1. Add to each spell script effect part which use Script Effect Start block, IsSpellTarget and Dispell command. 2. With OBSE using GetMagicEffectCounters/SetMagicEffectCounters. Running quest and script will still be needed, but I think it would be necessary to run it only at restart of Oblivion, so this script can be very light on performance. Link to comment Share on other sites More sharing options...
GamerRick Posted August 12, 2022 Author Share Posted August 12, 2022 I gave up and just decided to do it the same way the cure disease spell works. I can't figure out how to make it work for crafted spells. Oh well. Link to comment Share on other sites More sharing options...
Pellape Posted August 14, 2022 Share Posted August 14, 2022 (edited) Anything is possible with scripts. Lets make 1 spell to start with. Describe exactly what you want it to do. Lets start with Waterwalking/Waterbreathing. To make it duration independent, make 2 abilities. We need a quest script or a global variable but a quest script is more suitable, well lets keep it simple. Make a Global variable called GamToggleWater, so click the menu GamePlay and Global Variables and rightclick and make a new Short Global Variable called GamToggleWaterGLOB or GamerToggleWaterGLOB. :smile: Make 2 abilities and call themGamWaterWalkSPLGamWaterBreathSPL Make a spell called GamToggleWaterSPL So lets make the script and make sure you save it as a Magic Effect, not Object Script. There is a pull down menu to toggle between them + Quest Scripts. As it is abilities, we do not need to cast them, just have them added and removed to and from the player. scn GamToggleWaterSCR Begin ScriptEffectStart If ( GamToggleWaterGLOB == 0 ) ;Removes all spells Player.RemoveSpell GamWaterWalkSPL Player.RemoveSpell GamWaterBreathSPL Set GamToggleWaterGLOB to 1 ElseIf ( GamToggleWaterGLOB == 1 ) ; Adds the Water walking, removes the Water Breathing Player.AddSpell GamWaterWalkSPL Player.RemoveSpell GamWaterBreathSPL Set GamToggleWaterGLOB to 2 Else ; Adds the Water Breathing, removes the Water Walking Player.RemoveSpell GamWaterWalkSPL Player.AddSpell GamWaterBreathSPL Set GamToggleWaterGLOB to 0 EndIf End No need to dispell anything with this setup, as the 2 spells are abilities. Edited August 14, 2022 by Pellape Link to comment Share on other sites More sharing options...
GamerRick Posted August 15, 2022 Author Share Posted August 15, 2022 (edited) I wanted to know if it was possible to put a Magic Effect Script on the MGEF item, so it would run whenever any spell with that effect ran. In turn, the ME Script would remove the other MGEF effect from the, it wouldn't matter if it were a spell I bought or crafted myself. I couldn't find a way to do this. I then tried to write a ME script that would loop through the active effects on the player, and remove the other effect (or dispel the Spell it came from), but I found no way to do this. So, I just did the thing I know how to do already, which is to write a ME Script that I would put on all standard NightEye spells that dispells all standard Light spells, and vice versa for Light Spells dispelling all NightEye Spells. It obviously won't work with crafted spells. I can't figure out how you would loop through the active effects that are one the player. I tested the various OBSE and vanilla commands that look they might work, but couldn't figure it out. One of the scripts I cam up with is this one: scn GRLightDispelNightEyeMEScript begin ScriptEffectStart player.Dispel GRNightEyeNovice ; My Novice spell player.Dispel StandardNightEye2Apprentice player.Dispel StandardNightEye3Journeyman player.Dispel GRStandardNightEye4Expert ; My Expert spell player.Dispel DarkNightEyes endIt's working great. I will just have ol' Edgar sell my new spells! Edited August 15, 2022 by GamerRick Link to comment Share on other sites More sharing options...
RomanR Posted August 15, 2022 Share Posted August 15, 2022 It seems that using OBSE's CounterEffect commands isn't way to go. I made script which adds counter effect to spell's Counter Effects field, but Oblivion is simply ignoring them. Oh well, here it is anyway - at least there are lines to convert the effect codes to string, so it can be still some worth. It's script for a spell and also straight copy from CS editor. scn RRSetCounterEffectScript short checked short found array_var c_effects string_var code string_var hex_code string_var ascii_code int ef_code int temp int char_pos int cut_right ref magiceffect ref magiceffect2 int size int index begin ScriptEffectStart ; first check, if counter effect is already set if checked == 0 let size := ar_Size c_effects if size == -1 let c_effects := ar_Construct array endif set found to 0 set magiceffect to LGHT ; light let c_effects := GetMagicEffectCounters magiceffect let size := ar_size c_effects if size > 0 ; test ;print "There are "+$size+" counter effect(s)." set index to 0 while index < size let ef_code := c_effects[index] let hex_code := NumToHex ef_code let ascii_code := "" ; convert it to readable ascii set char_pos to 0 while char_pos < 8 set cut_right to char_pos + 2 let code := hex_code if cut_right > char_pos && cut_right != 8 sv_Erase code cut_right endif if char_pos > 0 sv_Erase code 0 char_pos endif let ef_code := ToNumber $code 1 let code := AsciiToChar ef_code if eval (sv_Length ascii_code == 0) let ascii_code := $code else sv_Insert $code ascii_code 0 endif set char_pos to char_pos + 2 loop ; and check if eval (ascii_code == "NEYE") set found to 1 endif set index to index + 1 loop endif set checked to 1 endif ; setting counter effect for light if checked != 0 && found == 0 set magiceffect2 to NEYE AddMagicEffectCounter magiceffect2 magiceffect print "Night Eye is set as counter effect to Light." endif if checked && found print "Night Eye is already set as counter effect to Light." endif ; check for night eye set checked to 0 ar_Resize c_effects 0 set magiceffect to NEYE set found to 0 let c_effects := GetMagicEffectCounters magiceffect let size := ar_size c_effects if size > 0 ; test ;print "There are "+$size+" counter effect(s)." set index to 0 while index < size let ef_code := c_effects[index] let hex_code := NumToHex ef_code let ascii_code := "" ; convert it to readable ascii set char_pos to 0 while char_pos < 8 set cut_right to char_pos + 2 let code := hex_code if cut_right > char_pos && cut_right != 8 sv_Erase code cut_right endif if char_pos > 0 sv_Erase code 0 char_pos endif let ef_code := ToNumber $code 1 let code := AsciiToChar ef_code if eval (sv_Length ascii_code == 0) let ascii_code := $code else sv_Insert $code ascii_code 0 endif set char_pos to char_pos + 2 loop ; and check if eval (ascii_code == "LGHT") set found to 1 endif set index to index + 1 loop endif set checked to 1 ; setting counter effect if checked != 0 && found == 0 set magiceffect2 to LGHT AddMagicEffectCounter magiceffect2 magiceffect print "Light is set as counter effect to Night Eye." endif if checked && found print "Light is already set as counter effect to Night Eye." endif ; cleanup sv_Destruct code hex_code ascii_code ar_Resize c_effects 0 let c_effects := ar_Null end Link to comment Share on other sites More sharing options...
GamerRick Posted August 15, 2022 Author Share Posted August 15, 2022 (edited) I don't think it's possible given the commands we have: GetActiveEffectCount - Use this to loop through the Active Effects for each active effect on the player GetNthActiveEffectCode index - Get first next code (I could not get this command to work! I GOT 0 trying this) (Assuming there is a way to actually get the current code.....) If effect code == LGHT && (The effect came from a spell. IS THERE A WAY TO DO THIS?? Can't remove light effects from enchantments or portions afterall.)) DispelNthActiveEffect - Dispel the current active effect continue ; There should only be one light spell on the player endif loop Or Maybe you can get the spell this way??? GetNthActiveEffectMagicItem - Get the item that caused the Effect Does it return a ref to the SPELL if it came from a SPELL?? Is there a way to get the SPELL that the effect came from???? player.dispel that_SpellIt looks easy, but I could not make it work. I AM DONE WITH THIS!!!! I already exhausted the gumption and energy I had to try and figure it out, given that I was able to solve it the way I ended up doing it. If someone else would like to try, I need the actual code that will work to solve the actual problem I originally asked about. Thanks for trying though! Edited August 15, 2022 by GamerRick Link to comment Share on other sites More sharing options...
RomanR Posted August 16, 2022 Share Posted August 16, 2022 Ok, another one - this time it scans all active effects on target actor and if it finds active Night Eye effect from any source, it dispels all spells and lesser powers which contains Light effect. This script was made for external test spell, but I believe there will be no trouble to adapt it for quest or something else. So far testing gave good results and is working also for crafted spells (as long they're using standard Magic Effects). scn RRDispelLightScript array_var activeeffects array_var lightindexes int index int lightindex int size int eff_code string_var ascii_code ref me ref item ref caster short nighteye short light short nighteye_item short light_item int magic_type begin ScriptEffectStart let size := ar_Size activeeffects if size == -1 let activeeffects := ar_Construct array endif let size := ar_Size lightindexes if size == -1 let lightindexes := ar_Construct array endif set me to GetSelf if me != 0 let activeeffects := me.GetActiveEffectCodes let size := ar_Size activeeffects endif if size > 0 ;print $me+" has "+$size+" active spell effects on him." ; searching for night eye set index to 0 set nighteye to 0 set nighteye_item to 0 while index < size let eff_code := activeeffects[index] let ascii_code := GetMagicEffectCharsC eff_code if eval ( ascii_code == "NEYE" ) set item to 0 let item := GetNthActiveEffectEnchantObject index if item != 0 ;print $me+" has active Night Eye effect coming from "+$item+" as enchanted item." set nighteye_item to 1 else ;print $me+" has active Night Eye effect coming from other source than enchanting." set nighteye to 1 endif endif set index to index + 1 loop ; now searching for light if nighteye != 0 || nighteye_item != 0 set index to 0 set lightindex to 0 set light to 0 set light_item to 0 while index < size let eff_code := activeeffects[index] let ascii_code := GetMagicEffectCharsC eff_code if eval (ascii_code == "LGHT") set item to 0 let item := GetNthActiveEffectEnchantObject index if item != 0 ;print $me+" has also Light effect coming from "+$item+" as enchated item." set light_item to 1 else set caster to 0 let caster := GetNthActiveEffectMagicItem index if caster != 0 set magic_type to 0 let magic_type := GetMagicItemType caster if magic_type == 1 ; we want disable spells let magic_type := GetSpellType caster if magic_type == 0 || magic_type == 3 ;disable only normal spell or lesser power ;print $magic_type ;print $me+" has also Light effect coming from spell or lesser power." set light to 1 let lightindexes[lightindex] := index set lightindex to lightindex + 1 endif endif endif endif endif set index to index + 1 loop ; found light as spell or power if light ;print "Trying to dispell all Light spells and powers." let size := ar_Size lightindexes set lightindex to 0 while lightindex < size let index := lightindexes[lightindex] me.DispelNthActiveEffect index set lightindex to lightindex + 1 loop endif endif endif ; cleanup sv_Destruct ascii_code ar_Resize activeeffects 0 let activeeffects := ar_Null ar_Resize lightindexes 0 let lightindexes := ar_Null end Link to comment Share on other sites More sharing options...
GamerRick Posted August 16, 2022 Author Share Posted August 16, 2022 Thanks for that RomanR!! Link to comment Share on other sites More sharing options...
glowplug Posted August 17, 2022 Share Posted August 17, 2022 Directly editing vanilla spells can be nullified by any mod later in load order. A solution is to use the OnSpellCast EventHandler bound to Player.OnSpellCast hands the aruments of Caster and Spell - we know the Caster but Spell provides a solution.The requirement is Dispel by Effect however it is a Many to Many relationship - each effect belongs to many spells and a spell can have many effects. The solution is to use mapping functions for each Effect that should Dispel any other Spell by any other Effect.It may be easier to do in Skyrim Creation Kit but I have to ask, would it be anywhere near the challenge or fun of making Oblivion bow to your will? Pseudo code... scn QstHandleEventsScript Begin GameMode if GetGameLoaded ;__This binds the event handler to player on new, quick or load game. PlayerRef.SetEventHandler "OnSpellCast", FnOnSpellCastPlayer endif End scn FnOnSpellCastPlayer ref refCaster ref refSpell Begin Function { refCaster, refSpell } ;__once bound, this always runs when the player casts a spell if MagicItemHasEffect ABAT, refSpell call FnDispelConflicts "ABAT" elseif MagicItemHasEffect ... call FnDispelConflicts ... endif End scn FnDispelConflicts string_var strEffect Begin Function { strEffect } ;__this does the Dispel(s) - each could be factored out to other functions for readability and tidiness if strEffect == "ABAT" PlayerRef.Dispel BSWarriorFarting PlayerRef.Dispel ... endif End Link to comment Share on other sites More sharing options...
Recommended Posts