Jump to content

Custom Event: Is There Rainy Weather?


ajs52698

Recommended Posts

I think you'd need to poll the current weather every so often in order to detect when the weather transitions to the one you're after. You'll need:

 

GetCurrentWeather http://www.creationkit.com/fallout4/index.php?title=GetCurrentWeather_-_Weather

GetClassification http://www.creationkit.com/fallout4/index.php?title=GetClassification_-_Weather

 

and a timer.

Link to comment
Share on other sites

Here's a script that should work if you want to use custom events. It compiles but I haven't tested it in-game; it should work however.

; Script by timtimman, http://www.nexusmods.com/games/users/34480070/
; Use however you'd like but be kind and give some sort of credit
Scriptname WeatherEventScript extends Quest
{ A quest script which sends the Custom Event WeatherChange }

Float Property UpdateTime = 5.0 Auto ; Time between updates, 5 seconds should be enough

Weather LastWeather

; Always sent on weather change with two arguments: akArgs[0] == Weather newWeather, akArgs[1] == Weather oldWeather.
;	May need to explicitly cast them as Weather on the recieving end to use their properties and methods
CustomEvent WeatherChange

; Sent if a weather classification has changed, sent with one argument akArgs[0] == bool isCurrent
CustomEvent WeatherUnclassified	; Classification == -1
CustomEvent WeatherPlesant		; Classification ==  0
CustomEvent WeatherRainy		; Classification ==  1
CustomEvent WeatherCloudy		; Classification ==  2
CustomEvent WeatherSnow 		; Classification ==  3

Event OnQuestInit()
	LastWeather = Weather.GetCurrentWeather()
	StartTimer(UpdateTime, 0)
EndEvent

Event OnTimer(Int aiTimerID)
	If (aiTimerID == 0)
		Weather currentWeather = Weather.GetCurrentWeather()
		If (currentWeather != LastWeather)
			SendWeatherEvents(currentWeather, lastWeather)
		EndIf
		LastWeather = currentWeather
	EndIf					
EndEvent

Function SendWeatherEvents(Weather newWeather, Weather oldWeather)
	Int classification = newWeather.GetClassification()
	If (classification != oldWeather.GetClassification())
		Var[] unclassArgs = new Var[1]
		unclassArgs[0] = false
		Var[] pleasantArgs = new Var[1]
		pleasantArgs[0] = false
		Var[] rainyArgs = new Var[1]
		rainyArgs[0] = false
		Var[] cloudyArgs = new Var[1]
		cloudyArgs[0] = false
		Var[] snowArgs = new Var[1]
		snowArgs[0] = false
		If (classification == -1)
			unclassArgs[0] = true
		ElseIf (classification == 0)
			pleasantArgs[0] = true
		ElseIf (classification == 1)
			rainyArgs[0] = true
		ElseIf (classification == 2)
			cloudyArgs[0] = true
		ElseIf (classification == 3)
			snowArgs[0] = true
		EndIf
		SendCustomEvent("WeatherUnclassified", unclassArgs)
		SendCustomEvent("WeatherPlesant", pleasantArgs)
		SendCustomEvent("WeatherRainy", rainyArgs)
		SendCustomEvent("WeatherCloudy", cloudyArgs)
		SendCustomEvent("WeatherSnow", snowArgs)
	EndIf
	
	Var[] akArgs = new Var[2]
	akArgs[0] = newWeather
	akArgs[1] = oldWeather
	SendCustomEvent("WeatherChange", akArgs)
EndFunction

Just attach it to a quest and then pass the quest in as a property (WeatherEventScript Property WeatherEvents Auto) to whichever script you want to receive the custom events.

Then just register for it using RegisterForCustomEvent(WeatherEvents, "WeatherRainy"), or which other event you'd like to receive.

 

And somewhere write: Event WeatherEventScript.WeatherRainy(WeatherEventScript akSender, Var[] akArgs) and you should be good to go.

Link to comment
Share on other sites

Holy moly thats a complicated script, so many vars, you think you can explain what exactly they are used for? the wiki is kinda vague . Im more interested in understanding how these scripts function than rather having someone just write one for me although I do appreciate it :tongue:

Edited by ajs52698
Link to comment
Share on other sites

If you actually break it down it's not very complicated. The var[]'s are just to allow sending parameters with the custom events.

And now that I think about it, I derped a bit on the Classification events, as they're sent every time one is changed. It would be better to only send if it was the previous one.

 

I'll fix that in an hour or so, don't quite have the time now. But it should work as is anyway, it's just that say WeatherRainy will be sent with akArgs[0] == false even if weather just transitioned from pleasant to cloudy. It doesn't break anything but is a bit confusing.

 

Edit: This is the neatest I can get it at the moment, am pretty tired. Still not tested in-game but compiles and should work.

; Script by timtimman, http://www.nexusmods.com/games/users/34480070/
; Use however you'd like but be kind and give some sort of credit
Scriptname WeatherEventScript extends Quest
{ A quest script which sends the Custom Event WeatherChange }

Float Property UpdateTime = 5.0 Auto ; Time between updates, 5 seconds should be enough

