@Bubb
It might be better to only apply a spell when all layers are lost if a spell is specified in the resource field of the stoneskin effect.
The -B suffix is the existing default for other subspell casting effects in the unmodded game, so there is an expectation to avoid such filenames (along with -D, -F, and -P).
@seraglio: I am at a loss, I can't reproduce the behavior, even with the files you have provided. Could you please upload your WeiDU.log so I can see everything you have installed? I think it's a larger conflict on some level...
An extremely helpful step you could take is seeing if you can reproduce the bug, starting from a clean installation, and working your way up until it starts manifesting. There's no obligation for you to do this, (it's a very time consuming process), but it'd help tremendously in squashing whatever this is.
@Endarire: EEex does not affect base classes / races. It might be possible in the future, and Lua workarounds might be possible currently, (extremely hacky, though I think K4thos has implemented something like this to emulate IWD2 subraces).
I hope to see the support of getting the known spells list some day.
Looking forward to replace my infinite spells simple mod with modified Spell Menu and run EET again from the start. The most interesting and satisfying thing in full saga is collecting spells, which aren't taken away.
Been working for the past day or two on a wonderful suggestion made by @raizo in my spell menu mod's thread:
1. To be able to know what spells enemies are under, without combing through the dialog box. Something like a pop-up on mouse hover?
Just imagine, 5 cowled enforcers start their contingencies all at once. Then you have to comb through the dialog box to know which spell is whose.
And here's the result, (only made to be proof-of-concept, mind you):
When the player presses LShift Spell-Inspection mode is enabled, which then pops up on hover all the named spells which have put effects on the creature.
It was, but via a stroke of genius I accidentally deleted it. I can probably do a better job on it now anyways - I'll reimplement it and release it as an EEex module.
@polymorphedsquirrel: EEex's Screen Effects, (Opcode #403), can be used to do this. The general setup would be as follows:
1) Attach an Opcode #403 to the target before the damage is applied, and set the resource field to an all-uppercase name which defines a Lua function to handle all effects applied to the target, (for example, B3DECDAM).
2) Define the Lua function in a M_*.lua file, (like M_DECDAM.lua, for example):
function B3DECDAM(screenEffectsData, effectData, targetData)
-- Make sure the opcode taking place is #12, (Damage)
local opcode = EEex_ReadDword(effectData + 0xC)
if opcode ~= 0xC then return end
-- Make sure the opcode is dealing straight damage
local opcodeMode = EEex_ReadWord(effectData + 0x1C, 0)
if opcodeMode ~= 0 then return end
-- Make sure the target creature is valid
local targetID = EEex_GetActorIDShare(targetData)
if not EEex_IsSprite(targetID) then return end
-- Read LOCALS value from the target
local localValue = EEex_GetActorLocal(targetID, "B3DECDAM")
-- Adjust damage opcode's Param1
local damageAmount = EEex_ReadDword(effectData + 0x18) - localValue
if damageAmount < 0 then damageAmount = 0 end
-- Write altered damage value back to damage opcode
EEex_WriteDword(effectData + 0x18, damageAmount)
end
If you wanted to read the LOCALS from the damage source instead of the target, use the following function instead:
function B3DECDAM(screenEffectsData, effectData, targetData)
-- Make sure the opcode taking place is #12, (Damage)
local opcode = EEex_ReadDword(effectData + 0xC)
if opcode ~= 0xC then return end
-- Make sure the opcode is dealing straight damage
local opcodeMode = EEex_ReadWord(effectData + 0x1C, 0)
if opcodeMode ~= 0 then return end
-- Make sure the source creature is valid
local sourceID = EEex_ReadDword(effectData + 0x10C)
if not EEex_IsSprite(sourceID) then return end
-- Read LOCALS value from the damage source
local localValue = EEex_GetActorLocal(sourceID, "B3DECDAM")
-- Adjust damage opcode's Param1
local damageAmount = EEex_ReadDword(effectData + 0x18) - localValue
if damageAmount < 0 then damageAmount = 0 end
-- Write altered damage value back to damage opcode
EEex_WriteDword(effectData + 0x18, damageAmount)
end
It was, but via a stroke of genius I accidentally deleted it. I can probably do a better job on it now anyways - I'll reimplement it and release it as an EEex module.
"Left Shift" becoming whatever key you wish. Note that most keys are self explanatory; the ctrl key is bound like so: "Left Ctrl".
Notes on the implementation: Most spells appear correctly in the menu. However, some spells that the AI casts aren't named properly / have incorrect spell icons. In some situations these spells will be hidden, and in others they will appear, but will display the wacky internal details. Additionally, some player spells immediately cast sub-spells that have the aforementioned detail problems - the menu does the best it can without using a manually-curated list.
Wow, this looks incredible. I've reinstalled this new version to try. However, the first time I tried it by enabling it from EEex_INI.lua and then pressing left shift key, it crashed to desktop. If you could tell me the files you need for debugging, I can attach them here
Wow, this looks incredible. I've reinstall this new version to try. However, the first time I tried it by enabling it from EEex_INI.lua and then pressing left shift key, it crashed to desktop. If you could tell me the files you need for debugging, I can attach them here
Thought I had this pretty crash proof, owch. EEex.log, the crash .dmp that it generated, and your WeiDU.log would all be appreciated. (I'll look into them in the morning, I really shouldn't be awake right now, but coding called!)
@raizo: Sure thing - v0.7.3-alpha now comes with an option to change how many rows there are in the list. Edit the following line in B3_EfMen.lua to whatever you wish:
B3EffectMenu_RowCount = 4
This update also fixes the crash that @Ludwig_II reported, (thanks again!).
Hello Bubb,
I just tested EEex with Bubb's Spell Menu and I cannot imagine playing baldur's gate without this functionnality. This is a real enhancement of the UI engine, absolutetly essential !
I also tried the new feature of the module B3_EfMen, but I noticed a little problem in the WORLD_MESSAGES. Currently I am using the Dragonspear UI mod from Pecca, you can see the difference before and after activation
Before
After
Do you think there is a way to activate the module and keep the layout of the Dragonspear UI ?
@Chevalier_Noir: Glad you're enjoying both the spell menu and EEex.
Could you please upload your WeiDU.log and EEex.log, (after exiting the game once the bug has manifested, so it logs any errors)? I can't reproduce it on my end, but hopefully one of the logs sheds some light on the situation.
Good news, the issue is not in EEex but in my UI.menu file.
As I used the Dragonspear UI mod with some little modification I never saw that the menu 'WORLD_MESSAGES' was twice in UI.menu with two different configuration.
Surprisingly, the second one was never activated but only when the module B3_EfMen was on.
Glad you found it, I wouldn't have been able to track that down. Have fun, and don't hesitate to report any other bugs should they appear!
As an aside, having duplicate menu names in UI.MENU is a bit risky. I'm pretty sure the algorithm that the UI uses internally to find the menu, (binary search), can randomly find either of the duplicate menus based on the total amount of menus defined. Since B3_EfMen defines a new menu, it might have been enough to shift the search into finding the nonfunctional duplicate menu - that's my theory, anyway.
EEex v0.8.0-alpha is now released with some new scripting functionality:
(Action) Added EEex_SetTarget(S:Name*,O:Target*) - Stores given target into name.
(Object) Added EEex_Target("<name>") - Evaluates to target stored in <name>.
(Lua) Added EEex_SetTarget(actorID, targetName, targetID) - Stores targetID on actorID in targetName.
(Lua) Added EEex_GetTarget(actorID, targetName) - Returns targetID stored in targetName on actorID.
These additions effectively allows for an unlimited number of objects to be stored on a creature via special string identifiers. This allows a creature's AI script to remember certain objects for future use - e.g. to lock onto a single target based on an initial assessment, or to maintain multiple targets for different tasks.
Example script:
IF
Global("ClearTargets","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("ClearTargets","LOCALS",0)
EEex_SetTarget("B3Player1",[-1]) // Only way to clear stored target
EEex_SetTarget("B3Nearest",[-1])
EEex_SetTarget("B3NearestElf",[-1])
END
IF
Global("SetTargets","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("SetTargets","LOCALS",0)
EEex_SetTarget("B3Player1",Player1) // Store Player1 in "B3Player1"
EEex_SetTarget("B3Nearest",[ANYONE]) // Store the creature nearest to me in "B3Nearest"
EEex_SetTarget("B3NearestElf",[0.0.ELF]) // Store the elf nearest to me in "B3NearestElf"
END
IF
Global("MoveToPlayer1","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("MoveToPlayer1","LOCALS",0)
MoveToObject(EEex_Target("B3Player1")) // Move to creature stored in "B3Player1"
END
IF
Global("MoveToNearest","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("MoveToNearest","LOCALS",0)
MoveToObject(EEex_Target("B3Nearest")) // Move to creature stored in "B3Nearest"
END
IF
Global("MoveToNearestElf","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("MoveToNearestElf","LOCALS",0)
MoveToObject(EEex_Target("B3NearestElf")) // Move to creature stored in "B3NearestElf"
END
Would an externalized Invoke Lua implementation be fine? It's a little awkward to set up spell-wise, (there ends up being 3 levels of indirection ):
Spell does Opcode #177 (Use EFF File).
EFF calls Invoke Lua with an EEex-provided function, (or your own if you want to supplant the default behavior).
Resource2 would hold the actual spell file to fire - other arguments could be passed via remaining EFF v2.0 params.
It's possible to make a dedicated opcode that does all of this, but it seems a bit silly to hardcode the probability portion, which I'm just going to write in Lua anyway. Also, if I implement it as the above, the only new additions to EEex would be a few additional internal-function externalizations.
And, as a side note, Opcode #252 has some funky hardcodedness going on - it's easier to reimplement its functionality than to try to adapt it.
I was getting a hankering to tinker with new skill functionality. Was the above ever implemented? Just to remind you, the idea was to have a way to tie abilities to custom stats so we could make success based on the value of that stat (i.e. in order to create new thief skills)
Thinking about it, I could probably do it using 326, but each implementation would require ~100 effects (would that slow down gameplay?)
Edit: *looking up* lol, also, you're going to inspire me to get more into ai modding, aren't you?
EEex v0.8.0-alpha is now released with some new scripting functionality:
(Action) Added EEex_SetTarget(S:Name*,O:Target*) - Stores given target into name.
(Object) Added EEex_Target("<name>") - Evaluates to target stored in <name>.
(Lua) Added EEex_SetTarget(actorID, targetName, targetID) - Stores targetID on actorID in targetName.
(Lua) Added EEex_GetTarget(actorID, targetName) - Returns targetID stored in targetName on actorID.
These additions effectively allows for an unlimited number of objects to be stored on a creature via special string identifiers. This allows a creature's AI script to remember certain objects for future use - e.g. to lock onto a single target based on an initial assessment, or to maintain multiple targets for different tasks.
Example script:
IF
Global("ClearTargets","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("ClearTargets","LOCALS",0)
EEex_SetTarget("B3Player1",[-1]) // Only way to clear stored target
EEex_SetTarget("B3Nearest",[-1])
EEex_SetTarget("B3NearestElf",[-1])
END
IF
Global("SetTargets","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("SetTargets","LOCALS",0)
EEex_SetTarget("B3Player1",Player1) // Store Player1 in "B3Player1"
EEex_SetTarget("B3Nearest",[ANYONE]) // Store the creature nearest to me in "B3Nearest"
EEex_SetTarget("B3NearestElf",[0.0.ELF]) // Store the elf nearest to me in "B3NearestElf"
END
IF
Global("MoveToPlayer1","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("MoveToPlayer1","LOCALS",0)
MoveToObject(EEex_Target("B3Player1")) // Move to creature stored in "B3Player1"
END
IF
Global("MoveToNearest","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("MoveToNearest","LOCALS",0)
MoveToObject(EEex_Target("B3Nearest")) // Move to creature stored in "B3Nearest"
END
IF
Global("MoveToNearestElf","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("MoveToNearestElf","LOCALS",0)
MoveToObject(EEex_Target("B3NearestElf")) // Move to creature stored in "B3NearestElf"
END
Thank you very much for fulfilling my request! Happy new year
@Grammarsalad: That has not been implemented - I'll look into a possible solution.
EEex v0.8.1-alpha is released with some new scripting functionality:
Added EEex_ChangeCurrentScript(S:Script*) action - Replicates IWD2 action of the same name.
Added ActionOverride(EEex_Instant,A:Action*) functionality - ActionOverride with (O:Actor*) == EEex_Instant executes before script evaluation is completed.
EEex_ChangeCurrentScript(S:Script*) replicates IWD2's action - which makes porting IWD2 scripts easier.
ActionOverride(EEex_Instant,A:Action*) allows for instantly evaluating an action while the script is being processed. Mostly intended to make setting GLOBALs during a script-pass possible, (like in IWD2):
Comments
And thanks for the link! I can see the eeex stuff now!
An extremely helpful step you could take is seeing if you can reproduce the bug, starting from a clean installation, and working your way up until it starts manifesting. There's no obligation for you to do this, (it's a very time consuming process), but it'd help tremendously in squashing whatever this is.
@Endarire: EEex does not affect base classes / races. It might be possible in the future, and Lua workarounds might be possible currently, (extremely hacky, though I think K4thos has implemented something like this to emulate IWD2 subraces).
Looking forward to replace my infinite spells simple mod with modified Spell Menu and run EET again from the start. The most interesting and satisfying thing in full saga is collecting spells, which aren't taken away.
(You'll need to be using the latest version of EEex, found here, for the cheat mode to work)
This will be a fun EET run.
Was this ever implemented by any chance?
It was, but via a stroke of genius I accidentally deleted it. I can probably do a better job on it now anyways - I'll reimplement it and release it as an EEex module.
1) Attach an Opcode #403 to the target before the damage is applied, and set the resource field to an all-uppercase name which defines a Lua function to handle all effects applied to the target, (for example, B3DECDAM).
2) Define the Lua function in a M_*.lua file, (like M_DECDAM.lua, for example):
If you wanted to read the LOCALS from the damage source instead of the target, use the following function instead:
This is now reimplemented in v0.7.2-alpha!
To enable, change "false" to "true" on this line in EEex_INI.lua:
The default key to open the menu (on hover) is Left Shift; if you want to change this key, open B3_EfMen.lua, and alter the following line:
"Left Shift" becoming whatever key you wish. Note that most keys are self explanatory; the ctrl key is bound like so: "Left Ctrl".
Notes on the implementation: Most spells appear correctly in the menu. However, some spells that the AI casts aren't named properly / have incorrect spell icons. In some situations these spells will be hidden, and in others they will appear, but will display the wacky internal details. Additionally, some player spells immediately cast sub-spells that have the aforementioned detail problems - the menu does the best it can without using a manually-curated list.
I have nothing but praise for all the work you have done, thank you!
Thank you for your kind words.
Thought I had this pretty crash proof, owch. EEex.log, the crash .dmp that it generated, and your WeiDU.log would all be appreciated. (I'll look into them in the morning, I really shouldn't be awake right now, but coding called!)
Works without problems.
If it is possible, please make the popup a little longer, to eliminate scrolling.
This update also fixes the crash that @Ludwig_II reported, (thanks again!).
I just tested EEex with Bubb's Spell Menu and I cannot imagine playing baldur's gate without this functionnality. This is a real enhancement of the UI engine, absolutetly essential !
I also tried the new feature of the module B3_EfMen, but I noticed a little problem in the WORLD_MESSAGES. Currently I am using the Dragonspear UI mod from Pecca, you can see the difference before and after activation
Before
After
Do you think there is a way to activate the module and keep the layout of the Dragonspear UI ?
Thanks a lot !
Could you please upload your WeiDU.log and EEex.log, (after exiting the game once the bug has manifested, so it logs any errors)? I can't reproduce it on my end, but hopefully one of the logs sheds some light on the situation.
As I used the Dragonspear UI mod with some little modification I never saw that the menu 'WORLD_MESSAGES' was twice in UI.menu with two different configuration.
Surprisingly, the second one was never activated but only when the module B3_EfMen was on.
As an aside, having duplicate menu names in UI.MENU is a bit risky. I'm pretty sure the algorithm that the UI uses internally to find the menu, (binary search), can randomly find either of the duplicate menus based on the total amount of menus defined. Since B3_EfMen defines a new menu, it might have been enough to shift the search into finding the nonfunctional duplicate menu - that's my theory, anyway.
These additions effectively allows for an unlimited number of objects to be stored on a creature via special string identifiers. This allows a creature's AI script to remember certain objects for future use - e.g. to lock onto a single target based on an initial assessment, or to maintain multiple targets for different tasks.
Example script:
Hi @Bubb (and happy new year!)
I was getting a hankering to tinker with new skill functionality. Was the above ever implemented? Just to remind you, the idea was to have a way to tie abilities to custom stats so we could make success based on the value of that stat (i.e. in order to create new thief skills)
Thinking about it, I could probably do it using 326, but each implementation would require ~100 effects (would that slow down gameplay?)
Edit: *looking up* lol, also, you're going to inspire me to get more into ai modding, aren't you?
Thank you very much for fulfilling my request! Happy new year
EEex v0.8.1-alpha is released with some new scripting functionality:
EEex_ChangeCurrentScript(S:Script*) replicates IWD2's action - which makes porting IWD2 scripts easier.
ActionOverride(EEex_Instant,A:Action*) allows for instantly evaluating an action while the script is being processed. Mostly intended to make setting GLOBALs during a script-pass possible, (like in IWD2):