PDA

View Full Version : A bit more help with the comabt tracker



Stv
June 7th, 2020, 20:59
I've added in some extra buttongroups to show in the Npc's combat tracker by adding to the ct_host.xml file.
These display where I want them when the NPC is the active character, bu they also display on the minimized sheets of the non-active characters, PC's included.
Whereabouts (I'm assuming somewhere in the ct_entry.lua file) do I need to insert the setVisible commands (depending on the character being active or not) to display/hide the new buttons as necessary.

I've tried injecting/testing into the functions I think are the correct ones but I'm having no luck.

Any assistance would be appreciated.

Cheers, Steve.

Trenloe
June 7th, 2020, 21:18
Within the 5E ct_entry.lua file there is a comment "-- SECTION VISIBILITY FUNCTIONS" - after this there are a number of function that have the .setVisible commands for the various controls within a specific section.

You'll also see these section functions being called at the start of the onInit function.

Stv
June 7th, 2020, 21:27
Yeah, it's around those function I've been experimenting but not having much luck :)
I'll take another look and try and get it working.

Thanks for the info Trenloe.

Cheers, Steve.

Stv
June 7th, 2020, 22:07
Hmm, looks like it may be an issue with my overrides.
The setActiveVisible() function is only called when the CT is 1st opened, but doesn't fire when the current actor is changed :S
It all seems OK to me though, guess I've some digging it do.

Cheers, Steve.

Stv
June 7th, 2020, 23:22
So this is really making my head hurt :)

here's my current new 'ct_entry.lua' file, referenced in my cthost.xml file like so :


<root>
<windowclass name="ct_entry" merge="join">
<script file="ct/scripts/new_ct_entry.lua" />
<sheetdata>


--
-- Please see the license.html file included with this distribution for
-- attribution and copyright information.
--
function onInit()
if super and super.onInit() then
super.onInit()
end
end
function updateDisplay()
if super and super.updateDisplay then
super.updateDisplay()
end
end
function linkToken()
if super and super.linkToken then
super.linkToken()
end
end
function onMenuSelection(selection, subselection)
if super and super.onMenuSelection(selection, subselection) then
super.onMenuSelection(selection, subselection)
end
end
function delete()
if super and super.delete then
super.delete()
end
end
function onLinkChanged()
if super and super.onLinkChanged then
super.onLinkChanged()
end
end
function onHealthChanged()
if super and super.onHealthChanged then
super.onHealthChanged()
end
end
function onIDChanged()
if super and super.onIDChanged then
super.onIDChanged()
end
end
function onFactionChanged()
if super and super.onFactionChanged then
super.onFactionChanged()
end
end
function onVisibilityChanged()
if super and super.onVisibilityChanged then
super.onVisibilityChanged()
end
end
function onActiveChanged()
if super and super.onActiveChanged then
super.onActiveChanged()
end
end
function linkPCFields()
if super and super.linkPCFields then
super.linkPCFields()
end
end
--
-- SECTION VISIBILITY FUNCTIONS
--
function setTargetingVisible()
if super and super.setTargetingVisible then
super.setTargetingVisible()
end
end
function setAttributesVisible()
if super and super.setAttributesVisible then
super.setAttributesVisible()
end
end
function setActiveVisible()
Debug.console("new setactivevisible")
--if super and super.setActiveVisible then
--super.setActiveVisible()
--end
end
function setSpacingVisible(v)
if super and super.setSpacingVisible then
super.setSpacingVisible(v)
end
end
function setEffectsVisible(v)
if super and super.setEffectsVisible then
super.setEffectsVisible(V)
end
end


When I run this, at 1st both the original and new setActiveVisible() functions fire, but when I move the combat tracker on to the next actor, the original setActiveVisible() function fires, not the new one, even after commenting out the call to the original function.

What the hell am I doing wrong here ?

Cheers, Steve.

Trenloe
June 7th, 2020, 23:47
Look through the other XML and LUA associated with the CT for a call to setActiveVisible - use find in files.

Stv
June 8th, 2020, 00:01
One other mention in the 5e ruleset, and that's in template_ct.xml... but it doesn't seem like that's what is calling the original setActiveVisible function.
I'm off to sleep on this one, 'cos I'm going round in circles :P

Cheers, STeve.

damned
June 8th, 2020, 05:21
I really think super.stuff is meant for when you are updating just one or two functions out of a larger file.
When you are updating 15 just replace the whole file!
My 2c.

Trenloe
June 8th, 2020, 08:41
So, there are two approaches here.

