PDA

View Full Version : Window argument not pointing to the right window



Tabulazero
July 22nd, 2019, 18:50
Hi everyone,

I have a special case. Let me explain a little bit. I have two characters (Bob the fighter and Bill the cleric) which each have their own character sheet generated from the same template. If you double-click on each character sheet, it opens up a dice roller window linked to the character where the player and the GM can secretly record ante (you bet D6) to modify the roll. Once the player or the GM has finished beting, he or she click on the check mark and if the other party has already done the same then it triggers a script which tally all the bets, roll them and modify the result accordingly.

When I run each dice roller window individually, it works perfectly well. However when I try to do it with multiple windows open, then the script gets triggered in the window I last opened by double-clicking on the character sheet.

I enclose the check mark script.



<buttoncontrol name="checkbutton_player">
<anchored width="30" height="85" >
<top parent="playerportrait" anchor="top" relation="relative" offset="0" />
<left parent="playerportrait" anchor="right" relation="relative" offset="15" />
</anchored>
<state icon="check_off" />
<state icon="check_on" />
<script>
function onInit()
self.setValue(0);
end

function onButtonPress()
local button_value=self.getValue();
local target = self.window;
if self.getValue()==1 and target.checkbutton_gm.getValue()==1 then
Debug.console("Player Name 1: ",target.name.getValue());
target.preClose();
end
end

</script>
</buttoncontrol>


For instance, if I click on this button in Bob the figher dice roller window, the preClose() function gets triggered on Bill the cleric dice roller window, assuming Bill the cleric is the last dice roller window I created. Looks like the window in self.window is pointing at the wrong window.

Any idea what is going on ?
28015

Trenloe
July 22nd, 2019, 19:10
I'd put some debug in the script to see exactly what's being returned.

Is each window completely self contained?

Also, is "preClose" a custom function you've written? I'd put debug in that as well - to see if it's the original self.window is incorrect, or the variables/code in preClose pointing to the wrong window.

celestian
July 22nd, 2019, 20:13
Interesting. Do you do anything with identities or something? Maybe if you could post some more of the code where you get values from?

Tabulazero
July 22nd, 2019, 21:15
I think I know what it is happening. It has not to do with the window argument. It has to do with:

Comm.throwDice("Pooldice", pooldice, 0, self.name.getValue().." throws Hero Dice");

basically all works well until the call to throw dices is implemented. When the call back is triggered, it switches to the last window opened which then triggers the rest of the script on the wrong window.

Which brings me to my next question:

in Comm.throwdice, is there a way to discriminate between players ? I am surprise there is not something like "playerid" in the original throwdice function.

Tabulazero
July 24th, 2019, 11:47
Could someone point me to the method to pass and retrieve an optional variable to throwDice, please ?


local sDragType = "dice";
local aDice = {"d20"};
local iModifier = 2;
local sDescription = "d20+2 Test"

Comm.throwDice(sDragType, aDice, iModifier, sDescription);

I do not understand the following from the function description:

customdata (any) [optional]
A custom value useful for e.g. storing special information about the roll required when the results are displayed (see dragdata.setCustomData).

For instance, if I have a the following variable local PlayerId= 00001; how am I meant to pass it to the throwDice ?

Comm.throwDice(sDragType, aDice, iModifier, sDescription).setCustomData(PalyerId) ?

Moon Wizard
July 24th, 2019, 15:12
There are 2 versions of that API function.

The first one takes 4 parameters plus one optional parameter; while the second accepts a single dragdata parameter. In the first version, a custom Lua object is the optional 5th parameter.
https://www.fantasygrounds.com/refdoc/Comm.xcp#throwDice

It would look more like:
Comm.throwDice(sDragType, aDice, iModifier, sDescription, PlayerId)

JPG

Tabulazero
July 25th, 2019, 11:25
There are 2 versions of that API function.

The first one takes 4 parameters plus one optional parameter; while the second accepts a single dragdata parameter. In the first version, a custom Lua object is the optional 5th parameter.
https://www.fantasygrounds.com/refdoc/Comm.xcp#throwDice

It would look more like:
Comm.throwDice(sDragType, aDice, iModifier, sDescription, PlayerId)

JPG

Thank you very much. I do I get to retrieve the custom Lua object from the roll result ?

rRoll.PlayerId ?

Trenloe
July 25th, 2019, 13:43
I’d recommend having a look at this thread: https://www.fantasygrounds.com/forums/showthread.php?35531-Fantasy-Grounds-v3-X-CoreRPG-based-Actions-(dice-rolling). It gives a lot of information regarding the whole process of rolling dice and processing the result.

Assuming you’re wanting to get the information regarding the PC that through the dice - look at step 5 in post #2. This gives information regarding the onRoll handler that processes the result of the dice roll! This contains the resource LUA table, which has details of the PC that initiated the action.

Tabulazero
July 25th, 2019, 20:57
Thanks but I still do not get how your are meant to extract an optional variable from the Throwdice function despite having read the link you sent me

I have tried Moon Wizard's suggestion and it works. However, I a still stuck to extracet the PlayerId from the rRoll. I have tried with multiple debug consol and it does not work. Please find below the functions I am using:



function onInit()
local id = DB.getPath(self.getDatabaseNode());
Debug.console(" id1: ",id);
ActionsManager.registerResultHandler("Rolld20", Rolld20);
Comm.throwDice("Rolld20", {"d20","d20"}, 0, self.name.getValue().." throws a d20",id);
end