Weather LastWeather

; Always sent on weather change with two arguments: akArgs[0] == Weather newWeather, akArgs[1] == Weather oldWeather.
;	May need to explicitly cast them as Weather on the recieving end to use their properties and methods
CustomEvent WeatherChange

; Sent if a weather classification has changed, sent with one argument akArgs[0] == bool isCurrent
CustomEvent WeatherUnclassified	; Classification == -1
CustomEvent WeatherPlesant		; Classification ==  0
CustomEvent WeatherRainy		; Classification ==  1
CustomEvent WeatherCloudy		; Classification ==  2
CustomEvent WeatherSnow 		; Classification ==  3

Event OnQuestInit()
	LastWeather = Weather.GetCurrentWeather()
	StartTimer(UpdateTime, 0)
EndEvent

Event OnTimer(Int aiTimerID)
	If (aiTimerID == 0)
		Weather currentWeather = Weather.GetCurrentWeather()
		If (currentWeather != LastWeather)
			SendWeatherEvents(currentWeather, lastWeather)
		EndIf
		LastWeather = currentWeather
		StartTimer(UpdateTime, 0)
	EndIf					
EndEvent

Function SendWeatherEvents(Weather newWeather, Weather oldWeather)
	Int[] classification = new Int[2]
	classification[0] = oldWeather.GetClassification()
	classification[1] = newWeather.GetClassification()
	If (classification[0] != classification[1])
		Var[] akArgs = new Var[1]
		int i = 0
		While (i < 2)
			akArgs[0] = i as Bool
			If (classification[i] == -1)
				SendCustomEvent("WeatherUnclassified", akArgs)
			ElseIf (classification[i] == 0)
				SendCustomEvent("WeatherPlesant", akArgs)
			ElseIf (classification[i] == 1)
				SendCustomEvent("WeatherRainy", akArgs)
			ElseIf (classification[i] == 2)
				SendCustomEvent("WeatherCloudy", akArgs)
			ElseIf (classification[i] == 3)
				SendCustomEvent("WeatherSnow", akArgs)
			EndIf
			i += 1
		EndWhile
	EndIf
	
	Var[] akArgs = new Var[2]
	akArgs[0] = newWeather
	akArgs[1] = oldWeather
	SendCustomEvent("WeatherChange", akArgs)
EndFunction
 

Edit 2: made a big dummy and forgot the repeated call StartTimer(UpdateTime, 0) in the OnTimer which actually makes the script continually check. The above version is correct but not the first I posted.

 

Edit 3: did first now see that you wanted to understand how it works, with is good! I'll try to keep it simple (should be easy enough as it is). I wrote the script mostly because I usually learn best by seeing a working example. Anyway;

This script uses a timer (StartTimer function & OnTimer event), and when it finishes (the event is called) it checks to see if the current weather is any different form last time it checked (stored in variable LastWeather). If there is a difference, it proceeds to the SendWeatherEvents function which sends out the custom events.

A custom event is sent just as is, or with arguments (this is where the Vars come in). The function SendCustomEvent takes the name of the CustomEvent as a raw string (not through a variable) and an optional arguments array in the form of a Var[]. This array need to have it's size declared and be filled manually.

The Var can take any type (not structs or arrays) and will remember the type. But in order to use Script functions you need to cast it manually on the receiving end, or the compiler will complain and fail.

I hope that clears some stuff up. Love to know in what context you'll put it to use.

 

Edit 4: made a rookie mistake pointed out by cadpnq, infinite loop! Just forgot to add 'i += 1' in the While loop. Fixed!

Edited by timtimman
Link to comment
Share on other sites

; Script by timtimman, http://www.nexusmods.com/games/users/34480070/
; Use however you'd like but be kind and give some sort of credit
Scriptname WeatherEventScript extends Quest
{ A quest script which sends the Custom Event WeatherChange }

...

Function SendWeatherEvents(Weather newWeather, Weather oldWeather)
	Int[] classification = new Int[2]
	classification[0] = oldWeather.GetClassification()
	classification[1] = newWeather.GetClassification()
	If (classification[0] != classification[1])
		Var[] akArgs = new Var[1]
		int i = 0
		While (i < 2)
			akArgs[0] = i as Bool
			If (classification[i] == -1)
				SendCustomEvent("WeatherUnclassified", akArgs)
			ElseIf (classification[i] == 0)
				SendCustomEvent("WeatherPlesant", akArgs)
			ElseIf (classification[i] == 1)
				SendCustomEvent("WeatherRainy", akArgs)
			ElseIf (classification[i] == 2)
				SendCustomEvent("WeatherCloudy", akArgs)
			ElseIf (classification[i] == 3)
				SendCustomEvent("WeatherSnow", akArgs)
			EndIf
		EndWhile
	EndIf
	
	Var[] akArgs = new Var[2]
	akArgs[0] = newWeather
	akArgs[1] = oldWeather
	SendCustomEvent("WeatherChange", akArgs)
EndFunction

 

You have an infinite loop in SendWeatherEvents, no?

Link to comment
Share on other sites

  • Recently Browsing   0 members

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