[MOD] EEex (v0.9.18-alpha)

Overview:
EEex is an executable extender for Beamdog's Enhanced Edition of the Infinity Engine. Its goal is to externalize certain parts of the engine to grant modders a greater degree of control over otherwise hardcoded mechanics. EEex does not make any gameplay changes itself - it merely enables other mods to do so.Download:
Alpha versions of this project are now available on GitHub.The current alpha version only supports Windows platforms, however, MacOS and Linux support is planned for release.
Supported game versions include:
BG:EE v2.6.6.0, BG2:EE v2.6.6.0, and IWD:EE v2.6.6.0 — EEex versions >= v0.9.0-alpha.
BG:EE v2.5.17.0, BG2:EE v2.5.16.6, and IWD:EE v2.5.17.0 — EEex versions < v0.9.0-alpha.
Function:
EEex uses a loader to modify the game's executable after it has been loaded into memory. The exact modifications made depend on the version of EEex installed, and any installed mods that make use of EEex's capabilities.Please note: The following links are NOT intended to be used for installing EEex; the loaders are bundled in their respective EEex versions and will be automatically installed alongside EEex.
InfinityLoader — EEex versions >= v0.9.0-alpha.
EEexLoader (thanks mrfearless!) — EEex versions < v0.9.0-alpha.
Installation:
EEex is installed just as any other WeiDU mod. Simply extract the archive's contents into your game's base folder, and run the setup - it will take care of the rest.Please note that the game has to be started using InfinityLoader.exe/EEex.exe after installation; any attempt to start the game using the vanilla executable will result in a crash.
If InfinityLoader.exe fails to start, please ensure you have installed the latest Microsoft Visual C++ Redistributable.
Stability: EEex is currently in alpha, and as such the odd crash may occur. If you encounter a crash, please report the issue - stating any installed mods, steps that lead to the crash, and upload the generated crash .dmp.
Documentation:
EEex makes extensive use of the EE Lua environment, with most of its functionality implemented as Lua code. Features include new Lua functions, opcodes, scripting actions, triggers, and objects. Please see the EEex Documentation for an overview of EEex's features.The above documentation is a work in progress. If you wish to contribute, visit the contributing page for details.
Post edited by Bubb on
37
Comments
If possible, I would like to have some more information about Saving Throws in the combat log (bonuses, penalties and displaying the roll no matter if you failed or succeeded). It is painful to know if a modded effect is working or not because requires tons of trial-and-error to make a poor estimative (as you can see in a discussion here)
- Get value of characters stats (from STATS.IDS)
- Get is set of characters spellstate (from SPLSTATE.IDS)
- Get characters EA/GENERAL/CLASS/RACE/ALIGNMENT/GENDER/ALIGNMENT IDS index (as opposed to their current string references).
- Get Memorized spell table of characters.
- Get Known/memorized spell tables for innate abilities.
- MemorizeSpell(level,"resref"), as opposed to the current MemorizeSpell(level,index), same for Unmemorize.
Infinity_DoString(chunk) - Runs whatever LUA code is embedded in the given string. Self-modifying code anyone?
I was wondering if I could take my LUA endeavors further and integrate them into BCS scripts. And well, I did just that.
The above is a BCS script that prints "No, I'm sorry, none of them sound familiar." to the log if the player has their cursor over the second portrait slot.
Oh, this is awesome!
Edit:
I'm not sure about psionics-- you would need to ask @subtledoctor about that-- but I would be so super happy with @kjeron 's list. So +1 to that
a) My plan is to make these modifications on every binary that isn't locked-down. So, Windows, Mac, and Linux. The mobile versions cannot be modified to the extent I am doing. I am currently using the Windows binary as my base, and I will port over my changes to the other binaries when I am done.
b) Mostly everything. My original purpose of this thread was to outline new LUA functions, (those that pertain to the UI), but I have recently been branching out into other behaviors of the engine. For example, in my last post I showed that I extended the LUA environment into the scripting environment, basically allowing for dynamic scripts; almost like ToBEx's Assign() and Eval() scripting triggers / actions, but more powerful. I'm not completely done with this concept, but I'm getting there. As for new opcodes, I might be able to create some that mirrors other parts of the engine, such as variable getting and usage, yes.
New triggers / actions (they are implemented as both):
Bubb_LUA(S:Chunk*) - Runs some LUA code provided by the given string. The trigger version of this checks the "trigger" LUA boolean after running the chunk, and succeeds if it is set to true.
Bubb_StoreObjectStat(S:Variable*,O:Object*,I:Stat*STATS) - Stores the provided stat from the given object in the defined LUA variable.
Bubb_StoreGlobal(S:Variable*,S:Global*) - Stores the given global into the defined LUA variable.
Bubb_StoreLocal(S:Variable*,S:Local*) - Stores the given local from the provided object into the defined LUA variable.
And perhaps the most important change of them all is the ability to dynamically override triggers / action parameters at runtime. This is accomplished by setting special LUA variables, here's an example of how it works:
The above script brings the XP value of the script owner to the exact value of Player1's XP.
I believe this system is good already, but I wanted to ask you all a question: is there any other triggers / actions you can think of that would help expand it even further? Any other information types you would like to be able to store... etc.
Edit: Oh, and I haven't ditched all of your UI suggestions. I'll implement them after I've finished my scripting stuff, (which I'm almost done with, btw).
Also, totally out of left field: spell exclusion flags:
http://gibberlings3.net/forums/index.php?showtopic=28382
Now, bit 14 excludes trueclass bards/sorcerers/mages. Unfortunately, unlike with mage kits, it also excludes bard kits. Would it be at all possible to make it only exclude trueclass bards? That one thing would allow me to create a mod with bard exclusive spells, which I think would be fun. Also, is it possible to make those exclusions that don't work, work?
I realize that the EE engine on the whole is not nearly as prone to it but I'm still a little concerned that we might have the old stutter bugs again when a lot of these things are being called at once.
well, you've requested this trigger in your previous post:
it's not really needed because this is already possible with Bubb_LUA (Bubb, correct me if I'm wrong). For example this OR section: can be rewritten like this to work as you requested: trigger = false means that the Bubb_Lua will return false and end the block. For easier understanding here is the above Bubb_Lua trigger code with formatting instead of 1 line (it's normal lua code) Alternatively, if you're doing lots of checks like this in your scripts you can for example prepare M_*.lua file with pre-made function that will do above mentioned stuff and just call it like this instead of repeating the same code over and over: This is just an example, far more complicated stuff can be done with access to lua from within BCS.
@MoonWolf: I am watching performance very closely to make sure my new functions don't impact the game. You are correct in that I am currently having the engine compile and run the LUA chunk every time it executes it; not very efficient, but the engine actually does this itself in several places as well. To test performance I spawned 500 creatures running my script, and I felt no noticeable slowdowns:
If problems do occur with arbitrary LUA execution I can easily have a script shove all the LUA code into a M_*.LUA file, and change my Bubb_LUA() function to execute already compiled functions. This would mirror exactly how the GUI code works, so the game will run just as fast as it would without my functions in this scenario.
@swit: You are correct that an exclusive OR can be replicated with my Bubb_LUA() function, but I believe this would only work IF the triggers you are working with deal with fields that you can store. I believe @Grammarsalad wanted any combination of triggers to be dealt with in this manner. In this situation, I think a dedicated exclusive or is the only way. I'll look into it, but I don't know if I can accomplish that, as it has to do with changing how scripts are fundamentally processed.
[Block 1]
OR(3)
A
-B
-C
...
[Block 2]
OR(3)
-A
B
-C
...
[Block 3]
OR(3)
-A
-B
C
Heh, it adds up
Edit: I'm really interested in the exclusion flag stuff, though...
The implementation you see in the XP example is a special trigger / action which could technically be used by the LUA environment by calling
C:Eval('Bubb_StoreObjectStat("xp",Player1,STATS.XP)')
The problem with trying to use Eval is that any concept of the "currently selected party member" is nonexistent.The good news is that I have all of the internal shenanigans to do with fetching stats done, so all I have to do is implement a LUA-side function which uses a Creature ID instead of a Object IDS value. This way, you could pass currentID into the function and get the stats of the selected party member. It would work like this:
local xp = Infinity_GetStat(currentID, STATS.XP)
Also, I've been working on some more scripting stuff:
The above script shows how objects can be stored and referred to using the LUA environment. The script doesn't really do anything other than having the script owner pick a random target once and then move to that object for all of eternity.
I believe this recreates IWD2's SetMyTarget action and MyTarget object.
@kjeron, while this is extremly impressive peace of code (like damn, I’m saving it right away - I’m sure something here will be useful for me in future) but the example XP matching code is something that can be written in a minute by anyone, while your opcode solution is a riddle that few people in the entire modding scene would be able to solve
@Bubb, absolutely fantastic.
*shivers*