PDA

View Full Version : Need help using images and tokens from a module



Diablobob
December 24th, 2018, 20:27
Hello,

I'm making an extension for FG and I'm having issues using images and tokens in my module. Using image@module isn't working. I've tried using GetModule, getmoduleinfo, get path, get root... I think I'm getting close, but it has eluded me for the last couple weeks. I might just be messing up the syntax... I don't know anymore... It's extremely frustrating!

I also do not know if I should use a onmodule load trigger, or just be able to use Oninit... Or if I need to identify the addressing in some way...

I have been working hard to crack this cookie... Any help would be greatly appreciated!

I'm trying to set an image (for bitmapWidget) or token (setting the prototype())but so far I have to include the file in the extension... And I want to use a token module...

Thank you all for your time, help and Happy holidays!

V/r,
~Bob

damned
December 24th, 2018, 21:16
Hello,

I'm making an extension for FG and I'm having issues using images and tokens in my module. Using image@module isn't working. I've tried using GetModule, getmoduleinfo, get path, get root... I think I'm getting close, but it has eluded me for the last couple weeks. I might just be messing up the syntax... I don't know anymore... It's extremely frustrating!

I also do not know if I should use a onmodule load trigger, or just be able to use Oninit... Or if I need to identify the addressing in some way...

I have been working hard to crack this cookie... Any help would be greatly appreciated!

I'm trying to set an image (for bitmapWidget) or token (setting the prototype())but so far I have to include the file in the extension... And I want to use a token module...

Thank you all for your time, help and Happy holidays!

V/r,
~Bob

welcome Diablobob
I think because of load orders that things like widgets need to be in the ruleset or at the very least an extension.
I think modules are loaded too late for use in most ofthese graphical elements.

Diablobob
December 24th, 2018, 21:56
welcome Diablobob
I think because of load orders that things like widgets need to be in the ruleset or at the very least an extension.
I think modules are loaded too late for use in most ofthese graphical elements.


It's in an extension... I'm trying to access the images and tokens, in a module, from the extensions...

Diablobob
December 24th, 2018, 22:03
So using an onmoduleload is probably my best bet... But still having pathing issues...

damned
December 24th, 2018, 23:25
So using an onmoduleload is probably my best bet... But still having pathing issues...

I could be wrong but modules load too late for what you are trying to do.
It needs to be in the extension.

Diablobob
December 25th, 2018, 00:15
I don't see why it would necessarily need to be "in" the ext...

To my knowledge the load hierarchy is:
FG
Rulesets
Extensions
Modules

If the sole problem was the load order, then rulesets would not be able to access modules... And the function I'm looking for is basically the same as the letters module usage by extensions and rulesets... Just instead of letters.mod, I want to use my module...

Automatic Letters was even incorporated into coreRPG by moonwizard after Ikael made a module to do such, for the SW ruleset... Obviously it was changed for the ruleset... But, my question is how do I do it?...

In the ruleset moonwizard made the addressing as token@module... I just need to know how to setup that same type of addressing for my extension...

Diablobob
December 25th, 2018, 00:19
Also before it was added to corRpg, trenlo adjusted the extension code to be used in 5e... And it worked... I'm just trying to figure out that ability

Trenloe
December 25th, 2018, 02:58
I'm trying to set an image (for bitmapWidget) or token (setting the prototype())but so far I have to include the file in the extension... And I want to use a token module...
For tokens you need the full path to the token within the .mod file, plus the @<module name> reference (the <name> field from the module definition.xml file). For example: tokens/tokenname.png@Token Module

I'm not really sure what you're trying to do and when. If you're trying to access tokens in modules during the initialization of an extension, then that probably won't work - which is what damned was mentioning. If your code is only ran once the campaign is fully loaded, then you should be able to access the token files in a module - assuming you have the path and module name correct.

Diablobob
December 25th, 2018, 04:13
For tokens you need the full path to the token within the .mod file, plus the @<module name> reference (the <name> field from the module definition.xml file). For example: tokens/tokenname.png@Token Module

I'm not really sure what you're trying to do and when. If you're trying to access tokens in modules during the initialization of an extension, then that probably won't work - which is what damned was mentioning. If your code is only ran once the campaign is fully loaded, then you should be able to access the token files in a module - assuming you have the path and module name correct.

Ah! I think that is where I was having an issue... I miss understood the context of damned's message... If you read this damned, I'm sorry if I seamed rude in anyway! I was just trying to figure stuf out...

