dylbill Posted March 1, 2020 Author Share Posted March 1, 2020 To each their own I guess, I prefer to use arrays because as I said it's faster. Also, IMO I don't think you need to include the suffix in the actual function, because in your script you can just write: Event SomeEvent() String MyHexString = ConvertIDToHex(SomeForm.GetFormID()) + " Some Suffix" EndEvent Thanks again for the help though, the function is now returning accurate hex ID's. Link to comment Share on other sites More sharing options...
Evangela Posted March 3, 2020 Share Posted March 3, 2020 (edited) They are faster. They increasingly become a pain to code though the more initialization you need to set up. Both are fine and I tried similar thing once before. Edited March 3, 2020 by Rasikko Link to comment Share on other sites More sharing options...
Grospolina Posted March 4, 2020 Share Posted March 4, 2020 For dylbill's code, the NegativeDecDigits array is unnecessary. You can simply replace it with math. i.e. s += HexDigits[j + 15] Also, the "safety first" bit isn't needed because (1 / 16 = 0) in integer math. Thus, it can be reduced to: String[] Property HexDigits Auto Int[] Property NegativeDecDigits Auto Event OnInit() InitArrays() EndEvent Function InitArrays() HexDigits = New String[16] HexDigits[0] = "0" HexDigits[1] = "1" HexDigits[2] = "2" HexDigits[3] = "3" HexDigits[4] = "4" HexDigits[5] = "5" HexDigits[6] = "6" HexDigits[7] = "7" HexDigits[8] = "8" HexDigits[9] = "9" HexDigits[10] = "a" HexDigits[11] = "b" HexDigits[12] = "c" HexDigits[13] = "d" HexDigits[14] = "e" HexDigits[15] = "f" EndFunction String function ConvertIDToHex(Int m) ;--------------------------------------------------------------- ; convert integer (i10) into hexstring with count of 8 numbers ; sample: 842 -> "0000034A" ; 842 = 8*10² + 4*10 + 2*1 ; base 10 ; 34Ah = 3*16² + 4*16 + A*1 ; base 16 int o = 0 ; digit offset If (m < 0) ; if negative, adjust offsets m += 1 o = 15 EndIf string s int v = 0x10000000 ; init divisor While (v > 0) int j = m / v s += HexDigits[j + o] m = m % v ; new remainder as result of modulo v = v / 16 ; new divisor EndWhile Return s EndFunction Furthermore, if you allow SKSE functions, then you can reduce the function way more: String function ConvertIDToHex(Int m) String s int i = 0 While (i < 8) int j = Math.LogicalAnd(m, 0xF) s = StringUtil.GetNthChar("0123456789abcdef", j) + s m = Math.RightShift(m, 4); i += 1 EndWhile Return s EndFunction I haven't actually tested the above function, but the logic should be good. Link to comment Share on other sites More sharing options...
OregonPete Posted June 5, 2021 Share Posted June 5, 2021 It's been over a year, so I'm not sure if this topic is still relevant, but I've come up with a method I like a bit better. It does use the SKSE StringUtil, but it doesn't require any Math functions, just regular math operations, and it's very short. String Function IntToHex( Int _input ) Int _value = _input String _hex = "" While ( _value > 0 ) Int _remainder = _value % 16 _hex = StringUtil.GetNthChar( "0123456789abcdef", _remainder ) + _hex _value /= 16 EndWhile Return _hex EndFunction Link to comment Share on other sites More sharing options...
dylbill Posted June 5, 2021 Author Share Posted June 5, 2021 Nice one. That still doesn't account for negative ID's though. (For objectreferences placed using placeatme). If using SKSE, I did find that Papyrus Extender does have functions to convert an int to a hex string and the other way around: ;Converts string to hex value if valid String Function IntToString(int aiValue, bool abHex) global native ;Converts strng to int. Returns -1 for out of bound values. int Function StringToInt(String asString) global native Link to comment Share on other sites More sharing options...
OregonPete Posted June 7, 2021 Share Posted June 7, 2021 That would be very cool, if SKSE already has a function like that. In which script object is it? Because I couldn't find it in the online CK script reference. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted June 7, 2021 Share Posted June 7, 2021 That would be very cool, if SKSE already has a function like that. In which script object is it? Because I couldn't find it in the online CK script reference.SKSE doesn't have it. dybill said that Papyrus Extender had it. Link to comment Share on other sites More sharing options...
OregonPete Posted June 8, 2021 Share Posted June 8, 2021 Ah, my mistake. Thanks for the clarification, IsharaMeradin. Why don't I know these things? LOL Link to comment Share on other sites More sharing options...
temporalpoporal Posted August 6, 2023 Share Posted August 6, 2023 Yes, po3 papyrus extender has that.Some little debug logging snippets related to the topic. string function ToFormIDString(Form akForm) global ObjectReference akReference = akForm as ObjectReference if(akReference != None) return "base id: " + PO3_SKSEFunctions.IntToString(akReference.GetBaseObject().GetFormID(),true) + ", ref id: " + PO3_SKSEFunctions.IntToString(akReference.GetFormID(), true) else return PO3_SKSEFunctions.IntToString(akForm.GetFormID(), true) endIf endFunction string function ToDebugString(Form akForm) global Actor akActor = akForm as Actor if(akActor != None) return akActor.GetDisplayName() + "(" + SBDebug.ToFormIDString(akForm) + ")" else return akForm.GetName() + "(" + SBDebug.ToFormIDString(akForm) + ")" endIf endFunction Link to comment Share on other sites More sharing options...
PeterMartyr Posted August 6, 2023 Share Posted August 6, 2023 Was this not this solved RAW without a framework... many many many many years ago? a quick google search would have found brilliant RAW recursive logarithms that make those here look like a child wrote them. hehehehe. that could have, should have, didn't get converted to papyrus to solved this for vanilla skyrim?? with NO SCRIPT EXTENDERS. just sayin' Link to comment Share on other sites More sharing options...
Recommended Posts