csbx Posted August 1 Share Posted August 1 I've been using getformfromfile a fair bit in the mod I created but am aware that having something working well on my system doesn't entail things working well on someone else's system. In my code, e.g., I have: If Game.GetFormFromFile(0x0490EC6D, "EasierRidersDungeonPackSSE.esp") != None ;create a bunch of string arrays here Endif The idea is that I only want to generate the string arrays if I'm using them - and they're only useful if that mod is installed. 0490EC6D happens to be the form id of a map marker originating in that mod. Is there something more I should be considering here ? Or is this fine ? Link to comment Share on other sites More sharing options...
scorrp10 Posted August 1 Share Posted August 1 This is wrong. The map marker has FormID 0490EC6D in YOUR game because you have EasierRidersDungeonPackSSE.esp at load index 04. It will not work for anyone with a different load order. When using GetFormFromFile: if this is from a regular type .esp, you should supply only the 6 last digits of the FormID. In your case, 0x90EC6D. If it is from a light .esp (FormID starting with FE), you should be using only the last 3 digits. Link to comment Share on other sites More sharing options...
PeterMartyr Posted August 1 Share Posted August 1 you should also cast it, no alway cast it Game.GetFormFromFile(0x0490EC6D, "EasierRidersDungeonPackSSE.esp") as string != None Link to comment Share on other sites More sharing options...
csbx Posted August 1 Author Share Posted August 1 (edited) 16 hours ago, scorrp10 said: This is wrong. The map marker has FormID 0490EC6D in YOUR game because you have EasierRidersDungeonPackSSE.esp at load index 04. It will not work for anyone with a different load order. When using GetFormFromFile: if this is from a regular type .esp, you should supply only the 6 last digits of the FormID. In your case, 0x90EC6D. If it is from a light .esp (FormID starting with FE), you should be using only the last 3 digits. I thought that might be the case -- thanks for pointing out the distinction between regular and light esp re syntax. I know that it seems like I'm a moron here, but I struggle for time to learn this stuff and sometimes when I achieve something that works (compiles, functions well in-game) I just move on with other problems. The getformfromfile as I had it worked for me so I marched onward.. That will make about 2 hours of work to resolve, but I'll never make that error again ! 12 hours ago, PeterMartyr said: you should also cast it, no alway cast it Game.GetFormFromFile(0x0490EC6D, "EasierRidersDungeonPackSSE.esp") as string != None Can you explain why this is ? Edited August 1 by csbx Link to comment Share on other sites More sharing options...
xkkmEl Posted August 1 Share Posted August 1 I think you are using the cast correctly in this case. In general, getFormFromFile gives you a Form, but you usually want an Actor, ObjectReference, Spell, Quest, or whatever. So you'll need to cast it quickly. Under the principle that it is better to detect errors early, the generally recommended practice is to cast immediately (to a type as specific as possible) and then compare with None (for error detection and recovery). In this case, you are simply comparing with None, so the cast is not required. It might still be useful to use a cast if you want the condition to fail in the case you get an unexpected object (perhaps because you are looking at the heavily/unwisely modded version of the referenced esp/esm). Link to comment Share on other sites More sharing options...
IsharaMeradin Posted August 2 Share Posted August 2 If you are already using SKSE, use GetModByName to ensure that a mod is present first. This way, if the user peeks into their papyrus log, they will not see any of the harmless entries created by GetFormFromFile when a mod is not present. Nothing more annoying than a user reporting that a mod is spitting out errors left and right in the papyrus log. Especially when those errors are harmless. If Game.GetModByName("EasierRidersDungeonPackSSE.esp") != 255 ; plugin is present. 255 is returned for inactive or missing plugins ; do whatever needed here EndIf Link to comment Share on other sites More sharing options...
PeterMartyr Posted August 5 Share Posted August 5 @csbx you need that maintenance script that I spoke about in an earlier post, using boolean (2 bytes each) Take Two this time with code, about handling mods in the load order. Spoiler ScriptName PlayerAlias extends ReferenceAlias Property Bool IsModInstalled Function Bool Get() return IsModInstalled_Var endFunction EndProperty Property Bool IsThisModInstalled Function Bool Get() return IsThisModInstalled_Var endFunction EndProperty ; above semi full get only Prop is not necessary but how I would do a Global if you need to check it ¯\_(ツ)_/¯ ; you should handle every thing here tho Bool IsModInstalled_Var = false Bool IsThisModInstalled_Var = false Event OnPlayerLoadGame() If(SKSE.GetVersion() as Bool) If(IsModInstalled_Var) IsModInstalled_Var = Game.GetModByName("Mod.esp") != 0xFF If(!IsModInstalled_Var) debug.Trace("this Mod been uninstalled") ; clean up code on removal FYI clean Formlist ; or call some code on another script or this EndIf else IsModInstalled_Var = Game.GetModByName("Mod.esp") != 0xFF If(IsModInstalled_Var) debug.Trace("adding this Mod is installed") ; add to formlist ; or call some code on another script or this EndIf EndIf ;next mod If(IsThisModInstalled_Var) IsThisModInstalled_Var = Game.GetModByName("thisMod.esp") != 0xFF If(!IsThisModInstalled_Var) debug.Trace("this ModName been uninstalled") ; clean up code on removal FYI clean Formlist ; or call some code on another script or this EndIf else IsThisModInstalled_Var = Game.GetModByName("thisMod.esp") != 0xFF If(IsThisModInstalled_Var) debug.Trace("adding this ModName is installed") ; add to formlist ;or call some code on another script or this endIf EndIf ;rinse and repeat till done else debug.TraceAndBox("SKSE is not running or installed, quit without saving and fix or install :)") EndIf EndEvent BTW I wrote that without having skyrim installed, take it with a grain of salt.. I also made them private because I am protecting them, I trust no one Hee Hee Hee and the Semi Full Prop are MANUAL READ ONLY, uses no memory and is not baked into the save either so it can't hurt having them has Globals even if you never use them. I hope you can see the logic? It handles mod install and removal in the middle of a playthru, at a convenient time, at load.. so when your running or searching lists, they are ready to go go go.... I noticed you needed to work this out weeks ago, why I did a preemptive strike then. Sorry for the tardy reply I have been busy, and did not have time... this time instead of hinting with pseudocode , I am being explicit with papyrus code. BTW, you need SKSE to handle things correctly, your mod has needs, just accept it and go with the flow...... if you were hoping for SKSE free? Edit: remember to comment out trace logs on release or when your happy, I am using them for Info. They are not Warnings or Errors.. But info output to check if the code is working, or if it need more attention to make it robust. https://ck.uesp.net/wiki/Trace_-_Debug spontaneous generated game engine logs warning and errors are not harmless, a null pointer or out of bounds error is a Memory Violation, and certainly not harmless, that why they caught and stopped by the game engine... an out of bounds error has the potential to corrupt the RAM , not F u c k up Skyrim, F u ck up the PC sideways, it is more accurate to say that they are caught and stop before they can do damage at massive performance hit. JOKE BUT TRUE, that recent windows blue screen in SKYRIM SPEAK: I ran skyrim with empty property and it did not work..., that was a NULL POINTER, harmless, S H I T NO, and it was caught too, before it damage the hardware or data, or system, only data currently in the RAM was LOST, windows is an operating system... , what a save, but yeah what an inconvenience too. Still think it is harmless? BTW that was not a Microsoft error, blame this company CloudStrike. The fix was easy too, boot in safe mode and delete CloudStrike files... Things is if your getting warnings or errors in the papyrus log, you need to handle it since your code may/will not run as intended, at a massive performance hit. But yeah people find what do not understand annoying, so comment out info trace logs on release, but use the info warnings and errors during development, to make your code more robust, and performance friendly Link to comment Share on other sites More sharing options...
Recommended Posts