PDA

View Full Version : Lock Tokens



Kelrugem
November 4th, 2020, 02:55
Hi :)

I have some extension where one can create a height widget when using the mouse wheel and some hotkey while hovering over a token. I just found out that this might not completely work for the clients when Lock Tokens is activated (in both, FGC and FGU), probably due to different permissions over the token.

Is the code somewhere visible for Lock Tokens in CoreRPG? I would like to see how the ownership is affect by that. But I understand when that is not open API, then I somehow try to force the ownership of the height widget for all clients, or maybe some OOB message to create it :)

Best wishes,

Kelrugem

Moon Wizard
November 4th, 2020, 03:46
The state of token locking should not impact whether scripts are getting called. What combination of actions are you trying to perform which are affected by token locking?

Regards,
JPG

Kelrugem
November 4th, 2020, 17:45
Hi :)

Oki, the idea is the following: I want to create some widget over a token depicting the height; that is done via ALT+Wheel while hovering over the token :)

Hence, I replace the onWheel function with



function onInit()
Token.onWheel = onWheel;
end


But, especially for the client, I need to give the clients ownership for doing so, and there seems to be the problem when Lock Token is activated. I use addHolder to do that but I need to run that on the Host side (respecting identity and char sheet ownership and stuff like this). Hence, I need to trigger the addHolder-code for all tokens at the "beginning" on the host side such that the clients can create their height widget for their token(s); that function I called setupToken, that will create the (empty) height widget and does the addHolder stuff. This function, setupToken, is triggered in updateAttributesHelper of the TokenManager by



HeightManager.setupToken(tokenCT);


So, I just trigger this code with the addHolder stuff and so on (and the HeightManager is just the file with all these functions I need for that) :) The function setupToken is essentially that:



function setupToken(token)
local ct = CombatManager.getCTFromToken(token);
if ct then
local wToken, hToken = token.getSize();
height = getCTHeight(token);
wdg = token.addTextWidget("height",height .. measure);
if wdg then
if height == 0 then
wdg.setVisible(false);
else
wdg.setVisible(true);
end
wdg.setName("height_text");
wdg.setPosition("top",0,8);
wdg.setFrame('tempmodmini',10,7,10,4);
wdg.setColor('00000000');
wdg.bringToFront();
-- make CT height field if it doesn't exist;
local heightNode = ct.createChild("height","number");
if User.isHost() then
addHolders(token);
end
end
end
end


So, it basically just adds the widget (also used in other parts of the code) and the addHolders there is the important thing, because this function checks the identity stuff etc.:



function addHolders(token)
local ct = CombatManager.getCTFromToken(token);
local heightNode,charSheets,owner,iden,cl,cn;

if ct then
heightNode = ct.createChild("height","number");
if heightNode and User.isHost() then
-- get datasource, try to find the charsheet
-- if there's a charsheet, then get the list of users
-- find all identities own by each user, if an identity owned by a user
-- is equal to the name field on the ct, then make that user a holder
if ct.getChild('link').getValue() == 'charsheet'then
iden = ct.getChild('name').getValue();

-- try iterating through char sheets
charSheets = DB.findNode('charsheet');
if charSheets then
cl = charSheets.getChildren();
for k,v in pairs(cl) do
cn = v.getChild('name');
if cn then
cn = cn.getValue();
if cn == iden then
owner = v.getOwner();
break;
end
end
end
if owner then
heightNode.addHolder(owner,true);
end
end
end
end
end
end


I think these are the essential steps I am doing; I am not sure though why the Lock Token thing affects the ability of the clients to create the widget :) Thanks a lot for your time :)

Best,

Kelrugem

Moon Wizard
November 4th, 2020, 18:16
Can you provide your "onWheel" function?

JPG

Kelrugem
November 4th, 2020, 20:07
Yes, sure :)



function onWheel(target, notches)
if Input.isAltPressed() then
if not hasHeightWidget(target) then
createHeightWidget(target);
else
if notches > 0 then
doIncreaseHeight(notches,target);
else
doDecreaseHeight(notches,target);
end
end
elseif Input.isShiftPressed() then
local vImage = ImageManager.getImageControl(target, true);
local OrientationCount = vImage.getTokenOrientationCount();
target.setOrientation((target.getOrientation()+not ches)%OrientationCount);
elseif Input.isControlPressed() then
local scale = target.getScale();
if UtilityManager.isClientFGU() then
local adj = notches * 0.1;
if adj < 0 then
scale = scale * (1 + adj);
else
scale = scale * (1 / (1 - adj));
end
else
if Input.isShiftPressed() then
scale = math.floor(scale + notches);
if scale < 1 then
scale = 1;
end
else
scale = scale + (notches * 0.1);
if scale < 0.1 then
scale = 0.1;
end
end
end
target.setScale(scale);
end

return true;
end


The first part of the if-clause is for the height widget while the other two parts are then about facing and scaling :) The first part of the if-clause first checks whether there is already a height widget



function hasHeightWidget(token)
local w;
if token then
w = token.findWidget("height_text");
end

return w;
end