function Rolld20(rSource, rTarget, rRoll)
DB.setValue(DB.getPath(self.getDatabaseNode())..".Firstd20","string",rRoll.aDice[1]["result"]);
DB.setValue(DB.getPath(self.getDatabaseNode())..".Secondd20","string",rRoll.aDice[2]["result"]);
local id = rRoll.id;
Debug.console(" id2: ", id);
local rMessage = ActionsManager.createActionMessage(nil, rRoll);
Comm.deliverChatMessage(rMessage);
end

What am I doing wrong and how on earth can I get back rSource and rTarget from a simple roll ?

Trenloe
July 25th, 2019, 21:11
Thanks but I still do not get how your are meant to extract an optional variable from the Throwdice function despite having read the link you sent me

I have tried Moon Wizard's suggestion and it works. However, I a still stuck to extracet the PlayerId from the rRoll.
The advantage of following the standard I outlined in the thread I posted is that you can take advantage of the CoreRPG helper functions. Hence why I mentioned rActor - which has all the details about the actor (the character that rolled the dice as part of the action), and various pieces of information can be returned from rActor using the ActorManager package functions detailed in CoreRPG scripts\manager_actor.lua - such as ActorManager.getCreatureNode(rActor) will return the database node of the character that rolled the action, e.g. a database node pointing to charsheet.xxxxx - this is essentially the database node of the PC ID, which I believe is what you're looking for?

It may seem like a lot of work to setup all the code for the action steps that are detailed in the the action thread I linked, but it is well worth (in my opinion) doing it this way as it will give you access to all the helper functions - getting PC/NPC info, getting details from the Combat Tracker, getting PC portraits and displaying them in the chat, etc..

Trenloe
July 25th, 2019, 21:14
What am I doing wrong and how on earth can I get back rSource and rTarget from a simple roll ?
You need to set them before making the roll - see post #3 of the action thread. The final code block in that post gives an example of how to to do this.

Moon Wizard
July 26th, 2019, 03:59
If you are using the raw APIs instead of the CoreRPG roll handler, then you will need to extract the custom data yourself from the dragdata parameter returned in the chat window.onDiceLanded callback by modifying the chat window control.

If you want to take advantage of the abstractions available in CoreRPG (rActor/rRoll/rSource/rTarget tables), then you’ll need to follow examples that Trenloe pointed out.

Regards,
JPG

Tabulazero
July 27th, 2019, 10:22
I have rewritten the code as per Trenloe’s method and it works.

However the problem has not disappeared.

When I open simultaneously multiple dice roller window, each linked to an individual character, the onRoll function which handle the roll result only gets triggered on the last window I opened.

How does FG handle multiple players rolling dices simultaneously ?

How does FG handle the GM doing multiple rolls simultaneously ?

damned
July 27th, 2019, 11:05
I have rewritten the code as per Trenloe’s method and it works.

However the problem has not disappeared.

When I open simultaneously multiple dice roller window, each linked to an individual character, the onRoll function which handle the roll result only gets triggered on the last window I opened.

How does FG handle multiple players rolling dices simultaneously ?

How does FG handle the GM doing multiple rolls simultaneously ?

Use more Debug statements...
Insert Debug statements liberally and watch what is being reported and when.

Trenloe
July 27th, 2019, 15:31
However the problem has not disappeared.

When I open simultaneously multiple dice roller window, each linked to an individual character, the onRoll function which handle the roll result only gets triggered on the last window I opened.
Ah, OK, I think I understand what the issue is now.

I believe this is the way it works - you only get one result event triggered when an action (roll) is executed, and that is on the FG instance where the roll was made. The last event handler registration is used to handle the result of the roll. Hence why you're seeing the result trigger on the last window that was opened, as this is the last registered event handler.

You could use code in that event handler to pass information/trigger other actions - but you'd probably have to do that via OOB messaging.


How does FG handle multiple players rolling dices simultaneously ?

How does FG handle the GM doing multiple rolls simultaneously ?

I'd recommend you look at the party sheet in one of the D&D rulesets. This has functionality on the main tab to roll checks for all of the PCs in the party sheet. This might give you some ideas as to how to do multiple rolls at once. But, for the party sheet, the GM instance makes all the rolls, but you can specify that the results are shown to the players - maybe this might be a good way to go?

Taking a step back... What I think you're trying to do is a process where rolls are made on each FG instance where there is a PC involved - with betting, etc.. The rolls are initiated once all of the PCs have completed their bets. Then the results of the rolls are tallied based off the bets made and a final result displayed?

This is quite a complex process. There are asynchronous actions happening on one or more FG instances, and it could get even more complex if a player is controlling 2 PCs on the same FG instance who are involved with the betting game.

You're going to have to use a mixture of database entries (I'm guessing you're doing this already?), event handlers (probably tied to the database entries) and OOB messaging to pass program control from the player instance to the GM and back to the player side. Like I say, this is a pretty complex operation.

Moon Wizard
July 27th, 2019, 19:59
There is no inherent knowledge of which character made a roll, because a GM can roll for any record (PC/NPC/etc.), and players can run more than one character and we’ll as roll for shared NPCs.

If you want to link a roll to a record, you have to pass that information with the roll. This is what the CoreRPG helper scripts are doing to pass rSource/rTarget, and other information with a roll.

My guess is that your window is either using the same data source (and only one window of a given class and data source can exist at one time); or that something in your window is remembering something outside the scripts for the window (either database or global script) that is getting overwritten/confused when you open two.

As the others mentioned, your best bet is to add Debug.chat statements to output the values of parameters and other variables on your scripts that make the rolls in order to determine which ones aren’t correct, and then work back from there to figure out why they are not correct.

Remember that you can use the /reload command while in a campaign to reload any ruleset/extension code.

Regards,
JPG