Vetril Posted October 8, 2015 Share Posted October 8, 2015 (edited) 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 October 8, 2015 by Vetril Link to comment Share on other sites More sharing options...
scrivener07 Posted October 9, 2015 Share Posted October 9, 2015 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 More sharing options...
Vetril Posted October 11, 2015 Author Share Posted October 11, 2015 (edited) 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 October 11, 2015 by Vetril Link to comment Share on other sites More sharing options...
Vetril Posted October 12, 2015 Author Share Posted October 12, 2015 (edited) 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 October 12, 2015 by Vetril Link to comment Share on other sites More sharing options...
scrivener07 Posted October 13, 2015 Share Posted October 13, 2015 Some of the menus are still messed up from decompiling afaik. Looks great post updates as you progress please. Link to comment Share on other sites More sharing options...
Vetril Posted October 16, 2015 Author Share Posted October 16, 2015 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 More sharing options...
scrivener07 Posted October 21, 2015 Share Posted October 21, 2015 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 / argumentsThe arguments are an object you can access in a function body. Link to comment Share on other sites More sharing options...
richterman235 Posted December 6, 2015 Share Posted December 6, 2015 Did you get it to work yet? what's the status update, Link to comment Share on other sites More sharing options...
richterman235 Posted December 9, 2015 Share Posted December 9, 2015 (edited) I promised ya he perfected it by now and kidnapped by the Institute Edited December 9, 2015 by richterman235 Link to comment Share on other sites More sharing options...
Vetril Posted January 1, 2016 Author Share Posted January 1, 2016 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 More sharing options...
Recommended Posts