PDA

View Full Version : Problem with setDieList()



BadElvis
September 12th, 2008, 17:47
Hi,

I plan to implement a system to roll a couple of dice and keep only the the best n dice. To do this, I would like to use draginfo.getDieList(), take out the lower dices and then update the table with draginfo.setDieList(...) according to https://fantasygrounds.com/refdoc/dragdata.xcp#setDieList.

Unfortunately, setDieList(...) does not work for me an I always get 0 as result for the roll in the chat window. Even if I simply load the list and store it again, all the data is gone and the result is 0: draginfo.setDieList(draginfo.getDieList());

Can anyone help with this problem? Thanks in advance.

Foen
September 13th, 2008, 06:54
I think you need to put your code in a handler for the onDiceLanded event in chat_chat.lua. Unfortunately I seem to recall that you cannot modify the draginfo dielist once the dice have landed, so you have to create the chat message yourself using the modifed dice and then return 'true' from the handler.

I think the code you need looks a bit like this:



entry.text = chattext; --[[ such as draginfo.getDescription() ]]
entry.font = "systemfont";
entry.dice = newDieList;
entry.diemodifier = diemodifier; --[[ such as draginfo.getNumberData() ]]

if User.isHost() then
if ChatManager.getDieRevealFlag() then
entry.dicesecret = false;
end
entry.sender = GmIdentityManager.getCurrent();
else
entry.sender = User.getIdentityLabel();
end

deliverMessage(entry);


Hope that helps

Stuart

BadElvis
September 13th, 2008, 09:33
Thanks very much for your response. This was, what I expected/observed. As soon as one tries to modify the DieList in any way, the result in the bubble becomes 0 (or nil?).

I will now try the workaround you suggested and use a chat message to display results. However, the option for the GM to show his roll (which is initially invisible) to everyone by dragging it into the chatbox cannot be implemented this way.

This is sad, I think I cannot create/modify the white dice bubbles manually, can I?

Foen
September 13th, 2008, 09:41
Using a chat message, a dice bubble is created for you :)

BadElvis
September 13th, 2008, 12:17
Thanks a lot for your help Foen. My solution is now:

Defining of custom dices for roll-and-keep in gameelements.xml:

<customdie name="k1">
<model>d10</model>
<menuicon>customdice</menuicon>
<script>
function explode(result)
if result==10 then
return 10 + explode(math.random(10));
else
return result;
end
end

function onValue(result)
return explode(result);
end
</script>
</customdie>

<customdie name="k2">
...
...

<customdie name="k3">
...
...


Handling the custom dices separately in chat_chat.lua. By the type of dice, I know how many dice to keep. I extract the results from the DieList, sort them and fill them into a new DieList. The new list is shown in the chat window.



...
elseif draginfo.isType("dice") then
local list = draginfo.getDieList();
local newlist = {};
local count = table.getn(list);
local p1, p2; -- start, end position of substr
p1, p2 = string.find(list[1]["type"], "k");
if p1 ~= nil then -- if we have a roll&keep dice here,
local keep = string.sub(list[1]["type"], p2+1, -1); -- calc, how much to keep
if tonumber(keep) > count then
return false; -- keep more than we roll... nonsense
end
local results = {};
local say = {};
if User.isHost() then -- set sender
if ChatManager.getDieRevealFlag() then
say.dicesecret = false;
end
say.sender = GmIdentityManager.getCurrent();
else
say.sender = User.getIdentityLabel();
end
say.font = "systemfont";

for i in pairs(list) do -- extract results from old list...
results[i] = list[i]["result"];
end
table.sort(results); -- ... so we can sort them
for i=1,keep do -- create new list
newlist[i] = {}; -- with the largest results of old list
newlist[i].result = results[count-i+1];
newlist[i].type = list[1].type;
end
say.dice = newlist;

if ModifierStack.getSum() > 0 then -- add modifier, if nesscessary
say.diemodifier = ModifierStack.getSum();
say.text = count .. "k" .. keep .. " + " .. ModifierStack.getSum();
elseif ModifierStack.getSum() < 0 then
say.diemodifier = ModifierStack.getSum();
say.text = count .. "k" .. keep .. " - " .. math.abs(ModifierStack.getSum());
else
say.text = count .. "k" .. keep;
end
deliverMessage(say);

return true; -- to avoid default output
end
applyModifierStackToRoll(draginfo); -- resets modifier
end
...


Like this, I can type the command /die 4k2+3 for example to roll four dices, keep the best 2 and add 3 as a modifier to the effective sum.

Foen
September 13th, 2008, 14:05
Looks like a neat solution, and the die names feel intuitive.

Bidmaron
September 13th, 2008, 22:12
But how do you specify the number of sides on the di(c)e?

zabulus
September 13th, 2008, 22:25
From the looks of it, you have to "know" which custom die is which

BadElvis
September 15th, 2008, 10:25
Legend of the Five Rings used only 10-sided dice for this purpose. Of course the coding of 10 different dices is not very elegant from a programmers point of view. But it is a very nice feature to simply write /die NkM to roll and not some more complicated custom command.

zabulus: I know which custom die is which. The die, used to keep the 3 best dice from a roll is called k3 for example. The dragdata delivered to the onDiceLanded event contains a list of dice names and dice results of all dice rolled. So by looking at the name (at the number behind k), I find out how many dice to keep.