and createHeightWidget is precisely the same as the setupToken from my last post, so, creating the widget and adding holders :) (actually, setupToken also checks first whether there is already a height widget; I just omitted that in the last post). If there is already a height widget then the number is changed, the increase function is as follows (decrease is of course similar; I could basically merge them, since they are the same because notches comes already with a sign):



function doIncreaseHeight(inc,token)
local w = hasHeightWidget(token);
local height = getCTHeight(token);
local txtHeight = "";
Incrementsize = GameSystem.getDistanceUnitsPerGrid();
height = height+(inc*Incrementsize);
setCTHeight(height,token);
end


The number of the height is saved in the CT entry, so, that is what getCTHeight and setCTHeight are about:



function getCTHeight(token)
local ct = CombatManager.getCTFromToken(token);

if ct then
heightNode = ct.createChild("height","number");
if heightNode then
local height = tonumber(heightNode.getValue());
return height;
end
end

return 0;
end




function setCTHeight(height,token)
local ct = CombatManager.getCTFromToken(token);

if ct then
heightNode = ct.createChild("height","number");
if heightNode then
heightNode.setValue(height);
end
end

end


:)

Moon Wizard
November 4th, 2020, 21:11
I just loaded up your "Height.ext" in the latest build of FGU; and it appears to be working fine with all 3 modifier keys. This is true regardless of whether I'm player or GM, or whether token locking is enabled.

I might suggest that you change the modifier keys to match the default FGU behaviors (Shift = orientation, Control = resize); which would put the height modification on Alt key.

Also, you might be able to simplify the onWheel handler behavior to the function below. This would have the added benefit of using the existing behaviors in FGC and FGU.


function onInit()
Token.onWheel = onWheel;
end
function onWheel(target, notches)
if Input.isAltPressed() then
if not hasHeightWidget(target) then
createHeightWidget(target);
else
if notches > 0 then
doIncreaseHeight(notches,target);
else
doDecreaseHeight(notches,target);
end
end
return true;
end
end
...


And finally, you can move the height.lua chat message registration code into an announcement tag to remove one more script.

Regards,
JPG

Moon Wizard
November 4th, 2020, 21:13
Also, you shouldn't need to use addHolders for CT, since the entire "combattracker" node and all children are marked as public by CoreRPG by default.

Regards,
JPG

Kelrugem
November 4th, 2020, 22:01
Oh, wow, cool, thanks for looking at that :) Yeah, the code is originally from Ken L and I quickly stripped his height extension; certainly the code needs some clean-up :)

I just tested again, because I was certainly sure that it didn't work for me, also due to some reports of others: The client cannot create the height widget under certain situations, but I was wrong in assuming that it is due to Lock Tokens. It is seemingly an edge case into which I ran, after I created a height widget as GM then it worked also on the client side. So, I tested a bit more, and the following I needed to do (in FGU):

1. Start campaign, add token to a shared map as GM. Then close campaign
2. Start Campaign again. Do not do anything else
3. Join yourself as player
4. Try to create the height widget, it won't work.
5. Turning on/off lock tokens and/or create height widget as GM solves this issue. Or maybe just moving the token as GM (the latter I did not test yet)

So, it looks like a problem when the token (without height widget seemingly) is already added to a map when starting the campaign. When then the player joins, it won't work immediately :) So, I accidentally ran into an edge case seemingly when I tested this. I then tried to turn on/off the Lock token which then solved this problem, which was why I thought that it was due to Lock Tokens. If you want to test that, I added the actual version of my extension here (the one of the forums has an outdated tokenmanager)

Thanks for the suggestions, I clean that up a bit now, maybe then this edge case is also solved then :)

Kelrugem
November 5th, 2020, 02:30
Oki, following the steps to reproduce it, I now checked the console and got the following warning:



[WARNING] setValue: Database node not owned (combattracker.list.id-00001.height)


I will let you know when I find a solution for the edge code :) When I erase the holder stuff, then I always get this warning, even when I tried my workarounds. So, I probably just need to add one more addholder update somewhere :) (or indeed just switch to OOB which may lead to some delay though, not sure :) )

Moon Wizard
November 5th, 2020, 03:02
The CT nodes are never owned by players. They are just shared. Therefore, you will always get an error trying to set a value unless ownership is changed.

Unless you want to have a really complex system trying to change ownership of nodes based on who is trying; it might be best to use OOB to ask GM host to adjust. Plus, you can handle "party movement and vision" option to prevent players from changing based on that option and/or their ownership of the PC.

Regards,
JPG

Kelrugem
November 5th, 2020, 03:18
The CT nodes are never owned by players. They are just shared. Therefore, you will always get an error trying to set a value unless ownership is changed.

Unless you want to have a really complex system trying to change ownership of nodes based on who is trying; it might be best to use OOB to ask GM host to adjust. Plus, you can handle "party movement and vision" option to prevent players from changing based on that option and/or their ownership of the PC.

Regards,
JPG

Ah, I understand, I try that :) Thanks for the suggestions and great help :)

Kelrugem
November 5th, 2020, 21:09
Just for completeness: I was able to keep the ownership stuff, I just added a little bit more updating of the ownership (like after the change of ownership or after deletion etc.), especially the ownership is now also configured when the GM opens the map; that solved my edge case above :) Thanks a lot for the help :)