Jump to content

Papyrus scripting newbie needs help!


Recommended Posts

I have a mod for a settlement in Sanctuary Hills.  I have my lights setup using a switch and an EnableMarker.  Everything is working as it should, but i wanted to add a "Day/Night" function to them where they turn on at dusk and off at dawn.  I'm having the hardest time trying to integrate both of these scripts into one script.

Need help getting this to work:

These are the 2 scripts I have for the lighting

CSLightsToggle.psc

TimedLightSwitch.psc

Any help would be greatly appreciated!

Edited by gamerdad5862
Link to comment
Share on other sites

I think figure out exactly what you want the behaviour to be first! That may make it easier for you to script.

So the light comes on at night and goes off during the day, but there's also a manual override switch. If I hit that during the day, what then happens at night? Does the light stay on or does it go off, i.e. have we reversed the behaviour? And what happens when day comes around again? Does the light stay on because I manually turned it on yesterday? Or is that irrelevant now?

Edited by adb3nj
Link to comment
Share on other sites

On 6/2/2024 at 12:58 PM, adb3nj said:

So the light comes on at night and goes off during the day, but there's also a manual override switch. If I hit that during the day, what then happens at night? Does the light stay on or does it go off, i.e. have we reversed the behaviour? And what happens when day comes around again? Does the light stay on because I manually turned it on yesterday? Or is that irrelevant now?

If you set an EnableParent Object Reference ("enable marker") of another Object Reference (the lamp post), then the light emitted by the lamp post stays on as long as the EnableParent's enable state is true (in other words, it's enabled).

A modified enable state of an Object Reference is stored in save games. So, if you call for example Enable() on the EnableParent, any Object Reference that has this EnableParent (they're called "enable parent children") stay enabled until you Disable() the EnableParent.

You can't call Enable() or Disable() on enable parent children to change their enable state as per game design. You can call Enable() and Disable() only on their EnableParent.

The game engine has a bug that randomly causes the lights emitted from certain light source Object References not to get rendered when their 3D loads (i.e. when the player approaches the area around them), making them dim. (The bug can be avoided. As for how, that depends on the how the light source was made).

If you want the light to go off at a specified time / scheduled event, you'll need to make a script that automatically, accordingly calls Enable() or Disable() on the light source Object Reference's EnableParent.

Link to comment
Share on other sites

1 hour ago, LarannKiar said:

If you set an EnableParent Object Reference ("enable marker") of another Object Reference (the lamp post), then the light emitted by the lamp post stays on as long as the EnableParent's enable state is true (in other words, it's enabled).

Is that what they want though? I took a quick look at the two scripts and couldn't figure out what the desired behaviour was.

Link to comment
Share on other sites

2 hours ago, adb3nj said:

Is that what they want though? I took a quick look at the two scripts and couldn't figure out what the desired behaviour was.

I think they're supposed to do this but it seems they were made for Skyrim.

 

This script can be used for Fallout:

Scriptname TestScript extends ObjectReference Const		; script should be attached to either the base form (e.g. Light, Activator) of the light source object reference or the object reference itself


