@OlvynChuru: If it helps any, Opcode #403 (ScreenEffects) now passes along the originating effect as the immunity function's first Lua param. Example immunity function:
function B3BLOCKD(originatingEffectData, effectData, creatureData)
local effectID = EEex_ReadDword(effectData + 0xC)
if effectID == 12 then
local timesBlocked = EEex_ReadDword(originatingEffectData + 0x18) + 1
EEex_WriteDword(originatingEffectData + 0x18, timesBlocked)
Infinity_DisplayString("B3BLOCKD blocked damage "..timesBlocked.." time(s)")
return true
end
end
An interesting sidenote: a cool feature of using opcodes like this is that you can keep track of a few things inside the opcode itself, like I'm doing above for block count. Note that you can't do this for equipped effects as they reset on every reload.
However, I found a serious problem with opcode 403 (this was before your new update, so I don't know if you've fixed it already). Putting any opcode 403 effect on a creature sometimes causes enormous slowdown, and sometimes it doesn't. It seems randomly determined when the game is launched whether it will cause slowdown or not. When it causes slowdown, even putting a single opcode 403 effect on a single creature will slow down the game tremendously. When it doesn't cause slowdown, the game can run multiple opcode 403 effects on every creature on the map without any slowdown at all.
It doesn't depend on the function; the same function can switch between causing massive slowdown and not causing any simply by exiting to desktop and running the game again.
Whatever is variably causing slowdown or not causing any is most likely determined in the Lua code when the game is launched, not in the functions that are called by opcode 403 effects.
@OlvynChuru: I noticed something like that a couple times... I simply chalked it up to my computer being randomly slow. Makes sense it's not just me, though.
I just launched my game ~20 times in a row without issue, so it is very possible this latest change fixed the issue. Hopefully it doesn't come back, as a bug that only happens some of the time + doesn't hard crash the game would be hell to find.
@Bubb It works now! Thank you! That was even better than the changes you intended to make!
By the way, the screening opcode is amazing! Here are some of the things I've done with it:
* I've made it so creatures can effectively get over 127% damage resistance or under -128%.
I might be able to do something similar for Strength, Dexterity, Constitution, Intelligence, Wisdom, and Charisma, allowing creatures to effectively get above 25 in an attribute.
* I've made it so spell and item effects retain the source ID of the creature that used them even when the game is reloaded (they regain the source ID one second after the game is loaded).
Normally if you have a character cast Melf's Acid Arrow on a creature and then save and reload, the delayed damage from the spell will lose its source, and since the game no longer knows an ally cast it, you won't get experience if the delayed damage kills the creature. I've fixed that.
After reload:
This is important for some of the new spells I'm making that link two creatures together.
* I've made it possible for spellcasters to adjust the power of their spells in new ways, like dealing maximum damage with their spells, or adjusting the saving throw penalties on each effect of the spell if the spell is of the right school (similar to the hardcoded bonuses specialist mages get). These would be set through stats on the spellcaster, and the screening opcode checks these stats on the spellcaster and changes the spell based on those stats.
* I've figured out a way for a weapon to deal non-physical damage as their base damage, so you could have a flaming sword that deals extra fire damage from Strength or from damage bonuses, and deals double fire damage on a critical hit or a backstab, and so on.
All of these will require screening effects to be put on every creature in the game (i.e. via WeiDU patches and Baldur.BCS), so they probably won't be included in the base EEex mod. I might create a separate mod (which would require EEex to be previously installed) that has some of these as components.
* I've made it possible for spellcasters to adjust the power of their spells in new ways, like dealing maximum damage with their spells, or adjusting the saving throw penalties on each effect of the spell if the spell is of the right school (similar to the hardcoded bonuses specialist mages get). These would be set through stats on the spellcaster, and the screening opcode checks these stats on the spellcaster and changes the spell based on those stats.
That's amazing! I bet this could lay the groundwork for a mod that adds a Metamagic system to the game; looks like you've already got the main part of Maximize Spell working!
* I've figured out a way for a weapon to deal non-physical damage as their base damage, so you could have a flaming sword that deals extra fire damage from Strength or from damage bonuses, and deals double fire damage on a critical hit or a backstab, and so on.
voidsword and voidhammer from SoD need this as an actual fix, since they only apply unalterable d+3 magical damage and no base phys. damage, making it unaffected by any modifiers (including backstab, kai...), which is unlikely to be WAD (judging by the desc: "A powerful weapon when used against most targets" - ehhm no, it isn't)
@OlvynChuru: That's just awesome! I knew Screen Effects was powerful, but not that powerful! Exactly the kind of thing I was hoping would spawn from EEex.
And I feel like I should go and buy a lottery ticket. Accidentally fixing one of the most serious bugs in EEex to date? Practically unheard of...
@Bubb I found another bug: the Screen Effects opcode doesn't screen any effects of a spell if the target has an opcode 318 or 324 effect that protects them from that spell - even if the target doesn't meet the splprot condition for that effect.
For example, I gave Magic Missile an opcode 324 effect that checks if the target has the Shield spell state. This means the other effects from Magic Missile won't be screened even if the target doesn't have a Shield spell up.
@OlvynChuru: Fixed. Was a stupid mistake where I was copying the function string the wrong direction, (dest -> source instead of source -> dest). Interesting it didn't come up earlier - Opcode #324 must trigger a stats copy for whatever reason.
It's been waaaaaaaaay too long since the last release. I've squashed some bugs recently, so hopefully what's there is stable.
With this release I decided to play a bit of catch up; I've documented every relevant change v0.6.0-alpha makes compared to the previous release, (to help modders though the many changes / new features). The ludicrous changelog is under a "Changelog:" tab on the release page.
(please look at the changelog, it took me way too much time to make )
Having this on the wiki so others can help you would be a good start, or as discussed maybe a separate repo for docs, which could use github pages (like IESDP does) or other solutions (sphinx and readthedocs etc)
I'm sure others would be willing to help - especially modders that are actively using EEex and can post small examples of usage under each function.
I made it so that EEex_IterateActorEffects() also looks through the equipped effects on the actor (I did this a while ago but I forgot to make a pull request for it). I also let EEex_ApplyEffectToActor() set the parameter3, parameter4, parameter5, and variable name in the effect (my system that allows effects to regain the caster's ID after a reload uses parameter5).
Having this on the wiki so others can help you would be a good start, or as discussed maybe a separate repo for docs, which could use github pages (like IESDP does) or other solutions (sphinx and readthedocs etc)
I'm sure others would be willing to help - especially modders that are actively using EEex and can post small examples of usage under each function.
I'm trying to help with documentation. I was using homebrewery, because it looks nice and would be easier to translate to github (because it uses markdown). But maybe a wiki would be a better option.
In any case, let me share what I have so far so we don't duplicate efforts.
Okay, can't really access homebrewery on my phone, but but the last post here is the most recent version. Just saw the new release so that's not in there yet:
There are a lot of benefits with homebrewery. It looks nice. You can have a Toc that links. But, you can't display code that you can copy/paste. You can have images (though, it's awkward with the dual columns, so that's why it's at the end) and you can link elsewhere (I was doing both). But, IDK
Regarding documentation, I'll look into setting up the wiki on the GitHub repository. Once we get a good amount of documentation flowing, a pretty-looking doc, (see what @Grammarsalad has done so far), would be a great addition.
@Bubb If you ever take a look at the "Range" detection for spell-casting, I am curious how it determines how much extra to add. It's usually between 1-2 feet for PC's, and consistent within a given environment(caster/target/area), but otherwise I have no idea how it's determined. I tried experimenting with various creature sizes, but didn't get anything determinate.
This is in regards to "normal" spellcasting. For example, the spell Burning Hands has a range of 5-ft in it's ability headers, but it can be cast up to ~7-ft away. If farther, the character will walk towards the creature before casting to get within range.
To contrast, if you put Burning Hands into a sequencer, it will fail if the target is more than exactly 5-ft away. I am also curious if it would be possible to add this same extra range to spells cast through sequencers and contingencies, so that touch-spells can actually be used in them without failing when targeting others.
It seems to have to do with the character's Personal Space value (set in the animation INI file or by opcode 342). I set Dynaheir's personal space value to 14, and she could cast Invisibility on Jaheira from farther away:
However, increasing a character's Personal Space also causes problems. Having a high Personal Space value is what causes large creatures to get stuck in doorways.
Also, setting a creature's Personal Space to 0 lets them cast a spell at any creature on the map, even outside their visual range. They can also attack or interact with any creature they see.
Also, setting a creature's Personal Space to 0 lets them cast a spell at any creature on the map, even outside their visual range. They can also attack or interact with any creature they see.
This can also be overridden with op342, and it goes both ways - enemies can cast/attack you at any range.
EEex_GetMenuVariantFunction(menuName, typeName) => Returns the internal Lua function associated with the given menu's attribute. Defined typeName's include:
"onopen"
"onclose"
"enabled"
For example:
local defaultOnopen = EEex_GetMenuVariantFunction("WORLD_ACTIONBAR", "onopen")
defaultOnopen()
Would invoke WORLD_ACTIONBAR's current onopen function.
EEex_SetMenuVariantFunction(menuName, typeName, myFunction) => Overwrites the internal Lua function associated with the given menu's attribute. For example:
Would replace WORLD_ACTIONBAR's default onopen function with the specified function.
EEex_ParseActionsString(string) => Parses the given string as if it was fed through C:Eval() and returns the compiled script object, (only filled with actions). Use in conjunction with one of the EEex_EvalActions* functions. For example:
Will fill the B3Test global with the compiled action "SetGlobal("B3Test","GLOBAL",42)".
EEex_EvalActionsAsActorResume(CAIScriptFile, actorID) => Executes compiled actions returned by EEex_ParseActionsString(). Note that due to intentional design, the following function attempts to resume the currently executing action after forcing the passed actions. *** ONLY WORKS CORRECTLY FOR ACTIONS DEFINED IN INSTANT.IDS ***
Will run "SetGlobal("B3Test","GLOBAL",42)" without disrupting what the actor is currently doing.
EEex_EvalActionsStringAsActorResume(string, actorID) => Same as EEex_EvalActionsAsActorResume(), though intead of passing a compiled script object, this function compiles the script from the given string and frees the resulting script object for you. Use this function sparingly, as compiling scripts takes a good amount of time. For example:
Will run "SetGlobal("B3Test","GLOBAL",42)" without disrupting what the actor is currently doing.
EEex_EvalActionsAsActor(CAIScriptFile, actorID) => Executes compiled actions returned by EEex_ParseActionsString(). Results practically identical to using C:Eval(), though note that executing compiled actions is significantly faster than parsing the actions string every call. For example:
Will run "SetGlobal("B3Test","GLOBAL",42)" as if it was run through C:Eval(), albeit without the extra logging and error feedback.
EEex_EvalActionsStringAsActor(string, actorID) => Same as EEex_EvalActionsAsActor(), though intead of passing a compiled script object, this function compiles the script from the given string and frees the resulting script object for you. Use this function sparingly, as compiling scripts takes a good amount of time. For example:
Will run "SetGlobal("B3Test","GLOBAL",42)" as if it was run through C:Eval(), albeit without the extra logging and error feedback.
EEex_FreeActions(CAIScriptFile) => Frees the compiled scripts returned by EEex_ParseActionsString(). Ensure that the freed actions are never used again, as attempting to reference freed actions will result in a crash. For example:
EEex_FreeActions(B3Test)
Will free the memory occupied by B3Test, with the caveat that it can no longer be used without crashing.
@OlvynChuru: Sorry the bouncing hooks are taking so long. The height map is giving me trouble currently...
@kjeron: I'll look into it in the morning. I really shouldn't be awake right now, but EEex called.
@kjeron: Here's the steps the engine takes to calculate casting-range satisfaction:
a = (sprite x / 16) - (target x / 16)
b = (sprite y / 12) - (target y / 12)
c = spell range + 2
Spell Range Satisfied: a^2 + b^2 <= c^2
Here's a screenshot that contrasts the +2 mod to the range of burning hands. Red is the range without the +2 offset, while the blue includes the +2 offset:
Also, it appears if the caster is "touching" the target as a side effect of a large personal space the engine overrides the range requirement and casts anyway.
Edit: Reason why the sequencer fails is because it uses the red "true" range, and not the "extended" blue range used by normal spell casting.
@kjeron: Here's the steps the engine takes to calculate casting-range satisfaction:
a = (sprite x / 16) - (target x / 16)
b = (sprite y / 12) - (target y / 12)
c = spell range + 2
Spell Range Satisfied: a^2 + b^2 <= c^2
Also, it appears if the caster is "touching" the target as a side effect of a large personal space the engine overrides the range requirement and casts anyway.
Thanks for looking into it. I did some more testing and I think I know now why my observed results varied:
It appears that these two steps:
a = (sprite x / 16) - (target x / 16)
b = (sprite y / 12) - (target y / 12)
do not use floating point numbers, but integers. (edit: or include rounding somewhere)
If I position the caster at 225x,1300y, I can cast a 15-ft range spell on a target at up to 511x,1300y.
(range + 2) * 16 + 14 pixels
If I position the caster at 224x,1300y, I can cast a 15-ft range spell on a target at up to 511x,1300y.
(range + 2) * 16 + 15 pixels
If I position the caster at 223x,1300y, I can cast a 15-ft range spell on a target at up to 495x,1300y.
(range + 2) * 16 + 0 pixels
EEex_IsSprite(actorID) => Returns true if the actor is a creature; returns false otherwise (e.g. if the actor is BALDUR.BCS or a script for an area, door, container or region). For example, if you get the sourceID of an effect of a fireball from a trap, and you do EEex_IsSprite(sourceID), it will return false. If the source had been a mage casting a fireball, it would've returned true.
Also, some EEex functions that only work on creatures now do a check with EEex_IsSprite() first so they don't crash if the target isn't a creature.
EEex_GetActorAreaSize(actorID) no longer crashes if it's called right after the game was loaded (when you load the game, for the first few moments creatures don't know what area they're in).
@OlvynChuru: Thanks, merged! Was unexpectedly out for the weekend, sorry for the delay.
Btw, I see you released High Power v2.0 - awesome work! Would you like a new EEex release to point to that includes everything you need? Targeting master might be a tricky business, with the uncertainty that comes with that and all.
The problem is, when you push new features of EEex into master, within a day I usually start working and creating things using those features to put in my mods. So unless you make a new release with every important new feature you push, the releases may sometimes be outdated for purposes of my mod.
@Bubb Good news! Your bounce override stuff won't be necessary. I've figured out a way to not only change a creature's height, but also give them a vertical speed and even a vertical acceleration!
(technically it's velocity, not speed, but whatever; I can get rid of those debug lines)
My implementation is quite versatile. I can add effects that persist as long as a creature is in the air (e.g. pass through walls, wing buffet), and I can have it cast a spell when the creature hits the ground (e.g. falling damage).
I can use this, for example, to give characters the ability to jump!
What I would like is an opcode (or just a stat) that makes a creature always be rendered on top of other objects (as flying creatures are).
@OlvynChuru: I will have the opcode done tomorrow. With the work I've done so far I've found that the shadows / lights in the area are all baked into the light map, and not separately removable. You either use the light map or you don't... so the reason why flying creatures are bright is because they ignore the light map.
I can either make render-override creatures ignore the light map, (being bright like flying creatures), or they can obey the light map and take on the color of whatever space their circle is at. I'm going to assume you want them to obey the light map, so I'll leave that in - correct me if I'm wrong.
So, in the end the opcode will do two things:
Render-override creatures will render on top of normal sprites, but "true" flying creatures will still render on top of everything.
Render-override creatures will always render on top of the map, so they won't be seen as "behind" any objects, see here:
Keldorn is behind / underneath that roof, but he is rendering as if he is on top of it.
Do those two behaviors satisfy everything the opcode needs to do?
Comments
An interesting sidenote: a cool feature of using opcodes like this is that you can keep track of a few things inside the opcode itself, like I'm doing above for block count. Note that you can't do this for equipped effects as they reset on every reload.
However, I found a serious problem with opcode 403 (this was before your new update, so I don't know if you've fixed it already). Putting any opcode 403 effect on a creature sometimes causes enormous slowdown, and sometimes it doesn't. It seems randomly determined when the game is launched whether it will cause slowdown or not. When it causes slowdown, even putting a single opcode 403 effect on a single creature will slow down the game tremendously. When it doesn't cause slowdown, the game can run multiple opcode 403 effects on every creature on the map without any slowdown at all.
It doesn't depend on the function; the same function can switch between causing massive slowdown and not causing any simply by exiting to desktop and running the game again.
Whatever is variably causing slowdown or not causing any is most likely determined in the Lua code when the game is launched, not in the functions that are called by opcode 403 effects.
I just launched my game ~20 times in a row without issue, so it is very possible this latest change fixed the issue. Hopefully it doesn't come back, as a bug that only happens some of the time + doesn't hard crash the game would be hell to find.
By the way, the screening opcode is amazing! Here are some of the things I've done with it:
* I've made it so creatures can effectively get over 127% damage resistance or under -128%.
I might be able to do something similar for Strength, Dexterity, Constitution, Intelligence, Wisdom, and Charisma, allowing creatures to effectively get above 25 in an attribute.
* I've made it so spell and item effects retain the source ID of the creature that used them even when the game is reloaded (they regain the source ID one second after the game is loaded).
Normally if you have a character cast Melf's Acid Arrow on a creature and then save and reload, the delayed damage from the spell will lose its source, and since the game no longer knows an ally cast it, you won't get experience if the delayed damage kills the creature. I've fixed that.
After reload:
This is important for some of the new spells I'm making that link two creatures together.
* I've made it possible for spellcasters to adjust the power of their spells in new ways, like dealing maximum damage with their spells, or adjusting the saving throw penalties on each effect of the spell if the spell is of the right school (similar to the hardcoded bonuses specialist mages get). These would be set through stats on the spellcaster, and the screening opcode checks these stats on the spellcaster and changes the spell based on those stats.
* I've figured out a way for a weapon to deal non-physical damage as their base damage, so you could have a flaming sword that deals extra fire damage from Strength or from damage bonuses, and deals double fire damage on a critical hit or a backstab, and so on.
All of these will require screening effects to be put on every creature in the game (i.e. via WeiDU patches and Baldur.BCS), so they probably won't be included in the base EEex mod. I might create a separate mod (which would require EEex to be previously installed) that has some of these as components.
voidsword and voidhammer from SoD need this as an actual fix, since they only apply unalterable d+3 magical damage and no base phys. damage, making it unaffected by any modifiers (including backstab, kai...), which is unlikely to be WAD (judging by the desc: "A powerful weapon when used against most targets" - ehhm no, it isn't)
And I feel like I should go and buy a lottery ticket. Accidentally fixing one of the most serious bugs in EEex to date? Practically unheard of...
For example, I gave Magic Missile an opcode 324 effect that checks if the target has the Shield spell state. This means the other effects from Magic Missile won't be screened even if the target doesn't have a Shield spell up.
It's been waaaaaaaaay too long since the last release. I've squashed some bugs recently, so hopefully what's there is stable.
With this release I decided to play a bit of catch up; I've documented every relevant change v0.6.0-alpha makes compared to the previous release, (to help modders though the many changes / new features). The ludicrous changelog is under a "Changelog:" tab on the release page.
(please look at the changelog, it took me way too much time to make )
Having this on the wiki so others can help you would be a good start, or as discussed maybe a separate repo for docs, which could use github pages (like IESDP does) or other solutions (sphinx and readthedocs etc)
I'm sure others would be willing to help - especially modders that are actively using EEex and can post small examples of usage under each function.
I made it so that EEex_IterateActorEffects() also looks through the equipped effects on the actor (I did this a while ago but I forgot to make a pull request for it). I also let EEex_ApplyEffectToActor() set the parameter3, parameter4, parameter5, and variable name in the effect (my system that allows effects to regain the caster's ID after a reload uses parameter5).
I'm trying to help with documentation. I was using homebrewery, because it looks nice and would be easier to translate to github (because it uses markdown). But maybe a wiki would be a better option.
In any case, let me share what I have so far so we don't duplicate efforts.
https://github.com/Grammarsalad/readmes/issues/3
Edit: it looks weird because it's formatted for homebrewery.
Edit2: This is how the pdf looks so far:
https://homebrewery.naturalcrit.com/share/rJZOF-sOCV
There are a lot of benefits with homebrewery. It looks nice. You can have a Toc that links. But, you can't display code that you can copy/paste. You can have images (though, it's awkward with the dual columns, so that's why it's at the end) and you can link elsewhere (I was doing both). But, IDK
Regarding documentation, I'll look into setting up the wiki on the GitHub repository. Once we get a good amount of documentation flowing, a pretty-looking doc, (see what @Grammarsalad has done so far), would be a great addition.
This is in regards to "normal" spellcasting. For example, the spell Burning Hands has a range of 5-ft in it's ability headers, but it can be cast up to ~7-ft away. If farther, the character will walk towards the creature before casting to get within range.
To contrast, if you put Burning Hands into a sequencer, it will fail if the target is more than exactly 5-ft away. I am also curious if it would be possible to add this same extra range to spells cast through sequencers and contingencies, so that touch-spells can actually be used in them without failing when targeting others.
It seems to have to do with the character's Personal Space value (set in the animation INI file or by opcode 342). I set Dynaheir's personal space value to 14, and she could cast Invisibility on Jaheira from farther away:
However, increasing a character's Personal Space also causes problems. Having a high Personal Space value is what causes large creatures to get stuck in doorways.
Also, setting a creature's Personal Space to 0 lets them cast a spell at any creature on the map, even outside their visual range. They can also attack or interact with any creature they see.
EEex_GetMenuVariantFunction(menuName, typeName) => Returns the internal Lua function associated with the given menu's attribute. Defined typeName's include:
"onopen"
"onclose"
"enabled"
For example:
Would invoke WORLD_ACTIONBAR's current onopen function.
EEex_SetMenuVariantFunction(menuName, typeName, myFunction) => Overwrites the internal Lua function associated with the given menu's attribute. For example:
Would replace WORLD_ACTIONBAR's default onopen function with the specified function.
EEex_ParseActionsString(string) => Parses the given string as if it was fed through C:Eval() and returns the compiled script object, (only filled with actions). Use in conjunction with one of the EEex_EvalActions* functions. For example:
Will fill the B3Test global with the compiled action "SetGlobal("B3Test","GLOBAL",42)".
EEex_EvalActionsAsActorResume(CAIScriptFile, actorID) => Executes compiled actions returned by EEex_ParseActionsString(). Note that due to intentional design, the following function attempts to resume the currently executing action after forcing the passed actions. *** ONLY WORKS CORRECTLY FOR ACTIONS DEFINED IN INSTANT.IDS ***
For example:
Will run "SetGlobal("B3Test","GLOBAL",42)" without disrupting what the actor is currently doing.
EEex_EvalActionsStringAsActorResume(string, actorID) => Same as EEex_EvalActionsAsActorResume(), though intead of passing a compiled script object, this function compiles the script from the given string and frees the resulting script object for you. Use this function sparingly, as compiling scripts takes a good amount of time. For example:
Will run "SetGlobal("B3Test","GLOBAL",42)" without disrupting what the actor is currently doing.
EEex_EvalActionsAsActor(CAIScriptFile, actorID) => Executes compiled actions returned by EEex_ParseActionsString(). Results practically identical to using C:Eval(), though note that executing compiled actions is significantly faster than parsing the actions string every call. For example:
Will run "SetGlobal("B3Test","GLOBAL",42)" as if it was run through C:Eval(), albeit without the extra logging and error feedback.
EEex_EvalActionsStringAsActor(string, actorID) => Same as EEex_EvalActionsAsActor(), though intead of passing a compiled script object, this function compiles the script from the given string and frees the resulting script object for you. Use this function sparingly, as compiling scripts takes a good amount of time. For example:
Will run "SetGlobal("B3Test","GLOBAL",42)" as if it was run through C:Eval(), albeit without the extra logging and error feedback.
EEex_FreeActions(CAIScriptFile) => Frees the compiled scripts returned by EEex_ParseActionsString(). Ensure that the freed actions are never used again, as attempting to reference freed actions will result in a crash. For example:
Will free the memory occupied by B3Test, with the caveat that it can no longer be used without crashing.
@OlvynChuru: Sorry the bouncing hooks are taking so long. The height map is giving me trouble currently...
@kjeron: I'll look into it in the morning. I really shouldn't be awake right now, but EEex called.
Now excuse me as I promptly pass out
Here's a screenshot that contrasts the +2 mod to the range of burning hands. Red is the range without the +2 offset, while the blue includes the +2 offset:
Also, it appears if the caster is "touching" the target as a side effect of a large personal space the engine overrides the range requirement and casts anyway.
Edit: Reason why the sequencer fails is because it uses the red "true" range, and not the "extended" blue range used by normal spell casting.
It appears that these two steps:
a = (sprite x / 16) - (target x / 16)
b = (sprite y / 12) - (target y / 12)
do not use floating point numbers, but integers. (edit: or include rounding somewhere)
If I position the caster at 225x,1300y, I can cast a 15-ft range spell on a target at up to 511x,1300y.
(range + 2) * 16 + 14 pixels
If I position the caster at 224x,1300y, I can cast a 15-ft range spell on a target at up to 511x,1300y.
(range + 2) * 16 + 15 pixels
If I position the caster at 223x,1300y, I can cast a 15-ft range spell on a target at up to 495x,1300y.
(range + 2) * 16 + 0 pixels
One new function:
EEex_IsSprite(actorID) => Returns true if the actor is a creature; returns false otherwise (e.g. if the actor is BALDUR.BCS or a script for an area, door, container or region). For example, if you get the sourceID of an effect of a fireball from a trap, and you do EEex_IsSprite(sourceID), it will return false. If the source had been a mage casting a fireball, it would've returned true.
Also, some EEex functions that only work on creatures now do a check with EEex_IsSprite() first so they don't crash if the target isn't a creature.
EEex_GetActorAreaSize(actorID) no longer crashes if it's called right after the game was loaded (when you load the game, for the first few moments creatures don't know what area they're in).
Btw, I see you released High Power v2.0 - awesome work! Would you like a new EEex release to point to that includes everything you need? Targeting master might be a tricky business, with the uncertainty that comes with that and all.
That would be nice!
The problem is, when you push new features of EEex into master, within a day I usually start working and creating things using those features to put in my mods. So unless you make a new release with every important new feature you push, the releases may sometimes be outdated for purposes of my mod.
(technically it's velocity, not speed, but whatever; I can get rid of those debug lines)
My implementation is quite versatile. I can add effects that persist as long as a creature is in the air (e.g. pass through walls, wing buffet), and I can have it cast a spell when the creature hits the ground (e.g. falling damage).
I can use this, for example, to give characters the ability to jump!
What I would like is an opcode (or just a stat) that makes a creature always be rendered on top of other objects (as flying creatures are).
Long story short: Assigning a character to the "flying" group messes with pathfinding, script detection, and crashes the game when the area changes.
What I can do is simply brute force render them last, (which will put them on the top of everything).
Some minor details:
Keldorn is "flying" in that screenshot, and as such he is brighter. Do you want this brightness effect?
Not having that brightness effect would be better (unless that's extremely hard to implement). If it's nighttime, sprites should be darker.
I can either make render-override creatures ignore the light map, (being bright like flying creatures), or they can obey the light map and take on the color of whatever space their circle is at. I'm going to assume you want them to obey the light map, so I'll leave that in - correct me if I'm wrong.
So, in the end the opcode will do two things:
Keldorn is behind / underneath that roof, but he is rendering as if he is on top of it.
Do those two behaviors satisfy everything the opcode needs to do?