LordSerathDarklands Posted June 9, 2016 Share Posted June 9, 2016 I'm trying to make a minor spell mod that I plan on calling either "Flicker" or "Blink" or something similar, with the idea of the spell being to blink the spell's target out of existence for the spell's duration. I've got the basics down (using the "disable" and "enable" commands to blink the target in and out of existence), but I don't know how to create a timer within scripts. For example, I'd like to have the script be something like: scn FlickerSpell begin ScriptEffectStartdisableend (Timer Script Command) enableend begin ScriptEffectFinishend Also, anyone who knows scripts well, if I've made a mistake in the syntax of the script, please correct me. The overall goal of the effect is to make it into a script effect for a spell so that when it's cast, it will remove the targeted item (like the "disable" console command) for the duration of the timer script command, then restore it (like the "enable" console command does on something that has had "disable" used on it if you've not clicked on anything else once you used "disable"), effectively temporarily "blinking" the object out of existence for a set amount of time. Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted June 9, 2016 Share Posted June 9, 2016 Is there a reason you're not just using the Oblivion-internal spell duration timer to achieve this? You can disable the target in the ScriptEffectStart block and enable it again in the corresponding ScriptEffectFinish block, which will automatically be called once your spell duration "runs out". You can also use a GameMode block, running about every frame, and GetSecondsPassed to reduce a timer variable each frame and only enable once it's <= 0 again. Have the ScriptEffectStart block set the variable to the amount of seconds you want to have it run down, and use a trigger flag variable so it only runs down and enables once the timer was set. But as it's a spell already, the spell's duration should do the trick. float timeout short docount Begin ScriptEffectStart disable ;or whatever set timeout to 10 ;seconds set docount to 1 End Begin GameMode if 1 == docount if 0 < timeout set timeout to timeout - GetSecondsPassed else enable ;or whatever set docount to 0 endif endif End There's one thing to keep in mind though. I don't know if "disable" doesn't actually cancel all spells or stops all scripts on the object disabled as well. In that case it'd be no use to even try anything of the above.But if that is the case, you can always create a "holding cell" instead where you "moveto" the objects hit by the spell and "moveto" them back to where they were before they got removed. I think a placeholder XMarker can be spawned in their place, and that'll be where they'll be transported back to then. But that's just a very basic idea of a different approach in case the above fails due to mentioned game engine limitations. Oh, and the above will also not work, when your spell runs out before the script has ended, of course. But that's to be expected I think. Link to comment Share on other sites More sharing options...
LordSerathDarklands Posted June 9, 2016 Author Share Posted June 9, 2016 The reason I wasn't using the existing spell duration was because I thought that would time the entire script - disable AND enable. So I thought it would effectively run a script of disable, then enable over the course of a few seconds, with no actual visible effect. This is much more advanced than I thought it was going to be. Perhaps I should put it in the mod request forum instead. Morrowind had the capacity to shrink objects to 0% scale, as opposed to Oblivion's minimum of 50%, which could have been rather useful for this kind of effect. Instead of disabling it, it could have simply been reduced to zero size, then resized to normal. Sadly, Morrowind didn't have script effect enchanting. Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted June 9, 2016 Share Posted June 9, 2016 For what it's worth, if you use this spell script: Begin ScriptEffectStart disable End Begin ScriptEffectFinish enable End and give your spell a duration, it might just do what you want already, given the "disable" does not kill the script. Both blocks will only run once, one at the start of the spell's duration, one when it ran out, and the spell duration will be your timer. I'd say give it a try and see what it does. Link to comment Share on other sites More sharing options...
LordSerathDarklands Posted June 13, 2016 Author Share Posted June 13, 2016 So I tried the script you provided, with a five second duration for testing purposes. It has no effect on inanimate objects (shelves, staircases, etc) or things that you can pick up (I tried it on a silver pitcher and a silver bowl). However, it makes objects that can be interacted with (NPCs, chairs, gates [i tried the ones at the Arcane University], benches, and so on) vanish - permanently. Link to comment Share on other sites More sharing options...
Surilindur Posted June 13, 2016 Share Posted June 13, 2016 (edited) Spell effects in general did not work on statics last I checked. They do seem to work on containers, activators, actors and all that. As for permanent disabling, chances are that - as Drake mentioned: -- it might just do what you want already, given the "disable" does not kill the script. -- So it sounds like, when the reference is disabled, all script processing on it might also be disabled (like actors have their AI disabled with the actor), and the script probably stops processing after the Disable command has been called on it. For actors, you could use GetActorAlpha and SetActorAlpha, with an AI toggle, and maybe something to stop combat (just an example, I have not yet managed to stop any combat at all this far... so go figure): float fOldAlpha Begin ScriptEffectStart StopCombatAlarmOnActor ; to stop others' combat, maybe? SetActorsAI 0 let fOldAlpha := GetActorAlpha SetActorAlpha 0 End Begin ScriptEffectFinish SetActorAlpha fOldAlpha SetActorsAI 1 EndFor activators and all that, I am not sure what would work, exactly. It is a bit tricky, SetActorAlpha does not work on something that is not an actor. Temporarily replacing model with an invisible one might be one option, assuming you can find a command that does not modify the base object - and those ones are probably pretty rare, from what I have noticed, since each reference is an instance of its base object, and modifying the base object will usually see the changes reflected in all instances of it. Hopefully that helps a little. And hopefully someone knows how to hide statics. :smile: Edit: Whoops. Added the missing SetActorAlpha, to hide the actor. Of sorts. Update3D works if the changes are not instantly reflected. Edit 2: One solution would be to use an array of StringMaps, with the ref ID and a timer, on a quest script, that could run each second, for example. This is just an idea, untested, I am writing it here directly, to give you an overall idea. The looping, in a quest script, for example: float fQuestDelayTime Array_var aRefs int iTemp ref rTemp Begin _GameMode let iTemp := ar_Size aRefs let fQuestDelayTime := 1.0 ; or otherwise set this While ( iTemp > 0 ) let iTemp -= 1 let aRefs[iTemp]["time"] -= fQuestDelayTime If Eval ( aRefs[iTemp]["time"] < 0 ) let rTemp := aRefs[iTemp]["ref"] rTemp.Enable ar_Erase aRefs iTemp EndIf Loop EndAnd the adding on a magic effect script: Begin _ScriptEffectStart If Eval ( YourQuestID.aRefs == ar_Null ) let YourQuestID.aRefs := ar_Construct "Array" EndIf ar_Append YourQuestID.aRefs ( ar_Map "ref"::GetSelf "time"::5.0 ) Disable EndOr something like that. Assuming GetSelf returns a reference and not a base object. Cannot remember at the moment. Edited June 13, 2016 by Contrathetix Link to comment Share on other sites More sharing options...
LordSerathDarklands Posted June 13, 2016 Author Share Posted June 13, 2016 I'm getting an issue on the script you provided. It's not recognizing the term "let". Script 'SDFlickerSpell', line 8:Script command "let" not found. Continue Playing?"Yes to all" will disable all Warnings this session. "SDFlickerSpell" is the script name I'm using. Also, if this works, awesome, but the main focus of the spell was for activators like locked gates. It's for a kind of "pathmage" like character, the kind of character that can open doors that aren't even there. Link to comment Share on other sites More sharing options...
Surilindur Posted June 13, 2016 Share Posted June 13, 2016 (edited) Oh yes, that is an OBSE command. The second suggestion (I edited when you posted, it seems, whoops) will not even get that far without it. However, the second one should work for statics, assuming they do not have an enable parent. If a reference has an enable parent, it will refuse to abide by the Disable command. I would recommend using the Construction Set Extender: http://www.nexusmods.com/oblivion/mods/36370/? Hopefully that helps a little. As for how to achieve it without OBSE, no idea. Interesting idea tha project of yours, though. Be sure to check that the door is not a load door. You can use the IsLoadDoor and invert it http://cs.elderscrolls.com/index.php?title=IsLoadDoor If Eval !( IsLoadDoor )Or, the more usual notation, equivalent to that one If ( IsLoadDoor == 0 )This is a handy place: http://cs.elderscrolls.com/index.php?title=List_of_Functions Edit: Using GetParentRef will help you check if it has an enable parent. You can invert it to check if it does not have one: If Eval !( GetParentRef )Edit 2: Like this, with the quest script mentioned earlier (remember to se the duration to at least 2 seconds if you use the visuals (which look nice) Begin _ScriptEffectStart If Eval ( IsDoor ) || ( IsActivator ) PlayMagicShaderVisuals effectEnchantAlteration 0.5 ; having duration of something like > 1 will allow for the effect to finish EndIf End Begin _ScriptEffectFinish If Eval ( !( IsDoor ) && !( IsActivator ) ) || ( GetParentRef ) || ( IsLoadDoor ) Message "The target resisted the spell!" Return EndIf If Eval ( YourQuestID.aRefs == ar_Null ) let YourQuestID.aRefs := ar_Construct "Array" EndIf ar_Append YourQuestID.aRefs ( ar_Map "ref"::GetSelf "time"::5.0 ) Disable EndEdit 3: I need to go get some sleep. If someone has better solutions, feel free to chime in. I will check back tomorrow. Happy modding. :) Edited June 13, 2016 by Contrathetix Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted June 14, 2016 Share Posted June 14, 2016 Contrathetix, I really like that Quest Script driven Array storage solution of your's to get around "disable" killing scripts and other processes running on the target. Very elegant. :thumbsup: Juts in case the limitation to only things a spell can affect bothers you too much, there's also another nifty OBSE function called GetCrosshairRef which used from inside a GameMode block instead of a spell script might turn out quite useful. Link to comment Share on other sites More sharing options...
LordSerathDarklands Posted June 14, 2016 Author Share Posted June 14, 2016 You guys, I have no idea what you're talking about. You have to talk to me about this stuff like I'm an idiot, because when it comes to scripting, that's what I am. I don't know what a "GameMode block" is, or any of the other stuff that you guys are talking about. Link to comment Share on other sites More sharing options...
Recommended Posts