Jump to content

statsmenu & custom skills


Vetril

Recommended Posts

Hi, I was looking into statsmenu.swf to see if it is possible to rewrite whatever function is responsible for pulling skills data from the game. I don't see any.

As far as I can see, AnimatedSkillText - the class that builds the skills UI objects - is given an array containing the skills values. The StatsMenu class does pass this array to the AnimatedSkillText instance, but I can't find where the array values are initialized.

I'm not a flash expert so I might be missing something obvious. Is the array fed by the engine itself instead of having the swf file access the data and build it on its own?

The idea I had was trying to pull an unused AV from the engine and add it to the array, so that it is used by the menu to build a new skill object - effectively turning the AV into a new skill (albeit one that needs to be manager through scripts).

Anyone?

Edited by Vetril
Link to comment
Share on other sites

Im no flash expert either but Ill try to help anyway.

 

If you look at StatsMeny.as and see InitExtensions() method the UpdateSkillsList method is added as a callback event to the game engine. The menu passes itself to GameDelegate.addCallBack along with a method name. Im not really sure how the game delegates work but since "this" is being passed to the engine it would be able to make any changes to the menu instance. Im also not sure what kind of objects are in the skill list array but maybe you can make a new method to try and add new elements. The callbacks will probably stomp on those changes when they fire if it works how I think it does.

Link to comment
Share on other sites

I'm actually suspicious of statsmenu.SetDescriptionCard, which has its own callback too - the function takes a parameter that differentiates between perk mode and skill mode... Whatever that means. Reading the code, it looks like it fills a descriptionCard object with stuff like a skill name, a skill value and the percent of a filled meter.
It might actually be the function that sets up the data required to display skill progress. I'll see what happens in the menu if I start putting my own data in the descriptionCard.
I need to look into it more, even if the skills array is handed down by the game engine, I could always divert the original functions towards another array initialized by a script that is run when the menu is opened. Will look into how SkyUI handles communication between UI files and scripts.

Edited by Vetril
Link to comment
Share on other sites

So, adding custom skills to the statsmenu is probably possible.

I had a few problems with the actionscript files from the SkyUI repository - they are not up to date and I guess that a patch changed some things in statsmenu, or that the decompiler messed up. Anyway, I caught a couple of bugs and now the original does work.

I can add a skill UI object that will be visualized by the menu. Right now it breaks the skill names and sometimes the description (this was another bug with the actionscript file). Furthermore, the starry background goes out of sync (obviously, as the background sphere is divided in 18 sections but I'm visualizing 19 skill UI objects).
Apart from these problems, it works fine and the game does not CTD. So it's a start.


http://s7.postimg.org/q8w0p7w6j/new_Skill.jpg

 

Edited by Vetril
Link to comment
Share on other sites

An update.

I've finished writing the Papyrus side of this mod. It runs a quest that retrieves and organizes the skill data (values, names, progress...).
The user can define custom skills through an array that is a property defined on the quest. Right now, the custom skills should point to unused Actor Values, but support for arbitrary variables is easy to implement.
The system should support an infinite number of custom skills (or virtually infinite - up to the number of elements that skse can allocate on a single array).
I now have a good grasp of how things are handled in the StatsMenu swf file. I've successfully hijacked the function that pulls the skills data from the engine.

Big problem: I can't get skse to pass data from papyrus to the UI. This is how I am doing it:

// smpQuest.psc

...

Function UpdateMenu()
	Update()
	
	string[] sSkillStats = Utility.CreateStringArray(5*nSkills)
	int i = 0
	Debug.Trace("smpQuest.psc: UpdateMenu() - sSkillStats length is " + sSkillStats.length)
		
	while (i < sSkillStats.length)
		sSkillStats[i] = fValues[i/5]
		sSkillStats[i+1] = sNames[i/5]
		sSkillStats[i+2] = fMeters[i/5]
		sSkillStats[i+3] = sColors[i/5]
		sSkillStats[i+4] = nLegendary[i/5]
		
		Debug.Trace("smpQuest.psc: UpdateMenu() - sSkillStats[" + i/5 + "] = " + sSkillStats[i] + " " + sSkillStats[i+1] + " " + sSkillStats[i+2] + " " + sSkillStats[i+3] + " " + sSkillStats[i+4])
		i += 5
	endwhile
	
	UI.InvokeStringA("StatsMenu", "_global.StatsMenu.StatsMenuInstance.UpdateSkills", sSkillStats)
EndFunction

// StatsMenu.as

function UpdateSkills(sSkillStats: Array): Void
{
	_global.skse.Log("StatsMenu_UpdateSkills")
	_global.skse.Log("StatsMenu_UpdateSkills:  sSkillStats length is " + sSkillStats.length.toString())
		
	for (var i: Number = 0; i < sSkillStats.length; i += 5)
	{
		_global.skse.Log("StatsMenu_UpdateSkills:  sSkillStats[" + (i/5).toString() + "] = " + sSkillStats[i] + " " + sSkillStats[i+1] + " " + sSkillStats[i+2] + " " + sSkillStats[i+3] + " " + sSkillStats[i+4])
	}
							 
	StatsMenu.StatsMenuInstance.AnimatingSkillTextInstance.InitAnimatedSkillText(testSkillStats);
}

Traces from both functions are as following:

// smpQuest.psc output

[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats length is 95
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[0] = 5.000000 $Alchemy 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[1] = 5.000000 $Illusion 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[2] = 5.000000 $Conjuration 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[3] = 5.000000 $Destruction 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[4] = 25.000000 $Restoration 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[5] = 5.000000 $Alteration 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[6] = 5.000000 $Enchanting 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[7] = 35.000000 $Smithing 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[8] = 10.000000 $HeavyArmor 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[9] = 15.000000 $Block 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[10] = 20.000000 $TwoHanded 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[11] = 35.000000 $OneHanded 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[12] = 30.000000 $Marksman 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[13] = 30.000000 $LightArmor 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[14] = 25.000000 $Sneak 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[15] = 5.000000 $Lockpicking 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[16] = 5.000000 $Pickpocket 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[17] = 10.000000 $Speechcraft 0.000000 #FFFFFF 0
[10/16/2015 - 08:47:26PM] smpQuest.psc: UpdateMenu() - sSkillStats[18] = 0.700000 $CombatHealthRegenMult 0.000000 #FFFFFF -1



// skse.log output

StatsMenu_UpdateSkills
StatsMenu_UpdateSkills:  sSkillStats length is 8
StatsMenu_UpdateSkills:  sSkillStats[0] = undefined undefined undefined undefined undefined
StatsMenu_UpdateSkills:  sSkillStats[1] = undefined undefined undefined undefined undefined

Which looks just odd - it is firing but it's getting garbage data instead of the array.

Am I doing something wrong?


Some considerations: this system can be easily extended to reintroduce Attributes. I have not started looking at the perk trees yet, but I believe it could also be used to create new creature trees (like the two trees introduced by Dawnguard).

Link to comment
Share on other sites

Im not sure about arrays either but I saw schlangster replied to you on the bethforums. The best I can tell is by example. Look at the WidgetBase.as setModes function and how its set from papyrus in WidgetBase.psc UpdateWidgetModes

 

See the AS2 Reference for arguments. ActionScript 2.0 Language Reference / ActionScript classes / arguments

The arguments are an object you can access in a function body.

Link to comment
Share on other sites

  • 1 month later...
  • 4 weeks later...

Unfortunately I couldn't get past that problem I had. I gave up since I couldn't see any reason for my script to produce the buggy behaviour. I thought about it and it might have something to do with the ActiveScript compiler settings, but it's just a wild guess.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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