Jump to content

Script Game.GetModName return wrong mod if form has a script


Recommended Posts

Posted

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?

Posted

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)

 

Posted
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

Posted
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.

 

 

Posted
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


 

Posted

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.

 

Posted
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

 

Posted
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:

image.jpeg

 

 

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. 

Posted
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

Posted
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?

Posted
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:

image.jpeg

 

 

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

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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