1) copy everything from the 5E ruleset and modify as needed. The XML, the LUA, everything. This is what @damned is essentially suggesting. The advantage of this is that it’s quicker/easier to do this. The disadvantage is that the chances of a future update (or another extension) breaking your functionality is pretty high. So, maybe more work in the long run.
2) only change what you’re actually changing. Which is what we’re trying here. More work up front, maybe less headaches in the long run.

Two approaches, each have their pros and cons.

Stv
June 8th, 2020, 08:57
Yeah, I get what damned is saying, and doing that removes my problem...However that is going to remove any possibility of this extension playing nicely with any others that change/edit the combat tracker which I'm trying to avoid.
Even after a nights sleep I can't figure out why it still calls the original file :P
I'll keep plugging away at it though.

Damned, Trenloe, once again thanks for our input it's invaluable.

Cheers, Steve.

Trenloe
June 8th, 2020, 11:53
Let's revisit, and expand on the layering structure. Note - this is my understanding from a practical sense (my experience) and reading posts on the forums. This may not be 100% correct, but I hope it will be close enough! :)

Some info here: https://fantasygroundsunity.atlassian.net/wiki/spaces/FGU/pages/4063481/Ruleset+-+Layering#Window-Class-Merging

In the scenario we're talking about in this thread (and the other thread we worked on). The windowclass for the host entry (ct_entry) in the CT has 3 layers:


The CoreRPG layer - with it's own ct/scripts/ct_entry.lua script file.
5e ruleset - with it's own ct/scripts/ct_entry.lua.
The extension - with it's own ct_entry.lua script file.


5E adds to the CoreRPG ct_entry windowclass with a new layer of XML and LUA code - it can directly access everything in this layer, can get to code in the CoreRPG layer using super references, and can access controls using their control name. Note - a control using the window variable will access the window object within their layer - this running the code within the layer specific scripts. See info here: https://fantasygroundsunity.atlassian.net/wiki/spaces/FGU/pages/4128914/Ruleset+-+Scripting#Script-Block-Scope

Then, the extension adds another windowclass ct_entry layer to the mix. It has it's own ct_entry.lua script file, which we've worked on to make sure its functions call the functions in the 5E layer using the super variable.

So, let's look at this specific problem - what happens when a control defined in the 5E layer raises an event which uses the window variable? (Hopefully the above gives a clue here)... We have a template defined at the 5E layer, and used at the 5E layer (this is the important bit - a control has scope to where it is used) - list_ct_actions which has the following code:


function onListChanged()
window.setActiveVisible();
end
window.setActiveVisible is called with the onListChanged event and is running the setActiveVisible function within it's current scope, using the window variable. So, it runs the function in the ct/scripts/ct_entry.lua related to the current scope - which is the 5E ruleset scope. Which is why you're seeing the 5E layer code running, not your extension layer code running.

I'm sure your question now is "How do I fix this?"

The straightforward approach is to include the controls that use the list_ct_actions template in the extension ct_host.xml file - this will define the controls at that level (they're also defined at a lower level, but the higher level builds on top of that) and so their code that refers to the window script variable will run your custom ct_entry.lua code - which can do its thing and also call the underlying code using super.

Yes, it can get pretty complex. Especially as you're modifying the most complex aspect of a ruleset. But, as has been mentioned, trying to minimize the footprint of your extension (even though it's more work) is probably a better idea in the long run.

I hope some of the above makes sense? Good luck! :)

Stv
June 8th, 2020, 12:00
OK, it turns out I'm a moron :P
I'm still not actually sure what exactly was happening, but it *does* help to not reference a local variable in the original function in your new code, things tend to break when that happens :)

So it appears it's all working as intended now.

Cheers, Steve.

Trenloe
June 8th, 2020, 12:06
Glad it's working now.

That blows my theory out of the water.

Out of curiosity, for my own education, what does the ct_entry windowclass XML look like in the current extension?

Stv
June 8th, 2020, 12:20
Do you mean my updated ct_entry windowclass, Trenloe?

Trenloe
June 8th, 2020, 12:58
Do you mean my updated ct_entry windowclass, Trenloe?
Yep.

Stv
June 8th, 2020, 13:17
Here it is :)

It probably currently has all sorts of non needed bits in it, whilst I've been on the 'trial an error' trail :)


<root>
<windowclass name="ct_entry" merge="join">
<script file="ct/scripts/ct_entry.lua" />
<sheetdata>
<!--New buttoncontrols setup below here-->
<genericcontrol name="spacer_legendary" insertbefore="init">
<anchored height="32">
<top parent="active_spacer_top" anchor="bottom" relation="relative" />
<left parent="activeicon" anchor="right" offset="75" />
<right offset="-17" />
</anchored>
<disabled />
</genericcontrol>

