xwhiteninjax Posted October 31, 2018 Posted October 31, 2018 I am used to equip my playerchar with items from console-batchfile-commands but discovered some nice possibilities with scripting and "OnInit()"-function. Using batch-files and sometimes changing mods/plugins is messing up with the batchfiles (wrong leading Prefix of the ID), the scriptfiles don't need any Loot-order, so it looks out, this should be the way to go... I have 3 problems to handle... a) playerchar equip with armor/weapons (without changing them), b) equip spells (solved, see example), c) equip with changed items (enchanted items for using wings) a) it is possible to add a simple quest to a special mod/plugin and use it to change the inventory of the playerchar - but this is more work than using batchfiles... so a nice script should be better... gathering the ID of the items before and then equip the playerchar with the items (and sometimes with more than "one", for example arrows or 2 swords for dual-fighting and so on) b) equip the playerchar with spells (from any plugin) was solved for my mod "vampiresuccubusplaystyle" with the following example, giving all races succubus-spells (even customraces) Spoiler function OnInit() actor PC = game.GetPlayer() spell SForm = game.GetFormFromFile(42094, "SuccubusRaceLite.esp") as spell spell SClaw = game.GetFormFromFile(168786, "SuccubusRaceLite.esp") as spell spell SSeduction = game.GetFormFromFile(138364, "SuccubusRaceLite.esp") as spell spell SRegen = game.GetFormFromFile(272955, "SuccubusRaceLite.esp") as spell spell SVision = game.GetFormFromFile(248032, "SuccubusRaceLite.esp") as spell if !PC.HasSpell(SForm as form) PC.AddSpell(SForm, true) PC.AddSpell(SClaw, true) PC.AddSpell(SSeduction, true) PC.AddSpell(SRegen, true) PC.AddSpell(SVision, true) endIf with this the spells would be added only once during the game.... maybe a similiar way could be used for weapons/armor ? c) I love to play succubus and change my followers to them (sometimes), too... .instead using the static Lillith-armor for succubi I want to use "animated wings"... with a batch-file this is easily solved batch-file for some items with animated wings Spoiler playerenchantobject 7100AA4A 33003897 ; GargoyleHorns and ForestWings PlayerChar playerenchantobject 7100AA4A 33003895 ; GargoyleHorns and BossWings PlayerChar playerenchantobject 7100AA4A 33006e8e ; GargoyleHorns and BossWings PlayerChar playerenchantobject 71087834 33003895 ; Blacksacrament Amulett and BossWings (Tundra) playerenchantobject 71087834 33003897 ; Blacksacrament Amulett and ForestWings (Tundra) playerenchantobject 71087834 33006e8e ; Blacksacrament Amulett and AlduinWings playerenchantobject 4f1F39ED 33003895 ; Hels Horns and BossWings PlayerChar and NPC playerenchantobject 4f1F39ED 33003897 ; Hels Horns and TundraWings PlayerChar and NPC playerenchantobject 4f1F39ED 33006e8e ; Hels Horns and AlduinWings PlayerChar and NPC playerenchantobject 5f020457 33006e8e ; SuccubusHorns and AlduinWings the problems with batchfiles are not only changes in loot-order, but with different numbers, too ... for example the same item and a special animated wing for followers/npc (and than more as one)... with batchfiles you have to use the same line again (so far, you reach the wanted count)... . a script (if possible) should solve the two problems , but I am not sure, if it is possible to use the console-command (or a script-equivalent) "playerenchantobject" any help would be fine (like a basic structure to use the "OnInit()"-function at creationtime of the playerchar ( showracemenu and LAL) beginning a new game
Guest Posted October 31, 2018 Posted October 31, 2018 I do not recommend using the event OnInit. It will not be fired when you reload the game. Now, you are speaking about the player, so its inventory it is stable in saves. It will be not for NPCs equipped items. But you should also check if a wereable object is still available on a game load, and if it is not the script should discard the reference. The best is to use the event OnPlayerLoadGame. This will be fired if you attach the script to a quest alias and the alias is assigned to the Player.
xwhiteninjax Posted October 31, 2018 Author Posted October 31, 2018 4 minutes ago, CPU said: I do not recommend using the event OnInit. It will not be fired when you reload the game. Now, you are speaking about the player, so its inventory it is stable in saves. It will be not for NPCs equipped items. But you should also check if a wereable object is still available on a game load, and if it is not the script should discard the reference. The best is to use the event OnPlayerLoadGame. This will be fired if you attach the script to a quest alias and the alias is assigned to the Player. the mentioned event "OnPlayerLoadGame" is better, you are right ... the items for NPC/Followers are to be equiped into the inventory of the playerchar, too... there are several existing plugins/mods for give them to the wanted npc/follower ingamestyle, so the effect will be done ( for example "sharing meals", changing inventory of the npc via dialog and so on)... the nice effect is, that putting the enchantment on horns/rings the wings will be vanishing during sex-scenes and afterwards spring to life, again... checking the itms before load... you are right again... I simply thought to choose some items from my plugins I always install and write down the ID before writing a script... but the better way should be a "if....else..." condition/loop script/quest-alias.... this is the way I did for "each" plugin with the chosen item... I am looking for way to use a script not inside a special plugin but searching all of them (like "additem menu" is doing it)... oh, maybe I have to look at this plugin and see, if there is a script which already solved my problem but is there a way to enchant items via scripts? Or am I stuck with batch-files for this?
Guest Posted October 31, 2018 Posted October 31, 2018 You can enchant items using scripts. For sure you need SKSE.
Psalam Posted October 31, 2018 Posted October 31, 2018 Spoiler 3 hours ago, CPU said: I do not recommend using the event OnInit. It will not be fired when you reload the game. Now, you are speaking about the player, so its inventory it is stable in saves. It will be not for NPCs equipped items. But you should also check if a wereable object is still available on a game load, and if it is not the script should discard the reference. The best is to use the event OnPlayerLoadGame. This will be fired if you attach the script to a quest alias and the alias is assigned to the Player. I frankly admit that I am just starting to learn Papyrus scripting but I need some clarification. I have been watching a series by Arron Dominion on YouTube. All his practical examples use OnInit. He shows his examples running in game from what is clearly a save (he is level 80 and starts at the College of Winterhold). So far, at least, he has had no problem with this approach. Is that because he is doing this only on this one save (in other words, since his script with OnInit is added when he is at level 80 already) and he would have a problem with this script if he then saved, quit and started again?
xwhiteninjax Posted October 31, 2018 Author Posted October 31, 2018 function "OnInit()" the result looks the same as "OnPlayerLoadGame()".... but.... OnInit() could be invoked again and again (so if there is no condition if something has been done, it might be, that there are doubles, tripples reactions (and so on).... "OnPlaerLoadGame()" is more or less a "one-time-function" (maybe invoked after loading a save, too), more foolproof as "OnInit()" and just for logical behaviour... it makes much more sense, to do something one-time at the beginning of a game/loading a save (like giving some items) with the proper function, as using something invoked by another trigger. For my example above there might be an excuse, since the function is triggered by opening the MCM of the succubus race (and since there are basic options for succubus-outlook it is a 100 percent-chance to do it at the very beginning of a game - after charcreationtime). so the function per se is not wrong, but it is like "dirty programming" (hope, this make sense)
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 OnInit() fires on a new game and on Quest start if it's put on a Quest or Alias, but it won't refire on loaded games. It could be repeated by stopping and restarting a Quest. OnPlayerLoadGame() will not fire on a new game, but it does fire on any loaded game. It's often good to have both so you have all bases covered, but it depends on specifically what you want to do. -Whether the results that you're after will be retained in the save game memory, or if it needs to be refreshed on load. Also, OnInit will take precedence over every other event/function in the script and block them from running until it completes all its processes. It's usually best to keep the event itself short and sweet, you can use a registerforsingleupdate inside of an OnInit() when you need to run more code and put the code in the update event instead.
Guest Posted October 31, 2018 Posted October 31, 2018 50 minutes ago, xwhiteninjax said: function "OnInit()" the result looks the same as "OnPlayerLoadGame()".... but.... OnInit() could be invoked again and again (so if there is no condition if something has been done, it might be, that there are doubles, tripples reactions (and so on).... "OnPlaerLoadGame()" is more or less a "one-time-function" (maybe invoked after loading a save, too), more foolproof as "OnInit()" and just for logical behaviour... it makes much more sense, to do something one-time at the beginning of a game/loading a save (like giving some items) with the proper function, as using something invoked by another trigger. For my example above there might be an excuse, since the function is triggered by opening the MCM of the succubus race (and since there are basic options for succubus-outlook it is a 100 percent-chance to do it at the very beginning of a game - after charcreationtime). so the function per se is not wrong, but it is like "dirty programming" (hope, this make sense) No, it is exactly the opposite. OnInit is called only once. OnPlayerLoadGame is called every time the game is loaded.
Psalam Posted October 31, 2018 Posted October 31, 2018 Spoiler 2 minutes ago, Hugh Reckum said: OnInit() fires on a new game and on Quest start if it's put on a Quest or Alias, but it won't refire on loaded games. It could be repeated by stopping and restarting a Quest. OnPlayerLoadGame() will not fire on a new game, but it does fire on any loaded game. It's often good to have both so you have all bases covered, but it depends on specifically what you want to do. -Whether the results that you're after will be retained in the save game memory, or if it needs to be refreshed on load. Also, OnInit will take precedence over every other event/function in the script and block them from running until it completes all its processes. It's usually best to keep the event itself short and sweet, you can use a registerforsingleupdate inside of an OnInit() when you need to run more code and put the code in the update event instead. Hi, Hugh and thanks again for SexLab Pheromones. Now, I am in no position to argue with you and really shouldn't say this again but I will because I really want to make sure that I understand. In the Scripting tutorial that I am watching on YouTube (https://www.youtube.com/watch?v=W0uLYRw3WF0&list=PLrN7sXqWQOBPVRNKPBBFl9aTjOtuL4uWK&index=10) the instructor uses OnInit for every one of his practical scripts (I believe I am now on the 15th video, so 15 times). He is clearly using it in a saved game (he is level 86 and starting at the College of Winterhold). His scripts fire off every time. So, is this just an illusion (he has this game set up to look like a save but he's actually starting a new game at level 86 at the College of Winterhold) or does OnInit fire off the first time that the game sees the script (and although he is at level 86 this is the first time the Papyrus Compiler sees the script and accepts it as OnInit). I fully accept that as a practical matter I would only ever use it in the manner that you described and can see the benefit of using it with OnPlayerLoadGame but there may come a time where the distinction might make a difference so I want to be sure I understand it correctly.
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 @Psalam Ok, so it fires on a new game and on Quest start. - Say you attached it to an Alias, it would fire as soon as that alias filled. - Which happens automatically when a Quest starts. Say you used forcedref Player as your alias, this should always be a valid alias guaranteed to fill, so as soon as the Quest starts, the alias fills, and the OnInit() will fire, and that's how it could be done on a loaded game. (Or repeated if stopping / restarting the Quest). In the case of a newly installed Mod, it could also fire the first time the script is loaded. Here's an excerpt from the Wiki: As you can see, it also depends on what the OnInit is attached to, I'm giving an Alias example, but it can be attached to other kinds of objects / references, and the results will change. But basically, once it fires, it's pretty much done, unless you are specifically manipulating things to get it to repeat. If you need things to refresh on game loads later, then you need the OnPlayerLoadGame as well.
Psalam Posted October 31, 2018 Posted October 31, 2018 @Hugh Reckum So, in his case he attaches it to an object (a barrel). So, this would be the second case that you have listed (base object). Then it fires when he loads the save because that is the first time that the Compiler sees the script. If he had loaded this script at the beginning of his game it would long since have fired. Or, as I said earlier, if he were to now save this game, quit and reload, it would NOT fire (in my generation's terms it would have "shot its wad.") Thanks again Hugh! @xwhiteninjax Sorry to have hijacked your thread. I will be quiet now (as much as I can be anyway).
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 @Psalam That's correct, so as long as what he needed stays persistent in save-game memory, it should be fine only 'shooting its load' once. A common thing to do with a Barrel might be to give it a a registerforsingleupdate loop to respawn items. Here's an example of a Barrel script I've used with an OnInit() int Property ResetTime Auto ObjectReference Property Barrel Auto Event OnInit() RegisterForSingleUpdateGameTime(Resettime) EndEvent Event OnUpdateGameTime() Reset() RegisterForSingleUpdateGameTime(ResetTime) EndEvent So it fires once, then it will loop the singleupdategametime, and whatever you set the int ResetTime to, it will respawn the initial barrel items on that timer... I.E. if you filled the property out to 8, it would reset the contents once every 8 game hours. *Bonus if you can find a correction to the above script because there is something added there that isn't needed.
Psalam Posted October 31, 2018 Posted October 31, 2018 @Hugh Reckum If I understood the Creation Kit wiki correctly: Spoiler Aliases and quests will automatically unregister for this event when the quest stops. Active magic effects will automatically unregister when they are removed. there is no need to reset.
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 @Psalam There's no magic effect or alias or quest here, it is simply calling a reset on an objectreference. Now technically, the Barrel would eventually reset its items without any script (if the 'Respawns' box was checked in the base container ID in CK). The game will effectively automatically call reset() once the respawn triggers. But this could take a long time, maybe 10 to 30 in-game days if the barrel was looted in a cleared dungeon, for instance. So, if you want to make an endless barrel of gold that will refill with 1,000,000 gold every hour, you'd need a script that calls reset() on the object with a 1 hour registerforsingleupdate loop. It's actually the following that isn't needed: ObjectReference Property Barrel Auto This is because the property 'Barrel' isn't being used anywhere in the script. The command isn't Barrel.reset(), (it could be, but you'd have to fill out the Barrel property), instead, it is simply Reset(). This is effectively telling the game that what you want to do is self.Reset(). In other words, the reset() function is going to be called automatically on whatever ObjectReference it's attached to, and you don't have to specify the object via Barrel.Reset() or something similar since the script will assume it's 'self' if it hasn't been specified and it's attached to an object. If you wanted to call reset on something other than self, then you'd need an objectreference property. For instance, you could have a script attached to the Barrel that would reset some other object on a timer: ObjectReference Property FerrisWheel Auto Then replace Reset() with FerrisWheel.Reset(), and the timer in the Barrel would reset the FerrisWheel (external object), this would be kind of a weird and convoluted way to go about resetting another object, so I'm not sure why someone might want to do it this way, but it's possible. But anyway, the issue with the script was that it had an extra script property that it wasn't using, all it actually needs is the int property. The previous script example will still work fine as is, but there's also no reason to have unused properties in your scripts... This is all that's needed (as long as the script is actually attached to the Barrel Object): int Property ResetTime Auto Event OnInit() RegisterForSingleUpdateGameTime(Resettime) EndEvent Event OnUpdateGameTime() Reset() RegisterForSingleUpdateGameTime(ResetTime) EndEvent
Psalam Posted October 31, 2018 Posted October 31, 2018 Spoiler 41 minutes ago, Hugh Reckum said: @Psalam There's no magic effect or alias or quest here, it is simply calling a reset on an objectreference. Now technically, the Barrel would eventually reset its items without any script (if the 'Respawns' box was checked in the base container ID in CK). The game will effectively automatically call reset() once the respawn triggers. But this could take a long time, maybe 10 to 30 in-game days if the barrel was looted in a cleared dungeon, for instance. So, if you want to make an endless barrel of gold that will refill with 1,000,000 gold every hour, you'd need a script that calls reset() on the object with a 1 hour registerforsingleupdate loop. It's actually the following that isn't needed: ObjectReference Property Barrel Auto This is because the property 'Barrel' isn't being used anywhere in the script. The command isn't Barrel.reset(), (it could be, but you'd have to fill out the Barrel property), instead, it is simply Reset(). This is effectively telling the game that what you want to do is self.Reset(). In other words, the reset() function is going to be called automatically on whatever ObjectReference it's attached to, and you don't have to specify the object via Barrel.Reset() or something similar since the script will assume it's 'self' if it hasn't been specified and it's attached to an object. If you wanted to call reset on something other than self, then you'd need an objectreference property. For instance, you could have a script attached to the Barrel that would reset some other object on a timer: ObjectReference Property FerrisWheel Auto Then replace Reset() with FerrisWheel.Reset(), and the timer in the Barrel would reset the FerrisWheel (external object), this would be kind of a weird and convoluted way to go about resetting another object, so I'm not sure why someone might want to do it this way, but it's possible. But anyway, the issue with the script was that it had an extra script property that it wasn't using, all it actually needs is the int property. The previous script example will still work fine as is, but there's also no reason to have unused properties in your scripts... This is all that's needed (as long as the script is actually attached to the Barrel Object): int Property ResetTime Auto Event OnInit() RegisterForSingleUpdateGameTime(Resettime) EndEvent Event OnUpdateGameTime() Reset() RegisterForSingleUpdateGameTime(ResetTime) EndEvent Thanks again.
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 3 minutes ago, Psalam said: Reveal hidden contents Thanks again. Keep it up with your scripting tutorials. It gets fun when you can make almost anything you want to have happen, happen.
Psalam Posted October 31, 2018 Posted October 31, 2018 Spoiler 7 minutes ago, Hugh Reckum said: Keep it up with your scripting tutorials. It gets fun when you can make almost anything you want to have happen, happen. I hope that you don't mind but I have been looking at scripts in mods already to see what I know and I don't know. Whether it's good or bad I find what you've done with SP to be the most comprehensible thing I've found. Since Ashal has not replaced his information on GitHub I had no idea how to call SexLab. Thanks to you I now have an inkling. Now if I can find out how to find an NPCs (specifically my custom follower's) arousal from SexLab Aroused Redux, I may be able to put my first script together. Anyway (and I'm sure you're tired of hearing it but it makes it no less true), thanks Hugh!
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 1 hour ago, Psalam said: I hope that you don't mind but I have been looking at scripts in mods already to see what I know and I don't know. Whether it's good or bad I find what you've done with SP to be the most comprehensible thing I've found. Since Ashal has not replaced his information on GitHub I had no idea how to call SexLab. Thanks to you I now have an inkling. Now if I can find out how to find an NPCs (specifically my custom follower's) arousal from SexLab Aroused Redux, I may be able to put my first script together. Anyway (and I'm sure you're tired of hearing it but it makes it no less true), thanks Hugh! I publish the .psc's so people can look at them if they want. I also don't put restrictions if people want to use stuff from my scripts because I don't believe in scarcity and feel like modding communities should be mostly free / open. That seems to be the best approach for a healthy community where more people get involved creatively, IMO... So to get your followers arousal, one suggestion might be to have an Allow Repeated Stages Quest with a startup stage and a Ref Alias that will fill based on conditions. Something like this: That checks the loaded area for someone in the current follower faction who is female and isn't a child (no pedo)... If you want to avoid creature followers and limit to NPCs, you'd do: Then in the script you'd have something like: Quest Property FollowerQuest Auto ReferenceAlias Property FollowerAlias Auto slaFrameworkScr Property Aroused Auto Function CheckFollowerArousal() ; Call this function however you want. FollowerQuest.Start() ; Quest will start, check the area, and fill the follower alias if available. (Alias is marked as optional so Quest won't fail to start). Utility.Wait(3.0); Give it a small wait so the game has a chance to load Quest and fill Alias. If FollowerAlias.GetActorReference() != None; Does a check if the alias is filled before executing code. Debug.Notification("My follower has " + Aroused.GetActorExposureRate(FollowerAlias.GetActorReference()) + " Arousal!") ; Tells you what arousal is but could run any code. EndIf Utility.Wait(3.0) FollowerQuest.Stop() EndFunction
Psalam Posted October 31, 2018 Posted October 31, 2018 Spoiler 8 minutes ago, Hugh Reckum said: I publish the .psc's so people can look at them if they want. I also don't put restrictions if people want to use stuff from my scripts because I don't believe in scarcity and feel like modding communities should be mostly free / open. That seems to be the best approach for a healthy community where more people get involved creatively, IMO... So to get your followers arousal, one suggestion might be to have an Allow Repeated Stages Quest with a startup stage and a Ref Alias that will fill based on conditions. Something like this: Hide contents That checks the loaded area for someone in the current follower faction who is female and isn't a child (no pedo)... If you want to avoid creature followers and limit to NPCs, you'd do: Then in the script you'd have something like: Quest Property FollowerQuest Auto ReferenceAlias Property FollowerAlias Auto slaFrameworkScr Property Aroused Auto Function CheckFollowerArousal() ; Call this function however you want. FollowerQuest.Start() ; Quest will start, check the area, and fill the follower alias if available. (Alias is marked as optional so Quest won't fail to start). Utility.Wait(3.0); Give it a small wait so the game has a chance to load Quest and fill Alias. If FollowerAlias.GetActorReference() != None; Does a check if the alias is filled before executing code. Debug.Notification("My follower has " + Aroused.GetActorExposureRate(FollowerAlias.GetActorReference()) + " Arousal!") ; Tells you what arousal is but could run any code. EndIf Utility.Wait(3.0) FollowerQuest.Stop() EndFunction Good God Hugh! Thank you so very much!
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 4 minutes ago, Psalam said: Good God Hugh! Thank you so very much! lol, well you lucked out because I was working on some SP follower support stuff, so was adding a Quest like this for real anyway.
Psalam Posted October 31, 2018 Posted October 31, 2018 Spoiler 5 minutes ago, Hugh Reckum said: lol, well you lucked out because I was working on some SP follower support stuff, so was adding a Quest like this for real anyway. So where does this from Fishburger play in? Event OnArousalComputed(string eventName, string argString, float argNum, form sender) It looks like that is when I'm supposed to check the arousal (and in my case if it's over 90 have my follower force greet). Can I just skip doing the EventOnArousal or is that still needed with what you've provided?
Tyrant99 Posted October 31, 2018 Posted October 31, 2018 @Psalam My bad, you probably wouldn't use GetActorExposureRate(Actor akRef) but instead GetActorExposure(Actor akRef) It's an int function so it will return a whole number value. I.E. If Aroused.GetActorExposure(FollowerAlias.GetActorReference()) > 50 ;Do something if follower's arousal is greater than 50 when you run a check. EndIf The version that I gave you is a periodic check type, but if you wanted to monitor things more real-time synchronized than you'd probably use the RegisterForModEvent / Event OnArousalComputed method. - Fishburger has some example code on the front page.
Psalam Posted October 31, 2018 Posted October 31, 2018 @Hugh Reckum I saw the code on SLAR. That was what I was asking you about (quoting him). Thank you though. I am now TREMENDOUSLY closer to doing what I was aiming for, I still intend to put more time into the tutorials and looking at code but you have helped me along tremendously. Thank you once again!!! ?
Holzfrau Posted November 1, 2018 Posted November 1, 2018 Quote If Aroused.GetActorExposure(FollowerAlias.GetActorReference()) > 50 ;Do something if follower's arousal is greater than 50 when you run a check. EndIf Shouldn't you be using Aroused.GetActorArousal here? Also, to save on performance, you can simply check the follower's faction rank in the slaArousal faction instead of calling the function.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.