PDA

View Full Version : Custom die question



Belizan
July 22nd, 2007, 08:35
So, I've been looking at making an L5R ruleset. For those not familiar, L5R involves a system where in you roll a bunch of d10, where each d10 has the possibility (potentially) to "explode" or open end up on a 10. The total of each die is important, however, because at the end of the roll, you pick so many of the highest of the dice you rolled. This is called x keep y. As in, roll 5 keep 3, abbreviated #k#, or xky and 5k3 to follow the previous examples.

Therein, Joshuha has a code sample that implements exploding dice of a kind...



local dicetable = {};
-- dicetable = draginfo.getDieList();

-- local size = table.maxn(dicetable)
-- for i= 1,size do
-- if (dicetable[i].type == "d10" and dicetable[i].result == 10) then
-- local explodetable = {};
-- table.insert(explodetable, "d10");
-- throwDice("dice", explodetable, 0, "Exploded");
-- end
-- end

But, I don't think this will work very well, because it will roll the extra d10, but they will be orphaned from the die which "sponsored" the extra die roll in the first place. Or something like this--
3D10: 10, 5, 10, 4, 10, 2.
Or actually more like...
3D10: 10, 5, 10
Exploded: 4
Exploded: 10
Exploded: 2

Instead, I'm looking for something that will produce results more like--
3D10: 10+4, 5, 10+10+2.

Which makes room for later more saavy implementation to automatically manage the "keep" part, etc. (There are other roll mechanics as well, but if I can solve this problem, the others should be no trouble).

I had been thinking to do this via a CustomDie type with something like...



<customdie name="Exploding d10">
<model>d10</model>
<menuicon>customdice</menuicon>
<script>
function onValue(result)
if result == 10 then
local dice = {};
table.insert(dice, "Exploding d10");
result += throwDice("dice", dice, 0, "Exploding");
return result;
end
</script>
</customdie>

Only.. this has lots of problems :)...
throwDice doesn't return a value
I'm not sure I can pass in custom die types that way
It looks as though it's going to asynchronously roll another die on the window triggering a separate chat entry. Which is to say, in other words, it's not going to help at all :(.

I've really just begun starting to wade into the ruleset files, but this is the key first step for me, and I was hoping someone might have some advice on how I could get this working?

Foen
July 22nd, 2007, 10:26
If you don't need to keep track of how many extra tens, you could change your customdie as follows:



<customdie name="x10">
<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>


A result from 3x10 might be:
14, 5, 22 (from your previous example)

Note that using x10 as the die name allows you to use 3x10 in the chat window (/die 3x10).

Hope that helps

Stuart
(Foen)

joshuha
July 23rd, 2007, 00:44
Ok first about throwDice. This just calls a function that the same as graphically rolling a dice and will actually trigger the dieroll graphic on the screen. If you want everything to be concatenated into one roll for each exploding set its easy to do if you don't want the fancy graphics.

You can easily construct your own message and take the original results from the d10, stop the normal processing, call math.random for every 10, and then format those results however you want. Its effective if not as pretty and I had some posts on how to do this on the beta forums before they were wiped. Would be happy to help you out on that but from what you have done so far you seem to have an OK handle on the code.

Belizan
July 23rd, 2007, 02:06
Yeah, I get what Foen is suggesting. I have to admit I never even considered using the built-in LUA lib for generating random numbers. How good is its random number generator anyway?

As an asside, while I want to have only one entryMessage in the chatwindow, ergonomically speaking, it would be nice to still trigger a roll. I suppose I could.. hrmm.. I could cheat I guess... And do something like (in onDiceLanded, modulo DB concurrency/semaphores and some serious assumptions about how tables work in LUA ;)...



if draginfo.isType("dice") then
dicetable = draginfo.getDieList();
local size = table.maxn(dicetable)
for i= 1,size do
if (dicetable[i].type == "x10" and dicetable[i].result == 10) then
local newtable = { result = i; type = "explode"};
newtable = dicetable.concat(newtable);
createNode("explodeVals", newtable);
local dice = { "x10" };
throwDice("explode", dice, 0, draginfo.getStringData());
return true;
end
end
elseif draginfo.isType("explode") then
local dicetable = draginfo.getDieList();
local cachevals = findNode("explodeVals");
local size = table.maxn(cachevals);
local start = cachevals[size].result;
cachevals[start].result += dicetable[1].result;
for i= start+1,size-1 do
if (cachevals[i].type == "x10" and cachevals[i].result == 10) then
cachevals[size].result = i;
createNode("explodeVals", cachevals);
local dice = { "x10" };
throwDice("explode", dice, 0, draginfo.getStringData());
return true;
end
end
end


And cachevals could be converted to store strings instead if you wanted to make a pretty entry with 10+10+4 type output instead of 24, I think.

Then again, I don't know much about this infrastructure. Would that work?

Belizan
July 23rd, 2007, 02:25
Er, sorry...


cachevals[start].result += dicetable[1].result;
if dicetable[1].result == 10 then
createNode("explodeVals", cachevals);
local dice = { "x10" };
throwDice("explode", dice, 0, draginfo.getStringData());
return true;
end
for i= start+1,size-1 do

BadElvis
September 13th, 2008, 12:22
I have implemented the roll and keep system for Legend of the Five Rings as shown in this Thread:

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