Ez0n3 Posted September 10, 2017 Share Posted September 10, 2017 Is there any way to save custom data to each ref/alias in a RefCollectionAlias? For instance, a RefCollectionAlias full of Actor Refs. Each Ref is already in the vanilla game and I don't want to edit them. But what I would like to do is store a bit of data for each ref while it's in the alias. After it is removed, I don't care what happens to it. RefCollectionAlias Property myAliasActors Auto ; To Add myAliasActors.AddRef(akActorRef) ; To Remove myAliasActors.RemoveRef(akActorRef) ; To Find myAliasActors.Find(akActorRef) ; To Get at Index myAliasActors.GetAt(aiIndex)How would I go about saving a custom Property such as "Potion myFavFood" to each alias in the collection? IE: While they're in the collection, I can set and get their "myFavFood". But after they're removed from the collection, it gets wiped. While they're in the RefCollectionAlias, I would like to be able to do something like: Actor myActoreRef = myAliasActors.GetAt(aiIndex) as Actor myActoreRef.myFavFood = NukaColaSo somewhere, I need to have: Potion Property myFavFood AutoThis is where I'm stumped. I have a script attached to the RefCollectionAlias, but I can't seem to get at each alias separately - only the Refs. I tried casting the Actor Ref in the collection to a new type which has the property like: Scriptname ActorExtensionScript extends Actor Potion Property myFavFood AutoIn-order to be able to call it like: ActorExtensionScript myActoreRef = myAliasActors.GetAt(aiIndex) as ActorExtensionScript myActoreRef.myFavFood = NukaColaBut that doesn't seem to "stick". I can put a custom function in there and try to call it with a debug messagebox, but that never triggers. So my question is, is there a way to store custom data into each alias in the collection? Thanks :) Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 10, 2017 Share Posted September 10, 2017 I think you're on the right track sort of. I haven't actually tested this but I saw someone in another place asking about it and the suggestion was to put a script on the refcollection which had the property/ies you want example myPropertyScript. Then access it with something like this (refCollection.GetAt(x) as myPropertyScript).SomePropertyInTheScript. Link to comment Share on other sites More sharing options...
Ez0n3 Posted September 10, 2017 Author Share Posted September 10, 2017 (edited) Hmm, I'll have to poke at it some more. If say I attach this script to the collection: Scriptname ActorExtensionScript extends Actor int Function Test() return 500 EndFunctionAnd then in the quest I do something like this: ActorExtensionScript myActoreRef = myAliasActors.GetAt(aiIndex) as ActorExtensionScript int i = myActoreRef.Test() Debug.Notification("Test="+ i)The script will compile, but the in-game result of "Test()" is always "0". The function resolves at compile, but at runtime, I get nothing. :/ I'll try a few more things, thanks for the info. PS: I also tried something like: myAliasActors.AddRef(akActorRef as ActorExtensionScript)Which compiles also, but at runtime, it refuses to add the "ref as ActorExtensionScript" to the collection. The collection is always size "0". But it gets added if i just do it normally: .AddRef(akActorRef) Edited September 10, 2017 by Ez0n3 Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 10, 2017 Share Posted September 10, 2017 That script sample Scriptname ActorExtensionScript extends Actor is not valid for a RefCollectionAlias. It needs to extend RefCollectionAlias. If you have papyrus logging turned on you should see some error spout about the types not being compatible. Link to comment Share on other sites More sharing options...
Ez0n3 Posted September 10, 2017 Author Share Posted September 10, 2017 (edited) Oh, ya I mean what I have on the collection is a script like: Scriptname myRefCollectionAliasScript extends RefCollectionAlias Potion Property myFavFood Auto ; i think this is a single instance that all refs in the collection share?If say Ref01 sets "myFavFood" to "NukaCola" and then later, Ref02 sets "myFavFood" to "Whiskey", Ref03 sets "myFavFood" to "Jet". I think no matter where you pull it from, it would be the last one set? I'll have to try, I thought all refs in the collection shared a single instance of RefCollectionAlias script. IE: Later if I check what their fav food is, I want to get:Ref01 myFavFood = NukaColaRef02 myFavFood = WhiskeyRef03 myFavFood = Jet If they all share a single instance, it would always get the last one set for all refs? It would be:Ref01 myFavFood = JetRef02 myFavFood = JetRef03 myFavFood = Jet Pretty sure, I will have to triple check x) What I thought you meant was add both scripts to the collection script field:myRefCollectionAliasScriptActorExtensionScript And then try to do: ActorExtensionScript myActoreRef = myAliasActors.GetAt(aiIndex) as ActorExtensionScriptWhich required me to check "Incompatible" in-order to add ActorExtensionScript to the collection as well as the RefCollectionAlias script. Edited September 11, 2017 by Ez0n3 Link to comment Share on other sites More sharing options...
shavkacagarikia Posted September 10, 2017 Share Posted September 10, 2017 Afaik If you set property on script which extends refcollectionalias then all collection elements will share that property value. I'm gonna suggest a different approach. Just make a new actor value ActorFavFood for example. Make a function in your controler script (you have it right?) Which returns a needed potion based on what float value is passed. Then you set actor value for needed actor in collection. And when needed you just call function and pass actor value there and it will return needed potion for that particular actor. I can explain in more detail if you want to use this method. Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 10, 2017 Share Posted September 10, 2017 It is entirely possible that all refs within the collection share one instance of the script. As I said, I didn't test it. I just saw it mentioned in another place and thought I'd regurgitate it in case someone wanted to try it. Another option that you could use if you're not going to have more than 128 refs in the collection at any given time. Use an array property and a custom add/remove function in the refcollectionalias script. You call your custom add ref function which adds an entry to the array for the new ref, then adds the ref to the collection stack. Likewise for the remove. Remove ref and then remove array index. This way you don't have to rely on remembering to do both in other script locations. Though if anyone else added/removed to the collection things would break. Link to comment Share on other sites More sharing options...
Ez0n3 Posted September 11, 2017 Author Share Posted September 11, 2017 (edited) Afaik If you set property on script which extends refcollectionalias then all collection elements will share that property value. I'm gonna suggest a different approach. Just make a new actor value ActorFavFood for example. Make a function in your controler script (you have it right?) Which returns a needed potion based on what float value is passed. Then you set actor value for needed actor in collection. And when needed you just call function and pass actor value there and it will return needed potion for that particular actor. I can explain in more detail if you want to use this method.I had forgotten about ActorValue, that would probably work for the actors. Ty :smile: It is entirely possible that all refs within the collection share one instance of the script. As I said, I didn't test it. I just saw it mentioned in another place and thought I'd regurgitate it in case someone wanted to try it. Another option that you could use if you're not going to have more than 128 refs in the collection at any given time. Use an array property and a custom add/remove function in the refcollectionalias script. You call your custom add ref function which adds an entry to the array for the new ref, then adds the ref to the collection stack. Likewise for the remove. Remove ref and then remove array index. This way you don't have to rely on remembering to do both in other script locations. Though if anyone else added/removed to the collection things would break.Ya, there are not that many, so for non actors, I will turn a bunch of separate alias's into an array. I had all the add/rem/getat etc stuff already in functions, so I have been messing with swapping the collection with an array of aliases for non actors. Thanks very much for the suggestions :smile: Edited September 11, 2017 by Ez0n3 Link to comment Share on other sites More sharing options...
Ez0n3 Posted September 11, 2017 Author Share Posted September 11, 2017 (edited) I ended up using the array of aliases, but another option I found that might interest some would be to store the ref data onto the RefCollectionAlias script. The main reason I didn't want to do this was it would require x amount of "Potion" properties, x amount of whatever else I want to store. I could make them into arrays (array of Potion, array of Armor, etc), but it gets really hairy after many are added. But if necessary, what could be done is have an array of a structure in the RefCollectionAlias script. But that would need to be kept in sync with the collection. Something like: Scriptname myRefCollectionAliasScript extends RefCollectionAlias Struct RefData ObjectReference myObjRef = None Potion myFavFood = None bool myBool = False int myInt = 0 float myFloat = 0.0 EndStruct RefData[] Property ObjRefData Auto ObjRefData = new RefData[GetSizeOfCollection()] if ref not in collection find next free index ObjRefData[index].myObjRef = theRef ObjRefData[index].myFavFood = NukaCola get this refs fav food find this ref == ObjRefData[index].myObjRef return ObjRefData[index].myFavFoodSomething like that. But that's a bit over what I need. It might help someone else though :wink: Edited September 11, 2017 by Ez0n3 Link to comment Share on other sites More sharing options...
JonathanOstrus Posted September 11, 2017 Share Posted September 11, 2017 (edited) Well you can't initialize the array like that outside of a function. And initializing with the size of the collection will be problematic unless it's already full. You'd want to initialize empty with [0] and then use the array.Add() and array.Remove() All you'd need to do is check if Array.Length <= 128 then add. The Add and Remove have some processing delay compared to a preallocated array, but if you had to loop through looking for a free spot it's sort of a trade off. Edited September 11, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
Recommended Posts