<buttonfield name="legendaryflag" insertbefore="init">
<anchored to="activeicon" position="righthigh" offset="55,30" width="12" height="20" />
<state icon="button_checkoff" tooltipres="ct_tooltip_legendaryoff" />
<state icon="button_checkon" tooltipres="ct_tooltip_legendaryon" />
<setVisible>false</setVisible>
</buttonfield>
<label name="legendaryflag_label" insertbefore="init">
<anchored to="legendaryflag" position="lefthigh" offset="5,0"/>
<static textres="ct_label_legendaryflag" />
</label>

<number_ct name="legendaryaction" source="legendaryassistant.totallegendaryactions" insertbefore="init">
<anchored to ="legendaryflag_label" position="rightlow" offset="100,0" width="34" />
<!--nokeyedit /-->
<max>8</max>
<hideonvalue > 0 </hideonvalue>
<font>reference-b-large</font>
</number_ct>
<label name="legact_label1" insertbefore="init">
<anchored to="legendaryaction" position="lefthigh" offset="10,-5"/>
<static textres="ct_legendary" />
</label>
<label name="legact_label2" insertbefore="init">
<anchored to="legendaryaction" position="lefthigh" offset="18,9"/>
<static textres="ct_legendary_actions" />
</label>
<buttongroup_counter name="legactcounter" insertbefore="init">
<anchored to="legendaryaction" position="righthigh" offset="5,2" />
<allowsinglespacing />
<sourcefields>
<current>legendaryassistant.legendaryactions</current>
<maximum>legendaryassistant.totallegendaryactions</maximum>
</sourcefields>
<values>
<maximum>8</maximum>
</values>
<maxslotperrow>4</maxslotperrow>
</buttongroup_counter>

<number_ct name="legendaryresistance" source="legendaryassistant.totallegendaryresistances" insertbefore="init">
<anchored to="legendaryaction" position="rightlow" offset="125,0" width="34" />
<!--nokeyedit /-->
<max>8</max>
<hideonvalue > 0 </hideonvalue>
<font>reference-b-large</font>
</number_ct>
<label name="legres_label1" insertbefore="init">
<anchored to="legendaryresistance" position="lefthigh" offset="10,-5"/>
<static textres="ct_legendary" />
</label>
<label name="legres_label2" insertbefore="init">
<anchored to="legendaryresistance" position="lefthigh" offset="6,9"/>
<static textres="ct_legendary_resistances" />
</label>
<buttongroup_counter name="legrescounter" insertbefore="init">
<anchored to="legendaryresistance" position="righthigh" offset="5,2" />
<allowsinglespacing />
<sourcefields>
<current>legendaryassistant.legendaryresistances</current>
<maximum>legendaryassistant.totallegendaryresistances</maximum>
</sourcefields>
<values>
<maximum>8</maximum>
</values>
<maxslotperrow>4</maxslotperrow>
</buttongroup_counter>


<number_ct name="lairact" source="legendaryassistant.totallairactions" insertbefore="init">
<anchored to="legendaryresistance" position="rightlow" offset="105,0" width="34" />
<!--nokeyedit /-->
<max>8</max>
<hideonvalue > 0 </hideonvalue>
<font>reference-b-large</font>
</number_ct>
<label name="lairact_label1" insertbefore="init">
<anchored to="lairact" position="lefthigh" offset="16,-5"/>
<static textres="ct_lair" />
</label>
<label name="lairact_label2" insertbefore="init">
<anchored to="lairact" position="lefthigh" offset="6,9"/>
<static textres="ct_lair_actions" />
</label>
<buttongroup_counter name="lairactcounter" insertbefore="init">
<anchored to="lairact" position="righthigh" offset="5,2" />
<allowsinglespacing />
<sourcefields>
<current>legendaryassistant.lairactions</current>
<maximum>legendaryassistant.totallairactions</maximum>
</sourcefields>
<values>
<maximum>8</maximum>
</values>
<maxslotperrow>4</maxslotperrow>
</buttongroup_counter>
</sheetdata>
</windowclass>
</root>

Trenloe
June 8th, 2020, 13:20
Thanks for that.

Maybe the list_ct_actions template setActiveVisible gets called at a different time. It was just for the various 5E NPC abilities/traits - so if you see some display issues with them, remember this thread!

Stv
June 8th, 2020, 13:31
I'm absolutely certain I'll come unstuck with this agin at some point, and will reading and re-reading what you've posted :P

Thanks again Trenloe.

Cheers, Steve.