ObjectReference Property MyEnableParent Auto Const		; variable that points to the enable parent of the light source object ref
Float Property fDaytimeBegin = 8.00 Auto Const			; daytime from 8am
Float Property fDaytimeEnd = 20.00 Auto Const			;         to 8pm
Float Property fDaytimeCheck = 5.00 Auto Const			; update interval (i.e. after how many real-time seconds the script should determine whether it's daytime or nighttime)



Event OnLoad()											; the object ref this script is attached to is loaded
	StartTimer(fDaytimeCheck, 555)								; start the timer that'll keep track of whether it's daytime or nighttime (555 is the timer ID, arbitrary number)
	AutoSetLightState()									; change the light state accordingly
EndEvent

Event OnUnload()										; the object ref this script is attached to is unloaded
	CancelTimer(555)									; cancel the timer
EndEvent

Event OnTimer(int aiTimerID)									; a timer expired
	If aiTimerID == 555									; the one whose timer ID is 555
		If Self.Is3DLoaded() == true							; if Self (i.e. the object ref this script is attached to) is loaded
			StartTimer(fDaytimeCheck, 555)						; restart the timer
			AutoSetLightState()							; turn on/off the lights if needed
		EndIf
	EndIf
EndEvent

Function AutoSetLightState()
	Float fCurrentTime = GetCurrentTime()
	If fCurrentTime >= fDaytimeBegin && fCurrentTime <= fDaytimeEnd							; if daytime
		If MyEnableParent.IsDisabled() == true
			MyEnableParent.Enable()										; enable the enable parent to turn the lights on
		EndIf
	Else														; otherwise
		If MyEnableParent.IsDisabled() == false
			MyEnableParent.Disable()									; disable the enable parent to turn the lights off
		EndIf
	EndIf
EndFunction

Float Function GetCurrentTime()												; returns the hour of the day
	Float CurrentTime = Utility.GetCurrentGameTime()
	CurrentTime = CurrentTime - Math.Floor(CurrentTime)
	CurrentTime = CurrentTime*24
	Return CurrentTime
EndFunction

 

Link to comment
Share on other sites

You can use CHRONOS Scheduler & CHRONOS ClientBase in F4MS with this script:

Scriptname YourNamespaceHere:ScheduledEnableDisable extends F4MS:CHRONOS_ClientBase

; custom scripting by niston

; ScheduledEnableDisable script performs a scheduled Enable or Disable on the attached reference.
; EventDataKeyword must be EventKeyword to trigger this instance upon receiving F4MS_ScheduledEvents
; EventDataFloat must be 1.0 for Enable, any other value results in a Disable being performed

; todo: currently works reliable with persistent references only. make it work for nonpersistent references by caching 

Bool Property FadeIn Auto Const
{ Fade in on enable }

Bool Property FadeOut Auto Const
{ Fade out on disable }

Function OnCHRONOSEventsReceived(Int lateEventCount, F4MS:CHRONOS_EventBuffer refEventBuffer)
    ; safety check
    If ((Self as ScriptObject).IsBoundGameObjectAvailable() == false)
        Return
    EndIf
    
    If (refEventBuffer.Size == 0)
        ; no actual event happened
        Return
    EndIf
    
    ; process events, retain last enablestate only
    Debug.Trace(Self + ": DEBUG - OnCHRONOSEventsReceived(lateEventCount=" + lateEventCount + ", refEventBuffer=" + refEventBuffer + ", refEventBuffer.Size=" + refEventBuffer.Size + ") called. Our EventKeyword: " + EventKeyword + ".")
    Bool setValue = (refEventBuffer.Entry[refEventBuffer.Size - 1].EventDataFloat == 1.0)
    
    ; perform Enable() or Disable()
    If (setValue)
        Debug.Trace(Self + ": DEBUG - Performing Enable(" + FadeIn + ") on " + (Self as ObjectReference) + "...")
        (Self as ObjectReference).Enable(FadeIn)
    Else
        Debug.Trace(Self + ": DEBUG - Performing Disable(" + FadeOut + ") on " + (Self as ObjectReference) + "...")
        (Self as ObjectReference).Disable(FadeOut)
    EndIf
EndFunction

Create a custom Keyword like "MuhMod_StreetlightsKeyword" or similar.

Then create a F4MS schedule, by copying F4MS_schdDefault and renaming it. Edit properties for the attached script F4MS_Schedule, and edit the Entries property. This list of entries is your schedule.

Create two entries in the schedule, both using the custom keyword you created:

  • First entry disables the streetlights in the morning: TimeOfDay=8.0 (8:00am), EventDataFloat=0.0 (disable), EventDataKeyword=MuhMod_StreetlightsKeyword, Initialize=True.
  • Second entry enables them in the evening: TimeOfDay=19.5 (7:30pm), EventDataFloat=1.0 (enable), EventDataKeyword=MuhMod_StreetlightsKeyword, Initialize=True.

Attach the F4MS:CHRONOS_Scheduler script to a new quest (priority 42, check start game enabled & allow repeatable stages) and give it the schedule you created. 

Finally, attach the ScheduledEnableDisable script to the EnableParent. Use your quest created above for the EventScheduler property, and your Keyword for the EventDataKeyword property on this script.

CHRONOS is very efficient as it doesn't use any fast running timers. Instead, it lays completely dormant until a scheduled event happens. After brief processing, it'll then go back to it's dormant state until the next scheduled event. It has provisions to handle events for many different things in a single schedule, schedule entries can pass data (such as the EventDataFloat mentioned above) to event consumers, and it allows to properly identify and handle late events. That is, events which have occurred while player was sleeping, waiting or fast travelling.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...