kxdace Posted May 3, 2020 Posted May 3, 2020 Hello fellow warrior poets! The goal is simple consume item(soap), add ability for 12 in game hours then remove. This code executes upon consumption a potions \ soap item. The first part of the code executes flawlessly but after 12 hours have passed the Update code doesn't trigger. How have I failed? Scriptname wrScriptCITDE_SoapA extends ActiveMagicEffect Import Debug Import Game Actor Property PlayerREF Auto Spell Property FreshShower Auto MagicEffect Property isWetNow Auto Event OnInit() EndEvent Event OnEffectStart(Actor akTarget, Actor akCaster) if (game.GetPlayer().HasMagicEffect(IsWetNow)) Game.DisablePlayerControls(False, False, False, False, False, True) Game.EnablePlayerControls(False, False, False, False, False, True) Utility.Wait(0.5) Debug.SendAnimationEvent(PlayerREF, "IdleWarmHandsCrouched") Utility.Wait(3) Debug.SendAnimationEvent(PlayerREF, "IdleStop") Utility.Wait(1) Debug.SendAnimationEvent(PlayerREF, "IdleWarmArms") Utility.Wait(2) Debug.SendAnimationEvent(PlayerREF, "IdleStop") Utility.Wait(1) Debug.SendAnimationEvent(PlayerREF, "IdleWipeBrow") Utility.Wait(1.5) ;FreshShower.cast(PlayerREF, game.getPlayer()) Game.GetPlayer().addSpell(FreshShower) RegisterForSingleUpdateGameTime(12) else debug.notification("You are too dry") endIf EndEvent Event OnUpdateGameTime() debug.MessageBox("You are starting to smell") Game.GetPlayer().RemoveSpell(FreshShower) endEvent Event OnEffectFinish(Actor akTarget, Actor akCaster) ;debug.notification("I feel refreshed") ;PlayerREF.removeSpell(BathSpell) endEvent
Guffel Posted May 3, 2020 Posted May 3, 2020 I don't see a direct mistake, but the wiki page has some notes concerning magic effects. Where is your script attached to? Also, OnUpdateGameTime doesn't count wait or sleep time, so you can't test this by just waiting in game. My workaround would be a one minute OnUpdate event checking how much time has passed since the effect was applied and then unregistering itself.
Fotogen Posted May 3, 2020 Posted May 3, 2020 Script must be attached to MagicEffect. MagicEffect must be part of a spell. How long does MagicEffect/Spell lasts? You can't have 2 same MagicEffects on one Actor at the same time. I dont't see any call to Dispel(). Some old one(script, MagicEffect) could be still running.
kxdace Posted May 3, 2020 Author Posted May 3, 2020 Guffel, The script is attached to a Magic Effect (please see screen shot). Did I mess that part up? I'll come up with the OnUpdate event code for review in a moment. Fotogen, I just attached the screen shots for the Magic Effect and spell. Please let me know if they are in error. When you say there is no call to dispel the old magic effect would the following accomplish this: Game.GetPlayer().RemoveSpell(FreshShower) Do I have to explicitly declare a .Dispel() to remove it. When I try I get an error (please see updated code)
kxdace Posted May 3, 2020 Author Posted May 3, 2020 Event OnUpdateGameTime() ;soapEffect.Dispel() - Eroor Dispel is not a function or does not exist debug.MessageBox("You are starting to smell") Game.GetPlayer().RemoveSpell(FreshShower) endEvent
MTB Posted May 3, 2020 Posted May 3, 2020 Note: I tried to achieve something similar but gave up and solved it another way. I think active magic effects will automatically unregister for updates when they are removed; so if the effect no longer last, it will not receive an update. Easiest would be to give the effect a longer duration (eg the real time equivalent 12hrs game time) and remove the spell in onend instead - would not capture wait/sleep but pretty close. Otherwise; if only for player you could make a quest that tracks the state; that could receive an updategametime event. Side remarks: 23 minutes ago, kxdace said: Event OnUpdateGameTime() ;soapEffect.Dispel() - Eroor Dispel is not a function or does not exist debug.MessageBox("You are starting to smell") Game.GetPlayer().RemoveSpell(FreshShower) endEvent I think you would need to use self.Dispel() here. > You can't have 2 same MagicEffects on one Actor at the same time. I think that is only true if the effect has no-recast selected.
kxdace Posted May 3, 2020 Author Posted May 3, 2020 MTB, I think your right quest is the only way I'm going to be able to reliably make it work.
kxdace Posted May 3, 2020 Author Posted May 3, 2020 Guffle, MTB and Fotogen thank you all for your replies. My solution ended up being a combination of all of your inputs. I got rid of the update code from the magic effect. The only reason I used a magic effect to begin with was cause that's the only method I know of to get a script to fire from a consumable object. I added a script to a quest that runs a check every hour to see if the player has the spell on them and if they do it runs a check to see if it's been more than 8 hours or not. Its functional and does what I want but I'm not sure if this is best practice or not. I've placed the two scripts below if anyone has any suggestions or ways of making it more effective. ===Quest Script=== Scriptname wrScriptPlayerD extends Quest MagicEffect Property showerEffect Auto Actor Property PlayerREF Auto Spell Property FreshShower Auto Quest Property thisQuest Auto GlobalVariable PROPERTY showerTimer auto GlobalVariable PROPERTY GameDaysPassed auto GlobalVariable PROPERTY showerStatus auto Event OnInit() RegisterForUpdateGameTime(1) ;debug.MessageBox("Script 2 active") EndEvent Event OnUpdateGameTime() ; because of how we registered, this event occurs every 60 minutes of game time ;if thisQuest.getStage() == 10 if(showerStatus.getValue() == 1) debug.MessageBox("Shower Status 1") if PlayerREF.hasSpell(FreshShower) ;debug.MessageBox("Last shower: " + showerTimer.getValue()) ;debug.MessageBox("The current time is " + GameDaysPassed.getValue()) ;debug.MessageBox("The current time plus .5 is " + (GameDaysPassed.getValue() + 0.336)) ;. 336 is about 8 hours or 042 for an hour if((showerTimer.getValue() + 0.336) < GameDaysPassed.getValue()) ;debug.MessageBox("8 hours past remove effect") PlayerREF.removeSpell(FreshShower) showerStatus.setValue(0) endIf ;endIf ;UnregisterForUpdateGameTime() ; when we're done with it, make sure to unregister ;Debug.Trace("Got what we needed, so stop polling!") else ;debug.MessageBox("No shower detected") endIf ;debug.MessageBox("Polling") else debug.MessageBox("Shower Status 0") endIf endEvent ===MAGIC Effect Script=== Scriptname wrScriptCITDE_SoapA extends ActiveMagicEffect Actor Property PlayerREF Auto Spell Property FreshShower Auto MagicEffect Property isWetNow Auto MagicEffect Property soapEffect Auto GlobalVariable PROPERTY showerTimer auto ;set as float GlobalVariable PROPERTY showerStatus auto ;set as float Event OnEffectStart(Actor akTarget, Actor akCaster) if (game.GetPlayer().HasMagicEffect(IsWetNow)) showerTimer.setValue(Utility.getCurrentGameTime()) Game.DisablePlayerControls(False, False, False, False, False, True) Game.EnablePlayerControls(False, False, False, False, False, True) Utility.Wait(0.5) Debug.SendAnimationEvent(PlayerREF, "IdleWarmHandsCrouched") Utility.Wait(3) Debug.SendAnimationEvent(PlayerREF, "IdleStop") Utility.Wait(1) Debug.SendAnimationEvent(PlayerREF, "IdleWarmArms") Utility.Wait(2) Debug.SendAnimationEvent(PlayerREF, "IdleStop") Utility.Wait(1) Debug.SendAnimationEvent(PlayerREF, "IdleWipeBrow") Utility.Wait(1.5) Game.GetPlayer().addSpell(FreshShower) showerStatus.setValue(1) else debug.notification("You are too dry") endIf EndEvent
Recommended Posts
Archived
This topic is now archived and is closed to further replies.