Scripting Advice Requested: Enabling Objects by Month

Post » Thu Jun 21, 2012 10:24 am

I'm working on my core method of implementing festivals in my mod in progress. What I want is to be able to enable objects for a month and then have them disable as the month changes. I also want to trigger the enabling with as little cpu usage as possible. i don't want some scripts checking for the conditions every few seconds you're playing. I've been toying with a few possible methods, but would like the advice of more experienced scripters (I've been away from the CK a few months and have gotten rusty :P )

1) Script on object: What would seem most elegant to me is to have a script that checks for the month once when a parent object is loaded in the cell as the player enters or nears an area. I've been experimenting with putting a script on an object or actor based on the OnCellLoad() or OnCellAttach() Event. So, far I haven't been able to get it working right. This is the current text I've been running, attached to an elk inside Whiterun. It never disables (although I start it disabled, so perhaps the problem is the script enables it regardless of month.)

Scriptname QutElkTestSctipt extends ObjectReference GlobalVariable Property Month  Auto Event OnCellAttach()	 if Month.GetValue() == 1			   Self.Enable()else			   Self.Disable()endifendevent

It could be I'm not getting the syntax right, but I'd be curious if you think such a simple script would work efficiently and reliably in the first place. I've read some posts that complain about the reliability of OnCellAttach().

2) A second solution would be to modify the method used by the Khajit caravans, which use an AI travel package to trigger stages of a master quest that handles the enabling and disabling of their camps. I am planning to have "Master" NPC that travels around to various festivals, so I could work with this, but it feels a little clunky to me. I suppose another way would be to have an invisible actor (I'd probably pick a Skeever) running around making this possible, so that I could have my master NPC have a more complex schedule.

3) I'd be curious if there is a month-change event in the system. In other words, would my scripts have to be placed on a object or triggered by a quest, or is there a way to have a script trigger at the change of a day or month? Where might I start looking if this is a feasible option. How does the engine decide when it's time to switch the name of the month? And can scripts be extended off of that function without messing things up?

So, in short, these seem to be object, quest, or global script-based methods, obviously still in the rough.

And if you all think more than one method would work, which do you think would be the least resource intensive?
User avatar
Oscar Vazquez
 
Posts: 3418
Joined: Sun Sep 30, 2007 12:08 pm

Post » Thu Jun 21, 2012 9:35 am

Use GameMonth.GetValueInt() to get the current (0-indexed) month. You could use RegisterForUpdateGameTime(24) to have your script check the current month each game day. If the current month != the month you care about, .Disable(), otherwise, .Enable().

Scripts attached to objects will fire their OnInit() block when they are instantiated. So you could have a single script attached to anything (say, an invisible activator) and do something like:

scriptname mySeasonalScript extends ObjectReference;The GlobalVar that contains the monthGlobalVariable property GameMonth auto;Various and sundry objects to enable and disable based on seasonObjectReference property myBanner1 autoObjectReference property myBanner2 autoObjectReference property mySeasonalTree1 autoActor property myJugglerGuy autoEvent Oninit()	RegisterForSingleUpdateGameTime(24)endEventEvent OnUpdateGameTime()	if GameMonth.GetValueInt() == 7  ;Last Seed			myBanner1.Enable()			myBanner2.Enable()			mySeasonalTree1.Enable()			myJugglerGuy.Enable()	else			myBanner1.Disable()			myBanner2.Disable()			mySeasonalTree1.Disable()			myJugglerGuy.Disable()	endif	RegisterForSingleUpdateGameTime(24)endEvent
This would drive the enabling and disabling of all of your seasonal objects. Good luck!

I don't have much experience with OnCellAttach and am not sure of its exact behavior.
User avatar
Betsy Humpledink
 
Posts: 3443
Joined: Wed Jun 28, 2006 11:56 am

Post » Thu Jun 21, 2012 8:39 am

OnCellAttach will fire just fine even if the object happens to be disabled. Here's some changes to Chesko's script so that it checks at midnight as much as possible:

scriptname mySeasonalScript extends ObjectReference;The GlobalVar that contains the monthGlobalVariable property GameMonth autoGlobalVariable Property GameHour Auto;Enable parents for seasonal objectsObjectReference property SeasonalEnableParent00 autoObjectReference property SeasonalEnableParent01 autoObjectReference property SeasonalEnableParent02 auto;etc.Event Oninit()    Float Interval = 24.0 - GameHour.Value    if (Interval < 0.025)        Interval = 0.025    endif    RegisterForSingleUpdateGameTime(Interval)endEventEvent OnUpdateGameTime()    if (GameMonth.GetValueInt() == 0)        SeasonalEnableParent00.Enable()    else        SeasonalEnableParent00.Disable()    endif    if (GameMonth.GetValueInt() == 1)        SeasonalEnableParent01.Enable()    else        SeasonalEnableParent01.Disable()    endif    if (GameMonth.GetValueInt() == 2)        SeasonalEnableParent02.Enable()    else        SeasonalEnableParent02.Disable()    endif    ;etc.    Float Interval = 24.0 - GameHour.Value    if (Interval < 0.025)        Interval = 0.025    endif    RegisterForSingleUpdateGameTime(Interval)endEvent

It would look slightly cleaner if using a formlist or array, but I didn't really want to go into that.
User avatar
anna ley
 
Posts: 3382
Joined: Fri Jul 07, 2006 2:04 am

Post » Thu Jun 21, 2012 12:12 pm

Wow, thanks both of you for the help. I'll try those suggestions out.
User avatar
Lynne Hinton
 
Posts: 3388
Joined: Wed Nov 15, 2006 4:24 am


Return to V - Skyrim