Jump to content

Convert Decimal FormID to Hexadecimal


dylbill

Recommended Posts

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

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

  • 1 year later...

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

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

  • 2 years later...

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

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...