Also thank you trenloe, I will try that... I was thinking that was the case, but I think I was placing it in the wrong location...

Diablobob
December 25th, 2018, 04:25
I think what my main problem is I was trying to define them in the ext, but was missing adding them to the mod file definitions... I'll let you know when I get to try it out

Trenloe
December 25th, 2018, 07:02
I think what my main problem is I was trying to define them in the ext, but was missing adding them to the mod file definitions...
You don’t need to add individual token names to the module definition.xml file. The <name> tag I mentioned is for the module name, to be used after the @ sign when referencing any tokens from that module in code.

Diablobob
December 25th, 2018, 15:46
You don’t need to add individual token names to the module definition.xml file. The <name> tag I mentioned is for the module name, to be used after the @ sign when referencing any tokens from that module in code.

Well... I feel stupid... I just realized I've been trying to use them as images for bitmapWidget... And using it as stated for that purpose isn't working... I need to overhaul the code and use tokenmanager.setprototype(X)

Wish me luck!

Diablobob
December 27th, 2018, 13:59
For tokens you need the full path to the token within the .mod file, plus the @<module name> reference (the <name> field from the module definition.xml file). For example: tokens/tokenname.png@Token Module

I'm not really sure what you're trying to do and when. If you're trying to access tokens in modules during the initialization of an extension, then that probably won't work - which is what damned was mentioning. If your code is only ran once the campaign is fully loaded, then you should be able to access the token files in a module - assuming you have the path and module name correct.

So I'm still having issues...

Is the <tokencontrol>.setprototype... Supposed to be in the XML or the LUA?

Also does setprototype change the token, or just token reference/I'd? Would I still need a replaceCombatantToken?

Lastly, I'm having issues getting the refnode and refid for the token...

Any help or suggestions would be appreciated!

Diablobob
December 27th, 2018, 14:54
I should probably clarify that I'm trying to change the token on the map with a different token... 5e ruleset

Andraax
December 27th, 2018, 16:21
Why don't you just drop a new token onto the entry on the CT?

Diablobob
December 27th, 2018, 16:39
Why don't you just drop a new token onto the entry on the CT?

I'm trying to automate the swap to make things easier

Trenloe
December 27th, 2018, 16:54
Is the <tokencontrol>.setprototype... Supposed to be in the XML or the LUA?
It always has to be in LUA code. LUA can be in specific LUA files (.lua file extension) or it can be within <script> tags in FG XML. Where you put it really relies on what you're doing. If you're doing anything complex, it's better doing it in a LUA file - as error checking/commenting is better in LUA files rather than LUA code embedded in XML.


Also does setprototype change the token, or just token reference/I'd? Would I still need a replaceCombatantToken?
It should change the image used for the token instance, it shouldn't change the ID.

CombatManager.replaceCombatantToken is used when the token for a creature is changed in the CT (drag/drop a token to the token entry in the CT) - this replaces the token graphic in the CT and the linked token instance on an image with the new token instance (the old token instance on the map is deleted).


