Swe-DivX Posted May 3, 2022 Posted May 3, 2022 Just got ready so you can add your own scenes in Sexlife. But stuck on a bug with mod names json { "formList" : { "scenes" : [ "138870|adcSexlife.esp" ] } } Script to get the json value string Function GetModName(form a_form) if a_form == none return "" endif int ID = a_form.GetFormID() int MODID = Math.RightShift(ID, 24) string Nameofmod = Game.GetModName(MODID) if Nameofmod == "" ; If empty NameofMod = "CANTFIND" endif return Nameofmod EndFunction int Function GetSceneModID(scene akref) int ID = akref.GetFormID() ID = Math.LogicalAnd(ID, 0x00ffffff) return ID EndFunction PageCurrentIndex = 0 Scene PageFileValuesForm = JsonUtil.FormListGet(path, "Scenes", PageCurrentIndex) as Scene String FModName = GetModName(PageFileValuesForm) String FModID = GetSceneModID(PageFileValuesForm) If the form has no script GetModName will return adcSexlife.esp, if i add a script to the form it will return Skyrim.esm. GetModID returns 0 with script and 138870 with no script in the form. Or is there any other way to get the mod name directly from the json file?
Monoman1 Posted May 3, 2022 Posted May 3, 2022 Try using lower case 'scenes' JsonUtil.FormListGet(path, "scenes", PageCurrentIndex) as Scene In my experience json keys should always be all lower case. And here is some code I wrote to get the mod name for the current AI package running on an Npc: Package AiPack = akTarget.GetCurrentPackage() Int FormId = AiPack.GetFormID() Int Index = Math.RightShift(Math.LogicalAnd(FormId, 0xFF000000), 24) String ModName = Game.GetModName(Index)
Swe-DivX Posted May 3, 2022 Author Posted May 3, 2022 1 hour ago, Monoman1 said: Try using lower case 'scenes' JsonUtil.FormListGet(path, "scenes", PageCurrentIndex) as Scene In my experience json keys should always be all lower case. And here is some code I wrote to get the mod name for the current AI package running on an Npc: Package AiPack = akTarget.GetCurrentPackage() Int FormId = AiPack.GetFormID() Int Index = Math.RightShift(Math.LogicalAnd(FormId, 0xFF000000), 24) String ModName = Game.GetModName(Index) Your script is the opposite, you getting the form Hex and convert it to int from the game engine. I already have int value and need to match against the game's Hex. But thanks anyway ? The only solution seems to be to save Mod.esp and int value separately in the json file
Monoman1 Posted May 3, 2022 Posted May 3, 2022 18 minutes ago, Swe-DivX said: The only solution seems to be to save Mod.esp and int value separately in the json file What exactly is it that you're trying to do? Get the the name of a mod of a scene form from a json? It's not clear from the script snippet. GetModID() is missing. Also, not hugely important but reusing the vanilla function name GetModName in your own function is a bit confusing IMO.
Swe-DivX Posted May 3, 2022 Author Posted May 3, 2022 1 hour ago, Monoman1 said: What exactly is it that you're trying to do? Get the the name of a mod of a scene form from a json? It's not clear from the script snippet. GetModID() is missing. Also, not hugely important but reusing the vanilla function name GetModName in your own function is a bit confusing IMO. Changed the GetModID to GetSceneModID. Form value from the json works to connect to the ingame form in the esp file. So i can start a scene directly with PageFileValuesForm.Start() Problem is when i need the ID and Mod.esp to write the path to the json settings files. It will return wrong mod name and 0 as ID if i use a script on the scene form in the esp file. float Function SceneAttributeGet(string AttrModName, string AttrModID, int SceneActor, string a_value, int AttrSex, float missing = 0.0) string path = MAIN.CONFIG.AttributeFilesPath + AttrModName + "/Scene/" + AttrSex + "/" + SceneActor + "/" + AttrModID + ".json" jsonutil.Load(path) float PageFileValuesFloat = GetFloatValue(path, a_value, missing = -1) jsonutil.UnLoad(path, false, false) return PageFileValuesFloat EndFunction
Fotogen Posted May 3, 2022 Posted May 3, 2022 I never used PapyrusUtil "form" functions. But its not super hard to get modul + object id from a string Code: Form Function _getFormId(string _data) Form retVal string[] params string fname int id params = StringUtil.Split(_data, ":") fname = params[0] id = params[1] as int retVal = Game.GetFormFromFile(id, fname) if !retVal MiscUtil.PrintConsole("Form not found: " + _data) endIf return retVal EndFunction Functions converts form in "mod_name:obj_id"(string, mod name and object id separated by ":") into papyrus Form. Weakness: object id is in dec. I haven't experimented enough to find a way to convert hex string into Int without extra .dlls. Key here is StringUtil.Split() function.
Scrab Posted May 3, 2022 Posted May 3, 2022 1 hour ago, Fotogen said: I haven't experimented enough to find a way to convert hex string into Int without extra .dlls The same way youd do it in any other language too: String Function DecToHex(int decimal) String hex = "" While(decimal != 0) int c = decimal % 16 If(c < 10) hex = c + hex Else hex = StringUtil.AsChar(55 + c) + hex EndIf decimal /= 16 EndWhile EndFunction oh, and the other around, much easier: int Function HexAsInt(String hex) return hex as int EndFunction String Function HexAsDec(String hex) return HexAsInt(hex) as String EndFunction ^ much much easier than in other languages 10 hours ago, Monoman1 said: Try using lower case 'scenes' Papyrus isnt case sensitive, nothing in Papyrus is case sensitive. The language is by design incapable to be case sensitive How the cpp code treats your string is another story but thats also nothing you can do anything about because you have no guarantee that the characters are upper or lower case in Papyrus, no matter what you send in your call 9 hours ago, Swe-DivX said: Your script is the opposite, you getting the form Hex and convert it to int from the game engine. I already have int value and need to match against the game's Hex. But thanks anyway Integers are integers. They are neither hex nor dec nor octa nor any other number system you come up with now, just integers When to use Hex, Decimal, Octa or Binar is just convention, for the system its all the same If you really really want to use decimls there (which is not the convention for IDs) you can just throw the 0xFF000... number into a calculator and replace it with its decimal equivalent. The result will be the same. You can also change the "24" in monos code into "0x18" (thats 24 in hex), the result will be the same
Monoman1 Posted May 3, 2022 Posted May 3, 2022 31 minutes ago, Scrab said: Papyrus isnt case sensitive, nothing in Papyrus is case sensitive. The language is by design incapable to be case sensitive How the cpp code treats your string is another story but thats also nothing you can do anything about because you have no guarantee that the characters are upper or lower case in Papyrus, no matter what you send in your call Sorry I was tired. Papyrus, yes. But the json keys should definitely be lower case in the json file itself. Trust me. Reference: many hours of frustration. Json: "formList" : { "father_forms" : [ "23058|pchsWartimes.esp" ], "Father_formz" : [ "23058|pchsWartimes.esp" ], "mother_forms" : [ "23062|pchsWartimes.esp" ], "sister_forms" : [ "8986781|pchsWartimes.esp", "9048995|pchsWartimes.esp" ] } Code: Function Testi() Debug.Messagebox(JsonUtil.FormListGet("Wartimes/Relatives.json", "father_forms", 0) + "\n\n" + JsonUtil.FormListGet("Wartimes/Relatives.json", "Father_formz", 0)) EndFunction Result: Better to just stick with lower case IMO to avoid this. I suspect papyutil is case sensitive and papyrus is not? I know papyrus has a habit of DE-capitalizing random letters in a string (usually the first letter) if there is no 'space' mostly it seems. This is just my observation. May not be correct.
Scrab Posted May 3, 2022 Posted May 3, 2022 6 minutes ago, Monoman1 said: Sorry I was tired. Papyrus, yes. But the json keys should definitely be lower case in the json file itself. Trust me. Reference: many hours of frustration. but in that case you wrote the .json yourself non? I strongly assume that JsonUtil will lower case everything it gets through its functions first and then looks it up. What you send in Papyrus doesnt matter. A string key in your code contains "ABCDEFGH" will be send to the native function as "ABCdEFgH", a cpp Plugin will usually lowercase this into "abcdefgh" and in case of JsonUtil, save or read it into the .json as that. Thats why everything Json util saves is lower case if you manually typed in the key as "Abcdefgh" then it wont find it since cpp/the json parser is most certainly case sensitive
Swe-DivX Posted May 3, 2022 Author Posted May 3, 2022 2 hours ago, Fotogen said: I never used PapyrusUtil "form" functions. But its not super hard to get modul + object id from a string Code: Form Function _getFormId(string _data) Form retVal string[] params string fname int id params = StringUtil.Split(_data, ":") fname = params[0] id = params[1] as int retVal = Game.GetFormFromFile(id, fname) if !retVal MiscUtil.PrintConsole("Form not found: " + _data) endIf return retVal EndFunction Functions converts form in "mod_name:obj_id"(string, mod name and object id separated by ":") into papyrus Form. Weakness: object id is in dec. I haven't experimented enough to find a way to convert hex string into Int without extra .dlls. Key here is StringUtil.Split() function. The value from json file is [SF_adcSexlifeSceneApproach_03021E76 < (8D021E76)>] when using JsonUtil.FormListGet on a form with script and [Scene < (8D021E76)>] if the script is removed. The first answer comes back as a script and the second as a Scene Could it be that the fault lies in StorageUtil.dll?
Swe-DivX Posted May 3, 2022 Author Posted May 3, 2022 2 hours ago, Monoman1 said: Sorry I was tired. Papyrus, yes. But the json keys should definitely be lower case in the json file itself. Trust me. Reference: many hours of frustration. Json: "formList" : { "father_forms" : [ "23058|pchsWartimes.esp" ], "Father_formz" : [ "23058|pchsWartimes.esp" ], "mother_forms" : [ "23062|pchsWartimes.esp" ], "sister_forms" : [ "8986781|pchsWartimes.esp", "9048995|pchsWartimes.esp" ] } Code: Function Testi() Debug.Messagebox(JsonUtil.FormListGet("Wartimes/Relatives.json", "father_forms", 0) + "\n\n" + JsonUtil.FormListGet("Wartimes/Relatives.json", "Father_formz", 0)) EndFunction Result: Better to just stick with lower case IMO to avoid this. I suspect papyutil is case sensitive and papyrus is not? I know papyrus has a habit of DE-capitalizing random letters in a string (usually the first letter) if there is no 'space' mostly it seems. This is just my observation. May not be correct. For me its works with small or large letters in the script but not in the json file. Scripting Utility Functions-58705-3-3
Recommended Posts
Archived
This topic is now archived and is closed to further replies.