Jump to content

Need help with a container formlist


jp2x

Recommended Posts

I am working on a big radio mod. To alleviate lag, I need to move a random holotape from one box to another. I am tired and would really appreciate some assistance. Please?

 

I started by trying to generate an OnItemAdded event. The code for that is at the bottom of the spoiler. I know this should be easy but I am just worn out.

 

 

Scriptname MusiciansModRadio002a extends Quest Conditional

FormList Property akTapeList auto ;an empty formlist
ObjectReference Property MusiciansModHolotapeBay Auto
ObjectReference Property MusiciansModHolotapeAutoloader Auto
Int Property aiItemCount Auto Conditional
Int Property iMusTapeTotal Auto Conditional
Int Property aiCounter Auto Conditional
;Int Function GetItemCount(Form akAllHolotapeList)
;Int Function GetItemCount(Form akItem)
FormList Property akAllHolotapeList auto

;Int Property index Auto Conditional
;FormList Property akChosenTapeList auto
;ObjectReference Property MusiciansModHolotapeAutoloader Auto


Function ChangeTapes()

;Create formlist akTapeList from container:MusiciansModHolotapeAutoloader

iMusTapeTotal = akTapeList.GetSize()
aiCounter= akTapeList.GetSize()
Debug.Trace(aiCounter)
MusiciansModHolotapeBay.Reset()

; While aiCounter> 0
; akTapeList.AddForm(akBaseItem) ; adding list of items in container
; aiCounter-= 1
; Debug.Trace("Item, Added!")
; EndWhile


MusiciansModHolotapeBay.AddItem(akTapeList.GetAt(Utility.RandomInt(0, (iMusTapeTotal))), aiItemCount)
; MusiciansModHolotapeBay.AddItem(akTapeList.GetAt(Utility.RandomInt(0, (iMusTapeTotal - 1))), aiItemCount)

akTapeList.Revert()

EndFunction






;Int Property aiItemCount Auto Conditional
;FormList Property akTapeList auto ;an empty formlist

;Function AddInventoryEventFilter(Form akAllHolotapeList) native


;Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)

; While aiItemCount > 0
; akTapeList.AddForm(akBaseItem) ; tracking list of items in container
; aiItemCount -= 1
; Debug.Trace("Item, Added!")
; EndWhile

;EndEvent

;Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)

; While aiItemCount > 0
; akTapeList.RemoveAddedForm(akBaseItem) ; tracking list of items in container
; aiItemCount -= 1
; Debug.Trace("Item, Removed!")
; EndWhile

;EndEvent

 



			
		
Link to comment
Share on other sites

I've been at this for another 2 hours. I'm sorry to keep asking but this is my first Fallout 4 script. Can I have another hint to getting this to work?

 

My container's script:

 

 

ScriptName MusiciansModHoloLoaderScript01 extends ObjectReference

Int Property aiItemCount Auto Conditional
FormList Property akTapeList auto ;an empty formlist

Function AddInventoryEventFilter(Form akAllHolotapeList) native


Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)

While aiItemCount > 0
akTapeList.AddForm(akBaseItem) ; tracking list of items in container
aiItemCount -= 1
Debug.Trace("Item, Added!")
EndWhile

EndEvent

Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)

While aiItemCount > 0
akTapeList.RemoveAddedForm(akBaseItem) ; tracking list of items in container
aiItemCount -= 1
Debug.Trace("Item, Removed!")
EndWhile

EndEvent

 

 

 

My radio quest script:

 

 

Scriptname MusiciansModRadio002a extends Quest Conditional

FormList Property akTapeList auto ;an empty formlist
ObjectReference Property MusiciansModHolotapeBayAlias Auto
ObjectReference Property MusiciansModHolotapeAutoloaderAlias Auto
Int Property aiItemCount Auto Conditional
Int Property iMusTapeTotal Auto Conditional
Int Property aiCounter Auto Conditional
FormList Property akAllHolotapeList auto
;Int Function GetItemCount(Form akAllHolotapeList)
;Int Function GetItemCount(Form akItem)
;FormList Property akChosenTapeList auto


Event OnInit() ; Special event to receive when the door is activated
; Register for Activate event from the secret door
RegisterForRemoteEvent(MusiciansModHolotapeAutoloaderAlias, "OnItemAdded")
RegisterForRemoteEvent(MusiciansModHolotapeAutoloaderAlias, "OnItemRemoved")
EndEvent

; Note the type in the event name matches the type of the first parameter, and is also the script where the
; event is originally defined.


Function ChangeTapes() ;Create formlist akTapeList from container:MusiciansModHolotapeAutoloader

