Jump to content

Need Help with Papyrus scripting a radio


LadyEdith

Recommended Posts

Hello I am trying to add a radio to a room that plays an audio file on loop that the player can toggle on and off. Here is what I'm hoping will happen

 

Player activates radio

Radio plays an audio file that is about an hour long

Radio plays the file even while the player walks away the file will continue looping and looping until the player returns to shut the radio off again.

I know there are radio stations however I do not want the radio station to play in the pip boy and I want it to just play one audio file over and over. Any ideas on how to either script this in or use the pre built mechanics of the creation kit to allow this to happen?

Thank you

Billie

Link to comment
Share on other sites

It's certainly possible. You will want to create a Sound Descriptor that points to your audio file and set it to loop. Then create your radio activator object and put this Papyrus script on it:

Edit:
1.1.0 - Updated code to deal with a savegame issue (sound wouldn't play anymore) noticed by LadyEdith and also added some code to potentially deal with an issue brought up by SKK50 (sound would stop after the object unloads).

Scriptname PlaySoundOnActivateAndLoop extends Objectreference

; Original script by Reneer. License: LGPL 3.0
; Version code: 1.1.0
; URL to license: https://www.gnu.org/licenses/lgpl-3.0.html

Sound Property YourSoundDescriptor Auto
Int Property CurrentSoundInstance = -1 Auto
Bool Property SoundPlaying = false Auto

Actor Property PlayerRef Auto

Float Property PlayerDistance = 3000.0 Auto

bool Property ObjUnloadedBool = false Auto

Event OnInit()

	if (PlayerRef == none)
		PlayerRef = Game.GetPlayer()
	endif
	Self.RegisterForRemoteEvent("OnPlayerLoadGame", PlayerRef)

endEvent

Event OnUnload()

	ObjUnloadedBool = true

endEvent

Event OnLoad()

	if (ObjUnloadedBool == true && (SoundPlaying == true || Self.IsRadioOn() == true))
		; assume the sound is not playing
		; because the object unloaded previously
		ObjUnloadedBool = false
		CurrentSoundInstance = -1
		ChangeSongState(true, true)		
	endif

endEvent

Event Actor.OnPlayerLoadGame(Actor akSender)

	if (SoundPlaying == true)
		CurrentSoundInstance = -1
		ChangeSongState(true, true)
	endif

EndEvent

Function ChangeSongState(bool state, bool force = false)

	if (PlayerRef == none)
		PlayerRef = Game.GetPlayer()
		Self.RegisterForRemoteEvent("OnPlayerLoadGame", PlayerRef)		
	endif

	if ((SoundPlaying == false && state == true) || force == true)
		; no sound is playing, so start playing the sound because
		; we are turning on.
		Self.SetRadioOn(true)
		if (CurrentSoundInstance == -1 || force == true)
			CurrentSoundInstance = YourSoundDescriptor.Play(Self)		
			SoundPlaying = true			
		else
			; assume the CurrentSoundInstance is playing. 
			; TODO: Figure out how to see if audio is still playing.
			SoundPlaying = true			
		endif
		Sound.SetInstanceVolume(CurrentSoundInstance, 1.0)		
	else if (SoundPlaying == true && state == false)
		; sound is playing, so QUIET the current sound, but don't stop playing it.
		; Volume change since we don't want the music to actually stop
		; playing when the radio itself is turned off.
		Self.SetRadioOn(false)
		SoundPlaying = false
		if (CurrentSoundInstance != -1)
			Sound.SetInstanceVolume(CurrentSoundInstance, 0.0)
		endif
	endif

endFunction

Event OnActivate(ObjectReference akActionRef)

	if (SoundPlaying == true)
		ChangeSongState(false)
	else
		ChangeSongState(true)
	endif

endEvent


Please note I haven't compiled or tested this script and you will need to set up the Properties yourself, unfortunately. It might have errors or bugs, but it should be a decent starting point. If you have any questions feel free to reply and I'll do my best to help.

Link to comment
Share on other sites

I tried something similar but found that when the object unloads the sound stops playing and does not restart OnLoad.

Hmm. That's unfortunate, but unless I'm missing something it doesn't sound insurmountable.

Link to comment
Share on other sites

The sound loop can be restarted OnLoad, but it will always start at the beginning not where it switched off. I reverted to the device being a zero range radio station where the scene(s) play(s) continuously while its quest is running regardless of the device state.

Link to comment
Share on other sites

The sound loop can be restarted OnLoad, but it will always start at the beginning not where it switched off. I reverted to the device being a zero range radio station where the scene(s) play(s) continuously while its quest is running regardless of the device state.

Ah, hm. That would definitely be a better way of doing it. Honestly I didn't think about a zero-range radio station since I got caught up in avoiding radio stations altogether, but it makes perfect sense. A lot of the code I wrote isn't helpful anymore, but maybe it will be useful for someone in the future.

Link to comment
Share on other sites

This is the code I entered

I changed the properties and some variables to match what I'm working on

I commented out things I saw appear when I entered the edit source menu

I made comments detailing lines where the errors were appearing.

I want to thank you for any help you wish or do not wish to give me. You are very generous with you time to be helping me. Thank you either way.

 

/////////

 

Scriptname Radios:EdenGitaRadioStereoProperty extends ObjectReference
;Sound Property pEdenRadioGitaSungInSanskrit Auto Mandatory
;Scriptname PlaySoundOnActivateAndLoop extends Objectreference
; Original script by Reneer. License: LGPL 3.0
; Version code: 1.1.0
Sound Property EdenRadioGitaSungInSanskrit Auto
Int Property CurrentSoundInstance = -1 Auto
Bool Property SoundPlaying = false Auto
Actor Property PlayerRef Auto
Float Property PlayerDistance = 3000.0 Auto
bool Property ObjUnloadedBool = false Auto
Event OnInit()
if (PlayerRef == none)
PlayerRef = Game.GetPlayer()
endif
Self.RegisterForRemoteEvent("OnPlayerLoadGame", PlayerRef)
endEvent
Event OnUnload()
ObjUnloadedBool = true
endEvent
Event OnLoad()
if (ObjUnloadedBool == true && (SoundPlaying == true || Self.IsRadioOn() == true))
; assume the sound is not playing
; because the object unloaded previously
ObjUnloadedBool = false
CurrentSoundInstance = -1
ChangeSongState(true, true)
endif
endEvent
Event Actor.OnPlayerLoadGame(Actor akSender)
if (SoundPlaying == true)
CurrentSoundInstance = -1
ChangeSongState(true, true)
endif
EndEvent
Function ChangeSongState(bool state, bool force = false)
;line57
if (PlayerRef == none)
PlayerRef = Game.GetPlayer()
Self.RegisterForRemoteEvent("OnPlayerLoadGame", PlayerRef)
endif
if ((SoundPlaying == false && state == true) || force == true)
;line64 no sound is playing, so start playing the sound because
; we are turning on.
Self.SetRadioOn(true)
if (CurrentSoundInstance == -1 || force == true)
CurrentSoundInstance = EdenRadioGitaSungInSanskrit.Play(Self)
SoundPlaying = true
else
; assume the CurrentSoundInstance is playing.
; TODO: Figure out how to see if audio is still playing.
SoundPlaying = true
endif
Sound.SetInstanceVolume(CurrentSoundInstance, 1.0)
else if (SoundPlaying == true && state == false)
; line77sound is playing, so QUIET the current sound, but don't stop playing it.
; Volume change since we don't want the music to actually stop
; playing when the radio itself is turned off.
Self.SetRadioOn(false)
SoundPlaying = false
if (CurrentSoundInstance != -1)
Sound.SetInstanceVolume(CurrentSoundInstance, 0.0)
endif
endif
endFunction
;line88
Event OnActivate(ObjectReference akActionRef)
if (SoundPlaying == true)
ChangeSongState(false)
else
ChangeSongState(true)
endif
endEvent

This is the error I received

Papyrus Compiler Version 2.8.0.4 for Fallout 4
Copyright © ZeniMax Media. All rights reserved.
Starting 1 compile threads for 1 files...
Compiling "Radios:EdenGitaRadioStereoProperty"...
C:\Users\billi\AppData\Local\Temp\PapyrusTemp\Radios\EdenGitaRadioStereoProperty.psc(57,30): no viable alternative at input 'state'
C:\Users\billi\AppData\Local\Temp\PapyrusTemp\Radios\EdenGitaRadioStereoProperty.psc(64,31): no viable alternative at input 'state'
C:\Users\billi\AppData\Local\Temp\PapyrusTemp\Radios\EdenGitaRadioStereoProperty.psc(77,6): required (...)+ loop did not match anything at input 'if'
C:\Users\billi\AppData\Local\Temp\PapyrusTemp\Radios\EdenGitaRadioStereoProperty.psc(77,34): no viable alternative at input 'state'
C:\Users\billi\AppData\Local\Temp\PapyrusTemp\Radios\EdenGitaRadioStereoProperty.psc(88,0): mismatched input 'endFunction' expecting ENDIF
No output generated for Radios:EdenGitaRadioStereoProperty, compilation failed.
Batch compile of 1 files finished. 0 succeeded, 1 failed.
Failed on Radios:EdenGitaRadioStereoProperty
Link to comment
Share on other sites

LadyEdith, you don't need the script I wrote anymore, based on what SKK50 wrote. If you create a radio station with zero range you can have your radio play the looping song without the radio station showing up on the Pipboy.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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