PDA

View Full Version : turnwidget



Hamish
October 31st, 2007, 22:22
I was looking through characterlist_entry.lua to see if I could do something with it, and I found this interesting piece of script:



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


It's purpose seems to be to add a little flag to the character's portrait if it's his/her turn in the combat tracker, but I have never seen it working, so it would seem that it's not implemented elsewhere in the ruleset.
Am I right, or does this little piece of script have a function after all?

Hamish
November 2nd, 2007, 11:10
I've been playing around with the widgets, and I noticed that if I create a new widget on the character portraits, and change the text on the host side, this does not show up on the client side. This surprised me, as the name under the character's portrait is also a widget, and that does change if changed on the character sheet. Anyone have any idea how to set it up so any change to the widget on the host will be propagated to the clients?

Dachannien
November 2nd, 2007, 15:00
The character name widget has some additional support code that works through the user state handler (User.onUserStateChange) using some partially undocumented functionality.

You could probably get something similar to work using database fields and onUpdate events.

Hamish
November 2nd, 2007, 21:45
Thanks for the reply Dachannien!

When you say partially undocumented, exactly how undocumented are we talking about? As in "You won't find it anywhere in the xml or lua files but this function actually changes the namewidget's text on the host and the client"?

I can only find 2 references to User.onUserStateChange. The first is in characterlist.lua, which controls the status widgets on the players portraits, but I don't see a reference to the namewidget. The other one is in desktop_classes.xml, that one controls the speech bubble in the chat windows when you are typing.

So either it is part of the game engine and not controlled by the script files, or I'm just not seeing it, or it is somewhere else in the code.

Dachannien
November 3rd, 2007, 02:29
By "partially undocumented", I mean that the documentation here on the FG website for User.onUserStateChange fails to mention that "label" is one of the valid state types, and that a string containing the new label for the user (i.e., their character's name) will be passed as the new state when the state type is "label". It's essentially the same way that User.onIdentityStateChange works, which is fully documented, except that function passes different parameters to you.

The actual way that this functionality works is mostly exposed in the ruleset scripts. The User.onUserStateChange handler is registered within characterlist.lua, and that function calls another function in characterlistentry.lua which determines what kind of state information is being passed and sets the widgets accordingly. There's another spot in the code where the database field containing the character's name is set up as providing the text for this, but I don't have the code handy right this second to tell you where it is specifically. (If I remember later, I'll try to find it again.)

AFAIK, the User.onUserStateChange handler will only work with one specific label field, meaning that if you try to use it for your own purposes, you'll have to break the functionality that lets the character name widget change when the player changes the character's name on their character sheet.

Hamish
November 4th, 2007, 12:53
If you can show me how the name updates work, I'm sure I can figure out how to update another widget. I've looked around quite a bit, but I can't find the code for the name updates anywhere.

Dachannien
November 5th, 2007, 17:03
Some of this stuff isn't well or properly documented, but I think this is how it works:

When you open up the character selection window as a player, you're given a list of characters you can select. When you double click one of them to select it, the onDoubleClick function in identityselection_entry_base.lua is called. In there, the User.requestIdentity function is called, and it passes to FG the name of the field to use as the identity label (the third parameter passed is the string "name", which is the same as the field in the character's database node that contains the character's name).

From then on, whenever that particular field is changed, it causes the User.onIdentityStateChange handler to fire, which is set up when the character list is set up in characterlist.lua. (User.onUserStateChange is also given a handler function here as well. I was in error when I said above that onUserStateChange is improperly documented - I was speeding through the code and didn't notice that both handlers wind up in the same place eventually.)

The handler function that is hooked to User.onIdentityStateChange takes care of changing the widget label.

The big whammy here is that this process goes through the User.requestIdentity function, which (a) isn't documented correctly, at least not like it's used in the ruleset code, and (b) only provides an interface for notification of one label field, which is already used by the character name.

In other words, understanding this part of the code probably won't be all that helpful in trying to figure out what you want to do. You'd have to get the database node corresponding to your extra text for each character, you'd have to have each client become a holder of that database node, and you'd have to register an onUpdate handler for each entry in the character list. This is made more complicated by the fact that this is a desktop panel without its own database node - the reason that the User module is used in the first place is to get around these difficulties by having it receive notification from the server.

Another way to handle it would be to use the ChatManager to send a text message to the clients from the server whenever the label field changes (registering the onUpdate handler on the server, of course, where the server is automatically a holder of the whole database), forming those messages in a special way so that they are intercepted and processed, so that they cause the widget labels to change instead of sending them to the chat window.

Hamish
November 5th, 2007, 18:30
Thanks for the complete and clear explanation Dachannien, I understand the process, I see how User.requestIdentity is not properly documented and I see the problems you describe at the end. I think I'll go with your suggestion and try to implement it using the chat box.

Hamish
November 5th, 2007, 21:16
I'm just being stubborn here, I know, but I seem so close to a solution. All I need now is a way to reference the characterlist. I tried:

Interface.findWindow("characterlist","")
But this returns nil. I tried using 'super', since I'm trying to reference it from a function bound to a characterlist_entry, but 'super' is unknown. Strange.... I thought that should work.
Any thoughts on that one?

Dachannien
November 6th, 2007, 08:29
I vaguely recall another thread around here where someone was having similar trouble, because they wanted to access a desktop panel and weren't able to figure out what to specify in the second parameter to findWindow to make it work. (It isn't bound to the database, so "" seems reasonable, but for whatever reason it doesn't work.)

One possible way to solve this problem might be to put the code in question inside the script for the characterlist, and set up an event handler there too, to trigger the code.

Hamish
November 6th, 2007, 09:55
Thanks Dachannien, that solves that problem! Simple solution if you think about it. :)
I'll need to check, double check and clean up my code and then I'll post it in the other topic I started about this.

https://www.fantasygrounds.com/forums/showthread.php?t=7468

In the meantime, I still need to figure out how to set permissions on the database node I created to hold the value for my widget. Can you tell me if the onIdentityActivation event is fired on the host as well as on the client when a players activates an identity?