iMusTapeTotal = akTapeList.GetSize()
aiCounter= akTapeList.GetSize()
Debug.Trace(aiCounter)
MusiciansModHolotapeBayAlias.Reset()

MusiciansModHolotapeBayAlias.AddItem(akTapeList.GetAt(Utility.RandomInt(0, (iMusTapeTotal))), aiItemCount)
; MusiciansModHolotapeBay.AddItem(akTapeList.GetAt(Utility.RandomInt(0, (iMusTapeTotal - 1))), aiItemCount)

akTapeList.Revert() ;Chosen tape has been moved so we empty the list for next time

EndFunction

Event ObjectReference.OnActivate(ObjectReference akSender, ObjectReference akActionRef)
Debug.Trace(akSender + " was activated by " + akActionRef)
EndEvent




Link to comment
Share on other sites

Ok, so there are a few things you're missing here. You've got

   RegisterForRemoteEvent(MusiciansModHolotapeAutoloaderAlias, "OnItemAdded")
   RegisterForRemoteEvent(MusiciansModHolotapeAutoloaderAlias, "OnItemRemoved")

but you aren't doing anything with it in your quest script, so even if those events fire on your container, the quest can't handle them. I'd write you an example script, but I honestly don't know why you are doing what you are doing (mitigating lag somehow?) or what your ultimate goal is (a radio mod that plays from holotapes?). If you gave me a bit more information I could help more.

Edited by Reneer
Link to comment
Share on other sites

Sorry. My script isn't doing anything with it because I got stuck. Here is some more detail.

 

The radio:

 

I have a radio station that will play a song if the corresponding holotape is placed in a container. That part works fine. The problem is that using quest conditions to manage the playlist doesn't work well. The radio playlist is customizable by placing holotapes in the loader container. So, each time the conditions randomly select a song that isn't in the loader, no song plays and the playlist loop starts over. This creates dead air on the radio; sometimes over a minute.

 

The goal:

 

I would like to place holotapes in a container (holotapeloader) and select one at random to copy to a second container (holotapebay). I've already started changing the radio quest so it will play based on the second container.

 

I was trying to empty and rebuild a formlist from the first container, select from the list at random, then empty the second container and copy the selection to the second container.

 

Your help is much appreciated.

Edited by jp2x
Link to comment
Share on other sites

You seem to be making this overly complicated. Having a second container is simply making things more complex than they need to be, since everything can be done from your 1st container. Unless you have that 2nd container for a reason?

 

Here is some code that might help you. Note that I haven't tested to see if this compiles, but it should give you a leg up:

Scriptname RenMusicSelectQuestScript extends Quest Conditional

Formlist Property MySongs Auto
; A formlist holding all your base Tapes

Objectreference Property CurrentSong Auto Conditional
; use this as the conditional in your Radio Scene

Objectreference Property RadioContainer Auto
; Your container that the player adds tapes into

Scene Property MyRadioScene Auto
; the scene that plays the songs

Event OnInit()
	Self.RegisterForRemoteEvent(MyRadioScene, "OnEnd")
	; registers this Quest to receive the OnEnd event from the Radio Scene
	
	int tries = 0
	CurrentSong = none
	while (tries <= 100 && CurrentSong == none)
		int randomnum = Utility.RandomInt(0, (MySongs.GetSize() - 1))
		if ( RadioContainer.GetItemCount( MySongs.GetAt(randomnum) ) >= 1)
			CurrentSong = MySongs.GetAt(randomnum)
			; CurrentSong now points to one of your tapes
		endif
		tries += 1
	endWhile
	
	if (MyRadioScene.IsPlaying() == false)
		MyRadioScene.Start()
		; forces the scene to start if it hasn't already
	endif
endEvent

Event Scene.OnEnd(Scene akSender)
	; radio has finished playing the song scene here.

	CurrentSong = none
	int tries = 0
	while (tries <= 100 && CurrentSong == none)
		int randomnum = Utility.RandomInt(0, (MySongs.GetSize() - 1))
		if ( RadioContainer.GetItemCount( MySongs.GetAt(randomnum) ) >= 1)
			CurrentSong = MySongs.GetAt(randomnum)
		endif
		tries += 1
	endWhile
	
	if (MyRadioScene.IsPlaying() == false)
		MyRadioScene.Start()
	endif	
endEvent
If you end up using this code in your mod, please give me credit in the ReadMe / mod description. Edited by Reneer
Link to comment
Share on other sites

I absolutely will! I'll give this a try and let you know how it goes.

 