Lastly, I'm having issues getting the refnode and refid for the token...
If the token is already on the image (which I'm guessing it is based off your follow up post), then you can get the tokeninstance (https://www.fantasygrounds.com/refdoc/tokeninstance.xcp) object using the CombatManager.getTokenFromCT command - which takes the database node of the linked combat tracker entry.

If you don't know the combat tracker entry, then you'll need to get all of the tokens on a specific image control: https://www.fantasygrounds.com/refdoc/imagecontrol.xcp#getTokens which will give you a LUA table of tokeninstance (https://www.fantasygrounds.com/refdoc/tokeninstance.xcp) objects, which you can iterate through and use getName, getPrototype, etc. to try to identify the individual tokeninstance.

Diablobob
December 27th, 2018, 17:32
It always has to be in LUA code. LUA can be in specific LUA files (.lua file extension) or it can be within <script> tags in FG XML. Where you put it really relies on what you're doing. If you're doing anything complex, it's better doing it in a LUA file - as error checking/commenting is better in LUA files rather than LUA code embedded in XML.


It should change the image used for the token instance, it shouldn't change the ID.

CombatManager.replaceCombatantToken is used when the token for a creature is changed in the CT (drag/drop a token to the token entry in the CT) - this replaces the token graphic in the CT and the linked token instance on an image with the new token instance (the old token instance on the map is deleted).


If the token is already on the image (which I'm guessing it is based off your follow up post), then you can get the tokeninstance (https://www.fantasygrounds.com/refdoc/tokeninstance.xcp) object using the CombatManager.getTokenFromCT command - which takes the database node of the linked combat tracker entry.

If you don't know the combat tracker entry, then you'll need to get all of the tokens on a specific image control: https://www.fantasygrounds.com/refdoc/imagecontrol.xcp#getTokens which will give you a LUA table of tokeninstance (https://www.fantasygrounds.com/refdoc/tokeninstance.xcp) objects, which you can iterate through and use getName, getPrototype, etc. to try to identify the individual tokeninstance.


So if I'm understanding it all, I need to update the prototype for the linked token entry inside the token instance... And when I update the prototype, the token image, on the map, will change accordingly?

Diablobob
December 27th, 2018, 17:47
So how does this look?
CombatManager.getTokenFromCT(setPrototype("TokenName.png@ModuleName")

Would that update the token image on the map if triggered by a player action or click? Or would I need to do a getActor type thing for the getTokenFromCT ?

Diablobob
December 27th, 2018, 17:55
Possibly better to nest them?

Local CharEntry = CombatManager.getTokenFromCT

CharEntry.setPrototype("TokenImageName.png@ModuleName")

But would I still need to identify the actor(CT actor) for the getTokenFromCT?

Trenloe
December 27th, 2018, 18:05
But would I still need to identify the actor(CT actor) for the getTokenFromCT?
Yes you need to pass that data into the getTokenFromCT function - otherwise it won't know which CT entry you're referring to.

Unpack the CoreRPG ruleset into some temporary folder on your hard drive and use a text editor Find in files functionality for "getTokenFromCT" (notepad ++ works well) - this will show you examples of how to use the function.

Diablobob
December 27th, 2018, 18:33
Thank you! I will be able to fully test it this evening...

I apologize for being any kind of bother... I'm still very new to FG programming

Diablobob
December 28th, 2018, 17:28
Yes you need to pass that data into the getTokenFromCT function - otherwise it won't know which CT entry you're referring to.

Unpack the CoreRPG ruleset into some temporary folder on your hard drive and use a text editor Find in files functionality for "getTokenFromCT" (notepad ++ works well) - this will show you examples of how to use the function.

ok, so I've gotten further... but now I keep getting a nil error... I don't know what I'm doing wrong.

so far:

local CharEntry = CombatManager.getTokenFromCT(rTarget);
local sType = (variable token image name set by another function);
local aProto = "tokens/" .. sType .. ".png@ModuleName";
CharEntry.setPrototype(aProto);
The error I've been getting is:

attempt to call field 'setPrototype' (a nil value)

So I tried to change it to

CharEntry.token.setPrototype(aProto);
Now I'm getting:

attempt to index field 'token' (a nil value)

Diablobob
December 28th, 2018, 18:32
is the problem that aProto isn't setup as a "token" type?

how would I declare that?

Is my syntax wrong?

Diablobob
December 28th, 2018, 20:38
is the problem that aProto isn't setup as a "token" type?

how would I declare that?

Additional notes: the module is loaded and the token that the addressing points to is displayed in the tokens menu (normal way of selecting tokens)...

I've been tryin different ways of trying to get this to work and keep getting nil errors

Diablobob
January 4th, 2019, 16:41
Further down the rabbit hole: So, I've managed to successfully swap out the token like I need... however, I am getting an error that I cannot seam to get around.

After the token is switched to the new one using:


local aProto = "tokens/TokenName.png@ModuleName";
local nodeTok = ActorManager.getCTNode(rTarget);
local tokCT = CombatManager.getTokenFromCT(rTarget);
DB.setValue(nodeTok, "token", "token", aProto);
local nodeContainerOld = tokCT.getContainerNode();
local newTokenInst = Token.getToken(nodeContainerOld.getNodeName(),DB.g etValue(nodeTok, "token", ""));
CombatManager.replaceCombatantToken(nodeTok, newTokenInst);


The token switches, and then I get the following error:


Script Error: [string "scripts/manager_token.lua"]:378: attempt to index local 'tokenCT' (a userdata value)


The error is happening in the "updateName(nodeName)" function in the TokenManager...

I've tried update owner, updateEffects, many other iterations... and if the token switches, I get the error...

Also newTokenInst is coming up as a nil value... which is where the issue is probably stemming from... however, how do I feed the correct "newTokenInstance" into replaceCombatantToken... I've also tried many iterations of trying to manually create or derive the token instance from


DB.setValue(nodeTok, "token", "token", aProto);


Any help on how to get this straight would be appreciated greatly!

damned
January 4th, 2019, 21:55
can you post screenshots or short video?

Diablobob
January 4th, 2019, 23:31
can you post screenshots or short video?

I will as soon as I can get to my computer this evening... ATM...newTokenInst is coming up nil... I tried a manual addToken, and that came up nil as well...

I know I need to create a new token instance and feed that through the process... But I don't know the correct way to create a token instance... (Pretty sure I keep getting the syntax wrong)... I will post more tonight when I get to comp

Diablobob
January 5th, 2019, 07:24
I don't have time this evening to post the screenshots... however I can explain what I'm trying to do very simply...

I am trying to do the same function as dropping an image onto the combat tracker character. How when you drop it, the image in the combat tracker and the map both change.

I am guessing, I need to ImageManager.registerImage(aProto) or something... and then update the refnode... at least that is where my thought process is at the moment... things have been hectic, and I'm not getting as much keyboard time as I'd like due to life... so ideas I come up with are far between tests... I am still new-ish to the specific callouts of the commands of FG...

so if I do an ActorManager.getCTnode(rTarget) I can use that to change the image on the combat tracker... however, that is where things start to fall apart... Although the image in the combat tracker changes, the token on the map does not...

if I run CombatManager.replaceCombatantToken.. it replaces the token on the map... but in doing to,throws up the error... I am unsure what is causing the image to update... if I could isolate that, I could try to emulate it and possibly circumvent the error...

If there is an easier way, I would appreciate any help I could get on this matter.

damned
January 5th, 2019, 08:08
You are way over my head - but if the image on the map can be replaced with CombatManager.replaceCombatantToken Id keep working at how/why the error is being generated and fix the error...

Diablobob
January 5th, 2019, 14:10
You are way over my head - but if the image on the map can be replaced with CombatManager.replaceCombatantToken Id keep working at how/why the error is being generated and fix the error...


Well, after thinking about it... The image is in the module is already listed in the tokenbag for the module... Which I'm guessing means it's already a registered image...I just need to figure out how to get the token/imagenode info for said image... Then the error should go away... However, that is new territory for me... Does anyone know how to get the info of a given image in the module tokenbag, without using draginfo?

Andraax
January 5th, 2019, 16:51
The code that handles a dropped token in the CT is in the file ct_token.lua for CoreRPG.

Diablobob
January 6th, 2019, 00:59
The code that handles a dropped token in the CT is in the file ct_token.lua for CoreRPG.

That is appreciated!... I will get to work on it this evening...

I just need to now find out how to "find" a token that's in the module... Since its in the token bag for the module... I'm guessing it's just something I'm overlooking that is simple...

The thing that is odd to me... Is after I update the token for the CT... Pulling the data from it all turns into nil, exceptional he path...

Diablobob
January 6th, 2019, 14:00
well, I'm back to trying to figure out how to get the token instance for the image in the module...

Or how to create a token instance for that image...

CombatManager.replaceCombatantToken is the key to getting the new token to be displayed in the map...

The error I keep getting is because I still need the newtokeninstance to push through the function... I don't understand why it's still updating the token on the map with the right one... Cause currently newTokenInstance is still being fed a nil value...

I think the error will be resolved once I figure out how to create a token instance with the image from the module, or to get the token data for that token, in the token bag...

This has been very frustrating an I'm not making any headway right now... Since I'm not using a drag/drop, which is what everything seams to use, I can't seam to get past this roadblock... I keep getting the error...

Diablobob
January 6th, 2019, 15:43
Boiled down...

How do you turn an image path, into a token instance? And then be able to reference the token instance.

That's what I'm really trying to do at the moment.

Moon Wizard
January 7th, 2019, 02:00
I think you might be having some terminology issues here:

* A "tokeninstance" is a very specific object type that is the Lua reference to a token that is tied to an imagecontrol. It can be acquired though drag and drop as you have seen in some of the code; or via imagecontrol.addToken API. It can not be generated from a token asset path.

* The token assets within a module are not "tokeninstance" objects. They are just assets that can be used with the addToken API.

* There are examples of this kind of activity in CombatManager.addBattle and CombatManager.replaceCombatantToken. You should use these as examples.

Regards,
JPG

Diablobob
January 7th, 2019, 07:07
Thank you Moon Wizard... that helped tremendously!
I wasn't understanding what a tokeninstance actually was...

So the error is still there... however, I now know what is triggering it... and I was able to isolate it down due to my new understanding on tokeninstance... since I was able to now feed the function a proper token instance, I was able to confirm that it wasn't the input...

The error I am getting occurs when the old token is deleted:


oldTokenInstance.delete();


Error code:


Script Error: [string "scripts/manager_token.lua"]:378: attempt to index local 'tokenCT' (a userdata value)


I isolated all the functions of CombatManager.replaceCombatantToken, and the error persisted, until I didn't delete the old token.

The TokenManager function that is having the error is:


function updateName(nodeName)
local nodeCT = nodeName.getParent();
local tokenCT = CombatManager.getTokenFromCT(nodeCT);
if tokenCT then
updateNameHelper(tokenCT, nodeCT);
updateTooltip(tokenCT, nodeCT);
end
end


So, I am at a loss for the moment on this one... But there is progress! I did replace the token like I wanted... and now getting rid of the old one is the issue...

*sigh*

damned
January 7th, 2019, 07:13
one step at at a time!

damned
January 8th, 2019, 00:41
I wonder if there is anything in Mintys extension that might help you...
https://www.fantasygrounds.com/forums/showthread.php?46890-Druid-Wild-Shapes-(for-5E)

Diablobob
January 8th, 2019, 00:57
I wonder if there is anything in Mintys extension that might help you...
https://www.fantasygrounds.com/forums/showthread.php?46890-Druid-Wild-Shapes-(for-5E)

That extension was brought to my attention after I had released my first version... He did a good job with it, however he uses completely different processes, and doesn't have a token swap... I am a fan of his work though, he's a good programmer...

I did some more digging during my lunch, and I put in a ton of console debug comments... It showed that the error is coming from the initial script... Which is a loop that uses update effects helper ...

The problem is that aparently after the functions have completed, and the loop goes to start over, it tries to use the previous version of tokenCT instead of acquiring the new version...

I've tried to massage te code to try to force the acquisition of the new version... However I haven't made any progress with it... If it will help, I'll post the code I use for the loop in a little while...

Diablobob
January 8th, 2019, 01:12
I think if it keeps being too much of a pain, that adding a couple addHandlers might be the way I might have to go in the init... But... I don't know how to use those to keep an eye on or extract the effect, since I haven't looked into handlers yet... Any advice on this?

Moon Wizard
January 8th, 2019, 16:06
Make sure to use Debug.chat and Debug.console extensively while developing to inspect variables in situations where things aren’t working as expected.

If you are making multiple passes through the combat tracker nodes, you will need to request the attributes/token during each pass, especially since you are changing things during each pass.

Again, use Debug.chat/console during the loops to inspect the variables to make sure they are what you expect.

Regards,
JPG

Diablobob
January 8th, 2019, 17:29
Still sitting at the same wall, with no progress...

As much as I dislike posting walls of code (i prefer the more short and to the point)... I am having a rough time hunting down this one... I have placed MANY Debug.console checks inside the entire code... I will post the loop and explain what I am seeing/doing, to hopefully aid in hunting down the reason for the error... Console log will be at bottom of post...

First, The Init code, to setup the basis of the loop, using updateEffectsHelper to keep an eye on the effects and help trigger the event:


function onInit()
orgUpdateEffectsHelper = TokenManager.updateEffectsHelper;
TokenManager.updateEffectsHelper = shiftedUpdateEffectsHelper;
end


Then the function trigger from the loop:


function shiftedUpdateEffectsHelper(tokenCT, nodeCT)
Debug.console("ATTENTION: shiftedUpdateEffectsHelper initiated");
orgUpdateEffectsHelper(tokenCT, nodeCT);
Debug.console("ATTENTION: orgUpdateEffectsHelper initiated");
if not procShiftedActive then
procShiftedActive = true;
processShifted(nodeCT,true,true);
procShiftedActive = false;
end

end


Next, the function that pulls the effect and triggers the processes of changing the token and such when the effect is added to the character:


function processShifted(nodeUnit,processStats,processToken)
local sTargetType, nodeTarget = ActorManager.getTypeAndNode(nodeUnit);
if sTargetType == "pc" or sTargetType == "ct" then
for _,nodeChild in pairs(DB.getChildren(nodeUnit, "effects")) do
local rEffect = EffectManager.getEffect(nodeChild);
if rEffect and (rEffect.sName or "") ~= "" then
if string.sub(rEffect.sName,1,8) == "Shifted;" then
if processStats then
setShiftedStats(sTargetType, nodeTarget, rEffect);
Debug.console("ATTENTION: setShiftedStats initiated");
setShiftedHP(sTargetType, nodeTarget, rEffect);
Debug.console("ATTENTION: setShiftedHP initiated");
end
if processToken then
setShiftedToken(sTargetType, nodeTarget, nodeUnit, rEffect);
Debug.console("ATTENTION: setShiftedToken initiated");
end
end
end
end
if processStats then
clearShiftedStats(sTargetType, nodeTarget);
Debug.console("ATTENTION: clearShiftedStats initiated");
end
if processToken then
clearShiftedToken(sTargetType, nodeTarget, nodeUnit);
Debug.console("ATTENTION: clearShiftedToken initiated");
end
end
end


Now the console readout:
Before Event Trigger:


Runtime Notice: s'ATTENTION: tokenCT = ' | tokeninstance = { { container = image.id-00001.image, id = 262, scale = 3.216, x,y = 1551,651 } }
Runtime Notice: s'ATTENTION: shiftedUpdateEffectsHelper initiated'
Runtime Notice: s'ATTENTION: orgUpdateEffectsHelper initiated'
Runtime Notice: s'token Scale Set'
Runtime Notice: s'ATTENTION: setShiftedToken COMPLETED'
Runtime Notice: s'ATTENTION: setShiftedToken initiated'
Runtime Notice: s'ATTENTION: clearShiftedStats STARTED'
Runtime Notice: s'revert stats process'
Runtime Notice: s'ATTENTION: clearShiftedStats COMPLETED'
Runtime Notice: s'ATTENTION: clearShiftedStats initiated'
Runtime Notice: s'ATTENTION: clearShiftedToken STARTED'
Runtime Notice: s'begining clear shifted process'
Runtime Notice: s'clear shifted process User Host check'
Runtime Notice: s'token Scale revert'
Runtime Notice: s'ATTENTION: clearShiftedToken COMPLETED'
Runtime Notice: s'ATTENTION: clearShiftedToken initiated'


Event Triggered, processing:


Runtime Notice: s'ATTENTION: tokenCT = ' | tokeninstance = { { container = image.id-00001.image, id = 262, scale = 3.216, x,y = 1551,651 } }
Runtime Notice: s'ATTENTION: shiftedUpdateEffectsHelper initiated'
Runtime Notice: s'ATTENTION: orgUpdateEffectsHelper initiated'
Runtime Notice: s'ATTENTION: setShiftedStats STARTED'
Runtime Notice: s'Setting new Stats'
Runtime Notice: s'ATTENTION: setShiftedStats COMPLETED'
Runtime Notice: s'ATTENTION: setShiftedStats initiated'
Runtime Notice: s'ATTENTION: setShiftedHP STARTED'
Runtime Notice: s'Begin setShiftedHP'
Runtime Notice: s'user host check for shifted hp'
Runtime Notice: s'PreShiftedHP = ' | #29
Runtime Notice: s'PreShiftedWounds = ' | #4
Runtime Notice: s'ACTIVEHP = ' | #34
Runtime Notice: s'ACTIVEWOUNDS = ' | #0
Runtime Notice: s'ATTENTION: setShiftedHP initiated'
Runtime Notice: s'ATTENTION: setShiftedToken STARTED'
Runtime Notice: s'early tokenCT = ' | tokeninstance = { { container = image.id-00001.image, id = 262, scale = 3.216, x,y = 1551,651 } }
Runtime Notice: s'oldTokenInstance = ' | tokeninstance = { { container = image.id-00001.image, id = 262, scale = 3.216, x,y = 1551,651 } }
Runtime Notice: s'nodeContainerOld = ' | databasenode = { image.id-00001.image }
Runtime Notice: s'x,y = ' | #1551 | #651
Runtime Notice: s'nodeContainerOld.getNodeName' | s'image.id-00001.image'
Runtime Notice: s'ImgCntrl = ' | { #1 = tokeninstance = { { container = image.id-00001.image, id = 262, scale = 3.216, x,y = 1551,651 } }, #2 = tokeninstance = { { container = image.id-00001.image, id = 263, scale = 2.5125, x,y = 1551,651 } } }
Runtime Notice: s'ATTENTION: tokenCT = ' | tokeninstance = { { container = image.id-00001.image, id = 263, scale = 2.5125, x,y = 1551,651 } }


Continue Loop, scale adjusted during this loop:


Runtime Notice: s'ATTENTION: shiftedUpdateEffectsHelper initiated'
Runtime Notice: s'ATTENTION: orgUpdateEffectsHelper initiated'
Runtime Notice: s'link complete'
Runtime Notice: s'update vis complete'
Runtime Notice: s'update targets complete'
Runtime Notice: s'updateName complete'
Runtime Notice: s'ATTENTION: tokenCT = ' | tokeninstance = { { container = image.id-00001.image, id = 263, scale = 2.5125, x,y = 1551,651 } }
Runtime Notice: s'ATTENTION: shiftedUpdateEffectsHelper initiated'
Runtime Notice: s'ATTENTION: orgUpdateEffectsHelper initiated'
Runtime Notice: s'updateEffects complete'
Runtime Notice: s'replaceCombatantToken complete'
Runtime Notice: s'ImgCntrl = ' | { #1 = tokeninstance = { { container = image.id-00001.image, id = 263, scale = 2.5125, x,y = 1551,651 } } }
Runtime Notice: s'tokenCT = ' | tokeninstance = { { container = image.id-00001.image, id = 263, scale = 2.5125, x,y = 1551,651 } }


Token changed and rescaled, continuing the loop: and now what happens up till error:


Runtime Notice: s'ATTENTION: tokenCT = ' | tokeninstance = { { container = image.id-00001.image, id = 263, scale = 6.432, x,y = 1551,651 } }
Runtime Notice: s'ATTENTION: shiftedUpdateEffectsHelper initiated'
Runtime Notice: s'ATTENTION: orgUpdateEffectsHelper initiated'
Runtime Notice: s'token Scale Set'
Runtime Notice: s'ATTENTION: setShiftedToken COMPLETED'
Runtime Notice: s'ATTENTION: setShiftedToken initiated'
Runtime Notice: s'ATTENTION: clearShiftedStats STARTED'
Runtime Notice: s'revert stats process'
Runtime Notice: s'ATTENTION: clearShiftedStats COMPLETED'
Runtime Notice: s'ATTENTION: clearShiftedStats initiated'
Runtime Notice: s'ATTENTION: clearShiftedToken STARTED'
Runtime Notice: s'begining clear shifted process'
Runtime Notice: s'clear shifted process User Host check'
Runtime Notice: s'token Scale revert'
Runtime Notice: s'ATTENTION: clearShiftedToken COMPLETED'
Runtime Notice: s'ATTENTION: clearShiftedToken initiated'
Script Error: [string "scripts/manager_token.lua"]:378: attempt to index local 'tokenCT' (a userdata value)


So after the token is changed...the loop runs 1 more complete time, and then has an error with tokenCT upon either completion, or while trying to continue the loop.

I originally used updateEffectsHelper while using bitmapWidget to display an image... I had no issue... but now I am swapping tokens...

Any advice or insight?

Moon Wizard
January 9th, 2019, 07:05
It's because you're changing the token in the middle of a bunch of code in the TokenManager, and replacing a single function. In this case, the tokenCT variable is passed into multiple functions, both "updateEffectsHelper" as well as "updateTooltip". Because you are replacing updateEffectsHelper and changing the token, then the token variable is invalid when it is subsequently passed to updateTooltip.

I think you should rethink your approach to this. Trying to insert a single override function and change information that's being referenced in the original global script will always be problematic, and will most likely break on updates.

If you are trying to trigger on "effects" being added/updated; then you need to use database handlers to capture the add/update/delete events. There are already a couple hooks in CombatManager that might be good enough for what you want. See setCustomAddCombatantEffectHandler/setCustomDeleteCombatantEffectHandler; which passes the nodeCT and the nodeEffect as two variables to your callback function you provide to the initial setCustom call. If you want to totally manage yourself, look at the addHandler calls at the top of CombatManager global script for an example of settings up your own monitoring.

Regards,
JPG

Diablobob
January 18th, 2019, 17:32
I know it has been a bit... I have been ill lately, hence the lack of messages... Thank you by the way!...

I can get the script to trigger on an effect added, but having issues having it parse the effect string... it is passing over that part of my script completely...



function onInit()
CombatManager.setCustomAddCombatantEffectHandler(s hiftedUpdateEffectsHelper);
CombatManager.setCustomDeleteCombatantEffectHandle r(shiftedUpdateEffectsHelper);
end




function shiftedUpdateEffectsHelper(nodeCT)
Debug.console("ATTENTION: onShiftEffectAdded initiated");
if not procShiftedActive then
procShiftedActive = true;
processShifted(nodeCT,true,true);
procShiftedActive = false;
end
end




function processShifted(nodeUnit,processStats,processToken)
local sTargetType, nodeTarget = ActorManager.getTypeAndNode(nodeUnit);
if sTargetType == "pc" or sTargetType == "ct" then
for _,nodeChild in pairs(DB.getChildren(nodeUnit, "effects")) do
local rEffect = EffectManager.getEffect(nodeChild);
if rEffect and (rEffect.sName or "") ~= "" then
if string.sub(rEffect.sName,1,8) == "Shifted;" then
if processStats then
setShiftedStats(sTargetType, nodeTarget, rEffect);
Debug.console("ATTENTION: setShiftedStats initiated");
setShiftedHP(sTargetType, nodeTarget, rEffect);
Debug.console("ATTENTION: setShiftedHP initiated");
end
if processToken then
setShiftedToken(sTargetType, nodeTarget, nodeUnit, rEffect);
Debug.console("ATTENTION: setShiftedToken initiated");
end
end
end
end
if processStats then
clearShiftedStats(sTargetType, nodeTarget);
Debug.console("ATTENTION: clearShiftedStats initiated");
end
if processToken then
clearShiftedToken(sTargetType, nodeTarget, nodeUnit);
Debug.console("ATTENTION: clearShiftedToken initiated");
end
-- end
end


The console readout is showing:


Runtime Notice: Reloading ruleset
Runtime Notice: s'ATTENTION: onShiftEffectAdded initiated'
Runtime Notice: s'ATTENTION: clearShiftedStats STARTED'
Runtime Notice: s'revert stats process'
Runtime Notice: s'ATTENTION: clearShiftedStats COMPLETED'
Runtime Notice: s'ATTENTION: clearShiftedStats initiated'
Runtime Notice: s'ATTENTION: clearShiftedToken STARTED'
Runtime Notice: s'begining clear shifted process'
Runtime Notice: s'clear shifted process User Host check'
Runtime Notice: s'token Scale revert'
Runtime Notice: s'ATTENTION: clearShiftedToken COMPLETED'
Runtime Notice: s'ATTENTION: clearShiftedToken initiated'



I'm confused why it's not reading the effect string. I'm pretty sure I'm just having another irritating syntax issue.

Any suggestions?

Diablobob
January 21st, 2019, 14:23
Still haven't been able to make progress... If I use an add handler, the function is triggered like it should... But the string isn't read...

Should I be using getString() function or something... It works with the override... Why not with the handler?

Please help! This is extremely frustrating!

Moon Wizard
January 23rd, 2019, 00:26
I looked closer at the CombatManager effect add/delete code; and I'm thinking that it may not work for your situation. It looks like it's not used with any of the other rulesets layered on CoreRPG; probably because the "add" event triggers before the label is set. It's the way that the client works (i.e. record is added, before any child values can be set).

Most likely, you are better off setting up your own effect handler processing code. Maybe something like this:


function onInit()
Interface.onDesktopInit = onDesktopInit;
end

function onDesktopInit()
DB.addHandler(DB.getPath(CombatManager.CT_COMBATAN T_PATH, "*.effects.*.label"), "onUpdate", onEffectLabelChanged);
DB.addHandler(DB.getPath(CombatManager.CT_COMBATAN T_PATH, "*.effects"), "onChildDeleted", onEffectDeleted);
end

function onEffectDeleted(nodeEffectList)
local nodeCT = DB.getChild(nodeEffectList, "..");
processShifted(nodeCT);
end

function onEffectLabelChanged(nodeField)
local nodeCT = DB.getChild(nodeField, "....");
processShifted(nodeCT);
end


I did this code off the top of my head; so you might want to use Debug.chat or Debug.console to make sure I got the nodeCT variable set up correctly.

Regards,
JPG

Diablobob
February 4th, 2019, 18:00
I got the token swap working... however the problem currently is that only the GM can initiate the token swap.. if the player tries, then there are errors "I'm assuming it's because token changes can only be done by the User.isHost"... The player isn't directly affecting the token, the script is triggering when the player applies an effect to themselves... but it looks like the script is assuming the player permissions, and not the GM...

Since the host is running the extension, is there a way to allow the script to assume the ishost permissions to change the token? or for the GM

damned
February 4th, 2019, 21:01
You will need to try and find some OOB messaging examples.
Your player needs to build the actions and then they need to be executed as the GM.
https://www.youtube.com/watch?v=zTNLJDMLpGk