Closed phylll closed 2 years ago
Ok, so there is hopefully a single point where anyone's endurance may be reduced to zero, which is m3mgdModifyEndurance()
.
Quick-and-dirty solution:
m3mgdModifyEndurance()
: if I carry one of these blades with its magic active, and my endurance hits zero, end the effect and produce the output to that effect.Elegant and scalable solution:
m3mgdModifyEndurance()
call a character's event handler on zero endurance (pull the command from a character attribute, call !mmm chat: !mmm do ${call}
)Either solution requires refactoring rune effect deactivation code into global functions, since otherwise we would be replicating the same code in two places.
What could a flexible event handler look like?
It would need to be
Since nested lists are not possible until we get https://github.com/michael-buschbeck/mychs-macro-magic/issues/159, for now we can only do single event handlers per char-event combination, and fixed storage for each. Storage would need to be in an attribute since that can be either tied to a character (sheet) and/or the name dynamically generated (char.(prefix & charID & suffix)
), neither of which are possible for accessing variables.
So, we could store an attribute m3mgd_event_endurance_floor
in the character's own sheet. The attribute would contain an MMM code line, usually a function call such as do runeEffectEarthBond("<charID>",default,default,"releaseByExhaustion")
which could be called dynamically through !mmm chat: ${line}
once pulled from its attribute.
When an earth bond is created, the creating code would write this code line into the event handler attribute. It could even dynamically generate a function and publish it to the game context, and write its call into the attribute:
!mmm chat: !mmm script
!mmm chat: !mmm function __myDynFunc()
!mmm chat: !mmm chat: Hello World!
!mmm chat: !mmm end function
!mmm chat: !mmm publish to game: __myDynFunc
!mmm chat: !mmm end script
!mmm
!mmm do setattr(charID, eventHandlerAttrLabel, "do __myDynFunc()")
When an earth bond is released, the handler attribute would be reset to ""
.
There is a risk of garbage cluttering the state of the game: if the earth bond status marker is removed manually rather than through the script (e.g. because the earth bond was set by accident), the invalid event handler is kept until the character's next earth bond is properly removed. Since valid earth bonds may well persist between game sessions (long combat sequences), however, cleaning out all event handlers at autorun is not an option. A cleanup script for all character event handlers would be a simple solution, though.
Alright, so that was fun thinking about. However, with no ways of validating the attribute and thus opening up to arbitrary code injection, including by accident, I decided to go for a simpler solution.
What I ended up implementing is a simple "stop all active rune blade effects" function that is executed by m3mgdModifyEndurance()
when it hits zero. Drawback: This comes earlier than the combat scripts' main output. It would be better to delay the effect until after the immediate effects of a hit -- including the fact that the character is reaching zero endurance -- were displayed.