user_no_3453 Posted February 7, 2019 Posted February 7, 2019 Just an idea but wouldn't it be more simple and give you more control over the resulting lighting setup to place actor independent dynamic light sources at specific positions relative to SL's scene center marker? I know nothing about lighting but there are some mods that make torches droppable so dynamically placeable, magic effect independent light sources seem to exist.
Yinkle Posted February 7, 2019 Author Posted February 7, 2019 17 minutes ago, user_no_3453 said: Just an idea but wouldn't it be more simple and give you more control over the resulting lighting setup to place actor independent dynamic light sources at specific positions relative to SL's scene center marker? I know nothing about lighting but there are some mods that make torches droppable so dynamically placeable, magic effect independent light sources seem to exist. That sounds great and as you say, way simpler. If you could link me an example that would be very helpful. This is what I wanted to do in the first place but couldn't figure out how. Edit: don't worry if you have no examples, you've given me enough to figure something out
user_no_3453 Posted February 7, 2019 Posted February 7, 2019 5 minutes ago, Yinkle said: That sounds great and as you say, way simpler. If you could link me an example that would be very helpful Here is one: https://www.nexusmods.com/skyrimspecialedition/mods/14490? Just checked and that mod seems to use Actor.PlaceAtMe(Torch01, ...) where Torch01 is the regular Skyrim torch which seems to be just a regular light source so maybe adding your mesh to a new light source in the CK and using PlaceAtMe to place an instance of it into the world would suffice?
Yinkle Posted February 7, 2019 Author Posted February 7, 2019 ahh. we could use placeatme on items with varied offsets and boom nice lighting. Using the SL marker would be better though
Yinkle Posted February 7, 2019 Author Posted February 7, 2019 leave it with me, my work is not done here!
pburnt Posted February 7, 2019 Posted February 7, 2019 3 hours ago, Yinkle said: I can't imagine why this mod would cause a crash unless the mesh was bad- it works fine here. Not much help I know! Have you made sure your version of SOS has the right .dll file for your version of SKSE? I'm thinking it's an armor I flagged as revealing that wasn't meant to. Doubt this is your mod's fault at all. Will check after work.
squirrellydood Posted February 7, 2019 Posted February 7, 2019 sweet serendipity look what just got uploaded to nexus https://www.nexusmods.com/skyrimspecialedition/mods/22630
Yinkle Posted February 8, 2019 Author Posted February 8, 2019 version 2.0 uploaded: 5 actor independent lights placed at the scene now! The script could probably be done better but it seems to work ok
user_no_3453 Posted February 8, 2019 Posted February 8, 2019 Hello Yinkle, nice to see this keeps going. There are two things that might be improved about the script. Most notably, a disabled reference is still in the save, you have to Delete it as well (and for best practice set the property containing it to None afterwards so the reference is no longer linked to from anywhere, otherwise the engine might not actually delete it until the property is filled with something else). Secondly if there is more than one NPC scene running, the lights from the second scene to start will override the lights from the first scene and therefore the first ones will not be disabled. I have quickly thrown together a script that should be more robust but it's entirely untested and also more complex. If you want to put in the effort you can try it out, see if it works as intended or needs some more adjustments, change the placement offsets or similar and use as you see fit but please don't feel pressurized to use it. Spoiler The script gets the 5 lights as an array "atLights" which you can fill from the CK. Keep in mind though that property values are baked into save games so changing the lights in the CK after running the script will not work without a clean save or without renaming the property (in the entire script so it is treated as a new property). Also if you want a number of lights different from 5, the size of the "aobLights" array would need to be adjusted accordingly. Scriptname SL_LightsAliasScript extends ReferenceAlias SexLabFramework Property SexLab Auto Actor Property PlayerRef Auto Light[] Property atLights Auto ; array with all 5 lights ; SexLab can run up to 15 scenes in parallel, so we have 15 different slots for lighting setups, corresponding to the thread ids. ; True for scene slots for which the lights have been placed Bool[] abLightsPlaced ; True for scene slot that are currently being cleaned up Bool[] abSceneLocks ; the light references placed in the world. the first 5 slots are for the first light setup, the next five for the second, etc. ObjectReference[] aobLights ; Changed from OnPlayerLoadGame once all necessary initialization steps for the ; current script version have been done. Don't change value here. Int iCurrentVersion = 0 event OnInit() OnPlayerLoadGame() endevent event OnPlayerLoadGame() if iCurrentVersion < 1 RegisterForModEvent("HookAnimationStart", "SLSceneStart") RegisterForModEvent("HookAnimationEnding", "SLSceneEnd") abLightsPlaced = new Bool[15] abSceneLocks = new Bool[15] aobLights = new ObjectReference[75] ; 5 lights x 15 scenes iCurrentVersion = 1 ;elseif iCurrentVersion < 2 ; uncomment for future initialization code changes ; ; NEW INIT CODE GOES HERE ; iCurrentVersion = 2 endif endevent event SLSceneStart(int threadID, bool hasPlayer) ; make sure the old lights are cleaned up properly if abLightsPlaced[threadID] RemoveLights(threadID) endif ; CenterRef is a property of sslThreadModel which sslThreadController inherits ObjectReference obSceneCenter = SexLab.GetController(threadID).CenterRef if !obSceneCenter return endif float[] fPosition = new float[3] float[] fRotation = new float[3] ; SpawnerTask should work more fluidly than placing the objects separately int iSpawner = SpawnerTask.Create() if iSpawner > 0 ; prepares the spawner int i = 0 while i < atLights.Length SpawnerTask.AddSpawn(iSpawner, aobLights[i], obSceneCenter, fPosition, fRotation) i += 1 endwhile ; actually place the lights ObjectReference[] aobSceneLights = SpawnerTask.Run(iSpawner) ; copy created objects to the array where we keep track of them int baseIndex = threadID * atLights.Length i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i] = aobSceneLights[i] endwhile abLightsPlaced[threadID] = true endif endevent event SLSceneEnd(int threadID, bool hasPlayer) RemoveLights(threadID) endevent function RemoveLights(int threadID) if threadID >= 0 && threadID < abLightsPlaced.Length ; If RemoveLights is called from SLSceneStart while it is still running ; from SLSceneEnd, we wait here until the cleaning is finished so we ; don't overwrite the old lights in our list and then clean the new ones. int iTimeout = 25 while abSceneLocks[threadID] && iTimeout > 0 Utility.WaitMenuMode(0.2) iTimeout -= 1 endwhile abSceneLocks[threadID] = true if abLightsPlaced[threadID] int baseIndex = threadID * atLights.Length ; first disable all as quickly as possible so they are no longer visible int i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i].DisableNoWait() endwhile ; now delete them properly i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i].Delete() aobLights[baseIndex + i] = None endwhile abLightsPlaced[threadID] = false endif abSceneLocks[threadID] = false endif endfunction
Yinkle Posted February 8, 2019 Author Posted February 8, 2019 16 minutes ago, user_no_3453 said: Hello Yinkle, nice to see this keeps going. There are two things that might be improved about the script. Most notably, a disabled reference is still in the save, you have to Delete it as well (and for best practice set the property containing it to None afterwards so the reference is no longer linked to from anywhere, otherwise the engine might not actually delete it until the property is filled with something else). Secondly if there is more than one NPC scene running, the lights from the second scene to start will override the lights from the first scene and therefore the first ones will not be disabled. I have quickly thrown together a script that should be more robust but it's entirely untested and also more complex. If you want to put in the effort you can try it out, see if it works as intended or needs some more adjustments, change the placement offsets or similar and use as you see fit but please don't feel pressurized to use it. Reveal hidden contents The script gets the 5 lights as an array "atLights" which you can fill from the CK. Keep in mind though that property values are baked into save games so changing the lights in the CK after running the script will not work without a clean save or without renaming the property (in the entire script so it is treated as a new property). Also if you want a number of lights different from 5, the size of the "aobLights" array would need to be adjusted accordingly. Scriptname SL_LightsAliasScript extends ReferenceAlias SexLabFramework Property SexLab Auto Actor Property PlayerRef Auto Light[] Property atLights Auto ; array with all 5 lights ; SexLab can run up to 15 scenes in parallel, so we have 15 different slots for lighting setups, corresponding to the thread ids. ; True for scene slots for which the lights have been placed Bool[] abLightsPlaced ; True for scene slot that are currently being cleaned up Bool[] abSceneLocks ; the light references placed in the world. the first 5 slots are for the first light setup, the next five for the second, etc. ObjectReference[] aobLights ; Changed from OnPlayerLoadGame once all necessary initialization steps for the ; current script version have been done. Don't change value here. Int iCurrentVersion = 0 event OnInit() OnPlayerLoadGame() endevent event OnPlayerLoadGame() if iCurrentVersion < 1 RegisterForModEvent("HookAnimationStart", "SLSceneStart") RegisterForModEvent("HookAnimationEnding", "SLSceneEnd") abLightsPlaced = new Bool[15] abSceneLocks = new Bool[15] aobLights = new ObjectReference[75] ; 5 lights x 15 scenes iCurrentVersion = 1 ;elseif iCurrentVersion < 2 ; uncomment for future initialization code changes ; ; NEW INIT CODE GOES HERE ; iCurrentVersion = 2 endif endevent event SLSceneStart(int threadID, bool hasPlayer) ; make sure the old lights are cleaned up properly if abLightsPlaced[threadID] RemoveLights(threadID) endif ; CenterRef is a property of sslThreadModel which sslThreadController inherits ObjectReference obSceneCenter = SexLab.GetController(threadID).CenterRef if !obSceneCenter return endif float[] fPosition = new float[3] float[] fRotation = new float[3] ; SpawnerTask should work more fluidly than placing the objects separately int iSpawner = SpawnerTask.Create() if iSpawner > 0 ; prepares the spawner int i = 0 while i < atLights.Length SpawnerTask.AddSpawn(iSpawner, aobLights[i], obSceneCenter, fPosition, fRotation) i += 1 endwhile ; actually place the lights ObjectReference[] aobSceneLights = SpawnerTask.Run(iSpawner) ; copy created objects to the array where we keep track of them int baseIndex = threadID * atLights.Length i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i] = aobSceneLights[i] endwhile abLightsPlaced[threadID] = true endif endevent event SLSceneEnd(int threadID, bool hasPlayer) RemoveLights(threadID) endevent function RemoveLights(int threadID) if threadID >= 0 && threadID < abLightsPlaced.Length ; If RemoveLights is called from SLSceneStart while it is still running ; from SLSceneEnd, we wait here until the cleaning is finished so we ; don't overwrite the old lights in our list and then clean the new ones. int iTimeout = 25 while abSceneLocks[threadID] && iTimeout > 0 Utility.WaitMenuMode(0.2) iTimeout -= 1 endwhile abSceneLocks[threadID] = true if abLightsPlaced[threadID] int baseIndex = threadID * atLights.Length ; first disable all as quickly as possible so they are no longer visible int i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i].DisableNoWait() endwhile ; now delete them properly i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i].Delete() aobLights[baseIndex + i] = None endwhile abLightsPlaced[threadID] = false endif abSceneLocks[threadID] = false endif endfunction This is fabulous! Thank you so much for helping in the effort to improve the script. Edit: I'll need to spend some time looking at your changes, hopefully I'll upload a new version tomorrow
Yinkle Posted February 9, 2019 Author Posted February 9, 2019 On 2/8/2019 at 7:14 PM, user_no_3453 said: Hello Yinkle, nice to see this keeps going. There are two things that might be improved about the script. Most notably, a disabled reference is still in the save, you have to Delete it as well (and for best practice set the property containing it to None afterwards so the reference is no longer linked to from anywhere, otherwise the engine might not actually delete it until the property is filled with something else). Secondly if there is more than one NPC scene running, the lights from the second scene to start will override the lights from the first scene and therefore the first ones will not be disabled. I have quickly thrown together a script that should be more robust but it's entirely untested and also more complex. If you want to put in the effort you can try it out, see if it works as intended or needs some more adjustments, change the placement offsets or similar and use as you see fit but please don't feel pressurized to use it. Reveal hidden contents The script gets the 5 lights as an array "atLights" which you can fill from the CK. Keep in mind though that property values are baked into save games so changing the lights in the CK after running the script will not work without a clean save or without renaming the property (in the entire script so it is treated as a new property). Also if you want a number of lights different from 5, the size of the "aobLights" array would need to be adjusted accordingly. Scriptname SL_LightsAliasScript extends ReferenceAlias SexLabFramework Property SexLab Auto Actor Property PlayerRef Auto Light[] Property atLights Auto ; array with all 5 lights ; SexLab can run up to 15 scenes in parallel, so we have 15 different slots for lighting setups, corresponding to the thread ids. ; True for scene slots for which the lights have been placed Bool[] abLightsPlaced ; True for scene slot that are currently being cleaned up Bool[] abSceneLocks ; the light references placed in the world. the first 5 slots are for the first light setup, the next five for the second, etc. ObjectReference[] aobLights ; Changed from OnPlayerLoadGame once all necessary initialization steps for the ; current script version have been done. Don't change value here. Int iCurrentVersion = 0 event OnInit() OnPlayerLoadGame() endevent event OnPlayerLoadGame() if iCurrentVersion < 1 RegisterForModEvent("HookAnimationStart", "SLSceneStart") RegisterForModEvent("HookAnimationEnding", "SLSceneEnd") abLightsPlaced = new Bool[15] abSceneLocks = new Bool[15] aobLights = new ObjectReference[75] ; 5 lights x 15 scenes iCurrentVersion = 1 ;elseif iCurrentVersion < 2 ; uncomment for future initialization code changes ; ; NEW INIT CODE GOES HERE ; iCurrentVersion = 2 endif endevent event SLSceneStart(int threadID, bool hasPlayer) ; make sure the old lights are cleaned up properly if abLightsPlaced[threadID] RemoveLights(threadID) endif ; CenterRef is a property of sslThreadModel which sslThreadController inherits ObjectReference obSceneCenter = SexLab.GetController(threadID).CenterRef if !obSceneCenter return endif float[] fPosition = new float[3] float[] fRotation = new float[3] ; SpawnerTask should work more fluidly than placing the objects separately int iSpawner = SpawnerTask.Create() if iSpawner > 0 ; prepares the spawner int i = 0 while i < atLights.Length SpawnerTask.AddSpawn(iSpawner, aobLights[i], obSceneCenter, fPosition, fRotation) i += 1 endwhile ; actually place the lights ObjectReference[] aobSceneLights = SpawnerTask.Run(iSpawner) ; copy created objects to the array where we keep track of them int baseIndex = threadID * atLights.Length i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i] = aobSceneLights[i] endwhile abLightsPlaced[threadID] = true endif endevent event SLSceneEnd(int threadID, bool hasPlayer) RemoveLights(threadID) endevent function RemoveLights(int threadID) if threadID >= 0 && threadID < abLightsPlaced.Length ; If RemoveLights is called from SLSceneStart while it is still running ; from SLSceneEnd, we wait here until the cleaning is finished so we ; don't overwrite the old lights in our list and then clean the new ones. int iTimeout = 25 while abSceneLocks[threadID] && iTimeout > 0 Utility.WaitMenuMode(0.2) iTimeout -= 1 endwhile abSceneLocks[threadID] = true if abLightsPlaced[threadID] int baseIndex = threadID * atLights.Length ; first disable all as quickly as possible so they are no longer visible int i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i].DisableNoWait() endwhile ; now delete them properly i = atLights.Length while i > 0 i -= 1 aobLights[baseIndex + i].Delete() aobLights[baseIndex + i] = None endwhile abLightsPlaced[threadID] = false endif abSceneLocks[threadID] = false endif endfunction I've made a new version incorporating your contribution.There was one issue that took a bit of hunting down- you'd used the aobLights array instead of the atLights in the spawnertask.addspawn thing. Anyhow it's all good and working nicely now, I'll upload the new version shortly.
SpyVsPie Posted February 10, 2019 Posted February 10, 2019 Wow, this is getting really good from the sound things! I love seeing people making new stuff for SE.
pburnt Posted February 11, 2019 Posted February 11, 2019 @Yinkle I accidentally figured out what made me crash. When adding the ESL header to one of my mods it did the same thing while giving some error about SoS, which doesn't seem to have anything to do with either mod. The only way I fixed my mod crashing the same way was to make it a light master in the CK. Trying in XEdit didn't work. Still no idea why this is only affecting me.
Yinkle Posted February 12, 2019 Author Posted February 12, 2019 18 hours ago, pburnt said: Still no idea why this is only affecting me. Therein at least lies a clue? Must be something up with your setup. Are you having the same issue on a new game?
pburnt Posted February 13, 2019 Posted February 13, 2019 10 hours ago, Yinkle said: Therein at least lies a clue? Must be something up with your setup. Are you having the same issue on a new game? Dunno. I rolled back my own mod to a regular esp. Tried studying what Arthmoor had to say about light plugins for any clues but got lost in the techno-babble. Really don't want to start a new game cuz I'm just getting to the point of playing some new mods that came out that I haven't tried yet. I'll bug you about it some other time.
user_no_3453 Posted February 13, 2019 Posted February 13, 2019 @pburnt In my experience there is some kind of bug with SOS that can cause CTDs when loading a game if the load order for esl flagged files has changed between the save and now. I assume the problem is related to the code that adds the 52 armor slot to all body armors because I could reliably get around the CTDs by loading the game in the last functioning configuration, using "Clean schlongified amors" from the SOS MCM, saving and only then doing the load order changes that previously caused the crash. @Yinkle Sorry about the issue with the arrays, I should have chosen more distinct names which would have made it obvious and I forgot about the lighting checks but it seems you got everything working flawlessly now. I have dimmed the light for my personal use but agree with what you wrote earlier that it won't be worth the extra complexity to introduce multiple sets of lights or expose light fade values to papyrus through a dll plugin, especially since the mod so far doesn't need a configuration menu. It might be a good idea though to add a note about self-adjusting the fade values back to the main page somewhere more prominent than the old version spoilers. And thanks for the mod, it does add a lot. 1
Yinkle Posted February 13, 2019 Author Posted February 13, 2019 52 minutes ago, user_no_3453 said: @pburnt In my experience there is some kind of bug with SOS that can cause CTDs when loading a game if the load order for esl flagged files has changed between the save and now. I assume the problem is related to the code that adds the 52 armor slot to all body armors because I could reliably get around the CTDs by loading the game in the last functioning configuration, using "Clean schlongified amors" from the SOS MCM, saving and only then doing the load order changes that previously caused the crash. @Yinkle Sorry about the issue with the arrays, I should have chosen more distinct names which would have made it obvious and I forgot about the lighting checks but it seems you got everything working flawlessly now. I have dimmed the light for my personal use but agree with what you wrote earlier that it won't be worth the extra complexity to introduce multiple sets of lights or expose light fade values to papyrus through a dll plugin, especially since the mod so far doesn't need a configuration menu. It might be a good idea though to add a note about self-adjusting the fade values back to the main page somewhere more prominent than the old version spoilers. And thanks for the mod, it does add a lot. I added a note about changing the fade values to the mod description and thanks again for your help.
pburnt Posted February 14, 2019 Posted February 14, 2019 12 hours ago, user_no_3453 said: @pburnt In my experience there is some kind of bug with SOS that can cause CTDs when loading a game if the load order for esl flagged files has changed between the save and now. I assume the problem is related to the code that adds the 52 armor slot to all body armors because I could reliably get around the CTDs by loading the game in the last functioning configuration, using "Clean schlongified amors" from the SOS MCM, saving and only then doing the load order changes that previously caused the crash. I'll try it out. Thanks for your help even if it doesn't work. Edit: It worked! Even my mod will mod will load as esl now. I wasn't aware of the quirk with SoS and light plugins. Thank you very much!
Serenna187 Posted February 19, 2019 Posted February 19, 2019 Does it use the standard vanilla torch,or the more fancy dragonborn variant that actually casts shadows? item id (00036343)
Yinkle Posted February 20, 2019 Author Posted February 20, 2019 On 2/19/2019 at 9:17 AM, Serenna187 said: Does it use the standard vanilla torch,or the more fancy dragonborn variant that actually casts shadows? item id (00036343) Neither, it uses the vanilla torch.nif as a base for the custom nif file. the actual light sources have nothing to do with torches. You can edit these to your own taste in xedit/ck
Serenna187 Posted February 20, 2019 Posted February 20, 2019 1 hour ago, Yinkle said: Neither, it uses the vanilla torch.nif as a base for the custom nif file. the actual light sources have nothing to do with torches. You can edit these to your own taste in xedit/ck I'm aware,i just wanted to mention that the dragonborn variant has a different light source that actually casts dynamic shadows,which might be preferable over the non-shadow regular one
Yinkle Posted February 20, 2019 Author Posted February 20, 2019 29 minutes ago, Serenna187 said: I'm aware,i just wanted to mention that the dragonborn variant has a different light source that actually casts dynamic shadows,which might be preferable over the non-shadow regular one I'm not sure you get the point here! This mod is meant as a starting point and the idea is that folk can edit the lights to taste using xedit or the CK. If you want to change the lights, please do, just don't request your preference to be set as the standard.
General Neondaze Posted February 25, 2019 Posted February 25, 2019 This is a great mod. The new MCM is a great idea as well. All works perfectly. ?
thesteve812 Posted February 25, 2019 Posted February 25, 2019 I just tried all the #2 versions and get the missing meshes, red triangle with exclamation. I'm using SkyrimLe if that makes any difference. thanks
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now