To clarify, as I obviously have plenty to learn, "; A formlist holding all your base Tapes". A formlist containing all of the song holotapes that I've created. It's a "all possible choices" list.

 

"Objectreference Property CurrentSong Auto Conditional
; use this as the conditional in your Radio Scene" So, 'if currentsong=a certain tape' for each song.

 

"while (tries <= 100 && CurrentSong == none)" This gives the script 100 tries to select a song and fill currentsong. Is the 100 an arbitrary number? Is it better than using MySongs.GetSize() to set tries and subtracting from the total?

 

I'm really tired but I'll try this right now. And, thank you!

Link to comment
Share on other sites

I absolutely will! I'll give this a try and let you know how it goes.

 

To clarify, as I obviously have plenty to learn, "; A formlist holding all your base Tapes". A formlist containing all of the song holotapes that I've created. It's a "all possible choices" list.

Exactly.

 

"Objectreference Property CurrentSong Auto Conditional

; use this as the conditional in your Radio Scene" So, 'if currentsong=a certain tape' for each song.

Yup.

 

"while (tries <= 100 && CurrentSong == none)" This gives the script 100 tries to select a song and fill currentsong. Is the 100 an arbitrary number? Is it better than using MySongs.GetSize() to set tries and subtracting from the total?

 

I'm really tired but I'll try this right now. And, thank you!

The 100 is pretty arbitrary. It's just so that the script won't get stuck in the while loop forever in case something goes wrong. It's better than MySongs.GetSize() because you could, theoretically, have the RandomInt function return multiples of the same number during different passes. Edited by Reneer
Link to comment
Share on other sites

Here is the code as I adjusted references:

 

 

Scriptname MusiciansModRadio002a extends Quest Conditional

Formlist Property akAllHolotapeList Auto
; A formlist holding all your base Tapes

Objectreference Property CurrentSong Auto Conditional
; use this as the conditional in your Radio Scene

Objectreference Property MusiciansModHolotapeAutoloader Auto
; Your container that the player adds tapes into

Scene Property MusiciansMod01aRadioQuest001SceneA Auto
; the scene that plays the songs

Event OnInit()
Self.RegisterForRemoteEvent(MusiciansMod01aRadioQuest001SceneA, "OnEnd")
; registers this Quest to receive the OnEnd event from the Radio Scene

int tries = 0
CurrentSong = none
while (tries <= 100 && CurrentSong == none)
int randomnum = Utility.RandomInt(0, (akAllHolotapeList.GetSize() - 1))
if ( MusiciansModHolotapeAutoloader.GetItemCount( akAllHolotapeList.GetAt(randomnum) ) >= 1)
CurrentSong = akAllHolotapeList.GetAt(randomnum)
; CurrentSong now points to one of your tapes
endif
tries += 1
endWhile

if (MusiciansMod01aRadioQuest001SceneA.IsPlaying() == false)
MusiciansMod01aRadioQuest001SceneA.Start()
; forces the scene to start if it hasn't already
endif
endEvent

Event Scene.OnEnd(Scene akSender)
; radio has finished playing the song scene here.

CurrentSong = none
int tries = 0
while (tries <= 100 && CurrentSong == none)
int randomnum = Utility.RandomInt(0, (akAllHolotapeList.GetSize() - 1))
if ( MusiciansModHolotapeAutoloader.GetItemCount( akAllHolotapeList.GetAt(randomnum) ) >= 1)
CurrentSong = akAllHolotapeList.GetAt(randomnum)
endif
tries += 1
endWhile

if (MusiciansMod01aRadioQuest001SceneA.IsPlaying() == false)
MusiciansMod01aRadioQuest001SceneA.Start()
endif
endEvent

 

 

 

It almost compiles.

 

C:\Users\OWNER\AppData\Local\Temp\PapyrusTemp\MusiciansModRadio002a.psc(24,3): type mismatch while assigning to a objectreference (cast missing or types unrelated)
C:\Users\OWNER\AppData\Local\Temp\PapyrusTemp\MusiciansModRadio002a.psc(44,3): type mismatch while assigning to a objectreference (cast missing or types unrelated)

It seems to be having trouble with: CurrentSong = akAllHolotapeList.GetAt(randomnum)

It compiles if the line is commented out both times.

 

 

I am a bit concerned as the station has tapes for all of the game's base songs and I expect roughly 200+ songs by the time the mod has a formal release. If someone makes a 'favorite songs' playlist of 20 songs, that would be 20 of 200+ and 100 tries could technically fail to find a song. But, if it fails to find a song, it just starts over anyway, right? So, no big deal.

Edited by jp2x
Link to comment
Share on other sites

  • Recently Browsing   0 members

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