FG Spreadshirt Swag
Page 1 of 2 12 Last
  1. #1

    How do custom dice?

    So I'm trying to implement a Descent: Journeys into the Dark ruleset into FG. It is a boardgame, so it requires some funky looking dice:

    Basically, it is a D6, but the faces are custom. On a result of a 2, the meaning is 2 damage, 1 range, for example. The values also change depending on the die color, so essentially you have a green d6 and a red d6, and they are not the same die.

    Is there a way to get those dice to work inside FG? I was thinking of just rolling d6's and then just cross referencing them by hand, but I figured that would quickly get tedious. I'd like FG to roll the dice and calculate the results. (throw red 2d6 and yellow d6, script crossreferences it to a table and gives me the result = 8 damage, 3 range, 2 surges) I'm assuming a LUA script would work, but if anyone could give me a tip on where/how to start, that would be super.

  2. #2
    Valarian's Avatar
    Join Date
    Mar 2007
    Location
    Worcestershire, UK
    Posts
    2,567
    I think you're right that it'll need Lua scripting ... it goes beyond what a simple custom die will be able to produce. I don't think you'll be able to get the pictorial representation in FGII.

    I'll try and describe what I think may be needed:
    1. Create custom dice based on the d6 model for the different colours (e.g. dR = Red die, dY = Yellow die)
    Example: https://www.fantasygrounds.com/forum...1&postcount=14
    2. Create custom onDiceLanded() handler for the custom dice in the chat_chat.lua file.
    e.g. if "dR" then .... do red die stuff

    The custom dice would allow you to use the /die command to roll the dice (e.g. /die 2dR+1dY). The onDiceLanded function in the chat window would then produce the expected results based on the die results.
    Last edited by Valarian; July 25th, 2008 at 12:56.
    Using Ultimate license - that means anyone can play.
    Valarian's Fantasy Grounds Rulesets

  3. #3
    Sorontar's Avatar
    Join Date
    Apr 2005
    Location
    Manchester UK
    Posts
    531
    Such good fun playing this game, took me back to playing Heroquest as a kid ....I can't help but best of luck.

  4. #4
    Thanks. Let me cook up something and I'll update when I get stuck.

  5. #5
    Ok, so the easy stuff is done.

    Code:
    	<customdie name="dR">
    		<model>d6</model>
    		<menuicon>customdice</menuicon>
    	</customdie>
    	
    	<customdie name="dB">
    		<model>d6</model>
    		<menuicon>customdice</menuicon>
    	</customdie>
    	
    	<customdie name="dW">
    		<model>d6</model>
    		<menuicon>customdice</menuicon>
    	</customdie>
    That makes the custom dice. Now the hard part, I think.

    So this is kind of what I want to achieve. In a 1dR, the result of 1 will be 4damage/0range/0surges. On a result of a 2, the dRwill be 1 damage/1 range/1 surge. Etcetera.

    so I think that will require a table some pattern matching.

    string.gsub (s, pattern, repl [, n])
    Returns a copy of s in which all (or the first n, if given) occurrences of the pattern have been replaced by a replacement string specified by repl, which may be a string, a table, or a function. gsub also returns, as its second value, the total number of matches that occurred.

    If repl is a string, then its value is used for replacement. The character % works as an escape character: any sequence in repl of the form %n, with n between 1 and 9, stands for the value of the n-th captured substring (see below). The sequence %0 stands for the whole match. The sequence %% stands for a single %.

    If repl is a table, then the table is queried for every match, using the first capture as the key; if the pattern specifies no captures, then the whole match is used as the key.

    If repl is a function, then this function is called every time a match occurs, with all captured substrings passed as arguments, in order; if the pattern specifies no captures, then the whole match is passed as a sole argument.

    If the value returned by the table query or by the function call is a string or a number, then it is used as the replacement string; otherwise, if it is false or nil, then there is no replacement (that is, the original match is kept in the string).

    Here are some examples:

    x = string.gsub("hello world", "(%w+)", "%1 %1")
    --> x="hello hello world world"

    x = string.gsub("hello world", "%w+", "%0 %0", 1)
    --> x="hello hello world"

    x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
    --> x="world hello Lua from"

    x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
    --> x="home = /home/roberto, user = roberto"

    x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
    return loadstring(s)()
    end)
    --> x="4+5 = 9"

    local t = {name="lua", version="5.1"}
    x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
    --> x="lua-5.1.tar.gz"
    So since a table is/can be an array, then could I do this?

    d6=a/b/c/d/e/f

    Code:
    var dRdamage = new Array(4,0,1,2,3,3)
    var dRrange = new Array(0,0,1,0,1,0)
    var dRsurge = new Array(0,0,2,2,1,1)
    var dRmiss = new Array(0,1,0,0,0,0)
    Call up the results and then add them together? Is that possible to do?

    Also, the 3d representation of the dice can't be done, but what about the icons in the chatbox? Can the dR die be red and show 3d/4r/0s and the blue die show 2d/1r/3/s?

  6. #6
    oh hey I CAN do it. I'll be back with the actual code isntead of copy-pasting from that java thing.

  7. #7
    Valarian's Avatar
    Join Date
    Mar 2007
    Location
    Worcestershire, UK
    Posts
    2,567
    I'm afraid I'm not too up on the tables and how they work on lookups. You might be able to get it working. The longhand version would be to interrogate the dice as you go through the onDiceLanded() function

    Code:
            for i = 1, draginfo.getSlotCount() do
                draginfo.setSlot(i);
                
                local entry = {};
                entry.text = draginfo.getDescription();
                entry.font = "systemfont";
                entry.dice = {};
                entry.diemodifier = draginfo.getNumberData();
                local dicetable = draginfo.getDieList();
    
                local damage = 0;
                local range = 0;
                local surge = 0;
                local miss = 0;
                
                if dicetable then
                    for n = 1, table.maxn(dicetable) do
                        if dicetable[n].type == "dR" then
                            if dicetable[n].result == 1 then
                                damage = damage + 4;
                            elseif dicetable[n].result == 2 then
                                miss = miss + 1;
                            elseif dicetable[n].result == 3 then
                                damage = damage + 1;
                                range = range + 1;
                                surge = surge + 1;
                            elseif ....
                        elseif dicetable[n].type == "dB" then
                            ....
                        elseif dicetable[n].type == "dW" then
                            ....
                        else
                            table.insert(entry.dice, dicetable[n]);
                        end
                    end
                end
    
                if miss > 0 then
                    entry.text = entry.text .. " {MISS} ";
                elseif damage > 0 or range > 0 or surge = 0 then 
                    entry.text = entry.text .. " {Damage: " .. damage .. ", Range: " .. range .. ", Surge: " .. surge .. "} ";
                end
                
                if User.isHost() then
                    if ChatManager.getDieRevealFlag() then
                       entry.dicesecret = false;
                    end
                    entry.sender = GmIdentityManager.getCurrent();
                else
                    entry.sender = User.getIdentityLabel();
                end
                 
                deliverMessage(entry);
    Using Ultimate license - that means anyone can play.
    Valarian's Fantasy Grounds Rulesets

  8. #8
    Thank you Valarian. I think I'm making progress.

  9. #9
    Foen's Avatar
    Join Date
    Jan 2007
    Location
    Suffolk, England
    Posts
    2,007
    For notational/programming convenience, you could try the following:

    Code:
      local dRresults = {
        damage={4,0,1,2,3,3},
        range={0,0,1,0,1,0},
        surge={0,0,2,2,1,1},
        miss={0,1,0,0,0,0}};
    Then to decode a roll of n (between 1 and 6), you would use:

    Code:
      damage=dRresults.damage[n];
      range=dRresults.range[n];
      surge=dRresults.surge[n];
      miss=dRresults.miss[n];
    Hope that helps,

    Foen

  10. #10
    That helps a lot because I scoured the internet and read the lua manual over and over again but couldn't get the table to work. Thank you.

    Here is what I have so far

    Code:
    function onDiceLanded()
    	for i=1, draginfo.getSlotCount() do
    	draginfo.setSlot(i);
    	
    		localentry = {};
    		entry.text = draginfo.getDescription();
    		entry.font = "systemfont";
    		entry.dice = {};
    		entry.diemodifier = draginfo.getNumberData();
    		local dicetable = draginfo.getDieList();
    	
    		local damage = 0;
            local range = 0;
            local surge = 0;
            local miss = 0;
            local damagerange= 0;
            
            local dRresults = {
        	damage={4,0,1,2,3,3},
        	range={0,0,2,2,1,1},
       	 	surge={0,0,1,0,1,0},
        	miss={0,1,0,0,0,0}};
        	
        	localdBresults = {
        	damage={1,0,1,2,0,2},
        	range={3,0,3,1,4,2},
        	surge={1,0,1,0,1,0},
        	miss{0,1,0,0,0,0};
        	
        	localdWresults = {
        	damage={3,0,1,1,3,2},
        	range={1,0,3,3,1,2},
        	surge={1,0,1,1,1,0},
        	miss{0,1,0,0,0,0};
        	
        	localdGresults = {
        	damage={2,2,2,1,3,3},
        	range={0,1,0,1,0,0},
        	surge={1,0,1,0,0,0};
        	
        	localdYresults = {
        	damage={1,0,1,0,0,0},
        	range={1,3,2,3,2,2},
        	surge={0,0,0,0,1,1};
        	
        	localdBlackresults = {
        	damagerange={1,1,1,0,0,0},
        	surge=0,0,0,1,1,0{};
        	
        	localdSilverresults = {
        	damagerange={2,2,2,0,0,0},
        	surge={0,0,0,2,2,0};
        	
        	localdGoldresults = {
        	damagerange={3,3,3,0,0,0},
        	surge={0,0,0,3,3,0};
    I think Valarian's suggetion would work like this

    Code:
    if dicetable then
                    for n = 1, table.maxn(dicetable) do
                        if dicetable[n].type == "dR" then
                            damage=dRresults.damage[n];
                            range=dRresults.range[n];
                            surge=dRresults.surge[n];
                            miss=dRresults.miss[n];
    If I can get that to work, that's each individual result. How do I add all the different dice up at the end?

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
5E Product Walkthrough Playlist

Log in

Log in