prinyo Posted May 8, 2016 Author Posted May 8, 2016 You can do this on Actor or ReferenceAlias. You have these events that are available: ; Event received when this actor starts a new package Event OnPackageStart(Package akNewPackage) EndEvent ; Event received when this actor's package changes Event OnPackageChange(Package akOldPackage) EndEvent ; Event received when this actor's package ends Event OnPackageEnd(Package akOldPackage) EndEvent Yes, but that has to be attached to each and every actor... What I hope exists is a place where I can attach the script and then have a event that would look like: Event OnPackageStart(Package akNewPackage, actor NPCref) or similar -------------------------------- OK, so it is not possible to do this as a general functionality. What are the possibilities? 1. To add scripts to 40+ packages 2. To create a quest (oli3d suggested earlier on the chat creating a quest that scans for beds on cell load, checking if the beds are occupied and assigning triggers to them) 3. ?
Guest Posted May 8, 2016 Posted May 8, 2016 1. editing 40 vanilla packages is long and risky. But probably the quickest solution. 2. scanning for beds will be a pain. And, do you have an easy way to track cell changes? Or a safe function to find furniture in F4SE? Not yet. 3. adding a single script to a refalias, and then duplicating it is quick. But then you have to fill all actors inside. So at the end is long.
prinyo Posted May 8, 2016 Author Posted May 8, 2016 From what I understood I add the PC as alias in the Quest and use it to detect cell changes. Then put the results of FindAllReferencesOfType() search for beds in another alias and add triggers. However this is too complicated for me at my current level of CK understanding. Also it seems a lot less performance-friendly. So editing packages it is.
ag12 Posted May 8, 2016 Posted May 8, 2016 From what I understood I add the PC as alias in the Quest and use it to detect cell changes. Then put the results of FindAllReferencesOfType() search for beds in another alias and add triggers. However this is too complicated for me at my current level of CK understanding. Also it seems a lot less performance-friendly. So editing packages it is. If you ever plan on publishing this mod, please make sure you give proper warning about the fact that it uses poor methods and alters all Sleep packages found in the game. People need to be made aware.
prinyo Posted May 8, 2016 Author Posted May 8, 2016 From what I understood I add the PC as alias in the Quest and use it to detect cell changes. Then put the results of FindAllReferencesOfType() search for beds in another alias and add triggers. However this is too complicated for me at my current level of CK understanding. Also it seems a lot less performance-friendly. So editing packages it is. If you ever plan on publishing this mod, please make sure you give proper warning about the fact that it uses poor methods and alters all Sleep packages found in the game. People need to be made aware. What is the better method? This is the best method possible. The fastest, the most "organic" and "native", no scans, no chain of references, no memory impact, no complicated scripting that can cause problems. People who install mods should be aware that mods by definition "alter stuff in the game". And it is not exactly "altering". I'm adding a script to the packages and not changing anything that is already there. I'm going to attach the script to 5-10 packages. The ones with "default" in the name and leave custom ones like "InstituteMadisonSleep" that are used for a single NPC untouched. Also it is one and the same script. It is not a fragment that is copy/pasted around making it hard to maintain, debug and update. I really don't see a better way to do it. This is the current situation: On the top left are the packages that use the Sleep template. Most of them a custom and I have decided to not touch them. On the right is the package edit that in FO4 has also an option to attach a full script. Currently I'm running a debug there as seen in the script window.
ag12 Posted May 8, 2016 Posted May 8, 2016 So as far as I can tell, it's not as clean as you describe it. Although adding a fragment that references a Quest script to run a single function to 5-10 packages sounds a lot better than adding something to 40 packages or even to all actors in the game, I still think there may be a lot of debris left. And I don't really think this can be described as non-complicated scripting. It's a script that stores something, then does something and at a later point in time retrieves the data and does something again. Which leaves a lot of stuff in memory, and that stuff is going to be left in the save game even after you uninstall the mod. Also, fiddling with master behavior packages isn't a great idea - I'm just saying. Experience tells me things can go wrong with this. I may be wrong. Don't forget to include a "Uninstall mod" function - to re-equip all currently naked actors with their gear and shut the functions down - because once we get the CellScan framework, that's going to be used instead. EDIT: I just saw your picture. Don't do that. Cleaner way is to add a new Quest, add a new Script to the Quest and then write the code in there like function Undress(actor akActor) etc etc. Then just reference the functions in that Quest script from the packages. That way you don't duplicate your code and paste it all over the packages, instead the code is kept in one single place.
Guest Posted May 8, 2016 Posted May 8, 2016 I may propose a smaller improvement on the scripts, to avoid to write tons of code for each of them. Create a Quest, create a script that extends Quest. Have an array of Actors have an array of Armors Add a function: setSleepOutfit(Actor a), and restoreNormalOutfit(Actor a) In the first function check if the actor is in the array, if not, then add it, grab the armor, and save it, and then add the sleep outfit you want (that should be in a Property) In the other function get the index of the actor, and restore the saved armor. You may want to create a struct, in case you like to use a single array. This is a little bit more advanced. And then on the "sleep package scripts", just add the property referring your quest script (<scriptname> Property <Quest name> Auto), and then call the first function in the OnStart, and the other function in the OnEnd. If you will do a second version of your mod, you will need to change only the script on the quest to add new features.
prinyo Posted May 8, 2016 Author Posted May 8, 2016 I'm a bit confused. It is already the same script. Open the package, select the script from the scripts list, add, done. It is one and the same script. I'm not trying to do this in the easiest way, I'm trying to do it in the best way possible. That's why I made this thread :-) So if is a bad way I'll just try another.
Guest Posted May 8, 2016 Posted May 8, 2016 You can re-use the same code for multiple packages. But you have to re-fill the properties every time. And if you day you want to add different sleep outfits based on some conditions, then it can be a pain to re-edit all the scripts in the packages to re-set the properties. If you do it only once in a quest script, then you can do future upgrades way more easy.
prinyo Posted May 8, 2016 Author Posted May 8, 2016 "grab the armor, and save it" Seems this is not possible at the moment... http://www.creationkit.com/fallout4/index.php?title=UnequipItemSlot_-_Actor and the other similar functions do not return anything. Seems there is no way to find out what the NPC is wearing.
ag12 Posted May 8, 2016 Posted May 8, 2016 Yeah, I had issues with that as well in F4SS. Wanted to implement a simple "Is Actor Naked" check - turns out no functions are available. Right now you can easily do the undress part by .SetOutfit(outfitProperty) with outfitProperty pointing to an empty outfit, but well, actor is going to stay naked for the rest of the game unless you call Reset(), which also moves the actor back to editor position, thus is completely useless.
prinyo Posted May 8, 2016 Author Posted May 8, 2016 So for all intents and purposes the idea for such a mod is doomed at the moment. I need to find another idea to experiment with. There was a concern that adding scripts directly to the packages can lead to conflicts with other mods that add such scripts. I made a test. I made 2 different esp files and attached 2 different scripts with similar content to the same packages in them. The first script (PSS_SleepPackScript): Scriptname PSS_SleepPackScript extends Package Event OnStart(Actor akActor) Debug.Notification("This package started on " + akActor)endEvent Event OnEnd(Actor akActor) Debug.Notification("This package finished on " + akActor)endEvent The second script (PPPTest1) , added to the same packages in the second esp file is the same but the notification says "Haha". They coexisted perfectly in the game: They were also handled correctly by FO4Edit:
ag12 Posted May 8, 2016 Posted May 8, 2016 Of course they co-exist and both run. It's just a really messy way of handling the scripts. You have unnecessary copies of the same script, since you should be referencing them in a Quest script instead. It's not about whether it works or not - it's about whether it's done properly or done hastily. Plastering scripts onto multiple objects when you can just have one script and reference that over and over again is an example of done hastily. I think you should read through this page and all sub-pages. There are some good tutorials on there, including one that goes into referencing.
prinyo Posted May 8, 2016 Author Posted May 8, 2016 Of course they co-exist and both run. It's just a really messy way of handling the scripts. You have unnecessary copies of the same script, since you should be referencing them in a Quest script instead. It's not about whether it works or not - it's about whether it's done properly or done hastily. Plastering scripts onto multiple objects when you can just have one script and reference that over and over again is an example of done hastily. I think you should read through this page and all sub-pages. There are some good tutorials on there, including one that goes into referencing. Again - it is the same script. There are no "unnecessary copies" and there is no "them". "when you can just have one script and reference that over and over again" is exactly what I'm doing. Except for referencing it - I don't need to. There is a way now to avoid all the unnecessary complications. I really dion't understand why a solution that seems better on any account is considered worse.
ag12 Posted May 8, 2016 Posted May 8, 2016 Look, if you put that same script on each of the packages, the game creates a script instance for each .. instance.. of the script. You know, if you ask here and one half-decent scripter (me) and an extremely decent scripter (CPU) tell you that you should be running the script on a Quest and referencing it, how big is the chance that we're just making this shit up to annoy you? Please, if you ask for the best way like you did, then do follow up on that if you're being told what the best way is. Thank you and if you need any help with the whole referencing, let me know, happy to help.
Guest Posted May 8, 2016 Posted May 8, 2016 Just a couple of considerations on performance, and instances. OPTION 1 - It is the same script. You create the source script once, and compile it once. Then you go in all packages and attach it to the package. Then you add the properties for the armors to be replaced, and some variables to keep the old armors. OPTION 2 - use a quest script You create the source script once, with all the functions, the properties, and the variables. in a quest. You do an empty script for the package, with just one property (the quest script), that calls a function at begin, and one at end. === (as example I will consider 30 packages to be updated) MEMORY OPT 1: (more memory) 1 instance for each actor that is running the package. a set of variables to store the armors, a set of properties to get the night outfit MEMORY OPT 2: (less memory) 1 instance for the quest with only once the properties and the variables 1 instance for each actor that is running the package with only the referral property
prinyo Posted May 8, 2016 Author Posted May 8, 2016 Me today - the several times I almost "got it" :-) I guess the reason I'm confused in all of this is because I don't understand the quest approach and I'm missing something in the bigger picture. And the reason I keep asking Why is because I want to understand the logic behind all this so I can use it in the future. The reason I want to make this mod is not because I want naked people sleeping in the game, but because I want to learn and understand how it works. So in the next few days I'm going to experiment with this and see where it gets me. Thanks for your help!
ag12 Posted May 8, 2016 Posted May 8, 2016 The thing you should focus on is Quests. Once you get the concept of how Quests work and what they do for the modder, you'll have unlimited possibilities. Except for doing what you want to do, because Bethesda will not have implemented the functions you need to do it. Count on it!
Guest Posted May 9, 2016 Posted May 9, 2016 Example code (super simplified) Scriptname myNakedSleep extends Quest function iAmGoingToSleep(Actor a) a.unequipAll() endFunction and then in your package myNakedSleep Property myNakedSleepQuest Auto Event OnStart(Actor akActor) myNakedSleep.iAmGoingToSleep(akActor) EndEvent
prinyo Posted May 9, 2016 Author Posted May 9, 2016 Thanks for the example code. I think it helped me finally understand what are we talking about. Translated into my web-developers mindset the quest script is a "library class" that contains the actual code the package scripts call. And the Quest thingy is a workaround in order to get it included into the system. Basically, if I want to translate this into PHP it looks like: include ("myNakedSleep.php"); $myNakedSleep = new MyNakedSleep(); --> we use the Quest functionality in CK in order to achieve this - inject and initialize the library object and then $mynakedSleep->goToSleep($actor); --> the package object calls the function from the library I can completely agree that this is way better programming style than simply assigning the same script everywhere. It is more modular, more expandable and simply more beautiful solution. But I want to point out that the other solution (with assigning the script to the packages) while not so elegant is still technically correct. And I still believe it is more memory efficient. It is been noticed before that Papyrus uses the term "Reference" not in the same sense as all the other languages and all the "references" are actually passed by value. So for each and every function or event call the parameters are duplicated in the memory. This means that in the example when a NPC goes to sleep the package script that already has received it's own copy of the actor object will call the Quest script and will give it yet another copy of the actor object. And now instead of one we have two of them each within the scope of their script. And since each NPC that goes to sleep will create two instances - one of the each script, all the properties will also be created within the script. Meaning - if John and Samantha are sleeping you have now 2 instances of the Quest script, each of them with it's own set of variables and properties (sleep outfit or whatever you assign via the properties window in CK). And with duplicated John and Samantha objects within the package script. It's 3AM here now so I'm not sure if I'm explaining it correctly. And it is quite possible that I;m wrong. But I completely agree that using the library object is a better way to do it.
Guest Posted May 9, 2016 Posted May 9, 2016 Your statement is correct. But you have only two options to create a reference: 1) Using a property 2) Getting a form from file And "instances" are not "references" they are actual threads in the VM.
prinyo Posted May 9, 2016 Author Posted May 9, 2016 Your statement is correct. But you have only two options to create a reference: 1) Using a property 2) Getting a form from file And "instances" are not "references" they are actual threads in the VM. I edited my post while you were posting this one. Since LL doesn't allow two consecutive posts I had to edit it :-)
prinyo Posted May 13, 2016 Author Posted May 13, 2016 http://www.nexusmods.com/fallout4/mods/13316/? This is undressing and redressing actors somehow. But there is no source in the files.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.