Partial re-implementation of Scale of Souls tweak
rhymechap1
Member Posts: 1
in PST:EE Mods
As has been mentioned on a couple of earlier threads, it appears that the Scale of Souls tweak from Qwinn's original Tweak Pack has not yet been ported to PST:EE. I just bought the game and was setting up with the old mods that I used to install on the original PST, and when I noticed this hadn't been ported, I decided to take a stab at investigating the code for the original tweak and trying to re-implement it. At this point, I have a partial re-implementation of the tweak, specifically the portion that shows the Lawful/Good alignment:
A couple of notes on this:
Implementation
I decided to start by taking a look at the source code for Qwinn's original tweak if I could find it. After some Googling, I found the code for the Linux port of the tweak pack. Unfortunately it appears that the original tweak was implemented by direct hex modification of the original game executable, making it rather inscrutable for re-implementation purposes since I wasn't able to decode the magic hex string used. Attempting to re-implement it this way would also require understanding and mapping the binary structure of the current game executable, and I wasn't able to find any existing documentation on this, or commit the amount of time that would be needed to do this from scratch.
After some more searching, I came across the source code for @argent77 's port of the Unfinished Business pack, and noticed how the Bestiary image updates were done by modifying the game's Lua scripts. That suggested that the character statistics screens were also implemented in Lua, so after some more digging in UI.MENU using Near Infinity, I came across where the alignment text lookup was implemented:
Adding a check to this function to append the values of global variables indicating the Lawful/Good alignment for the Nameless One does the trick:
Obviously, this is a little hacky since it doesn't handle internationalization/translation into different languages, but it seems to work. A more robust check would probably use the PC field found in the "character" table, though I haven't investigated that to ensure it behaves as expected.
It seemed like it would be fairly simple to extend this code to output the morale stat for party followers. However, the "character" table that these scripts have access to (i.e. the return value of characters[currentID] in the code snippet above) doesn't appear to have a field/key-value pair for the character morale, which I confirmed by dumping the full contents of the table to screen. So, I'd be interested in hearing how that can be done from those more familiar with the game - if that information isn't stored in a UI-side data structure which the scripts have direct access to, then this might have to involve using some of the other Infinity Engine APIs to retrieve this information.
A couple of notes on this:
- I took a look at releasing this as a WeiDU mod, but seeing as I'm currently unfamiliar with WeiDU and WeiDU doesn't seem to have great support for Lua script modification, which this tweak requires, figuring that out will require more time than I can commit at the moment. I'm posting the code for this tweak below, so anyone familiar with WeiDU scripting can package and release it if they want to. Anyone familiar with using Near Infinity should also be able to replicate and re-implement this locally.
- At this time, I have not figured out how to re-implement the second half of Qwinn's original tweak, namely displaying follower morales (more details in the code section below). If anyone knows how that can be done, I'd be interested in hearing your thoughts.
Implementation
I decided to start by taking a look at the source code for Qwinn's original tweak if I could find it. After some Googling, I found the code for the Linux port of the tweak pack. Unfortunately it appears that the original tweak was implemented by direct hex modification of the original game executable, making it rather inscrutable for re-implementation purposes since I wasn't able to decode the magic hex string used. Attempting to re-implement it this way would also require understanding and mapping the binary structure of the current game executable, and I wasn't able to find any existing documentation on this, or commit the amount of time that would be needed to do this from scratch.
After some more searching, I came across the source code for @argent77 's port of the Unfinished Business pack, and noticed how the Bestiary image updates were done by modifying the game's Lua scripts. That suggested that the character statistics screens were also implemented in Lua, so after some more digging in UI.MENU using Near Infinity, I came across where the alignment text lookup was implemented:
function setAlignmentHelp() recordHelpString = Infinity_FetchString(20105) ..'\n\n' .. Infinity_FetchString(33033) .. '\n' .. Infinity_FetchString(characters[currentID].alignmentHelp) end
Adding a check to this function to append the values of global variables indicating the Lawful/Good alignment for the Nameless One does the trick:
function setAlignmentHelp() recordHelpString = Infinity_FetchString(20105) ..'\n\n' .. Infinity_FetchString(33033) .. '\n' .. Infinity_FetchString(characters[currentID].alignmentHelp) if(characters[currentID].name == 'Nameless One') then recordHelpString = recordHelpString .. '\n\n' recordHelpString = recordHelpString .. 'Lawfulness: ' .. Infinity_GetScriptVarInt('LAW') .. '\n' recordHelpString = recordHelpString .. 'Goodness: ' .. Infinity_GetScriptVarInt('GOOD') end end
Obviously, this is a little hacky since it doesn't handle internationalization/translation into different languages, but it seems to work. A more robust check would probably use the PC field found in the "character" table, though I haven't investigated that to ensure it behaves as expected.
It seemed like it would be fairly simple to extend this code to output the morale stat for party followers. However, the "character" table that these scripts have access to (i.e. the return value of characters[currentID] in the code snippet above) doesn't appear to have a field/key-value pair for the character morale, which I confirmed by dumping the full contents of the table to screen. So, I'd be interested in hearing how that can be done from those more familiar with the game - if that information isn't stored in a UI-side data structure which the scripts have direct access to, then this might have to involve using some of the other Infinity Engine APIs to retrieve this information.
1
Comments
The labels "Lawfulness" and "Goodness" could be added to the dialog.tlk and fetched via Infinity_FetchString() to support translations.
I don't think this feature would fit into PST-UB, and (to my knowledge) there are no UI overhauls available for PST:EE. But it may be an option for Tweaks Anthology.
It seems to work, at least for Morte and Dak'kon (I'm still early in the playthrough that inspired me to do this), and in multiple languages at that (although of course the 'Lawfulness', 'Goodness' and 'Morale' text strings will always appear as such, at least without messing around with Infinity_FetchString, which is beyond me at the moment). That said, I haven't tested it thoroughly, so there's a possibility I've overlooked something, especially when it comes to the other companions.
Edit: I did overlook something - Dak'kon's name has punctuation in it! It's a bit messier, but this revised code work should for Morte, Dak'kon, and Annah:
This won't display anything for the other companions, but looking around some endgame saves with Near Infinity I'm not even sure the other companions have morale (at least, I can't find any variables for it). I feel like Fall-From-Grace should, at least in principle. Can anyone confirm or deny?
I installed Qwinns pack in original version (gog_polish) and for me shows only TNO stats .
As for above code (EE) - for Annah, BD_ANNAH_MORALE didin't work at all.
If I'm not mistaken, there is a difference between morale with NI and in game (with code BD_ ...). Save file (Party members > CRE resource), shows for Dak'kon, morale:16, and in-game shows me: 18. Same with Morte: 13(NI) vs 3(in game) ?
Could there be a gente Soul to help me?
You need to export UI.menu from game to override folder.
To do this use NearInfinity.jar (java required) - https://github.com/Argent77/NearInfinity/releases
Run it, and from the "MENU section" > export...
Next, open exported UI.menu with a text editor, search in the file for:
function setAlignmentHelp()
recordHelpString = Infinity_FetchString(20105) ..'\n\n' .. Infinity_FetchString(33033) .. '\n' .. Infinity_FetchString(characters[currentID].alignmentHelp)
end
And replace this with the above code from ineffablelogic post, save file (in override folder).