PDA

View Full Version : How does portrait link name to char sheet?



unimatrixzero
March 17th, 2008, 03:37
Hi All
Time for me to have another go at creating a ruleset! :)
Can anyone help me out with the following?
I'm looking to add some extra info to the portrait icons that display above the chat box. for example, besides the character name i'm looking to display character's age or current level. i know the code takes the character name straight from the character sheet but i don't know what code links the two together. In the characterlist.entry.lua there is a nameWidget but i don't see how this 'connects' to the character sheet.
Anyhelp on this would be appreciated.
Regards
Uni

Hamish
March 17th, 2008, 08:28
Check out this thread (https://www.fantasygrounds.com/forums/showthread.php?t=7511). I use widgets to display the character's initiative, but the idea is the same.

unimatrixzero
March 18th, 2008, 09:08
Thanks for the link.
I'm still uncertain as to which bit of code i need to focus on. As i'm not using anything to do with the combat tracker i am just using bits from the characterlist scripts. I had previously figured out that i could use a widget and so have added one. The trouble is it references the characters name and cant figure out how it does it. If i could understand how it does it then i can get a better grasp of how it all works. Any takers on helping me out here?
Regards
Lee

taken from characterlistentry.lua with my additions in bold.

function createWidgets(name)
identityname = name;

portraitwidget = addBitmapWidget("portrait_" .. name .. "_charlist");

namewidget = addTextWidget("sheetlabelsmall", "- Unnamed -");
namewidget.setPosition("center", 0, 27);
namewidget.setFrame("mini_name", 5, 2, 5, 2);
namewidget.setMaxWidth(75);

agewidget = addTextWidget("sheetlabelsmall", "- scl-");
agewidget.setPosition("center", 25, -6);
agewidget.setFrame("mini_name", 5, 2, 5, 2);
agewidget.setMaxWidth(15);

turnwidget = addBitmapWidget("indicator_flag");
turnwidget.setPosition("center", 30, -20);
turnwidget.setVisible(false);

typingwidget = addBitmapWidget("indicator_typing");
typingwidget.setPosition("center", -23, -23);
typingwidget.setVisible(false);
idlingwidget = addBitmapWidget("indicator_idling");
idlingwidget.setPosition("center", -23, -23);
idlingwidget.setVisible(false);

colorwidget = addBitmapWidget("indicator_pointer");
colorwidget.setPosition("center", 31, 16);
colorwidget.setVisible(false);

resetMenuItems();
if User.isHost() then
registerMenuItem("Ring Bell", "bell", 5);
else
if User.isOwnedIdentity(name) then
registerMenuItem("Activate", "turn", 5);
registerMenuItem("Release", "erase", 4);
end
end
end

function stateChange(statename, state)
if statename == "current" then
if state then
namewidget.setFont("sheetlabelsmallbold");
else
namewidget.setFont("sheetlabelsmall");
end
end

if statename == "label" then
if state ~= "" then
namewidget.setText(state);
else
namewidget.setText("- Unnamed - ");
end
end

if statename == "label" then
if state ~= "" then
agewidget.setText(state);
else
agewidget.setText("- Unnamed - ");
end
end

Hamish
March 18th, 2008, 20:14
The link between the name on the widget and the character sheet is through the stateChange function, so you were right to try something with that. What you've done with it is not correct though.

What I do in my modification is a different approach. I add new nodes to the database to hold the value I want to store, set up handlers that watch these nodes and when the node changes value they adjust the value on the widget accordingly. A lot of the magic is in the onIdentityActivation function.

To add nodes to the database, I use the following code:


DB.createNode("charsheet." .. identity .. ".init.value", "number");
DB.createNode("charsheet." .. identity .. ".init.turn", "number");


To add a handler for this node, I use the following code:


DB.findNode("charsheet." .. identity .. ".init.value").onUpdate = initUpdate;
DB.findNode("charsheet." .. identity .. ".init.turn").onUpdate = turnUpdate;


The functions initUpdate and turnUpdate handle the actual changing of the widgets. One changes the value of the initiative widget, the other controls the visibility of the turn indicator flag.

There is one additional problem with what you (and I) are trying to do. By default, one player cannot see into the database node of a character owned by another player. To tackle this, you have to add all players to the 'watchers' list of the approprate database nodes. To do this, I added the following code:


tPCs = DB.findNode("charsheet").getChildren();
for name, oPC in pairs(tPCs) do
if User.isHost() then
DB.findNode("charsheet." .. identity .. ".init").addHolder(oPC.getOwner(), false);
if oPC.getChild("init") then
oPC.getChild("init").addHolder(username, false);
end
end
end

Basically, what this does is loop through all existing charactersheet database nodes, adds the owner of that player to the 'watchers' list of the nodes in the sheet of the character logging on, and adds the owner of the character logging on to the 'watchers' list of all nodes in existing character sheets.

Hope this helps!

meathome
May 17th, 2010, 00:55
I was trying to do something similar. I used the code you posted and modified it a bit. I add the other players on the character sheet nodes of each character, (they are set for all sub nodes and this appears correctly in the database)

So the holder data is ok for all nodes I try to access. But regardless of this I get lots of tried to index a nil value errors. I will mark the lines in the code:



function layoutControls()
local identitylist = {};

for key, val in pairs(User.getAllActiveIdentities()) do
table.insert(identitylist, { name = val, control =findControlForIdentity(val) });
end

table.sort(identitylist, controlSortCmp);

local n = 0;
for key, val in pairs(identitylist) do
val.control.sendToBack(); <----------It happens here
end

anchor.sendToBack();
end

function onIdentityActivation(identity, username, activated)
if activated then
do

DB.createNode("charsheet." .. identity .. ".wounds.current", "number");
DB.createNode("charsheet." .. identity .. ".wounds.max", "number");
DB.createNode("charsheet." .. identity .. ".wounds.fatiguecurrent", "number");
DB.createNode("charsheet." .. identity .. ".wounds.fatiguemax", "number");

tPCs = DB.findNode("charsheet").getChildren(); <--------------And Here
for name, oPC in pairs(tPCs) do
if User.isHost() then
DB.findNode("charsheet." .. identity).addHolder(oPC.getOwner(), false);
oPC.addHolder(username, false);
end
end

if not findControlForIdentity(identity) then
createControl("characterlist_entry", "ctrl_" .. identity);

userctrl = findControlForIdentity(identity);
userctrl.createWidgets(identity);

layoutControls();
end

DB.findNode("charsheet." .. identity .. ".wounds.current", "number").onUpdate = woundsUpdate; <------------------ And lastly here
DB.findNode("charsheet." .. identity .. ".wounds.max", "number").onUpdate = woundsUpdate;
DB.findNode("charsheet." .. identity .. ".wounds.fatiguecurrent", "number").onUpdate = fatigueUpdate;
DB.findNode("charsheet." .. identity .. ".wounds.fatiguemax", "number").onUpdate = fatigueUpdate;

woundsUpdate(DB.findNode("charsheet." .. identity .. ".wounds.current"));
woundsUpdate(DB.findNode("charsheet." .. identity .. ".wounds.max"));
fatigueUpdate(DB.findNode("charsheet." .. identity .. ".wounds.fatiguecurrent"));
fatigueUpdate(DB.findNode("charsheet." .. identity .. ".wounds.fatiguemax"));

end
else
findControlForIdentity(identity).destroy();
layoutControls();
end
end


I checked the corresponding database nodes for each entry and they do xist and get all palyers as holders.. I get the nil index error regardless of what I do.... Im ready to bang my head into a wall.

Im totally stuck and need help (again)

Edit: I changed it around a bit, it seems that the createDatabaseNode calls fail on the other (non owner) clients and return nil. I included a check for this...

It happens with newly created characters on the clients that are not the creators of the character.
The values show up fine on the host and the creating client.
After the owning client relinquishes the identity once and then reactivates it everything works.
So it seems theres a problem with either commiting changes to the database or the order entries in the characterlist are processed.