-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add hooks for modifying elements and thresholds. #127
Conversation
To avoid double-counting element markers in player areas for the aid board, each player area's countItems() loop counts non-token elements separately. This makes it difficult to implement a hook to modify elements, as both counting methods, countItems() and aidBoard's scanElements(), have to be handled separately. To make this easier, shift the onus for avoiding double-counting to the aid board, removing the need for tracking non-token elements. This likely comes with a performance penalty, as now scanElements() must call getZones() on each element token. But scanElements() runs only every two seconds, and getZones() isn't a raycast, so this shouldn't be too bad.
As more hooks are added, the colour's going to be needed more often, so for performance reasons, just find it once at the beginning of the function.
In case Dark Fire wants to delete the Moon or Fire element bag, leaving just a Dark Fire bag.
To avoid variable name shadowing. Instead of defining a shadowed local copy of the color variable in countItems() and other functions, simply edit the outer version of the variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so assuming the idea for darkfire is that you take an 8 element table and turn it into a 7 element table with fire and moon combined, you probably want to fix all the assumed hard coding that you'll always have 8 elements (since in theory something could add a 9th)
script.lua
Outdated
@@ -5729,6 +5729,18 @@ function setupPlayerArea(params) | |||
function Elements:__tostring() | |||
return table.concat(self, "") | |||
end | |||
local function modifyElements(pars) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for syntax purposes, i've typically been calling the parameter params
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did that initially, but on first push, the linter complained that the params
argument in in modifyElements()
was shadowing the params
argument in the outer setupPlayerArea()
function. modifyElements()
has to be called inside setupPlayerArea()
, 'cause the definition of Elements
sits inside setupPlayerArea()
.
I'm not actually sure why Elements
is defined inside setupPlayerArea()
. If this definition could be moved outside setupPlayerArea()
, then the definition of modifyElements()
could likewise be moved outside, thus dodging any shadowing problems. I wonder if it would then also be possible to access the definition of Elements
from the aidBoard
script, 'cause I noticed that the aidBoard
script contains a lot of lines of duplicated code to define Elements
again.
So, do you know why Elements
is defined inside setupPlayerArea()
? Or a better way of avoiding the linter error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont remember why elements is defined in there, Tom (the guy who wrote the python plugin to deconstruct and construct tts save files) was the one who wrote this. i imagine it can be moved outside
edit: test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll move it outside. Given it's duplicated in aidBoard
, I might do something about trying to avoid that duplication, as well. I think I need to read up on metatables to know how to do that properly. I did notice that one of Tom's old pull requests (#48) mentioned that tts-tools
can handle Lua modules, so I may also look into that as a possibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, looks like Tom pulled support for modules in tts-tools
(tomprince/tabletop-tools#21), so I won't be using a module for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it not possible to move Elements
to live outside of the current scope it's in while still having it exist in this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it's certainly possible, and I'm treating it as a backup option. But the definition of Elements
is over 30 lines of code that's duplicated four times (in Global, aidBoard
, PowerEditor
and SpiritEditor
, so it'd be really nice to get those consolidated. I'm still investigating whether that's possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alas, I can't find any way this is possible. I've just moved the global copy of Elements
outside of setupPlayerArea()
, and not touched the other three copies.
Replacing the table with a 7 element table isn't quite the idea, 'cause that wouldn't work correctly with the aid board. The idea is to still return an 8 element table, but where the Moon and Fire entries are both equal to the sum of the input Moon and Fire entries. Altering all Shadows' thresholds in exactly the same way then makes threshold-checking work correctly. The advantage of doing it that way is that it then makes the aid board work correctly, assuming you'd treat all your Moon as Fire for a Fire event, or vice versa. The only place it'd turn 8 elements into 7 is for the actual element bags along the top of the player area. The second element bag would be a dark fire bag, and it'd still be treated as either the fire or the moon bag (it doesn't matter which). The other bag can be nilled out (hence me adding the nil check when editing the buttons that give the counts on the element bags), but the table of element counts stored in the code would still have the full 8 elements. |
script.lua
Outdated
@@ -5729,6 +5729,18 @@ function setupPlayerArea(params) | |||
function Elements:__tostring() | |||
return table.concat(self, "") | |||
end | |||
local function modifyElements(pars) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont remember why elements is defined in there, Tom (the guy who wrote the python plugin to deconstruct and construct tts save files) was the one who wrote this. i imagine it can be moved outside
edit: test
This allows the related functions to use "params" as their argument without shadowing "params" from setupPlayerArea().
Merging the card gain hook has left this with a couple of merge conflicts. They're both pretty trivial to resolve (it's just that both have added new entries to the bottom of |
rebase or another commit is fine with me |
for _,object in pairs(getObjectsWithTag("Modify Elements")) do | ||
params.elements = object.call("modifyElements", params) | ||
end | ||
return Elements:new(params.elements) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to call Elements:new
again? we called it before to pass in parameter to modifyElements
. is this just kind of sanity checking the return value of from the object function callss?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
People writing their own modifyElements()
functions won't have access to the Elements
metatable (or more specifically, won't have access to the functions in the Elements
metatable, even if they can access the metatable itself). And I haven't even mentioned the metatable in the documentation. That's no concern if they modify and return params.elements
, 'cause then the metatable will still be attached. But if they decide to build the table they return from scratch (which the documentation doesn't tell them not to do), then it'll be a plain table without the elements metatable attached. Calling Elements:new()
on it reattaches the metatable, making it essentially a proper Elements
"object" again, rather than just a plain table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And it's necessary to ensure that the object has the metatable attached, 'cause addThresholdDecals()
later uses elements:threshold()
from the metatable:
Line 5811 in 083daed
if elements:threshold(thresholdElements) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense, thanks
To aid in implementing Dark Fire.