Skip to content

[MOD] EEex (v0.10.2-alpha)

1101113151648

Comments

  • OlvynChuruOlvynChuru Member Posts: 3,075

    I'm more interested in if EEex could disable the vertical mirror effect that happens when a spell or projectile is reflected. Opcode 291 does not disable it. I'd like this because I could then make a version of Larloch's Minor Drain where the spell deals damage and then the projectile travels back to the caster (by being reflected off the target) to heal the caster. I can already implement this, but it causes that vertical mirror effect to appear even though the effect doesn't represent reflection in this case.
  • OlvynChuruOlvynChuru Member Posts: 3,075
    edited April 2019
    @subtledoctor
    I've been longing for years for an opcode or action that ticks the 'OriginalClass' bit(s) - I think they are at offset 0x10 of the .CRE file. I once did it with NI I think: leveled up a multiclass demihuman fighter/cleric, then changed the .CRE file in the savegame to flip the 'OriginalClass:fighter' bit. Loaded up the modified save, and the game saw the character as a dual-class, and I only proceeded as a cleric thereafter.

    I have a whole mod concept designed around this, starting as multi and changing to dual. There is an OriginalClass trigger in the game, but no corresponding actions... :(

    Good news! I figured out how to read and write to a creature's flags using EEex. I made a function that can set or unset bits in a creature's flags. I have the function attached, along with seven .SPL files: six of them will set one of the six dual-class bits, and the other file will unset all six of them. I've already tested them, and they work.

    You will need to have EEex installed in order to use this. The spells call the function using opcode 402, and the function uses the parameters of the opcode. If parameter2 is 2, it will set the bits specified by parameter1. If parameter2 is 4, it will unset the bits specified by parameter1. It's a similar bit-setting syntax to opcode 339. The resource field must contain the name of the function. The duration of the opcode should be 0, with limited timing (making it permanent causes the function to be repeatedly called).

    My function could also be used set or unset other bits in the creature flags field, such as the bit that disables the tooltip above the creature.
    Post edited by OlvynChuru on
  • switswit Member, Translator (NDA) Posts: 495
    edited April 2019
    @OlvynChuru, nice :)

    For Invoke Lua function that I'm working on I need to read stat values (both vanilla stat as well as new one set by opcode 401). Is there a dedicated Infinity_/EEex Lua function to retrieve stat values of the particular ID?
    Post edited by swit on
  • [Deleted User][Deleted User] Posts: 0
    edited April 2019
    The user and all related content has been deleted.
    Post edited by [Deleted User] on
  • BubbBubb Member Posts: 1,000
    edited April 2019
    @OlvynChuru: Exactly how I was hoping someone would use it! I'm curious how you found the cre flag offset; to my knowledge the only place where that is defined is the debug symbols file, unless you did a lot of trial and error. :)

    I can always look up an offset for you, if you ever need me to.

    @swit: You can use
    EEex_GetActorStat(actorID, statID)
    

    It is capable of fetching both vanilla stats and extended stats.
  • OlvynChuruOlvynChuru Member Posts: 3,075
    edited April 2019
    @subtledoctor
    Cool, sure. If I can ever actually use EEex, I'll go agead and make my mod. :tongue::rage:

    You don't need to learn to how to use EEex. It can simply be installed like any other WeiDU mod. Just download and install EEex, download the zip file I attached earlier, unzip it, and put the files in your override folder. Then if you have characters cast the spells I attached, the spells will change the characters' Original Class bits.

    The spells do the following:

    MEDUALMU.SPL: Unsets all Original Class bits
    MEDUALFI.SPL: Sets Original Class: Fighter bit
    MEDUALMA.SPL: Sets Original Class: Mage bit
    MEDUALTH.SPL: Sets Original Class: Thief bit
    MEDUALCL.SPL: Sets Original Class: Cleric bit
    MEDUALDR.SPL: Sets Original Class: Druid bit
    MEDUALRN.SPL: Sets Original Class: Ranger bit
    Bubb wrote: »
    I'm curious how you found the cre flag offset; to my knowledge the only place where that is defined is the debug symbols file, unless you did a lot of trial and error. :)

    I used a sneaky way to find it, with far less trial and error. I had a spell call a function that uses a for loop to search the offsets after EEex_GetActorShare() for a specified value. If it finds the value, it prints the offset. Then I looked at the creature flags value of a specific creature, which in this case was 0x800000. Then I set the function to search for the value 0x800000 and I had the character cast the spell on the creature. It found a single offset that matched that value: at EEex_GetActorShare() + 0x424. That was the location of the creature's flags!
  • BubbBubb Member Posts: 1,000
    @OlvynChuru: Smart; I think you're suited to this sort of hackery!

    What @subtledoctor is referring to is that EEex only works on Windows atm. I'm planning on getting a Mac / Linux loader running, but it's currently not there. He literally can't use EEex right now :/
  • switswit Member, Translator (NDA) Posts: 495
    edited April 2019
    thanks, @Bubb, Invoke Lua works wonderfully. I've just implemented IWD2 Spellscraft skill with it (displaying spell names above head on successful Spellcraft check by any party member). The only thing missing in the code is forcing data stored in variable into Eval. Is something like this possible?:
    C:Eval('SetToken("CASTSPELL",strref)')
    
    where strref is a local lua variable.
    Alternativelly if there is already a way to set global variables from within lua I could use something like this instead:
    C:Eval('SetTokenGlobal("globalSetByLua","GLOBAL","CASTSPELL")')
    

    btw. thanks for implementing control over wild surge opcode - I've used it to implement "Use Magic Device" skill from IWD2 :)
  • OlvynChuruOlvynChuru Member Posts: 3,075
    Bubb wrote: »
    I can always look up an offset for you, if you ever need me to.

    Would it be possible for you to post the debug symbols file here so we could see it for ourselves? Or is that illegal?

    Another idea: Would it be possible to add another option to the Apply Repeating EFF opcode so that it applies the eff once per parameter1 ticks?
  • OlvynChuruOlvynChuru Member Posts: 3,075
    One more idea: it would be great to have a Lua function that creates an effect and applies it to a creature. This way, we could have an opcode 402 function apply an effect based on stats of the creature that opcode 326 normally can't reach (like the creature's current HP, or their animation). It would also let us put different parameters in the effect we're applying based on the creature's stats and the input. We can already call a script action to apply a spell, but that has its own problems, such as the slight delay before the action happens.
  • switswit Member, Translator (NDA) Posts: 495
    edited April 2019
    thanks @Bubb for variable stuff explanation, everything works perfectly now. 2 more questions, if you don't mind:
    - any way to fetch current area res (e.g. "AR2600") out of object id that casted opcode 402? I need this to finalize Wilderness Lore skill implementation (Tracking externalized to lua code)
    - when using EEex_LuaTrigger is there a way to get ID out of object declarations like Myself, [PC], NearestEnemyOf(Myself) etc.? I didn't find any code like this in M__EEEX.LUA, so I assume it's not implemented. The only object that I know how to convert into ID is Player1-6 (via EEex_Call(EEex_Label("CInfGame::GetCharacterId"), {num}, m_pObjectGame, 0x0)) and opcode 402 caster's ID (via EEex_ReadDword(creatureData + 0x34)).
  • switswit Member, Translator (NDA) Posts: 495
    edited April 2019
    thanks! I will test it soon.

    btw. is it just me or are the lua function calls from DLG files done via EEex_LuaTrigger limited to just one parameter? Here is a test trigger with 2 values:
    EEex_LuaTrigger("testMeDlg(4,5)")
    
    The function itself:
    function testMeDlg(val1, val2)
    	return true
    end
    
    The result is:
    y3tz6b4ge0l6.png
    Despite the warning the function returned true - trigger was attached to the first reply that showed up.

    No problems at all with just 1 parameter.

    edit: hmm, the reply also shows up when the function returns false. In such case I have no idea how to use it correctly :P
  • David77David77 Member Posts: 30
    Dont know if this is a good place to ask :) but it seems people here are quite knowledgable:

    Is the number of stoneskins left something that is able to externalised, to the feedback mayeb when its down to 2?
  • OlvynChuruOlvynChuru Member Posts: 3,075
    David77 wrote: »
    Dont know if this is a good place to ask :) but it seems people here are quite knowledgable:

    Is the number of stoneskins left something that is able to externalised, to the feedback mayeb when its down to 2?

    You can already get the number of stoneskins left without EEex. There is a stat called STONESKINS that has the number of stoneskins (or ironskins) left on the character. If you created a new splprot condition (by inserting a new line in splprot.2da) you could use opcode 326 (apply effects list) to cast a spell on a creature if it has 2 stoneskins left.
  • The user and all related content has been deleted.
  • OlvynChuruOlvynChuru Member Posts: 3,075
    @subtledoctor
    OlvynChuru wrote: »
    One more idea: it would be great to have a Lua function that creates an effect and applies it to a creature. This way, we could have an opcode 402 function apply an effect based on stats of the creature that opcode 326 normally can't reach (like the creature's current HP, or their animation).

    Just FYI, you can already use current hp with 318/324/326.

    How? Although I remember hearing about something like that in the notes for one of the newer patches, I don't see a new splprot condition that checks for current HP, and the IESDP index makes no mention of any new options for splprot.2da.
  • BubbBubb Member Posts: 1,000
    @swit: Currently EEex_LuaTrigger only accepts a function name. It's not actually running the contents of the string, but turning around and calling the function name that it's passed.

    I changed it away from running Lua chunks because the chunk has to be compiled every time it is run, and that takes time.

    I have three options:
    1) Change EEex_LuaTrigger to use chunks again, compiling them every time.
    2) Same as above, but somehow store the compiled chunk after the initial pass.
    3) Implement another trigger that runs chunks instead of directly calling functions.

    I'll figure out what I'm doing and have a fix uploaded tomorrow :)
  • MoonWolfMoonWolf Member Posts: 23
    You may also consider creating a Register Function. Making declaring a new lua function explicit instead of having EEex_LuaTrigger do both.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    Bubb wrote: »
    What @subtledoctor is referring to is that EEex only works on Windows atm. I'm planning on getting a Mac / Linux loader running, but it's currently not there. He literally can't use EEex right now :/

    I think it's much more complicated than that.....
    @subtledoctor and I (and probably someone other people) would like to use EEex features on iOS..... But who knows if it will ever be possible :( .....
  • The user and all related content has been deleted.
  • [Deleted User][Deleted User] Posts: 0
    edited April 2019
    The user and all related content has been deleted.
  • RaduzielRaduziel Member Posts: 4,714
    @Mythalar I'm in love with your desk. So clean and organized.
  • FlashburnFlashburn Member Posts: 1,847
    I will +1 the request to enforce flanking sneak attacks for enemies instead of letting them sneak attack anywhere, anytime in melee.
  • MythalarMythalar Member Posts: 68
    (I was just joking, one could play on a watch that I could not care less if it's good for them ^^ )

    On topic still so eager to see new cool mods with all those possibilities (even though just the timer bars/icons would change my life...)
  • BubbBubb Member Posts: 1,000
    @swit: I've gone ahead and changed EEex_LuaTrigger back to running Lua chunks in the master branch. I believe I can get the compiling process to use a cache by hijacking one of the trigger parameters, but that will take me a while to figure out.

    Some implementation details:

    1) The Lua global "EEex_LuaTriggerActorID" is now set to the executing creature's actorID right before the chunk is run.

    2) The result of the chunk is no longer passed-back to the engine via global variable. Instead, you have to explicitly return the boolean. Like this:
    EEex_LuaTrigger("return B3MySuperCoolFunction(1, 1)")
    

    Of course, the function itself must also return its result in this case.
  • switswit Member, Translator (NDA) Posts: 495
    edited April 2019
    thanks! Considering the engine gets rid of any spaces when it parses DLG files will that return work? I've just tested it with the same test code and "too many parameters" error still shows up (with and without additional bool return).
    Post edited by swit on
Sign In or Register to comment.